mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-27 03:31:49 +01:00
.fixed I/O access issues with devkitpro r18
.updated OGG support (compatibility with last libtremor + threading fixes from Tantric) .improved controller auto-detection .added experimental support for cartridge hot swapping, check System Options Menu .improved reset (soft/hard) emulation accuracy BEFORE COMPILING, REMOVE THE FOLLOWING FILES: *from ($DEVKITPRO)/libogc/lib/cube & /wii ----------------------------------------- libpng.a libtremor.a *from ($DEVKITPRO)/libogc/include --------------------------------- /tremor png.h pngconf.h DOWNLOAD & INSTALL THE FOLLOWING PORTLIBS in ($DEVKITPRO)/portlibs/ppc (PPC versions, from http://sourceforge.net/projects/devkitpro/files/) *libpng *libtremor
This commit is contained in:
parent
d129e7da94
commit
fe055c2a2c
@ -34,13 +34,13 @@ LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -lpng -lfat -ltremor -lasnd -logc -lm -lz
|
||||
LIBS := -lpng -lfat -lvorbisidec -lasnd -logc -lm -lz
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS :=
|
||||
LIBDIRS := $(PORTLIBS)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
@ -88,7 +88,7 @@ export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD) \
|
||||
-I$(LIBOGC_INC)
|
||||
-I$(LIBOGC_INC) -I$(PORTLIBS)/include
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# build a list of library paths
|
||||
|
@ -34,13 +34,13 @@ LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -lpng -ldi -lfat -ltremor -lasnd -lwiiuse -lbte -logc -lm -lz
|
||||
LIBS := -lpng -ldi -lfat -lvorbisidec -lasnd -lwiiuse -lbte -logc -lm -lz
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS :=
|
||||
LIBDIRS := $(PORTLIBS)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
@ -88,7 +88,7 @@ export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD) \
|
||||
-I$(LIBOGC_INC)
|
||||
-I$(LIBOGC_INC) -I$(PORTLIBS)/include
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# build a list of library paths
|
||||
|
@ -39,6 +39,9 @@ static struct port_t
|
||||
*****************************************************************************/
|
||||
void io_init(void)
|
||||
{
|
||||
/* set region according to ROM header */
|
||||
set_region();
|
||||
|
||||
/* restore previous setting */
|
||||
if (old_system[0] != -1) input.system[0] = old_system[0];
|
||||
if (old_system[1] != -1) input.system[1] = old_system[1];
|
||||
|
@ -140,15 +140,15 @@ void gen_reset(uint32 hard_reset)
|
||||
|
||||
count_m68k = 0;
|
||||
count_z80 = 0;
|
||||
}
|
||||
|
||||
resetline = -1; /* clear !RESET */
|
||||
gen_running = 1; /* System is running */
|
||||
zreset = 0; /* Z80 is reset */
|
||||
zbusreq = 0; /* Z80 has control of the Z bus */
|
||||
zbusack = 1; /* Z80 is busy using the Z bus */
|
||||
zirq = 0; /* No interrupts occuring */
|
||||
zbank = 0; /* Assume default bank is $000000-$007FFF */
|
||||
}
|
||||
|
||||
resetline = -1;
|
||||
|
||||
/* reset CPUs */
|
||||
m68k_pulse_reset();
|
||||
|
@ -85,6 +85,7 @@ void config_default(void)
|
||||
config.bios_enabled = 0;
|
||||
config.lock_on = 0;
|
||||
config.romtype = 0;
|
||||
config.hot_swap = 0;
|
||||
|
||||
/* video options */
|
||||
config.xshift = 0;
|
||||
@ -107,7 +108,11 @@ void config_default(void)
|
||||
gx_input_SetDefault();
|
||||
|
||||
/* menu options */
|
||||
#ifdef HW_RVL
|
||||
config.sram_auto = 0;
|
||||
#else
|
||||
config.sram_auto = -1;
|
||||
#endif
|
||||
config.state_auto = -1;
|
||||
config.bg_color = 0;
|
||||
config.screen_w = 658;
|
||||
|
@ -47,6 +47,7 @@ typedef struct
|
||||
uint8 addr_error;
|
||||
uint8 bios_enabled;
|
||||
uint8 lock_on;
|
||||
uint8 hot_swap;
|
||||
uint8 romtype;
|
||||
int16 xshift;
|
||||
int16 yshift;
|
||||
|
@ -23,6 +23,7 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include "shared.h"
|
||||
#include "file_dvd.h"
|
||||
#include "gui.h"
|
||||
|
||||
#ifndef HW_RVL
|
||||
@ -44,7 +45,7 @@ static u8 DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32); /* data buffer for all DVD
|
||||
u32 dvd_read (void *dst, u32 len, u64 offset)
|
||||
{
|
||||
/*** We only allow 2k reads **/
|
||||
if (len > 2048) return 0;
|
||||
if (len > DVDCHUNK) return 0;
|
||||
|
||||
/*** Let's not read past end of DVD ***/
|
||||
if(offset < DvdMaxOffset)
|
||||
|
@ -48,7 +48,7 @@ static int rootdirlength = 0;
|
||||
static int IsJoliet = 0;
|
||||
static int diroffset = 0;
|
||||
static int haveDVDdir = 0;
|
||||
static char dvdbuffer[2048];
|
||||
static char dvdbuffer[DVDCHUNK];
|
||||
|
||||
/****************************************************************************
|
||||
* Primary Volume Descriptor
|
||||
@ -67,7 +67,7 @@ static int getpvd()
|
||||
/** Look for Joliet PVD first **/
|
||||
while (sector < 32)
|
||||
{
|
||||
if (dvd_read (&dvdbuffer, 2048, (u64)(sector << 11)))
|
||||
if (dvd_read (&dvdbuffer, DVDCHUNK, (u64)(sector << 11)))
|
||||
{
|
||||
if (memcmp (&dvdbuffer, "\2CD001\1", 8) == 0)
|
||||
{
|
||||
@ -89,7 +89,7 @@ static int getpvd()
|
||||
sector = 16;
|
||||
while (sector < 32)
|
||||
{
|
||||
if (dvd_read (&dvdbuffer, 2048, (u64)(sector << 11)))
|
||||
if (dvd_read (&dvdbuffer, DVDCHUNK, (u64)(sector << 11)))
|
||||
{
|
||||
if (memcmp (&dvdbuffer, "\1CD001\1", 8) == 0)
|
||||
{
|
||||
@ -126,7 +126,7 @@ static int getentry(int entrycount)
|
||||
|
||||
/* Basic checks */
|
||||
if (entrycount >= MAXFILES) return 0;
|
||||
if (diroffset >= 2048) return 0;
|
||||
if (diroffset >= DVDCHUNK) return 0;
|
||||
|
||||
/** Decode this entry **/
|
||||
if (dvdbuffer[diroffset]) /* Record length available */
|
||||
@ -139,7 +139,7 @@ static int getentry(int entrycount)
|
||||
|
||||
/* Check for wrap round - illegal in ISO spec,
|
||||
* but certain crap writers do it! */
|
||||
if ((diroffset + dvdbuffer[diroffset]) > 2048) return 0;
|
||||
if ((diroffset + dvdbuffer[diroffset]) > DVDCHUNK) return 0;
|
||||
|
||||
if (*filenamelength)
|
||||
{
|
||||
@ -252,7 +252,7 @@ int DVD_ParseDirectory(void)
|
||||
/*** Get as many files as possible ***/
|
||||
while (len < pdlength)
|
||||
{
|
||||
if (dvd_read (&dvdbuffer, 2048, pdoffset) == 0) return 0;
|
||||
if (dvd_read (&dvdbuffer, DVDCHUNK, pdoffset) == 0) return 0;
|
||||
|
||||
diroffset = 0;
|
||||
|
||||
@ -262,7 +262,7 @@ int DVD_ParseDirectory(void)
|
||||
filecount++;
|
||||
}
|
||||
|
||||
len += 2048;
|
||||
len += DVDCHUNK;
|
||||
pdoffset = rdoffset + len;
|
||||
}
|
||||
|
||||
@ -288,9 +288,9 @@ int DVD_LoadFile(u8 *buffer, u32 selection)
|
||||
if (length > 0)
|
||||
{
|
||||
/* Read first data chunk */
|
||||
char readbuffer[2048];
|
||||
char readbuffer[DVDCHUNK];
|
||||
u64 discoffset = filelist[selection].offset;
|
||||
dvd_read (&readbuffer, 2048, discoffset);
|
||||
dvd_read (&readbuffer, DVDCHUNK, discoffset);
|
||||
|
||||
/* determine file type */
|
||||
if (!IsZipFile ((char *) readbuffer))
|
||||
@ -299,24 +299,24 @@ int DVD_LoadFile(u8 *buffer, u32 selection)
|
||||
sprintf(msg,"Loading %d bytes...", length);
|
||||
GUI_MsgBoxOpen("Information",msg,1);
|
||||
/* How many 2k blocks to read */
|
||||
int blocks = length / 2048;
|
||||
int blocks = length / DVDCHUNK;
|
||||
int readoffset = 0;
|
||||
int i;
|
||||
|
||||
/* read data chunks */
|
||||
for (i = 0; i < blocks; i++)
|
||||
{
|
||||
dvd_read(readbuffer, 2048, discoffset);
|
||||
discoffset += 2048;
|
||||
memcpy (buffer + readoffset, readbuffer, 2048);
|
||||
readoffset += 2048;
|
||||
dvd_read(readbuffer, DVDCHUNK, discoffset);
|
||||
discoffset += DVDCHUNK;
|
||||
memcpy (buffer + readoffset, readbuffer, DVDCHUNK);
|
||||
readoffset += DVDCHUNK;
|
||||
}
|
||||
|
||||
/* final read */
|
||||
i = length % 2048;
|
||||
i = length % DVDCHUNK;
|
||||
if (i)
|
||||
{
|
||||
dvd_read (readbuffer, 2048, discoffset);
|
||||
dvd_read (readbuffer, DVDCHUNK, discoffset);
|
||||
memcpy (buffer + readoffset, readbuffer, i);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
#ifndef _FILE_DVD_H
|
||||
#define _FILE_DVD_H
|
||||
|
||||
#define DVDCHUNK (2048)
|
||||
|
||||
extern void DVD_ClearDirectory(void);
|
||||
extern int DVD_UpdateDirectory(bool go_up,u64 offset, u32 length);
|
||||
extern int DVD_ParseDirectory(void);
|
||||
|
@ -181,8 +181,8 @@ int FAT_LoadFile(u8 *buffer, u32 selection)
|
||||
}
|
||||
|
||||
/* Read first data chunk */
|
||||
unsigned char temp[2048];
|
||||
fread(temp, 1, 2048, sdfile);
|
||||
unsigned char temp[FATCHUNK];
|
||||
fread(temp, FATCHUNK, 1, sdfile);
|
||||
fclose(sdfile);
|
||||
|
||||
/* determine file type */
|
||||
@ -195,9 +195,16 @@ int FAT_LoadFile(u8 *buffer, u32 selection)
|
||||
char msg[50];
|
||||
sprintf(msg,"Loading %d bytes ...", length);
|
||||
GUI_MsgBoxOpen("Information",msg,1);
|
||||
fread(buffer, 1, length, sdfile);
|
||||
int i = 0;
|
||||
while (length > FATCHUNK)
|
||||
{
|
||||
fread(buffer+i, FATCHUNK, 1, sdfile);
|
||||
length -= FATCHUNK;
|
||||
i += FATCHUNK;
|
||||
}
|
||||
fread(buffer+i, length, 1, sdfile);
|
||||
fclose(sdfile);
|
||||
return length;
|
||||
return filelist[selection].length;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -31,6 +31,8 @@
|
||||
#define TYPE_USB 2
|
||||
#endif
|
||||
|
||||
#define FATCHUNK (2048)
|
||||
|
||||
extern void FAT_ClearDirectory(void);
|
||||
extern int FAT_UpdateDirectory(bool go_up, char *filename);
|
||||
extern int FAT_ParseDirectory(void);
|
||||
|
@ -24,10 +24,11 @@
|
||||
|
||||
#include "shared.h"
|
||||
#include "file_mem.h"
|
||||
#include "file_fat.h"
|
||||
#include "dvd.h"
|
||||
#include "gui.h"
|
||||
#include "filesel.h"
|
||||
#include "saveicon.h"
|
||||
#include "dvd.h"
|
||||
|
||||
/* Global ROM filename */
|
||||
char rom_filename[MAXJOLIET];
|
||||
@ -85,15 +86,22 @@ static int FAT_ManageFile(char *filename, u8 direction, u8 filetype)
|
||||
}
|
||||
else filesize = state_save(savebuffer); /* STATE */
|
||||
|
||||
/* write buffer */
|
||||
done = fwrite(savebuffer, 1, filesize, fp);
|
||||
/* write buffer (2k blocks) */
|
||||
while (filesize > FATCHUNK)
|
||||
{
|
||||
fwrite(savebuffer + done, FATCHUNK, 1, fp);
|
||||
filesize -= FATCHUNK;
|
||||
done += FATCHUNK;
|
||||
}
|
||||
done += fwrite(savebuffer + done, filesize, 1, fp);
|
||||
fclose(fp);
|
||||
|
||||
if (done < filesize)
|
||||
{
|
||||
GUI_WaitPrompt("Error","Unable to write file !");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
sprintf (fname, "Saved %d bytes successfully", done);
|
||||
GUI_WaitPrompt("Information",fname);
|
||||
return 1;
|
||||
@ -105,14 +113,21 @@ static int FAT_ManageFile(char *filename, u8 direction, u8 filetype)
|
||||
filesize = ftell (fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
/* read into buffer (32k blocks) */
|
||||
done = fread(savebuffer, 1, filesize, fp);
|
||||
/* read into buffer (2k blocks) */
|
||||
while (filesize > FATCHUNK)
|
||||
{
|
||||
fread(savebuffer + done, FATCHUNK, 1, fp);
|
||||
filesize -= FATCHUNK;
|
||||
done += FATCHUNK;
|
||||
}
|
||||
done += fread(savebuffer + done, filesize, 1, fp);
|
||||
fclose(fp);
|
||||
|
||||
if (done < filesize)
|
||||
{
|
||||
GUI_WaitPrompt("Error","Unable to read file !");
|
||||
return 0;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
if (filetype) /* SRAM */
|
||||
{
|
||||
|
@ -28,6 +28,8 @@
|
||||
|
||||
#include "shared.h"
|
||||
#include "dvd.h"
|
||||
#include "file_dvd.h"
|
||||
#include "file_fat.h"
|
||||
#include "gui.h"
|
||||
|
||||
/*
|
||||
@ -120,11 +122,11 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
|
||||
if (fatfile)
|
||||
{
|
||||
fseek(fatfile, 0, SEEK_SET);
|
||||
fread(readbuffer, 1, 2048, fatfile);
|
||||
fread(readbuffer, FATCHUNK, 1, fatfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
dvd_read (&readbuffer, 2048, discoffset);
|
||||
dvd_read (&readbuffer, DVDCHUNK, discoffset);
|
||||
}
|
||||
|
||||
/*** Copy PKZip header to local, used as info ***/
|
||||
@ -188,12 +190,12 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
|
||||
|
||||
if (fatfile)
|
||||
{
|
||||
fread(readbuffer, 1, 2048, fatfile);
|
||||
fread(readbuffer, FATCHUNK, 1, fatfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
discoffset += 2048;
|
||||
dvd_read (&readbuffer, 2048, discoffset);
|
||||
discoffset += DVDCHUNK;
|
||||
dvd_read (&readbuffer, DVDCHUNK, discoffset);
|
||||
}
|
||||
}
|
||||
while (res != Z_STREAM_END);
|
||||
|
@ -232,13 +232,14 @@ static gui_item items_audio[10] =
|
||||
};
|
||||
|
||||
/* System options menu */
|
||||
static gui_item items_system[6] =
|
||||
static gui_item items_system[7] =
|
||||
{
|
||||
{NULL,NULL,"Console Region: AUTO", "Select system region", 52,132,276,48},
|
||||
{NULL,NULL,"System Lockups: OFF", "Enable/disable original system lock-ups", 52,132,276,48},
|
||||
{NULL,NULL,"68k Address Error: ON", "Enable/disable 68k Address Error", 52,132,276,48},
|
||||
{NULL,NULL,"System BIOS: OFF", "Enable/disable TMSS BIOS support", 52,132,276,48},
|
||||
{NULL,NULL,"Lock-on: OFF", "Select Lock-On cartridge type", 52,132,276,48},
|
||||
{NULL,NULL,"Cartridge Swap: OFF", "Enable/disable cartridge hot swap", 52,132,276,48},
|
||||
{NULL,NULL,"SVP Cycles: 1500", "Adjust SVP chip emulation speed", 52,132,276,48}
|
||||
};
|
||||
|
||||
@ -880,16 +881,17 @@ static void systemmenu ()
|
||||
else if (config.lock_on == TYPE_AR) sprintf (items[4].text, "Lock-On: ACTION REPLAY");
|
||||
else if (config.lock_on == TYPE_SK) sprintf (items[4].text, "Lock-On: SONIC & KNUCKLES");
|
||||
else sprintf (items[4].text, "Lock-On: OFF");
|
||||
sprintf (items[5].text, "Cartridge Swap: %s", config.hot_swap ? "ON":"OFF");
|
||||
|
||||
if (svp)
|
||||
{
|
||||
sprintf (items[5].text, "SVP Cycles: %d", SVP_cycles);
|
||||
m->max_items = 6;
|
||||
sprintf (items[6].text, "SVP Cycles: %d", SVP_cycles);
|
||||
m->max_items = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
m->max_items = 5;
|
||||
if (m->offset > 1) m->offset =1;
|
||||
m->max_items = 6;
|
||||
if (m->offset > 2) m->offset--;
|
||||
}
|
||||
|
||||
GUI_InitMenu(m);
|
||||
@ -973,9 +975,14 @@ static void systemmenu ()
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: /*** SVP emulation ***/
|
||||
case 5: /*** Cartridge Hot Swap ***/
|
||||
config.hot_swap ^= 1;
|
||||
sprintf (items[5].text, "Cartridge Swap: %s", config.hot_swap ? "ON":"OFF");
|
||||
break;
|
||||
|
||||
case 6: /*** SVP emulation ***/
|
||||
GUI_OptionBox(m,0,"SVP Cycles",(void *)&SVP_cycles,1,1,1500,1);
|
||||
sprintf (items[5].text, "SVP Cycles: %d", SVP_cycles);
|
||||
sprintf (items[6].text, "SVP Cycles: %d", SVP_cycles);
|
||||
break;
|
||||
|
||||
case -1:
|
||||
@ -1193,10 +1200,7 @@ static void ctrlmenu(void)
|
||||
gui_item *items = NULL;
|
||||
u8 *special = NULL;
|
||||
char msg[16];
|
||||
|
||||
#ifdef HW_RVL
|
||||
u32 exp;
|
||||
#endif
|
||||
|
||||
/* System devices */
|
||||
gui_item items_sys[2][7] =
|
||||
@ -1528,20 +1532,45 @@ static void ctrlmenu(void)
|
||||
break;
|
||||
|
||||
case 11: /* input controller selection */
|
||||
#ifdef HW_RVL
|
||||
|
||||
/* no input device */
|
||||
if (config.input[player].device > 0)
|
||||
if (config.input[player].device < 0)
|
||||
{
|
||||
/* use next port */
|
||||
config.input[player].port ++;
|
||||
/* try gamecube controllers */
|
||||
config.input[player].device = 0;
|
||||
config.input[player].port = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use gamecube pad */
|
||||
config.input[player].device ++;
|
||||
config.input[player].port = config.input[player].device ? 0 : (player%4);
|
||||
/* try next port */
|
||||
config.input[player].port ++;
|
||||
}
|
||||
|
||||
/* autodetect connected gamecube controllers */
|
||||
if (config.input[player].device == 0)
|
||||
{
|
||||
exp = 0;
|
||||
while ((config.input[player].port<4) && !exp)
|
||||
{
|
||||
exp = PAD_ScanPads() & (1<<config.input[player].port);
|
||||
if (!exp) config.input[player].port ++;
|
||||
}
|
||||
|
||||
if (config.input[player].port >= 4)
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
/* no gamecube controller found, try wiimote */
|
||||
config.input[player].port = 0;
|
||||
config.input[player].device = 1;
|
||||
#else
|
||||
/* no input controller left */
|
||||
config.input[player].device = -1;
|
||||
config.input[player].port = player%4;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HW_RVL
|
||||
/* autodetect connected wiimotes (without nunchuk) */
|
||||
if (config.input[player].device == 1)
|
||||
{
|
||||
@ -1622,8 +1651,8 @@ static void ctrlmenu(void)
|
||||
|
||||
if (config.input[player].port >= 4)
|
||||
{
|
||||
/* no classic controller found, use default gamecube pad */
|
||||
config.input[player].device = 0;
|
||||
/* no input controller left */
|
||||
config.input[player].device = -1;
|
||||
config.input[player].port = player%4;
|
||||
}
|
||||
}
|
||||
@ -1634,11 +1663,6 @@ static void ctrlmenu(void)
|
||||
config.input[player].padtype = DEVICE_3BUTTON;
|
||||
memcpy(&m->items[10],&items[*special],sizeof(gui_item));
|
||||
}
|
||||
|
||||
#else
|
||||
/* use gamecube pad */
|
||||
config.input[player].device = 0;
|
||||
config.input[player].port = player%4;
|
||||
#endif
|
||||
|
||||
/* update menu items */
|
||||
@ -1670,6 +1694,7 @@ static void ctrlmenu(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if (update < 0)
|
||||
{
|
||||
if (m->bg_images[7].state & IMAGE_VISIBLE)
|
||||
@ -1702,6 +1727,32 @@ static void ctrlmenu(void)
|
||||
update = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* check we have at least one connected input before leaving */
|
||||
if (update < 0)
|
||||
{
|
||||
old_player = player;
|
||||
player = 0;
|
||||
for (i=0; i<MAX_DEVICES; i++)
|
||||
{
|
||||
/* check inputs */
|
||||
if (input.dev[i] != NO_DEVICE)
|
||||
{
|
||||
if (config.input[player].device != -1)
|
||||
break;
|
||||
player++;
|
||||
}
|
||||
}
|
||||
player = old_player;
|
||||
|
||||
/* no input connected */
|
||||
if (i == MAX_DEVICES)
|
||||
{
|
||||
/* stay in menu */
|
||||
GUI_WaitPrompt("Error","No input connected !");
|
||||
update = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* remove duplicate assigned inputs before leaving */
|
||||
@ -2224,13 +2275,16 @@ void MainMenu (void)
|
||||
GUI_InitMenu(m);
|
||||
break;
|
||||
|
||||
case 4: /*** Emulator Reset ***/
|
||||
case 4: /*** System Power Off/On ***/
|
||||
if (!cart.romsize) break;
|
||||
GUI_DrawMenuFX(m,10,1);
|
||||
GUI_DeleteMenu(m);
|
||||
gxClearScreen((GXColor)BLACK);
|
||||
gxSetScreen();
|
||||
system_init();
|
||||
audio_init(48000);
|
||||
system_reset();
|
||||
memfile_autoload(config.sram_auto,-1);
|
||||
quit = 1;
|
||||
break;
|
||||
|
||||
|
@ -2,6 +2,9 @@
|
||||
Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net>
|
||||
All rights reserved.
|
||||
|
||||
Proper (standard) vorbis usage by Tantric, 2009
|
||||
Threading modifications/corrections by Tantric, 2009
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
@ -24,10 +27,212 @@
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef NO_SOUND
|
||||
|
||||
#include "oggplayer.h"
|
||||
#include <gccore.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
/* functions to read the Ogg file from memory */
|
||||
|
||||
static struct
|
||||
{
|
||||
char *mem;
|
||||
int size;
|
||||
int pos;
|
||||
} file[4];
|
||||
|
||||
static int f_read(void * punt, int bytes, int blocks, int *f)
|
||||
{
|
||||
int b;
|
||||
int c;
|
||||
int d;
|
||||
|
||||
if (bytes * blocks <= 0)
|
||||
return 0;
|
||||
|
||||
blocks = bytes * blocks;
|
||||
c = 0;
|
||||
|
||||
while (blocks > 0)
|
||||
{
|
||||
b = blocks;
|
||||
if (b > 4096)
|
||||
b = 4096;
|
||||
|
||||
if (*f >= 0x666 && *f <= 0x669)
|
||||
{
|
||||
d = (*f) - 0x666;
|
||||
if (file[d].size == 0)
|
||||
return -1;
|
||||
if ((file[d].pos + b) > file[d].size)
|
||||
b = file[d].size - file[d].pos;
|
||||
if (b > 0)
|
||||
{
|
||||
memcpy(punt, file[d].mem + file[d].pos, b);
|
||||
file[d].pos += b;
|
||||
}
|
||||
}
|
||||
else
|
||||
b = read(*f, ((char *) punt) + c, b);
|
||||
|
||||
if (b <= 0)
|
||||
{
|
||||
return c / bytes;
|
||||
}
|
||||
c += b;
|
||||
blocks -= b;
|
||||
}
|
||||
return c / bytes;
|
||||
}
|
||||
|
||||
static int f_seek(int *f, ogg_int64_t offset, int mode)
|
||||
{
|
||||
if(f==NULL) return(-1);
|
||||
|
||||
int k, d;
|
||||
mode &= 3;
|
||||
if (*f >= 0x666 && *f <= 0x669)
|
||||
{
|
||||
d = (*f) - 0x666;
|
||||
k = 0;
|
||||
|
||||
if (file[d].size == 0)
|
||||
return -1;
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
if ((offset) >= file[d].size)
|
||||
{
|
||||
file[d].pos = file[d].size;
|
||||
k = -1;
|
||||
}
|
||||
else if ((offset) < 0)
|
||||
{
|
||||
file[d].pos = 0;
|
||||
k = -1;
|
||||
}
|
||||
else
|
||||
file[d].pos = offset;
|
||||
}
|
||||
if (mode == 1)
|
||||
{
|
||||
if ((file[d].pos + offset) >= file[d].size)
|
||||
{
|
||||
file[d].pos = file[d].size;
|
||||
k = -1;
|
||||
}
|
||||
else if ((file[d].pos + offset) < 0)
|
||||
{
|
||||
file[d].pos = 0;
|
||||
k = -1;
|
||||
}
|
||||
else
|
||||
file[d].pos += offset;
|
||||
}
|
||||
if (mode == 2)
|
||||
{
|
||||
|
||||
if ((file[d].size + offset) >= file[d].size)
|
||||
{
|
||||
file[d].pos = file[d].size;
|
||||
k = -1;
|
||||
}
|
||||
else if ((file[d].size + offset) < 0)
|
||||
{
|
||||
file[d].pos = 0;
|
||||
k = -1;
|
||||
}
|
||||
else
|
||||
file[d].pos = file[d].size + offset;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
k = lseek(*f, (int) offset, mode);
|
||||
|
||||
if (k < 0)
|
||||
k = -1;
|
||||
else
|
||||
k = 0;
|
||||
return k;
|
||||
}
|
||||
|
||||
static int f_close(int *f)
|
||||
{
|
||||
int d;
|
||||
if (*f >= 0x666 && *f <= 0x669)
|
||||
{
|
||||
d = (*f) - 0x666;
|
||||
file[d].size = 0;
|
||||
file[d].pos = 0;
|
||||
if (file[d].mem)
|
||||
{
|
||||
file[d].mem = (void *) 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return close(*f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long f_tell(int *f)
|
||||
{
|
||||
int k, d;
|
||||
|
||||
if (*f >= 0x666 && *f <= 0x669)
|
||||
{
|
||||
d = (*f) - 0x666;
|
||||
k = file[d].pos;
|
||||
}
|
||||
else
|
||||
k = lseek(*f, 0, 1);
|
||||
|
||||
return (long) k;
|
||||
}
|
||||
|
||||
static int mem_open(char * ogg, int size)
|
||||
{
|
||||
static int one = 1;
|
||||
int n;
|
||||
if (one)
|
||||
{
|
||||
one = 0;
|
||||
for (n = 0; n < 4; n++)
|
||||
file[n].size = 0;
|
||||
}
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
if (file[n].size == 0)
|
||||
{
|
||||
file[n].mem = ogg;
|
||||
file[n].size = size;
|
||||
file[n].pos = 0;
|
||||
return (0x666 + n);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mem_close(int fd)
|
||||
{
|
||||
if (fd >= 0x666 && fd <= 0x669) // it is a memory file descriptor?
|
||||
{
|
||||
fd -= 0x666;
|
||||
file[fd].size = 0;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return f_close(&fd);
|
||||
}
|
||||
|
||||
static ov_callbacks callbacks = {
|
||||
(size_t (*)(void *, size_t, size_t, void *)) f_read,
|
||||
(int (*)(void *, ogg_int64_t, int)) f_seek,
|
||||
(int (*)(void *)) f_close,
|
||||
(long (*)(void *)) f_tell
|
||||
};
|
||||
|
||||
/* OGG control */
|
||||
|
||||
@ -61,15 +266,15 @@ static private_data_ogg private_ogg;
|
||||
#define STACKSIZE 8192
|
||||
|
||||
static u8 oggplayer_stack[STACKSIZE];
|
||||
static lwpq_t oggplayer_queue;
|
||||
static lwp_t h_oggplayer;
|
||||
static lwpq_t oggplayer_queue = LWP_TQUEUE_NULL;
|
||||
static lwp_t h_oggplayer = LWP_THREAD_NULL;
|
||||
static int ogg_thread_running = 0;
|
||||
|
||||
static void ogg_add_callback(int voice)
|
||||
{
|
||||
if (ogg_thread_running <= 0)
|
||||
if (!ogg_thread_running)
|
||||
{
|
||||
SND_StopVoice(0);
|
||||
ASND_StopVoice(0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -78,7 +283,7 @@ static void ogg_add_callback(int voice)
|
||||
|
||||
if (private_ogg.pcm_indx >= READ_SAMPLES)
|
||||
{
|
||||
if (SND_AddVoice(0,
|
||||
if (ASND_AddVoice(0,
|
||||
(void *) private_ogg.pcmout[private_ogg.pcmout_pos],
|
||||
private_ogg.pcm_indx << 1) == 0)
|
||||
{
|
||||
@ -101,14 +306,14 @@ static void ogg_add_callback(int voice)
|
||||
static void * ogg_player_thread(private_data_ogg * priv)
|
||||
{
|
||||
int first_time = 1;
|
||||
long ret;
|
||||
|
||||
ogg_thread_running = 0;
|
||||
/* init */
|
||||
LWP_InitQueue(&oggplayer_queue);
|
||||
|
||||
priv[0].vi = ov_info(&priv[0].vf, -1);
|
||||
|
||||
SND_Pause(0);
|
||||
ASND_Pause(0);
|
||||
|
||||
priv[0].pcm_indx = 0;
|
||||
priv[0].pcmout_pos = 0;
|
||||
@ -118,22 +323,15 @@ static void * ogg_player_thread(private_data_ogg * priv)
|
||||
|
||||
ogg_thread_running = 1;
|
||||
|
||||
while (!priv[0].eof)
|
||||
while (!priv[0].eof && ogg_thread_running)
|
||||
{
|
||||
long ret;
|
||||
if (ogg_thread_running <= 0)
|
||||
break;
|
||||
|
||||
if (priv[0].flag)
|
||||
LWP_ThreadSleep(oggplayer_queue); /* wait only when i have samples to send */
|
||||
|
||||
if (ogg_thread_running <= 0)
|
||||
break;
|
||||
|
||||
if (priv[0].flag == 0) /* wait to all samples are sended */
|
||||
{
|
||||
if (SND_TestPointer(0, priv[0].pcmout[priv[0].pcmout_pos])
|
||||
&& SND_StatusVoice(0) != SND_UNUSED)
|
||||
if (ASND_TestPointer(0, priv[0].pcmout[priv[0].pcmout_pos])
|
||||
&& ASND_StatusVoice(0) != SND_UNUSED)
|
||||
{
|
||||
priv[0].flag |= 64;
|
||||
continue;
|
||||
@ -187,12 +385,12 @@ static void * ogg_player_thread(private_data_ogg * priv)
|
||||
|
||||
if (priv[0].flag == 1)
|
||||
{
|
||||
if (SND_StatusVoice(0) == SND_UNUSED || first_time)
|
||||
if (ASND_StatusVoice(0) == SND_UNUSED || first_time)
|
||||
{
|
||||
first_time = 0;
|
||||
if (priv[0].vi->channels == 2)
|
||||
{
|
||||
SND_SetVoice(0, VOICE_STEREO_16BIT, priv[0].vi->rate, 0,
|
||||
ASND_SetVoice(0, VOICE_STEREO_16BIT, priv[0].vi->rate, 0,
|
||||
(void *) priv[0].pcmout[priv[0].pcmout_pos],
|
||||
priv[0].pcm_indx << 1, priv[0].volume,
|
||||
priv[0].volume, ogg_add_callback);
|
||||
@ -202,7 +400,7 @@ static void * ogg_player_thread(private_data_ogg * priv)
|
||||
}
|
||||
else
|
||||
{
|
||||
SND_SetVoice(0, VOICE_MONO_16BIT, priv[0].vi->rate, 0,
|
||||
ASND_SetVoice(0, VOICE_MONO_16BIT, priv[0].vi->rate, 0,
|
||||
(void *) priv[0].pcmout[priv[0].pcmout_pos],
|
||||
priv[0].pcm_indx << 1, priv[0].volume,
|
||||
priv[0].volume, ogg_add_callback);
|
||||
@ -211,48 +409,47 @@ static void * ogg_player_thread(private_data_ogg * priv)
|
||||
priv[0].flag = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* all samples sended */
|
||||
/* if(priv[0].pcm_indx==0) priv[0].flag=0; */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
usleep(10);
|
||||
}
|
||||
ov_clear(&priv[0].vf);
|
||||
priv[0].fd = -1;
|
||||
priv[0].pcm_indx = 0;
|
||||
ogg_thread_running = 0;
|
||||
/* free */
|
||||
LWP_CloseQueue(oggplayer_queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void StopOgg()
|
||||
{
|
||||
SND_StopVoice(0);
|
||||
if (ogg_thread_running > 0)
|
||||
ASND_StopVoice(0);
|
||||
ogg_thread_running = 0;
|
||||
|
||||
if(h_oggplayer != LWP_THREAD_NULL)
|
||||
{
|
||||
ogg_thread_running = -2;
|
||||
if(oggplayer_queue != LWP_TQUEUE_NULL)
|
||||
LWP_ThreadSignal(oggplayer_queue);
|
||||
LWP_JoinThread(h_oggplayer, NULL);
|
||||
|
||||
while (((volatile int) ogg_thread_running) != 0)
|
||||
{
|
||||
;;;
|
||||
h_oggplayer = LWP_THREAD_NULL;
|
||||
}
|
||||
if(oggplayer_queue != LWP_TQUEUE_NULL)
|
||||
{
|
||||
LWP_CloseQueue(oggplayer_queue);
|
||||
oggplayer_queue = LWP_TQUEUE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int PlayOgg(int fd, int time_pos, int mode)
|
||||
int PlayOgg(char * buf, int buflen, int time_pos, int mode)
|
||||
{
|
||||
StopOgg();
|
||||
|
||||
ogg_thread_running = 0;
|
||||
private_ogg.fd = mem_open(buf, buflen);
|
||||
|
||||
if (private_ogg.fd < 0)
|
||||
{
|
||||
private_ogg.fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private_ogg.fd = fd;
|
||||
private_ogg.mode = mode;
|
||||
private_ogg.eof = 0;
|
||||
private_ogg.volume = 127;
|
||||
@ -262,32 +459,22 @@ int PlayOgg(int fd, int time_pos, int mode)
|
||||
if (time_pos > 0)
|
||||
private_ogg.seek_time = time_pos;
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
private_ogg.fd = -1;
|
||||
return -1;
|
||||
}
|
||||
if (ov_open((void *) &private_ogg.fd, &private_ogg.vf, NULL, 0) < 0)
|
||||
if (ov_open_callbacks((void *) &private_ogg.fd, &private_ogg.vf, NULL, 0, callbacks) < 0)
|
||||
{
|
||||
mem_close(private_ogg.fd); /* mem_close() can too close files from devices */
|
||||
private_ogg.fd = -1;
|
||||
ogg_thread_running = -1;
|
||||
ogg_thread_running = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (LWP_CreateThread(&h_oggplayer, (void *) ogg_player_thread,
|
||||
&private_ogg, oggplayer_stack, STACKSIZE, 80) == -1)
|
||||
{
|
||||
ogg_thread_running = -1;
|
||||
ogg_thread_running = 0;
|
||||
ov_clear(&private_ogg.vf);
|
||||
private_ogg.fd = -1;
|
||||
return -1;
|
||||
}
|
||||
while (((volatile int) ogg_thread_running) == 0)
|
||||
{
|
||||
;;;
|
||||
}
|
||||
LWP_ThreadSignal(oggplayer_queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -306,39 +493,33 @@ void PauseOgg(int pause)
|
||||
if (ogg_thread_running > 0)
|
||||
{
|
||||
LWP_ThreadSignal(oggplayer_queue);
|
||||
/* while(((volatile int )private_ogg.flag)!=1 && ((volatile int )ogg_thread_running)>0) {;;;} */
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int StatusOgg()
|
||||
{
|
||||
if (ogg_thread_running <= 0)
|
||||
if (ogg_thread_running == 0)
|
||||
return -1; /* Error */
|
||||
|
||||
if (private_ogg.eof)
|
||||
else if (private_ogg.eof)
|
||||
return 255; /* EOF */
|
||||
|
||||
if (private_ogg.flag & 128)
|
||||
else if (private_ogg.flag & 128)
|
||||
return 2; /* paused */
|
||||
else
|
||||
return 1; /* running */
|
||||
}
|
||||
|
||||
void SetVolumeOgg(int volume)
|
||||
{
|
||||
private_ogg.volume = volume;
|
||||
|
||||
SND_ChangeVolumeVoice(0, volume, volume);
|
||||
ASND_ChangeVolumeVoice(0, volume, volume);
|
||||
}
|
||||
|
||||
s32 GetTimeOgg()
|
||||
{
|
||||
int ret;
|
||||
if (ogg_thread_running <= 0)
|
||||
return 0;
|
||||
if (private_ogg.fd < 0)
|
||||
if (ogg_thread_running == 0 || private_ogg.fd < 0)
|
||||
return 0;
|
||||
ret = ((s32) ov_time_tell(&private_ogg.vf));
|
||||
if (ret < 0)
|
||||
@ -353,4 +534,3 @@ void SetTimeOgg(s32 time_pos)
|
||||
private_ogg.seek_time = time_pos;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -58,7 +58,9 @@ extern "C"
|
||||
|
||||
-- Params ---
|
||||
|
||||
fd: file descriptor from open() or mem_open()
|
||||
buf: pointer to sound data
|
||||
|
||||
buflen: buffer size in bytes
|
||||
|
||||
time_pos: initial time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds
|
||||
|
||||
@ -68,7 +70,7 @@ extern "C"
|
||||
|
||||
*/
|
||||
|
||||
int PlayOgg(int fd, int time_pos, int mode);
|
||||
int PlayOgg(char * buf, int buflen, int time_pos, int mode);
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -196,7 +196,7 @@ void gx_audio_Stop(void)
|
||||
if (Bg_music_ogg && !Shutdown)
|
||||
{
|
||||
PauseOgg(0);
|
||||
PlayOgg(mem_open((char *)Bg_music_ogg, Bg_music_ogg_size), 0, OGG_INFINITE_TIME);
|
||||
PlayOgg((char *)Bg_music_ogg, Bg_music_ogg_size, 0, OGG_INFINITE_TIME);
|
||||
SetVolumeOgg(((int)config.bgm_volume * 255) / 100);
|
||||
}
|
||||
}
|
||||
|
@ -563,6 +563,26 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USB_MOUSE
|
||||
if (MOUSE_IsConnected())
|
||||
{
|
||||
/* USB Mouse support */
|
||||
mouse_event event;
|
||||
MOUSE_GetEvent(&event);
|
||||
MOUSE_FlushEvents();
|
||||
|
||||
/* relative X/Y position: (-128;+127) -> (-255;+255) */
|
||||
if (event.rx) input.analog[2][0] = (event.rx * 2) + 1;
|
||||
else input.analog[2][0] = 0;
|
||||
if (event.ry) input.analog[2][1] = (event.ry * 2) + 1;
|
||||
else input.analog[2][1] = 0;
|
||||
|
||||
/* buttons pressed */
|
||||
if (event.button & 1) input.pad[i] |= INPUT_A;
|
||||
if (event.button & 2) input.pad[i] |= INPUT_B;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Invert Y coordinate */
|
||||
if (!config.invert_mouse) input.analog[2][1] = -input.analog[2][1];
|
||||
}
|
||||
@ -651,7 +671,7 @@ void gx_input_SetDefault(void)
|
||||
#endif
|
||||
|
||||
/* Default player inputs */
|
||||
for (i=0; i<MAX_DEVICES; i++)
|
||||
for (i=0; i<MAX_INPUTS; i++)
|
||||
{
|
||||
config.input[i].device = -1;
|
||||
config.input[i].port = i%4;
|
||||
@ -697,7 +717,7 @@ void gx_input_SetDefault(void)
|
||||
/* check if Gamecube Controller is connected */
|
||||
if (exp & (1 << i))
|
||||
{
|
||||
for (j=0; j<MAX_DEVICES; j++)
|
||||
for (j=0; j<MAX_INPUTS; j++)
|
||||
{
|
||||
/* look for the first unassigned player */
|
||||
if (config.input[j].device == -1)
|
||||
|
@ -588,7 +588,6 @@ static void gxDrawCrosshair(gx_texture *texture, int x, int y)
|
||||
GX_Color4u8(0xff,0xff,0xff,0xff);
|
||||
GX_TexCoord2f32(0.0, 0.0);
|
||||
GX_End ();
|
||||
GX_DrawDone();
|
||||
|
||||
/* restore GX rendering */
|
||||
gxResetRendering(0);
|
||||
@ -625,7 +624,6 @@ void gxDrawRectangle(s32 x, s32 y, s32 w, s32 h, u8 alpha, GXColor color)
|
||||
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);
|
||||
@ -664,7 +662,6 @@ void gxDrawTexture(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alpha)
|
||||
GX_Color4u8(0xff,0xff,0xff,alpha);
|
||||
GX_TexCoord2f32(0.0, 0.0);
|
||||
GX_End ();
|
||||
GX_DrawDone();
|
||||
}
|
||||
}
|
||||
|
||||
@ -709,7 +706,6 @@ void gxDrawTextureRotate(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, f32 an
|
||||
GX_Color4u8(0xff,0xff,0xff,alpha);
|
||||
GX_TexCoord2f32(0.0, 1.0);
|
||||
GX_End ();
|
||||
GX_DrawDone();
|
||||
|
||||
/* restore default Modelview */
|
||||
guLookAt(mv, &cam.pos, &cam.up, &cam.view);
|
||||
@ -752,7 +748,6 @@ void gxDrawTextureRepeat(gx_texture *texture, s32 x, s32 y, s32 w, s32 h, u8 alp
|
||||
GX_Color4u8(0xff,0xff,0xff,alpha);
|
||||
GX_TexCoord2f32(0.0, 0.0);
|
||||
GX_End ();
|
||||
GX_DrawDone();
|
||||
}
|
||||
}
|
||||
|
||||
@ -796,7 +791,6 @@ void gxDrawScreenshot(u8 alpha)
|
||||
GX_Color4u8(0xff,0xff,0xff,alpha);
|
||||
GX_TexCoord2f32(0.0, 0.0);
|
||||
GX_End ();
|
||||
GX_DrawDone();
|
||||
}
|
||||
|
||||
void gxCopyScreenshot(gx_texture *texture)
|
||||
@ -829,7 +823,6 @@ void gxCopyScreenshot(gx_texture *texture)
|
||||
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;
|
||||
@ -838,6 +831,7 @@ void gxCopyScreenshot(gx_texture *texture)
|
||||
texture->data = screenshot;
|
||||
GX_SetTexCopySrc(0, 0, texture->width * 2, texture->height * 2);
|
||||
GX_SetTexCopyDst(texture->width, texture->height, texture->format, GX_TRUE);
|
||||
GX_DrawDone();
|
||||
GX_CopyTex(texture->data, GX_TRUE);
|
||||
GX_Flush();
|
||||
|
||||
@ -847,6 +841,7 @@ void gxCopyScreenshot(gx_texture *texture)
|
||||
GX_PixModeSync();
|
||||
GX_LoadTexObj(&texobj, GX_TEXMAP0);
|
||||
GX_InvalidateTexAll();
|
||||
GX_Flush();
|
||||
DCFlushRange(texture->data, texture->width * texture->height * 4);
|
||||
}
|
||||
|
||||
@ -869,6 +864,7 @@ void gxSaveScreenshot(char *filename)
|
||||
|
||||
void gxSetScreen(void)
|
||||
{
|
||||
GX_DrawDone();
|
||||
GX_CopyDisp(xfb[whichfb], GX_FALSE);
|
||||
GX_Flush();
|
||||
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
||||
@ -1396,7 +1392,6 @@ void gx_video_Update(void)
|
||||
|
||||
/* render textured quad */
|
||||
draw_square();
|
||||
GX_DrawDone();
|
||||
|
||||
/* LightGun marks */
|
||||
if (crosshair[0]) gxDrawCrosshair(crosshair[0], input.analog[0][0],input.analog[0][1]);
|
||||
@ -1406,6 +1401,7 @@ void gx_video_Update(void)
|
||||
whichfb ^= 1;
|
||||
|
||||
/* copy EFB to XFB */
|
||||
GX_DrawDone();
|
||||
GX_CopyDisp(xfb[whichfb], GX_TRUE);
|
||||
GX_Flush();
|
||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||
|
@ -110,12 +110,26 @@ static void init_machine(void)
|
||||
***************************************************/
|
||||
void reloadrom (int size, char *name)
|
||||
{
|
||||
/* cartridge hot-swap support */
|
||||
uint8 hotswap = 0;
|
||||
if (cart.romsize) hotswap = config.hot_swap;
|
||||
|
||||
/* Load ROM */
|
||||
cart.romsize = size;
|
||||
load_rom(name); /* Load ROM */
|
||||
load_rom(name);
|
||||
|
||||
if (hotswap)
|
||||
{
|
||||
cart_hw_init();
|
||||
cart_hw_reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
system_init (); /* Initialize System */
|
||||
audio_init(48000); /* Audio System initialization */
|
||||
ClearGGCodes (); /* Clear Game Genie patches */
|
||||
system_reset (); /* System Power ON */
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
|
@ -33,9 +33,9 @@
|
||||
#define SK_UPMEM "/genplus/sk2chip.bin"
|
||||
|
||||
#ifdef HW_RVL
|
||||
#define VERSION "version 1.3.XW"
|
||||
#define VERSION "version 1.3.2W"
|
||||
#else
|
||||
#define VERSION "version 1.3.XG"
|
||||
#define VERSION "version 1.3.2G"
|
||||
#endif
|
||||
|
||||
#define osd_input_Update() gx_input_UpdateEmu()
|
||||
|
@ -267,7 +267,7 @@ int load_rom(char *filename)
|
||||
free(ptr);
|
||||
#endif
|
||||
|
||||
/* detect interleaved roms (.smd format) */
|
||||
/* detect interleaved format (.SMD) */
|
||||
if (strncmp((char *)(cart.rom + 0x100),"SEGA", 4) && ((size / 512) & 1))
|
||||
{
|
||||
size -= 512;
|
||||
@ -288,8 +288,8 @@ int load_rom(char *filename)
|
||||
/* clear unused ROM space */
|
||||
memset (cart.rom + size, 0xff, MAXROMSIZE - size);
|
||||
|
||||
getrominfo((char *)cart.rom); /* get infos from ROM header */
|
||||
set_region(); /* set game region (PAL/NTSC, JAP/USA/EUR) */
|
||||
/* get infos from ROM header */
|
||||
getrominfo((char *)cart.rom);
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* Byteswap ROM */
|
||||
@ -380,10 +380,6 @@ void set_region ()
|
||||
else if (config.region_detect == 2) region_code = REGION_EUROPE;
|
||||
else if (config.region_detect == 3) region_code = REGION_JAPAN_NTSC;
|
||||
else if (config.region_detect == 4) region_code = REGION_JAPAN_PAL;
|
||||
|
||||
/* set cpu/vdp speed: PAL or NTSC */
|
||||
if ((region_code == REGION_EUROPE) || (region_code == REGION_JAPAN_PAL)) vdp_pal = 1;
|
||||
else vdp_pal = 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -199,7 +199,7 @@ int Fir_Resampler_read( sample_t** out, unsigned long count )
|
||||
{
|
||||
sample_t* out_l = out[0];
|
||||
sample_t* out_r = out[1];
|
||||
const sample_t* in = buffer;
|
||||
sample_t* in = buffer;
|
||||
sample_t* end_pos = write_pos;
|
||||
unsigned long skip = skip_bits >> imp_phase;
|
||||
sample_t const* imp = impulses [imp_phase];
|
||||
|
@ -210,9 +210,9 @@ void system_init (void)
|
||||
{
|
||||
/* Genesis hardware */
|
||||
gen_init();
|
||||
io_init();
|
||||
vdp_init();
|
||||
render_init();
|
||||
io_init();
|
||||
|
||||
/* Cartridge hardware */
|
||||
cart_hw_init();
|
||||
@ -229,9 +229,9 @@ void system_reset (void)
|
||||
/* Genesis hardware */
|
||||
gen_reset(1);
|
||||
SN76489_Reset();
|
||||
io_reset();
|
||||
vdp_reset();
|
||||
render_reset();
|
||||
io_reset();
|
||||
|
||||
/* Clear Sound Buffers */
|
||||
if (snd.psg.buffer) memset (snd.psg.buffer, 0, SND_SIZE);
|
||||
|
19
source/vdp.c
19
source/vdp.c
@ -142,8 +142,21 @@ static inline void dma_fill(unsigned int data);
|
||||
void vdp_init(void)
|
||||
{
|
||||
/* PAL/NTSC timings */
|
||||
vdp_rate = vdp_pal ? 50 : 60;
|
||||
lines_per_frame = vdp_pal ? 313 : 262;
|
||||
switch (region_code)
|
||||
{
|
||||
case REGION_EUROPE:
|
||||
case REGION_JAPAN_PAL:
|
||||
vdp_pal = 1;
|
||||
vdp_rate = 50;
|
||||
lines_per_frame = 313;
|
||||
break;
|
||||
|
||||
default:
|
||||
vdp_pal = 0;
|
||||
vdp_rate = 60;
|
||||
lines_per_frame = 262;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void vdp_reset(void)
|
||||
@ -443,7 +456,7 @@ unsigned int vdp_ctrl_r(void)
|
||||
if (!(reg[1] & 0x40)) temp |= 0x8;
|
||||
|
||||
/* HBLANK flag (Sonic 3 and Sonic 2 "VS Modes", Lemmings 2, Mega Turrican) */
|
||||
if ((count_m68k <= (line_m68k + 84)) || (count_m68k > (line_m68k + m68cycles_per_line))) temp |= 0x4;
|
||||
if ((count_m68k % m68cycles_per_line) < 84) temp |= 0x4;
|
||||
|
||||
/* clear pending flag */
|
||||
pending = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user