/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
- (*
- Easy GL2D
- Relminator 2011
- Richard Eric M. Lope BSN RN
- Http://Rel.Phatcode.Net
- A very small, simple, yet very fast DS 2D rendering lib using the DS' 3D core.
- --
- Translated in Object Pascal by Francesco Lombardi - 2012
- http://itaprogaming.free.fr
- *)
- program sprites;
- {$L build/enemies.o}
- {$L build/zero.o}
- {$L build/tiles.o}
- {$L build/shuttle.o}
- {$L build/anya.o}
- {$L build/font.o}
- {$L build/fontbubble.o}
- {$mode objfpc}
- {$H+}
- uses
- ctypes, nds9, gl2d,
- cearn_atan,
- uvcoord_enemies, uvcoord_zero;
- // GRIT auto-generated files
- const
- enemiesBitmapLen = 65536;
- enemiesPalLen = 512;
- zeroBitmapLen = 32768;
- tilesBitmapLen = 65536;
- tilesPalLen = 512;
- shuttleBitmapLen = 2048;
- shuttlePalLen = 32;
- anyaBitmapLen = 32768;
- fontTilesLen = 3072;
- fontPalLen = 512;
- fontbubbleTilesLen = 2048;
- fontbubblePalLen = 512;
- var
- enemiesBitmap: array [0..0] of cuint; cvar; external;
- enemiesPal: array [0..0] of cushort; cvar; external;
- zeroBitmap: array [0..0] of cuint; cvar; external;
- tilesBitmap: array [0..0] of cuint; cvar; external;
- tilesPal: array [0..0] of cushort; cvar; external;
- shuttleBitmap: array [0..0] of cuint; cvar; external;
- shuttlePal: array [0..0] of cushort; cvar; external;
- anyaBitmap: array [0..0] of cuint; cvar; external;
- fontTiles: array [0..0] of cuint; cvar; external;
- fontPal: array [0..0] of cushort; cvar; external;
- fontbubbleTiles: array [0..0] of cuint; cvar; external;
- fontbubblePal: array [0..0] of cushort; cvar; external;
- // Declare our BG drawing routine
- procedure DrawBG(images: pglImage);
- var
- x, y, i: integer;
- begin
- for y := 0 to (256 div 16) - 1 do
- for x := 0 to (256 div 16) - 1 do
- begin
- i := y * 16 + x;
- glSprite(x * 16, y * 16, GL_FLIP_NONE, @images[i and 255]);
- end;
- end;
- var
- BRAD_PI: cint = 1 shl 14;
- // This imagesets would use our texture packer generated coords so it's kinda
- // safe and easy to use
- // ENEMIES_NUM_IMAGES is a value from "uvcoord_crono.h"
- // ZERO_NUM_IMAGES is a value from "uvcoord_zero.h"
- Enemies: array [0..ENEMIES_NUM_IMAGES -1] of glImage; // spriteset
- Zero: array [0..ZERO_NUM_IMAGES - 1] of glImage; // spriteset
- // This tileset won't make use of our texture packer generated coords.
- // Messy, manual and prone to errors.
- // BMP is 256x256 and tiles are 16x16 so.. (256/16) * (256 /16) = 16 * 16
- Tiles: array [0..(256 div 16) * (256 div 16) - 1] of glImage;
- // These sprites are single texture only so no need to
- // do anything special
- Shuttle: array [0..0] of glImage;
- Anya: array [0..0] of glImage;
-
- topScreen, bottomScreen: TPrintConsole;
- font, fontbubble: consoleFont;
-
- hitPal: array of cushort;
-
- i: cint;
-
- PaletteID: cint; // the all-white pal
- OriginalPaletteID: cint; // Original palette
- EnemiesTextureID: cint;
- ZeroTextureID: cint;
- TilesTextureID: cint;
- ShuttleTextureID: cint;
- AnyaTextureID: cint;
- TextureSize: cint;
-
- Frame: cint; // just the standard frame counter
- PhoenixFrame: cint; // animation frame for our firebird
- BeeFrame: cint; // animation frame for the bee
- ZeroFrame: cint; // animation frame for zero
- Rotation: cint; // rotation value of the rotating sprites
-
- x, y: integer;
- color: cint;
- begin
- // set mode 5, enable BG0 and set it to 3D
- videoSetMode(MODE_5_3D);
- videoSetModeSub(MODE_0_2D);
-
- // initialize gl2d
- glScreen2D();
-
- // Set up enough texture memory for our textures
- // Bank A is just 128kb and we are using 194 kb of
- // sprites
- vramSetBankA(VRAM_A_TEXTURE);
- vramSetBankB(VRAM_B_TEXTURE);
- vramSetBankF(VRAM_F_TEX_PALETTE); // Allocate VRAM bank for all the palettes
-
- vramSetBankE(VRAM_E_MAIN_BG); // Main bg text/8bit bg. Bank E size == 64kb, exactly enough for 8bit * 256 * 192 + text layer
-
- // Load our custom font for the top screen
- consoleInit(@topScreen, 1, BgType_Text4bpp, BgSize_T_256x256, 31, 0, true, false);
- //put bg 0 at a lower priority than the text background
- bgSetPriority(0, 1);
- // Bottom screeen
- vramSetBankI(VRAM_I_SUB_BG_0x06208000);
- consoleInit(@bottomScreen, 0, BgType_Text4bpp, BgSize_T_256x256, 20, 0, false, false);
-
- font.gfx := pcuint16(@fontTiles);
- font.pal := pcuint16(@fontPal);
- font.numChars := 95;
- font.numColors := fontPalLen div 2;
- font.bpp := 4;
- font.asciiOffset := 32;
- font.convertSingleColor := false;
-
-
- // Top Screen
- fontbubble.gfx := pcuint16(@fontbubbleTiles);
- fontbubble.pal := pcuint16(@fontbubblePal);
- fontbubble.numChars := 64;
- fontbubble.numColors := fontbubblePalLen div 2;
- fontbubble.bpp := 4;
- fontbubble.asciiOffset := 32;
- fontbubble.convertSingleColor := false;
-
- consoleSetFont(@bottomScreen, @font);
- consoleSetFont(@topScreen, @fontbubble);
-
-
- setlength(hitPal, 256);
- for i := 0 to 255 do
- hitPal[i] := ($FF shl 8) or $FF;
-
-
- // Generate the texture and load the all-white palette
- glGenTextures(1, @PaletteID);
- glBindTexture(0, PaletteID);
- glColorTableEXT(0, 0, 256, 0, 0, @hitPal[0]);
-
- // Generate another palette for our original image palette
- glGenTextures(1, @OriginalPaletteID);
- glBindTexture(0, OriginalPaletteID);
- glColorTableEXT(0, 0, 256, 0, 0, enemiesPal);
-
- // free some memory
- setLength(hitPal, 0);
- // Load our Enemies texture
- // We used glLoadSpriteSet since the texture was made
- // with my texture packer.
- EnemiesTextureID := glLoadSpriteSet(
- Enemies, // pointer to glImage array
- ENEMIES_NUM_IMAGES, // Texture packer auto-generated #define
- @enemies_texcoords, // Texture packer auto-generated array
- GL_RGB256, // texture type for glTexImage2D() in videoGL.h
- TEXTURE_SIZE_256, // sizeX for glTexImage2D() in videoGL.h
- TEXTURE_SIZE_256, // sizeY for glTexImage2D() in videoGL.h
- GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF or
- GL_TEXTURE_COLOR0_TRANSPARENT, // param for glTexImage2D() in videoGL.h
- 256, // Length of the palette to use (256 colors)
- @enemiesPal, // Load our 256 color enemies palette
- @enemiesBitmap // image data generated by GRIT
- );
-
- // Load our Zero texture
- // We used glLoadSpriteSet since the texture was made
- // with my texture packer.
- // No need for another palette since enemies and zero
- // share the same palette.
- ZeroTextureID := glLoadSpriteSet(
- Zero, // pointer to glImage array
- ZERO_NUM_IMAGES, // Texture packer auto-generated #define
- @zero_texcoords, // Texture packer auto-generated array
- GL_RGB256, // texture type for glTexImage2D() in videoGL.h
- TEXTURE_SIZE_128, // sizeX for glTexImage2D() in videoGL.h
- TEXTURE_SIZE_256, // sizeY for glTexImage2D() in videoGL.h
- GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF or
- GL_TEXTURE_COLOR0_TRANSPARENT, // param for glTexImage2D() in videoGL.h
- 256, // Length of the palette to use (256 colors)
- @enemiesPal, // Zero and Enemies share the same palette
- @zeroBitmap // image data generated by GRIT
- );
-
-
- // Our texture handle for our tiles
- // I used glLoadTileSet since the texture
- // is just a bunch of 16x16 tiles in a 256x256
- // tileset so we don't need a texture packer for this.
- TilesTextureID := glLoadTileSet(
- Tiles, // pointer to glImage array
- 16, // sprite width
- 16, // sprite height
- 256, // bitmap width
- 256, // bitmap height
- GL_RGB256, // texture type for glTexImage2D() in videoGL.h
- TEXTURE_SIZE_256, // sizeX for glTexImage2D() in videoGL.h
- TEXTURE_SIZE_256, // sizeY for glTexImage2D() in videoGL.h
- GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF or
- GL_TEXTURE_COLOR0_TRANSPARENT, // param for glTexImage2D() in videoGL.h
- 256, // Length of the palette to use (256 colors)
- @tilesPal, // Load our 256 color tiles palette
- @tilesBitmap // image data generated by GRIT
- );
-
-
-
- // Shuttle
- // Since the shuttle is just a single 64x64 image,
- // We use glLoadTileSet() giving the right dimensions.
- ShuttleTextureID := glLoadTileSet(
- Shuttle, // pointer to glImage array
- 64, // sprite width
- 64, // sprite height
- 64, // bitmap image width
- 64, // bitmap image height
- GL_RGB16, // texture type for glTexImage2D() in videoGL.h
- TEXTURE_SIZE_64, // sizeX for glTexImage2D() in videoGL.h
- TEXTURE_SIZE_64, // sizeY for glTexImage2D() in videoGL.h
- GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF or
- GL_TEXTURE_COLOR0_TRANSPARENT,
- 16, // Length of the palette to use (16 colors)
- @shuttlePal, // Load our 256 color tiles palette
- @shuttleBitmap // image data generated by GRIT
- );
-
- // Anya
- // This is a 16 bit image
- AnyaTextureID := glLoadTileSet(
- Anya,
- 128,
- 128,
- 128,
- 128,
- GL_RGB,
- TEXTURE_SIZE_128,
- TEXTURE_SIZE_128,
- GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF,
- 0, // Just use 0 if palette is not in use
- nil, // Just use nil if palette is not in use
- @anyaBitmap
- );
- // Print some console stuff
- // Top
- consoleSelect(@topScreen);
- iprintf(#10#10#10#10#9'WOOT!'#10);
- iprintf(#9'TOPSCREEN 3D+TEXT'#10);
-
-
- // Bottom
- consoleSelect(@bottomScreen);
- iprintf(#$1b'[1;1HEasy GL2D Sprites Demo');
- iprintf(#$1b'[2;1HRelminator');
- iprintf(#$1b'[4;1HHttp://Rel.Phatcode.Net');
-
- iprintf(#$1b'[6;1HA demo showing some sprite');
- iprintf(#$1b'[7;1Hcapabilities of Easy GL2D');
-
- iprintf(#$1b'[ 9;1HSprites by:');
- iprintf(#$1b'[10;1HAdigun A. Polack, Patater,');
- iprintf(#$1b'[11;1HCapcom and Anya Therese Lope');
-
- iprintf(#$1b'[13;1HTextureIDs = %i, %i, %i, %i, %i',
- EnemiesTextureID,
- ZeroTextureID,
- TilesTextureID,
- ShuttleTextureID,
- AnyaTextureID );
-
-
- // calculate the amount of
- // memory uploaded to VRAM in KB
- TextureSize := enemiesBitmapLen + zeroBitmapLen + tilesBitmapLen + shuttleBitmapLen + anyaBitmapLen;
-
-
- iprintf(#$1b'[15;1HTotal Texture size= %i kb', TextureSize div 1024);
-
-
- iprintf(#$1b'[17;1HEnemies use a 256 color pal');
- iprintf(#$1b'[18;1HZero uses a 256 color pal');
- iprintf(#$1b'[19;1HTiles use a 256 color pal');
- iprintf(#$1b'[20;1HShuttle uses a 16 color pal');
- iprintf(#$1b'[21;1HAnya is a 16 bit image');
-
-
- // some variables for our demo
- Frame := 0; // just the standard frame counter
- PhoenixFrame := 0; // animation frame for our firebird
- BeeFrame := 0; // animation frame for the bee
- ZeroFrame := 0; // animation frame for zero
- Rotation := 0; // rotation value of the rotating sprites
-
-
- while true do
- begin
- inc(Frame);
-
- Rotation := Frame * 240; // speed up our rotation
-
- // animate some of our animated sprites
- // every 8th frame
- if (Frame and 7) = 0 then
- begin
- BeeFrame := (BeeFrame + 1) and 1;
- inc(PhoenixFrame);
- if (PhoenixFrame > 2) then
- PhoenixFrame := 0;
-
- end;
- // Faster zero animation
- if (Frame and 3) = 0 then
- begin
- inc(ZeroFrame);
- if (ZeroFrame > 9) then
- ZeroFrame := 0;
- end;
-
-
- // calculate positions for our rotating sprites
- x := 128 + SarLongInt((cosLerp(Frame) + sinLerp(BRAD_PI + Rotation) * 100), 12);
- y := 96 + SarLongInt((cosLerp(Frame) + cosLerp(-Rotation) * 80), 12);
-
-
-
- // Start 2D mode
- glBegin2D();
- // Set our palette to our tiles (256 colors)
- // and draw our background
- DrawBG(@Tiles);
-
- // Make the Anya's rotoscaled sprite translucent just for kicks
- // Use glSpriteRotateScaleXY() for some effect
- // Give it a polygon ID so that transluceny would work
- glPolyFmt(POLY_ALPHA(20) or POLY_CULL_NONE or POLY_ID(1));
- glSpriteRotateScaleXY(SCREEN_WIDTH div 2, SCREEN_HEIGHT div 2,
- Frame * 140, sinLerp(Frame * 120) * 3, sinLerp(Frame * 210) * 2,
- GL_FLIP_NONE,
- @Anya);
-
-
- // Draw our enemies
- // draw some rotated and/or animated sprites
- // Give the other sprites different polygon IDs
- // so that translucency works
- glPolyFmt(POLY_ALPHA(20) or POLY_CULL_NONE or POLY_ID(2));
- glSpriteRotate( x, y, Rotation, GL_FLIP_NONE, @Enemies[30 + BeeFrame]);
- glSpriteRotate(255 - x, 191 - y, Rotation * 4, GL_FLIP_H, @Enemies[84]);
- glSpriteRotate(255 - x, y, -Rotation, GL_FLIP_V, @Enemies[32]);
- glSpriteRotate( x, 191 - y, -Rotation * 3, GL_FLIP_H or GL_FLIP_V, @Enemies[81]);
-
-
- // Some phoenix enemies on the right
- // Note the flipmodes
- // Also shows how we can draw in "color mode" and shadow mode
- glPolyFmt(POLY_ALPHA(20) or POLY_CULL_NONE or POLY_ID(3));
- glSprite(200, 0, GL_FLIP_NONE, @Enemies[87 + PhoenixFrame]);
- glColor(RGB15(31, 0, 0));
- glSprite(200, 30, GL_FLIP_H, @Enemies[87 + PhoenixFrame]);
-
- // Make the last two sprites translucent
- glPolyFmt(POLY_ALPHA(20) or POLY_CULL_NONE or POLY_ID(4));
- glColor(RGB15(0, 31, 20) );
- glSprite(200, 60, GL_FLIP_V, @Enemies[87 + PhoenixFrame]);
- glColor(RGB15(0, 0, 0));
- glSprite(200, 90, GL_FLIP_V or GL_FLIP_H, @Enemies[87 + PhoenixFrame]);
-
- //Restore color and translucency to normal
- glColor(RGB15(31, 31, 31));
- glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE or POLY_ID(5));
-
-
- // "Clean Stretch" the sprite
- // Useful for lasers and some effects
- glSpriteStretchHorizontal(0, 135, 64 + (abs(sinLerp(Frame * 100) * 200) shr 12), @Shuttle);
-
-
- // USING DIFFERENT PALETTES
- // Set the active texture to Zero
- // and use our special all white palette
- glSetActiveTexture(ZeroTextureID);
- glAssignColorTable(0, PaletteID);
-
- // Zero Sprite is drawn all white
- glSprite(0, 42 * 0, GL_FLIP_NONE, @Zero[ZeroFrame]);
- // Draw a horizontally flipped "disco" zero
- // Disco fx is done with glColor
- color := (Frame * 4) and 31;
- glColor(RGB15(color, 31 - color, 16 + color * 2));
- glSprite(0, 42 * 1, GL_FLIP_H, @Zero[ZeroFrame]);
-
- // Restore our palette
- glAssignColorTable(0, OriginalPaletteID);
-
- // restore pal to enemies
- glColor(RGB15(31 - color, 16 + color * 2, color));
- glSprite(0, 42 * 2, GL_FLIP_V, @Zero[ZeroFrame]);
-
- // Normalize color
- glColor(RGB15(31, 31, 31));
- glSprite(0, 42 * 3, GL_FLIP_V or GL_FLIP_H, @Zero[ZeroFrame]);
- glEnd2D();
- glFlush(0);
- swiWaitForVBlank();
-
-
- end;
- end.