~ fixed YM2612 channel connections when loading savestate

~ optimized VDP renderer buffers size
~ fixed directories automatic creation
+ added game screenshot feature
+ added game screenshot support in ROM File browser
+ improved Controller menu icons
+ added new images for the new Controller menu
- removed unused images
This commit is contained in:
ekeeke31 2009-05-01 12:56:48 +00:00
parent 3e82e4f058
commit b1f11ed311
63 changed files with 935 additions and 524 deletions

View File

@ -8,7 +8,7 @@ Genesis Plus GX 1.3.2 (??/??/????) (Eke-Eke)
* modified SN76489 cut-off frequency * modified SN76489 cut-off frequency
* removed now outdated Gens YM2612 core * removed now outdated Gens YM2612 core
* improved MAME YM2612 emulation accuracy (SSG-EG, CSM mode and more), thanks to Nemesis for his tests on real hardware * improved MAME YM2612 emulation accuracy (SSG-EG, CSM mode and more), thanks to Nemesis for his tests on real hardware
* fixed FM context restore when loading savesates * fixed FM context in savestates
* improved sprites masking emulation: fixes 3D level in Mickey Mania * improved sprites masking emulation: fixes 3D level in Mickey Mania
* fixed lightgun games detection: fixes cursor position in Lethal Enforcers II * fixed lightgun games detection: fixes cursor position in Lethal Enforcers II
* various code cleanup & optimization * various code cleanup & optimization
@ -16,9 +16,10 @@ Genesis Plus GX 1.3.2 (??/??/????) (Eke-Eke)
[Gamecube/Wii] [Gamecube/Wii]
* improved audio/video synchronization: fixes video skipping issues with 60Hz modes * improved audio/video synchronization: fixes video skipping issues with 60Hz modes
* fixed stability issues * fixed stability issues and potential memory leaks
* added screenshot feature
* completely rewrote FONT & GUI engines (powered by GX hardware) * completely rewrote FONT & GUI engines (powered by GX hardware)
* new GUI design (incl. Wii Remote pointing, ROM snapshots & more) * new GUI layout (incl. IR pointing, ROM snapshots, sound effects & more)

View File

@ -22,51 +22,45 @@
***************************************************************************/ ***************************************************************************/
#include "shared.h" #include "shared.h"
void config_save() void config_save(void)
{ {
char pathname[MAXPATHLEN];
if (!fat_enabled) return;
/* first check if directory exist */
sprintf (pathname, DEFAULT_PATH);
DIR_ITER *dir = diropen(pathname);
if (dir == NULL) mkdir(pathname,S_IRWXU);
else dirclose(dir);
/* open configuration file */ /* open configuration file */
sprintf (pathname, "%s/config.ini", pathname); char fname[MAXPATHLEN];
FILE *fp = fopen(pathname, "wb"); sprintf (fname, "%s/config.ini", DEFAULT_PATH);
if (fp == NULL) return; FILE *fp = fopen(fname, "wb");
if (fp)
/* save options */ {
fwrite(&config, sizeof(config), 1, fp); /* write file */
fwrite(&config, sizeof(config), 1, fp);
fclose(fp); fclose(fp);
}
} }
void config_load() void config_load(void)
{ {
char pathname[MAXPATHLEN];
/* open configuration file */ /* open configuration file */
sprintf (pathname, "%s/config.ini", DEFAULT_PATH); char fname[MAXPATHLEN];
FILE *fp = fopen(pathname, "rb"); sprintf (fname, "%s/config.ini", DEFAULT_PATH);
if (fp == NULL) return; FILE *fp = fopen(fname, "rb");
if (fp)
{
/* read version */
char version[16];
fread(version, 16, 1, fp);
fclose(fp);
if (strcmp(version,VERSION)) return;
/* read version */ /* read file */
char version[16]; fp = fopen(fname, "rb");
fread(version, 16, 1, fp); if (fp)
fclose(fp); {
if (strcmp(version,VERSION)) return; fread(&config, sizeof(config), 1, fp);
fclose(fp);
/* read file */ }
fp = fopen(pathname, "rb"); }
fread(&config, sizeof(config), 1, fp);
fclose(fp);
} }
void config_setDefault(void) void config_default(void)
{ {
/* version TAG */ /* version TAG */
strncpy(config.version,VERSION,16); strncpy(config.version,VERSION,16);
@ -109,5 +103,8 @@ void config_setDefault(void)
config.bg_color = 0; config.bg_color = 0;
config.bgm_volume = 100.0; config.bgm_volume = 100.0;
config.sfx_volume = 100.0; config.sfx_volume = 100.0;
/* restore saved configuration */
config_load();
} }

View File

@ -65,9 +65,9 @@ typedef struct
t_config config; t_config config;
extern void config_save(); extern void config_save(void);
extern void config_load(); extern void config_load(void);
extern void config_setDefault(void); extern void config_default(void);
#endif /* _CONFIG_H_ */ #endif /* _CONFIG_H_ */

View File

@ -96,28 +96,19 @@ void memfile_autosave(s8 autosram, s8 autostate)
*****************************************************************************/ *****************************************************************************/
static int FAT_ManageFile(char *filename, int direction, int filetype) static int FAT_ManageFile(char *filename, int direction, int filetype)
{ {
char pathname[MAXPATHLEN]; char fname[MAXPATHLEN];
int done = 0; int done = 0;
int filesize; int filesize;
if (!fat_enabled) return 0;
/* first check if directory exist */
sprintf (pathname, "%s/saves", DEFAULT_PATH);
DIR_ITER *dir = diropen(pathname);
if (dir == NULL) mkdir(pathname,S_IRWXU);
else dirclose(dir);
/* build complete SDCARD filename */ /* build complete SDCARD filename */
sprintf (pathname, "%s/%s", pathname, filename); sprintf (fname, "%s/saves/%s", DEFAULT_PATH, filename);
/* open file */ /* open file */
FILE *fp = fopen(pathname, direction ? "rb" : "wb"); FILE *fp = fopen(fname, direction ? "rb" : "wb");
if (fp == NULL) if (fp == NULL)
{ {
sprintf (filename, "Error opening %s", pathname); sprintf (fname, "Error opening %s", filename);
WaitPrompt(filename); WaitPrompt(fname);
return 0; return 0;
} }
@ -137,14 +128,14 @@ static int FAT_ManageFile(char *filename, int direction, int filetype)
done = fwrite(savebuffer, 1, filesize, fp); done = fwrite(savebuffer, 1, filesize, fp);
if (done < filesize) if (done < filesize)
{ {
sprintf (filename, "Error writing %s", pathname); sprintf (fname, "Error writing %s", filename);
WaitPrompt(filename); WaitPrompt(fname);
return 0; return 0;
} }
fclose(fp); fclose(fp);
sprintf (filename, "Saved %d bytes successfully", done); sprintf (fname, "Saved %d bytes successfully", done);
WaitPrompt (filename); WaitPrompt (fname);
return 1; return 1;
case 1: /* LOADING */ case 1: /* LOADING */
@ -158,8 +149,8 @@ static int FAT_ManageFile(char *filename, int direction, int filetype)
done = fread(savebuffer, 1, filesize, fp); done = fread(savebuffer, 1, filesize, fp);
if (done < filesize) if (done < filesize)
{ {
sprintf (filename, "Error reading %s", pathname); sprintf (fname, "Error reading %s", filename);
WaitPrompt(filename); WaitPrompt(fname);
return 0; return 0;
} }
fclose(fp); fclose(fp);
@ -172,8 +163,8 @@ static int FAT_ManageFile(char *filename, int direction, int filetype)
} }
else state_load(savebuffer); /* STATE */ else state_load(savebuffer); /* STATE */
sprintf (filename, "Loaded %d bytes successfully", done); sprintf (fname, "Loaded %d bytes successfully", done);
WaitPrompt (filename); WaitPrompt (fname);
return 1; return 1;
} }

View File

@ -26,28 +26,6 @@
t_history history; t_history history;
void history_save()
{
char pathname[MAXPATHLEN];
if (!fat_enabled) return;
/* first check if directory exist */
sprintf (pathname, DEFAULT_PATH);
DIR_ITER *dir = diropen(pathname);
if (dir == NULL) mkdir(pathname,S_IRWXU);
else dirclose(dir);
/* open file for writing */
sprintf (pathname, "%s/history.ini", pathname);
FILE *fp = fopen(pathname, "wb");
if (fp == NULL) return;
/* save options */
fwrite(&history, sizeof(history), 1, fp);
fclose(fp);
}
/**************************************************************************** /****************************************************************************
* history_add_file * history_add_file
@ -95,28 +73,44 @@ void history_add_file(char *filepath, char *filename)
history_save(); history_save();
} }
void history_load() void history_save()
{ {
char pathname[MAXPATHLEN]; /* open file */
char fname[MAXPATHLEN];
/* open file for reading */ sprintf (fname, "%s/history.ini", DEFAULT_PATH);
sprintf (pathname, "%s/history.ini", DEFAULT_PATH); FILE *fp = fopen(fname, "wb");
FILE *fp = fopen(pathname, "rb"); if (fp)
if (fp == NULL) return; {
/* write file */
/* read file */ fwrite(&history, sizeof(history), 1, fp);
fread(&history, sizeof(history), 1, fp); fclose(fp);
}
fclose(fp);
} }
void history_setDefault(void) void history_load(void)
{
/* open file */
char fname[MAXPATHLEN];
sprintf (fname, "%s/history.ini", DEFAULT_PATH);
FILE *fp = fopen(fname, "rb");
if (fp)
{
/* read file */
fread(&history, sizeof(history), 1, fp);
fclose(fp);
}
}
void history_default(void)
{ {
int i; int i;
for(i=0; i < NUM_HISTORY_ENTRIES; i++) for(i=0; i < NUM_HISTORY_ENTRIES; i++)
{ {
memset(&history.entries[i], 0, sizeof(t_history_entry)); memset(&history.entries[i], 0, sizeof(t_history_entry));
} }
/* restore history */
history_load();
} }

View File

@ -45,7 +45,8 @@ typedef struct
extern t_history history; extern t_history history;
extern void history_add_file(char *filepath, char *filename); extern void history_add_file(char *filepath, char *filename);
extern void history_load(); extern void history_save(void);
extern void history_setDefault(); extern void history_load(void);
extern void history_default(void);
#endif #endif

View File

@ -95,7 +95,7 @@ static gui_item action_select =
/*****************************************************************************/ /*****************************************************************************/
/* GUI Background images */ /* GUI Background images */
/*****************************************************************************/ /*****************************************************************************/
static gui_image bg_filesel[9] = static gui_image bg_filesel[10] =
{ {
{NULL,Bg_main_png,IMAGE_VISIBLE,356,144,348,288,255,{0,0},{0,0}}, {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,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255,{0,0},{0,0}},
@ -105,6 +105,7 @@ static gui_image bg_filesel[9] =
{NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,200,{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,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_empty_png,IMAGE_VISIBLE,422,114,164,116,255,{0,0},{0,0}},
{NULL,NULL,0,424,116,160,112,255,{0,0},{0,0}},
{NULL,Snap_frame_png,IMAGE_VISIBLE,388,112,236,148,255,{0,0},{0,0}} {NULL,Snap_frame_png,IMAGE_VISIBLE,388,112,236,148,255,{0,0},{0,0}}
}; };
@ -113,9 +114,9 @@ static gui_image bg_filesel[9] =
/*****************************************************************************/ /*****************************************************************************/
static gui_menu menu_browser = static gui_menu menu_browser =
{ {
"ROM Selection", "Game Selection",
-1,-1, -1,-1,
0,0,9, 0,0,10,
NULL, NULL,
NULL, NULL,
bg_filesel, bg_filesel,
@ -165,6 +166,7 @@ int FileSelector(unsigned char *buffer)
int ret,i,yoffset,string_offset; int ret,i,yoffset,string_offset;
int go_up = 0; int go_up = 0;
int quit =0; int quit =0;
int old = -1;
char text[MAXJOLIET+2]; char text[MAXJOLIET+2];
char fname[MAXPATHLEN]; char fname[MAXPATHLEN];
FILE *xml,*snap; FILE *xml,*snap;
@ -181,7 +183,7 @@ int FileSelector(unsigned char *buffer)
/* Initialize directory icon */ /* Initialize directory icon */
gui_image dir_icon; gui_image dir_icon;
dir_icon.texture = gxTextureOpenPNG(Browser_dir_png); dir_icon.texture = gxTextureOpenPNG(Browser_dir_png,0);
dir_icon.w = dir_icon.texture->width; dir_icon.w = dir_icon.texture->width;
dir_icon.h = dir_icon.texture->height; dir_icon.h = dir_icon.texture->height;
dir_icon.x = 26; dir_icon.x = 26;
@ -189,7 +191,7 @@ int FileSelector(unsigned char *buffer)
/* Initialize selection bar */ /* Initialize selection bar */
gui_image bar_over; gui_image bar_over;
bar_over.texture = gxTextureOpenPNG(Overlay_bar_png); bar_over.texture = gxTextureOpenPNG(Overlay_bar_png,0);
bar_over.w = bar_over.texture->width; bar_over.w = bar_over.texture->width;
bar_over.h = bar_over.texture->height; bar_over.h = bar_over.texture->height;
bar_over.x = 22; bar_over.x = 22;
@ -219,11 +221,23 @@ int FileSelector(unsigned char *buffer)
} }
/* ROM snapshot */ /* ROM snapshot */
sprintf (fname, "%s/snaps/%s.png", DEFAULT_PATH, text); if (old != selection)
snap = fopen(fname, "rb");
if (snap)
{ {
fclose(snap); /* TODO */ old = selection;
/* delete previous texture if any */
gxTextureClose(&bg_filesel[8].texture);
bg_filesel[8].state &= ~IMAGE_VISIBLE;
/* open screenshot file */
sprintf (fname, "%s/snaps/%s.png", DEFAULT_PATH, text);
snap = fopen(fname, "rb");
if (snap)
{
bg_filesel[8].texture = gxTextureOpenPNG(0,snap);
fclose(snap);
if (bg_filesel[8].texture) bg_filesel[8].state |= IMAGE_VISIBLE;
}
} }
/* Draw menu*/ /* Draw menu*/
@ -317,14 +331,14 @@ int FileSelector(unsigned char *buffer)
/* find selected button */ /* find selected button */
for (i=0; i<2; i++) for (i=0; i<2; i++)
{
button = m->arrows[i];
if (button)
{ {
if (button->state & BUTTON_VISIBLE) button = m->arrows[i];
if (button)
{ {
if ((x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) 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; m->selected = m->max_buttons + i;
break; break;
} }

View File

@ -154,7 +154,7 @@ void WriteCentre( int y, char *string)
void WriteCentre_HL( int y, char *string) void WriteCentre_HL( int y, char *string)
{ {
gx_texture *texture = gxTextureOpenPNG(Overlay_bar_png); gx_texture *texture = gxTextureOpenPNG(Overlay_bar_png,0);
if (texture) if (texture)
{ {
gxDrawTexture(texture, 0, y-fheight, 640, fheight,240); gxDrawTexture(texture, 0, y-fheight, 640, fheight,240);

View File

@ -61,7 +61,7 @@ void legal ()
WriteCentre (ypos, "You are free to use it as you wish."); WriteCentre (ypos, "You are free to use it as you wish.");
ypos += 2*fheight; ypos += 2*fheight;
texture= gxTextureOpenPNG(Bg_intro_c4_png); texture= gxTextureOpenPNG(Bg_intro_c4_png,0);
if (texture) if (texture)
{ {
gxDrawTexture(texture, (640-texture->width)/2, ypos, texture->width, texture->height,255); gxDrawTexture(texture, (640-texture->width)/2, ypos, texture->width, texture->height,255);
@ -84,7 +84,7 @@ void legal ()
} }
gxClearScreen((GXColor)BLACK); gxClearScreen((GXColor)BLACK);
texture = gxTextureOpenPNG(Bg_intro_c1_png); texture = gxTextureOpenPNG(Bg_intro_c1_png,0);
if (texture) if (texture)
{ {
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255); gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
@ -96,7 +96,7 @@ void legal ()
sleep (1); sleep (1);
gxClearScreen((GXColor)WHITE); gxClearScreen((GXColor)WHITE);
texture = gxTextureOpenPNG(Bg_intro_c2_png); texture = gxTextureOpenPNG(Bg_intro_c2_png,0);
if (texture) if (texture)
{ {
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255); gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
@ -108,7 +108,7 @@ void legal ()
sleep (1); sleep (1);
gxClearScreen((GXColor)BLACK); gxClearScreen((GXColor)BLACK);
texture = gxTextureOpenPNG(Bg_intro_c3_png); texture = gxTextureOpenPNG(Bg_intro_c3_png,0);
if (texture) if (texture)
{ {
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255); gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);

View File

@ -39,16 +39,17 @@ t_input_menu m_input;
gx_texture *w_pointer; gx_texture *w_pointer;
#endif #endif
#define BG_COLOR_MAX 14 #define BG_COLOR_MAX 15
/* various background colors */ /* various background colors */
static GXColor bg_colors[BG_COLOR_MAX]= static GXColor bg_colors[BG_COLOR_MAX]=
{ {
{0xd6,0xcb,0xba,0xff}, /* light gold */ {0xd6,0xcb,0xba,0xff}, /* light gold */
{0xbb,0xb0,0x99,0xff}, /* gold */ {0xbb,0xb0,0x99,0xff}, /* gold */
{0x66,0x66,0x66,0xff}, /* faded grey */ {0x66,0x66,0x66,0xff}, /* faded grey */
{0xcc,0xcc,0xcc,0xff}, /* light grey */ {0xcc,0xcc,0xcc,0xff}, /* light grey */
{0xd4,0xd0,0xc8,0xff}, /* cream */ {0xd4,0xd0,0xc8,0xff}, /* cream */
{0x50,0x51,0x5b,0xff}, /* grey blue */
{0xb8,0xc7,0xda,0xff}, /* light blue */ {0xb8,0xc7,0xda,0xff}, /* light blue */
{0xc0,0xcf,0xe7,0xff}, /* sky blue */ {0xc0,0xcf,0xe7,0xff}, /* sky blue */
{0x98,0xb1,0xd8,0xff}, /* sea blue */ {0x98,0xb1,0xd8,0xff}, /* sea blue */
@ -144,7 +145,7 @@ static gui_image bg_list[6] =
/*****************************************************************************/ /*****************************************************************************/
/* Main menu */ /* Main menu */
static gui_item items_main[8] = static gui_item items_main[9] =
{ {
{NULL,Main_quit_png ,"","",128, 84,52,80}, {NULL,Main_quit_png ,"","",128, 84,52,80},
{NULL,Main_load_png ,"","",280, 72,80,92}, {NULL,Main_load_png ,"","",280, 72,80,92},
@ -153,11 +154,12 @@ static gui_item items_main[8] =
{NULL,Main_reset_png ,"","",282,224,76,84}, {NULL,Main_reset_png ,"","",282,224,76,84},
{NULL,Main_ggenie_png ,"","",450,224,72,84}, {NULL,Main_ggenie_png ,"","",450,224,72,84},
#ifdef HW_RVL #ifdef HW_RVL
{NULL,Main_play_wii_png,"","", 10,368,84,32}, {NULL,Main_play_wii_png,"","", 10,372,84,32},
#else #else
{NULL,Main_play_gcn_png,"","", 10,368,84,32}, {NULL,Main_play_gcn_png,"","", 10,372,84,32},
#endif #endif
{NULL,Main_showinfo_png,"","",546,368,84,32} {NULL,Main_takeshot_png,"","",546,334,84,32},
{NULL,Main_showinfo_png,"","",546,372,84,32}
}; };
#ifdef HW_RVL #ifdef HW_RVL
@ -246,7 +248,7 @@ static gui_butn buttons_list[4] =
}; };
/* Main menu */ /* Main menu */
static gui_butn buttons_main[8] = static gui_butn buttons_main[9] =
{ {
{&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3}, 80, 50,148,132}, {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3}, 80, 50,148,132},
{&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3},246, 50,148,132}, {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3},246, 50,148,132},
@ -255,7 +257,8 @@ static gui_butn buttons_main[8] =
{&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX ,{3,3},246,194,148,132}, {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX ,{3,3},246,194,148,132},
{&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,2},412,194,148,132}, {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,2},412,194,148,132},
{NULL ,BUTTON_VISIBLE|BUTTON_OVER_SFX ,{3,0}, 0,360, 88, 48}, {NULL ,BUTTON_VISIBLE|BUTTON_OVER_SFX ,{3,0}, 0,360, 88, 48},
{NULL ,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0},552,360, 88, 48} {NULL ,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,1},542,330, 88, 38},
{NULL ,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0},542,370, 88, 48}
}; };
@ -296,7 +299,7 @@ static gui_menu menu_main =
{ {
"", "",
0,0, 0,0,
8,8,4, 9,9,4,
items_main, items_main,
buttons_main, buttons_main,
bg_main, bg_main,
@ -408,7 +411,7 @@ void GUI_InitMenu(gui_menu *menu)
for (i=0; i<menu->max_images; i++) for (i=0; i<menu->max_images; i++)
{ {
image = &menu->bg_images[i]; image = &menu->bg_images[i];
image->texture = gxTextureOpenPNG(image->data); image->texture = gxTextureOpenPNG(image->data,0);
} }
for (i=0; i<2; i++) for (i=0; i<2; i++)
@ -417,15 +420,15 @@ void GUI_InitMenu(gui_menu *menu)
item = menu->helpers[i]; item = menu->helpers[i];
if (item) if (item)
{ {
item->texture = gxTextureOpenPNG(item->data); item->texture = gxTextureOpenPNG(item->data,0);
} }
/* arrows */ /* arrows */
button = menu->arrows[i]; button = menu->arrows[i];
if (button) if (button)
{ {
if (!button->data->texture[0]) button->data->texture[0] = gxTextureOpenPNG(button->data->image[0]); if (!button->data->texture[0]) button->data->texture[0] = gxTextureOpenPNG(button->data->image[0],0);
if (!button->data->texture[1]) button->data->texture[1] = gxTextureOpenPNG(button->data->image[1]); if (!button->data->texture[1]) button->data->texture[1] = gxTextureOpenPNG(button->data->image[1],0);
/* initial state */ /* initial state */
button->state &= ~BUTTON_VISIBLE; button->state &= ~BUTTON_VISIBLE;
@ -443,8 +446,8 @@ void GUI_InitMenu(gui_menu *menu)
button = &menu->buttons[i]; button = &menu->buttons[i];
if (button->data) if (button->data)
{ {
if (!button->data->texture[0]) button->data->texture[0] = gxTextureOpenPNG(button->data->image[0]); if (!button->data->texture[0]) button->data->texture[0] = gxTextureOpenPNG(button->data->image[0],0);
if (!button->data->texture[1]) button->data->texture[1] = gxTextureOpenPNG(button->data->image[1]); if (!button->data->texture[1]) button->data->texture[1] = gxTextureOpenPNG(button->data->image[1],0);
} }
} }
@ -452,7 +455,7 @@ void GUI_InitMenu(gui_menu *menu)
for (i=0; i<menu->max_items; i++) for (i=0; i<menu->max_items; i++)
{ {
item = &menu->items[i]; item = &menu->items[i];
if (item->data) item->texture = gxTextureOpenPNG(item->data); if (item->data) item->texture = gxTextureOpenPNG(item->data,0);
} }
} }
@ -604,6 +607,21 @@ void GUI_DrawMenu(gui_menu *menu)
} }
} }
/* Menu fading */
void GUI_FadeMenu(gui_menu *menu, u8 speed, u8 out)
{
int alpha = 255;
while (alpha > 0)
{
GUI_DrawMenu(menu);
gxDrawRectangle(0, 0, 640, 480, out ? (255-alpha) : alpha, (GXColor)BLACK);
alpha -= speed;
}
if (out) gxDrawRectangle(0, 0, 640, 480, 255, (GXColor)BLACK);
}
/* Menu transitions effect */ /* Menu transitions effect */
void GUI_DrawMenuFX(gui_menu *menu, u8 speed, u8 out) void GUI_DrawMenuFX(gui_menu *menu, u8 speed, u8 out)
{ {
@ -768,14 +786,14 @@ int GUI_WindowPrompt(gui_menu *parent, char *title, char *items[], u8 nb_items)
delete_me[i] = 0; delete_me[i] = 0;
if (!data->texture[i]) if (!data->texture[i])
{ {
data->texture[i] = gxTextureOpenPNG(data->image[i]); data->texture[i] = gxTextureOpenPNG(data->image[i],0);
delete_me[i] = 1; delete_me[i] = 1;
} }
} }
/* initialize texture window */ /* initialize texture window */
gx_texture *window = gxTextureOpenPNG(Frame_s1_png); gx_texture *window = gxTextureOpenPNG(Frame_s1_png,0);
gx_texture *top = gxTextureOpenPNG(Frame_title_png); gx_texture *top = gxTextureOpenPNG(Frame_s1_title_png,0);
/* get initial positions */ /* get initial positions */
int w = data->texture[0]->width; int w = data->texture[0]->width;
@ -1191,6 +1209,12 @@ int GUI_RunMenu(gui_menu *menu)
/* basic slide effect for option menus */ /* basic slide effect for option menus */
static void GUI_SlideMenuTitle(gui_menu *m, int title_offset) static void GUI_SlideMenuTitle(gui_menu *m, int title_offset)
{ {
#ifdef HW_RVL
gui_butn *button;
int i,x,y;
struct orient_t orient;
#endif
char title[64]; char title[64];
strcpy(title,m->title); strcpy(title,m->title);
@ -1199,6 +1223,53 @@ static void GUI_SlideMenuTitle(gui_menu *m, int title_offset)
strcpy(m->title,title+title_offset); strcpy(m->title,title+title_offset);
m->title[strlen(title)-title_offset-1] = 0; m->title[strlen(title)-title_offset-1] = 0;
GUI_DrawMenu(m); GUI_DrawMenu(m);
#ifdef HW_RVL
if (m_input.ir.valid)
{
/* get cursor position */
x = m_input.ir.x;
y = m_input.ir.y;
/* draw wiimote pointer */
WPAD_Orientation(0,&orient);
gxResetAngle(orient.roll);
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 */
m->selected = m->max_buttons + 2;
for (i=0; i<m->max_buttons; i++)
{
button = &m->buttons[i];
if ((button->state & BUTTON_VISIBLE)&&(x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h)))
{
m->selected = i;
break;
}
}
for (i=0; i<2; i++)
{
button = m->arrows[i];
if (button)
{
if (button->state & BUTTON_VISIBLE)
{
if ((x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h)))
{
m->selected = m->max_buttons + i;
break;
}
}
}
}
}
else
{
/* reinitialize selection */
if (m->selected >= m->max_buttons) m->selected = 0;
}
#endif
gxSetScreen (); gxSetScreen ();
usleep(6000); usleep(6000);
title_offset--; title_offset--;
@ -1230,28 +1301,28 @@ static void drawmenu (char items[][25], int maxitems, int selected)
/* draw background items */ /* draw background items */
gxClearScreen (bg_colors[config.bg_color]); gxClearScreen (bg_colors[config.bg_color]);
texture= gxTextureOpenPNG(Bg_main_png); texture= gxTextureOpenPNG(Bg_main_png,0);
if (texture) if (texture)
{ {
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255); gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
if (texture->data) free(texture->data); if (texture->data) free(texture->data);
free(texture); free(texture);
} }
texture= gxTextureOpenPNG(Banner_bottom_png); texture= gxTextureOpenPNG(Banner_bottom_png,0);
if (texture) if (texture)
{ {
gxDrawTexture(texture, 0, 480-texture->height, texture->width, texture->height, 255); gxDrawTexture(texture, 0, 480-texture->height, texture->width, texture->height, 255);
if (texture->data) free(texture->data); if (texture->data) free(texture->data);
free(texture); free(texture);
} }
texture= gxTextureOpenPNG(Banner_top_png); texture= gxTextureOpenPNG(Banner_top_png,0);
if (texture) if (texture)
{ {
gxDrawTexture(texture, 0, 0, texture->width, texture->height, 255); gxDrawTexture(texture, 0, 0, texture->width, texture->height, 255);
if (texture->data) free(texture->data); if (texture->data) free(texture->data);
free(texture); free(texture);
} }
texture= gxTextureOpenPNG(Main_logo_png); texture= gxTextureOpenPNG(Main_logo_png,0);
if (texture) if (texture)
{ {
gxDrawTexture(texture, 444, 28, 176, 48, 255); gxDrawTexture(texture, 444, 28, 176, 48, 255);
@ -1338,24 +1409,24 @@ static void prefmenu ()
gui_menu *m = &menu_prefs; gui_menu *m = &menu_prefs;
gui_item *items = m->items; gui_item *items = m->items;
if (config.sram_auto == 0) sprintf (items[0].text, "SRAM Auto: FAT");
else if (config.sram_auto == 1) sprintf (items[0].text, "SRAM Auto: MCARD A");
else if (config.sram_auto == 2) sprintf (items[0].text, "SRAM Auto: MCARD B");
else sprintf (items[0].text, "SRAM Auto: OFF");
if (config.state_auto == 0) sprintf (items[1].text, "Savestate Auto: FAT");
else if (config.state_auto == 1) sprintf (items[1].text, "Savestate Auto: MCARD A");
else if (config.state_auto == 2) sprintf (items[1].text, "Savestate Auto: MCARD B");
else sprintf (items[1].text, "Savestate Auto: OFF");
sprintf (items[2].text, "SFX Volume: %1.1f", config.sfx_volume);
sprintf (items[3].text, "BGM Volume: %1.1f", config.bgm_volume);
if (config.bg_color) sprintf (items[4].text, "BG Color: Type %d", config.bg_color);
else sprintf (items[4].text, "BG Color: DEFAULT");
GUI_InitMenu(m); GUI_InitMenu(m);
GUI_SlideMenuTitle(m,strlen("Menu ")); GUI_SlideMenuTitle(m,strlen("Menu "));
while (quit == 0) while (quit == 0)
{ {
if (config.sram_auto == 0) sprintf (items[0].text, "SRAM Auto: FAT");
else if (config.sram_auto == 1) sprintf (items[0].text, "SRAM Auto: MCARD A");
else if (config.sram_auto == 2) sprintf (items[0].text, "SRAM Auto: MCARD B");
else sprintf (items[0].text, "SRAM Auto: OFF");
if (config.state_auto == 0) sprintf (items[1].text, "Savestate Auto: FAT");
else if (config.state_auto == 1) sprintf (items[1].text, "Savestate Auto: MCARD A");
else if (config.state_auto == 2) sprintf (items[1].text, "Savestate Auto: MCARD B");
else sprintf (items[1].text, "Savestate Auto: OFF");
sprintf (items[2].text, "SFX Volume: %1.1f", config.sfx_volume);
sprintf (items[3].text, "BGM Volume: %1.1f", config.bgm_volume);
if (config.bg_color) sprintf (items[4].text, "BG Color: Type %d", config.bg_color);
else sprintf (items[4].text, "BG Color: DEFAULT");
ret = GUI_RunMenu(m); ret = GUI_RunMenu(m);
switch (ret) switch (ret)
@ -1363,11 +1434,19 @@ static void prefmenu ()
case 0: /*** SRAM auto load/save ***/ case 0: /*** SRAM auto load/save ***/
config.sram_auto ++; config.sram_auto ++;
if (config.sram_auto > 2) config.sram_auto = -1; if (config.sram_auto > 2) config.sram_auto = -1;
if (config.sram_auto == 0) sprintf (items[0].text, "SRAM Auto: FAT");
else if (config.sram_auto == 1) sprintf (items[0].text, "SRAM Auto: MCARD A");
else if (config.sram_auto == 2) sprintf (items[0].text, "SRAM Auto: MCARD B");
else sprintf (items[0].text, "SRAM Auto: OFF");
break; break;
case 1: /*** Savestate auto load/save ***/ case 1: /*** Savestate auto load/save ***/
config.state_auto ++; config.state_auto ++;
if (config.state_auto > 2) config.state_auto = -1; if (config.state_auto > 2) config.state_auto = -1;
if (config.state_auto == 0) sprintf (items[1].text, "Savestate Auto: FAT");
else if (config.state_auto == 1) sprintf (items[1].text, "Savestate Auto: MCARD A");
else if (config.state_auto == 2) sprintf (items[1].text, "Savestate Auto: MCARD B");
else sprintf (items[1].text, "Savestate Auto: OFF");
break; break;
case 2: /*** Sound effects volume ***/ case 2: /*** Sound effects volume ***/
@ -1376,6 +1455,7 @@ static void prefmenu ()
else config.sfx_volume +=10; else config.sfx_volume +=10;
if (config.sfx_volume < 0) config.sfx_volume = 100.0; if (config.sfx_volume < 0) config.sfx_volume = 100.0;
else if (config.sfx_volume > 100) config.sfx_volume = 0.0; else if (config.sfx_volume > 100) config.sfx_volume = 0.0;
sprintf (items[2].text, "SFX Volume: %1.1f", config.sfx_volume);
break; break;
case 3: /*** Background music volume ***/ case 3: /*** Background music volume ***/
@ -1385,6 +1465,7 @@ static void prefmenu ()
if (config.bgm_volume < 0) config.bgm_volume = 100.0; if (config.bgm_volume < 0) config.bgm_volume = 100.0;
else if (config.bgm_volume > 100) config.bgm_volume = 0.0; else if (config.bgm_volume > 100) config.bgm_volume = 0.0;
SetVolumeOgg(((int)config.bgm_volume * 255) / 100); SetVolumeOgg(((int)config.bgm_volume * 255) / 100);
sprintf (items[3].text, "BGM Volume: %1.1f", config.bgm_volume);
break; break;
case 4: /*** Background color ***/ case 4: /*** Background color ***/
@ -1393,6 +1474,8 @@ static void prefmenu ()
else config.bg_color ++; else config.bg_color ++;
if (config.bg_color < 0) config.bg_color = BG_COLOR_MAX - 1; if (config.bg_color < 0) config.bg_color = BG_COLOR_MAX - 1;
if (config.bg_color >= BG_COLOR_MAX) config.bg_color = 0; if (config.bg_color >= BG_COLOR_MAX) config.bg_color = 0;
if (config.bg_color) sprintf (items[4].text, "BG Color: Type %d", config.bg_color);
else sprintf (items[4].text, "BG Color: DEFAULT");
break; break;
case -1: case -1:
@ -1414,18 +1497,19 @@ static void soundmenu ()
gui_menu *m = &menu_audio; gui_menu *m = &menu_audio;
gui_item *items = m->items; gui_item *items = m->items;
sprintf (items[0].text, "PSG Volume: %1.2f", (double)config.psg_preamp/100.0);
sprintf (items[1].text, "FM Volume: %1.2f", (double)config.fm_preamp/100.0);
sprintf (items[2].text, "Volume Boost: %dX", config.boost);
sprintf (items[3].text, "LowPass Filter: %s", config.filter ? " ON":"OFF");
if (config.hq_fm == 0) sprintf (items[4].text, "HQ YM2612: OFF");
else if (config.hq_fm == 1) sprintf (items[4].text, "HQ YM2612: LINEAR");
else sprintf (items[4].text, "HQ YM2612: SINC");
GUI_InitMenu(m); GUI_InitMenu(m);
GUI_SlideMenuTitle(m,strlen("Sound ")); GUI_SlideMenuTitle(m,strlen("Sound "));
while (quit == 0) while (quit == 0)
{ {
sprintf (items[0].text, "PSG Volume: %1.2f", (double)config.psg_preamp/100.0);
sprintf (items[1].text, "FM Volume: %1.2f", (double)config.fm_preamp/100.0);
sprintf (items[2].text, "Volume Boost: %dX", config.boost);
sprintf (items[3].text, "LowPass Filter: %s", config.filter ? " ON":"OFF");
if (config.hq_fm == 0) sprintf (items[4].text, "HQ YM2612: OFF");
else if (config.hq_fm == 1) sprintf (items[4].text, "HQ YM2612: LINEAR");
else sprintf (items[4].text, "HQ YM2612: SINC");
ret = GUI_RunMenu(m); ret = GUI_RunMenu(m);
@ -1437,6 +1521,7 @@ static void soundmenu ()
else config.psg_preamp ++; else config.psg_preamp ++;
if (config.psg_preamp < 0) config.psg_preamp = 500; if (config.psg_preamp < 0) config.psg_preamp = 500;
if (config.psg_preamp > 500) config.psg_preamp = 0; if (config.psg_preamp > 500) config.psg_preamp = 0;
sprintf (items[0].text, "PSG Volume: %1.2f", (double)config.psg_preamp/100.0);
break; break;
case 1: case 1:
@ -1445,23 +1530,29 @@ static void soundmenu ()
else config.fm_preamp ++; else config.fm_preamp ++;
if (config.fm_preamp < 0) config.fm_preamp = 500; if (config.fm_preamp < 0) config.fm_preamp = 500;
if (config.fm_preamp > 500) config.fm_preamp = 0; if (config.fm_preamp > 500) config.fm_preamp = 0;
sprintf (items[1].text, "FM Volume: %1.2f", (double)config.fm_preamp/100.0);
break; break;
case 2: case 2:
config.boost ++; config.boost ++;
if (config.boost > 4) config.boost = 0; if (config.boost > 4) config.boost = 0;
sprintf (items[2].text, "Volume Boost: %dX", config.boost);
break; break;
case 3: case 3:
config.filter ^= 1; config.filter ^= 1;
sprintf (items[3].text, "LowPass Filter: %s", config.filter ? " ON":"OFF");
break; break;
case 4: case 4:
config.hq_fm ++; config.hq_fm ++;
if (config.hq_fm>2) config.hq_fm = 0; if (config.hq_fm>2) config.hq_fm = 0;
if (config.hq_fm == 0) sprintf (items[4].text, "HQ YM2612: OFF");
else if (config.hq_fm == 1) sprintf (items[4].text, "HQ YM2612: LINEAR");
else sprintf (items[4].text, "HQ YM2612: SINC");
if (genromsize) if (genromsize)
{ {
unsigned char *temp = malloc(YM2612GetContextSize()); unsigned char *temp = memalign(32,YM2612GetContextSize());
if (temp) memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize()); if (temp) memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
audio_init(48000); audio_init(48000);
if (temp) if (temp)
@ -1492,25 +1583,29 @@ static void systemmenu ()
gui_menu *m = &menu_system; gui_menu *m = &menu_system;
gui_item *items = m->items; gui_item *items = m->items;
if (config.region_detect == 0) sprintf (items[0].text, "Console Region: AUTO");
else if (config.region_detect == 1) sprintf (items[0].text, "Console Region: USA");
else if (config.region_detect == 2) sprintf (items[0].text, "Console Region: EUR");
else if (config.region_detect == 3) sprintf (items[0].text, "Console Region: JAP");
sprintf (items[1].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
sprintf (items[2].text, "System BIOS: %s", (config.bios_enabled & 1) ? "ON":"OFF");
sprintf (items[3].text, "SVP Cycles: %d", SVP_cycles);
GUI_InitMenu(m); GUI_InitMenu(m);
GUI_SlideMenuTitle(m,strlen("System ")); GUI_SlideMenuTitle(m,strlen("System "));
while (quit == 0) while (quit == 0)
{ {
if (config.region_detect == 0) sprintf (items[0].text, "Console Region: AUTO");
else if (config.region_detect == 1) sprintf (items[0].text, "Console Region: USA");
else if (config.region_detect == 2) sprintf (items[0].text, "Console Region: EUR");
else if (config.region_detect == 3) sprintf (items[0].text, "Console Region: JAP");
sprintf (items[1].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
sprintf (items[2].text, "System BIOS: %s", (config.bios_enabled & 1) ? "ON":"OFF");
sprintf (items[3].text, "SVP Cycles: %d", SVP_cycles);
ret = GUI_RunMenu(m); ret = GUI_RunMenu(m);
switch (ret) switch (ret)
{ {
case 0: /*** Region Force ***/ case 0: /*** Region Force ***/
config.region_detect = (config.region_detect + 1) % 4; config.region_detect = (config.region_detect + 1) % 4;
if (config.region_detect == 0) sprintf (items[0].text, "Console Region: AUTO");
else if (config.region_detect == 1) sprintf (items[0].text, "Console Region: USA");
else if (config.region_detect == 2) sprintf (items[0].text, "Console Region: EUR");
else if (config.region_detect == 3) sprintf (items[0].text, "Console Region: JAP");
if (genromsize) if (genromsize)
{ {
/* force region & cpu mode */ /* force region & cpu mode */
@ -1518,11 +1613,14 @@ static void systemmenu ()
/* reinitialize timings */ /* reinitialize timings */
system_init (); system_init ();
unsigned char *temp = malloc(YM2612GetContextSize()); unsigned char *temp = memalign(32,YM2612GetContextSize());
if (temp) memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize()); if (temp) memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
audio_init(48000); audio_init(48000);
YM2612Restore(temp); if (temp)
if (temp) free(temp); {
YM2612Restore(temp);
free(temp);
}
/* reinitialize HVC tables */ /* reinitialize HVC tables */
vctab = (vdp_pal) ? ((reg[1] & 8) ? vc_pal_240 : vc_pal_224) : vc_ntsc_224; vctab = (vdp_pal) ? ((reg[1] & 8) ? vc_pal_240 : vc_pal_224) : vc_ntsc_224;
@ -1536,10 +1634,12 @@ static void systemmenu ()
case 1: /*** force DTACK ***/ case 1: /*** force DTACK ***/
config.force_dtack ^= 1; config.force_dtack ^= 1;
sprintf (items[1].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
break; break;
case 2: /*** BIOS support ***/ case 2: /*** BIOS support ***/
config.bios_enabled ^= 1; config.bios_enabled ^= 1;
sprintf (items[2].text, "System BIOS: %s", (config.bios_enabled & 1) ? "ON":"OFF");
if (genromsize || (config.bios_enabled == 3)) if (genromsize || (config.bios_enabled == 3))
{ {
system_init (); system_init ();
@ -1553,6 +1653,7 @@ static void systemmenu ()
if (ret<0) SVP_cycles = SVP_cycles ? (SVP_cycles-1) : 1500; if (ret<0) SVP_cycles = SVP_cycles ? (SVP_cycles-1) : 1500;
else SVP_cycles++; else SVP_cycles++;
if (SVP_cycles > 1500) SVP_cycles = 0; if (SVP_cycles > 1500) SVP_cycles = 0;
sprintf (items[3].text, "SVP Cycles: %d", SVP_cycles);
break; break;
case -1: case -1:
@ -1574,24 +1675,25 @@ static void videomenu ()
gui_menu *m = &menu_video; gui_menu *m = &menu_video;
gui_item *items = m->items; gui_item *items = m->items;
sprintf (items[0].text, "Aspect: %s", config.aspect ? "ORIGINAL" : "STRETCHED");
if (config.render == 1) sprintf (items[1].text,"Display: INTERLACED");
else if (config.render == 2) sprintf (items[1].text, "Display: PROGRESSIVE");
else sprintf (items[1].text, "Display: ORIGINAL");
if (config.tv_mode == 0) sprintf (items[2].text, "TV Mode: 60HZ");
else if (config.tv_mode == 1) sprintf (items[2].text, "TV Mode: 50HZ");
else sprintf (items[2].text, "TV Mode: 50/60HZ");
sprintf (items[3].text, "Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
if (config.ntsc == 1) sprintf (items[4].text, "NTSC Filter: COMPOSITE");
else if (config.ntsc == 2) sprintf (items[4].text, "NTSC Filter: S-VIDEO");
else if (config.ntsc == 3) sprintf (items[4].text, "NTSC Filter: RGB");
else sprintf (items[4].text, "NTSC Filter: OFF");
sprintf (items[5].text, "Borders: %s", config.overscan ? " ON" : "OFF");
GUI_InitMenu(m); GUI_InitMenu(m);
GUI_SlideMenuTitle(m,strlen("Video ")); GUI_SlideMenuTitle(m,strlen("Video "));
while (quit == 0) while (quit == 0)
{ {
sprintf (items[0].text, "Aspect: %s", config.aspect ? "ORIGINAL" : "STRETCHED");
if (config.render == 1) sprintf (items[1].text,"Display: INTERLACED");
else if (config.render == 2) sprintf (items[1].text, "Display: PROGRESSIVE");
else sprintf (items[1].text, "Display: ORIGINAL");
if (config.tv_mode == 0) sprintf (items[2].text, "TV Mode: 60HZ");
else if (config.tv_mode == 1) sprintf (items[2].text, "TV Mode: 50HZ");
else sprintf (items[2].text, "TV Mode: 50/60HZ");
sprintf (items[3].text, "Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
if (config.ntsc == 1) sprintf (items[4].text, "NTSC Filter: COMPOSITE");
else if (config.ntsc == 2) sprintf (items[4].text, "NTSC Filter: S-VIDEO");
else if (config.ntsc == 3) sprintf (items[4].text, "NTSC Filter: RGB");
else sprintf (items[4].text, "NTSC Filter: OFF");
sprintf (items[5].text, "Borders: %s", config.overscan ? " ON" : "OFF");
ret = GUI_RunMenu(m); ret = GUI_RunMenu(m);
@ -1599,6 +1701,7 @@ static void videomenu ()
{ {
case 0: /*** config.aspect ratio ***/ case 0: /*** config.aspect ratio ***/
config.aspect ^= 1; config.aspect ^= 1;
sprintf (items[0].text, "Aspect: %s", config.aspect ? "ORIGINAL" : "STRETCHED");
break; break;
case 1: /*** rendering ***/ case 1: /*** rendering ***/
@ -1616,25 +1719,38 @@ static void videomenu ()
config.render = 0; config.render = 0;
} }
} }
if (config.render == 1) sprintf (items[1].text,"Display: INTERLACED");
else if (config.render == 2) sprintf (items[1].text, "Display: PROGRESSIVE");
else sprintf (items[1].text, "Display: ORIGINAL");
if (config.tv_mode == 0) sprintf (items[2].text, "TV Mode: 60HZ");
else if (config.tv_mode == 1) sprintf (items[2].text, "TV Mode: 50HZ");
else sprintf (items[2].text, "TV Mode: 50/60HZ");
break; break;
case 2: /*** tv mode ***/ case 2: /*** tv mode ***/
if (config.render != 2) config.tv_mode = (config.tv_mode + 1) % 3; if (config.render != 2) config.tv_mode = (config.tv_mode + 1) % 3;
if (config.tv_mode == 0) sprintf (items[2].text, "TV Mode: 60HZ");
else if (config.tv_mode == 1) sprintf (items[2].text, "TV Mode: 50HZ");
else sprintf (items[2].text, "TV Mode: 50/60HZ");
break; break;
case 3: /*** bilinear filtering ***/ case 3: /*** bilinear filtering ***/
config.bilinear ^= 1; config.bilinear ^= 1;
sprintf (items[3].text, "Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
break; break;
case 4: /*** NTSC filter ***/ case 4: /*** NTSC filter ***/
config.ntsc ++; config.ntsc ++;
if (config.ntsc > 3) config.ntsc = 0; if (config.ntsc > 3) config.ntsc = 0;
if (config.ntsc == 1) sprintf (items[4].text, "NTSC Filter: COMPOSITE");
else if (config.ntsc == 2) sprintf (items[4].text, "NTSC Filter: S-VIDEO");
else if (config.ntsc == 3) sprintf (items[4].text, "NTSC Filter: RGB");
else sprintf (items[4].text, "NTSC Filter: OFF");
break; break;
case 5: /*** overscan emulation ***/ case 5: /*** overscan emulation ***/
config.overscan ^= 1; config.overscan ^= 1;
bitmap.viewport.x = config.overscan ? ((reg[12] & 1) ? 16 : 12) : 0; sprintf (items[5].text, "Borders: %s", config.overscan ? " ON" : "OFF");
bitmap.viewport.y = config.overscan ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0;
break; break;
/* case 6: /* case 6:
@ -1689,6 +1805,28 @@ static void inputsmenu(void)
u32 exp; u32 exp;
#endif #endif
/* gui_item items_sys[7][2] =
{
{
{NULL,Ctrl_none ,"","Port 1 - Unconnected",110,130,48,72},
{NULL,Ctrl_gamepad ,"","Port 1 - Gamepad" , 87,117,96,84},
{NULL,Ctrl_mouse ,"","Port 1 - Mouse" , 97,113,64,88},
{NULL,Ctrl_menacer ,"","Port 1 - Menacer" , 94,113,80,88},
{NULL,Ctrl_justifier ,"","Port 1 - Justifiers" , 88,117,80,84}
{NULL,Ctrl_teamplayer,"","Port 1 - Teamplayer" , 94,109,80,92},
{NULL,Ctrl_4wayplay ,"","Port 1 - 4 Way Play" , 98,110,72,92}
},
{
{NULL,Ctrl_none ,"","Port 2 - Unconnected",110,130,48,72},
{NULL,Ctrl_gamepad ,"","Port 2 - Gamepad" , 87,117,96,84},
{NULL,Ctrl_mouse ,"","Port 2 - Mouse" , 97,113,64,88},
{NULL,Ctrl_menacer ,"","Port 2 - Menacer" , 94,113,80,88},
{NULL,Ctrl_justifier ,"","Port 2 - Justifiers" , 88,117,80,84}
{NULL,Ctrl_teamplayer,"","Port 2 - Teamplayer" , 94,109,80,92},
{NULL,Ctrl_4wayplay ,"","Port 2 - 4 Way Play" , 98,110,72,92}
}
};
*/
strcpy (menutitle, "Press B to return"); strcpy (menutitle, "Press B to return");
menu = 0; menu = 0;
@ -2323,7 +2461,7 @@ void MainMenu (void)
} }
/* wiimote pointer */ /* wiimote pointer */
w_pointer = gxTextureOpenPNG(generic_point_png); w_pointer = gxTextureOpenPNG(generic_point_png,0);
#endif #endif
gui_menu *m = &menu_main; gui_menu *m = &menu_main;
@ -2332,8 +2470,8 @@ void MainMenu (void)
if (genromsize) if (genromsize)
{ {
m->screenshot = 1; m->screenshot = 1;
m->max_items = 8; m->max_items = 9;
m->max_buttons = 8; m->max_buttons = 9;
m->buttons[3].state |= BUTTON_SELECT_SFX; m->buttons[3].state |= BUTTON_SELECT_SFX;
m->buttons[5].state |= BUTTON_SELECT_SFX; m->buttons[5].state |= BUTTON_SELECT_SFX;
m->buttons[3].shift[1] = 3; m->buttons[3].shift[1] = 3;
@ -2378,6 +2516,7 @@ void MainMenu (void)
switch (GUI_WindowPrompt(m, VERSION, items,3)) switch (GUI_WindowPrompt(m, VERSION, items,3))
{ {
case 1: case 1:
GUI_FadeMenu(m,1,1);
#ifdef HW_RVL #ifdef HW_RVL
gxTextureClose(&w_pointer); gxTextureClose(&w_pointer);
#endif #endif
@ -2387,6 +2526,7 @@ void MainMenu (void)
break; break;
case 2: case 2:
GUI_FadeMenu(m,1,1);
#ifdef HW_RVL #ifdef HW_RVL
gxTextureClose(&w_pointer); gxTextureClose(&w_pointer);
#endif #endif
@ -2400,9 +2540,9 @@ void MainMenu (void)
break; break;
default: /* TODO */ default: /* TODO */
GUI_DeleteMenu(m);
break; break;
} }
GUI_DeleteMenu(m);
break; break;
} }
@ -2431,8 +2571,12 @@ void MainMenu (void)
GetGGEntries(); GetGGEntries();
break; break;
case 7: /*** ROM Information ***/ case 7: /*** ROM Captrure ***/
showrominfo (); if (genromsize) gx_video_Capture();
break;
case 8: /*** ROM Information ***/
if (genromsize) showrominfo ();
break; break;
} }
} }

View File

@ -64,7 +64,9 @@ extern const u8 Banner_top_png[];
extern const u8 Frame_s1_png[]; extern const u8 Frame_s1_png[];
extern const u8 Frame_s2_png[]; extern const u8 Frame_s2_png[];
extern const u8 Frame_title_png[]; extern const u8 Frame_s3_png[];
extern const u8 Frame_s1_title_png[];
extern const u8 Frame_s3_title_png[];
extern const u8 Overlay_bar_png[]; extern const u8 Overlay_bar_png[];
@ -83,6 +85,7 @@ extern const u8 Main_file_png[];
extern const u8 Main_reset_png[]; extern const u8 Main_reset_png[];
extern const u8 Main_ggenie_png[]; extern const u8 Main_ggenie_png[];
extern const u8 Main_showinfo_png[]; extern const u8 Main_showinfo_png[];
extern const u8 Main_takeshot_png[];
#ifdef HW_RVL #ifdef HW_RVL
extern const u8 Main_play_wii_png[]; extern const u8 Main_play_wii_png[];
#else #else
@ -221,6 +224,7 @@ extern void GUI_InitMenu(gui_menu *menu);
extern void GUI_DeleteMenu(gui_menu *menu); extern void GUI_DeleteMenu(gui_menu *menu);
extern void GUI_DrawMenu(gui_menu *menu); extern void GUI_DrawMenu(gui_menu *menu);
extern void GUI_DrawMenuFX(gui_menu *menu, u8 speed, u8 out); extern void GUI_DrawMenuFX(gui_menu *menu, u8 speed, u8 out);
extern void GUI_FadeMenu(gui_menu *menu, u8 speed, u8 out);
extern int GUI_RunMenu(gui_menu *menu); extern int GUI_RunMenu(gui_menu *menu);
extern int GUI_WindowPrompt(gui_menu *parent, char *title, char *items[], u8 nb_items);
#endif #endif

View File

@ -3,7 +3,7 @@
* *
* Genesis Plus GX audio support * Genesis Plus GX audio support
* *
* code by Eke-Eke (2007,2008) * code by Eke-Eke (2007,2009)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -54,25 +54,16 @@ static u8 audioStarted = 0;
static u8 *Bg_music_ogg = NULL; static u8 *Bg_music_ogg = NULL;
static u32 Bg_music_ogg_size = 0; static u32 Bg_music_ogg_size = 0;
/*** /***************************************************************************************/
AudioDmaCallback /* Audio engine */
/***************************************************************************************/
In 50Hz emulation mode, we synchronize frame emulation with audio DMA /* Audio DMA callback */
50Hz VSYNC period is shorter than DMA period so there is no video frameskipping static void ai_callback(void)
In 60Hz modes, VSYNC period is longer than default DMA period so it requires different sync.
***/
static void AudioDmaCallback(void)
{ {
frameticker++; frameticker++;
} }
/***
gx_audio__init
This function initializes the Audio Interface
Default samplerate is set to 48khZ
***/
void gx_audio_Init(void) void gx_audio_Init(void)
{ {
AUDIO_Init (NULL); AUDIO_Init (NULL);
@ -171,7 +162,7 @@ void gx_audio_Start(void)
AUDIO_RegisterDMACallback(NULL); AUDIO_RegisterDMACallback(NULL);
/* let's use audio DMA to synchronize frame emulation */ /* let's use audio DMA to synchronize frame emulation */
if (vdp_pal | gc_pal) AUDIO_RegisterDMACallback(AudioDmaCallback); if (vdp_pal | gc_pal) AUDIO_RegisterDMACallback(ai_callback);
/* 60hz video mode requires synchronization with Video interrupt */ /* 60hz video mode requires synchronization with Video interrupt */
/* VSYNC period is 16715 us which is approx. 802.32 samples */ /* VSYNC period is 16715 us which is approx. 802.32 samples */

View File

@ -3,7 +3,7 @@
* *
* Genesis Plus GX input support * Genesis Plus GX input support
* *
* code by Eke-Eke (2008) * code by Eke-Eke (2008-2009)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -42,7 +42,7 @@ typedef struct
{ {
u8 *buffer; u8 *buffer;
u32 offset; u32 offset;
} png_file; } png_image;
extern const u8 Crosshair_p1_png[]; extern const u8 Crosshair_p1_png[];
extern const u8 Crosshair_p2_png[]; extern const u8 Crosshair_p2_png[];
@ -52,6 +52,7 @@ unsigned int *xfb[2]; /* External Framebuffers */
int whichfb = 0; /* Current Framebuffer */ int whichfb = 0; /* Current Framebuffer */
GXRModeObj *vmode; /* Default Video Mode */ GXRModeObj *vmode; /* Default Video Mode */
u8 *texturemem; /* Texture Data */ u8 *texturemem; /* Texture Data */
u8 *screenshot; /* Texture Data */
/* 50/60hz flag */ /* 50/60hz flag */
u8 gc_pal = 0; u8 gc_pal = 0;
@ -65,13 +66,15 @@ static md_ntsc_setup_t md_setup;
/*** GX FIFO ***/ /*** GX FIFO ***/
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32); static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
/*** custom Video modes ***/
static GXRModeObj *rmode;
/*** GX Textures ***/ /*** GX Textures ***/
static u32 vwidth,vheight; static u32 vwidth,vheight;
static gx_texture *crosshair[2]; static gx_texture *crosshair[2];
/***************************************************************************************/
/* Emulation video modes */
/***************************************************************************************/
static GXRModeObj *rmode;
/* 288 lines progressive (PAL 50Hz) */ /* 288 lines progressive (PAL 50Hz) */
static GXRModeObj TV50hz_288p = static GXRModeObj TV50hz_288p =
{ {
@ -296,6 +299,11 @@ static GXRModeObj *tvmodes[6] =
&TV50hz_576i &TV50hz_576i
}; };
/***************************************************************************************/
/* GX rendering engine */
/***************************************************************************************/
typedef struct tagcamera typedef struct tagcamera
{ {
Vector pos; Vector pos;
@ -325,11 +333,6 @@ static camera cam = {
{0.0F, 0.0F, 0.0F} {0.0F, 0.0F, 0.0F}
}; };
static void updateFrameCount(u32 cnt)
{
frameticker++;
}
/* Vertex Rendering */ /* Vertex Rendering */
static inline void draw_vert(u8 pos, f32 s, f32 t) static inline void draw_vert(u8 pos, f32 s, f32 t)
{ {
@ -348,7 +351,7 @@ static inline void draw_square(void)
GX_End (); GX_End ();
} }
/* Initialize GX renderer */ /* Initialize GX */
static void gxStart(void) static void gxStart(void)
{ {
/*** Clear out FIFO area ***/ /*** Clear out FIFO area ***/
@ -589,79 +592,344 @@ static void gxDrawCrosshair(gx_texture *texture, int x, int y)
} }
} }
void gxDrawRectangle(s32 x, s32 y, s32 w, s32 h, u8 alpha, GXColor color)
{
/* GX only use Color channel for rendering */
GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR);
GX_SetVtxDesc (GX_VA_TEX0, GX_NONE);
GX_Flush();
/* vertex coordinate */
x -= (vmode->fbWidth/2);
y -= (vmode->efbHeight/2);
/* draw colored quad */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(x,y+h);
GX_Color4u8(color.r,color.g,color.b,alpha);
GX_Position2s16(x+w,y+h);
GX_Color4u8(color.r,color.g,color.b,alpha);
GX_Position2s16(x+w,y);
GX_Color4u8(color.r,color.g,color.b,alpha);
GX_Position2s16(x,y);
GX_Color4u8(color.r,color.g,color.b,alpha);
GX_End ();
GX_DrawDone();
/* restore GX rendering */
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE);
GX_Flush();
}
void gxDrawTexture(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha)
{
if (!texture) return;
if (texture->data)
{
/* load texture object */
GXTexObj texObj;
GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObjLOD(&texObj,GX_LINEAR,GX_LIN_MIP_LIN,0.0,10.0,0.0,GX_FALSE,GX_TRUE,GX_ANISO_4); /* does this really change anything ? */
GX_LoadTexObj(&texObj, GX_TEXMAP0);
GX_InvalidateTexAll();
/* vertex coordinate */
x -= (vmode->fbWidth/2);
y -= (vmode->efbHeight/2);
/* draw textured quad */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(x,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 1.0);
GX_Position2s16(x+w,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(1.0, 1.0);
GX_Position2s16(x+w,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(1.0, 0.0);
GX_Position2s16(x,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 0.0);
GX_End ();
GX_DrawDone();
}
}
void gxDrawTextureRepeat(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha)
{
if (!texture) return;
if (texture->data)
{
/* load texture object */
GXTexObj texObj;
GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_MIRROR, GX_MIRROR, GX_FALSE);
GX_LoadTexObj(&texObj, GX_TEXMAP0);
GX_InvalidateTexAll();
/* vertex coordinate */
x -= (vmode->fbWidth/2);
y -= (vmode->efbHeight/2);
/* texture coordinates */
f32 s = (f32)w / (f32)texture->width;
f32 t = (f32)h / (f32)texture->height;
/* draw textured quad */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(x,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, t);
GX_Position2s16(x+w,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(s, t);
GX_Position2s16(x+w,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(s, 0.0);
GX_Position2s16(x,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 0.0);
GX_End ();
GX_DrawDone();
}
}
void gxDrawScreenshot(u8 alpha)
{
if (!rmode) return;
GXTexObj texobj;
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_LoadTexObj(&texobj, GX_TEXMAP0);
GX_InvalidateTexAll();
/* retrieve current xscale/xshift values */
s32 xscale = (rmode->viWidth + square[6] - square[0] - rmode->fbWidth) / 2 - (vmode->viWidth - 640)/2;
s32 xshift = (square[6] + square[0]) / 2;
/* apply current position/size */
s32 x = xshift - xscale;
s32 y = square[7];
s32 w = xscale * 2;
s32 h = square[4] - square[7];
if (rmode->efbHeight < 480)
{
y = y * 2;
h = h * 2;
}
/* Draw textured quad */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(x,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 1.0);
GX_Position2s16(x+w,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(1.0, 1.0);
GX_Position2s16(x+w,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(1.0, 0.0);
GX_Position2s16(x,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 0.0);
GX_End ();
GX_DrawDone();
}
void gxCopyScreenshot(gx_texture *texture)
{
/* current game texture */
gxClearScreen((GXColor)BLACK);
GXTexObj texobj;
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_LoadTexObj(&texobj, GX_TEXMAP0);
GX_InvalidateTexAll();
/* scale texture to EFB width */
s32 w = bitmap.viewport.x ? (704) : (640);
s32 h = (bitmap.viewport.h + 2*bitmap.viewport.y) * 2;
s32 x = -w/2;
s32 y = -(240+ 2*bitmap.viewport.y);
/* render gamescreen to EFB */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(x,y+h);
GX_Color4u8(0xff,0xff,0xff,0xff);
GX_TexCoord2f32(0.0, 1.0);
GX_Position2s16(x+w,y+h);
GX_Color4u8(0xff,0xff,0xff,0xff);
GX_TexCoord2f32(1.0, 1.0);
GX_Position2s16(x+w,y);
GX_Color4u8(0xff,0xff,0xff,0xff);
GX_TexCoord2f32(1.0, 0.0);
GX_Position2s16(x,y);
GX_Color4u8(0xff,0xff,0xff,0xff);
GX_TexCoord2f32(0.0, 0.0);
GX_End ();
GX_DrawDone();
/* copy EFB to texture */
texture->format = GX_TF_RGBA8;
texture->width = 320;
texture->height = bitmap.viewport.h;
texture->data = screenshot;
GX_SetTexCopySrc(0, 0, texture->width * 2, texture->height * 2);
GX_SetTexCopyDst(texture->width, texture->height, texture->format, GX_TRUE);
GX_CopyTex(texture->data, GX_TRUE);
GX_Flush();
/* wait for copy operation to finish */
/* GX_PixModeSync is only useful if GX_ command follows */
/* we use dummy GX commands to stall CPU execution */
GX_PixModeSync();
GX_LoadTexObj(&texobj, GX_TEXMAP0);
GX_InvalidateTexAll();
DCFlushRange(texture->data, texture->width * texture->height * 4);
}
void gxResetAngle(f32 angle)
{
Mtx view;
if (angle)
{
Mtx m,m1;
Vector axis = (Vector) {0,0,1};
guLookAt(m, &cam.pos, &cam.up, &cam.view);
guMtxRotAxisDeg (m1, &axis, angle);
guMtxConcat(m,m1,view);
}
else
{
guLookAt(view, &cam.pos, &cam.up, &cam.view);
}
GX_LoadPosMtxImm(view, GX_PNMTX0);
GX_Flush();
}
void gxSetScreen ()
{
GX_CopyDisp(xfb[whichfb], GX_FALSE);
GX_Flush();
VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_Flush ();
VIDEO_WaitVSync ();
}
void gxClearScreen (GXColor color)
{
whichfb ^= 1;
GX_SetCopyClear(color,0x00ffffff);
GX_CopyDisp(xfb[whichfb], GX_TRUE);
GX_Flush();
}
/***************************************************************************************/
/* GX Texture <-> LibPNG routines */
/***************************************************************************************/
/* libpng read callback function */ /* libpng read callback function */
static void png_read_from_mem (png_structp png_ptr, png_bytep data, png_size_t length) static void png_read_from_mem (png_structp png_ptr, png_bytep data, png_size_t length)
{ {
png_file *file = (png_file *)png_get_io_ptr (png_ptr); png_image *image = (png_image *)png_get_io_ptr(png_ptr);
/* copy data from image buffer */ /* copy data from image buffer */
memcpy (data, file->buffer + file->offset, length); memcpy (data, image->buffer + image->offset, length);
/* advance in the file */ /* advance in the file */
file->offset += length; image->offset += length;
} }
/* convert a png file into RGBA8 texture */ /* convert PNG image (from file or data buffer) into RGBA8 texture */
gx_texture *gxTextureOpenPNG(const u8 *buffer) gx_texture *gxTextureOpenPNG(const u8 *png_data, FILE *png_file)
{ {
int i; int i;
png_file file;
/* init PNG file structure */
file.buffer = (u8 *) buffer;
file.offset = 0;
/* check for valid magic number */
/*if (!png_check_sig (file.buffer, 8)) return;*/
/* create a png read struct */ /* create a png read struct */
png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
if (!png_ptr) return NULL; if (!png_ptr) return NULL;
/* create a png info struct */ /* create a png info struct */
png_infop info_ptr = png_create_info_struct (png_ptr); png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) if (!info_ptr)
{ {
png_destroy_read_struct (&png_ptr, NULL, NULL); png_destroy_read_struct(&png_ptr,NULL,NULL);
return NULL; return NULL;
} }
/* set callback for the read function */ if (png_data)
png_set_read_fn (png_ptr, (png_voidp *)(&file), png_read_from_mem); {
/* init PNG image structure */
png_image image;
image.buffer = (u8 *) png_data;
image.offset = 0;
/* set callback for the read function */
png_set_read_fn(png_ptr,(png_voidp *)(&image),png_read_from_mem);
}
else if (png_file)
{
/* check for valid magic number */
png_byte magic[8];
if (fread (magic, 1, 8, png_file) != 8)
{
png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
return NULL;
}
if (!png_check_sig (magic, 8))
if (fread (magic, 1, 8, png_file) != 8)
{
png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
return NULL;
}
/* set IO callback for read function */
png_init_io (png_ptr, png_file);
png_set_sig_bytes (png_ptr, 8);
}
else
{
png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
return NULL;
}
/* read png info */ /* read png info */
png_read_info (png_ptr, info_ptr); png_read_info(png_ptr,info_ptr);
/* retrieve image information */ /* retrieve image information */
u32 width = png_get_image_width(png_ptr, info_ptr); u32 width = png_get_image_width(png_ptr,info_ptr);
u32 height = png_get_image_height(png_ptr, info_ptr); u32 height = png_get_image_height(png_ptr,info_ptr);
u32 bit_depth = png_get_bit_depth(png_ptr,info_ptr);
u32 color_type = png_get_color_type(png_ptr,info_ptr);
#if 0 /* ensure PNG file is in the supported format */
/* ensure PNG images are in the supported format */ if (png_file)
u32 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
u32 color_type = png_get_color_type(png_ptr, info_ptr);
/* support for RGBA8 textures ONLY !*/
if ((color_type != PNG_COLOR_TYPE_RGB_ALPHA) || (bit_depth != 8))
{ {
png_destroy_read_struct (&png_ptr, &info_ptr, NULL); /* support for RGBA8 textures ONLY !*/
return; if ((color_type != PNG_COLOR_TYPE_RGB_ALPHA) || (bit_depth != 8))
} {
png_destroy_read_struct(&png_ptr, &info_ptr,NULL);
return NULL;
}
/* 4x4 tiles are required */ /* 4x4 tiles are required */
if ((width%4) || (height%4)) if ((width%4) || (height%4))
{ {
png_destroy_read_struct (&png_ptr, &info_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return; return NULL;
}
} }
#endif
/* allocate memory to store raw image data */ /* allocate memory to store raw image data */
u32 stride = width << 2; u32 stride = width << 2;
u8 *img_data = memalign (32, stride * height); u8 *img_data = memalign (32, stride * height);
if (!img_data) if (!img_data)
{ {
png_destroy_read_struct (&png_ptr, &info_ptr, NULL); png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
return NULL; return NULL;
} }
@ -670,7 +938,7 @@ gx_texture *gxTextureOpenPNG(const u8 *buffer)
if (!row_pointers) if (!row_pointers)
{ {
free (img_data); free (img_data);
png_destroy_read_struct (&png_ptr, &info_ptr, NULL); png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
return NULL; return NULL;
} }
@ -681,11 +949,11 @@ gx_texture *gxTextureOpenPNG(const u8 *buffer)
} }
/* decode image */ /* decode image */
png_read_image (png_ptr, row_pointers); png_read_image(png_ptr, row_pointers);
/* finish decompression and release memory */ /* finish decompression and release memory */
png_read_end (png_ptr, NULL); png_read_end(png_ptr, NULL);
png_destroy_read_struct (&png_ptr, &info_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
free(row_pointers); free(row_pointers);
/* initialize texture */ /* initialize texture */
@ -776,6 +1044,127 @@ gx_texture *gxTextureOpenPNG(const u8 *buffer)
return texture; return texture;
} }
/* Write RGBA8 Texture to PNG file */
void gxTextureWritePNG(gx_texture *texture, FILE *png_file)
{
/* allocate PNG data buffer */
u8 *img_data = (u8 *)memalign(32, texture->width * texture->height * 4);
if(!img_data) return;
/* decode GX_TF_RGBA8 format (4x4 pixels paired titles) */
u16 *ar = (u16 *)(texture->data);
u16 *gb = (u16 *)(texture->data + 32);
u32 *dst1 = (u32 *)(img_data);
u32 *dst2 = dst1 + texture->width;
u32 *dst3 = dst2 + texture->width;
u32 *dst4 = dst3 + texture->width;
u32 i,h,w,pixel;
for (h=0; h<texture->height; h+=4)
{
for (w=0; w<texture->width; w+=4)
{
/* line N (4 pixels) */
for (i=0; i<4; i++)
{
pixel = ((*ar & 0xff) << 24) | (*gb << 8) | ((*ar & 0xff00) >> 8);
*dst1++ = pixel;
ar++;
gb++;
}
/* line N + 1 (4 pixels) */
for (i=0; i<4; i++)
{
pixel = ((*ar & 0xff) << 24) | (*gb << 8) | ((*ar & 0xff00) >> 8);
*dst2++ = pixel;
ar++;
gb++;
}
/* line N + 2 (4 pixels) */
for (i=0; i<4; i++)
{
pixel = ((*ar & 0xff) << 24) | (*gb << 8) | ((*ar & 0xff00) >> 8);
*dst3++ = pixel;
ar++;
gb++;
}
/* line N + 3 (4 pixels) */
for (i=0; i<4; i++)
{
pixel = ((*ar & 0xff) << 24) | (*gb << 8) | ((*ar & 0xff00) >> 8);
*dst4++ = pixel;
ar++;
gb++;
}
/* next paired tiles */
ar += 16;
gb += 16;
}
/* next 4 lines */
dst1 = dst4;
dst2 = dst1 + texture->width;
dst3 = dst2 + texture->width;
dst4 = dst3 + texture->width;
}
/* create a png write struct */
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr)
{
free(img_data);
return;
}
/* create a png info struct */
png_infop info_ptr = png_create_info_struct (png_ptr);
if (!info_ptr)
{
free(img_data);
png_destroy_write_struct(&png_ptr, NULL);
return;
}
/* set IO callback for the write function */
png_init_io(png_ptr, png_file);
/* set PNG file properties */
png_set_IHDR(png_ptr, info_ptr, texture->width, texture->height, 8, PNG_COLOR_TYPE_RGB_ALPHA,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
/* allocate row pointer data */
png_bytep *row_pointers = (png_bytep *)memalign (32, sizeof (png_bytep) * texture->height);
if (!row_pointers)
{
free (img_data);
png_destroy_write_struct(&png_ptr, &info_ptr);
return;
}
/* store raw image data */
for (i = 0; i < texture->height; i++)
{
row_pointers[i] = img_data + (i * texture->width * 4);
}
/* configure libpng for image data */
png_set_rows(png_ptr,info_ptr,row_pointers);
/* write data to PNG file */
png_write_png(png_ptr,info_ptr,PNG_TRANSFORM_IDENTITY,NULL);
/* finish compression and release memory */
png_write_end(png_ptr, NULL);
free(row_pointers);
free(img_data);
png_destroy_write_struct(&png_ptr, &info_ptr);
}
void gxTextureClose(gx_texture **p_texture) void gxTextureClose(gx_texture **p_texture)
{ {
gx_texture *texture = *p_texture; gx_texture *texture = *p_texture;
@ -788,177 +1177,42 @@ void gxTextureClose(gx_texture **p_texture)
} }
} }
void gxDrawScreenshot(u8 alpha)
/***************************************************************************************/
/* VIDEO engine */
/***************************************************************************************/
/* VIDEO callback */
static void vi_callback(u32 cnt)
{ {
if (rmode) frameticker++;
}
/* Take Screenshot */
void gx_video_Capture(void)
{
/* capture screenshot into a texture */
gx_texture texture;
gxCopyScreenshot(&texture);
/* open PNG file */
char fname[MAXPATHLEN];
sprintf(fname,"%s/snaps/%s.png", DEFAULT_PATH, rom_filename);
FILE *f = fopen(fname,"wb");
if (f)
{ {
GXTexObj texobj; /* encode screenshot into PNG file */
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); gxTextureWritePNG(&texture,f);
GX_LoadTexObj(&texobj, GX_TEXMAP0); fclose(f);
GX_InvalidateTexAll();
/* retrieve current xscale/xshift values */
s32 xscale = (rmode->viWidth + square[6] - square[0] - rmode->fbWidth) / 2 - (vmode->viWidth - 640)/2;
s32 xshift = (square[6] + square[0]) / 2;
/* apply current position/size */
s32 x = xshift - xscale;
s32 y = square[7];
s32 w = xscale * 2;
s32 h = square[4] - square[7];
if (rmode->efbHeight < 480)
{
y = y * 2;
h = h * 2;
}
/* Draw textured quad */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(x,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 1.0);
GX_Position2s16(x+w,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(1.0, 1.0);
GX_Position2s16(x+w,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(1.0, 0.0);
GX_Position2s16(x,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 0.0);
GX_End ();
GX_DrawDone();
} }
} }
void gxDrawTexture(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha) /* Emulation mode -> Menu mode */
{
if (!texture) return;
if (texture->data)
{
/* load texture object */
GXTexObj texObj;
GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObjLOD(&texObj,GX_LINEAR,GX_LIN_MIP_LIN,0.0,10.0,0.0,GX_FALSE,GX_TRUE,GX_ANISO_4); /* does this really change anything ? */
GX_LoadTexObj(&texObj, GX_TEXMAP0);
GX_InvalidateTexAll();
/* vertex coordinate */
x -= (vmode->fbWidth/2);
y -= (vmode->efbHeight/2);
/* draw textured quad */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(x,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 1.0);
GX_Position2s16(x+w,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(1.0, 1.0);
GX_Position2s16(x+w,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(1.0, 0.0);
GX_Position2s16(x,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 0.0);
GX_End ();
GX_DrawDone();
}
}
void gxDrawTextureRepeat(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha)
{
if (!texture) return;
if (texture->data)
{
/* load texture object */
GXTexObj texObj;
GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_MIRROR, GX_MIRROR, GX_FALSE);
GX_LoadTexObj(&texObj, GX_TEXMAP0);
GX_InvalidateTexAll();
/* vertex coordinate */
x -= (vmode->fbWidth/2);
y -= (vmode->efbHeight/2);
/* texture coordinates */
f32 s = (f32)w / (f32)texture->width;
f32 t = (f32)h / (f32)texture->height;
/* draw textured quad */
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(x,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, t);
GX_Position2s16(x+w,y+h);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(s, t);
GX_Position2s16(x+w,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(s, 0.0);
GX_Position2s16(x,y);
GX_Color4u8(0xff,0xff,0xff,alpha);
GX_TexCoord2f32(0.0, 0.0);
GX_End ();
GX_DrawDone();
}
}
void gxResetAngle(f32 angle)
{
Mtx view;
if (angle)
{
Mtx m,m1;
Vector axis = (Vector) {0,0,1};
guLookAt(m, &cam.pos, &cam.up, &cam.view);
guMtxRotAxisDeg (m1, &axis, angle);
guMtxConcat(m,m1,view);
}
else
{
guLookAt(view, &cam.pos, &cam.up, &cam.view);
}
GX_LoadPosMtxImm(view, GX_PNMTX0);
GX_Flush();
}
void gxSetScreen ()
{
GX_CopyDisp(xfb[whichfb], GX_FALSE);
GX_Flush();
VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_Flush ();
VIDEO_WaitVSync ();
}
void gxClearScreen (GXColor color)
{
whichfb ^= 1;
GX_SetCopyClear(color,0x00ffffff);
GX_CopyDisp(xfb[whichfb], GX_TRUE);
GX_Flush();
}
/* Restore Menu Video mode */
void gx_video_Stop(void) void gx_video_Stop(void)
{ {
/* lightgun textures */ /* lightgun textures */
if (crosshair[0]) gxTextureClose(&crosshair[0]);
{ gxTextureClose(&crosshair[1]);
if (crosshair[0]->data) free(crosshair[0]->data);
free(crosshair[0]);
crosshair[0] = NULL;
}
if (crosshair[1])
{
if (crosshair[1]->data) free(crosshair[1]->data);
free(crosshair[1]);
crosshair[1] = NULL;
}
/* reset GX */ /* reset GX */
gxResetRendering(1); gxResetRendering(1);
@ -972,16 +1226,17 @@ void gx_video_Stop(void)
gxSetScreen (); gxSetScreen ();
} }
/* Update Video settings */ /* Menu mode -> Emulation mode */
void gx_video_Start(void) void gx_video_Start(void)
{ {
/* 50Hz/60Hz mode */ /* 50Hz/60Hz mode */
if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1; if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1;
else gc_pal = 0; else gc_pal = 0;
/* Video Interrupt synchronization */ /* VIDEO sync */
VIDEO_SetPostRetraceCallback(NULL); VIDEO_SetPostRetraceCallback(NULL);
if (!gc_pal && !vdp_pal) VIDEO_SetPreRetraceCallback(updateFrameCount); if (!gc_pal && !vdp_pal)
VIDEO_SetPreRetraceCallback(vi_callback);
VIDEO_Flush(); VIDEO_Flush();
/* interlaced/progressive mode */ /* interlaced/progressive mode */
@ -996,6 +1251,19 @@ void gx_video_Start(void)
tvmodes[2]->xfbMode = VI_XFBMODE_DF; tvmodes[2]->xfbMode = VI_XFBMODE_DF;
} }
/* overscan */
if (config.overscan)
{
bitmap.viewport.x = (reg[12] & 1) ? 16 : 12;
bitmap.viewport.y = (reg[1] & 8) ? 0 : 8;
if (vdp_pal) bitmap.viewport.y += 24;
}
else
{
bitmap.viewport.x = 0;
bitmap.viewport.y = 0;
}
/* software NTSC filters */ /* software NTSC filters */
if (config.ntsc == 1) if (config.ntsc == 1)
{ {
@ -1024,8 +1292,8 @@ void gx_video_Start(void)
{ {
if (config.gun_cursor) if (config.gun_cursor)
{ {
if (input.dev[4] == DEVICE_LIGHTGUN) crosshair[0] = gxTextureOpenPNG(Crosshair_p1_png); if (input.dev[4] == DEVICE_LIGHTGUN) crosshair[0] = gxTextureOpenPNG(Crosshair_p1_png,0);
if (input.dev[5] == DEVICE_LIGHTGUN) crosshair[1] = gxTextureOpenPNG(Crosshair_p2_png); if (input.dev[5] == DEVICE_LIGHTGUN) crosshair[1] = gxTextureOpenPNG(Crosshair_p2_png,0);
} }
} }
@ -1034,10 +1302,8 @@ void gx_video_Start(void)
/* reset GX rendering */ /* reset GX rendering */
gxResetRendering(0); gxResetRendering(0);
} }
/* GX render update */ /* GX render update */
void gx_video_Update(void) void gx_video_Update(void)
{ {
@ -1244,24 +1510,16 @@ void gx_video_Init(void)
#endif #endif
} }
/* Initialize texture data */ /* Initialize textures */
texturemem = memalign(32, TEX_SIZE); texturemem = memalign(32, TEX_SIZE);
if (!texturemem) screenshot = memalign(32, HASPECT*VASPECT*4);
{ if (!texturemem || !screenshot) gx_video_Shutdown();
WaitPrompt("Failed to allocate texture buffer... Rebooting");
#ifdef HW_RVL
DI_Close();
SYS_ResetSystem(SYS_RESTART,0,0);
#else
SYS_ResetSystem(SYS_HOTRESET,0,0);
#endif
}
memset (texturemem, 0, TEX_SIZE);
} }
void gx_video_Shutdown(void) void gx_video_Shutdown(void)
{ {
if (texturemem) free(texturemem); if (texturemem) free(texturemem);
if (screenshot) free(screenshot);
FONT_Shutdown(); FONT_Shutdown();
VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK); VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK);
VIDEO_Flush(); VIDEO_Flush();

View File

@ -45,21 +45,28 @@ extern GXRModeObj *vmode;
extern u8 *texturemem; extern u8 *texturemem;
extern u8 gc_pal; extern u8 gc_pal;
/* GX video emulation functions */
/* GX rendering */
extern void gxDrawRectangle(s32 x, s32 y, s32 w, s32 h, u8 alpha, GXColor color);
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 gxDrawScreenshot(u8 alpha);
extern void gxCopyScreenshot(gx_texture *texture);
extern void gxResetAngle(f32 angle);
extern void gxClearScreen (GXColor color);
extern void gxSetScreen ();
/* PNG textures */
extern gx_texture *gxTextureOpenPNG(const u8 *png_data, FILE *png_file);
extern void gxTextureWritePNG(gx_texture *p_texture, FILE *png_file);
extern void gxTextureClose(gx_texture **p_texture);
/* GX video engine */
extern void gx_video_Init(void); extern void gx_video_Init(void);
extern void gx_video_Shutdown(void); extern void gx_video_Shutdown(void);
extern void gx_video_Start(void); extern void gx_video_Start(void);
extern void gx_video_Stop(void); extern void gx_video_Stop(void);
extern void gx_video_Update(void); extern void gx_video_Update(void);
extern void gx_video_Capture(void);
/* GX draw functions */
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, 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 ();
#endif #endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 KiB

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 698 B

View File

@ -1,9 +1,9 @@
/**************************************************************************** /****************************************************************************
* main.c * main.c
* *
* Genesis Plus GX main * Genesis Plus GX
* *
* code by Softdev (2006), Eke-Eke (2007,2008) * code by Softdev (2006), Eke-Eke (2007,2009)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -156,7 +156,7 @@ u32 frameticker = 0;
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
#ifdef HW_RVL #ifdef HW_RVL
/* initialize DVD Mode */ /* initialize DVDX */
DI_Close(); DI_Close();
DI_Init(); DI_Init();
#endif #endif
@ -168,7 +168,6 @@ int main (int argc, char *argv[])
/* initialize hardware */ /* initialize hardware */
gx_video_Init(); gx_video_Init();
gx_input_Init(); gx_input_Init();
gx_audio_Init();
#ifdef HW_DOL #ifdef HW_DOL
DVD_Init (); DVD_Init ();
dvd_drive_detect(); dvd_drive_detect();
@ -177,7 +176,6 @@ int main (int argc, char *argv[])
/* initialize FAT devices */ /* initialize FAT devices */
if (fatInitDefault()) if (fatInitDefault())
{ {
fat_enabled = 1;
#ifdef HW_RVL #ifdef HW_RVL
fatEnableReadAhead ("sd", 6, 64); fatEnableReadAhead ("sd", 6, 64);
fatEnableReadAhead ("usb", 6, 64); fatEnableReadAhead ("usb", 6, 64);
@ -185,22 +183,44 @@ int main (int argc, char *argv[])
fatEnableReadAhead ("carda", 6, 64); fatEnableReadAhead ("carda", 6, 64);
fatEnableReadAhead ("cardb", 6, 64); fatEnableReadAhead ("cardb", 6, 64);
#endif #endif
/* check for default directories */
DIR_ITER *dir = NULL;
/* base directory */
char pathname[MAXPATHLEN];
sprintf (pathname, DEFAULT_PATH);
dir = diropen(pathname);
if (dir == NULL) mkdir(pathname,S_IRWXU);
else dirclose(dir);
/* SRAM & Savestate files directory */
sprintf (pathname, "%s/saves",DEFAULT_PATH);
dir = diropen(pathname);
if (dir == NULL) mkdir(pathname,S_IRWXU);
else dirclose(dir);
/* Snapshot files directory */
sprintf (pathname, "%s/snaps",DEFAULT_PATH);
dir = diropen(pathname);
if (dir == NULL) mkdir(pathname,S_IRWXU);
else dirclose(dir);
/* Cheat files directory */
sprintf (pathname, "%s/cheats",DEFAULT_PATH);
dir = diropen(pathname);
if (dir == NULL) mkdir(pathname,S_IRWXU);
else dirclose(dir);
} }
/* Initialize sound engine */ /* initialize sound engine */
gx_audio_Init(); gx_audio_Init();
/* default config */ /* initialize core engine */
legal(); legal();
config_setDefault(); config_default();
config_load(); history_default();
init_machine();
/* recent ROM files list */
history_setDefault();
history_load();
/* initialize Virtual Machine */
init_machine ();
/* run any injected rom */ /* run any injected rom */
if (genromsize) if (genromsize)
@ -213,7 +233,7 @@ int main (int argc, char *argv[])
} }
else else
{ {
/* show menu first */ /* Main Menu */
ConfigRequested = 1; ConfigRequested = 1;
} }
@ -225,14 +245,14 @@ int main (int argc, char *argv[])
/* main emulation loop */ /* main emulation loop */
while (1) while (1)
{ {
/* check for menu request */ /* Main Menu request */
if (ConfigRequested) if (ConfigRequested)
{ {
/* stop audio & video */ /* stop audio & video */
gx_video_Stop(); gx_video_Stop();
gx_audio_Stop(); gx_audio_Stop();
/* go to menu */ /* show menu */
MainMenu (); MainMenu ();
ConfigRequested = 0; ConfigRequested = 0;

View File

@ -23,9 +23,9 @@
#define DEFAULT_PATH "/genplus" #define DEFAULT_PATH "/genplus"
#ifdef HW_RVL #ifdef HW_RVL
#define VERSION "v1.3.2 (WII)" #define VERSION "version 1.3.2W"
#else #else
#define VERSION "v1.3.2 (GCN)" #define VERSION "version 1.3.2G"
#endif #endif
/* globals */ /* globals */
@ -42,7 +42,6 @@ extern int ManageState(u8 direction, u8 device);
extern void memfile_autosave(s8 autosram, s8 autostate); extern void memfile_autosave(s8 autosram, s8 autostate);
extern void memfile_autoload(s8 autosram, s8 autostate); extern void memfile_autoload(s8 autosram, s8 autostate);
extern u8 fat_enabled;
extern u32 frameticker; extern u32 frameticker;
extern char rom_filename[256]; extern char rom_filename[256];

View File

@ -387,11 +387,11 @@ static uint16 pixel_16[0x100];
static uint16 pixel_16_lut[3][0x200]; static uint16 pixel_16_lut[3][0x200];
/* Line buffers */ /* Line buffers */
static uint8 tmp_buf[0x400]; /* Temporary buffer */ static uint8 tmp_buf[0x200]; /* Temporary buffer */
static uint8 bg_buf[0x400]; /* Merged background buffer */ static uint8 bg_buf[0x200]; /* Merged background buffer */
static uint8 nta_buf[0x400]; /* Plane A / Window line buffer */ static uint8 nta_buf[0x200]; /* Plane A / Window line buffer */
static uint8 ntb_buf[0x400]; /* Plane B line buffer */ static uint8 ntb_buf[0x200]; /* Plane B line buffer */
static uint8 obj_buf[0x400]; /* Object layer line buffer */ static uint8 obj_buf[0x200]; /* Object layer line buffer */
/* Sprite line buffer data */ /* Sprite line buffer data */
static uint32 object_index_count; static uint32 object_index_count;

View File

@ -2156,4 +2156,12 @@ void YM2612Restore(unsigned char *buffer)
ym2612.OPN.ST.clock = clock; ym2612.OPN.ST.clock = clock;
ym2612.OPN.ST.rate = rate; ym2612.OPN.ST.rate = rate;
OPNSetPres(6*24); OPNSetPres(6*24);
/* restore outputs connections */
setup_connection(&ym2612.CH[0],0);
setup_connection(&ym2612.CH[1],1);
setup_connection(&ym2612.CH[2],2);
setup_connection(&ym2612.CH[3],3);
setup_connection(&ym2612.CH[4],4);
setup_connection(&ym2612.CH[5],5);
} }

View File

@ -22,6 +22,8 @@
#include "shared.h" #include "shared.h"
static unsigned char state[STATE_SIZE];
#define load_param(param, size) \ #define load_param(param, size) \
memcpy(param, &state[bufferptr], size); \ memcpy(param, &state[bufferptr], size); \
bufferptr+= size; bufferptr+= size;
@ -32,10 +34,6 @@
void state_load(unsigned char *buffer) void state_load(unsigned char *buffer)
{ {
/* allocate memory */
unsigned char *state = malloc(STATE_SIZE);
if (state == NULL) return;
/* buffer size */ /* buffer size */
int bufferptr = 0; int bufferptr = 0;
@ -79,14 +77,8 @@ void state_load(unsigned char *buffer)
vdp_restore(temp_reg); vdp_restore(temp_reg);
// FM // FM
unsigned char *temp = malloc (YM2612GetContextSize()); YM2612Restore(&state[bufferptr]);
if (temp) bufferptr+= YM2612GetContextSize();
{
load_param(temp,YM2612GetContextSize());
YM2612Restore(temp);
free(temp);
}
else bufferptr+=YM2612GetContextSize();
// PSG // PSG
load_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ()); load_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
@ -116,17 +108,10 @@ void state_load(unsigned char *buffer)
// Z80 // Z80
load_param(&Z80, sizeof(Z80_Regs)); load_param(&Z80, sizeof(Z80_Regs));
/* Free memory */
free(state);
} }
int state_save(unsigned char *buffer) int state_save(unsigned char *buffer)
{ {
/* allocate memory */
unsigned char *state = malloc(STATE_SIZE);
if (state == NULL) return 0;
/* buffer size */ /* buffer size */
int bufferptr = 0; int bufferptr = 0;
@ -166,21 +151,21 @@ int state_save(unsigned char *buffer)
uint16 tmp16; uint16 tmp16;
uint32 tmp32; uint32 tmp32;
tmp32 = m68k_get_reg(NULL, M68K_REG_D0); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D0); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D1); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D1); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D2); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D2); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D3); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D3); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D4); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D4); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D5); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D5); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D6); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D6); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D7); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_D7); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A0); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A0); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A1); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A1); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A2); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A2); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A3); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A3); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A4); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A4); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A5); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A5); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A6); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A6); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A7); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_A7); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_PC); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_PC); save_param(&tmp32, 4);
tmp16 = m68k_get_reg(NULL, M68K_REG_SR); save_param(&tmp16, 2); tmp16 = m68k_get_reg(NULL, M68K_REG_SR); save_param(&tmp16, 2);
tmp32 = m68k_get_reg(NULL, M68K_REG_USP); save_param(&tmp32, 4); tmp32 = m68k_get_reg(NULL, M68K_REG_USP); save_param(&tmp32, 4);
@ -194,9 +179,6 @@ int state_save(unsigned char *buffer)
compress2 ((Bytef *)(buffer + 4), &outbytes, (Bytef *)state, inbytes, 9); compress2 ((Bytef *)(buffer + 4), &outbytes, (Bytef *)state, inbytes, 9);
memcpy(buffer, &outbytes, 4); memcpy(buffer, &outbytes, 4);
/* Free memory */
free(state);
/* return total size */ /* return total size */
return (outbytes + 4); return (outbytes + 4);
} }