Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*===========================================
- GRRLIB (GX Version)
- - Template Code -
- Minimum Code To Use GRRLIB
- ============================================*/
- #include <grrlib.h>
- #include <stdlib.h>
- #include <wiiuse/wpad.h>
- #include "custcolors.h"
- #include "objects.h"
- #include "font.h"
- #include "font.c"
- extern const unsigned char font[];
- extern const int font_size;
- struct cursor
- {
- int x;
- int y;
- int rot;
- };
- struct gametile
- {
- unsigned char chunk_id;
- GRRLIB_texImg *tile_bottom; // this is the backgrond tile
- GRRLIB_texImg *tile_top; // this is the foreground tile
- GRRLIB_texImg *tile_col; // this one will be used for collision
- };
- /*----------------------------------------------------------------------
- These level index collapse/uncollapse functions were provided by GerbilSoft from Sonic Retro,
- they're for turning 2d tile coordinates into a 1d level array value and vice-versa
- ----------------------------------------------------------------------*/
- inline int rowcolToIdx(int row, int col)
- {
- return (col + (row * 256));
- }
- inline int rowFromIdx(int idx)
- {
- return (idx >> 8);
- }
- inline int colFromIdx(int idx)
- {
- return (idx & 0xFF);
- }
- /*----------------------------------------------------------------------
- LoadMap() is a direct hack from PieChart at the moment. Remember that the new level format
- is a series of horizontal tiles and wraps every 256 entries. It'll also probably need to be
- split somehow to load object layouts as well. tilearray[] is the series of u8 values for
- tileID's that make up the level. tuledata[] is the struct that holds all of the PNG images
- for each tile.
- -----------------------------------------------------------------------*/
- struct gametile tiledata[256]; // This holds the tile structure data
- u8 tilearray[10][256];
- bool LoadMap(u8 level)
- {
- u16 h;
- FILE *leveldata;
- //u8 levelarray[2560];
- char levelpath[35];
- char FG_path[35];
- char BG_path[35];
- char COL_path[35];
- char sizemessage[30];
- unsigned short filesize;
- GRRLIB_texImg *tex_load = GRRLIB_LoadTextureFromFile("images/loading.png");
- GRRLIB_ttfFont *error_font = GRRLIB_LoadTTF(font, font_size);
- sprintf(levelpath,"sd:/apps/SonicWii/maps/%d/%d.bin", level, level);
- GRRLIB_FillScreen(GRRLIB_BLACK);
- GRRLIB_DrawImg(140, 300, tex_load, 0,1,1,GRRLIB_WHITE);
- GRRLIB_Render();
- leveldata = fopen(levelpath, "rb");
- if (leveldata == NULL)
- {
- while(1)
- {
- WPAD_ScanPads();
- GRRLIB_FillScreen(GRRLIB_BLACK);
- GRRLIB_PrintfTTF(90,90, error_font, "Error Loading Map", 18, GRRLIB_WHITE);
- GRRLIB_PrintfTTF(90,110, error_font, levelpath, 18, GRRLIB_WHITE);
- GRRLIB_PrintfTTF(90,130, error_font, "Press [HOME] to exit.", 14, GRRLIB_WHITE);
- if (WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_HOME)
- {
- GRRLIB_Exit();
- exit(0);
- }
- GRRLIB_Render();
- }
- return false; // error protection, file didn't load
- }
- /*if (false) // old tile debugging routine. Use for checking GRRLIB_LoadTextureFromFile
- {
- tile_error:
- while(1)
- {
- WPAD_ScanPads();
- GRRLIB_FillScreen(GRRLIB_BLACK);
- GRRLIB_PrintfTTF(90,90, error_font, "Error Loading Tile", 18, GRRLIB_WHITE);
- GRRLIB_PrintfTTF(90,110, error_font, COL_path, 18, GRRLIB_WHITE);
- GRRLIB_PrintfTTF(90,130, error_font, "Press [HOME] to exit.", 14, GRRLIB_WHITE);
- if (WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_HOME)
- {
- GRRLIB_Exit();
- exit(0);
- }
- GRRLIB_Render();
- }
- return false; // error protection, file didn't load
- }*/
- fseek(leveldata, 0 , SEEK_END);
- filesize = ftell(leveldata);
- if (ftell(leveldata) != 0xa00)
- {
- sprintf(sizemessage,"filesize is %d, expected 2560", filesize);
- while(1)
- {
- WPAD_ScanPads();
- GRRLIB_FillScreen(GRRLIB_BLACK);
- GRRLIB_PrintfTTF(90,90, error_font, "Error Loading Map: Size Mismatch", 18, GRRLIB_WHITE);
- GRRLIB_PrintfTTF(90,110, error_font, sizemessage, 18, GRRLIB_WHITE);
- GRRLIB_PrintfTTF(90,130, error_font, "Press [HOME] to exit.", 14, GRRLIB_WHITE);
- if (WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_HOME)
- {
- GRRLIB_Exit();
- exit(0);
- }
- GRRLIB_Render();
- }
- return false; // error protection, file didn't load
- }
- rewind(leveldata);
- fread(&tilearray, 1,2560,leveldata);
- /*for(h=0;h < 2560;h++)
- {
- tilearray[h] = levelarray[h];// walk through file byte by byte and assign tile ID's accordingly
- }*/
- for(h=0; h <= 255; h++)
- {
- sprintf(COL_path,"maps/%d/%02d.png", level, h);
- tiledata[h].chunk_id = h;
- if (GRRLIB_LoadTextureFromFile(COL_path) != NULL)
- {
- tiledata[h].tile_col = GRRLIB_LoadTextureFromFile(COL_path);
- //GRRLIB_InitTileSet(tiledata[h].tile_col, 256, 256, 0);
- }
- /*tiledata[h].tile_top = GRRLIB_CreateEmptyTexture(2,2);
- tiledata[h].tile_bottom = GRRLIB_CreateEmptyTexture(2,2);*/
- }
- fclose(leveldata);
- return true;
- }
- /*------------------------------------------------------------------------------------------
- ProcessPlayer()
- ----------------
- All of the player's physics and collision calculations will be processed by this function.
- First, the player's state gets passed to a switch statement that decides wether to apply air
- physics, ground physics, etc.
- -------------------------------------------------------------------------------------------*/
- void ProcessPlayer(struct PLAYEROBJ *player)
- {
- enum player_states playerstate;
- player->gnd_speed = player->x_speed + player->y_speed;
- switch(playerstate)
- {
- case(PLAYER_GROUND): // All ground physics/collision calcs go here.
- if ((WPAD_ButtonsUp(0) & WIIMOTE_BUTTON_UP) && (WPAD_ButtonsUp(0) & WIIMOTE_BUTTON_DOWN))
- {
- // no D-Pad input, we need to apply surface friction value
- // We'll also need to add Collision checks here and at the D-Pad hold to make sure
- // sonic doesn't go out of bounds
- if (abs(player->x_speed) < FRICTION) player->x_speed = 0;
- else if (player->x_speed < 0) player->x_speed = player->x_speed += (FRICTION*-1);
- else if (player->x_speed > 0) player->x_speed = player->x_speed += (FRICTION*1);
- }
- if (WPAD_ButtonsHeld(0) & WIIMOTE_BUTTON_UP)
- {
- /* we're holding left on the D-Pad. First we'll need to check our ground speed is
- over the limit, then if it isn't, start adding acceleration to the x_speed value.
- We'll also want to branch out of this if collision to the left returns true.*/
- if (abs(player->x_speed) > MAXSPEED)
- {
- if (player->x_speed > 0) player->x_speed = MAXSPEED;
- if (player->x_speed < 0) player->x_speed = NEG_MAXSPD;
- }
- if ((player->x_speed != MAXSPEED) && (player->x_speed != NEG_MAXSPD))
- {
- if (player->x_speed > 0) player->x_speed += DECELERATION;
- if (player->x_speed < 0) player->x_speed -= ACCELERATION;
- }
- } else if (WPAD_ButtonsHeld(0) & WIIMOTE_BUTTON_DOWN)
- {
- /* we're holding right on the D-Pad. First we'll need to check our ground speed is
- over the limit, then if it isn't, start adding acceleration to the x_speed value.
- We'll also want to branch out of this if collision to the left returns true.*/
- if (abs(player->x_speed) > MAXSPEED)
- {
- if (player->x_speed > 0) player->x_speed = MAXSPEED;
- if (player->x_speed < 0) player->x_speed = NEG_MAXSPD;
- }
- if ((player->x_speed != MAXSPEED) && (player->x_speed != NEG_MAXSPD))
- {
- if (player->x_speed < 0) player->x_speed += DECELERATION;
- if (player->x_speed > 0) player->x_speed -= ACCELERATION;
- }
- }
- break; // Done with ground physics
- case(PLAYER_AIR): // All player air physics/collision goes here
- break;
- case(PLAYER_LEFT_WALL): // player left wall physics
- break;
- case(PLAYER_RIGHT_WALL): // player right wall physics
- break;
- case(PLAYER_CEILING): // player right wall physics
- break;
- default: // insert some error handling here, as this state is 'unreachable'
- break;
- }
- }
- /*---------------------------------------------------------------------------------
- GameLoop() is where most of the real action happens, all of the game's runtime calculations
- occur here or are initiated here. Expect this function to change the most. The first thing
- we need to do is to load all of P1's graphics. Don't forget that the wii's screen real
- estate is 640x480, approximately double the Genesis' 320x244, with some black bars
- on top for proper aspect ratio keeping.
- -----------------------------------------------------------------------------------*/
- void GameLoop()
- {
- ir_t ir;
- u8 level=1;
- // sonic
- GRRLIB_texImg *tex_sonic_walk = GRRLIB_LoadTextureFromFile("images/sonic/sonic_walk.png");
- GRRLIB_texImg *tex_sonic_stand = GRRLIB_LoadTextureFromFile("images/sonic/sonic_stand.png");
- GRRLIB_texImg *tex_sonic_ball = GRRLIB_LoadTextureFromFile("images/sonic/sonic_ball.png");
- GRRLIB_texImg *tex_sonic_run = GRRLIB_LoadTextureFromFile("images/sonic/sonic_run.png");
- GRRLIB_InitTileSet(tex_sonic_walk, 80, 80, 0);
- GRRLIB_InitTileSet(tex_sonic_stand, 80, 80, 0);
- GRRLIB_InitTileSet(tex_sonic_ball, 80, 80, 0);
- GRRLIB_InitTileSet(tex_sonic_run, 80, 80, 0);
- unsigned int count;
- struct CAMOBJ camera;
- struct PLAYEROBJ sonic_obj;
- sonic_obj.score = 0;
- sonic_obj.lives = 4;
- sonic_obj.anim = 0;
- sonic_obj.frame = 0;
- sonic_obj.x_coord = 368;
- sonic_obj.y_coord = 434;
- // ring
- GRRLIB_texImg *tex_ring = GRRLIB_LoadTextureFromFile("images/ring.png");
- GRRLIB_ttfFont *font1 = GRRLIB_LoadTTF(font, font_size);
- GRRLIB_texImg *tex_pointer = GRRLIB_LoadTextureFromFile("images/cursor.png");
- // cursor for collision picking
- struct cursor pointer;
- pointer.x=200;
- pointer.y=200;
- /*----------------======Game Variables=========----------------------*/
- unsigned int tickcounter=0;
- u8 framecounter=0;
- u8 secondcounter=0;
- unsigned int minutecounter=0;
- char time_string[15]="";
- char debug_ln1[30]="";
- char debug_ln2[30]="";
- char debug_ln3[30]="";
- char debug_ln4[30]="";
- bool debugflag=false;
- bool mapflag=false;
- camera.x=6;
- camera.y=222;
- sonic_obj.score = 0;
- sonic_obj.rings = 0;
- sprintf(sonic_obj.score_string, "Score: %d", sonic_obj.score);
- sprintf(sonic_obj.ring_string, "Rings: %d", sonic_obj.rings);
- /*----------------======END Game Variables=====-----------------------*/
- /*----------------=======Level Processing=====------------------------*/
- unsigned int vis_tiles[4][4];
- unsigned int first_tile[2];
- unsigned int x_current,y_current;
- unsigned short h,v;
- LoadMap(level);
- /*---------------------=========END level processing====----------------------------*/
- // Done loading, begin game loop.
- while(1)
- {
- tickcounter++;
- if (framecounter < 60) framecounter ++;
- if ((framecounter == 60) && (secondcounter < 60))
- {
- framecounter = 0;
- secondcounter++;
- }
- if ((framecounter == 60) && (secondcounter == 60))
- {
- framecounter = 0;
- secondcounter = 0;
- minutecounter++;
- }
- /*------------====Control Collection/Gameplay Calc=====-------------
- Obviously comes before drawing =P
- --------------------------------------------------------------------*/
- WPAD_ScanPads(); // Scan the Wiimotes
- WPAD_IR(WPAD_CHAN_0, &ir);
- pointer.x = ir.x;
- pointer.y = ir.y;
- if ((WPAD_ButtonsHeld(0) & WPAD_BUTTON_RIGHT) && (camera.y >= 1)) camera.y--;
- else if ((WPAD_ButtonsHeld(0) & WPAD_BUTTON_RIGHT) && (camera.y == 0)) camera.y = 0;
- if (WPAD_ButtonsHeld(0) & WPAD_BUTTON_LEFT) camera.y++;
- if ((WPAD_ButtonsHeld(0) & WPAD_BUTTON_UP) && (camera.x >= 1)) camera.x--;
- else if((WPAD_ButtonsHeld(0) & WPAD_BUTTON_UP) && (camera.x == 0)) camera.x = 0;
- if (WPAD_ButtonsHeld(0) & WPAD_BUTTON_DOWN) camera.x++;
- if ((WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_ONE)) debugflag = !debugflag;
- if (WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_TWO) mapflag = true;
- /*--------------========END game calc===========--------------------*/
- GRRLIB_FillScreen(GRRLIB_BLACK);
- /*---------------------------------------------------------------
- Map drawing will need to be split into 2 different passes, so that the characters can
- be drawn inbetween the 2 layers. This is the first of 2 passes. At any given time, 16
- tiles will be in the level renderer. To figure out which tiles to draw and how far to
- offset them, we'll need to use the camera's coordinates and divide by 256 to find our
- starting tile. The rest can be filled in automatically, as each line is 4 tiles long.
- 4 arrays were created for holding this render queue, named "vis_tiles_x[4]"
- respectively. A member of CAMOBJ called in_tile was added for computing where in the
- main tile array to search.
- -------------------------------------------------------------------*/
- // first we fill our screen cache
- camera.in_tile[0] = camera.x/256; // row
- camera.in_tile[1] = camera.y/256; // column
- first_tile[0] = camera.in_tile[0];
- first_tile[1] = camera.in_tile[1];
- for(h=0; h < 4; h++) // first row
- {
- for(v=0; v < 4; v++)
- {
- vis_tiles[h][v] = tilearray[first_tile[1] + v][first_tile[0] + h];
- }
- }
- // this is the actual display loop, first pass
- for(h = 0; h < 4; h++)
- {
- for(v=0; v < 4; v++)
- {
- x_current = (first_tile[0] + h) * 256;
- y_current = (first_tile[1] + v) * 256;
- GRRLIB_DrawImg(x_current - camera.x, y_current - camera.y, tiledata[vis_tiles[h][v]].tile_col, 0, 1, 1, GRRLIB_WHITE);
- }
- }
- // Draw Sonic
- 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);
- GRRLIB_Rectangle(pointer.x, pointer.y, 4, 4, GRRLIB_RED, true);
- // second level render pass goes here.
- // Drawing HUD - this will need to get moved to the end of the drawchain to show up
- // on top of everything else
- sprintf(time_string, "Time: %d:%d:%d", minutecounter,secondcounter,framecounter);
- GRRLIB_PrintfTTF(32,32, font1, sonic_obj.score_string, 26, GRRLIB_WHITE);
- GRRLIB_PrintfTTF(32,64, font1, time_string, 26, GRRLIB_WHITE);
- GRRLIB_PrintfTTF(32,98, font1, sonic_obj.ring_string, 26, GRRLIB_WHITE);
- if ((debugflag == true) && (mapflag == false))
- {
- sprintf(debug_ln1, "x: %d", camera.x);
- sprintf(debug_ln2, "y: %d", camera.y);
- sprintf(debug_ln3, "it: %d:%d | %d x %d", camera.in_tile[0], camera.in_tile[1], (camera.x % 256), (camera.y % 256));
- GRRLIB_PrintfTTF(420,32, font1, debug_ln1, 18, GRRLIB_RED);
- GRRLIB_PrintfTTF(420,64, font1, debug_ln2, 18, GRRLIB_RED);
- GRRLIB_PrintfTTF(420,98, font1, debug_ln3, 18, GRRLIB_RED);
- }
- while (mapflag == true)
- {
- WPAD_ScanPads();
- debugflag = false;
- sprintf(debug_ln1, "%d | %d | %d | %d", vis_tiles[0][0], vis_tiles[1][0], vis_tiles[2][0], vis_tiles[3][0]);
- sprintf(debug_ln2, "%d | %d | %d | %d", vis_tiles[0][1], vis_tiles[1][1], vis_tiles[2][1], vis_tiles[3][1]);
- sprintf(debug_ln3, "%d | %d | %d | %d", vis_tiles[0][2], vis_tiles[1][2], vis_tiles[2][2], vis_tiles[3][2]);
- sprintf(debug_ln4, "%d | %d | %d | %d", vis_tiles[0][3], vis_tiles[1][3], vis_tiles[2][3], vis_tiles[3][3]);
- GRRLIB_PrintfTTF(50,32, font1, debug_ln1, 22, GRRLIB_WHITE);
- GRRLIB_PrintfTTF(50,64, font1, debug_ln2, 22, GRRLIB_WHITE);
- GRRLIB_PrintfTTF(50,98, font1, debug_ln3, 22, GRRLIB_WHITE);
- //GRRLIB_PrintfTTF(50,130, font1, debug_ln4, 22, GRRLIB_WHITE);
- if (WPAD_ButtonsHeld(0) & WIIMOTE_BUTTON_ONE)
- {
- mapflag = false;
- break;
- } else if (WPAD_ButtonsHeld(0) & WPAD_BUTTON_HOME)
- {
- GRRLIB_Exit();
- exit(0);
- }
- GRRLIB_Render();
- }
- if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) break;
- if (WPAD_ButtonsDown(0) & WIIMOTE_BUTTON_A) GRRLIB_ScrShot("screenshot.png");
- GRRLIB_Render();
- }
- return;
- }
- int main(int argc, char **argv)
- {
- // Initialise the Graphics & Video subsystem
- GRRLIB_Init();
- // Initialise the Wiimotes
- WPAD_Init();
- WPAD_SetDataFormat(WPAD_CHAN_0, WPAD_FMT_BTNS_ACC_IR);
- GameLoop();
- GRRLIB_Exit(); // Be a good boy, clear the memory allocated by GRRLIB
- exit(0); // Use exit() to exit a program, do not use 'return' from main()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement