diff --git a/Makefile.gc b/Makefile.gc index f364e96..35afb96 100644 --- a/Makefile.gc +++ b/Makefile.gc @@ -20,7 +20,7 @@ BUILD := build_cube SOURCES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc source/cart_hw source/cart_hw/svp \ source/gx source/gx/gui source/gx/fileio source/gx/images source/gx/sounds INCLUDES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc source/cart_hw source/cart_hw/svp \ - source/gx source/gx/gui source/gx/fileio source/gx/images source/gx/sounds + build_cube source/gx source/gx/gui source/gx/fileio source/gx/images source/gx/sounds #--------------------------------------------------------------------------------- # options for code generation @@ -34,7 +34,7 @@ LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lpng -lfat -lasnd -logc -lm -lz +LIBS := -lpng -lfat -ltremor -lasnd -logc -lm -lz #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing @@ -66,6 +66,7 @@ SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm))) +OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg))) #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C @@ -77,8 +78,8 @@ else endif export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(PNGFILES:.png=.png.o) $(PCMFILES:.pcm=.pcm.o) $(OGGFILES:.ogg=.ogg.o) \ $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ - $(PNGFILES:.png=.png.o) $(PCMFILES:.pcm=.pcm.o) \ $(sFILES:.s=.o) $(SFILES:.S=.o) #--------------------------------------------------------------------------------- @@ -135,6 +136,10 @@ $(OUTPUT).elf: $(OFILES) @echo $(notdir $<) $(bin2o) +%.ogg.o : %.ogg + @echo $(notdir $<) + $(bin2o) + -include $(DEPENDS) #--------------------------------------------------------------------------------- diff --git a/Makefile.wii b/Makefile.wii index 4b6ba7a..efdccc1 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -20,7 +20,7 @@ BUILD := build_wii SOURCES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc source/cart_hw source/cart_hw/svp \ source/gx source/gx/gui source/gx/fileio source/gx/images source/gx/sounds INCLUDES := source source/m68k source/z80 source/sound source/sound/SRC source/ntsc source/cart_hw source/cart_hw/svp \ - source/gx source/gx/gui source/gx/fileio source/gx/images source/gx/sounds + build_wii source/gx source/gx/gui source/gx/fileio source/gx/images source/gx/sounds #--------------------------------------------------------------------------------- # options for code generation @@ -34,7 +34,7 @@ LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lpng -ldi -lfat -lasnd -lwiiuse -lbte -logc -lm -lz +LIBS := -lpng -ldi -lfat -ltremor -lasnd -lwiiuse -lbte -logc -lm -lz #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing @@ -52,7 +52,7 @@ ifneq ($(BUILD),$(notdir $(CURDIR))) export OUTPUT := $(CURDIR)/$(TARGET) export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) export DEPSDIR := $(CURDIR)/$(BUILD) @@ -66,6 +66,7 @@ SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm))) +OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg))) #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C @@ -77,8 +78,8 @@ else endif export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(PNGFILES:.png=.png.o) $(PCMFILES:.pcm=.pcm.o) $(OGGFILES:.ogg=.ogg.o) \ $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ - $(PNGFILES:.png=.png.o) $(PCMFILES:.pcm=.pcm.o) \ $(sFILES:.s=.o) $(SFILES:.S=.o) #--------------------------------------------------------------------------------- @@ -135,6 +136,10 @@ $(OUTPUT).elf: $(OFILES) @echo $(notdir $<) $(bin2o) +%.ogg.o : %.ogg + @echo $(notdir $<) + $(bin2o) + -include $(DEPENDS) #--------------------------------------------------------------------------------- diff --git a/source/gx/config.c b/source/gx/config.c index 3ea2a25..b76aaec 100644 --- a/source/gx/config.c +++ b/source/gx/config.c @@ -85,9 +85,9 @@ void config_setDefault(void) config.filter = 1; /* system options */ - config.freeze_auto = -1; + config.state_auto = -1; #ifdef HW_RVL - config.sram_auto = 0; /* assume we always got SDCARD */ + config.sram_auto = 0; /* let's assume we always have a FAT device by default */ #else config.sram_auto = -1; #endif diff --git a/source/gx/config.h b/source/gx/config.h index cc817b7..000a949 100644 --- a/source/gx/config.h +++ b/source/gx/config.h @@ -37,7 +37,7 @@ typedef struct uint8 filter; uint8 hq_fm; int8 sram_auto; - int8 freeze_auto; + int8 state_auto; uint8 region_detect; uint8 force_dtack; uint8 bios_enabled; diff --git a/source/gx/fileio/file_mem.c b/source/gx/fileio/file_mem.c index aa8c359..7ebed37 100644 --- a/source/gx/fileio/file_mem.c +++ b/source/gx/fileio/file_mem.c @@ -53,23 +53,23 @@ int ManageState(u8 direction, u8 device); * * *****************************************************************************/ -void memfile_autoload() +void memfile_autoload(s8 autosram, s8 autostate) { /* this should be transparent to the user */ SILENT = 1; /* SRAM */ - if (config.sram_auto != -1) - ManageSRAM(1,config.sram_auto); + if (autosram != -1) + ManageSRAM(1,autosram); /* STATE */ - if (config.freeze_auto != -1) - ManageState(1,config.freeze_auto); + if (autostate != -1) + ManageState(1,autostate); SILENT = 0; } -void memfile_autosave() +void memfile_autosave(s8 autosram, s8 autostate) { int crccheck = crc32 (0, sram.sram, 0x10000); @@ -77,12 +77,12 @@ void memfile_autosave() SILENT = 1; /* SRAM */ - if ((config.sram_auto != -1) && (crccheck != sram.crc)) - ManageSRAM(0, config.sram_auto); + if ((autosram != -1) && (crccheck != sram.crc)) + ManageSRAM(0, autosram); /* STATE */ - if (config.freeze_auto != -1) - ManageState(0,config.freeze_auto); + if (autostate != -1) + ManageState(0,autostate); SILENT = 0; } diff --git a/source/gx/gui/filesel.c b/source/gx/gui/filesel.c index d2743c4..0fc67a9 100644 --- a/source/gx/gui/filesel.c +++ b/source/gx/gui/filesel.c @@ -33,8 +33,8 @@ #endif /* this is emulator specific ! */ -#define PAGESIZE 13 -#define PAGEOFFSET 86 +#define PAGESIZE 11 +#define PAGEOFFSET 120 /* Global Variables */ @@ -49,6 +49,82 @@ int haveFATdir = 0; FILEENTRIES filelist[MAXFILES]; +/*****************************************************************************/ +/* GUI Buttons data */ +/*****************************************************************************/ +static butn_data arrow_up_data = +{ + {NULL,NULL}, + {Button_up_png,Button_up_over_png} +}; + +static butn_data arrow_down_data = +{ + {NULL,NULL}, + {Button_down_png,Button_down_over_png} +}; + +/*****************************************************************************/ +/* GUI Buttons */ +/*****************************************************************************/ + +static gui_butn arrow_up = {&arrow_up_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,14,76,360,32}; +static gui_butn arrow_down = {&arrow_down_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,14,368,360,32}; + +/*****************************************************************************/ +/* GUI helpers */ +/*****************************************************************************/ +static gui_item action_cancel = +{ +#ifdef HW_RVL + NULL,Key_B_wii_png,"","Previous",10,422,28,28 +#else + NULL,Key_B_gcn_png,"","Previous",10,422,28,28 +#endif +}; + +static gui_item action_select = +{ +#ifdef HW_RVL + NULL,Key_A_wii_png,"","Load ROM file",602,422,28,28 +#else + NULL,Key_A_gcn_png,"","Load ROM file",602,422,28,28 +#endif +}; + +/*****************************************************************************/ +/* GUI Background images */ +/*****************************************************************************/ +static gui_image bg_filesel[9] = +{ + {NULL,Bg_main_png,IMAGE_VISIBLE,356,144,348,288,255,{0,0},{0,0}}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255,{0,0},{0,0}}, + {NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255,{0,0},{0,0}}, + {NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255,{0,0},{0,0}}, + {NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255,{0,0},{0,0}}, + {NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,200,{0,0},{0,0}}, + {NULL,Frame_s2_png,0,384,264,248,140,200,{0,0},{0,0}}, + {NULL,Snap_empty_png,IMAGE_VISIBLE,422,114,164,116,255,{0,0},{0,0}}, + {NULL,Snap_frame_png,IMAGE_VISIBLE,388,112,236,148,255,{0,0},{0,0}} +}; + +/*****************************************************************************/ +/* GUI Descriptor */ +/*****************************************************************************/ +static gui_menu menu_browser = +{ + "ROM Selection", + -1,0, + 0,0,9, + {0,0}, + NULL, + NULL, + bg_filesel, + {&action_cancel, &action_select}, + {&arrow_up,&arrow_down}, + FALSE +}; + /*************************************************************************** * FileSortCallback (Marty Disibio) * @@ -84,186 +160,195 @@ int FileSortCallback(const void *f1, const void *f2) * ROM size is returned * ****************************************************************************/ - -int FileSelector(unsigned char *buffer) +int FileSelector(unsigned char *buffer) { +#ifdef HW_RVL + int x,y; + gui_butn *button; +#endif short p; -// int redraw = 1; + int ret,i,yoffset,string_offset; int go_up = 0; int quit =0; - int ret; - int i,size; - - int yoffset; char text[MAXJOLIET+2]; - FILE *xml; - FILE *snap; + char fname[MAXPATHLEN]; + FILE *xml,*snap; -#ifdef HW_RVL - /* allocate wiimote pointer data (only done once) */ - // gx_texture *pointer = gxTextureOpenPNG(generic_point_png); -#endif + /* Initialize Menu */ + gui_menu *m = &menu_browser; + GUI_InitMenu(m); - /* allocate background overlay texture */ - gui_image *overlay = &bg_overlay_line; - if (!overlay->texture) overlay->texture = gxTextureOpenPNG(overlay->data); + /* Initialize directory icon */ + gui_image dir_icon; + dir_icon.texture = gxTextureOpenPNG(Browser_dir_png); + dir_icon.w = dir_icon.texture->width; + dir_icon.h = dir_icon.texture->height; + dir_icon.x = 26; + dir_icon.y = PAGEOFFSET; - /* allocate background image texture */ - gui_image *bg = &bg_right; - if (!bg->texture) bg->texture = gxTextureOpenPNG(bg->data); + /* Initialize selection bar */ + gui_image bar_over; + bar_over.texture = gxTextureOpenPNG(Overlay_bar_png); + bar_over.w = bar_over.texture->width; + bar_over.h = bar_over.texture->height; + bar_over.x = 22; + bar_over.y = -(bar_over.h - dir_icon.h)/2; - /* allocate logo texture */ - gui_image *logo = &logo_small; - if (!logo->texture) logo->texture = gxTextureOpenPNG(logo->data); + /* Initialize star icons */ + //gx_texture *star_full = gxTextureOpenPNG(Star_full_png); + //gx_texture *star_empty = gxTextureOpenPNG(Star_empty_png); - /* allocate generic elements textures */ - gui_image *frames[2] = {&left_frame,&right_frame}; - gui_image *banners[2] = {&top_banner,&bottom_banner}; - gui_item *helpers[2] = {&action_cancel, &action_select}; - for (i=0; i<2; i++) - { - /* frames */ - if (!frames[i]->texture) frames[i]->texture = gxTextureOpenPNG(frames[i]->data); - - /* banners */ - if (!banners[i]->texture) banners[i]->texture = gxTextureOpenPNG(banners[i]->data); - - /* key helpers */ - if (!helpers[i]->texture) helpers[i]->texture = gxTextureOpenPNG(helpers[i]->data); - } - - /* snapshots */ - gx_texture *snap_frame = gxTextureOpenPNG(Snap_frame_png); - gx_texture *snap_empty = gxTextureOpenPNG(Snap_empty_png); - - /* selection bar */ - gx_texture *bar_over = gxTextureOpenPNG(Overlay_bar_png); - - /* directory icon */ - gx_texture *dir_icon = gxTextureOpenPNG(Browser_dir_png); - -#ifdef NEW_GUI - - /* arrows */ - gx_texture *arrow_up = gxTextureOpenPNG(Button_up_png); - gx_texture *arrow_up_over = gxTextureOpenPNG(Button_up_over_png); - gx_texture *arrow_down = gxTextureOpenPNG(Button_down_png); - gx_texture *arrow_down_over = gxTextureOpenPNG(Button_down_over_png); - - /* stars */ - gx_texture *star_full = gxTextureOpenPNG(Star_full_png); - gx_texture *star_empty = gxTextureOpenPNG(Star_empty_png); -#endif while (!quit) { - /* Draw menu*/ - gxClearScreen ((GXColor)BACKGROUND); - - gxDrawRepeat(overlay->texture,overlay->x,overlay->y,overlay->w,overlay->h); - gxDrawTexture(bg->texture,bg->x,bg->y,bg->w,bg->h,255); - gxDrawTexture(banners[0]->texture,banners[0]->x,banners[0]->y,banners[0]->w,banners[0]->h,255); - gxDrawTexture(banners[1]->texture,banners[1]->x,banners[1]->y,banners[1]->w,banners[1]->h,255); - gxDrawTexture(helpers[0]->texture,helpers[0]->x,helpers[0]->y,helpers[0]->w,helpers[0]->h,255); - gxDrawTexture(helpers[1]->texture,helpers[1]->x,helpers[1]->y,helpers[1]->w,helpers[1]->h,255); - gxDrawTexture(logo->texture,logo->x,logo->y,logo->w,logo->h,255); - - /* Draw title & helps */ - FONT_alignLeft("ROM Selection", 22,10,56, (GXColor)WHITE); - FONT_alignLeft("Back", 16, helpers[0]->x+helpers[0]->w+6,helpers[0]->y+(helpers[0]->h-16)/2 + 16, (GXColor)WHITE); - FONT_alignRight("Load ROM File", 16, helpers[1]->x - 6, helpers[1]->y+(helpers[1]->h-16)/2 + 16, (GXColor)WHITE); - - gxDrawTexture(snap_empty,422,114,snap_empty->width,snap_empty->height,255); - gxDrawTexture(frames[0]->texture,frames[0]->x,frames[0]->y,frames[0]->w,frames[0]->h,200); - -#ifdef NEW_GUI + /* get ROM filename without extension */ + sprintf (text, "%s", filelist[selection].filename); + text[strlen(text) - 4] = 0; + /* ROM database informations */ - strncpy(fname, filelist[selection].filename, strlen(filelist[selection].filename) - 4); - sprintf(fname, "%s/db/%s.xml",DEFAULT_PATH,fname); + sprintf (fname, "%s/db/%s.xml", DEFAULT_PATH, text); xml = fopen(fname, "rb"); if (xml) { - gxDrawTexture(frames[1]->texture,frames[1]->x,frames[1]->y,frames[1]->w,frames[1]->h,200); + bg_filesel[6].state |= IMAGE_VISIBLE; fclose(xml); /* TODO */ } + else + { + bg_filesel[6].state &= ~IMAGE_VISIBLE; + } /* ROM snapshot */ - strncpy(fname, filelist[selection].filename, strlen(filelist[selection].filename) - 4); - sprintf(fname, "%s/snap/%s.png",DEFAULT_PATH,fname); + sprintf (fname, "%s/snaps/%s.png", DEFAULT_PATH, text); snap = fopen(fname, "rb"); if (snap) { fclose(snap); /* TODO */ } - else - { - gxDrawTexture(snap_empty,422,114,snap_empty->width,snap_empty->height,255); - } -#endif - /* Cartridge picture */ - gxDrawTexture(snap_frame,388,112,snap_frame->width,snap_frame->height,255); + /* Draw menu*/ + GUI_DrawMenu(m); - /* File list */ - gxDrawTexture(frames[0]->texture,frames[0]->x,frames[0]->y,frames[0]->w,frames[0]->h,200); - - yoffset = 86; + /* Draw Files list */ + yoffset = PAGEOFFSET; for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++) { - sprintf (text, "%s", filelist[i].filename + filelist[i].filename_offset); if (i == selection) { - gxDrawTexture(bar_over,22,yoffset - ((bar_over->height - dir_icon->height)/2), bar_over->width,bar_over->height,255); - } + /* scrolling text */ + string_offset = filelist[i].filename_offset/10; + if (string_offset >= strlen(filelist[i].filename)) + { + string_offset = 0; + filelist[i].filename_offset = 0; + } + sprintf(text, "%s ",filelist[i].filename + string_offset); + strncat(text, filelist[i].filename, string_offset); - if (filelist[i].flags) - { - /* directory icon */ - gxDrawTexture(dir_icon,26,yoffset,dir_icon->width,dir_icon->height,255); - FONT_alignLeft(text, 16,26+dir_icon->width+6,yoffset + 16, (GXColor)WHITE); + gxDrawTexture(bar_over.texture,bar_over.x,yoffset+bar_over.y,bar_over.w,bar_over.h,255); + if (filelist[i].flags) + { + /* directory icon */ + gxDrawTexture(dir_icon.texture,dir_icon.x-1,yoffset-1,dir_icon.w+2,dir_icon.h+2,255); + if (FONT_write(text,18,dir_icon.x+dir_icon.w+6,yoffset+16,bar_over.w-dir_icon.w-14,(GXColor)WHITE)) + { + filelist[i].filename_offset ++; + } + } + else + { + if (FONT_write(text,18,dir_icon.x,yoffset+16,bar_over.w-8,(GXColor)WHITE)) + { + filelist[i].filename_offset ++; + } + } } else { - FONT_alignLeft(text, 16,26,yoffset+16, (GXColor)WHITE); + filelist[i].filename_offset = 0; + if (filelist[i].flags) + { + /* directory icon */ + gxDrawTexture(dir_icon.texture,dir_icon.x,yoffset,dir_icon.w,dir_icon.h,255); + FONT_write(filelist[i].filename,16,dir_icon.x+dir_icon.w+6,yoffset+16,bar_over.w-dir_icon.w-14,(GXColor)WHITE); + } + else + { + FONT_write(filelist[i].filename,16,dir_icon.x,yoffset+16,bar_over.w-8,(GXColor)WHITE); + } } - yoffset += 20; + yoffset += 22; } +#ifdef HW_RVL + if (Shutdown) + { + gxTextureClose(&w_pointer); + GUI_DeleteMenu(m); + shutdown(); + SYS_ResetSystem(SYS_POWEROFF, 0, 0); + } + else if (m_input.ir.valid) + { + /* get cursor position */ + x = m_input.ir.x; + y = m_input.ir.y; + + /* draw wiimote pointer */ + gxResetAngle(m_input.ir.angle); + gxDrawTexture(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,255); + gxResetAngle(0.0); + + /* find selected item */ + yoffset = PAGEOFFSET; + m->selected = m->max_buttons + 2; + for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++) + { + if ((x<=380)&&(y>=yoffset)&&(y<(yoffset+22))) + { + selection = i; + m->selected = -1; + break; + } + yoffset += 22; + } + + /* find selected button */ + for (i=0; i<2; i++) + { + button = m->arrows[i]; + if (button) + { + if (button->state & BUTTON_VISIBLE) + { + if ((x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) + { + m->selected = m->max_buttons + i; + break; + } + } + } + } + } + else + { + /* reset indicator */ + m->selected = -1; + } +#endif + /* copy EFB to XFB */ gxSetScreen (); p = m_input.keys; - /* scroll displayed filename */ - if (p & PAD_BUTTON_LEFT) - { - if (filelist[selection].filename_offset > 0) - { - filelist[selection].filename_offset --; - //redraw = 1; - } - } - else if (p & PAD_BUTTON_RIGHT) - { - size = 0; - for (i=filelist[selection].filename_offset; i back_framewidth) - { - filelist[selection].filename_offset ++; - //redraw = 1; - } - } - /* highlight next item */ - else if (p & PAD_BUTTON_DOWN) + if (p & PAD_BUTTON_DOWN) { filelist[selection].filename_offset = 0; selection++; if (selection == maxfiles) selection = offset = 0; if ((selection - offset) >= PAGESIZE) offset += PAGESIZE; - //redraw = 1; } /* highlight previous item */ @@ -278,7 +363,6 @@ int FileSelector(unsigned char *buffer) } if (selection < offset) offset -= PAGESIZE; if (offset < 0) offset = 0; - //redraw = 1; } /* go back one page */ @@ -293,7 +377,6 @@ int FileSelector(unsigned char *buffer) } if (selection < offset) offset -= PAGESIZE; if (offset < 0) offset = 0; - //redraw = 1; } /* go forward one page */ @@ -303,85 +386,92 @@ int FileSelector(unsigned char *buffer) selection += PAGESIZE; if (selection > maxfiles - 1) selection = offset = 0; if ((selection - offset) >= PAGESIZE) offset += PAGESIZE; - //redraw = 1; } /* quit */ - if (p & PAD_TRIGGER_Z) + else if (p & PAD_TRIGGER_Z) { filelist[selection].filename_offset = 0; quit = 2; } /* open selected file or directory */ - if ((p & PAD_BUTTON_A) || (p & PAD_BUTTON_B)) + else if ((p & PAD_BUTTON_A) || (p & PAD_BUTTON_B)) { filelist[selection].filename_offset = 0; go_up = 0; - + if (p & PAD_BUTTON_B) { /* go up one directory or quit */ go_up = 1; selection = useFAT ? 0 : 1; } - - /*** This is directory ***/ - if (filelist[selection].flags) +#ifdef HW_RVL + else { - /* get new directory */ - if (useFAT) ret =FAT_UpdateDir(go_up); - else ret = DVD_UpdateDir(go_up); - - /* get new entry list or quit */ - if (ret) + /* arrow buttons selected */ + if (m->selected == m->max_buttons) /* up arrow */ { - if (useFAT) maxfiles = FAT_ParseDirectory(); - else maxfiles = DVD_ParseDirectory(); + filelist[selection].filename_offset = 0; + selection--; + if (selection < 0) + { + selection = maxfiles - 1; + offset = selection - PAGESIZE + 1; + } + if (selection < offset) offset -= PAGESIZE; + if (offset < 0) offset = 0; } - else + else if (m->selected == (m->max_buttons+1)) /* down arrow */ { - quit = 2; + filelist[selection].filename_offset = 0; + selection++; + if (selection == maxfiles) selection = offset = 0; + if ((selection - offset) >= PAGESIZE) offset += PAGESIZE; } } - - /*** This is a file ***/ - else +#endif + + /* ensure we are in focus area */ + if (m->selected < m->max_buttons) { - /* root directory ? */ - if (go_up) quit = 2; - else quit = 1; + /*** This is directory ***/ + if (filelist[selection].flags) + { + /* get new directory */ + if (useFAT) ret =FAT_UpdateDir(go_up); + else ret = DVD_UpdateDir(go_up); + + /* get new entry list or quit */ + if (ret) + { + if (useFAT) maxfiles = FAT_ParseDirectory(); + else maxfiles = DVD_ParseDirectory(); + } + else + { + quit = 2; + } + } + + /*** This is a file ***/ + else + { + /* root directory ? */ + if (go_up) quit = 2; + else quit = 1; + } } - //redraw = 1; } } -#ifdef HW_RVL - /* allocate wiimote pointer data (only done once) */ -// gxTextureClose(&pointer); -#endif - - gxTextureClose(&overlay->texture); - gxTextureClose(&bg->texture); - gxTextureClose(&logo->texture); - for (i=0; i<2; i++) - { - gxTextureClose(&frames[i]->texture); - gxTextureClose(&banners[i]->texture); - gxTextureClose(&helpers[i]->texture); - } - gxTextureClose(&snap_frame); - gxTextureClose(&snap_empty); - gxTextureClose(&bar_over); - gxTextureClose(&dir_icon); -#ifdef NEW_GUI - gxTextureClose(&arrow_up); - gxTextureClose(&arrow_up_over); - gxTextureClose(&arrow_down); - gxTextureClose(&arrow_down_over); - gxTextureClose(&star_full); - gxTextureClose(&star_empty); -#endif + /* Delete Menu */ + GUI_DeleteMenu(m); + gxTextureClose(&bar_over.texture); + gxTextureClose(&dir_icon.texture); + //gxTextureClose(&star_full); + //gxTextureClose(&star_empty); if (quit == 2) return 0; else if (useFAT) return FAT_LoadFile(buffer); diff --git a/source/gx/gui/font.c b/source/gx/gui/font.c index 8e6c2b0..4ad91d0 100644 --- a/source/gx/gui/font.c +++ b/source/gx/gui/font.c @@ -164,15 +164,41 @@ void WriteCentre_HL( int y, char *string) WriteCentre(y, string); } -void FONT_alignLeft(char *string, int size, int x, int y, GXColor color) +int FONT_write(char *string, int size, int x, int y, int max_width, GXColor color) { x -= (vmode->fbWidth / 2); y -= (vmode->efbHeight / 2); + int w, ox = x; + + while (*string) + { + w = (font_size[(u8)*string] * size) / fheight; + if ((x + w) <= (ox + max_width)) + { + DrawChar(*string, x, y, size,color); + x += w; + string++; + } + else return 1; + } + return 0; +} + +void FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor color) +{ + int i; + u16 width = 0; + + for (i=0; ifbWidth) / 2; + y -= (vmode->efbHeight / 2); while (*string) { - DrawChar(*string, x, y, size,color); - x += (font_size[(u8)*string++] * size) / fheight; + DrawChar(*string, x1, y, size,color); + x1 += (font_size[(u8)*string++] * size) / fheight; } } @@ -194,24 +220,6 @@ void FONT_alignRight(char *string, int size, int x, int y, GXColor color) } } -void FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor color) -{ - int i; - u16 width = 0; - - for (i=0; ifbWidth) / 2; - y -= (vmode->efbHeight / 2); - - while (*string) - { - DrawChar(*string, x1, y, size,color); - x1 += (font_size[(u8)*string++] * size) / fheight; - } -} - /**************************************************************************** * Draw functions (FrameBuffer) * diff --git a/source/gx/gui/font.h b/source/gx/gui/font.h index 535a88e..476d66d 100644 --- a/source/gx/gui/font.h +++ b/source/gx/gui/font.h @@ -27,9 +27,9 @@ extern int FONT_Init(void); extern void FONT_Shutdown(void); -extern void FONT_alignLeft(char *string, int size, int x, int y, GXColor color); -extern void FONT_alignRight(char *string, int size, int x, int y, GXColor color); +extern int FONT_write(char *string, int size, int x, int y, int max_width, GXColor color); extern void FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor color); +extern void FONT_alignRight(char *string, int size, int x, int y, GXColor color); extern void WaitButtonA (); diff --git a/source/gx/gui/legal.c b/source/gx/gui/legal.c index bf58e0f..1ad1865 100644 --- a/source/gx/gui/legal.c +++ b/source/gx/gui/legal.c @@ -26,6 +26,9 @@ #include "font.h" #include "menu.h" +#include "intro_pcm.h" +#include + /* * This is the legal stuff - which must be shown at program startup * Any derivative work MUST include the same textual output. @@ -113,5 +116,11 @@ void legal () } gxSetScreen (); + ASND_Init(); + ASND_Pause(0); + int voice = ASND_GetFirstUnusedVoice(); + ASND_SetVoice(voice,VOICE_MONO_16BIT,44100,0,(u8 *)intro_pcm,intro_pcm_size,200,200,NULL); sleep (2); + ASND_Pause(1); + ASND_End(); } diff --git a/source/gx/gui/menu.c b/source/gx/gui/menu.c index c50b912..07cac0b 100644 --- a/source/gx/gui/menu.c +++ b/source/gx/gui/menu.c @@ -32,57 +32,13 @@ #include #ifdef HW_RVL -static gx_texture *w_pointer[2]; +gx_texture *w_pointer; #endif t_input_menu m_input; /*****************************************************************************/ -/* Common GUI images */ -/*****************************************************************************/ -gui_image logo_main = {NULL,Main_logo_png,204,362,232,56}; -gui_image logo_small = {NULL,Main_logo_png,466,40,152,44}; -gui_image top_banner = {NULL,Banner_top_png,0,0,640,108}; -gui_image bottom_banner = {NULL,Banner_bottom_png,0,380,640,100}; -gui_image main_banner = {NULL,Banner_main_png,0,340,640,140}; -gui_image bg_right = {NULL,Bg_main_png,356,144,348,288}; -gui_image bg_center = {NULL,Bg_main_png,146,80,348,288}; -gui_image bg_overlay_line = {NULL,Bg_overlay_png,0,0,640,480}; -gui_image left_frame = {NULL,Frame_s1_png,8,70,372,336}; -gui_image right_frame = {NULL,Frame_s2_png,384,264,248,140}; - -/*****************************************************************************/ -/* Common GUI items */ -/*****************************************************************************/ -gui_item action_cancel = -{ -#ifdef HW_RVL - NULL,Key_B_wii_png,"","Back",10,422,28,28 -#else - NULL,Key_B_gcn_png,"","Back",10,422,28,28 -#endif -}; - -gui_item action_select = -{ -#ifdef HW_RVL - NULL,Key_A_wii_png,"","",602,422,28,28 -#else - NULL,Key_A_gcn_png,"","",602,422,28,28 -#endif -}; - -gui_item action_exit = -{ -#ifdef HW_RVL - NULL,Key_home_png,"","",10,372,68,28 -#else - NULL,Key_trigger_Z_png,"","",10,372,92,28 -#endif -}; - -/*****************************************************************************/ -/* Buttons data */ +/* Generic Buttons data */ /*****************************************************************************/ static butn_data arrow_up_data = { @@ -109,11 +65,64 @@ static butn_data button_icon_data = }; /*****************************************************************************/ -/* Arrow Buttons for items list menu */ +/* Generic GUI items */ /*****************************************************************************/ -static gui_butn arrow_up = {&arrow_up_data,172,86,36,36}; -static gui_butn arrow_down = {&arrow_down_data,172,356,36,36}; +static gui_item action_cancel = +{ +#ifdef HW_RVL + NULL,Key_B_wii_png,"","Back",10,422,28,28 +#else + NULL,Key_B_gcn_png,"","Back",10,422,28,28 +#endif +}; +static gui_item action_select = +{ +#ifdef HW_RVL + NULL,Key_A_wii_png,"","",602,422,28,28 +#else + NULL,Key_A_gcn_png,"","",602,422,28,28 +#endif +}; + +static gui_item action_exit = +{ +#ifdef HW_RVL + NULL,Key_home_png,"","",10,372,68,28 +#else + NULL,Key_trigger_Z_png,"","",10,372,92,28 +#endif +}; + +/*****************************************************************************/ +/* Generic GUI backgrounds */ +/*****************************************************************************/ +static gui_image bg_main[4] = +{ + {NULL,Bg_main_png,IMAGE_VISIBLE|IMAGE_FADE,146,80,348,288,255,{0,0},{0,0}}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255,{0,0},{0,0}}, + {NULL,Banner_main_png,IMAGE_VISIBLE|IMAGE_SLIDE_Y,0,340,640,140,255,{0,0},{0,0}}, + {NULL,Main_logo_png,IMAGE_VISIBLE|IMAGE_SLIDE_Y,200,362,232,56,255,{0,0},{0,0}} +}; + +static gui_image bg_misc[5] = +{ + {NULL,Bg_main_png,IMAGE_VISIBLE,146,80,348,288,255,{0,0},{0,0}}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255,{0,0},{0,0}}, + {NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255,{0,0},{0,0}}, + {NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255,{0,0},{0,0}}, + {NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255,{0,0},{0,0}} +}; + +static gui_image bg_list[6] = +{ + {NULL,Bg_main_png,IMAGE_VISIBLE,356,144,348,288,255,{0,0},{0,0}}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255,{0,0},{0,0}}, + {NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255,{0,0},{0,0}}, + {NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255,{0,0},{0,0}}, + {NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255,{0,0},{0,0}}, + {NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,128,{0,0},{0,0}} +}; /*****************************************************************************/ /* Menu Items description */ @@ -195,52 +204,56 @@ static gui_item items_options[5] = /* Menu Buttons description */ /*****************************************************************************/ +/* Generic Buttons for list menu */ +static gui_butn arrow_up = {&arrow_up_data,BUTTON_OVER_SFX,14,76,360,32}; +static gui_butn arrow_down = {&arrow_down_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,14,368,360,32}; + /* Generic list menu */ -static gui_butn buttons_generic[4] = +static gui_butn buttons_list[4] = { - {&button_text_data,52,132,276,48}, - {&button_text_data,52,188,276,48}, - {&button_text_data,52,244,276,48}, - {&button_text_data,52,300,276,48} -}; + {&button_text_data,BUTTON_VISIBLE|BUTTON_OVER_SFX, 52,132,276,48}, + {&button_text_data,BUTTON_VISIBLE|BUTTON_OVER_SFX, 52,188,276,48}, + {&button_text_data,BUTTON_VISIBLE|BUTTON_OVER_SFX, 52,244,276,48}, + {&button_text_data,BUTTON_VISIBLE|BUTTON_OVER_SFX, 52,300,276,48} + }; /* Main menu */ static gui_butn buttons_main[6] = { - {&button_icon_data, 80, 50,148,132}, - {&button_icon_data,246, 50,148,132}, - {&button_icon_data,412, 50,148,132}, - {&button_icon_data, 80,194,148,132}, - {&button_icon_data,246,194,148,132}, - {&button_icon_data,412,194,148,132} + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,80, 50,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,246, 50,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,412, 50,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,80,194,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,246,194,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,412,194,148,132} }; /* Load Game menu */ #ifdef HW_RVL static gui_butn buttons_load[4] = { - {&button_icon_data,246,102,148,132}, - {&button_icon_data, 80,248,148,132}, - {&button_icon_data,246,248,148,132}, - {&button_icon_data,412,248,148,132} + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,246,102,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX, 80,248,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,246,248,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,412,248,148,132} }; #else static gui_butn buttons_load[3] = { - {&button_icon_data, 80,180,148,132}, - {&button_icon_data,246,180,148,132}, - {&button_icon_data,412,180,148,132} + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX, 80,180,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,246,180,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,412,180,148,132} }; #endif /* Options menu */ static gui_butn buttons_options[5] = { - {&button_icon_data, 80,120,148,132}, - {&button_icon_data,246,120,148,132}, - {&button_icon_data,412,120,148,132}, - {&button_icon_data,162,264,148,132}, - {&button_icon_data,330,264,148,132} + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX, 80,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,246,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,412,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,162,264,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,330,264,148,132} }; /*****************************************************************************/ @@ -251,156 +264,131 @@ static gui_butn buttons_options[5] = static gui_menu menu_main = { "", - 0,0,6,6,3, + 0,0, + 6,6,4, + {3,3}, items_main, buttons_main, - &bg_overlay_line, - &bg_center, - &logo_main, - {NULL,NULL}, - {NULL,&main_banner}, + bg_main, {&action_exit,NULL}, - {NULL,NULL} + {NULL,NULL}, + FALSE }; /* Load Game menu */ static gui_menu menu_load = { "Load Game", + 0,0, #ifdef HW_RVL - 0,0,4,4,3, + 4,4,5, + {1,3}, #else - 0,0,3,3,0, + 3,3,5, + {3,0}, #endif items_load, buttons_load, - &bg_overlay_line, - &bg_center, - &logo_small, - {NULL,NULL}, - {&top_banner,&bottom_banner}, + bg_misc, {&action_cancel, &action_select}, - {NULL, NULL} + {NULL,NULL}, + FALSE }; /* Options menu */ static gui_menu menu_options = { "Settings", - 0,0,5,5,3, + 0,0, + 5,5,5, + {3,2}, items_options, buttons_options, - &bg_overlay_line, - &bg_center, - &logo_small, - {NULL,NULL}, - {&top_banner,&bottom_banner}, + bg_misc, {&action_cancel, &action_select}, - {NULL, NULL} + {NULL,NULL}, + FALSE }; /* System Options menu */ static gui_menu menu_system = { "System Options", - 0,0,6,4,1, + 0,0, + 6,4,6, + {1,1}, items_system, - buttons_generic, - &bg_overlay_line, - &bg_right, - &logo_small, - {&left_frame,NULL}, - {&top_banner,&bottom_banner}, + buttons_list, + bg_list, {&action_cancel, &action_select}, - {NULL, &arrow_down} + {&arrow_up,&arrow_down}, + FALSE }; /* Video Options menu */ static gui_menu menu_video = { "Video Options", - 0,0,8,4,1, + 0,0, + 8,4,6, + {1,1}, items_video, - buttons_generic, - &bg_overlay_line, - &bg_right, - &logo_small, - {&left_frame,NULL}, - {&top_banner,&bottom_banner}, + buttons_list, + bg_list, {&action_cancel, &action_select}, - {NULL, &arrow_down} + {&arrow_up,&arrow_down}, + FALSE }; /* Sound Options menu */ static gui_menu menu_audio = { "Sound Options", - 0,0,5,4,1, + 0,0, + 5,4,6, + {1,1}, items_audio, - buttons_generic, - &bg_overlay_line, - &bg_right, - &logo_small, - {&left_frame,NULL}, - {&top_banner,&bottom_banner}, + buttons_list, + bg_list, {&action_cancel, &action_select}, - {NULL, &arrow_down} + {&arrow_up,&arrow_down}, + FALSE }; /*****************************************************************************/ /* Generic GUI routines */ /*****************************************************************************/ -static void menu_initialize(gui_menu *menu) +/* Allocate texture images data */ +void GUI_InitMenu(gui_menu *menu) { int i; gui_item *item; - gui_image *image; gui_butn *button; + gui_image *image; -#ifdef HW_RVL - /* allocate wiimote pointer data (only done once) */ - w_pointer[0] = gxTextureOpenPNG(generic_point_png); -/* w_pointer[1] = gxTextureOpenPNG(generic_openhand);*/ -#endif + /* background elements */ + for (i=0; imax_images; i++) + { + image = &menu->bg_images[i]; + image->texture = gxTextureOpenPNG(image->data); + } - /* allocate background overlay texture */ - image = menu->overlay; - if (image) image->texture = gxTextureOpenPNG(image->data); - - /* allocate background image texture */ - image = menu->background; - if (image) image->texture = gxTextureOpenPNG(image->data); - - /* allocate logo texture */ - image = menu->logo; - if (image) image->texture = gxTextureOpenPNG(image->data); - - /* allocate background elements textures */ for (i=0; i<2; i++) { - /* banners */ - image = menu->banners[i]; - if (image) image->texture = gxTextureOpenPNG(image->data); - - /* frames */ - image = menu->frames[i]; - if (image) image->texture = gxTextureOpenPNG(image->data); - /* key helpers */ item = menu->helpers[i]; if (item) item->texture = gxTextureOpenPNG(item->data); + + /* arrows */ + button = menu->arrows[i]; + if (button) + { + if (!button->data->texture[0]) button->data->texture[0] = gxTextureOpenPNG(button->data->image[0]); + if (!button->data->texture[1]) button->data->texture[1] = gxTextureOpenPNG(button->data->image[1]); + } } - /* allocate arrow buttons */ - if (menu->max_items > menu->max_buttons) - { - arrow_up_data.texture[0] = gxTextureOpenPNG(arrow_up_data.image[0]); - arrow_up_data.texture[1] = gxTextureOpenPNG(arrow_up_data.image[1]); - arrow_down_data.texture[0] = gxTextureOpenPNG(arrow_down_data.image[0]); - arrow_down_data.texture[1] = gxTextureOpenPNG(arrow_down_data.image[1]); - } - - /* allocate menu buttons */ + /* menu buttons */ for (i=0; imax_buttons; i++) { button = &menu->buttons[i]; @@ -408,7 +396,7 @@ static void menu_initialize(gui_menu *menu) if (!button->data->texture[1]) button->data->texture[1] = gxTextureOpenPNG(button->data->image[1]); } - /* allocate item textures */ + /* menu items */ for (i=0; imax_items; i++) { item = &menu->items[i]; @@ -416,50 +404,37 @@ static void menu_initialize(gui_menu *menu) } } -static void menu_delete(gui_menu *menu) +/* release allocated memory */ +void GUI_DeleteMenu(gui_menu *menu) { int i; gui_butn *button; gui_item *item; + gui_image *image; - /* free background image texture */ - if (menu->overlay) - gxTextureClose(&menu->overlay->texture); - - /* free background image texture */ - if (menu->background) - gxTextureClose(&menu->background->texture); - - /* free logo texture */ - if (menu->logo) - gxTextureClose(&menu->logo->texture); - - /* free background elements textures */ - for (i=0; i<2; i++) + /* background elements */ + for (i=0; imax_images; i++) { -#ifdef HW_RVL - /* free wiimote pointer data */ - gxTextureClose(&w_pointer[i]); -#endif - - /* banners */ - if (menu->banners[i]) - gxTextureClose(&menu->banners[i]->texture); - - /* frames */ - if (menu->frames[i]) - gxTextureClose(&menu->frames[i]->texture); - - /* key helpers */ - if (menu->helpers[i]) - gxTextureClose(&menu->helpers[i]->texture); - - /* up&down arrows */ - gxTextureClose(&arrow_up_data.texture[i]); - gxTextureClose(&arrow_down_data.texture[i]); + image = &menu->bg_images[i]; + gxTextureClose(&image->texture); } - /* free menu buttons */ + for (i=0; i<2; i++) + { + /* key helpers */ + item = menu->helpers[i]; + if (item) gxTextureClose(&item->texture); + + /* arrows */ + button = menu->arrows[i]; + if (button) + { + gxTextureClose(&button->data->texture[0]); + gxTextureClose(&button->data->texture[1]); + } + } + + /* menu buttons */ for (i=0; imax_buttons; i++) { button = &menu->buttons[i]; @@ -467,7 +442,7 @@ static void menu_delete(gui_menu *menu) gxTextureClose(&button->data->texture[1]); } - /* free item textures */ + /* menu items */ for (i=0; imax_items; i++) { item = &menu->items[i]; @@ -475,110 +450,260 @@ static void menu_delete(gui_menu *menu) } } -static void menu_draw(gui_menu *menu) +void GUI_DrawMenu(gui_menu *menu) { int i; gui_item *item; gui_butn *button; gui_image *image; - /* draw background */ - if ((menu == &menu_main) && genromsize) + /* background color */ + if (menu->screenshot) { - gxClearScreen ((GXColor)BLACK); + gxClearScreen((GXColor)BLACK); gxDrawScreenshot(128); - image = menu->overlay; - if (image) gxDrawRepeat(image->texture,image->x,image->y,image->w,image->h); } else { - gxClearScreen ((GXColor)BACKGROUND); - image = menu->overlay; - if (image) gxDrawRepeat(image->texture,image->x,image->y,image->w,image->h); - image = menu->background; - if (image) gxDrawTexture(image->texture,image->x,image->y,image->w,image->h,255); + gxClearScreen((GXColor)BACKGROUND); } - for (i=0; i<2; i++) + /* background elements */ + for (i=0; imax_images; i++) { - /* draw top&bottom banners */ - image = menu->banners[i]; - if (image) gxDrawTexture(image->texture,image->x,image->y,image->w,image->h,255); - - /* draw frames */ - image = menu->frames[i]; - if (image) gxDrawTexture(image->texture,image->x,image->y,image->w,image->h, 128); + image = &menu->bg_images[i]; + if (image->state & IMAGE_REPEAT) gxDrawTextureRepeat(image->texture,image->x,image->y,image->w,image->h,image->alpha); + else if (image->state & IMAGE_VISIBLE)gxDrawTexture(image->texture,image->x,image->y,image->w,image->h,image->alpha); } - /* draw logo */ - image = menu->logo; - if (image) gxDrawTexture(image->texture,image->x,image->y,image->w,image->h,255); - - /* draw title */ - FONT_alignLeft(menu->title, 22,10,56, (GXColor)WHITE); - - /* draw left comment */ - item = menu->helpers[0]; - if (item) - { - gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); - FONT_alignLeft(item->comment,16,item->x+item->w+6,item->y+(item->h-16)/2 + 16,(GXColor)WHITE); - } + /* menu title */ + FONT_write(menu->title, 22,10,56,640,(GXColor)WHITE); /* draw buttons + items */ for (i=0; imax_buttons; i++) { - /* draw button */ button = &menu->buttons[i]; - if (i == menu->selected)gxDrawTexture(button->data->texture[1],button->x-2,button->y-2,button->w+4,button->h+4,255); - else gxDrawTexture(button->data->texture[0],button->x,button->y,button->w, button->h,255); - /* draw item */ - item = &menu->items[menu->offset +i]; - if (i == menu->selected) + if (button->state & BUTTON_VISIBLE) { - /* selected item */ - if (item->data) gxDrawTexture(item->texture, item->x-2,item->y-2,item->w+4,item->h+4,255); - else FONT_writeCenter(item->text,18,button->x,button->x+button->w,button->y+(button->h-18)/2+18,(GXColor)DARK_GREY); - - /* update help comment */ - if (menu->helpers[1]) + /* draw button + items */ + item = &menu->items[menu->offset +i]; + if (i == menu->selected) { - strcpy(menu->helpers[1]->comment,item->comment); - item = menu->helpers[1]; - gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); - FONT_alignRight(item->comment,16,item->x-6,item->y+(item->h-16)/2+16,(GXColor)WHITE); + gxDrawTexture(button->data->texture[1],button->x-2,button->y-2,button->w+4,button->h+4,255); + if (item->data) + { + gxDrawTexture(item->texture, item->x-2,item->y-2,item->w+4,item->h+4,255); + } + else + { + FONT_writeCenter(item->text,18,button->x,button->x+button->w,button->y+(button->h-18)/2+18,(GXColor)DARK_GREY); + } + + /* update help comment */ + if (menu->helpers[1]) strcpy(menu->helpers[1]->comment,item->comment); + } + else + { + gxDrawTexture(button->data->texture[0],button->x,button->y,button->w, button->h,255); + if (item->data) + { + gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); + } + else + { + FONT_writeCenter(item->text,16,button->x,button->x+button->w,button->y+(button->h - 16)/2+16,(GXColor)DARK_GREY); + } } - } - else - { - /* normal item */ - if (item->data) gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); - else FONT_writeCenter(item->text,16,button->x,button->x+button->w,button->y+(button->h - 16)/2+16,(GXColor)DARK_GREY); } } - /* Arrows (Items list only) */ + /* draw arrow */ for (i=0; i<2; i++) { button = menu->arrows[i]; if (button) { - if (menu->selected == menu->max_buttons + i) + if (button->state & BUTTON_VISIBLE) { - gxDrawTexture(button->data->texture[1],button->x-2,button->y-2,button->w+4,button->h+4,255); - } - else - { - gxDrawTexture(button->data->texture[0],button->x,button->y,button->w,button->h,255); + if (menu->selected == (menu->max_buttons + i)) + { + gxDrawTexture(button->data->texture[1],button->x-2,button->y-2,button->w+4,button->h+4,255); + } + else + { + gxDrawTexture(button->data->texture[0],button->x,button->y,button->w, button->h,255); + } } } } + + /* left comment */ + item = menu->helpers[0]; + if (item) + { + gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); + FONT_write(item->comment,16,item->x+item->w+6,item->y+(item->h-16)/2 + 16,640,(GXColor)WHITE); + } + + /* right comment */ + item = menu->helpers[1]; + if (item) + { + if (menu->selected < menu->max_buttons) + { + gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); + FONT_alignRight(item->comment,16,item->x-6,item->y+(item->h-16)/2+16,(GXColor)WHITE); + } + } } -/* Menu Prompt */ +/* Menu transitions effect */ +static void GUI_DrawMenuFX(gui_menu *menu, u8 speed, u8 out) +{ + int i,temp,xpos,ypos; + int max_offset = 0; + gui_item *item; + gui_butn *button; + gui_image *image; + + /* find maximal offset */ + for (i=0; imax_images; i++) + { + image = &menu->bg_images[i]; + + if (image->state & IMAGE_SLIDE_X) + { + temp = (image->x > 320) ? (640 - image->x) : (image->x + image->w); + if (max_offset < temp) max_offset = temp; + } + + if (image->state & IMAGE_SLIDE_Y) + { + temp = (image->y > 240) ? (480 - image->y) : (image->y + image->h); + if (max_offset < temp) max_offset = temp; + } + } + + /* set position ranges*/ + for (i=0; imax_images; i++) + { + image = &menu->bg_images[i]; + + if (image->state & IMAGE_SLIDE_X) + { + image->xrange[out] = (image->x > 320) ? (image->x + max_offset) : (image->x - max_offset); + image->xrange[out^1] = image->x; + } + + if (image->state & IMAGE_SLIDE_Y) + { + image->yrange[out] = (image->y > 240) ? (image->y + max_offset) : (image->y - max_offset); + image->yrange[out^1] = image->y; + } + } + + /* Alpha steps */ + int alpha = out ? 255 : 0; + int alpha_step = (255 * speed) / max_offset; + if (out) alpha_step = -alpha_step; + + /* Intialize Menu */ + GUI_InitMenu(menu); + + /* Let's loop until final position has been reached */ + while (max_offset > 0) + { + /* background color */ + if (menu->screenshot) + { + gxClearScreen((GXColor)BLACK); + if (alpha > 127) gxDrawScreenshot(128); + else gxDrawScreenshot(255 - alpha); + } + else + { + gxClearScreen((GXColor)BACKGROUND); + } + + /* background elements */ + for (i=0; imax_images; i++) + { + image = &menu->bg_images[i]; + + /* default position */ + xpos = image->x; + ypos = image->y; + + /* update position */ + if (image->state & IMAGE_SLIDE_X) + { + xpos = (image->xrange[0] < image->xrange[1]) ? (image->xrange[1] - max_offset) : (image->xrange[1] + max_offset); + } + if (image->state & IMAGE_SLIDE_Y) + { + ypos = (image->yrange[0] < image->yrange[1]) ? (image->yrange[1] - max_offset) : (image->yrange[1] + max_offset); + } + + if ((image->state & IMAGE_FADE) && ((out && (image->alpha > alpha)) || (!out && (image->alpha < alpha)))) + { + /* FADE In-Out */ + if (image->state & IMAGE_REPEAT) gxDrawTextureRepeat(image->texture,xpos,ypos,image->w,image->h,alpha); + else if (image->state & IMAGE_VISIBLE)gxDrawTexture(image->texture,xpos,ypos,image->w,image->h,alpha); + } + else + { + if (image->state & IMAGE_REPEAT) gxDrawTextureRepeat(image->texture,xpos,ypos,image->w,image->h,image->alpha); + else if (image->state & IMAGE_VISIBLE)gxDrawTexture(image->texture,xpos,ypos,image->w,image->h,image->alpha); + } + } + + /* draw buttons + items */ + for (i=0; imax_buttons; i++) + { + button = &menu->buttons[i]; + + if (button->state & BUTTON_VISIBLE) + { + /* draw button + items */ + item = &menu->items[menu->offset + i]; + gxDrawTexture(button->data->texture[0],button->x,button->y,button->w, button->h,alpha); + if (item->data) gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,alpha); + } + } + + /* update offset */ + max_offset -= speed; + + /* update alpha */ + alpha += alpha_step; + if (alpha > 255) alpha = 255; + else if (alpha < 0) alpha = 0; + + /* copy EFB to XFB */ + gxSetScreen (); + } + + /* final position */ + if (!out) + { + GUI_DrawMenu(menu); + gxSetScreen (); + } + else if (menu->screenshot) + { + gxClearScreen((GXColor)BLACK); + gxDrawScreenshot(255); + gxSetScreen (); + } + + GUI_DeleteMenu(menu); +} + + +/* Window Prompt */ /* prompt window slides in & out */ -static int menu_prompt(gui_menu *parent, char *title, char *items[], u8 nb_items) +int GUI_WindowPrompt(gui_menu *parent, char *title, char *items[], u8 nb_items) { int i, ret, quit = 0; s32 selected = 0; @@ -615,7 +740,7 @@ static int menu_prompt(gui_menu *parent, char *title, char *items[], u8 nb_items int ypos = (window->height - top->height - (h*nb_items) - (nb_items-1)*20)/2; ypos = ypos + ywindow + top->height; - /* get initial vertical offset */ + /* set initial vertical offset */ int yoffset = ywindow + window->height; /* slide in */ @@ -623,7 +748,7 @@ static int menu_prompt(gui_menu *parent, char *title, char *items[], u8 nb_items while (yoffset > 0) { /* draw parent menu */ - menu_draw(parent); + GUI_DrawMenu(parent); /* draw window */ gxDrawTexture(window,xwindow,ywindow-yoffset,window->width,window->height,208); @@ -643,14 +768,14 @@ static int menu_prompt(gui_menu *parent, char *title, char *items[], u8 nb_items gxSetScreen (); /* slide speed */ - yoffset -=60; + yoffset -= 60; } /* draw menu */ while (quit == 0) { /* draw parent menu (should have been initialized first) */ - menu_draw(parent); + GUI_DrawMenu(parent); /* draw window */ gxDrawTexture(window,xwindow,ywindow,window->width,window->height,208); @@ -674,11 +799,9 @@ static int menu_prompt(gui_menu *parent, char *title, char *items[], u8 nb_items #ifdef HW_RVL if (Shutdown) { - /* autosave SRAM/State */ - memfile_autosave(); - - /* shutdown Wii */ - DI_Close(); + gxTextureClose(&w_pointer); + GUI_DeleteMenu(parent); + shutdown(); SYS_ResetSystem(SYS_POWEROFF, 0, 0); } else if (m_input.ir.valid) @@ -689,8 +812,7 @@ static int menu_prompt(gui_menu *parent, char *title, char *items[], u8 nb_items /* draw wiimote pointer */ gxResetAngle(m_input.ir.angle); - gx_texture *texture = w_pointer[0]; - gxDrawTexture(texture,x-texture->width/2,y-texture->height/2,texture->width,texture->height,255); + gxDrawTexture(w_pointer,x-w_pointer->width/2,y-w_pointer->height/2,w_pointer->width,w_pointer->height,255); gxResetAngle(0.0); /* check for valid buttons */ @@ -744,14 +866,14 @@ static int menu_prompt(gui_menu *parent, char *title, char *items[], u8 nb_items } } - /* get initial vertical offset */ + /* reset initial vertical offset */ yoffset = 0; /* slide out */ while (yoffset < (ywindow + window->height)) { /* draw parent menu */ - menu_draw(parent); + GUI_DrawMenu(parent); /* draw window + header */ gxDrawTexture(window,xwindow,ywindow-yoffset,window->width,window->height,208); @@ -767,7 +889,7 @@ static int menu_prompt(gui_menu *parent, char *title, char *items[], u8 nb_items FONT_writeCenter(items[i],18,xpos,xpos+w,ypos+i*(20+h)+(h+18)/2-yoffset,(GXColor)WHITE); } - yoffset +=60; + yoffset += 60; gxSetScreen (); } @@ -779,108 +901,6 @@ static int menu_prompt(gui_menu *parent, char *title, char *items[], u8 nb_items return ret; } -/* Basic menu sliding effect */ -/* this basically makes the bottom & top banners sliding in or out */ -/* when a game is displayed in background, it is faded accordingly */ -static void menu_slide(gui_menu *menu, u8 speed, u8 out) -{ - int yoffset; - int yfinal[3]; - gui_image *image[3]; - gui_image *temp; - - menu_initialize(menu); - - yoffset = 0; - yfinal[0] = 0; - yfinal[1] = 0; - yfinal[2] = 0; - - /* Main Logo (top or bottom) */ - image[2] = menu->logo; - - /* Top banner */ - image[0] = menu->banners[0]; - if (image[0]) - { - /* intial offset */ - yoffset = image[0]->y + image[0]->h; - - /* final ypos */ - yfinal[0] = out ? (-image[0]->h) : (image[0]->y); - if (image[2] && !image[1]) yfinal[2] = out ? (image[2]->y - yoffset) : image[2]->y; - } - - /* Bottom banner */ - image[1] = menu->banners[1]; - if (image[1]) - { - if ((480 + image[1]->h - image[1]->y) > offset) - { - /* intial offset */ - yoffset = 480 - image[1]->y; - - /* final ypos */ - yfinal[1] = out ? 480 : (image[1]->y); - if (image[2] && !image[0]) yfinal[2] = out ? (image[2]->y + yoffset) : image[2]->y; - } - } - - /* Alpha steps */ - u16 alpha = out ? 128 : 255; - s16 alpha_step = (127 * speed) / yoffset; - if (!out) alpha_step = -alpha_step; - - /* Let's loop until final position has been reached */ - while (offset > 0) - { - if ((menu == &menu_main) && genromsize) - { - gxClearScreen((GXColor)BLACK); - gxDrawScreenshot(alpha); - } - else - { - gxClearScreen((GXColor)BACKGROUND); - temp = menu->overlay; - if (temp) gxDrawRepeat(temp->texture,temp->x,temp->y,temp->w,temp->h); - temp = menu->background; - if (temp) gxDrawTexture(temp->texture,temp->x,temp->y,temp->w,temp->h,255); - } - - /* draw top banner + logo */ - if (image[out]) - { - gxDrawTexture(image[out]->texture,image[out]->x,yfinal[out]-yoffset,image[out]->w,image[out]->h,255); - if (image[2] && !image[out^1]) gxDrawTexture(image[2]->texture,image[2]->x,yfinal[2]-yoffset,image[2]->w,image[2]->h,255); - } - /* draw bottom banner + logo */ - if (image[out^1]) - { - gxDrawTexture(image[out^1]->texture,image[out^1]->x,yfinal[out^1]+yoffset,image[out^1]->w,image[out^1]->h,255); - if (image[2] && !image[out]) gxDrawTexture(image[2]->texture,image[2]->x,image[2]->y+yoffset,image[2]->w,image[2]->h,255); - } - - /* update offset */ - yoffset -= speed; - - /* update alpha */ - alpha += alpha_step; - if (alpha > 255) alpha = 255; - - /* copy EFB to XFB */ - gxSetScreen (); - } - - /* final position */ - if (!out) - { - menu_draw(menu); - gxSetScreen (); - } - - menu_delete(menu); -} #define MAX_COLORS 14 #define VERSION "Version 1.03" @@ -906,39 +926,41 @@ static GXColor background_colors[MAX_COLORS]= static s8 color_cnt = 0; -static int menu_callback(gui_menu *menu) +int GUI_RunMenu(gui_menu *menu) { - s32 voice,old; + int selected,quit=0; + gui_butn *button; u16 p; u16 max_buttons = menu->max_buttons; u16 max_items = menu->max_items; - u16 shift = menu->shift; + u16 shift[2] = {menu->shift[0],menu->shift[1]}; #ifdef HW_RVL int i,x,y; - gui_butn *button; #endif - for(;;) + char *items[3] = { - menu_draw(menu); - old = menu->selected; - p = m_input.keys; + "View Credits", + "Exit to Loader", +#ifdef HW_RVL + "Exit to System Menu" +#else + "Reset System" +#endif + }; + + while(quit==0) + { + GUI_DrawMenu(menu); + selected = menu->selected; #ifdef HW_RVL if (Shutdown) { - /* system shutdown */ - memfile_autosave(); - system_shutdown(); - audio_shutdown(); - free(cart_rom); - free(texturemem); - FONT_Shutdown(); - VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK); - VIDEO_Flush(); - VIDEO_WaitVSync(); - DI_Close(); + gxTextureClose(&w_pointer); + GUI_DeleteMenu(menu); + shutdown(); SYS_ResetSystem(SYS_POWEROFF, 0, 0); } else if (m_input.ir.valid) @@ -949,107 +971,115 @@ static int menu_callback(gui_menu *menu) /* draw wiimote pointer */ gxResetAngle(m_input.ir.angle); - gx_texture *texture = w_pointer[0]; - gxDrawTexture(texture, x-texture->width/2, y-texture->height/2, texture->width, texture->height,255); + gxDrawTexture(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,255); gxResetAngle(0.0); /* check for valid buttons */ + selected = max_buttons + 2; for (i=0; ibuttons[i]; - if ((x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) + if ((button->state & BUTTON_VISIBLE)&&(x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) { - menu->selected = i; + selected = i; break; } } - /* no valid buttons */ - if (i == max_buttons) + for (i=0; i<2; i++) { - menu->selected = i + 2; - - /* check for arrow buttons */ - button = menu->arrows[0]; + button = menu->arrows[i]; if (button) { - if ((y <= button->y + button->h) && (x < 320)) - menu->selected = i; - } - button = menu->arrows[1]; - if (button) - { - if ((y >= button->y) && (x < 320)) - menu->selected = i + 1; + if (button->state & BUTTON_VISIBLE) + { + if ((x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) + { + selected = max_buttons + i; + break; + } + } } } } + else + { + /* reinitialize selection */ + if (selected >= menu->max_buttons) selected = 0; + } #endif /* update screen */ gxSetScreen (); /* update menu */ - if (p & PAD_BUTTON_UP) + p = m_input.keys; + + if (selected < max_buttons) { - if (menu->selected == 0) + if (p & PAD_BUTTON_UP) { - if (menu->offset) menu->offset --; + if (selected == 0) + { + if (menu->offset) menu->offset --; + } + else if (selected >= shift[0]) + { + selected -= shift[1]; + if (selected < 0) selected = 0; + } } - else if (menu->selected >= shift) + else if (p & PAD_BUTTON_DOWN) { - menu->selected -= shift; + if (selected == (max_buttons - 1)) + { + if ((menu->offset + selected < (max_items - 1))) menu->offset ++; + } + else if ((shift[1] == 1) || (selected < shift[0])) + { + selected += shift[0]; + if (selected >= max_buttons) selected = max_buttons - 1; + } } - } - else if (p & PAD_BUTTON_DOWN) - { - if (menu->selected == (max_buttons - 1)) + else if (p & PAD_BUTTON_LEFT) { - if ((menu->offset + menu->selected < (max_items - 1))) menu->offset ++; + if (max_buttons == max_items) + { + selected --; + if (selected < 0) selected = 0; + } + else + { + quit = -1; + } } - else if ((menu->selected + shift) < max_buttons) + else if (p & PAD_BUTTON_RIGHT) { - menu->selected += shift; - } - } - else if (p & PAD_BUTTON_LEFT) - { - if (shift != 1) - { - menu->selected --; - if (menu->selected < 0) menu->selected = 0; - } - else - { - return 0-2-menu->offset-menu->selected; - } - } - else if (p & PAD_BUTTON_RIGHT) - { - if (shift != 1) - { - menu->selected ++; - if (menu->selected >= max_buttons) menu->selected = max_buttons - 1; - } - else - { - return (menu->offset + menu->selected); + if (max_buttons == max_items) + { + selected ++; + if (selected >= max_buttons) selected = max_buttons - 1; + } + else + { + quit = 1; + } } } - /* sound fx */ - if (menu->selected != old) + if (p & PAD_BUTTON_A) { - if (menu->selected < max_buttons + 2) - { - voice = ASND_GetFirstUnusedVoice(); - if(voice >= 0) ASND_SetVoice(voice,VOICE_MONO_16BIT,22050,0,(u8 *)button_over_pcm,button_over_pcm_size,255,255,NULL); - } + if (selected < max_buttons) quit = 1; + else if (selected == max_buttons) menu->offset --; /* up arrow */ + else if (selected == (max_buttons+1))menu->offset ++; /* down arrow */ } - - /* swap menu background color */ - if (p & PAD_TRIGGER_R) + else if (p & PAD_BUTTON_B) { + quit = 2; + } + else if (p & PAD_TRIGGER_R) + { + /* swap menu background color (debug) */ color_cnt++; if (color_cnt >= MAX_COLORS) color_cnt = 0; BACKGROUND.r = background_colors[color_cnt].r; @@ -1059,6 +1089,7 @@ static int menu_callback(gui_menu *menu) } else if (p & PAD_TRIGGER_L) { + /* swap menu background color (debug) */ color_cnt--; if (color_cnt < 0) color_cnt = MAX_COLORS - 1; BACKGROUND.r = background_colors[color_cnt].r; @@ -1066,84 +1097,96 @@ static int menu_callback(gui_menu *menu) BACKGROUND.b = background_colors[color_cnt].b; BACKGROUND.a = background_colors[color_cnt].a; } - - if (p & PAD_BUTTON_A) - { - if (menu->selected < max_buttons) - { - voice = ASND_GetFirstUnusedVoice(); - if(voice >= 0) ASND_SetVoice(voice,VOICE_MONO_16BIT,22050,0,(u8 *)button_select_pcm,button_select_pcm_size,255,255,NULL); - return (menu->offset + menu->selected); - } - else if (menu->selected == max_buttons) menu->offset --; - else if (menu->selected == max_buttons + 1) menu->offset ++; - } - else if (p & PAD_BUTTON_B) - { - return -1; - } else if (p & PAD_TRIGGER_Z) { - char *items[3] = - { - "View Credits", - "Exit to Loader", -#ifdef HW_RVL - "Exit to System Menu" -#else - "Reset System" -#endif - }; - - switch (menu_prompt(menu, VERSION, items,3)) + switch (GUI_WindowPrompt(menu, VERSION, items,3)) { case 1: - memfile_autosave(); - system_shutdown(); - audio_shutdown(); - free(cart_rom); - free(texturemem); - FONT_Shutdown(); - VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK); - VIDEO_Flush(); - VIDEO_WaitVSync(); #ifdef HW_RVL - DI_Close(); + gxTextureClose(&w_pointer); #endif + GUI_DeleteMenu(menu); + shutdown(); exit(0); break; case 2: - memfile_autosave(); - system_shutdown(); - audio_shutdown(); - free(cart_rom); - free(texturemem); - FONT_Shutdown(); - VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK); - VIDEO_Flush(); - VIDEO_WaitVSync(); - #ifdef HW_RVL - DI_Close(); + GUI_DeleteMenu(menu); + shutdown(); +#ifdef HW_RVL + gxTextureClose(&w_pointer); SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); - #else +#else SYS_ResetSystem(SYS_HOTRESET,0,0); - #endif +#endif break; - default: + default: /* TODO */ break; } } - /* update arrows status (items list) */ - menu->arrows[0] = NULL; - menu->arrows[1] = NULL; - if (menu->offset > 0) menu->arrows[0] = &arrow_up; - if (menu->offset + max_buttons < max_items) menu->arrows[1] = &arrow_down; - } -} + /* selected item has changed ? */ + if (menu->selected != selected) + { + if (selected < max_buttons) + { + /* sound fx */ + button = &menu->buttons[selected]; + if (button->state & BUTTON_OVER_SFX) + { + ASND_SetVoice(ASND_GetFirstUnusedVoice(),VOICE_MONO_16BIT,22050,0,(u8 *)button_over_pcm,button_over_pcm_size,200,200,NULL); + } + } + else if (selected < (max_buttons + 2)) + { + /* sound fx */ + button = menu->arrows[selected-max_buttons]; + if (button->state & BUTTON_OVER_SFX) + { + ASND_SetVoice(ASND_GetFirstUnusedVoice(),VOICE_MONO_16BIT,22050,0,(u8 *)button_over_pcm,button_over_pcm_size,200,200,NULL); + } + } + /* update selection */ + menu->selected = selected; + } + + /* update arrows buttons status (items list) */ + button = menu->arrows[0]; + if (button) + { + if (menu->offset > 0) button->state |= BUTTON_VISIBLE; + else button->state &= ~BUTTON_VISIBLE; + } + button = menu->arrows[1]; + if (button) + { + if ((menu->offset + max_buttons) < max_items) button->state |= BUTTON_VISIBLE; + else button->state &= ~BUTTON_VISIBLE; + } + } + + if (quit < 2) + { + if (selected < max_buttons) + { + /* sound fx */ + button = &menu->buttons[selected]; + if (button->state & BUTTON_SELECT_SFX) + { + ASND_SetVoice(ASND_GetFirstUnusedVoice(),VOICE_MONO_16BIT,22050,0,(u8 *)button_select_pcm,button_select_pcm_size,200,200,NULL); + } + } + + /* return item selection index */ + if (quit < 0) return -2-menu->offset-menu->selected; + else return (menu->offset + menu->selected); + } + + /* leave menu (default) */ + return -1; + } /*************************************************************************** * drawmenu (deprecated) @@ -1277,6 +1320,7 @@ static void soundmenu () gui_menu *m = &menu_audio; gui_item *items = m->items; + GUI_InitMenu(m); while (quit == 0) { @@ -1288,9 +1332,8 @@ static void soundmenu () else if (config.hq_fm == 1) sprintf (items[4].text, "HQ YM2612: LINEAR"); else sprintf (items[4].text, "HQ YM2612: SINC"); - menu_initialize(m); - ret = menu_callback(m); - menu_delete(m); + ret = GUI_RunMenu(m); + switch (ret) { case 0: @@ -1339,6 +1382,8 @@ static void soundmenu () break; } } + + GUI_DeleteMenu(m); } /**************************************************************************** @@ -1347,11 +1392,12 @@ static void soundmenu () ****************************************************************************/ static void systemmenu () { - int ret, quit = 0; + int ret = 255; + int quit = 0; gui_menu *m = &menu_system; gui_item *items = m->items; - menu_initialize(m); + GUI_InitMenu(m); while (quit == 0) { @@ -1366,12 +1412,12 @@ static void systemmenu () else if (config.sram_auto == 1) sprintf (items[4].text, "Auto SRAM: MCARD A"); else if (config.sram_auto == 2) sprintf (items[4].text, "Auto SRAM: MCARD B"); else sprintf (items[4].text, "Auto SRAM: OFF"); - if (config.freeze_auto == 0) sprintf (items[5].text, "Auto FREEZE: FAT"); - else if (config.freeze_auto == 1) sprintf (items[5].text, "Auto FREEZE: MCARD A"); - else if (config.freeze_auto == 2) sprintf (items[5].text, "Auto FREEZE: MCARD B"); + if (config.state_auto == 0) sprintf (items[5].text, "Auto FREEZE: FAT"); + else if (config.state_auto == 1) sprintf (items[5].text, "Auto FREEZE: MCARD A"); + else if (config.state_auto == 2) sprintf (items[5].text, "Auto FREEZE: MCARD B"); else sprintf (items[5].text, "Auto FREEZE: OFF"); - ret = menu_callback(m); + ret = GUI_RunMenu(m); switch (ret) { @@ -1427,8 +1473,8 @@ static void systemmenu () break; case 5: /*** FreezeState autoload/autosave ***/ - config.freeze_auto ++; - if (config.freeze_auto > 2) config.freeze_auto = -1; + config.state_auto ++; + if (config.state_auto > 2) config.state_auto = -1; break; case -1: @@ -1436,7 +1482,8 @@ static void systemmenu () break; } } - menu_delete(m); + + GUI_DeleteMenu(m); } /**************************************************************************** @@ -1449,7 +1496,7 @@ static void videomenu () gui_menu *m = &menu_video; gui_item *items = m->items; - menu_initialize(m); + GUI_InitMenu(m); while (quit == 0) { @@ -1467,7 +1514,8 @@ static void videomenu () else sprintf (items[4].text, "NTSC Filter: OFF"); sprintf (items[5].text, "Borders: %s", config.overscan ? " ON" : "OFF"); - ret = menu_callback(m); + ret = GUI_RunMenu(m); + switch (ret) { case 0: /*** config.aspect ratio ***/ @@ -1541,7 +1589,8 @@ static void videomenu () break; } } - menu_delete(m); + + GUI_DeleteMenu(m); } /**************************************************************************** @@ -1859,9 +1908,9 @@ static void optionmenu(void) while (quit == 0) { - menu_initialize(m); - ret = menu_callback(m); - menu_delete(m); + GUI_InitMenu(m); + ret = GUI_RunMenu(m); + GUI_DeleteMenu(m); switch (ret) { case 0: @@ -1990,26 +2039,22 @@ static int filemenu () * Load Rom menu * ****************************************************************************/ -extern char rom_filename[MAXJOLIET]; -static u8 load_menu = 0; - static int loadmenu () { - int ret,size,quit = 0; + int ret,size; gui_menu *m = &menu_load; - while (quit == 0) + while (1) { - menu_initialize(m); - ret = menu_callback(m); - menu_delete(m); + GUI_InitMenu(m); + ret = GUI_RunMenu(m); + GUI_DeleteMenu(m); switch (ret) { /*** Button B ***/ case -1: - quit = 1; - break; + return 0; /*** Load from DVD ***/ #ifdef HW_RVL @@ -2017,40 +2062,30 @@ static int loadmenu () #else case 2: #endif - load_menu = menu; size = DVD_Open(cart_rom); if (size) { - dvd_motor_off(); - genromsize = size; - memfile_autosave(); - reloadrom(); - sprintf(rom_filename,"%s",filelist[selection].filename); - rom_filename[strlen(rom_filename) - 4] = 0; - memfile_autoload(); + //dvd_motor_off(); + memfile_autosave(-1,config.state_auto); + reloadrom(size,filelist[selection].filename); + memfile_autoload(config.sram_auto,config.state_auto); return 1; } break; /*** Load from FAT device ***/ default: - load_menu = menu; size = FAT_Open(ret,cart_rom); if (size) { - memfile_autosave(); - genromsize = size; - reloadrom(); - sprintf(rom_filename,"%s",filelist[selection].filename); - rom_filename[strlen(rom_filename) - 4] = 0; - memfile_autoload(); + memfile_autosave(-1,config.state_auto); + reloadrom(size,filelist[selection].filename); + memfile_autoload(config.sram_auto,config.state_auto); return 1; } break; } } - - return 0; } /*************************************************************************** @@ -2178,50 +2213,50 @@ static void showrominfo () * Main Menu * ****************************************************************************/ -void MainMenu (u32 fps) +void MainMenu (void) { int ret, quit = 0; - /* uint32 crccheck;*/ + + /* autosave SRAM */ + memfile_autosave(config.sram_auto,-1); #ifdef HW_RVL if (Shutdown) { - /* system shutdown */ - memfile_autosave(); - system_shutdown(); - audio_shutdown(); - free(cart_rom); - free(texturemem); - FONT_Shutdown(); - VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK); - VIDEO_Flush(); - VIDEO_WaitVSync(); - DI_Close(); + shutdown(); SYS_ResetSystem(SYS_POWEROFF, 0, 0); } -#endif - /* autosave (SRAM only) */ - int temp = config.freeze_auto; - config.freeze_auto = -1; - memfile_autosave(); - config.freeze_auto = temp; + /* wiimote pointer */ + w_pointer = gxTextureOpenPNG(generic_point_png); +#endif gui_menu *m = &menu_main; - /* basic fade-in effect */ - menu_slide(m,10,0); + /* display game screen in background */ + if (genromsize) + { + m->screenshot = 1; + gui_image *image = &m->bg_images[0]; + image->state &= ~IMAGE_VISIBLE; + gui_butn *button = &m->buttons[0]; + button->state |= BUTTON_SELECT_SFX; + button = &m->buttons[3]; + button->state |= BUTTON_SELECT_SFX; + button = &m->buttons[4]; + button->state |= BUTTON_SELECT_SFX; + button = &m->buttons[5]; + button->state |= BUTTON_SELECT_SFX; + } + + /* game screen transition to menu */ + GUI_DrawMenuFX(m,10,0); while (quit == 0) { -/* crccheck = crc32 (0, &sram.sram[0], 0x10000); - strcpy (menutitle,""); - if (genromsize && (crccheck != sram.crc)) strcpy (menutitle, "*** SRAM has been modified ***"); - else if (genromsize) sprintf (menutitle, "%d FPS",fps); -*/ - menu_initialize(m); - ret = menu_callback(m); - menu_delete(m); + GUI_InitMenu(m); + ret = GUI_RunMenu(m); + GUI_DeleteMenu(m); switch (ret) { @@ -2229,11 +2264,8 @@ void MainMenu (u32 fps) case 0: /*** Play Game ***/ if (genromsize) { - /* basic fade-out effect */ - menu_slide(m,10,1); - gxClearScreen ((GXColor)BLACK); - gxDrawScreenshot(0xff); - gxSetScreen (); + /* menu transition to game screen */ + GUI_DrawMenuFX(m,10,1); quit = 1; } break; @@ -2251,7 +2283,7 @@ void MainMenu (u32 fps) break; case 4: /*** Emulator Reset ***/ - if (genromsize || (config.bios_enabled == 3)) + if (genromsize) { system_reset (); gxClearScreen ((GXColor)BLACK); @@ -2270,9 +2302,11 @@ void MainMenu (u32 fps) while (PAD_ButtonsHeld(0)) PAD_ScanPads(); #ifdef HW_RVL while (WPAD_ButtonsHeld(0)) WPAD_ScanPads(); -#endif -#ifndef HW_RVL + /* free wiimote pointer data */ + gxTextureClose(&w_pointer); + +#else /*** Stop the DVD from causing clicks while playing ***/ uselessinquiry (); #endif diff --git a/source/gx/gui/menu.h b/source/gx/gui/menu.h index cc97ddb..3313b38 100644 --- a/source/gx/gui/menu.h +++ b/source/gx/gui/menu.h @@ -28,6 +28,23 @@ #include #endif + +/*****************************************************************************/ +/* GUI Buttons state */ +/*****************************************************************************/ +#define BUTTON_VISIBLE 0x01 +#define BUTTON_OVER_SFX 0x10 +#define BUTTON_SELECT_SFX 0x20 + +/*****************************************************************************/ +/* GUI Image state */ +/*****************************************************************************/ +#define IMAGE_VISIBLE 0x01 +#define IMAGE_REPEAT 0x02 +#define IMAGE_FADE 0x10 +#define IMAGE_SLIDE_X 0x20 +#define IMAGE_SLIDE_Y 0x40 + /*****************************************************************************/ /* GUI png data */ /*****************************************************************************/ @@ -120,27 +137,28 @@ typedef struct /* Item descriptor*/ typedef struct { - gx_texture *texture; /* temporary texture data */ - const u8 *data; /* pointer to png image data (items icon only) */ - char text[64]; /* item string (items list only) */ - char comment[64]; /* item comment */ - u16 x; /* button image or text X position (upper left corner) */ - u16 y; /* button image or text Y position (upper left corner) */ - u16 w; /* button image or text width */ - u16 h; /* button image or text height */ + gx_texture *texture; /* temporary texture data */ + const u8 *data; /* pointer to png image data (items icon only) */ + char text[64]; /* item string (items list only) */ + char comment[64]; /* item comment */ + u16 x; /* item image or text X position (upper left corner) */ + u16 y; /* item image or text Y position (upper left corner) */ + u16 w; /* item image or text width */ + u16 h; /* item image or text height */ } gui_item; /* Button descriptor */ typedef struct { - gx_texture *texture[2]; /* temporary texture datas */ - const u8 *image[2]; /* pointer to png image datas (default) */ + gx_texture *texture[2]; /* temporary texture datas */ + const u8 *image[2]; /* pointer to png image datas (default) */ } butn_data; /* Button descriptor */ typedef struct { butn_data *data; /* pointer to button image/texture data */ + u8 state; /* button state (ACTIVE,VISIBLE,SELECTED...) */ u16 x; /* button image X position (upper left corner) */ u16 y; /* button image Y position (upper left corner) */ u16 w; /* button image pixels width */ @@ -150,32 +168,34 @@ typedef struct /* Image descriptor */ typedef struct { - gx_texture *texture; /* temporary texture data */ - const u8 *data; /* pointer to png image data */ - u16 x; /* button image or text X position (upper left corner) */ - u16 y; /* button image or text Y position (upper left corner) */ - u16 w; /* button image or text width */ - u16 h; /* button image or text height */ + gx_texture *texture; /* temporary texture data */ + const u8 *data; /* pointer to png image data */ + u8 state; /* image state (VISIBLE) */ + u16 x; /* image X position (upper left corner) */ + u16 y; /* image Y position (upper left corner) */ + u16 w; /* image width */ + u16 h; /* image height */ + u8 alpha; /* alpha transparency */ + u16 xrange[2]; /* image X range (slide effect) */ + u16 yrange[2]; /* image Y range (slide effect) */ } gui_image; /* Menu descriptor */ typedef struct { - char title[64]; /* menu title */ - s8 selected; /* index of selected item */ - u8 offset; /* items list offset */ - u8 max_items; /* total number of items */ - u8 max_buttons; /* total number of buttons (not necessary identical) */ - u8 shift; /* number of items by line */ - gui_item *items; /* menu items table */ - gui_butn *buttons; /* menu buttons table */ - gui_image *overlay; /* overlay image */ - gui_image *background; /* background image */ - gui_image *logo; /* logo image */ - gui_image *frames[2]; /* windows (max. 2) */ - gui_image *banners[2]; /* bottom & top banners */ - gui_item *helpers[2]; /* left & right key comments */ - gui_butn *arrows[2]; /* items list up & down arrows */ + char title[64]; /* menu title */ + s8 selected; /* index of selected item */ + u8 offset; /* items list offset */ + u8 max_items; /* total number of items */ + u8 max_buttons; /* total number of buttons */ + u8 max_images; /* total number of background images */ + u8 shift[2]; /* number of buttons per line */ + gui_item *items; /* menu items */ + gui_butn *buttons; /* menu buttons */ + gui_image *bg_images; /* background images */ + gui_item *helpers[2]; /* left & right key comments */ + gui_butn *arrows[2]; /* arrows buttons */ + bool screenshot; /* use gamescreen as background */ } gui_menu; @@ -183,25 +203,15 @@ typedef struct extern u8 SILENT; extern t_input_menu m_input; -/*****************************************************************************/ -/* Common GUI images */ -/*****************************************************************************/ -extern gui_image logo_main; -extern gui_image logo_small; -extern gui_image top_banner; -extern gui_image bottom_banner; -extern gui_image main_banner; -extern gui_image bg_right; -extern gui_image bg_center; -extern gui_image bg_overlay_line; -extern gui_image left_frame; -extern gui_image right_frame; +#ifdef HW_RVL +extern gx_texture *w_pointer; +#endif -/*****************************************************************************/ -/* Common GUI items */ -/*****************************************************************************/ -extern gui_item action_cancel; -extern gui_item action_select; -extern gui_item action_exit; + +extern void MainMenu(void); +extern void GUI_InitMenu(gui_menu *menu); +extern void GUI_DeleteMenu(gui_menu *menu); +extern void GUI_DrawMenu(gui_menu *menu); +extern int GUI_RunMenu(gui_menu *menu); #endif diff --git a/source/gx/gui/oggplayer.c b/source/gx/gui/oggplayer.c new file mode 100644 index 0000000..e22039f --- /dev/null +++ b/source/gx/gui/oggplayer.c @@ -0,0 +1,354 @@ +/* + Copyright (c) 2008 Francisco Muņoz 'Hermes' + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + - The names of the contributors may not be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NO_SOUND + +#include "oggplayer.h" +#include + +/* OGG control */ + +#define READ_SAMPLES 4096 // samples that it must read before to send +#define MAX_PCMOUT 4096 // minimum size to read ogg samples +typedef struct +{ + OggVorbis_File vf; + vorbis_info *vi; + int current_section; + + // OGG file operation + int fd; + int mode; + int eof; + int flag; + int volume; + int seek_time; + + /* OGG buffer control */ + short pcmout[2][READ_SAMPLES + MAX_PCMOUT * 2]; /* take 4k out of the data segment, not the stack */ + int pcmout_pos; + int pcm_indx; + +} private_data_ogg; + +static private_data_ogg private_ogg; + +// OGG thread control + +#define STACKSIZE 8192 + +static u8 oggplayer_stack[STACKSIZE]; +static lwpq_t oggplayer_queue; +static lwp_t h_oggplayer; +static int ogg_thread_running = 0; + +static void ogg_add_callback(int voice) +{ + if (ogg_thread_running <= 0) + { + SND_StopVoice(0); + return; + } + + if (private_ogg.flag & 128) + return; // Ogg is paused + + if (private_ogg.pcm_indx >= READ_SAMPLES) + { + if (SND_AddVoice(0, + (void *) private_ogg.pcmout[private_ogg.pcmout_pos], + private_ogg.pcm_indx << 1) == 0) + { + private_ogg.pcmout_pos ^= 1; + private_ogg.pcm_indx = 0; + private_ogg.flag = 0; + LWP_ThreadSignal(oggplayer_queue); + } + } + else + { + if (private_ogg.flag & 64) + { + private_ogg.flag &= ~64; + LWP_ThreadSignal(oggplayer_queue); + } + } +} + +static void * ogg_player_thread(private_data_ogg * priv) +{ + int first_time = 1; + + ogg_thread_running = 0; + //init + LWP_InitQueue(&oggplayer_queue); + + priv[0].vi = ov_info(&priv[0].vf, -1); + + SND_Pause(0); + + priv[0].pcm_indx = 0; + priv[0].pcmout_pos = 0; + priv[0].eof = 0; + priv[0].flag = 0; + priv[0].current_section = 0; + + ogg_thread_running = 1; + + while (!priv[0].eof) + { + long ret; + if (ogg_thread_running <= 0) + break; + + if (priv[0].flag) + LWP_ThreadSleep(oggplayer_queue); // wait only when i have samples to send + + if (ogg_thread_running <= 0) + break; + + if (priv[0].flag == 0) // wait to all samples are sended + { + if (SND_TestPointer(0, priv[0].pcmout[priv[0].pcmout_pos]) + && SND_StatusVoice(0) != SND_UNUSED) + { + priv[0].flag |= 64; + continue; + } + if (priv[0].pcm_indx < READ_SAMPLES) + { + priv[0].flag = 3; + + if (priv[0].seek_time >= 0) + { + ov_time_seek(&priv[0].vf, priv[0].seek_time); + priv[0].seek_time = -1; + } + + ret + = ov_read( + &priv[0].vf, + (void *) &priv[0].pcmout[priv[0].pcmout_pos][priv[0].pcm_indx], + MAX_PCMOUT,/*0,2,1,*/&priv[0].current_section); + priv[0].flag &= 192; + if (ret == 0) + { + /* EOF */ + if (priv[0].mode & 1) + ov_time_seek(&priv[0].vf, 0); // repeat + else + priv[0].eof = 1; // stops + // + } + else if (ret < 0) + { + /* error in the stream. Not a problem, just reporting it in + case we (the app) cares. In this case, we don't. */ + if (ret != OV_HOLE) + { + if (priv[0].mode & 1) + ov_time_seek(&priv[0].vf, 0); // repeat + else + priv[0].eof = 1; // stops + } + } + else + { + /* we don't bother dealing with sample rate changes, etc, but + you'll have to*/ + priv[0].pcm_indx += ret >> 1; //get 16 bits samples + } + } + else + priv[0].flag = 1; + } + + if (priv[0].flag == 1) + { + if (SND_StatusVoice(0) == SND_UNUSED || first_time) + { + first_time = 0; + if (priv[0].vi->channels == 2) + { + SND_SetVoice(0, VOICE_STEREO_16BIT, priv[0].vi->rate, 0, + (void *) priv[0].pcmout[priv[0].pcmout_pos], + priv[0].pcm_indx << 1, priv[0].volume, + priv[0].volume, ogg_add_callback); + priv[0].pcmout_pos ^= 1; + priv[0].pcm_indx = 0; + priv[0].flag = 0; + } + else + { + SND_SetVoice(0, VOICE_MONO_16BIT, priv[0].vi->rate, 0, + (void *) priv[0].pcmout[priv[0].pcmout_pos], + priv[0].pcm_indx << 1, priv[0].volume, + priv[0].volume, ogg_add_callback); + priv[0].pcmout_pos ^= 1; + priv[0].pcm_indx = 0; + priv[0].flag = 0; + } + } + else + { + // if(priv[0].pcm_indx==0) priv[0].flag=0; // all samples sended + } + + } + + } + ov_clear(&priv[0].vf); + priv[0].fd = -1; + priv[0].pcm_indx = 0; + ogg_thread_running = 0; + + return 0; +} + +void StopOgg() +{ + SND_StopVoice(0); + if (ogg_thread_running > 0) + { + ogg_thread_running = -2; + LWP_ThreadSignal(oggplayer_queue); + LWP_JoinThread(h_oggplayer, NULL); + + while (((volatile int) ogg_thread_running) != 0) + { + ;;; + } + } +} + +int PlayOgg(int fd, int time_pos, int mode) +{ + StopOgg(); + + ogg_thread_running = 0; + + private_ogg.fd = fd; + private_ogg.mode = mode; + private_ogg.eof = 0; + private_ogg.volume = 127; + private_ogg.flag = 0; + private_ogg.seek_time = -1; + + if (time_pos > 0) + private_ogg.seek_time = time_pos; + + if (fd < 0) + { + private_ogg.fd = -1; + return -1; + } + if (ov_open((void *) &private_ogg.fd, &private_ogg.vf, NULL, 0) < 0) + { + mem_close(private_ogg.fd); // mem_close() can too close files from devices + private_ogg.fd = -1; + ogg_thread_running = -1; + return -1; + } + + if (LWP_CreateThread(&h_oggplayer, (void *) ogg_player_thread, + &private_ogg, oggplayer_stack, STACKSIZE, 80) == -1) + { + ogg_thread_running = -1; + ov_clear(&private_ogg.vf); + private_ogg.fd = -1; + return -1; + } + LWP_ThreadSignal(oggplayer_queue); + while (((volatile int) ogg_thread_running) == 0) + { + ;;; + } + return 0; +} + +void PauseOgg(int pause) +{ + if (pause) + { + private_ogg.flag |= 128; + } + else + { + if (private_ogg.flag & 128) + { + private_ogg.flag |= 64; + private_ogg.flag &= ~128; + if (ogg_thread_running > 0) + { + LWP_ThreadSignal(oggplayer_queue); + // while(((volatile int )private_ogg.flag)!=1 && ((volatile int )ogg_thread_running)>0) {;;;} + } + } + + } +} + +int StatusOgg() +{ + if (ogg_thread_running <= 0) + return -1; // Error + + if (private_ogg.eof) + return 255; // EOF + + if (private_ogg.flag & 128) + return 2; // paused + return 1; // running +} + +void SetVolumeOgg(int volume) +{ + private_ogg.volume = volume; + + SND_ChangeVolumeVoice(0, volume, volume); +} + +s32 GetTimeOgg() +{ + int ret; + if (ogg_thread_running <= 0) + return 0; + if (private_ogg.fd < 0) + return 0; + ret = ((s32) ov_time_tell(&private_ogg.vf)); + if (ret < 0) + ret = 0; + + return ret; +} + +void SetTimeOgg(s32 time_pos) +{ + if (time_pos >= 0) + private_ogg.seek_time = time_pos; +} + +#endif diff --git a/source/gx/gui/oggplayer.h b/source/gx/gui/oggplayer.h new file mode 100644 index 0000000..cb14adc --- /dev/null +++ b/source/gx/gui/oggplayer.h @@ -0,0 +1,174 @@ +/* + Copyright (c) 2008 Francisco Muņoz 'Hermes' + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + - The names of the contributors may not be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NO_SOUND + +#ifndef __OGGPLAYER_H__ +#define __OGGPLAYER_H__ + +#include +#include "tremor/ivorbiscodec.h" +#include "tremor/ivorbisfile.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define OGG_ONE_TIME 0 +#define OGG_INFINITE_TIME 1 + +#define OGG_STATUS_RUNNING 1 +#define OGG_STATUS_ERR -1 +#define OGG_STATUS_PAUSED 2 +#define OGG_STATUS_EOF 255 + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Player OGG functions */ +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* int PlayOgg(int fd, int time_pos, int mode); + + Play an Ogg file. This file can be loaded from memory (mem_open(void *ogg, int size_ogg)) or from device with open("device:file.ogg",O_RDONLY,0); + + NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail. + + -- Params --- + + fd: file descriptor from open() or mem_open() + + time_pos: initial time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds + + mode: Use OGG_ONE_TIME or OGG_INFINITE_TIME. When you use OGG_ONE_TIME the sound stops and StatusOgg() return OGG_STATUS_EOF + + return: 0- Ok, -1 Error + + */ + +int PlayOgg(int fd, int time_pos, int mode); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* void StopOgg(); + + Stop an Ogg file. + + NOTE: The file is closed and the player thread is released + + -- Params --- + + + */ + +void StopOgg(); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* void PauseOgg(int pause); + + Pause an Ogg file. + + -- Params --- + + pause: 0 -> continue, 1-> pause + + */ + +void PauseOgg(int pause); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* int StatusOgg(); + + Return the Ogg status + + -- Params --- + + + return: OGG_STATUS_RUNNING + OGG_STATUS_ERR -> not initialized? + OGG_STATUS_PAUSED + OGG_STATUS_EOF -> player stopped by End Of File + + */ + +int StatusOgg(); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* void SetVolumeOgg(int volume); + + Set the Ogg playing volume. + NOTE: it change the volume of voice 0 (used for the Ogg player) + + -- Params --- + + volume: 0 to 255 (max) + + */ + +void SetVolumeOgg(int volume); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* s32 GetTimeOgg(); + + Return the Ogg time from the starts of the file + + -- Params --- + + return: 0 -> Ok or error condition (you must ignore this value) + >0 -> time in milliseconds from the starts + + */ + +s32 GetTimeOgg(); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* void SetTimeOgg(s32 time_pos); + + Set the time position + + NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail. + + -- Params --- + + time_pos: time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds + + */ + +void SetTimeOgg(s32 time_pos); + +/*------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/source/gx/gx_audio.c b/source/gx/gx_audio.c index 8597ab0..a6dabf5 100644 --- a/source/gx/gx_audio.c +++ b/source/gx/gx_audio.c @@ -22,8 +22,10 @@ ***************************************************************************/ #include "shared.h" +//#include "Bg_music_ogg.h" #include +#include /* DMA soundbuffers (required to be 32-bytes aligned) Length is dimensionned for one frame of emulation (see below) @@ -47,7 +49,7 @@ static int delta; static u32 dma_sync; /* audio DMA status */ -static u8 audioStarted; +static u8 audioStarted = 0; /*** AudioDmaCallback @@ -126,6 +128,8 @@ void gx_audio_update(void) void gx_audio_start(void) { /* shutdown menu audio */ + PauseOgg(1); + StopOgg(); ASND_Pause(1); ASND_End(); @@ -163,11 +167,14 @@ void gx_audio_start(void) ***/ void gx_audio_stop(void) { - /* shutdown sound emulation */ + /* stop emulator audio */ AUDIO_StopDMA (); audioStarted = 0; - /* start menu audio */ + /* restart menu audio */ ASND_Init(); ASND_Pause(0); + PauseOgg(0); + // PlayOgg(mem_open((char *)Bg_music_ogg, Bg_music_ogg_size), 0, OGG_INFINITE_TIME); + //SetVolumeOgg(255); } diff --git a/source/gx/gx_video.c b/source/gx/gx_video.c index ef70533..de23b0d 100644 --- a/source/gx/gx_video.c +++ b/source/gx/gx_video.c @@ -831,7 +831,7 @@ void gxDrawScreenshot(u8 alpha) } } -void gxDrawTexture(gx_texture *texture, int x, int y, int w, int h, u8 alpha) +void gxDrawTexture(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha) { if (!texture) return; if (texture->data) @@ -866,7 +866,7 @@ void gxDrawTexture(gx_texture *texture, int x, int y, int w, int h, u8 alpha) } } -void gxDrawRepeat(gx_texture *texture, int x, int y, int w, int h) +void gxDrawTextureRepeat(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha) { if (!texture) return; if (texture->data) @@ -888,16 +888,16 @@ void gxDrawRepeat(gx_texture *texture, int x, int y, int w, int h) /* draw textured quad */ GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Position2s16(x,y+h); - GX_Color4u8(0xff,0xff,0xff,0xff); + GX_Color4u8(0xff,0xff,0xff,alpha); GX_TexCoord2f32(0.0, t); GX_Position2s16(x+w,y+h); - GX_Color4u8(0xff,0xff,0xff,0xff); + GX_Color4u8(0xff,0xff,0xff,alpha); GX_TexCoord2f32(s, t); GX_Position2s16(x+w,y); - GX_Color4u8(0xff,0xff,0xff,0xff); + GX_Color4u8(0xff,0xff,0xff,alpha); GX_TexCoord2f32(s, 0.0); GX_Position2s16(x,y); - GX_Color4u8(0xff,0xff,0xff,0xff); + GX_Color4u8(0xff,0xff,0xff,alpha); GX_TexCoord2f32(0.0, 0.0); GX_End (); GX_DrawDone(); @@ -983,6 +983,7 @@ void gx_video_start(void) /* Video Interrupt synchronization */ VIDEO_SetPostRetraceCallback(NULL); if (!gc_pal && !vdp_pal) VIDEO_SetPreRetraceCallback(updateFrameCount); + VIDEO_Flush(); /* interlaced/progressive mode */ if (config.render == 2) diff --git a/source/gx/gx_video.h b/source/gx/gx_video.h index e632659..51d91cc 100644 --- a/source/gx/gx_video.h +++ b/source/gx/gx_video.h @@ -56,8 +56,8 @@ extern void gx_video_update(void); extern gx_texture *gxTextureOpenPNG(const u8 *buffer); extern void gxTextureClose(gx_texture **p_texture); extern void gxDrawScreenshot(u8 alpha); -extern void gxDrawTexture(gx_texture *texture, int x, int y, int w, int h, u8 alpha); -extern void gxDrawRepeat(gx_texture *texture, int x, int y, int w, int h); +extern void gxDrawTexture(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha); +extern void gxDrawTextureRepeat(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha); extern void gxResetAngle(f32 angle); extern void gxClearScreen (GXColor color); extern void gxSetScreen (); diff --git a/source/gx/images/Button_down.png b/source/gx/images/Button_down.png index 457ad3f..6d33dab 100644 Binary files a/source/gx/images/Button_down.png and b/source/gx/images/Button_down.png differ diff --git a/source/gx/images/Button_down_over.png b/source/gx/images/Button_down_over.png index cb32ec8..41dcde5 100644 Binary files a/source/gx/images/Button_down_over.png and b/source/gx/images/Button_down_over.png differ diff --git a/source/gx/images/Button_up.png b/source/gx/images/Button_up.png index f9e8419..56e4303 100644 Binary files a/source/gx/images/Button_up.png and b/source/gx/images/Button_up.png differ diff --git a/source/gx/images/Button_up_over.png b/source/gx/images/Button_up_over.png index e242237..aad9864 100644 Binary files a/source/gx/images/Button_up_over.png and b/source/gx/images/Button_up_over.png differ diff --git a/source/gx/images/Frame_title.png b/source/gx/images/Frame_title.png index a066e70..a97d588 100644 Binary files a/source/gx/images/Frame_title.png and b/source/gx/images/Frame_title.png differ diff --git a/source/gx/main.c b/source/gx/main.c index 1ded406..9265190 100644 --- a/source/gx/main.c +++ b/source/gx/main.c @@ -23,6 +23,7 @@ #include "shared.h" #include "font.h" +#include "menu.h" #include "history.h" #include "aram.h" #include "dvd.h" @@ -35,7 +36,7 @@ /* Power Button callback */ u8 Shutdown = 0; -void Power_Off(void) +static void Power_Off(void) { Shutdown = 1; ConfigRequested = 1; @@ -47,7 +48,7 @@ void Power_Off(void) * Genesis Plus Virtual Machine * ***************************************************************************/ -static void load_bios() +static void load_bios(void) { char pathname[MAXPATHLEN]; @@ -74,7 +75,7 @@ static void load_bios() } } -static void init_machine (void) +static void init_machine(void) { /* Allocate cart_rom here ( 10 MBytes ) */ cart_rom = memalign(32, MAXROMSIZE); @@ -115,15 +116,36 @@ static void init_machine (void) /************************************************** Load a new rom and performs some initialization ***************************************************/ -void reloadrom () +void reloadrom (int size, char *name) { - load_rom(""); /* Load ROM */ + genromsize = size; + load_rom(name); /* Load ROM */ system_init (); /* Initialize System */ audio_init(48000); /* Audio System initialization */ ClearGGCodes (); /* Clear Game Genie patches */ system_reset (); /* System Power ON */ } +/************************************************** + Shutdown everything properly +***************************************************/ +void shutdown(void) +{ + /* system shutdown */ + memfile_autosave(-1,config.state_auto); + system_shutdown(); + audio_shutdown(); + free(cart_rom); + free(texturemem); + FONT_Shutdown(); + VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK); + VIDEO_Flush(); + VIDEO_WaitVSync(); +#ifdef HW_RVL + DI_Close(); +#endif +} + /*************************************************************************** * M A I N * @@ -134,7 +156,7 @@ u32 frameticker = 0; int main (int argc, char *argv[]) { #ifdef HW_RVL - /* initialize Wii DVD interface first */ + /* initialize DVD Mode */ DI_Close(); DI_Init(); #endif @@ -201,7 +223,7 @@ int main (int argc, char *argv[]) if (genromsize) { ARAMFetch((char *)cart_rom, (void *)0x8000, genromsize); - reloadrom (); + reloadrom (genromsize,"INJECT.bin"); gx_video_start(); gx_audio_start(); frameticker = 1; @@ -219,11 +241,11 @@ int main (int argc, char *argv[]) if (ConfigRequested) { /* stop audio & video */ - gx_audio_stop(); gx_video_stop(); + gx_audio_stop(); /* go to menu */ - MainMenu (FramesPerSecond); + MainMenu (); ConfigRequested = 0; /* reset framecounts */ diff --git a/source/gx/osd.h b/source/gx/osd.h index 9b2a346..9151ed0 100644 --- a/source/gx/osd.h +++ b/source/gx/osd.h @@ -27,16 +27,19 @@ extern void error(char *format, ...); extern void ClearGGCodes(); extern void GetGGEntries(); -extern void reloadrom(); extern void legal(); -extern void MainMenu(u32 fps); + +extern void reloadrom (int size, char *name); +extern void shutdown(); + extern int ManageSRAM(u8 direction, u8 device); extern int ManageState(u8 direction, u8 device); -extern void memfile_autosave(); -extern void memfile_autoload(); +extern void memfile_autosave(s8 autosram, s8 autostate); +extern void memfile_autoload(s8 autosram, s8 autostate); extern u8 fat_enabled; extern u32 frameticker; +extern char rom_filename[256]; #ifdef HW_RVL extern u8 Shutdown; diff --git a/source/gx/sounds/Bg_music.ogg b/source/gx/sounds/Bg_music.ogg new file mode 100644 index 0000000..01d00d7 Binary files /dev/null and b/source/gx/sounds/Bg_music.ogg differ diff --git a/source/gx/sounds/intro.pcm b/source/gx/sounds/intro.pcm new file mode 100644 index 0000000..1cee395 Binary files /dev/null and b/source/gx/sounds/intro.pcm differ diff --git a/source/loadrom.c b/source/loadrom.c index 02c8571..e0b21e7 100644 --- a/source/loadrom.c +++ b/source/loadrom.c @@ -265,6 +265,8 @@ int load_rom(char *filename) #ifdef NGC size = genromsize; + sprintf(rom_filename,"%s",filename); + rom_filename[strlen(rom_filename) - 4] = 0; #else uint8 *ptr; ptr = load_archive(filename, &size);