// INCLUDES #include "mygba.h" #include "modules.h" // IMAGE INCLUDES //////////////////////////////////////////////////////////////////////// // palettes #include "gfx/master.pal.c" // master palette // images #include "gfx/ptr.raw.c" // menu pointer #include "gfx/main_menu_start.raw.c" // Main menu 'start' icon #include "gfx/main_menu_help.raw.c" // Main menu 'help' icon #include "gfx/main_menu_quit.raw.c" // Main menu 'quit' icon #include "gfx/enemy_frigate.raw.c" // Enemy frigate ship #include "gfx/ally_frigate.raw.c" // Ally frigate ship #include "gfx/enemy_laser.raw.c" // Enemy laser #include "gfx/ally_laser.raw.c" // Ally laser // DEFINES /////////////////////////////////////////////////////////////////////////////// #define NUM_SPRITES 128 #define GAME_STATE_INIT 1 #define GAME_STATE_MENU 2 #define GAME_STATE_GAME_INIT 3 #define GAME_STATE_RUN 4 #define GAME_STATE_SHUTDOWN 256 #define NUM_ENEMIES 10 // STRUCTURES //////////////////////////////////////////////////////////////////////////// typedef struct enemy { s16 x, y; s16 dx, dy; // speed u32 state; bool alive; u8 sprite; u32 curr_anim; bool visible; u8 sclass; u32 hp; u32 weaponid; } enemy, *enemy_ptr; typedef struct player { s32 x, y; // x & y pos u32 state; // state (destroy, etc) bool alive; // alive? u32 sprite; // sprite # x/128 u32 curr_anim; // current animation # bool visible; // visible? char *charname; // character name u8 sclass; // ship class u32 hp, sp, lp; // hitpoints, shield power, laser power } player, *player_ptr; typedef struct laser { u8 x, y, id, isally, lx, ly; } laser, *laser_ptr; typedef struct menu { int selected; // currently selected item int contents[9]; // items char names[9]; // names for each item u8 x, y; // x and y coords. } menu, *menu_ptr; // VARIABLES ///////////////////////////////////////////////////////////////////////////// int game_state = GAME_STATE_INIT; // for Game_Main bool new_frame; // For vblFunc bool inBitmapMode = FALSE; // for the bitmap mode clear functions u8 menu_ptr_x = 2, menu_ptr_y = 25; // menu pointers u8 num_lasers = 0; // OBJECTS /////////////////////////////////////////////////////////////////////////////// menu main_menu; // the main menu. player main_player; // the main player enemy enemies[40]; // an array holding 40 enemies laser lasers[20]; // Menu-related u8 menu_pointer; // Main menu items u8 main_menu_start; u8 main_menu_help; u8 main_menu_quit; // Gfx#s u8 active_enemy; // PROTOTYPES //////////////////////////////////////////////////////////////////////////// void Sleep(int time); int randn(int num); void vblFunc(void); void Game_Main(void); void Game_Init(void); void Game_Shutdown(void); void emptyBackBuffer(void); void flipBackgroundBuffer(void); u8 make_laser(u8 objno, u8 x, u8 y); void fire_laser(u8 objno, u8 x, u8 y); void update_lasers(); int main(void); // FUNCTIONS ///////////////////////////////////////////////////////////////////////////// void Sleep(int time) // A seriously cheap sleep hack, and very inefficient as well. LOL { int sleep_time = time * 300000; // rough estimate on seconds, really about .6 of a sec int stime = 0; while (stime < sleep_time) { stime++; } } int randn(int num) { return rand()%num; } void vblFunc(void) { kramWorker(); ham_CopyObjToOAM(); new_frame=TRUE; } void Game_Main(void) { while(game_state != GAME_STATE_SHUTDOWN) { if (new_frame == TRUE) { ham_UpdatePad(); emptyBackBuffer(); // Main Menu State if (game_state == GAME_STATE_MENU) { // Draw the menu. ham_SetObjXY(menu_pointer, menu_ptr_x, menu_ptr_y); // Do menu logic if (Pad.Pressed.Down && main_menu.selected < 3) // 1-3 menu-items { main_menu.selected++; menu_ptr_y += 40; } if (Pad.Pressed.Up && main_menu.selected > 1) // 1-3 menu-items { main_menu.selected--; menu_ptr_y -= 40; } if (Pad.Pressed.A || Pad.Pressed.Start) { game_state = GAME_STATE_GAME_INIT; } } // Game Run state if (game_state == GAME_STATE_GAME_INIT) { if (main_menu.selected == 1) { // Remove map entries ham_DeleteObj(menu_pointer); ham_DeleteObj(main_menu_start); ham_DeleteObj(main_menu_help); ham_DeleteObj(main_menu_quit); main_player.sprite = ham_CreateObj(&ally_frigate_Bitmap, OBJ_SIZE_16X16, 0, 1, 0, 0, 0, 0, 0, 0, main_player.x, main_player.y); // Populate with `NUM_ENEMIES' initial enemies // FIXME: `for' doesn't seem to work here? enemies[0].x = randn(300); enemies[0].y = randn(30); enemies[0].dx = randn(2); enemies[0].dy = randn(1); enemies[0].alive = TRUE; enemies[0].curr_anim = 0; enemies[0].visible = TRUE; enemies[0].sclass = 1; // Frigates enemies[0].hp = 20; enemies[0].weaponid = 1; // basic laser enemies[0].sprite = ham_CreateObj(&enemy_frigate_Bitmap, OBJ_SIZE_16X16, 0, 1, 0, 0, 0, 0, 0, 0, enemies[0].x, enemies[0].y); int x = 1; // 240x160 while(x < NUM_ENEMIES) { enemies[x].x = randn(300); enemies[x].y = randn(30); enemies[x].dx = randn(2); enemies[x].dy = randn(1); enemies[x].alive = TRUE; enemies[x].curr_anim = 0; enemies[x].visible = TRUE; enemies[x].sclass = 1; // Frigates enemies[x].hp = 20; enemies[x].sprite = ham_CloneObj(enemies[0].sprite, enemies[x].x, enemies[x].y); enemies[x].weaponid = 1; // basic laser x++; } game_state = GAME_STATE_RUN; // Run the game } else if (main_menu.selected == 2) { // Display game help info if (Pad.Pressed.B || Pad.Pressed.A || Pad.Pressed.Start) game_state = GAME_STATE_MENU; } else if (main_menu.selected == 3) game_state = GAME_STATE_SHUTDOWN; } // Main game logic if (game_state == GAME_STATE_RUN) { // Move the enemy ships around randomly int x = 0; while (x < NUM_ENEMIES) { enemies[x].x += enemies[x].dx; enemies[x].y += enemies[x].dy; // Update speeds enemies[x].dx = randn(3); if (enemies[x].dx > 1) enemies[x].dx = -1; enemies[x].dy = randn(3); if (enemies[x].dy > 1) enemies[x].dy = -1; // Sleep a little Sleep(0.999); if (randn(9) == 2) { fire_laser(enemies[x].sprite, enemies[x].x, enemies[x].y); } // Update screen positions ham_SetObjXY(enemies[x].sprite, enemies[x].x, enemies[x].y); // next enemy x++; } // Don't go offscreen! if (Pad.Held.Left && main_player.x > 0) main_player.x -= 2; if (Pad.Held.Right && main_player.x < 224) main_player.x += 2; if (Pad.Held.Up && main_player.y > 100) main_player.y -= 2; if (Pad.Held.Down && main_player.y < 144) main_player.y += 2; if (Pad.Pressed.A) fire_laser(main_player.sprite, main_player.x, main_player.y); // Update your screen position ham_SetObjXY(main_player.sprite, main_player.x, main_player.y); update_lasers(); } flipBackgroundBuffer(); } new_frame = FALSE; } Game_Shutdown(); ham_ResetPad(); } void Game_Init(void) { // Display the initial title sequence // and a note about all these " "'s, cheap way to clear your text ;) srand(0xDEADBEEF); // FIXME: truly random seeding // text-mode Intro ham_InitText(0); char libver[10]; sprintf(libver, "%.2f", (float)((ham_GetHAMlibVersion()>>16)+((ham_GetHAMlibVersion()&0x0000FFFF)*0.1f))); ham_DrawText(2,7,"Compiled with HAMLib %s", libver); Sleep(5); ham_DrawText(2,7," "); ham_DrawText(2,7," (c) 2005-2007 INAKIChan"); Sleep(5); ham_DrawText(2,7," "); int tmp = 0; while(tmp < 100) { ham_DrawText(2,7," Loading... %d ",++tmp); Sleep(0.999); } Sleep(3); ham_DeInitText(); // Start the title-sequence music kragInit(KRAG_INIT_STEREO); krapPlay(&mod_dq, KRAP_MODE_LOOP, 0); ham_StartIntHandler(INT_TYPE_TIM1, &kradInterrupt); ham_StartIntHandler(INT_TYPE_VBL, &vblFunc); // Initialize a few objects main_menu.selected = 1; main_player.hp = 100; // start with max hp main_player.sp = 100; // '' main_player.lp = 75; // '' main_player.x = 120; // x position main_player.y = 140; // y position main_player.alive = TRUE; // alive or not? main_player.sclass = 1; // class 1 is a frigate main_player.visible = TRUE; // visible? main_player.state = 1; // state alive, healthy main_player.charname = "Cadet"; // FIXME: menu for name-choosing not implimented! ham_SetBgMode(0); ham_LoadObjPal(&master_Palette, 256); menu_pointer = ham_CreateObj(&ptr_Bitmap, OBJ_SIZE_16X16, 0, 1, 0, 0, 0, 0, 0, 0, 2, 10); main_menu_start = ham_CreateObj(&main_menu_start_Bitmap, OBJ_SIZE_64X32, 0, 1, 0, 0, 0, 0, 0, 0, 17, 20); main_menu_help = ham_CreateObj(&main_menu_help_Bitmap, OBJ_SIZE_64X32, 0, 1, 0, 0, 0, 0, 0, 0, 17, 60); main_menu_quit = ham_CreateObj(&main_menu_quit_Bitmap, OBJ_SIZE_64X32, 0, 1, 0, 0, 0, 0, 0, 0, 17, 100); /* u8 ham_CreateObj ( void * src, u16 obj_shape, u16 obj_size, u16 obj_mode, u16 col_mode, u16 pal_no, u16 mosaic, u16 hflip, u16 vflip, u16 prio, u16 dbl_size, u16 x, u16 y ) */ // Game state is now menu. game_state = GAME_STATE_MENU; inBitmapMode = FALSE; // Set this to false if you're not in bitmap mode. } void Game_Shutdown(void) { // You would do your saving, etc. functions here. // We just loop forever until I find a clean way of resetting the GBA while (1) { } } void emptyBackBuffer(void) { if (inBitmapMode) ham_ClearBackBuffer(0); } void flipBackgroundBuffer(void) { if (inBitmapMode) ham_FlipBGBuffer(); } void fire_laser(u8 objno, u8 x, u8 y) { return make_laser(objno, x, y); } void update_lasers(void) { u8 l = 0; while(++l < 20) { // cycle through enemy ships and then test ally ship u8 e = 0; while (++e < 40) { lasers[l].lx = lasers[l].x; lasers[l].ly = lasers[l].y; if (lasers[l].x == enemies[e].x) { if (lasers[l].y == enemies[e].y) { ham_DeleteObj(lasers[l].id); enemies[e].hp -= 2; lasers[l].x = lasers[l].y = lasers[l].id = -1; } } } if (lasers[l].x == main_player.x) { if (lasers[l].y == main_player.y) { ham_DeleteObj(lasers[l].id); main_player.hp -= 2; lasers[l].x = lasers[l].y = lasers[l].id = -1; } } if (lasers[l].y > 150) { ham_DeleteObj(lasers[l].id); lasers[l].x = lasers[l].y = lasers[l].id = -1; } if (lasers[l].isally == 1) { lasers[l].y += 2; } else { lasers[l].y -= 2; } if (lasers[l].y == lasers[l].ly) { // hasn't moved.. bad? ham_DeleteObj(lasers[l].id); lasers[l].x = lasers[l].y = lasers[l].id = -1; } ham_SetObjXY(lasers[l].id, lasers[l].x, lasers[l].y); } } u8 make_laser(u8 objno, u8 x, u8 y) { int fire_dir = 1; u8 laser; if (objno == main_player.sprite) fire_dir = 2; // fire in a `-y' direction if (fire_dir == 2) { laser = ham_CreateObj(&ally_laser_Bitmap, OBJ_SIZE_8X8, 0, 1, 0, 0, 0, 0, 0, 0, x, y); } laser = ham_CreateObj(&enemy_laser_Bitmap, OBJ_SIZE_8X8, 0, 1, 0, 0, 0, 0, 0, 0, x, y); lasers[num_lasers++].id = laser; lasers[num_lasers].x = x; lasers[num_lasers].y = y; lasers[num_lasers].isally = fire_dir; return laser; } int main(void) { ham_Init(); ham_InitPad(); Game_Init(); Game_Main(); return(-1); // XXX: not reached }