Advertisement
Guest User

Untitled

a guest
Nov 19th, 2010
279
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.80 KB | None | 0 0
  1. /*===========================================
  2. GRRLIB (GX Version)
  3. - Template Code -
  4.  
  5. Minimum Code To Use GRRLIB
  6. ============================================*/
  7. #include <grrlib.h>
  8.  
  9. #include <stdlib.h>
  10. #include <wiiuse/wpad.h>
  11.  
  12. #include "custcolors.h"
  13. #include "objects.h"
  14. #include "font.h"
  15. #include "font.c"
  16.  
  17. extern const unsigned char font[];
  18. extern const int font_size;
  19.  
  20. struct cursor
  21. {
  22. int x;
  23. int y;
  24. int rot;
  25. };
  26.  
  27. struct gametile
  28. {
  29. unsigned char chunk_id;
  30. GRRLIB_texImg *tile_bottom; // this is the backgrond tile
  31. GRRLIB_texImg *tile_top; // this is the foreground tile
  32. GRRLIB_texImg *tile_col; // this one will be used for collision
  33. };
  34.  
  35. /*----------------------------------------------------------------------
  36. These level index collapse/uncollapse functions were provided by GerbilSoft from Sonic Retro,
  37. they're for turning 2d tile coordinates into a 1d level array value and vice-versa
  38. ----------------------------------------------------------------------*/
  39.  
  40. inline int rowcolToIdx(int row, int col)
  41. {
  42. return (col + (row * 256));
  43. }
  44.  
  45. inline int rowFromIdx(int idx)
  46. {
  47. return (idx >> 8);
  48. }
  49.  
  50. inline int colFromIdx(int idx)
  51. {
  52. return (idx & 0xFF);
  53. }
  54.  
  55. /*----------------------------------------------------------------------
  56. LoadMap() is a direct hack from PieChart at the moment. Remember that the new level format
  57. is a series of horizontal tiles and wraps every 256 entries. It'll also probably need to be
  58. split somehow to load object layouts as well. tilearray[] is the series of u8 values for
  59. tileID's that make up the level. tuledata[] is the struct that holds all of the PNG images
  60. for each tile.
  61. -----------------------------------------------------------------------*/
  62.  
  63. struct gametile tiledata[255]; // This holds the tile data
  64. u8 tilearray[2560]; // every 256 entries is one 'row', making for 10 rows total.
  65.  
  66. bool LoadMap(u8 level)
  67. {
  68. u16 h;
  69. FILE *leveldata;
  70. //u8 levelarray[2560];
  71. char levelpath[35];
  72. char FG_path[35];
  73. char BG_path[35];
  74. char COL_path[35];
  75. char sizemessage[30];
  76. unsigned short filesize;
  77.  
  78. GRRLIB_ttfFont *error_font = GRRLIB_LoadTTF(font, font_size);
  79.  
  80. sprintf(levelpath,"sd:/apps/SonicWii/maps/%d/%d.bin", level, level);
  81.  
  82. leveldata = fopen(levelpath, "rb");
  83.  
  84. if (leveldata == NULL)
  85. {
  86. while(1)
  87. {
  88. WPAD_ScanPads();
  89. GRRLIB_FillScreen(GRRLIB_BLACK);
  90. GRRLIB_PrintfTTF(90,90, error_font, "Error Loading Map", 18, GRRLIB_WHITE);
  91. GRRLIB_PrintfTTF(90,110, error_font, levelpath, 18, GRRLIB_WHITE);
  92. GRRLIB_PrintfTTF(90,130, error_font, "Press [HOME] to exit.", 14, GRRLIB_WHITE);
  93.  
  94. if (WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_HOME)
  95. {
  96. GRRLIB_Exit();
  97. exit(0);
  98. }
  99. GRRLIB_Render();
  100. }
  101. return false; // error protection, file didn't load
  102. }
  103.  
  104. /*if (false) // old tile debugging routine. Use for checking GRRLIB_LoadTextureFromFile
  105. {
  106. tile_error:
  107. while(1)
  108. {
  109. WPAD_ScanPads();
  110. GRRLIB_FillScreen(GRRLIB_BLACK);
  111. GRRLIB_PrintfTTF(90,90, error_font, "Error Loading Tile", 18, GRRLIB_WHITE);
  112. GRRLIB_PrintfTTF(90,110, error_font, COL_path, 18, GRRLIB_WHITE);
  113. GRRLIB_PrintfTTF(90,130, error_font, "Press [HOME] to exit.", 14, GRRLIB_WHITE);
  114.  
  115. if (WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_HOME)
  116. {
  117. GRRLIB_Exit();
  118. exit(0);
  119. }
  120. GRRLIB_Render();
  121. }
  122. return false; // error protection, file didn't load
  123. }*/
  124.  
  125. fseek(leveldata, 0 , SEEK_END);
  126. filesize = ftell(leveldata);
  127. if (ftell(leveldata) != 0xa00)
  128. {
  129. sprintf(sizemessage,"filesize is %d, expected 2560", filesize);
  130. while(1)
  131. {
  132. WPAD_ScanPads();
  133. GRRLIB_FillScreen(GRRLIB_BLACK);
  134. GRRLIB_PrintfTTF(90,90, error_font, "Error Loading Map: Size Mismatch", 18, GRRLIB_WHITE);
  135. GRRLIB_PrintfTTF(90,110, error_font, sizemessage, 18, GRRLIB_WHITE);
  136. GRRLIB_PrintfTTF(90,130, error_font, "Press [HOME] to exit.", 14, GRRLIB_WHITE);
  137.  
  138. if (WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_HOME)
  139. {
  140. GRRLIB_Exit();
  141. exit(0);
  142. }
  143. GRRLIB_Render();
  144. }
  145. return false; // error protection, file didn't load
  146. }
  147.  
  148. rewind(leveldata);
  149. fread(&tilearray, 1,2560,leveldata);
  150.  
  151. /*for(h=0;h < 2560;h++)
  152. {
  153. tilearray[h] = levelarray[h];// walk through file byte by byte and assign tile ID's accordingly
  154. }*/
  155.  
  156. for(h=0; h <= 255; h++)
  157. {
  158. sprintf(COL_path,"maps/%d/%02d.png", level, h);
  159. tiledata[h].chunk_id = h;
  160. if (GRRLIB_LoadTextureFromFile(COL_path) != NULL)
  161. {
  162. tiledata[h].tile_col = GRRLIB_LoadTextureFromFile(COL_path);
  163. //GRRLIB_InitTileSet(tiledata[h].tile_col, 256, 256, 0);
  164. }
  165. /*tiledata[h].tile_top = GRRLIB_CreateEmptyTexture(2,2);
  166. tiledata[h].tile_bottom = GRRLIB_CreateEmptyTexture(2,2);*/
  167. }
  168.  
  169. fclose(leveldata);
  170. return true;
  171. }
  172.  
  173. /*------------------------------------------------------------------------------------------
  174. ProcessPlayer()
  175. ----------------
  176. All of the player's physics and collision calculations will be processed by this function.
  177. First, the player's state gets passed to a switch statement that decides wether to apply air
  178. physics, ground physics, etc.
  179. -------------------------------------------------------------------------------------------*/
  180.  
  181. void ProcessPlayer(struct PLAYEROBJ *player)
  182. {
  183. enum player_states playerstate;
  184.  
  185. player->gnd_speed = player->x_speed + player->y_speed;
  186.  
  187. switch(playerstate)
  188. {
  189. case(PLAYER_GROUND): // All ground physics/collision calcs go here.
  190. if ((WPAD_ButtonsUp(0) & WIIMOTE_BUTTON_UP) && (WPAD_ButtonsUp(0) & WIIMOTE_BUTTON_DOWN))
  191. {
  192. // no D-Pad input, we need to apply surface friction value
  193. // We'll also need to add Collision checks here and at the D-Pad hold to make sure
  194. // sonic doesn't go out of bounds
  195. if (abs(player->x_speed) < FRICTION) player->x_speed = 0;
  196. else if (player->x_speed < 0) player->x_speed = player->x_speed += (FRICTION*-1);
  197. else if (player->x_speed > 0) player->x_speed = player->x_speed += (FRICTION*1);
  198. }
  199.  
  200. if (WPAD_ButtonsHeld(0) & WIIMOTE_BUTTON_UP)
  201. {
  202. /* we're holding left on the D-Pad. First we'll need to check our ground speed is
  203. over the limit, then if it isn't, start adding acceleration to the x_speed value.
  204. We'll also want to branch out of this if collision to the left returns true.*/
  205. if (abs(player->x_speed) > MAXSPEED)
  206. {
  207. if (player->x_speed > 0) player->x_speed = MAXSPEED;
  208. if (player->x_speed < 0) player->x_speed = NEG_MAXSPD;
  209. }
  210.  
  211. if ((player->x_speed != MAXSPEED) && (player->x_speed != NEG_MAXSPD))
  212. {
  213. if (player->x_speed > 0) player->x_speed += DECELERATION;
  214. if (player->x_speed < 0) player->x_speed -= ACCELERATION;
  215. }
  216. } else if (WPAD_ButtonsHeld(0) & WIIMOTE_BUTTON_DOWN)
  217. {
  218. /* we're holding right on the D-Pad. First we'll need to check our ground speed is
  219. over the limit, then if it isn't, start adding acceleration to the x_speed value.
  220. We'll also want to branch out of this if collision to the left returns true.*/
  221. if (abs(player->x_speed) > MAXSPEED)
  222. {
  223. if (player->x_speed > 0) player->x_speed = MAXSPEED;
  224. if (player->x_speed < 0) player->x_speed = NEG_MAXSPD;
  225. }
  226.  
  227. if ((player->x_speed != MAXSPEED) && (player->x_speed != NEG_MAXSPD))
  228. {
  229. if (player->x_speed < 0) player->x_speed += DECELERATION;
  230. if (player->x_speed > 0) player->x_speed -= ACCELERATION;
  231. }
  232. }
  233. break; // Done with ground physics
  234.  
  235. case(PLAYER_AIR): // All player air physics/collision goes here
  236. break;
  237.  
  238. case(PLAYER_LEFT_WALL): // player left wall physics
  239. break;
  240.  
  241. case(PLAYER_RIGHT_WALL): // player right wall physics
  242. break;
  243.  
  244. case(PLAYER_CEILING): // player right wall physics
  245. break;
  246.  
  247. default: // insert some error handling here, as this state is 'unreachable'
  248. break;
  249. }
  250. }
  251.  
  252. /*---------------------------------------------------------------------------------
  253. GameLoop() is where most of the real action happens, all of the game's runtime calculations
  254. occur here or are initiated here. Expect this function to change the most. The first thing
  255. we need to do is to load all of P1's graphics. Don't forget that the wii's screen real
  256. estate is 640x480, approximately double the Genesis' 320x244, with some black bars
  257. on top for proper aspect ratio keeping.
  258. -----------------------------------------------------------------------------------*/
  259. void GameLoop()
  260. {
  261. ir_t ir;
  262. u8 level=1;
  263.  
  264. // sonic
  265. GRRLIB_texImg *tex_sonic_walk = GRRLIB_LoadTextureFromFile("images/sonic/sonic_walk.png");
  266. GRRLIB_texImg *tex_sonic_stand = GRRLIB_LoadTextureFromFile("images/sonic/sonic_stand.png");
  267. GRRLIB_texImg *tex_sonic_ball = GRRLIB_LoadTextureFromFile("images/sonic/sonic_ball.png");
  268. GRRLIB_texImg *tex_sonic_run = GRRLIB_LoadTextureFromFile("images/sonic/sonic_run.png");
  269. GRRLIB_InitTileSet(tex_sonic_walk, 80, 80, 0);
  270. GRRLIB_InitTileSet(tex_sonic_stand, 80, 80, 0);
  271. GRRLIB_InitTileSet(tex_sonic_ball, 80, 80, 0);
  272. GRRLIB_InitTileSet(tex_sonic_run, 80, 80, 0);
  273. unsigned int count;
  274. struct CAMOBJ camera;
  275. struct PLAYEROBJ sonic_obj;
  276. sonic_obj.score = 0;
  277. sonic_obj.lives = 4;
  278. sonic_obj.anim = 0;
  279. sonic_obj.frame = 0;
  280. sonic_obj.x_coord = 77;
  281. sonic_obj.y_coord = 446;
  282.  
  283. // ring
  284. GRRLIB_texImg *tex_ring = GRRLIB_LoadTextureFromFile("images/ring.png");
  285. GRRLIB_ttfFont *font1 = GRRLIB_LoadTTF(font, font_size);
  286. GRRLIB_texImg *tex_pointer = GRRLIB_LoadTextureFromFile("images/cursor.png");
  287.  
  288. // cursor for collision picking
  289. struct cursor pointer;
  290. pointer.x=200;
  291. pointer.y=200;
  292.  
  293. /*----------------======Game Variables=========----------------------*/
  294. unsigned int tickcounter=0;
  295. u8 framecounter=0;
  296. u8 secondcounter=0;
  297. unsigned int minutecounter=0;
  298. char score_string[18]="";
  299. char time_string[15]="";
  300. char ring_string[11]="";
  301. char debug_ln1[30]="";
  302. char debug_ln2[30]="";
  303. char debug_ln3[30]="";
  304. char debug_ln4[30]="";
  305. bool debugflag=false;
  306. bool mapflag=false;
  307. camera.x=6;
  308. camera.y=222;
  309. /*----------------======END Game Variables=====-----------------------*/
  310.  
  311.  
  312. /*----------------=======Level Processing=====------------------------*/
  313. unsigned int vis_tiles_1[3];
  314. unsigned int vis_tiles_2[3];
  315. unsigned int vis_tiles_3[3];
  316. unsigned int vis_tiles_4[3];
  317. unsigned int first_tile;
  318. unsigned int x_current,y_current;
  319. unsigned short h;
  320. LoadMap(level);
  321. /*---------------------=========END level processing====----------------------------*/
  322.  
  323. // Done loading, begin game loop.
  324. while(1)
  325. {
  326. tickcounter++;
  327.  
  328. if (framecounter < 60) framecounter ++;
  329.  
  330. if ((framecounter == 60) && (secondcounter < 60))
  331. {
  332. framecounter = 0;
  333. secondcounter++;
  334. }
  335.  
  336. if ((framecounter == 60) && (secondcounter == 60))
  337. {
  338. framecounter = 0;
  339. secondcounter = 0;
  340. minutecounter++;
  341. }
  342.  
  343. /*------------====Control Collection/Gameplay Calc=====-------------
  344. Obviously comes before drawing =P
  345. --------------------------------------------------------------------*/
  346. WPAD_ScanPads(); // Scan the Wiimotes
  347. WPAD_IR(WPAD_CHAN_0, &ir);
  348.  
  349. pointer.x = ir.x;
  350. pointer.y = ir.y;
  351.  
  352. if (WPAD_ButtonsHeld(0) & WPAD_BUTTON_RIGHT) camera.y--;
  353. if (WPAD_ButtonsHeld(0) & WPAD_BUTTON_LEFT) camera.y++;
  354. if (WPAD_ButtonsHeld(0) & WPAD_BUTTON_UP) camera.x--;
  355. if (WPAD_ButtonsHeld(0) & WPAD_BUTTON_DOWN) camera.x++;
  356.  
  357. if ((WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_ONE) && (debugflag == false)) debugflag = true;
  358. else if ((WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_ONE) && (debugflag == true)) debugflag = false;
  359.  
  360. if (WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_TWO) mapflag = true;
  361.  
  362. /*--------------========END game calc===========--------------------*/
  363.  
  364. GRRLIB_FillScreen(GRRLIB_BLACK);
  365.  
  366. /*---------------------------------------------------------------
  367. Map drawing will need to be split into 2 different passes, so that the characters can
  368. be drawn inbetween the 2 layers. This is the first of 2 passes. At any given time, 16
  369. tiles will be in the level renderer. To figure out which tiles to draw and how far to
  370. offset them, we'll need to use the camera's coordinates and divide by 256 to find our
  371. starting tile. The rest can be filled in automatically, as each line is 4 tiles long.
  372. 4 arrays were created for holding this render queue, named "vis_tiles_x[4]"
  373. respectively. A member of CAMOBJ called in_tile was added for computing where in the
  374. main tile array to search.
  375. -------------------------------------------------------------------*/
  376. // first we fill our screen cache
  377. camera.in_tile[0] = camera.x/256; // row
  378. camera.in_tile[1] = camera.y/256; // column
  379. first_tile = rowcolToIdx(camera.in_tile[0], camera.in_tile[1]);
  380.  
  381. for(h = 0; h < 4; h++) // first row
  382. {
  383. vis_tiles_1[h] = first_tile + h;
  384. }
  385.  
  386. for(h = 0; h < 4; h++) // second row
  387. {
  388. vis_tiles_2[h] = (first_tile + 256) + h;
  389. }
  390.  
  391. for(h = 0; h < 4; h++) // third row
  392. {
  393. vis_tiles_3[h] = (first_tile + 512) + h;
  394. }
  395.  
  396. for(h = 0; h < 4; h++) // fourth row
  397. {
  398. vis_tiles_4[h] = (first_tile + 768) + h;
  399. }
  400.  
  401. // this is the actual display loop, first pass
  402. for(h = 0; h < 4; h++)
  403. {
  404. x_current = rowFromIdx(vis_tiles_1[h]) * 256;
  405. y_current = colFromIdx(vis_tiles_1[h]) * 256;
  406. GRRLIB_DrawImg(x_current - camera.x, y_current - camera.y, tiledata[tilearray[vis_tiles_1[h]]].tile_col, 0, 1, 1, GRRLIB_WHITE);
  407. }
  408.  
  409. for(h = 0; h < 4; h++)
  410. {
  411. x_current = rowFromIdx(vis_tiles_2[h]) * 256;
  412. y_current = colFromIdx(vis_tiles_2[h]) * 256;
  413. GRRLIB_DrawImg(x_current - camera.x, y_current - camera.y, tiledata[tilearray[vis_tiles_2[h]]].tile_col, 0, 1, 1, GRRLIB_WHITE);
  414. }
  415.  
  416. for(h = 0; h < 4; h++)
  417. {
  418. x_current = rowFromIdx(vis_tiles_3[h]) * 256;
  419. y_current = colFromIdx(vis_tiles_3[h]) * 256;
  420. GRRLIB_DrawImg(x_current - camera.x, y_current - camera.y, tiledata[tilearray[vis_tiles_3[h]]].tile_col, 0, 1, 1, GRRLIB_WHITE);
  421. }
  422.  
  423. for(h = 0; h < 4; h++)
  424. {
  425. x_current = rowFromIdx(vis_tiles_4[h]) * 256;
  426. y_current = colFromIdx(vis_tiles_4[h]) * 256;
  427. GRRLIB_DrawImg(x_current - camera.x, y_current - camera.y, tiledata[tilearray[vis_tiles_4[h]]].tile_col, 0, 1, 1, GRRLIB_WHITE);
  428. }
  429.  
  430. // Draw Sonic
  431. GRRLIB_DrawTile(sonic_obj.x_coord - camera.x, sonic_obj.y_coord - camera.y, tex_sonic_stand, 0,1,1,GRRLIB_WHITE,sonic_obj.frame);
  432. GRRLIB_Rectangle(pointer.x, pointer.y, 80, 2, GRRLIB_RED, true);
  433.  
  434. // second level render pass goes here.
  435.  
  436. // Drawing HUD - this will need to get moved to the end of the drawchain to show up
  437. // on top of everything else
  438. sprintf(score_string, "Score: %d", sonic_obj.score);
  439. sprintf(time_string, "Time: %d:%d:%d", minutecounter,secondcounter,framecounter);
  440. sprintf(ring_string, "Rings: %d", sonic_obj.rings);
  441. GRRLIB_PrintfTTF(32,32, font1, score_string, 26, GRRLIB_WHITE);
  442. GRRLIB_PrintfTTF(32,64, font1, time_string, 26, GRRLIB_WHITE);
  443. GRRLIB_PrintfTTF(32,98, font1, ring_string, 26, GRRLIB_WHITE);
  444.  
  445. if ((debugflag == true) && (mapflag == false))
  446. {
  447. sprintf(debug_ln1, "x: %d", camera.x);
  448. sprintf(debug_ln2, "y: %d", camera.y);
  449. sprintf(debug_ln3, "tile: %d:%d | %d", camera.in_tile[0], camera.in_tile[1], first_tile);
  450. GRRLIB_PrintfTTF(420,32, font1, debug_ln1, 18, GRRLIB_WHITE);
  451. GRRLIB_PrintfTTF(420,64, font1, debug_ln2, 18, GRRLIB_WHITE);
  452. GRRLIB_PrintfTTF(420,98, font1, debug_ln3, 18, GRRLIB_WHITE);
  453. }
  454.  
  455. while (mapflag == true)
  456. {
  457. WPAD_ScanPads();
  458. debugflag = false;
  459. sprintf(debug_ln1, "%d | %d | %d | %d", vis_tiles_1[0], vis_tiles_1[1], vis_tiles_1[2], vis_tiles_1[3]);
  460. sprintf(debug_ln2, "%d | %d | %d | %d", vis_tiles_2[0], vis_tiles_2[1], vis_tiles_2[2], vis_tiles_2[3]);
  461. sprintf(debug_ln3, "%d | %d | %d | %d", vis_tiles_3[0], vis_tiles_3[1], vis_tiles_3[2], vis_tiles_3[3]);
  462. sprintf(debug_ln4, "%d | %d | %d | %d", vis_tiles_4[0], vis_tiles_4[1], vis_tiles_4[2], vis_tiles_4[3]);
  463. GRRLIB_PrintfTTF(50,32, font1, debug_ln1, 22, GRRLIB_WHITE);
  464. GRRLIB_PrintfTTF(50,64, font1, debug_ln2, 22, GRRLIB_WHITE);
  465. GRRLIB_PrintfTTF(50,98, font1, debug_ln3, 22, GRRLIB_WHITE);
  466. GRRLIB_PrintfTTF(50,130, font1, debug_ln4, 22, GRRLIB_WHITE);
  467.  
  468. if (WPAD_ButtonsHeld(0) & WIIMOTE_BUTTON_ONE)
  469. {
  470. mapflag = false;
  471. break;
  472. } else if (WPAD_ButtonsHeld(0) & WPAD_BUTTON_HOME)
  473. {
  474. GRRLIB_Exit();
  475. exit(0);
  476. }
  477.  
  478. GRRLIB_Render();
  479. }
  480.  
  481.  
  482. if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) break;
  483. if (WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_A) GRRLIB_ScrShot("screenshot.png");
  484.  
  485. GRRLIB_Render();
  486. }
  487. return;
  488. }
  489.  
  490. int main(int argc, char **argv)
  491. {
  492. // Initialise the Graphics & Video subsystem
  493. GRRLIB_Init();
  494.  
  495. // Initialise the Wiimotes
  496. WPAD_Init();
  497. WPAD_SetDataFormat(WPAD_CHAN_0, WPAD_FMT_BTNS_ACC_IR);
  498.  
  499. GameLoop();
  500.  
  501. GRRLIB_Exit(); // Be a good boy, clear the memory allocated by GRRLIB
  502.  
  503. exit(0); // Use exit() to exit a program, do not use 'return' from main()
  504. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement