~ 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
@ -8,7 +8,7 @@ Genesis Plus GX 1.3.2 (??/??/????) (Eke-Eke)
|
||||
* modified SN76489 cut-off frequency
|
||||
* 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
|
||||
* fixed FM context restore when loading savesates
|
||||
* fixed FM context in savestates
|
||||
* improved sprites masking emulation: fixes 3D level in Mickey Mania
|
||||
* fixed lightgun games detection: fixes cursor position in Lethal Enforcers II
|
||||
* various code cleanup & optimization
|
||||
@ -16,9 +16,10 @@ Genesis Plus GX 1.3.2 (??/??/????) (Eke-Eke)
|
||||
[Gamecube/Wii]
|
||||
|
||||
* 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)
|
||||
* new GUI design (incl. Wii Remote pointing, ROM snapshots & more)
|
||||
* new GUI layout (incl. IR pointing, ROM snapshots, sound effects & more)
|
||||
|
||||
|
||||
|
||||
|
@ -22,51 +22,45 @@
|
||||
***************************************************************************/
|
||||
#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 */
|
||||
sprintf (pathname, "%s/config.ini", pathname);
|
||||
FILE *fp = fopen(pathname, "wb");
|
||||
if (fp == NULL) return;
|
||||
|
||||
/* save options */
|
||||
fwrite(&config, sizeof(config), 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
char fname[MAXPATHLEN];
|
||||
sprintf (fname, "%s/config.ini", DEFAULT_PATH);
|
||||
FILE *fp = fopen(fname, "wb");
|
||||
if (fp)
|
||||
{
|
||||
/* write file */
|
||||
fwrite(&config, sizeof(config), 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void config_load()
|
||||
void config_load(void)
|
||||
{
|
||||
char pathname[MAXPATHLEN];
|
||||
|
||||
/* open configuration file */
|
||||
sprintf (pathname, "%s/config.ini", DEFAULT_PATH);
|
||||
FILE *fp = fopen(pathname, "rb");
|
||||
if (fp == NULL) return;
|
||||
char fname[MAXPATHLEN];
|
||||
sprintf (fname, "%s/config.ini", DEFAULT_PATH);
|
||||
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 */
|
||||
char version[16];
|
||||
fread(version, 16, 1, fp);
|
||||
fclose(fp);
|
||||
if (strcmp(version,VERSION)) return;
|
||||
|
||||
/* read file */
|
||||
fp = fopen(pathname, "rb");
|
||||
fread(&config, sizeof(config), 1, fp);
|
||||
fclose(fp);
|
||||
/* read file */
|
||||
fp = fopen(fname, "rb");
|
||||
if (fp)
|
||||
{
|
||||
fread(&config, sizeof(config), 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void config_setDefault(void)
|
||||
void config_default(void)
|
||||
{
|
||||
/* version TAG */
|
||||
strncpy(config.version,VERSION,16);
|
||||
@ -109,5 +103,8 @@ void config_setDefault(void)
|
||||
config.bg_color = 0;
|
||||
config.bgm_volume = 100.0;
|
||||
config.sfx_volume = 100.0;
|
||||
|
||||
/* restore saved configuration */
|
||||
config_load();
|
||||
}
|
||||
|
||||
|
@ -65,9 +65,9 @@ typedef struct
|
||||
t_config config;
|
||||
|
||||
|
||||
extern void config_save();
|
||||
extern void config_load();
|
||||
extern void config_setDefault(void);
|
||||
extern void config_save(void);
|
||||
extern void config_load(void);
|
||||
extern void config_default(void);
|
||||
|
||||
|
||||
#endif /* _CONFIG_H_ */
|
||||
|
@ -96,28 +96,19 @@ void memfile_autosave(s8 autosram, s8 autostate)
|
||||
*****************************************************************************/
|
||||
static int FAT_ManageFile(char *filename, int direction, int filetype)
|
||||
{
|
||||
char pathname[MAXPATHLEN];
|
||||
char fname[MAXPATHLEN];
|
||||
int done = 0;
|
||||
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 */
|
||||
sprintf (pathname, "%s/%s", pathname, filename);
|
||||
sprintf (fname, "%s/saves/%s", DEFAULT_PATH, filename);
|
||||
|
||||
/* open file */
|
||||
FILE *fp = fopen(pathname, direction ? "rb" : "wb");
|
||||
FILE *fp = fopen(fname, direction ? "rb" : "wb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
sprintf (filename, "Error opening %s", pathname);
|
||||
WaitPrompt(filename);
|
||||
sprintf (fname, "Error opening %s", filename);
|
||||
WaitPrompt(fname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -137,14 +128,14 @@ static int FAT_ManageFile(char *filename, int direction, int filetype)
|
||||
done = fwrite(savebuffer, 1, filesize, fp);
|
||||
if (done < filesize)
|
||||
{
|
||||
sprintf (filename, "Error writing %s", pathname);
|
||||
WaitPrompt(filename);
|
||||
sprintf (fname, "Error writing %s", filename);
|
||||
WaitPrompt(fname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
sprintf (filename, "Saved %d bytes successfully", done);
|
||||
WaitPrompt (filename);
|
||||
sprintf (fname, "Saved %d bytes successfully", done);
|
||||
WaitPrompt (fname);
|
||||
return 1;
|
||||
|
||||
case 1: /* LOADING */
|
||||
@ -158,8 +149,8 @@ static int FAT_ManageFile(char *filename, int direction, int filetype)
|
||||
done = fread(savebuffer, 1, filesize, fp);
|
||||
if (done < filesize)
|
||||
{
|
||||
sprintf (filename, "Error reading %s", pathname);
|
||||
WaitPrompt(filename);
|
||||
sprintf (fname, "Error reading %s", filename);
|
||||
WaitPrompt(fname);
|
||||
return 0;
|
||||
}
|
||||
fclose(fp);
|
||||
@ -172,8 +163,8 @@ static int FAT_ManageFile(char *filename, int direction, int filetype)
|
||||
}
|
||||
else state_load(savebuffer); /* STATE */
|
||||
|
||||
sprintf (filename, "Loaded %d bytes successfully", done);
|
||||
WaitPrompt (filename);
|
||||
sprintf (fname, "Loaded %d bytes successfully", done);
|
||||
WaitPrompt (fname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -26,28 +26,6 @@
|
||||
|
||||
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
|
||||
@ -95,28 +73,44 @@ void history_add_file(char *filepath, char *filename)
|
||||
history_save();
|
||||
}
|
||||
|
||||
void history_load()
|
||||
void history_save()
|
||||
{
|
||||
char pathname[MAXPATHLEN];
|
||||
|
||||
/* open file for reading */
|
||||
sprintf (pathname, "%s/history.ini", DEFAULT_PATH);
|
||||
FILE *fp = fopen(pathname, "rb");
|
||||
if (fp == NULL) return;
|
||||
|
||||
/* read file */
|
||||
fread(&history, sizeof(history), 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
/* open file */
|
||||
char fname[MAXPATHLEN];
|
||||
sprintf (fname, "%s/history.ini", DEFAULT_PATH);
|
||||
FILE *fp = fopen(fname, "wb");
|
||||
if (fp)
|
||||
{
|
||||
/* write file */
|
||||
fwrite(&history, sizeof(history), 1, 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;
|
||||
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
|
||||
{
|
||||
memset(&history.entries[i], 0, sizeof(t_history_entry));
|
||||
}
|
||||
|
||||
/* restore history */
|
||||
history_load();
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,8 @@ typedef struct
|
||||
|
||||
extern t_history history;
|
||||
extern void history_add_file(char *filepath, char *filename);
|
||||
extern void history_load();
|
||||
extern void history_setDefault();
|
||||
extern void history_save(void);
|
||||
extern void history_load(void);
|
||||
extern void history_default(void);
|
||||
|
||||
#endif
|
||||
|
@ -95,7 +95,7 @@ static gui_item action_select =
|
||||
/*****************************************************************************/
|
||||
/* 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_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_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,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}}
|
||||
};
|
||||
|
||||
@ -113,9 +114,9 @@ static gui_image bg_filesel[9] =
|
||||
/*****************************************************************************/
|
||||
static gui_menu menu_browser =
|
||||
{
|
||||
"ROM Selection",
|
||||
"Game Selection",
|
||||
-1,-1,
|
||||
0,0,9,
|
||||
0,0,10,
|
||||
NULL,
|
||||
NULL,
|
||||
bg_filesel,
|
||||
@ -165,6 +166,7 @@ int FileSelector(unsigned char *buffer)
|
||||
int ret,i,yoffset,string_offset;
|
||||
int go_up = 0;
|
||||
int quit =0;
|
||||
int old = -1;
|
||||
char text[MAXJOLIET+2];
|
||||
char fname[MAXPATHLEN];
|
||||
FILE *xml,*snap;
|
||||
@ -181,7 +183,7 @@ int FileSelector(unsigned char *buffer)
|
||||
|
||||
/* Initialize directory 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.h = dir_icon.texture->height;
|
||||
dir_icon.x = 26;
|
||||
@ -189,7 +191,7 @@ int FileSelector(unsigned char *buffer)
|
||||
|
||||
/* Initialize selection bar */
|
||||
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.h = bar_over.texture->height;
|
||||
bar_over.x = 22;
|
||||
@ -219,11 +221,23 @@ int FileSelector(unsigned char *buffer)
|
||||
}
|
||||
|
||||
/* ROM snapshot */
|
||||
sprintf (fname, "%s/snaps/%s.png", DEFAULT_PATH, text);
|
||||
snap = fopen(fname, "rb");
|
||||
if (snap)
|
||||
if (old != selection)
|
||||
{
|
||||
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*/
|
||||
@ -317,14 +331,14 @@ int FileSelector(unsigned char *buffer)
|
||||
|
||||
/* find selected button */
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ void WriteCentre( 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)
|
||||
{
|
||||
gxDrawTexture(texture, 0, y-fheight, 640, fheight,240);
|
||||
|
@ -61,7 +61,7 @@ void legal ()
|
||||
WriteCentre (ypos, "You are free to use it as you wish.");
|
||||
ypos += 2*fheight;
|
||||
|
||||
texture= gxTextureOpenPNG(Bg_intro_c4_png);
|
||||
texture= gxTextureOpenPNG(Bg_intro_c4_png,0);
|
||||
if (texture)
|
||||
{
|
||||
gxDrawTexture(texture, (640-texture->width)/2, ypos, texture->width, texture->height,255);
|
||||
@ -84,7 +84,7 @@ void legal ()
|
||||
}
|
||||
|
||||
gxClearScreen((GXColor)BLACK);
|
||||
texture = gxTextureOpenPNG(Bg_intro_c1_png);
|
||||
texture = gxTextureOpenPNG(Bg_intro_c1_png,0);
|
||||
if (texture)
|
||||
{
|
||||
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
|
||||
@ -96,7 +96,7 @@ void legal ()
|
||||
sleep (1);
|
||||
|
||||
gxClearScreen((GXColor)WHITE);
|
||||
texture = gxTextureOpenPNG(Bg_intro_c2_png);
|
||||
texture = gxTextureOpenPNG(Bg_intro_c2_png,0);
|
||||
if (texture)
|
||||
{
|
||||
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
|
||||
@ -108,7 +108,7 @@ void legal ()
|
||||
sleep (1);
|
||||
|
||||
gxClearScreen((GXColor)BLACK);
|
||||
texture = gxTextureOpenPNG(Bg_intro_c3_png);
|
||||
texture = gxTextureOpenPNG(Bg_intro_c3_png,0);
|
||||
if (texture)
|
||||
{
|
||||
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
|
||||
|
@ -39,16 +39,17 @@ t_input_menu m_input;
|
||||
gx_texture *w_pointer;
|
||||
#endif
|
||||
|
||||
#define BG_COLOR_MAX 14
|
||||
#define BG_COLOR_MAX 15
|
||||
|
||||
/* various background colors */
|
||||
static GXColor bg_colors[BG_COLOR_MAX]=
|
||||
{
|
||||
{0xd6,0xcb,0xba,0xff}, /* light gold */
|
||||
{0xbb,0xb0,0x99,0xff}, /* gold */
|
||||
{0xbb,0xb0,0x99,0xff}, /* gold */
|
||||
{0x66,0x66,0x66,0xff}, /* faded grey */
|
||||
{0xcc,0xcc,0xcc,0xff}, /* light grey */
|
||||
{0xd4,0xd0,0xc8,0xff}, /* cream */
|
||||
{0x50,0x51,0x5b,0xff}, /* grey blue */
|
||||
{0xb8,0xc7,0xda,0xff}, /* light blue */
|
||||
{0xc0,0xcf,0xe7,0xff}, /* sky blue */
|
||||
{0x98,0xb1,0xd8,0xff}, /* sea blue */
|
||||
@ -144,7 +145,7 @@ static gui_image bg_list[6] =
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Main menu */
|
||||
static gui_item items_main[8] =
|
||||
static gui_item items_main[9] =
|
||||
{
|
||||
{NULL,Main_quit_png ,"","",128, 84,52,80},
|
||||
{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_ggenie_png ,"","",450,224,72,84},
|
||||
#ifdef HW_RVL
|
||||
{NULL,Main_play_wii_png,"","", 10,368,84,32},
|
||||
{NULL,Main_play_wii_png,"","", 10,372,84,32},
|
||||
#else
|
||||
{NULL,Main_play_gcn_png,"","", 10,368,84,32},
|
||||
{NULL,Main_play_gcn_png,"","", 10,372,84,32},
|
||||
#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
|
||||
@ -246,7 +248,7 @@ static gui_butn buttons_list[4] =
|
||||
};
|
||||
|
||||
/* 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},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|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|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,
|
||||
8,8,4,
|
||||
9,9,4,
|
||||
items_main,
|
||||
buttons_main,
|
||||
bg_main,
|
||||
@ -408,7 +411,7 @@ void GUI_InitMenu(gui_menu *menu)
|
||||
for (i=0; i<menu->max_images; i++)
|
||||
{
|
||||
image = &menu->bg_images[i];
|
||||
image->texture = gxTextureOpenPNG(image->data);
|
||||
image->texture = gxTextureOpenPNG(image->data,0);
|
||||
}
|
||||
|
||||
for (i=0; i<2; i++)
|
||||
@ -417,15 +420,15 @@ void GUI_InitMenu(gui_menu *menu)
|
||||
item = menu->helpers[i];
|
||||
if (item)
|
||||
{
|
||||
item->texture = gxTextureOpenPNG(item->data);
|
||||
item->texture = gxTextureOpenPNG(item->data,0);
|
||||
}
|
||||
|
||||
/* 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]);
|
||||
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],0);
|
||||
|
||||
/* initial state */
|
||||
button->state &= ~BUTTON_VISIBLE;
|
||||
@ -443,8 +446,8 @@ void GUI_InitMenu(gui_menu *menu)
|
||||
button = &menu->buttons[i];
|
||||
if (button->data)
|
||||
{
|
||||
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]);
|
||||
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],0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -452,7 +455,7 @@ void GUI_InitMenu(gui_menu *menu)
|
||||
for (i=0; i<menu->max_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 */
|
||||
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;
|
||||
if (!data->texture[i])
|
||||
{
|
||||
data->texture[i] = gxTextureOpenPNG(data->image[i]);
|
||||
data->texture[i] = gxTextureOpenPNG(data->image[i],0);
|
||||
delete_me[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize texture window */
|
||||
gx_texture *window = gxTextureOpenPNG(Frame_s1_png);
|
||||
gx_texture *top = gxTextureOpenPNG(Frame_title_png);
|
||||
gx_texture *window = gxTextureOpenPNG(Frame_s1_png,0);
|
||||
gx_texture *top = gxTextureOpenPNG(Frame_s1_title_png,0);
|
||||
|
||||
/* get initial positions */
|
||||
int w = data->texture[0]->width;
|
||||
@ -1191,6 +1209,12 @@ int GUI_RunMenu(gui_menu *menu)
|
||||
/* basic slide effect for option menus */
|
||||
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];
|
||||
strcpy(title,m->title);
|
||||
|
||||
@ -1199,6 +1223,53 @@ static void GUI_SlideMenuTitle(gui_menu *m, int title_offset)
|
||||
strcpy(m->title,title+title_offset);
|
||||
m->title[strlen(title)-title_offset-1] = 0;
|
||||
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 ();
|
||||
usleep(6000);
|
||||
title_offset--;
|
||||
@ -1230,28 +1301,28 @@ static void drawmenu (char items[][25], int maxitems, int selected)
|
||||
|
||||
/* draw background items */
|
||||
gxClearScreen (bg_colors[config.bg_color]);
|
||||
texture= gxTextureOpenPNG(Bg_main_png);
|
||||
texture= gxTextureOpenPNG(Bg_main_png,0);
|
||||
if (texture)
|
||||
{
|
||||
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
|
||||
if (texture->data) free(texture->data);
|
||||
free(texture);
|
||||
}
|
||||
texture= gxTextureOpenPNG(Banner_bottom_png);
|
||||
texture= gxTextureOpenPNG(Banner_bottom_png,0);
|
||||
if (texture)
|
||||
{
|
||||
gxDrawTexture(texture, 0, 480-texture->height, texture->width, texture->height, 255);
|
||||
if (texture->data) free(texture->data);
|
||||
free(texture);
|
||||
}
|
||||
texture= gxTextureOpenPNG(Banner_top_png);
|
||||
texture= gxTextureOpenPNG(Banner_top_png,0);
|
||||
if (texture)
|
||||
{
|
||||
gxDrawTexture(texture, 0, 0, texture->width, texture->height, 255);
|
||||
if (texture->data) free(texture->data);
|
||||
free(texture);
|
||||
}
|
||||
texture= gxTextureOpenPNG(Main_logo_png);
|
||||
texture= gxTextureOpenPNG(Main_logo_png,0);
|
||||
if (texture)
|
||||
{
|
||||
gxDrawTexture(texture, 444, 28, 176, 48, 255);
|
||||
@ -1338,24 +1409,24 @@ static void prefmenu ()
|
||||
gui_menu *m = &menu_prefs;
|
||||
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_SlideMenuTitle(m,strlen("Menu "));
|
||||
|
||||
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);
|
||||
|
||||
switch (ret)
|
||||
@ -1363,11 +1434,19 @@ static void prefmenu ()
|
||||
case 0: /*** SRAM auto load/save ***/
|
||||
config.sram_auto ++;
|
||||
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;
|
||||
|
||||
case 1: /*** Savestate auto load/save ***/
|
||||
config.state_auto ++;
|
||||
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;
|
||||
|
||||
case 2: /*** Sound effects volume ***/
|
||||
@ -1376,6 +1455,7 @@ static void prefmenu ()
|
||||
else config.sfx_volume +=10;
|
||||
if (config.sfx_volume < 0) config.sfx_volume = 100.0;
|
||||
else if (config.sfx_volume > 100) config.sfx_volume = 0.0;
|
||||
sprintf (items[2].text, "SFX Volume: %1.1f", config.sfx_volume);
|
||||
break;
|
||||
|
||||
case 3: /*** Background music volume ***/
|
||||
@ -1385,6 +1465,7 @@ static void prefmenu ()
|
||||
if (config.bgm_volume < 0) config.bgm_volume = 100.0;
|
||||
else if (config.bgm_volume > 100) config.bgm_volume = 0.0;
|
||||
SetVolumeOgg(((int)config.bgm_volume * 255) / 100);
|
||||
sprintf (items[3].text, "BGM Volume: %1.1f", config.bgm_volume);
|
||||
break;
|
||||
|
||||
case 4: /*** Background color ***/
|
||||
@ -1393,6 +1474,8 @@ static void prefmenu ()
|
||||
else config.bg_color ++;
|
||||
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) sprintf (items[4].text, "BG Color: Type %d", config.bg_color);
|
||||
else sprintf (items[4].text, "BG Color: DEFAULT");
|
||||
break;
|
||||
|
||||
case -1:
|
||||
@ -1414,18 +1497,19 @@ static void soundmenu ()
|
||||
gui_menu *m = &menu_audio;
|
||||
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_SlideMenuTitle(m,strlen("Sound "));
|
||||
|
||||
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);
|
||||
|
||||
@ -1437,6 +1521,7 @@ static void soundmenu ()
|
||||
else config.psg_preamp ++;
|
||||
if (config.psg_preamp < 0) config.psg_preamp = 500;
|
||||
if (config.psg_preamp > 500) config.psg_preamp = 0;
|
||||
sprintf (items[0].text, "PSG Volume: %1.2f", (double)config.psg_preamp/100.0);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
@ -1445,23 +1530,29 @@ static void soundmenu ()
|
||||
else config.fm_preamp ++;
|
||||
if (config.fm_preamp < 0) config.fm_preamp = 500;
|
||||
if (config.fm_preamp > 500) config.fm_preamp = 0;
|
||||
sprintf (items[1].text, "FM Volume: %1.2f", (double)config.fm_preamp/100.0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
config.boost ++;
|
||||
if (config.boost > 4) config.boost = 0;
|
||||
sprintf (items[2].text, "Volume Boost: %dX", config.boost);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
config.filter ^= 1;
|
||||
sprintf (items[3].text, "LowPass Filter: %s", config.filter ? " ON":"OFF");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
config.hq_fm ++;
|
||||
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)
|
||||
{
|
||||
unsigned char *temp = malloc(YM2612GetContextSize());
|
||||
unsigned char *temp = memalign(32,YM2612GetContextSize());
|
||||
if (temp) memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
|
||||
audio_init(48000);
|
||||
if (temp)
|
||||
@ -1492,25 +1583,29 @@ static void systemmenu ()
|
||||
gui_menu *m = &menu_system;
|
||||
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_SlideMenuTitle(m,strlen("System "));
|
||||
|
||||
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);
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case 0: /*** Region Force ***/
|
||||
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)
|
||||
{
|
||||
/* force region & cpu mode */
|
||||
@ -1518,11 +1613,14 @@ static void systemmenu ()
|
||||
|
||||
/* reinitialize timings */
|
||||
system_init ();
|
||||
unsigned char *temp = malloc(YM2612GetContextSize());
|
||||
unsigned char *temp = memalign(32,YM2612GetContextSize());
|
||||
if (temp) memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
|
||||
audio_init(48000);
|
||||
YM2612Restore(temp);
|
||||
if (temp) free(temp);
|
||||
if (temp)
|
||||
{
|
||||
YM2612Restore(temp);
|
||||
free(temp);
|
||||
}
|
||||
|
||||
/* reinitialize HVC tables */
|
||||
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 ***/
|
||||
config.force_dtack ^= 1;
|
||||
sprintf (items[1].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
|
||||
break;
|
||||
|
||||
case 2: /*** BIOS support ***/
|
||||
config.bios_enabled ^= 1;
|
||||
sprintf (items[2].text, "System BIOS: %s", (config.bios_enabled & 1) ? "ON":"OFF");
|
||||
if (genromsize || (config.bios_enabled == 3))
|
||||
{
|
||||
system_init ();
|
||||
@ -1553,6 +1653,7 @@ static void systemmenu ()
|
||||
if (ret<0) SVP_cycles = SVP_cycles ? (SVP_cycles-1) : 1500;
|
||||
else SVP_cycles++;
|
||||
if (SVP_cycles > 1500) SVP_cycles = 0;
|
||||
sprintf (items[3].text, "SVP Cycles: %d", SVP_cycles);
|
||||
break;
|
||||
|
||||
case -1:
|
||||
@ -1574,24 +1675,25 @@ static void videomenu ()
|
||||
gui_menu *m = &menu_video;
|
||||
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_SlideMenuTitle(m,strlen("Video "));
|
||||
|
||||
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);
|
||||
|
||||
@ -1599,6 +1701,7 @@ static void videomenu ()
|
||||
{
|
||||
case 0: /*** config.aspect ratio ***/
|
||||
config.aspect ^= 1;
|
||||
sprintf (items[0].text, "Aspect: %s", config.aspect ? "ORIGINAL" : "STRETCHED");
|
||||
break;
|
||||
|
||||
case 1: /*** rendering ***/
|
||||
@ -1616,25 +1719,38 @@ static void videomenu ()
|
||||
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;
|
||||
|
||||
case 2: /*** tv mode ***/
|
||||
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;
|
||||
|
||||
case 3: /*** bilinear filtering ***/
|
||||
config.bilinear ^= 1;
|
||||
sprintf (items[3].text, "Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
|
||||
break;
|
||||
|
||||
case 4: /*** NTSC filter ***/
|
||||
config.ntsc ++;
|
||||
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;
|
||||
|
||||
case 5: /*** overscan emulation ***/
|
||||
config.overscan ^= 1;
|
||||
bitmap.viewport.x = config.overscan ? ((reg[12] & 1) ? 16 : 12) : 0;
|
||||
bitmap.viewport.y = config.overscan ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0;
|
||||
sprintf (items[5].text, "Borders: %s", config.overscan ? " ON" : "OFF");
|
||||
break;
|
||||
|
||||
/* case 6:
|
||||
@ -1689,6 +1805,28 @@ static void inputsmenu(void)
|
||||
u32 exp;
|
||||
#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");
|
||||
|
||||
menu = 0;
|
||||
@ -2323,7 +2461,7 @@ void MainMenu (void)
|
||||
}
|
||||
|
||||
/* wiimote pointer */
|
||||
w_pointer = gxTextureOpenPNG(generic_point_png);
|
||||
w_pointer = gxTextureOpenPNG(generic_point_png,0);
|
||||
#endif
|
||||
|
||||
gui_menu *m = &menu_main;
|
||||
@ -2332,8 +2470,8 @@ void MainMenu (void)
|
||||
if (genromsize)
|
||||
{
|
||||
m->screenshot = 1;
|
||||
m->max_items = 8;
|
||||
m->max_buttons = 8;
|
||||
m->max_items = 9;
|
||||
m->max_buttons = 9;
|
||||
m->buttons[3].state |= BUTTON_SELECT_SFX;
|
||||
m->buttons[5].state |= BUTTON_SELECT_SFX;
|
||||
m->buttons[3].shift[1] = 3;
|
||||
@ -2378,6 +2516,7 @@ void MainMenu (void)
|
||||
switch (GUI_WindowPrompt(m, VERSION, items,3))
|
||||
{
|
||||
case 1:
|
||||
GUI_FadeMenu(m,1,1);
|
||||
#ifdef HW_RVL
|
||||
gxTextureClose(&w_pointer);
|
||||
#endif
|
||||
@ -2387,6 +2526,7 @@ void MainMenu (void)
|
||||
break;
|
||||
|
||||
case 2:
|
||||
GUI_FadeMenu(m,1,1);
|
||||
#ifdef HW_RVL
|
||||
gxTextureClose(&w_pointer);
|
||||
#endif
|
||||
@ -2400,9 +2540,9 @@ void MainMenu (void)
|
||||
break;
|
||||
|
||||
default: /* TODO */
|
||||
GUI_DeleteMenu(m);
|
||||
break;
|
||||
}
|
||||
GUI_DeleteMenu(m);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2431,8 +2571,12 @@ void MainMenu (void)
|
||||
GetGGEntries();
|
||||
break;
|
||||
|
||||
case 7: /*** ROM Information ***/
|
||||
showrominfo ();
|
||||
case 7: /*** ROM Captrure ***/
|
||||
if (genromsize) gx_video_Capture();
|
||||
break;
|
||||
|
||||
case 8: /*** ROM Information ***/
|
||||
if (genromsize) showrominfo ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,9 @@ extern const u8 Banner_top_png[];
|
||||
|
||||
extern const u8 Frame_s1_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[];
|
||||
|
||||
@ -83,6 +85,7 @@ extern const u8 Main_file_png[];
|
||||
extern const u8 Main_reset_png[];
|
||||
extern const u8 Main_ggenie_png[];
|
||||
extern const u8 Main_showinfo_png[];
|
||||
extern const u8 Main_takeshot_png[];
|
||||
#ifdef HW_RVL
|
||||
extern const u8 Main_play_wii_png[];
|
||||
#else
|
||||
@ -221,6 +224,7 @@ extern void GUI_InitMenu(gui_menu *menu);
|
||||
extern void GUI_DeleteMenu(gui_menu *menu);
|
||||
extern void GUI_DrawMenu(gui_menu *menu);
|
||||
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_WindowPrompt(gui_menu *parent, char *title, char *items[], u8 nb_items);
|
||||
#endif
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* 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
|
||||
* 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 u32 Bg_music_ogg_size = 0;
|
||||
|
||||
/***
|
||||
AudioDmaCallback
|
||||
/***************************************************************************************/
|
||||
/* Audio engine */
|
||||
/***************************************************************************************/
|
||||
|
||||
In 50Hz emulation mode, we synchronize frame emulation with audio DMA
|
||||
50Hz VSYNC period is shorter than DMA period so there is no video frameskipping
|
||||
In 60Hz modes, VSYNC period is longer than default DMA period so it requires different sync.
|
||||
***/
|
||||
|
||||
static void AudioDmaCallback(void)
|
||||
/* Audio DMA callback */
|
||||
static void ai_callback(void)
|
||||
{
|
||||
frameticker++;
|
||||
}
|
||||
|
||||
/***
|
||||
gx_audio__init
|
||||
|
||||
This function initializes the Audio Interface
|
||||
Default samplerate is set to 48khZ
|
||||
***/
|
||||
void gx_audio_Init(void)
|
||||
{
|
||||
AUDIO_Init (NULL);
|
||||
@ -171,7 +162,7 @@ void gx_audio_Start(void)
|
||||
AUDIO_RegisterDMACallback(NULL);
|
||||
|
||||
/* 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 */
|
||||
/* VSYNC period is 16715 us which is approx. 802.32 samples */
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -42,7 +42,7 @@ typedef struct
|
||||
{
|
||||
u8 *buffer;
|
||||
u32 offset;
|
||||
} png_file;
|
||||
} png_image;
|
||||
|
||||
extern const u8 Crosshair_p1_png[];
|
||||
extern const u8 Crosshair_p2_png[];
|
||||
@ -52,6 +52,7 @@ unsigned int *xfb[2]; /* External Framebuffers */
|
||||
int whichfb = 0; /* Current Framebuffer */
|
||||
GXRModeObj *vmode; /* Default Video Mode */
|
||||
u8 *texturemem; /* Texture Data */
|
||||
u8 *screenshot; /* Texture Data */
|
||||
|
||||
/* 50/60hz flag */
|
||||
u8 gc_pal = 0;
|
||||
@ -65,13 +66,15 @@ static md_ntsc_setup_t md_setup;
|
||||
/*** GX FIFO ***/
|
||||
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
|
||||
|
||||
/*** custom Video modes ***/
|
||||
static GXRModeObj *rmode;
|
||||
|
||||
/*** GX Textures ***/
|
||||
static u32 vwidth,vheight;
|
||||
static gx_texture *crosshair[2];
|
||||
|
||||
/***************************************************************************************/
|
||||
/* Emulation video modes */
|
||||
/***************************************************************************************/
|
||||
static GXRModeObj *rmode;
|
||||
|
||||
/* 288 lines progressive (PAL 50Hz) */
|
||||
static GXRModeObj TV50hz_288p =
|
||||
{
|
||||
@ -296,6 +299,11 @@ static GXRModeObj *tvmodes[6] =
|
||||
&TV50hz_576i
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************************/
|
||||
/* GX rendering engine */
|
||||
/***************************************************************************************/
|
||||
|
||||
typedef struct tagcamera
|
||||
{
|
||||
Vector pos;
|
||||
@ -325,11 +333,6 @@ static camera cam = {
|
||||
{0.0F, 0.0F, 0.0F}
|
||||
};
|
||||
|
||||
static void updateFrameCount(u32 cnt)
|
||||
{
|
||||
frameticker++;
|
||||
}
|
||||
|
||||
/* Vertex Rendering */
|
||||
static inline void draw_vert(u8 pos, f32 s, f32 t)
|
||||
{
|
||||
@ -348,7 +351,7 @@ static inline void draw_square(void)
|
||||
GX_End ();
|
||||
}
|
||||
|
||||
/* Initialize GX renderer */
|
||||
/* Initialize GX */
|
||||
static void gxStart(void)
|
||||
{
|
||||
/*** 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 */
|
||||
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 */
|
||||
memcpy (data, file->buffer + file->offset, length);
|
||||
memcpy (data, image->buffer + image->offset, length);
|
||||
|
||||
/* advance in the file */
|
||||
file->offset += length;
|
||||
image->offset += length;
|
||||
}
|
||||
|
||||
/* convert a png file into RGBA8 texture */
|
||||
gx_texture *gxTextureOpenPNG(const u8 *buffer)
|
||||
/* convert PNG image (from file or data buffer) into RGBA8 texture */
|
||||
gx_texture *gxTextureOpenPNG(const u8 *png_data, FILE *png_file)
|
||||
{
|
||||
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 */
|
||||
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;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
png_destroy_read_struct (&png_ptr, NULL, NULL);
|
||||
png_destroy_read_struct(&png_ptr,NULL,NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set callback for the read function */
|
||||
png_set_read_fn (png_ptr, (png_voidp *)(&file), png_read_from_mem);
|
||||
if (png_data)
|
||||
{
|
||||
/* 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 */
|
||||
png_read_info (png_ptr, info_ptr);
|
||||
png_read_info(png_ptr,info_ptr);
|
||||
|
||||
/* retrieve image information */
|
||||
u32 width = png_get_image_width(png_ptr, info_ptr);
|
||||
u32 height = png_get_image_height(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 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 images are in the supported format */
|
||||
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))
|
||||
/* ensure PNG file is in the supported format */
|
||||
if (png_file)
|
||||
{
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
return;
|
||||
}
|
||||
/* 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);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 4x4 tiles are required */
|
||||
if ((width%4) || (height%4))
|
||||
{
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
return;
|
||||
/* 4x4 tiles are required */
|
||||
if ((width%4) || (height%4))
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* allocate memory to store raw image data */
|
||||
u32 stride = width << 2;
|
||||
u8 *img_data = memalign (32, stride * height);
|
||||
if (!img_data)
|
||||
{
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -670,7 +938,7 @@ gx_texture *gxTextureOpenPNG(const u8 *buffer)
|
||||
if (!row_pointers)
|
||||
{
|
||||
free (img_data);
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -681,11 +949,11 @@ gx_texture *gxTextureOpenPNG(const u8 *buffer)
|
||||
}
|
||||
|
||||
/* decode image */
|
||||
png_read_image (png_ptr, row_pointers);
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
|
||||
/* finish decompression and release memory */
|
||||
png_read_end (png_ptr, NULL);
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
png_read_end(png_ptr, NULL);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
free(row_pointers);
|
||||
|
||||
/* initialize texture */
|
||||
@ -776,6 +1044,127 @@ gx_texture *gxTextureOpenPNG(const u8 *buffer)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
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();
|
||||
/* encode screenshot into PNG file */
|
||||
gxTextureWritePNG(&texture,f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
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 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 */
|
||||
/* Emulation mode -> Menu mode */
|
||||
void gx_video_Stop(void)
|
||||
{
|
||||
/* lightgun textures */
|
||||
if (crosshair[0])
|
||||
{
|
||||
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;
|
||||
}
|
||||
gxTextureClose(&crosshair[0]);
|
||||
gxTextureClose(&crosshair[1]);
|
||||
|
||||
/* reset GX */
|
||||
gxResetRendering(1);
|
||||
@ -972,16 +1226,17 @@ void gx_video_Stop(void)
|
||||
gxSetScreen ();
|
||||
}
|
||||
|
||||
/* Update Video settings */
|
||||
/* Menu mode -> Emulation mode */
|
||||
void gx_video_Start(void)
|
||||
{
|
||||
/* 50Hz/60Hz mode */
|
||||
if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1;
|
||||
else gc_pal = 0;
|
||||
|
||||
/* Video Interrupt synchronization */
|
||||
/* VIDEO sync */
|
||||
VIDEO_SetPostRetraceCallback(NULL);
|
||||
if (!gc_pal && !vdp_pal) VIDEO_SetPreRetraceCallback(updateFrameCount);
|
||||
if (!gc_pal && !vdp_pal)
|
||||
VIDEO_SetPreRetraceCallback(vi_callback);
|
||||
VIDEO_Flush();
|
||||
|
||||
/* interlaced/progressive mode */
|
||||
@ -996,6 +1251,19 @@ void gx_video_Start(void)
|
||||
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 */
|
||||
if (config.ntsc == 1)
|
||||
{
|
||||
@ -1024,8 +1292,8 @@ void gx_video_Start(void)
|
||||
{
|
||||
if (config.gun_cursor)
|
||||
{
|
||||
if (input.dev[4] == DEVICE_LIGHTGUN) crosshair[0] = gxTextureOpenPNG(Crosshair_p1_png);
|
||||
if (input.dev[5] == DEVICE_LIGHTGUN) crosshair[1] = gxTextureOpenPNG(Crosshair_p2_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,0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1034,10 +1302,8 @@ void gx_video_Start(void)
|
||||
|
||||
/* reset GX rendering */
|
||||
gxResetRendering(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* GX render update */
|
||||
void gx_video_Update(void)
|
||||
{
|
||||
@ -1244,24 +1510,16 @@ void gx_video_Init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize texture data */
|
||||
/* Initialize textures */
|
||||
texturemem = memalign(32, TEX_SIZE);
|
||||
if (!texturemem)
|
||||
{
|
||||
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);
|
||||
screenshot = memalign(32, HASPECT*VASPECT*4);
|
||||
if (!texturemem || !screenshot) gx_video_Shutdown();
|
||||
}
|
||||
|
||||
void gx_video_Shutdown(void)
|
||||
{
|
||||
if (texturemem) free(texturemem);
|
||||
if (screenshot) free(screenshot);
|
||||
FONT_Shutdown();
|
||||
VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK);
|
||||
VIDEO_Flush();
|
||||
|
@ -45,21 +45,28 @@ extern GXRModeObj *vmode;
|
||||
extern u8 *texturemem;
|
||||
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_Shutdown(void);
|
||||
extern void gx_video_Start(void);
|
||||
extern void gx_video_Stop(void);
|
||||
extern void gx_video_Update(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 ();
|
||||
extern void gx_video_Capture(void);
|
||||
|
||||
#endif
|
||||
|
Before Width: | Height: | Size: 341 KiB After Width: | Height: | Size: 341 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 6.2 KiB |
BIN
source/gx/images/Button_left.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
source/gx/images/Button_left_over.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
source/gx/images/Button_right.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
source/gx/images/Button_right_over.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 5.4 KiB |
BIN
source/gx/images/Ctrl_config.png
Normal file
After Width: | Height: | Size: 635 B |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 3.8 KiB |
BIN
source/gx/images/Ctrl_none.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
source/gx/images/Ctrl_pad3b.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
source/gx/images/Ctrl_pad6b.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
source/gx/images/Ctrl_player.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
source/gx/images/Ctrl_player_none.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
source/gx/images/Ctrl_player_over.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 249 B |
Before Width: | Height: | Size: 269 B |
Before Width: | Height: | Size: 298 B |
Before Width: | Height: | Size: 280 B |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 6.8 KiB |
BIN
source/gx/images/Frame_s1_title.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
source/gx/images/Frame_s3.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
source/gx/images/Frame_s4.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 698 B |
@ -1,9 +1,9 @@
|
||||
/****************************************************************************
|
||||
* 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
|
||||
* 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[])
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
/* initialize DVD Mode */
|
||||
/* initialize DVDX */
|
||||
DI_Close();
|
||||
DI_Init();
|
||||
#endif
|
||||
@ -168,7 +168,6 @@ int main (int argc, char *argv[])
|
||||
/* initialize hardware */
|
||||
gx_video_Init();
|
||||
gx_input_Init();
|
||||
gx_audio_Init();
|
||||
#ifdef HW_DOL
|
||||
DVD_Init ();
|
||||
dvd_drive_detect();
|
||||
@ -177,7 +176,6 @@ int main (int argc, char *argv[])
|
||||
/* initialize FAT devices */
|
||||
if (fatInitDefault())
|
||||
{
|
||||
fat_enabled = 1;
|
||||
#ifdef HW_RVL
|
||||
fatEnableReadAhead ("sd", 6, 64);
|
||||
fatEnableReadAhead ("usb", 6, 64);
|
||||
@ -185,22 +183,44 @@ int main (int argc, char *argv[])
|
||||
fatEnableReadAhead ("carda", 6, 64);
|
||||
fatEnableReadAhead ("cardb", 6, 64);
|
||||
#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();
|
||||
|
||||
/* default config */
|
||||
/* initialize core engine */
|
||||
legal();
|
||||
config_setDefault();
|
||||
config_load();
|
||||
|
||||
/* recent ROM files list */
|
||||
history_setDefault();
|
||||
history_load();
|
||||
|
||||
/* initialize Virtual Machine */
|
||||
init_machine ();
|
||||
config_default();
|
||||
history_default();
|
||||
init_machine();
|
||||
|
||||
/* run any injected rom */
|
||||
if (genromsize)
|
||||
@ -213,7 +233,7 @@ int main (int argc, char *argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
/* show menu first */
|
||||
/* Main Menu */
|
||||
ConfigRequested = 1;
|
||||
}
|
||||
|
||||
@ -225,14 +245,14 @@ int main (int argc, char *argv[])
|
||||
/* main emulation loop */
|
||||
while (1)
|
||||
{
|
||||
/* check for menu request */
|
||||
/* Main Menu request */
|
||||
if (ConfigRequested)
|
||||
{
|
||||
/* stop audio & video */
|
||||
gx_video_Stop();
|
||||
gx_audio_Stop();
|
||||
|
||||
/* go to menu */
|
||||
/* show menu */
|
||||
MainMenu ();
|
||||
ConfigRequested = 0;
|
||||
|
||||
|
@ -23,9 +23,9 @@
|
||||
|
||||
#define DEFAULT_PATH "/genplus"
|
||||
#ifdef HW_RVL
|
||||
#define VERSION "v1.3.2 (WII)"
|
||||
#define VERSION "version 1.3.2W"
|
||||
#else
|
||||
#define VERSION "v1.3.2 (GCN)"
|
||||
#define VERSION "version 1.3.2G"
|
||||
#endif
|
||||
|
||||
/* globals */
|
||||
@ -42,7 +42,6 @@ extern int ManageState(u8 direction, u8 device);
|
||||
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];
|
||||
|
||||
|
@ -387,11 +387,11 @@ static uint16 pixel_16[0x100];
|
||||
static uint16 pixel_16_lut[3][0x200];
|
||||
|
||||
/* Line buffers */
|
||||
static uint8 tmp_buf[0x400]; /* Temporary buffer */
|
||||
static uint8 bg_buf[0x400]; /* Merged background buffer */
|
||||
static uint8 nta_buf[0x400]; /* Plane A / Window line buffer */
|
||||
static uint8 ntb_buf[0x400]; /* Plane B line buffer */
|
||||
static uint8 obj_buf[0x400]; /* Object layer line buffer */
|
||||
static uint8 tmp_buf[0x200]; /* Temporary buffer */
|
||||
static uint8 bg_buf[0x200]; /* Merged background buffer */
|
||||
static uint8 nta_buf[0x200]; /* Plane A / Window line buffer */
|
||||
static uint8 ntb_buf[0x200]; /* Plane B line buffer */
|
||||
static uint8 obj_buf[0x200]; /* Object layer line buffer */
|
||||
|
||||
/* Sprite line buffer data */
|
||||
static uint32 object_index_count;
|
||||
|
@ -2156,4 +2156,12 @@ void YM2612Restore(unsigned char *buffer)
|
||||
ym2612.OPN.ST.clock = clock;
|
||||
ym2612.OPN.ST.rate = rate;
|
||||
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);
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
static unsigned char state[STATE_SIZE];
|
||||
|
||||
#define load_param(param, size) \
|
||||
memcpy(param, &state[bufferptr], size); \
|
||||
bufferptr+= size;
|
||||
@ -32,10 +34,6 @@
|
||||
|
||||
void state_load(unsigned char *buffer)
|
||||
{
|
||||
/* allocate memory */
|
||||
unsigned char *state = malloc(STATE_SIZE);
|
||||
if (state == NULL) return;
|
||||
|
||||
/* buffer size */
|
||||
int bufferptr = 0;
|
||||
|
||||
@ -79,14 +77,8 @@ void state_load(unsigned char *buffer)
|
||||
vdp_restore(temp_reg);
|
||||
|
||||
// FM
|
||||
unsigned char *temp = malloc (YM2612GetContextSize());
|
||||
if (temp)
|
||||
{
|
||||
load_param(temp,YM2612GetContextSize());
|
||||
YM2612Restore(temp);
|
||||
free(temp);
|
||||
}
|
||||
else bufferptr+=YM2612GetContextSize();
|
||||
YM2612Restore(&state[bufferptr]);
|
||||
bufferptr+= YM2612GetContextSize();
|
||||
|
||||
// PSG
|
||||
load_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
|
||||
@ -116,17 +108,10 @@ void state_load(unsigned char *buffer)
|
||||
|
||||
// Z80
|
||||
load_param(&Z80, sizeof(Z80_Regs));
|
||||
|
||||
/* Free memory */
|
||||
free(state);
|
||||
}
|
||||
|
||||
int state_save(unsigned char *buffer)
|
||||
{
|
||||
/* allocate memory */
|
||||
unsigned char *state = malloc(STATE_SIZE);
|
||||
if (state == NULL) return 0;
|
||||
|
||||
/* buffer size */
|
||||
int bufferptr = 0;
|
||||
|
||||
@ -166,21 +151,21 @@ int state_save(unsigned char *buffer)
|
||||
uint16 tmp16;
|
||||
uint32 tmp32;
|
||||
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_D2); 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_D5); 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_A0); 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_A3); 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_A6); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A7); 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_D3); 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_D6); 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_A1); 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_A4); 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_A7); 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);
|
||||
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);
|
||||
memcpy(buffer, &outbytes, 4);
|
||||
|
||||
/* Free memory */
|
||||
free(state);
|
||||
|
||||
/* return total size */
|
||||
return (outbytes + 4);
|
||||
}
|
||||
|