/packages/libndsfpc/examples/gl2d/sprites/sprites.pp
Puppet | 460 lines | 425 code | 35 blank | 0 comment | 20 complexity | 0921f0006001a3a21ab45aa3f29f6fb8 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, LGPL-3.0
1(* 2 Easy GL2D 3 Relminator 2011 4 Richard Eric M. Lope BSN RN 5 Http://Rel.Phatcode.Net 6 A very small, simple, yet very fast DS 2D rendering lib using the DS' 3D core. 7 -- 8 Translated in Object Pascal by Francesco Lombardi - 2012 9 http://itaprogaming.free.fr 10*) 11program sprites; 12 13{$L build/enemies.o} 14{$L build/zero.o} 15{$L build/tiles.o} 16{$L build/shuttle.o} 17{$L build/anya.o} 18{$L build/font.o} 19{$L build/fontbubble.o} 20 21{$mode objfpc} 22{$H+} 23 24 25 26uses 27 ctypes, nds9, gl2d, 28 cearn_atan, 29 uvcoord_enemies, uvcoord_zero; 30 31// GRIT auto-generated files 32const 33 enemiesBitmapLen = 65536; 34 enemiesPalLen = 512; 35 zeroBitmapLen = 32768; 36 tilesBitmapLen = 65536; 37 tilesPalLen = 512; 38 shuttleBitmapLen = 2048; 39 shuttlePalLen = 32; 40 anyaBitmapLen = 32768; 41 fontTilesLen = 3072; 42 fontPalLen = 512; 43 fontbubbleTilesLen = 2048; 44 fontbubblePalLen = 512; 45 46var 47 enemiesBitmap: array [0..0] of cuint; cvar; external; 48 enemiesPal: array [0..0] of cushort; cvar; external; 49 zeroBitmap: array [0..0] of cuint; cvar; external; 50 tilesBitmap: array [0..0] of cuint; cvar; external; 51 52 tilesPal: array [0..0] of cushort; cvar; external; 53 shuttleBitmap: array [0..0] of cuint; cvar; external; 54 55 shuttlePal: array [0..0] of cushort; cvar; external; 56 anyaBitmap: array [0..0] of cuint; cvar; external; 57 fontTiles: array [0..0] of cuint; cvar; external; 58 fontPal: array [0..0] of cushort; cvar; external; 59 fontbubbleTiles: array [0..0] of cuint; cvar; external; 60 fontbubblePal: array [0..0] of cushort; cvar; external; 61 62// Declare our BG drawing routine 63procedure DrawBG(images: pglImage); 64var 65 x, y, i: integer; 66begin 67 for y := 0 to (256 div 16) - 1 do 68 for x := 0 to (256 div 16) - 1 do 69 begin 70 i := y * 16 + x; 71 glSprite(x * 16, y * 16, GL_FLIP_NONE, @images[i and 255]); 72 end; 73end; 74 75 76 77var 78 BRAD_PI: cint = 1 shl 14; 79 80 // This imagesets would use our texture packer generated coords so it's kinda 81 // safe and easy to use 82 // ENEMIES_NUM_IMAGES is a value from "uvcoord_crono.h" 83 // ZERO_NUM_IMAGES is a value from "uvcoord_zero.h" 84 Enemies: array [0..ENEMIES_NUM_IMAGES -1] of glImage; // spriteset 85 Zero: array [0..ZERO_NUM_IMAGES - 1] of glImage; // spriteset 86 87 // This tileset won't make use of our texture packer generated coords. 88 // Messy, manual and prone to errors. 89 // BMP is 256x256 and tiles are 16x16 so.. (256/16) * (256 /16) = 16 * 16 90 Tiles: array [0..(256 div 16) * (256 div 16) - 1] of glImage; 91 92 // These sprites are single texture only so no need to 93 // do anything special 94 Shuttle: array [0..0] of glImage; 95 Anya: array [0..0] of glImage; 96 97 topScreen, bottomScreen: TPrintConsole; 98 font, fontbubble: consoleFont; 99 100 hitPal: array of cushort; 101 102 i: cint; 103 104 PaletteID: cint; // the all-white pal 105 OriginalPaletteID: cint; // Original palette 106 EnemiesTextureID: cint; 107 ZeroTextureID: cint; 108 TilesTextureID: cint; 109 ShuttleTextureID: cint; 110 AnyaTextureID: cint; 111 112 TextureSize: cint; 113 114 Frame: cint; // just the standard frame counter 115 PhoenixFrame: cint; // animation frame for our firebird 116 BeeFrame: cint; // animation frame for the bee 117 ZeroFrame: cint; // animation frame for zero 118 Rotation: cint; // rotation value of the rotating sprites 119 120 x, y: integer; 121 color: cint; 122 123begin 124 // set mode 5, enable BG0 and set it to 3D 125 videoSetMode(MODE_5_3D); 126 videoSetModeSub(MODE_0_2D); 127 128 // initialize gl2d 129 glScreen2D(); 130 131 // Set up enough texture memory for our textures 132 // Bank A is just 128kb and we are using 194 kb of 133 // sprites 134 vramSetBankA(VRAM_A_TEXTURE); 135 vramSetBankB(VRAM_B_TEXTURE); 136 137 vramSetBankF(VRAM_F_TEX_PALETTE); // Allocate VRAM bank for all the palettes 138 139 vramSetBankE(VRAM_E_MAIN_BG); // Main bg text/8bit bg. Bank E size == 64kb, exactly enough for 8bit * 256 * 192 + text layer 140 141 // Load our custom font for the top screen 142 consoleInit(@topScreen, 1, BgType_Text4bpp, BgSize_T_256x256, 31, 0, true, false); 143 //put bg 0 at a lower priority than the text background 144 bgSetPriority(0, 1); 145 146 // Bottom screeen 147 vramSetBankI(VRAM_I_SUB_BG_0x06208000); 148 consoleInit(@bottomScreen, 0, BgType_Text4bpp, BgSize_T_256x256, 20, 0, false, false); 149 150 font.gfx := pcuint16(@fontTiles); 151 font.pal := pcuint16(@fontPal); 152 font.numChars := 95; 153 font.numColors := fontPalLen div 2; 154 font.bpp := 4; 155 font.asciiOffset := 32; 156 font.convertSingleColor := false; 157 158 159 // Top Screen 160 fontbubble.gfx := pcuint16(@fontbubbleTiles); 161 fontbubble.pal := pcuint16(@fontbubblePal); 162 fontbubble.numChars := 64; 163 fontbubble.numColors := fontbubblePalLen div 2; 164 fontbubble.bpp := 4; 165 fontbubble.asciiOffset := 32; 166 fontbubble.convertSingleColor := false; 167 168 consoleSetFont(@bottomScreen, @font); 169 consoleSetFont(@topScreen, @fontbubble); 170 171 172 setlength(hitPal, 256); 173 for i := 0 to 255 do 174 hitPal[i] := ($FF shl 8) or $FF; 175 176 177 // Generate the texture and load the all-white palette 178 glGenTextures(1, @PaletteID); 179 glBindTexture(0, PaletteID); 180 glColorTableEXT(0, 0, 256, 0, 0, @hitPal[0]); 181 182 // Generate another palette for our original image palette 183 glGenTextures(1, @OriginalPaletteID); 184 glBindTexture(0, OriginalPaletteID); 185 glColorTableEXT(0, 0, 256, 0, 0, enemiesPal); 186 187 // free some memory 188 setLength(hitPal, 0); 189 190 // Load our Enemies texture 191 // We used glLoadSpriteSet since the texture was made 192 // with my texture packer. 193 EnemiesTextureID := glLoadSpriteSet( 194 Enemies, // pointer to glImage array 195 ENEMIES_NUM_IMAGES, // Texture packer auto-generated #define 196 @enemies_texcoords, // Texture packer auto-generated array 197 GL_RGB256, // texture type for glTexImage2D() in videoGL.h 198 TEXTURE_SIZE_256, // sizeX for glTexImage2D() in videoGL.h 199 TEXTURE_SIZE_256, // sizeY for glTexImage2D() in videoGL.h 200 GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF or 201 GL_TEXTURE_COLOR0_TRANSPARENT, // param for glTexImage2D() in videoGL.h 202 256, // Length of the palette to use (256 colors) 203 @enemiesPal, // Load our 256 color enemies palette 204 @enemiesBitmap // image data generated by GRIT 205 ); 206 207 // Load our Zero texture 208 // We used glLoadSpriteSet since the texture was made 209 // with my texture packer. 210 // No need for another palette since enemies and zero 211 // share the same palette. 212 ZeroTextureID := glLoadSpriteSet( 213 Zero, // pointer to glImage array 214 ZERO_NUM_IMAGES, // Texture packer auto-generated #define 215 @zero_texcoords, // Texture packer auto-generated array 216 GL_RGB256, // texture type for glTexImage2D() in videoGL.h 217 TEXTURE_SIZE_128, // sizeX for glTexImage2D() in videoGL.h 218 TEXTURE_SIZE_256, // sizeY for glTexImage2D() in videoGL.h 219 GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF or 220 GL_TEXTURE_COLOR0_TRANSPARENT, // param for glTexImage2D() in videoGL.h 221 256, // Length of the palette to use (256 colors) 222 @enemiesPal, // Zero and Enemies share the same palette 223 @zeroBitmap // image data generated by GRIT 224 ); 225 226 227 // Our texture handle for our tiles 228 // I used glLoadTileSet since the texture 229 // is just a bunch of 16x16 tiles in a 256x256 230 // tileset so we don't need a texture packer for this. 231 TilesTextureID := glLoadTileSet( 232 Tiles, // pointer to glImage array 233 16, // sprite width 234 16, // sprite height 235 256, // bitmap width 236 256, // bitmap height 237 GL_RGB256, // texture type for glTexImage2D() in videoGL.h 238 TEXTURE_SIZE_256, // sizeX for glTexImage2D() in videoGL.h 239 TEXTURE_SIZE_256, // sizeY for glTexImage2D() in videoGL.h 240 GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF or 241 GL_TEXTURE_COLOR0_TRANSPARENT, // param for glTexImage2D() in videoGL.h 242 256, // Length of the palette to use (256 colors) 243 @tilesPal, // Load our 256 color tiles palette 244 @tilesBitmap // image data generated by GRIT 245 ); 246 247 248 249 // Shuttle 250 // Since the shuttle is just a single 64x64 image, 251 // We use glLoadTileSet() giving the right dimensions. 252 ShuttleTextureID := glLoadTileSet( 253 Shuttle, // pointer to glImage array 254 64, // sprite width 255 64, // sprite height 256 64, // bitmap image width 257 64, // bitmap image height 258 GL_RGB16, // texture type for glTexImage2D() in videoGL.h 259 TEXTURE_SIZE_64, // sizeX for glTexImage2D() in videoGL.h 260 TEXTURE_SIZE_64, // sizeY for glTexImage2D() in videoGL.h 261 GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF or 262 GL_TEXTURE_COLOR0_TRANSPARENT, 263 16, // Length of the palette to use (16 colors) 264 @shuttlePal, // Load our 256 color tiles palette 265 @shuttleBitmap // image data generated by GRIT 266 ); 267 268 269 270 // Anya 271 // This is a 16 bit image 272 AnyaTextureID := glLoadTileSet( 273 Anya, 274 128, 275 128, 276 128, 277 128, 278 GL_RGB, 279 TEXTURE_SIZE_128, 280 TEXTURE_SIZE_128, 281 GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF, 282 0, // Just use 0 if palette is not in use 283 nil, // Just use nil if palette is not in use 284 @anyaBitmap 285 ); 286 287 // Print some console stuff 288 289 // Top 290 consoleSelect(@topScreen); 291 iprintf(#10#10#10#10#9'WOOT!'#10); 292 iprintf(#9'TOPSCREEN 3D+TEXT'#10); 293 294 295 // Bottom 296 consoleSelect(@bottomScreen); 297 iprintf(#$1b'[1;1HEasy GL2D Sprites Demo'); 298 iprintf(#$1b'[2;1HRelminator'); 299 iprintf(#$1b'[4;1HHttp://Rel.Phatcode.Net'); 300 301 iprintf(#$1b'[6;1HA demo showing some sprite'); 302 iprintf(#$1b'[7;1Hcapabilities of Easy GL2D'); 303 304 iprintf(#$1b'[ 9;1HSprites by:'); 305 iprintf(#$1b'[10;1HAdigun A. Polack, Patater,'); 306 iprintf(#$1b'[11;1HCapcom and Anya Therese Lope'); 307 308 iprintf(#$1b'[13;1HTextureIDs = %i, %i, %i, %i, %i', 309 EnemiesTextureID, 310 ZeroTextureID, 311 TilesTextureID, 312 ShuttleTextureID, 313 AnyaTextureID ); 314 315 316 // calculate the amount of 317 // memory uploaded to VRAM in KB 318 TextureSize := enemiesBitmapLen + zeroBitmapLen + tilesBitmapLen + shuttleBitmapLen + anyaBitmapLen; 319 320 321 iprintf(#$1b'[15;1HTotal Texture size= %i kb', TextureSize div 1024); 322 323 324 iprintf(#$1b'[17;1HEnemies use a 256 color pal'); 325 iprintf(#$1b'[18;1HZero uses a 256 color pal'); 326 iprintf(#$1b'[19;1HTiles use a 256 color pal'); 327 iprintf(#$1b'[20;1HShuttle uses a 16 color pal'); 328 iprintf(#$1b'[21;1HAnya is a 16 bit image'); 329 330 331 // some variables for our demo 332 Frame := 0; // just the standard frame counter 333 PhoenixFrame := 0; // animation frame for our firebird 334 BeeFrame := 0; // animation frame for the bee 335 ZeroFrame := 0; // animation frame for zero 336 Rotation := 0; // rotation value of the rotating sprites 337 338 339 while true do 340 begin 341 inc(Frame); 342 343 Rotation := Frame * 240; // speed up our rotation 344 345 // animate some of our animated sprites 346 // every 8th frame 347 if (Frame and 7) = 0 then 348 begin 349 BeeFrame := (BeeFrame + 1) and 1; 350 inc(PhoenixFrame); 351 if (PhoenixFrame > 2) then 352 PhoenixFrame := 0; 353 354 end; 355 356 // Faster zero animation 357 if (Frame and 3) = 0 then 358 begin 359 inc(ZeroFrame); 360 if (ZeroFrame > 9) then 361 ZeroFrame := 0; 362 end; 363 364 365 // calculate positions for our rotating sprites 366 x := 128 + SarLongInt((cosLerp(Frame) + sinLerp(BRAD_PI + Rotation) * 100), 12); 367 y := 96 + SarLongInt((cosLerp(Frame) + cosLerp(-Rotation) * 80), 12); 368 369 370 371 // Start 2D mode 372 glBegin2D(); 373 374 // Set our palette to our tiles (256 colors) 375 // and draw our background 376 DrawBG(@Tiles); 377 378 // Make the Anya's rotoscaled sprite translucent just for kicks 379 // Use glSpriteRotateScaleXY() for some effect 380 // Give it a polygon ID so that transluceny would work 381 glPolyFmt(POLY_ALPHA(20) or POLY_CULL_NONE or POLY_ID(1)); 382 glSpriteRotateScaleXY(SCREEN_WIDTH div 2, SCREEN_HEIGHT div 2, 383 Frame * 140, sinLerp(Frame * 120) * 3, sinLerp(Frame * 210) * 2, 384 GL_FLIP_NONE, 385 @Anya); 386 387 388 // Draw our enemies 389 // draw some rotated and/or animated sprites 390 // Give the other sprites different polygon IDs 391 // so that translucency works 392 glPolyFmt(POLY_ALPHA(20) or POLY_CULL_NONE or POLY_ID(2)); 393 glSpriteRotate( x, y, Rotation, GL_FLIP_NONE, @Enemies[30 + BeeFrame]); 394 glSpriteRotate(255 - x, 191 - y, Rotation * 4, GL_FLIP_H, @Enemies[84]); 395 glSpriteRotate(255 - x, y, -Rotation, GL_FLIP_V, @Enemies[32]); 396 glSpriteRotate( x, 191 - y, -Rotation * 3, GL_FLIP_H or GL_FLIP_V, @Enemies[81]); 397 398 399 // Some phoenix enemies on the right 400 // Note the flipmodes 401 // Also shows how we can draw in "color mode" and shadow mode 402 glPolyFmt(POLY_ALPHA(20) or POLY_CULL_NONE or POLY_ID(3)); 403 glSprite(200, 0, GL_FLIP_NONE, @Enemies[87 + PhoenixFrame]); 404 glColor(RGB15(31, 0, 0)); 405 glSprite(200, 30, GL_FLIP_H, @Enemies[87 + PhoenixFrame]); 406 407 // Make the last two sprites translucent 408 glPolyFmt(POLY_ALPHA(20) or POLY_CULL_NONE or POLY_ID(4)); 409 glColor(RGB15(0, 31, 20) ); 410 glSprite(200, 60, GL_FLIP_V, @Enemies[87 + PhoenixFrame]); 411 glColor(RGB15(0, 0, 0)); 412 glSprite(200, 90, GL_FLIP_V or GL_FLIP_H, @Enemies[87 + PhoenixFrame]); 413 414 //Restore color and translucency to normal 415 glColor(RGB15(31, 31, 31)); 416 glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE or POLY_ID(5)); 417 418 419 // "Clean Stretch" the sprite 420 // Useful for lasers and some effects 421 glSpriteStretchHorizontal(0, 135, 64 + (abs(sinLerp(Frame * 100) * 200) shr 12), @Shuttle); 422 423 424 // USING DIFFERENT PALETTES 425 // Set the active texture to Zero 426 // and use our special all white palette 427 glSetActiveTexture(ZeroTextureID); 428 glAssignColorTable(0, PaletteID); 429 430 // Zero Sprite is drawn all white 431 glSprite(0, 42 * 0, GL_FLIP_NONE, @Zero[ZeroFrame]); 432 433 // Draw a horizontally flipped "disco" zero 434 // Disco fx is done with glColor 435 color := (Frame * 4) and 31; 436 glColor(RGB15(color, 31 - color, 16 + color * 2)); 437 glSprite(0, 42 * 1, GL_FLIP_H, @Zero[ZeroFrame]); 438 439 // Restore our palette 440 glAssignColorTable(0, OriginalPaletteID); 441 442 // restore pal to enemies 443 glColor(RGB15(31 - color, 16 + color * 2, color)); 444 glSprite(0, 42 * 2, GL_FLIP_V, @Zero[ZeroFrame]); 445 446 447 // Normalize color 448 glColor(RGB15(31, 31, 31)); 449 glSprite(0, 42 * 3, GL_FLIP_V or GL_FLIP_H, @Zero[ZeroFrame]); 450 451 glEnd2D(); 452 453 glFlush(0); 454 455 swiWaitForVBlank(); 456 457 458 end; 459 460end.