diff options
| author | Xavier Del Campo <xavi.dcr@gmail.com> | 2017-02-04 14:49:08 +0100 |
|---|---|---|
| committer | Xavier Del Campo <xavi.dcr@gmail.com> | 2017-02-04 14:49:08 +0100 |
| commit | 189ecf754d0c8131464bfdff98fb56e7752556b1 (patch) | |
| tree | 89e7d02128bbc7b2d3f5c19a3da14ec14291982a /Source/LoadMenu.c | |
| download | airport-189ecf754d0c8131464bfdff98fb56e7752556b1.tar.gz | |
Initial commit
Diffstat (limited to 'Source/LoadMenu.c')
| -rwxr-xr-x | Source/LoadMenu.c | 523 |
1 files changed, 523 insertions, 0 deletions
diff --git a/Source/LoadMenu.c b/Source/LoadMenu.c new file mode 100755 index 0000000..7c90cba --- /dev/null +++ b/Source/LoadMenu.c @@ -0,0 +1,523 @@ +/* ************************************** + * Includes * + * *************************************/ + +#include "LoadMenu.h" + +/* ************************************** + * Defines * + * *************************************/ + +/* ************************************** + * Structs and enums * + * *************************************/ + +enum +{ + SMALL_FONT_SIZE = 8 +}; + +enum +{ + BG_BLUE_TARGET_VALUE = 0xC0, + BG_WHITE_TARGET_VALUE = /*0x40*/ 0, + BG_INCREASE_STEP = 0x10 +}; + +enum +{ + LOADING_BAR_X = 64, + LOADING_BAR_Y = 200, + LOADING_BAR_N_LINES = 4, + + LOADING_BAR_WIDTH = 256, + LOADING_BAR_HEIGHT = 16, + + LOADING_BAR_LUMINANCE_TARGET = NORMAL_LUMINANCE, + LOADING_BAR_LUMINANCE_STEP = 10 +}; + +enum +{ + LOADING_TITLE_CLUT_X = 384, + LOADING_TITLE_CLUT_Y = 496, + LOADING_TITLE_X = 128, + LOADING_TITLE_Y = 32, + + LOADING_TITLE_U = 0, + LOADING_TITLE_V = 0, + + LOADING_TITLE_LUMINANCE_STEP = 10, + LOADING_TITLE_LUMINANCE_TARGET = NORMAL_LUMINANCE +}; + +enum +{ + PLANE_START_X = 56, + PLANE_START_Y = 200, + + PLANE_U = 0, + PLANE_V = 32, + PLANE_SIZE = 16, + + PLANE_LUMINANCE_STEP = 0x10, + PLANE_LUMINANCE_TARGET_VALUE = NORMAL_LUMINANCE +}; + +/* ************************************* + * Local Prototypes + * *************************************/ + +static void LoadMenuInit(void); +static void ISR_LoadMenuVBlank(void); +static bool LoadMenuISRHasEnded(void); +static bool LoadMenuISRHasStarted(void); +static void LoadMenuLoadFileList( char * fileList[], void * dest[], + uint8_t szFileList, uint8_t szDestList); + +/* ************************************* + * Local Variables + * *************************************/ + +static GsGPoly4 loadMenuBg; +static GsSprite LoadMenuPlaneSpr; +static GsSprite LoadMenuTitleSpr; +static GsLine LoadMenuBarLines[LOADING_BAR_N_LINES]; +static GsRectangle LoadMenuBarRect; + +static char * LoadMenuFiles[] = { "cdrom:\\DATA\\SPRITES\\PLANE.TIM;1", + "cdrom:\\DATA\\SPRITES\\LOADING.TIM;1", + "cdrom:\\DATA\\FONTS\\FONT_2.FNT;1" }; +static void * LoadMenuDest[] = {(GsSprite*)&LoadMenuPlaneSpr, + (GsSprite*)&LoadMenuTitleSpr, + (TYPE_FONT*)&SmallFont }; + +static char * strCurrentFile; + +// Flags to communicate with ISR state +// * startup_flag: background fades in from black to blue. +// * end_flag: tells the background to fade out to black. +// * isr_ended: background has totally faded out to black. +// * isr_started: tells the ISR has finished starting up. +static volatile bool startup_flag; +static volatile bool isr_started; +static volatile bool end_flag; +static volatile bool isr_ended; +// Set to true when LoadMenuInit() has been called, and set to false +// once LoadMenuEnd() is called. +// It's used when multiple modules call LoadMenu() at the same time, +// so load menu does not have to be initialised each time; +static bool load_menu_running; + +void LoadMenuInit(void) +{ + int i; + static bool first_load = false; + + if(first_load == false) + { + first_load = true; + LoadMenuLoadFileList( LoadMenuFiles, + LoadMenuDest, + sizeof(LoadMenuFiles) / sizeof(char*), + sizeof(LoadMenuDest) / sizeof(void*)); + } + + FontSetSize(&SmallFont, SMALL_FONT_SIZE); + + LoadMenuPlaneSpr.r = 0; + LoadMenuPlaneSpr.g = 0; + LoadMenuPlaneSpr.b = 0; + + LoadMenuPlaneSpr.x = PLANE_START_X; + LoadMenuPlaneSpr.y = PLANE_START_Y; + + // "Loading..." title init + + LoadMenuTitleSpr.r = 0; + LoadMenuTitleSpr.g = 0; + LoadMenuTitleSpr.b = 0; + + LoadMenuTitleSpr.x = LOADING_TITLE_X; + LoadMenuTitleSpr.y = LOADING_TITLE_Y; + + LoadMenuTitleSpr.cx = LOADING_TITLE_CLUT_X; + LoadMenuTitleSpr.cy = LOADING_TITLE_CLUT_Y; + LoadMenuTitleSpr.u = LOADING_TITLE_U; + LoadMenuTitleSpr.v = LOADING_TITLE_V; + + startup_flag = true; + isr_started = false; + end_flag = false; + isr_ended = false; + + // Background init + + loadMenuBg.x[0] = 0; + loadMenuBg.x[1] = X_SCREEN_RESOLUTION; + loadMenuBg.x[2] = 0; + loadMenuBg.x[3] = X_SCREEN_RESOLUTION; + + loadMenuBg.y[0] = 0; + loadMenuBg.y[1] = 0; + loadMenuBg.y[2] = Y_SCREEN_RESOLUTION; + loadMenuBg.y[3] = Y_SCREEN_RESOLUTION; + + // Colour components adjustment (default to zero) + for(i = 0; i < 4 ; i++) + { + loadMenuBg.r[i] = 0; + loadMenuBg.g[i] = 0; + loadMenuBg.b[i] = 0; + } + + // "Loading" bar line 0 (up left - up right) + + LoadMenuBarLines[0].x[0] = LOADING_BAR_X; + LoadMenuBarLines[0].x[1] = LOADING_BAR_X + LOADING_BAR_WIDTH; + + LoadMenuBarLines[0].y[0] = LOADING_BAR_Y; + LoadMenuBarLines[0].y[1] = LOADING_BAR_Y; + + // "Loading" bar line 1 (up left - down left) + + LoadMenuBarLines[1].x[0] = LOADING_BAR_X; + LoadMenuBarLines[1].x[1] = LOADING_BAR_X; + + LoadMenuBarLines[1].y[0] = LOADING_BAR_Y; + LoadMenuBarLines[1].y[1] = LOADING_BAR_Y + LOADING_BAR_HEIGHT; + + // "Loading" bar line 2 (down left - down right) + + LoadMenuBarLines[2].x[0] = LOADING_BAR_X; + LoadMenuBarLines[2].x[1] = LOADING_BAR_X + LOADING_BAR_WIDTH; + + LoadMenuBarLines[2].y[0] = LOADING_BAR_Y + LOADING_BAR_HEIGHT; + LoadMenuBarLines[2].y[1] = LOADING_BAR_Y + LOADING_BAR_HEIGHT; + + // "Loading" bar line 3 (up right - down right) + + LoadMenuBarLines[3].x[0] = LOADING_BAR_X + LOADING_BAR_WIDTH; + LoadMenuBarLines[3].x[1] = LOADING_BAR_X + LOADING_BAR_WIDTH; + + LoadMenuBarLines[3].y[0] = LOADING_BAR_Y; + LoadMenuBarLines[3].y[1] = LOADING_BAR_Y + LOADING_BAR_HEIGHT; + + for(i = 0; i < LOADING_BAR_N_LINES ; i++) + { + LoadMenuBarLines[i].r = 0; + LoadMenuBarLines[i].g = 0; + LoadMenuBarLines[i].b = 0; + } + + LoadMenuBarRect.r = 0; + LoadMenuBarRect.g = 0; + LoadMenuBarRect.b = 0; + + // LoadMenuBarRect.attribute |= ENABLE_TRANS | TRANS_MODE(0); + + LoadMenuBarRect.x = LOADING_BAR_X; + LoadMenuBarRect.y = LOADING_BAR_Y; + LoadMenuBarRect.w = 0; + LoadMenuBarRect.h = LOADING_BAR_HEIGHT; + + LoadMenuBarRect.attribute |= ENABLE_TRANS | TRANS_MODE(0); + + load_menu_running = true; + + SmallFont.spr.r = 0; + SmallFont.spr.g = 0; + SmallFont.spr.b = 0; + + GfxSetGlobalLuminance(0); + + SetVBlankHandler(&ISR_LoadMenuVBlank); +} + +void LoadMenuEnd(void) +{ + end_flag = true; + load_menu_running = false; + + while(LoadMenuISRHasEnded() == false); + dprintf("Set default VBlank handler.\n"); + SetVBlankHandler(&ISR_SystemDefaultVBlank); + + GfxSetGlobalLuminance(NORMAL_LUMINANCE); +} + +void ISR_LoadMenuVBlank(void) +{ + uint8_t i; + + if( (SystemIsBusy() == true) || (GfxIsGPUBusy() == true) ) + { + return; + } + + if(startup_flag == true) + { + // "Loading..." text + if(LoadMenuTitleSpr.r < LOADING_TITLE_LUMINANCE_TARGET) + { + LoadMenuTitleSpr.r += LOADING_TITLE_LUMINANCE_STEP; + LoadMenuTitleSpr.g += LOADING_TITLE_LUMINANCE_STEP; + LoadMenuTitleSpr.b += LOADING_TITLE_LUMINANCE_STEP; + } + + if(loadMenuBg.g[0] < BG_WHITE_TARGET_VALUE) + { + loadMenuBg.r[0] += BG_INCREASE_STEP; + loadMenuBg.r[1] += BG_INCREASE_STEP; + + loadMenuBg.g[0] += BG_INCREASE_STEP; + loadMenuBg.g[1] += BG_INCREASE_STEP; + + loadMenuBg.b[0] += BG_INCREASE_STEP; + loadMenuBg.b[1] += BG_INCREASE_STEP; + } + // Blue background + if(loadMenuBg.b[2] < BG_BLUE_TARGET_VALUE) + { + loadMenuBg.b[2] += BG_INCREASE_STEP; + loadMenuBg.b[3] += BG_INCREASE_STEP; + } + + if(LoadMenuBarRect.r < LOADING_BAR_LUMINANCE_TARGET) + { + LoadMenuBarRect.r += LOADING_BAR_LUMINANCE_STEP; + LoadMenuBarRect.g += LOADING_BAR_LUMINANCE_STEP; + LoadMenuBarRect.b += LOADING_BAR_LUMINANCE_STEP; + } + else + { + startup_flag = false; + isr_started = true; + } + + for(i = 0;i < LOADING_BAR_N_LINES ; i++) + { + if(LoadMenuBarLines[i].r < LOADING_BAR_LUMINANCE_TARGET) + { + LoadMenuBarLines[i].r += LOADING_BAR_LUMINANCE_STEP; + LoadMenuBarLines[i].g += LOADING_BAR_LUMINANCE_STEP; + LoadMenuBarLines[i].b += LOADING_BAR_LUMINANCE_STEP; + } + } + + if(LoadMenuPlaneSpr.r < PLANE_LUMINANCE_TARGET_VALUE) + { + LoadMenuPlaneSpr.r += PLANE_LUMINANCE_STEP; + LoadMenuPlaneSpr.g += PLANE_LUMINANCE_STEP; + LoadMenuPlaneSpr.b += PLANE_LUMINANCE_STEP; + } + + } + else if(end_flag == true) + { + LoadMenuTitleSpr.r -= LOADING_TITLE_LUMINANCE_STEP; + LoadMenuTitleSpr.g -= LOADING_TITLE_LUMINANCE_STEP; + LoadMenuTitleSpr.b -= LOADING_TITLE_LUMINANCE_STEP; + + if(loadMenuBg.g[0] > 0) + { + loadMenuBg.r[0] -= BG_INCREASE_STEP; + loadMenuBg.r[1] -= BG_INCREASE_STEP; + + loadMenuBg.g[0] -= BG_INCREASE_STEP; + loadMenuBg.g[1] -= BG_INCREASE_STEP; + + loadMenuBg.b[0] -= BG_INCREASE_STEP; + loadMenuBg.b[1] -= BG_INCREASE_STEP; + } + + if(loadMenuBg.b[2] > 0) + { + loadMenuBg.b[2] -= BG_INCREASE_STEP; + loadMenuBg.b[3] -= BG_INCREASE_STEP; + } + + if(loadMenuBg.b[2] == 0) + { + end_flag = false; + isr_ended = true; + } + + if(LoadMenuPlaneSpr.r > 0) + { + LoadMenuPlaneSpr.r -= PLANE_LUMINANCE_STEP; + LoadMenuPlaneSpr.g -= PLANE_LUMINANCE_STEP; + LoadMenuPlaneSpr.b -= PLANE_LUMINANCE_STEP; + } + + LoadMenuPlaneSpr.x = (PLANE_START_X + LOADING_BAR_WIDTH); + LoadMenuPlaneSpr.y = PLANE_START_Y; + + LoadMenuBarRect.w = LOADING_BAR_WIDTH; + + if(LoadMenuBarRect.r > 0) + { + LoadMenuBarRect.r -= LOADING_BAR_LUMINANCE_STEP; + LoadMenuBarRect.g -= LOADING_BAR_LUMINANCE_STEP; + LoadMenuBarRect.b -= LOADING_BAR_LUMINANCE_STEP; + } + + for(i = 0;i < LOADING_BAR_N_LINES ; i++) + { + if(LoadMenuBarLines[i].r > 0) + { + LoadMenuBarLines[i].r -= LOADING_BAR_LUMINANCE_STEP; + LoadMenuBarLines[i].g -= LOADING_BAR_LUMINANCE_STEP; + LoadMenuBarLines[i].b -= LOADING_BAR_LUMINANCE_STEP; + } + } + } + + GsSortGPoly4(&loadMenuBg); + + GsSortRectangle(&LoadMenuBarRect); + + for(i = 0 ; i < LOADING_BAR_N_LINES ; i++) + { + GsSortLine(&LoadMenuBarLines[i]); + } + + GsSortSprite(&LoadMenuTitleSpr); + + LoadMenuPlaneSpr.w = PLANE_SIZE; + LoadMenuPlaneSpr.h = PLANE_SIZE; + + LoadMenuPlaneSpr.u = PLANE_U; + LoadMenuPlaneSpr.v = PLANE_V; + + GsSortSprite(&LoadMenuPlaneSpr); + + FontSetFlags(&SmallFont, FONT_BLEND_EFFECT); + + FontPrintText( &SmallFont, + LOADING_BAR_X - 8, + LOADING_BAR_Y + LOADING_BAR_HEIGHT + 8, + strCurrentFile ); + + FontSetFlags(&SmallFont, FONT_NOFLAGS); + + GfxDrawScene_Fast(); +} + +bool LoadMenuISRHasEnded(void) +{ + return isr_ended; +} + +bool LoadMenuISRHasStarted(void) +{ + return isr_started; +} + +void LoadMenu( char * fileList[], + void * dest[], + uint8_t szFileList , uint8_t szDestList) +{ + + if(load_menu_running == false) + { + LoadMenuInit(); + + while(LoadMenuISRHasStarted() == false); + } + + LoadMenuLoadFileList(fileList,dest,szFileList,szDestList); + +} + +void LoadMenuLoadFileList( char * fileList[], void * dest[], + uint8_t szFileList, uint8_t szDestList) +{ + char aux_file_name[100]; + char * extension; + short x_increment; + uint8_t fileLoadedCount; + + if(szFileList != szDestList) + { + dprintf("File list size different from dest list size! %d vs %d\n", + szFileList, szDestList); + return; + } + + for(fileLoadedCount = 0; fileLoadedCount < szFileList ; fileLoadedCount++) + { + if(fileList[fileLoadedCount] == NULL) + { + continue; + } + + strCurrentFile = fileList[fileLoadedCount]; + + x_increment = (short)(LOADING_BAR_WIDTH / szFileList); + + // Calculate new X position for loading menu plane sprite. + // This is not calculated on ISR as to avoid longer ISR time. + LoadMenuPlaneSpr.x = (PLANE_START_X + (fileLoadedCount* x_increment) ); + + LoadMenuBarRect.w = fileLoadedCount* x_increment; + + //dprintf("Files %d / %d loaded. New plane X = %d.\n",fileLoadedCount,szFileList,LoadMenuPlaneSpr.x); + + // Backup original file path + strncpy(aux_file_name,fileList[fileLoadedCount],100); + + //We want to get file extension, so split into tokens + strtok(fileList[fileLoadedCount],".;"); + extension = strtok(NULL,".;"); + + dprintf("File extension: .%s\n",extension); + //Restore original file path in order to load file + strncpy(fileList[fileLoadedCount],aux_file_name,100); + + if(strncmp(extension,"TIM",3) == 0) + { + if(GfxSpriteFromFile(fileList[fileLoadedCount], dest[fileLoadedCount]) == false) + { + dprintf("Could not load image file \"%s\"!\n",fileList[fileLoadedCount]); + } + } + else if(strncmp(extension,"CLT",3) == 0) + { + if(dest[fileLoadedCount] != NULL) + { + dprintf("WARNING: File %s linked to non-NULL destination pointer!\n", dest[fileLoadedCount]); + } + + if(GfxCLUTFromFile(fileList[fileLoadedCount]) == false) + { + dprintf("Could not load CLUT file \"%s\"!\n",fileList[fileLoadedCount]); + } + } + else if(strncmp(extension,"VAG",3) == 0) + { + if(SfxUploadSound(fileList[fileLoadedCount], dest[fileLoadedCount]) == false) + { + dprintf("Could not load sound file \"%s\"!\n",fileList[fileLoadedCount]); + } + } + else if(strncmp(extension,"FNT",3) == 0) + { + if(FontLoadImage(fileList[fileLoadedCount], dest[fileLoadedCount]) == false) + { + dprintf("Could not load font file \"%s\"!\n",fileList[fileLoadedCount]); + } + } + else if(strncmp(extension,"PLT",3) == 0) + { + if(PltParserLoadFile(fileList[fileLoadedCount], dest[fileLoadedCount]) == false) + { + dprintf("Could not load pilots file \"%s\"!\n",fileList[fileLoadedCount]); + } + } + else + { + dprintf("LoadMenu does not recognize following extension: %s\n",extension); + } + } +} |
