2Dplus3D.pp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  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. *)
  11. program TwoDplusThreeD;
  12. {$mode objfpc}
  13. {$H+}
  14. {$L build/flyer.o}
  15. {$L build/shuttle.o}
  16. {$L build/enemies.o}
  17. {$L build/organ16.o}
  18. uses
  19. ctypes, nds9, gl2d, cearn_atan, vbuffer, uvcoord_enemies;
  20. const
  21. flyerBitmapLen = 2048;
  22. flyerPalLen = 512;
  23. shuttleBitmapLen = 2048;
  24. shuttlePalLen = 32;
  25. enemiesBitmapLen = 65536;
  26. enemiesPalLen = 512;
  27. organ16BitmapLen = 32768;
  28. var
  29. flyerBitmap: array [0..0] of cuint; cvar; external;
  30. flyerPal: array [0..0] of cushort; cvar; external;
  31. shuttleBitmap: array [0..0] of cuint; cvar; external;
  32. shuttlePal: array [0..0] of cushort; cvar; external;
  33. enemiesBitmap: array [0..0] of cuint; cvar; external;
  34. enemiesPal: array [0..0] of cushort; cvar; external;
  35. organ16Bitmap: array [0..0] of cuint; cvar; external;
  36. const
  37. // Mode7-like 3D effect parameters
  38. GRID_RINGS: cint = 2;
  39. GRID_BANDS: cint = 2;
  40. GRID_WIDTH: cint = 15;
  41. GRID_HEIGHT: cint = 12;
  42. // PI for our binary radian measure
  43. BRAD_PI = 1 shl 14;
  44. var
  45. // Our sprites
  46. Enemies: array [0..ENEMIES_NUM_IMAGES-1] of glImage; // spriteset
  47. Shuttle: array [0..0] of glImage; // single image
  48. Flyer: array [0..0] of glImage; // single image
  49. vb: PVertexBuffer;
  50. EnemiesTextureID: cint;
  51. ShuttleTextureID: cint;
  52. FlyerTextureID: cint;
  53. TextureSize: cint;
  54. ox, oy: cint32;
  55. Frame, PhoenixFrame, BeeFrame, Rotation: cint; // rotation value of the rotating sprites
  56. x, y: cint;
  57. sx, sy, angle: cint32;
  58. // function to draw our mode7 fx
  59. // draws 2 planes
  60. // for a fake mode7 effect
  61. procedure draw_grid();
  62. const
  63. text_off_u: cint32 = 0;
  64. text_off_v: cint32 = 0;
  65. frame: cint = 0;
  66. begin
  67. inc(frame);
  68. glPushMatrix();
  69. glLoadIdentity();
  70. glTranslate3f32( 0, 0, floattof32(3.0) );
  71. glScalef32(floattof32(1),floattof32(1.5),floattof32(1.5));
  72. // floor
  73. glPushMatrix();
  74. glTranslate3f32( 0, -1 shl 12, -2 shl 12 );
  75. glRotateXi( inttof32(244) );
  76. vb^.render( text_off_u, text_off_v, true );
  77. glPopMatrix( 1 );
  78. // ceiling
  79. glPushMatrix();
  80. glTranslate3f32( 0, 1 shl 12, -2 shl 12 );
  81. glRotateXi( inttof32(180) );
  82. vb^.render( text_off_u ,text_off_v, true );
  83. glPopMatrix( 1 );
  84. glPopMatrix( 1 );
  85. // "move" the floor and ceiling
  86. text_off_u := (sinLerp(frame*30)*2) and 4095;
  87. text_off_v := (sinLerp(-frame*50)*3) and 4095;
  88. end;
  89. begin
  90. // Initialize fake mode7 planes
  91. vb := init_grid (GRID_RINGS, GRID_BANDS, GRID_WIDTH, GRID_HEIGHT, 8, 8);
  92. //set mode 5, enable BG0 and set it to 3D
  93. videoSetMode(MODE_5_3D);
  94. consoleDemoInit();
  95. // initialize gl2d
  96. glScreen2D();
  97. //set up enough texture memory for our textures
  98. vramSetBankA( VRAM_A_TEXTURE );
  99. // Very Important!!! Or you get black sprites
  100. vramSetBankE(VRAM_E_TEX_PALETTE); // Allocate VRAM bank for all the palettes
  101. // Load our texture for our mode7 effect
  102. vb^.load_texture( @organ16Bitmap );
  103. // Load our Enemies texture
  104. // We used glLoadSpriteSet since the texture was made
  105. // with my texture packer.
  106. EnemiesTextureID := glLoadSpriteSet(
  107. Enemies, // pointer to glImage array
  108. ENEMIES_NUM_IMAGES, // Texture packer auto-generated #define
  109. @enemies_texcoords, // Texture packer auto-generated array
  110. GL_RGB256, // texture type for glTexImage2D() in videoGL.h
  111. TEXTURE_SIZE_256, // sizeX for glTexImage2D() in videoGL.h
  112. TEXTURE_SIZE_256, // sizeY for glTexImage2D() in videoGL.h
  113. GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF or GL_TEXTURE_COLOR0_TRANSPARENT, // param for glTexImage2D() in videoGL.h
  114. 256, // Length of the palette to use (256 colors)
  115. @enemiesPal, // Load our 256 color enemies palette
  116. @enemiesBitmap // image data generated by GRIT
  117. );
  118. // Shuttle
  119. // Since the shuttle is just a single 64x64 image,
  120. // We use glLoadTileSet() giving the right dimensions.
  121. ShuttleTextureID := glLoadTileSet(
  122. Shuttle, // pointer to glImage array
  123. 64, // sprite width
  124. 64, // sprite height
  125. 64, // bitmap image width
  126. 64, // bitmap image height
  127. GL_RGB16, // texture type for glTexImage2D() in videoGL.h
  128. TEXTURE_SIZE_64, // sizeX for glTexImage2D() in videoGL.h
  129. TEXTURE_SIZE_64, // sizeY for glTexImage2D() in videoGL.h
  130. GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF or GL_TEXTURE_COLOR0_TRANSPARENT,
  131. 16, // Length of the palette to use (16 colors)
  132. @shuttlePal, // Load our 16 color Shuttle palette
  133. @shuttleBitmap // image data generated by GRIT
  134. );
  135. // Flyer
  136. FlyerTextureID := glLoadTileSet(
  137. Flyer,
  138. 64,
  139. 64,
  140. 64,
  141. 64,
  142. GL_RGB16,
  143. TEXTURE_SIZE_64,
  144. TEXTURE_SIZE_64,
  145. GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_OFF or GL_TEXTURE_COLOR0_TRANSPARENT,
  146. 16, // Length of the palette to use (16 colors)
  147. @flyerPal, // Load our 16 color Flyer palette
  148. @flyerBitmap
  149. );
  150. // Print some console stuff
  151. iprintf(#$1b'[1;1HEasy GL2D + 3D');
  152. iprintf(#$1b'[2;1HRelminator');
  153. iprintf(#$1b'[4;1HHttp://Rel.Phatcode.Net');
  154. iprintf(#$1b'[6;1HA demo showing a very easy');
  155. iprintf(#$1b'[7;1Hway to combine 3D and 2D');
  156. iprintf(#$1b'[ 9;1HSprites by:');
  157. iprintf(#$1b'[10;1H Adigun A. Polack and Patater');
  158. iprintf(#$1b'[11;1HFixed Point atan2Lerp By Cearn');
  159. iprintf(#$1b'[13;1HEnemiesTextureID = %i', EnemiesTextureID);
  160. iprintf(#$1b'[14;1HFlyerTextureID = %i', FlyerTextureID);
  161. iprintf(#$1b'[15;1HShuttleTextureID = %i', ShuttleTextureID);
  162. iprintf(#$1b'[17;1HEnemies use a 256 color pal');
  163. iprintf(#$1b'[18;1HShuttle uses a 16 color pal');
  164. iprintf(#$1b'[19;1HFlyer uses a 16 color pal');
  165. iprintf(#$1b'[20;1H3D plane is a 16 bit image');
  166. TextureSize := enemiesBitmapLen + flyerBitmapLen + organ16BitmapLen + shuttleBitmapLen;
  167. iprintf(#$1b'[22;1HTotal Texture size= %i kb', TextureSize div 1024);
  168. // some variables for our demo
  169. ox := 0; oy := 0; // needed for shuttle angle calculation
  170. Frame := 0; // just the standard frame counter
  171. PhoenixFrame := 0; // animation frame for our firebird
  172. BeeFrame := 0; // animation frame for the bee
  173. Rotation := 0; // rotation value of the rotating sprites
  174. while true do
  175. begin
  176. inc(frame);
  177. rotation := frame * 240; // speed up our rotation
  178. // animate some of our animated sprites
  179. // every 8th frame
  180. if ( (Frame and 7) = 0 ) then
  181. begin
  182. BeeFrame := (BeeFrame + 1) and 1;
  183. inc(PhoenixFrame);
  184. if (PhoenixFrame > 2) then
  185. PhoenixFrame := 0;
  186. end;
  187. // calculate positions for our rotating sprites
  188. x := 128 + SarLongint((cosLerp(Frame) + sinLerp(BRAD_PI + Rotation) * 70), 12);
  189. y := 96 + SarLongint((cosLerp(Frame) + cosLerp(-Rotation) * 50), 12);
  190. // Calculate moving shuttle position
  191. // Get new ship position in f32 format for accuracy since
  192. // shifting here by >> 12 looses accuracy
  193. sx := (cosLerp(Frame * 150) + sinLerp(Frame * 70)) * (SCREEN_WIDTH div 4) ;
  194. sy := (sinLerp(-(Frame * 80)) + sinLerp(Frame * 190)) * (SCREEN_HEIGHT div 4) ;
  195. // get angle(binary radian) to draw the rotated shuttle
  196. angle := atan2Lerp(ox - sx, oy - sy);
  197. // save positions for use on the nexgt frame to get the new angle
  198. ox := sx;
  199. oy := sy;
  200. // Get new shuttle position
  201. // Shifting by >> 12 so that we can screen coordinates to draw
  202. sx := SCREEN_WIDTH div 2 + SarLongint(sx, 12);
  203. sy := SCREEN_HEIGHT div 2 + SarLongint(sy, 12);
  204. // Drawing the fake mode7 FX in 3D mode
  205. draw_grid();
  206. // End drawing in 3D mode
  207. // Start 2D mode
  208. glBegin2D();
  209. // Draw our enemies
  210. // draw some rotated and/or animated sprites
  211. glSpriteRotate( x, y, Rotation, GL_FLIP_NONE, @Enemies[30+BeeFrame]);
  212. glSpriteRotate(255-x, 191-y, Rotation * 4, GL_FLIP_H, @Enemies[84]);
  213. glSpriteRotate(255-x, y, -Rotation, GL_FLIP_V, @Enemies[32]);
  214. glSpriteRotate( x, 191-y, -Rotation * 3, GL_FLIP_H or GL_FLIP_V, @Enemies[81]);
  215. // Some phoenix enemies on the right
  216. // Note the flipmodes
  217. // Also shows how we can draw in "color mode" and shadow mode
  218. glSprite(200, 30, GL_FLIP_NONE, @Enemies[87 + PhoenixFrame]);
  219. glColor( RGB15(31,0,0) );
  220. glSprite(200, 60, GL_FLIP_H, @Enemies[87 + PhoenixFrame]);
  221. // Make the last two sprites translucent
  222. glPolyFmt(POLY_ALPHA(20) or POLY_CULL_NONE or POLY_ID(1));
  223. glColor( RGB15(0,31,20) );
  224. glSprite(200, 90, GL_FLIP_V, @Enemies[87 + PhoenixFrame]);
  225. glColor( RGB15(0,0,0) );
  226. glSprite(200, 130, GL_FLIP_V or GL_FLIP_H , @Enemies[87 + PhoenixFrame]);
  227. //Restore color and translucency to normal
  228. glColor( RGB15(31,31,31) );
  229. glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE );
  230. // Offset the angle by -PI/2 since Patater's
  231. // Original sprite faces upwards
  232. glSpriteRotate( sx, sy, angle - (BRAD_PI div 2), GL_FLIP_NONE, @Shuttle);
  233. // Make the flyer translucent just for kicks
  234. glPolyFmt(POLY_ALPHA(20) or POLY_CULL_NONE or POLY_ID(2));
  235. glSpriteRotateScaleXY(SCREEN_WIDTH div 2, SCREEN_HEIGHT div 2, Frame * 140, sinLerp(Frame * 120) * 3, sinLerp(Frame * 210) * 2, GL_FLIP_NONE, @Flyer);
  236. // Restore to normal rendering just to be safe
  237. glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE );
  238. glEnd2D();
  239. glFlush( 0 );
  240. swiWaitForVBlank();
  241. end;
  242. end.