PageRenderTime 33ms CodeModel.GetById 11ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/packages/libndsfpc/examples/gl2d/sprites/sprites.pp

https://github.com/slibre/freepascal
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.