mirror of
https://github.com/dborth/vbagx.git
synced 2024-11-01 00:15:10 +01:00
structure/system overhaul - partially working
This commit is contained in:
parent
e7dc70438e
commit
fc4c229edc
@ -16,6 +16,8 @@ static int tail = 0;
|
||||
static u8 mixerdata[MIXBUFFSIZE];
|
||||
#define MIXERMASK ((MIXBUFFSIZE >> 2) - 1)
|
||||
|
||||
static u8 soundbuffer[3200] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
/****************************************************************************
|
||||
* MIXER_AddSamples
|
||||
*
|
||||
@ -71,3 +73,29 @@ int MIXER_GetSamples( u8 *dstbuffer, int maxlen )
|
||||
return 3200;
|
||||
}
|
||||
|
||||
static void AudioPlayer()
|
||||
{
|
||||
AUDIO_StopDMA();
|
||||
MIXER_GetSamples(soundbuffer, 3200);
|
||||
DCFlushRange(soundbuffer,3200);
|
||||
AUDIO_InitDMA((u32)soundbuffer,3200);
|
||||
AUDIO_StartDMA();
|
||||
}
|
||||
|
||||
void InitialiseSound()
|
||||
{
|
||||
AUDIO_Init(NULL); // Start audio subsystem
|
||||
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ);
|
||||
AUDIO_RegisterDMACallback(AudioPlayer);
|
||||
memset(soundbuffer, 0, 3200);
|
||||
}
|
||||
|
||||
void StopAudio()
|
||||
{
|
||||
AUDIO_StopDMA();
|
||||
}
|
||||
|
||||
void StartAudio()
|
||||
{
|
||||
AUDIO_StartDMA();
|
||||
}
|
@ -8,6 +8,8 @@
|
||||
|
||||
void MIXER_AddSamples( u8 *sampledata, int len );
|
||||
int MIXER_GetSamples( u8 *dstbuffer, int maxlen );
|
||||
void StopAudio();
|
||||
void StartAudio();
|
||||
void InitialiseSound();
|
||||
|
||||
#endif
|
||||
|
117
source/ngc/button_mapping.c
Normal file
117
source/ngc/button_mapping.c
Normal file
@ -0,0 +1,117 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* michniewski August 2008
|
||||
*
|
||||
* button_mapping.c
|
||||
*
|
||||
* Controller button mapping
|
||||
***************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
#include <unistd.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
|
||||
#include "button_mapping.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Controller Button Descriptions:
|
||||
* used for identifying which buttons have been pressed when configuring
|
||||
* and for displaying the name of said button
|
||||
***************************************************************************/
|
||||
|
||||
CtrlrMap ctrlr_def[4] = {
|
||||
// Nunchuk btn def
|
||||
{
|
||||
CTRLR_NUNCHUK,
|
||||
13,
|
||||
{
|
||||
{WPAD_BUTTON_DOWN, "DOWN"},
|
||||
{WPAD_BUTTON_UP, "UP"},
|
||||
{WPAD_BUTTON_LEFT, "LEFT"},
|
||||
{WPAD_BUTTON_RIGHT, "RIGHT"},
|
||||
{WPAD_BUTTON_A, "A"},
|
||||
{WPAD_BUTTON_B, "B"},
|
||||
{WPAD_BUTTON_1, "1"},
|
||||
{WPAD_BUTTON_2, "2"},
|
||||
{WPAD_BUTTON_PLUS, "PLUS"},
|
||||
{WPAD_BUTTON_MINUS, "MINUS"},
|
||||
{WPAD_BUTTON_HOME, "HOME"},
|
||||
{WPAD_NUNCHUK_BUTTON_Z, "Z"},
|
||||
{WPAD_NUNCHUK_BUTTON_C, "C"},
|
||||
{0, ""},
|
||||
{0, ""}
|
||||
}
|
||||
},
|
||||
// Classic btn def
|
||||
{
|
||||
CTRLR_CLASSIC,
|
||||
15,
|
||||
{
|
||||
{WPAD_CLASSIC_BUTTON_DOWN, "DOWN"},
|
||||
{WPAD_CLASSIC_BUTTON_UP, "UP"},
|
||||
{WPAD_CLASSIC_BUTTON_LEFT, "LEFT"},
|
||||
{WPAD_CLASSIC_BUTTON_RIGHT, "RIGHT"},
|
||||
{WPAD_CLASSIC_BUTTON_A, "A"},
|
||||
{WPAD_CLASSIC_BUTTON_B, "B"},
|
||||
{WPAD_CLASSIC_BUTTON_X, "X"},
|
||||
{WPAD_CLASSIC_BUTTON_Y, "Y"},
|
||||
{WPAD_CLASSIC_BUTTON_PLUS, "PLUS"},
|
||||
{WPAD_CLASSIC_BUTTON_MINUS, "MINUS"},
|
||||
{WPAD_CLASSIC_BUTTON_HOME, "HOME"},
|
||||
{WPAD_CLASSIC_BUTTON_FULL_L, "L TRIG"},
|
||||
{WPAD_CLASSIC_BUTTON_FULL_R, "R TRIG"},
|
||||
{WPAD_CLASSIC_BUTTON_ZL, "ZL"},
|
||||
{WPAD_CLASSIC_BUTTON_ZR, "ZR"}
|
||||
}
|
||||
},
|
||||
// Gamecube controller btn def
|
||||
{
|
||||
CTRLR_GCPAD,
|
||||
13,
|
||||
{
|
||||
{PAD_BUTTON_DOWN, "DOWN"},
|
||||
{PAD_BUTTON_UP, "UP"},
|
||||
{PAD_BUTTON_LEFT, "LEFT"},
|
||||
{PAD_BUTTON_RIGHT, "RIGHT"},
|
||||
{PAD_BUTTON_A, "A"},
|
||||
{PAD_BUTTON_B, "B"},
|
||||
{PAD_BUTTON_X, "X"},
|
||||
{PAD_BUTTON_Y, "Y"},
|
||||
{PAD_BUTTON_MENU, "MENU"},
|
||||
{PAD_BUTTON_START, "START"},
|
||||
{PAD_TRIGGER_L, "L TRIG"},
|
||||
{PAD_TRIGGER_R, "R TRIG"},
|
||||
{PAD_TRIGGER_Z, "Z"},
|
||||
{0, ""},
|
||||
{0, ""}
|
||||
}
|
||||
},
|
||||
// Wiimote btn def
|
||||
{
|
||||
CTRLR_WIIMOTE,
|
||||
11,
|
||||
{
|
||||
{WPAD_BUTTON_DOWN, "DOWN"},
|
||||
{WPAD_BUTTON_UP, "UP"},
|
||||
{WPAD_BUTTON_LEFT, "LEFT"},
|
||||
{WPAD_BUTTON_RIGHT, "RIGHT"},
|
||||
{WPAD_BUTTON_A, "A"},
|
||||
{WPAD_BUTTON_B, "B"},
|
||||
{WPAD_BUTTON_1, "1"},
|
||||
{WPAD_BUTTON_2, "2"},
|
||||
{WPAD_BUTTON_PLUS, "PLUS"},
|
||||
{WPAD_BUTTON_MINUS, "MINUS"},
|
||||
{WPAD_BUTTON_HOME, "HOME"},
|
||||
{0, ""},
|
||||
{0, ""},
|
||||
{0, ""},
|
||||
{0, ""}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
38
source/ngc/button_mapping.h
Normal file
38
source/ngc/button_mapping.h
Normal file
@ -0,0 +1,38 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* michniewski August 2008
|
||||
*
|
||||
* button_mapping.h
|
||||
*
|
||||
* Controller button mapping
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BTN_MAP_H
|
||||
#define BTN_MAP_H
|
||||
|
||||
enum {
|
||||
CTRLR_NONE = -1,
|
||||
CTRLR_NUNCHUK,
|
||||
CTRLR_CLASSIC,
|
||||
CTRLR_GCPAD,
|
||||
CTRLR_WIIMOTE,
|
||||
CTRLR_SNES = 7 // give some other value for the snes padmap
|
||||
};
|
||||
|
||||
typedef struct _btn_map {
|
||||
u32 btn; // button 'id'
|
||||
char* name; // button name
|
||||
} BtnMap;
|
||||
|
||||
typedef struct _ctrlr_map {
|
||||
u16 type; // controller type
|
||||
int num_btns; // number of buttons on the controller
|
||||
BtnMap map[15]; // controller button map
|
||||
} CtrlrMap;
|
||||
|
||||
// externs:
|
||||
|
||||
extern CtrlrMap ctrlr_def[4];
|
||||
|
||||
#endif
|
573
source/ngc/dvd.cpp
Normal file
573
source/ngc/dvd.cpp
Normal file
@ -0,0 +1,573 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* svpe & crunchy2 June 2007
|
||||
* Tantric September 2008
|
||||
*
|
||||
* dvd.cpp
|
||||
*
|
||||
* DVD I/O functions
|
||||
***************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <ogcsys.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WII_DVD
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <di/di.h>
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "menudraw.h"
|
||||
#include "gcunzip.h"
|
||||
|
||||
extern int offset;
|
||||
extern int selection;
|
||||
extern FILEENTRIES filelist[MAXFILES];
|
||||
extern int maxfiles;
|
||||
u64 dvddir = 0;
|
||||
u64 dvdrootdir = 0;
|
||||
int dvddirlength = 0;
|
||||
bool isWii = false;
|
||||
|
||||
#ifdef HW_DOL
|
||||
/** DVD I/O Address base **/
|
||||
volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000;
|
||||
#endif
|
||||
|
||||
/** Due to lack of memory, we'll use this little 2k keyhole for all DVD operations **/
|
||||
unsigned char DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32);
|
||||
unsigned char dvdbuffer[2048];
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* dvd_read
|
||||
*
|
||||
* The only DVD function we need - you gotta luv gc-linux self-boots!
|
||||
* returns: 1 - ok ; 0 - error
|
||||
***************************************************************************/
|
||||
int
|
||||
dvd_read (void *dst, unsigned int len, u64 offset)
|
||||
{
|
||||
|
||||
unsigned char *buffer = (unsigned char *) (unsigned int) DVDreadbuffer;
|
||||
|
||||
if (len > 2048)
|
||||
return 0; /*** We only allow 2k reads **/
|
||||
|
||||
DCInvalidateRange ((void *) buffer, len);
|
||||
|
||||
// don't read past the end of the DVD (1.5 GB for GC DVD, 4.7 GB for DVD)
|
||||
if(offset < 0x57057C00 || (isWii && offset < 0x118244F00LL))
|
||||
{
|
||||
|
||||
#ifdef HW_DOL
|
||||
|
||||
dvd[0] = 0x2E;
|
||||
dvd[1] = 0;
|
||||
dvd[2] = 0xA8000000;
|
||||
dvd[3] = (u32)(offset >> 2);
|
||||
dvd[4] = len;
|
||||
dvd[5] = (u32) buffer;
|
||||
dvd[6] = len;
|
||||
dvd[7] = 3; /*** Enable reading with DMA ***/
|
||||
while (dvd[7] & 1);
|
||||
memcpy (dst, buffer, len);
|
||||
|
||||
if (dvd[0] & 0x4) /* Ensure it has completed */
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
||||
#elif WII_DVD
|
||||
int ret = 1;
|
||||
ret = DI_ReadDVD(dst, len >> 11, (u32)(offset >> 11));
|
||||
if (ret==0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Minimal ISO Directory Definition **/
|
||||
#define RECLEN 0 /* Record length */
|
||||
#define EXTENT 6 /* Extent */
|
||||
#define FILE_LENGTH 14 /* File length (BIG ENDIAN) */
|
||||
#define FILE_FLAGS 25 /* File flags */
|
||||
#define FILENAME_LENGTH 32 /* Filename length */
|
||||
#define FILENAME 33 /* ASCIIZ filename */
|
||||
|
||||
/** Minimal Primary Volume Descriptor **/
|
||||
#define PVDROOT 0x9c
|
||||
static int IsJoliet = 0;
|
||||
|
||||
/****************************************************************************
|
||||
* Primary Volume Descriptor
|
||||
*
|
||||
* The PVD should reside between sector 16 and 31.
|
||||
* This is for single session DVD only.
|
||||
***************************************************************************/
|
||||
int
|
||||
getpvd ()
|
||||
{
|
||||
int sector = 16;
|
||||
u32 rootdir32;
|
||||
|
||||
dvddir = dvddirlength = 0;
|
||||
IsJoliet = -1;
|
||||
|
||||
/** Look for Joliet PVD first **/
|
||||
while (sector < 32)
|
||||
{
|
||||
if (dvd_read (&dvdbuffer, 2048, (u64)(sector << 11)))
|
||||
{
|
||||
if (memcmp (&dvdbuffer, "\2CD001\1", 8) == 0)
|
||||
{
|
||||
memcpy(&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
|
||||
dvddir = (u64)rootdir32;
|
||||
dvddir <<= 11;
|
||||
dvdrootdir = dvddir;
|
||||
memcpy (&dvddirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
|
||||
IsJoliet = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0; /*** Can't read sector! ***/
|
||||
sector++;
|
||||
}
|
||||
|
||||
if (IsJoliet > 0) /*** Joliet PVD Found ? ***/
|
||||
return 1;
|
||||
|
||||
sector = 16;
|
||||
|
||||
/*** Look for standard ISO9660 PVD ***/
|
||||
while (sector < 32)
|
||||
{
|
||||
if (dvd_read (&dvdbuffer, 2048, sector << 11))
|
||||
{
|
||||
if (memcmp (&dvdbuffer, "\1CD001\1", 8) == 0)
|
||||
{
|
||||
memcpy (&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
|
||||
dvddir = (u64)rootdir32;
|
||||
dvddir <<= 11;
|
||||
dvdrootdir = dvddir;
|
||||
memcpy (&dvddirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
|
||||
IsJoliet = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0; /*** Can't read sector! ***/
|
||||
sector++;
|
||||
}
|
||||
return (IsJoliet == 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* TestDVD()
|
||||
*
|
||||
* Tests if a ISO9660 DVD is inserted and available
|
||||
***************************************************************************/
|
||||
bool TestDVD()
|
||||
{
|
||||
|
||||
if (!getpvd())
|
||||
{
|
||||
#ifdef HW_DOL
|
||||
DVD_Mount();
|
||||
#elif WII_DVD
|
||||
DI_Mount();
|
||||
while(DI_GetStatus() & DVD_INIT);
|
||||
#endif
|
||||
if (!getpvd())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* getentry
|
||||
*
|
||||
* Support function to return the next file entry, if any
|
||||
* Declared static to avoid accidental external entry.
|
||||
***************************************************************************/
|
||||
static int diroffset = 0;
|
||||
static int
|
||||
getentry (int entrycount)
|
||||
{
|
||||
char fname[512]; /* Huge, but experience has determined this */
|
||||
char *ptr;
|
||||
char *filename;
|
||||
char *filenamelength;
|
||||
char *rr;
|
||||
int j;
|
||||
u32 offset32;
|
||||
|
||||
/* Basic checks */
|
||||
if (entrycount >= MAXFILES)
|
||||
return 0;
|
||||
|
||||
if (diroffset >= 2048)
|
||||
return 0;
|
||||
|
||||
/** Decode this entry **/
|
||||
if (dvdbuffer[diroffset]) /* Record length available */
|
||||
{
|
||||
/* Update offsets into sector buffer */
|
||||
ptr = (char *) &dvdbuffer[0];
|
||||
ptr += diroffset;
|
||||
filename = ptr + FILENAME;
|
||||
filenamelength = ptr + FILENAME_LENGTH;
|
||||
|
||||
/* Check for wrap round - illegal in ISO spec,
|
||||
* but certain crap writers do it! */
|
||||
if ((diroffset + dvdbuffer[diroffset]) > 2048)
|
||||
return 0;
|
||||
|
||||
if (*filenamelength)
|
||||
{
|
||||
memset (&fname, 0, 512);
|
||||
|
||||
if (!IsJoliet) /*** Do ISO 9660 first ***/
|
||||
strcpy (fname, filename);
|
||||
else
|
||||
{ /*** The more tortuous unicode joliet entries ***/
|
||||
for (j = 0; j < (*filenamelength >> 1); j++)
|
||||
{
|
||||
fname[j] = filename[j * 2 + 1];
|
||||
}
|
||||
|
||||
fname[j] = 0;
|
||||
|
||||
if (strlen (fname) >= MAXJOLIET)
|
||||
fname[MAXJOLIET - 1] = 0;
|
||||
|
||||
if (strlen (fname) == 0)
|
||||
fname[0] = filename[0];
|
||||
}
|
||||
|
||||
if (strlen (fname) == 0) // root entry
|
||||
{
|
||||
fname[0] = 0; // we'll skip it by setting the filename to 0 length
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fname[0] == 1)
|
||||
{
|
||||
if(dvddir == dvdrootdir) // at root already, don't show ..
|
||||
fname[0] = 0;
|
||||
else
|
||||
strcpy (fname, "..");
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Move *filenamelength to t,
|
||||
* Only to stop gcc warning for noobs :)
|
||||
*/
|
||||
int t = *filenamelength;
|
||||
fname[t] = 0;
|
||||
}
|
||||
}
|
||||
/** Rockridge Check **/
|
||||
rr = strstr (fname, ";");
|
||||
if (rr != NULL)
|
||||
*rr = 0;
|
||||
|
||||
strcpy (filelist[entrycount].filename, fname);
|
||||
fname[MAXDISPLAY - 1] = 0;
|
||||
strcpy (filelist[entrycount].displayname, fname);
|
||||
|
||||
memcpy (&offset32, &dvdbuffer[diroffset + EXTENT], 4);
|
||||
|
||||
filelist[entrycount].offset = (u64)offset32;
|
||||
memcpy (&filelist[entrycount].length, &dvdbuffer[diroffset + FILE_LENGTH], 4);
|
||||
memcpy (&filelist[entrycount].flags, &dvdbuffer[diroffset + FILE_FLAGS], 1);
|
||||
|
||||
filelist[entrycount].offset <<= 11;
|
||||
filelist[entrycount].flags = filelist[entrycount].flags & 2;
|
||||
|
||||
/*** Prepare for next entry ***/
|
||||
|
||||
diroffset += dvdbuffer[diroffset];
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* parseDVDdirectory
|
||||
*
|
||||
* This function will parse the directory tree.
|
||||
* It relies on dvddir and dvddirlength being pre-populated by a call to
|
||||
* getpvd, a previous parse or a menu selection.
|
||||
*
|
||||
* The return value is number of files collected, or 0 on failure.
|
||||
***************************************************************************/
|
||||
int
|
||||
ParseDVDdirectory ()
|
||||
{
|
||||
int pdlength;
|
||||
u64 pdoffset;
|
||||
u64 rdoffset;
|
||||
int len = 0;
|
||||
int filecount = 0;
|
||||
|
||||
// initialize selection
|
||||
selection = offset = 0;
|
||||
|
||||
pdoffset = rdoffset = dvddir;
|
||||
pdlength = dvddirlength;
|
||||
filecount = 0;
|
||||
|
||||
// Clear any existing values
|
||||
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
|
||||
|
||||
/*** Get as many files as possible ***/
|
||||
while (len < pdlength)
|
||||
{
|
||||
if (dvd_read (&dvdbuffer, 2048, pdoffset) == 0)
|
||||
return 0;
|
||||
|
||||
diroffset = 0;
|
||||
|
||||
while (getentry (filecount))
|
||||
{
|
||||
if(strlen(filelist[filecount].filename) > 0 && filecount < MAXFILES)
|
||||
filecount++;
|
||||
}
|
||||
|
||||
len += 2048;
|
||||
pdoffset = rdoffset + len;
|
||||
}
|
||||
|
||||
// Sort the file list
|
||||
qsort(filelist, filecount, sizeof(FILEENTRIES), FileSortCallback);
|
||||
|
||||
return filecount;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DirectorySearch
|
||||
*
|
||||
* Searches for the directory name specified within the current directory
|
||||
* Returns the index of the directory, or -1 if not found
|
||||
***************************************************************************/
|
||||
int DirectorySearch(char dir[512])
|
||||
{
|
||||
for (int i = 0; i < maxfiles; i++ )
|
||||
if (strcmp(filelist[i].filename, dir) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* SwitchDVDFolder
|
||||
*
|
||||
* Recursively searches for any directory path 'dir' specified
|
||||
* Also loads the directory contents via ParseDVDdirectory()
|
||||
* It relies on dvddir, dvddirlength, and filelist being pre-populated
|
||||
***************************************************************************/
|
||||
bool SwitchDVDFolder(char * dir, int maxDepth)
|
||||
{
|
||||
if(maxDepth > 8) // only search to a max depth of 8 levels
|
||||
return false;
|
||||
|
||||
bool lastdir = false;
|
||||
char * nextdir = NULL;
|
||||
unsigned int t = strcspn(dir, "/");
|
||||
|
||||
if(t != strlen(dir))
|
||||
nextdir = dir + t + 1; // next directory path to find
|
||||
else
|
||||
lastdir = true;
|
||||
|
||||
dir[t] = 0;
|
||||
|
||||
int dirindex = DirectorySearch(dir);
|
||||
|
||||
if(dirindex >= 0)
|
||||
{
|
||||
dvddir = filelist[dirindex].offset;
|
||||
dvddirlength = filelist[dirindex].length;
|
||||
maxfiles = ParseDVDdirectory();
|
||||
|
||||
if(lastdir)
|
||||
return true;
|
||||
else
|
||||
return SwitchDVDFolder(nextdir, maxDepth++);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SwitchDVDFolder(char origdir[])
|
||||
{
|
||||
// make a copy of origdir so we don't mess with original
|
||||
char dir[200];
|
||||
strcpy(dir, origdir);
|
||||
|
||||
char * dirptr = dir;
|
||||
|
||||
// strip off leading/trailing slashes on the directory path
|
||||
// we don't want to screw up our recursion!
|
||||
if(dir[0] == '/')
|
||||
dirptr = dirptr + 1;
|
||||
if(dir[strlen(dir)-1] == '/')
|
||||
dir[strlen(dir)-1] = 0;
|
||||
|
||||
return SwitchDVDFolder(dirptr, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* LoadDVDFile
|
||||
* This function will load a file from DVD, in BIN, SMD or ZIP format.
|
||||
* The values for offset and length are inherited from dvddir and
|
||||
* dvddirlength.
|
||||
*
|
||||
* The buffer parameter should re-use the initial ROM buffer.
|
||||
***************************************************************************/
|
||||
|
||||
int
|
||||
LoadDVDFile (unsigned char *buffer)
|
||||
{
|
||||
int offset;
|
||||
int blocks;
|
||||
int i;
|
||||
u64 discoffset;
|
||||
char readbuffer[2048];
|
||||
|
||||
// How many 2k blocks to read
|
||||
blocks = dvddirlength / 2048;
|
||||
offset = 0;
|
||||
discoffset = dvddir;
|
||||
ShowAction ((char*) "Loading...");
|
||||
dvd_read (readbuffer, 2048, discoffset);
|
||||
|
||||
if (!IsZipFile (readbuffer))
|
||||
{
|
||||
for (i = 0; i < blocks; i++)
|
||||
{
|
||||
dvd_read (readbuffer, 2048, discoffset);
|
||||
memcpy (buffer + offset, readbuffer, 2048);
|
||||
offset += 2048;
|
||||
discoffset += 2048;
|
||||
}
|
||||
|
||||
/*** And final cleanup ***/
|
||||
if (dvddirlength % 2048)
|
||||
{
|
||||
i = dvddirlength % 2048;
|
||||
dvd_read (readbuffer, 2048, discoffset);
|
||||
memcpy (buffer + offset, readbuffer, i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return UnZipFile (buffer, discoffset); // unzip from dvd
|
||||
}
|
||||
return dvddirlength;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* uselessinquiry
|
||||
*
|
||||
* As the name suggests, this function is quite useless.
|
||||
* It's only purpose is to stop any pending DVD interrupts while we use the
|
||||
* memcard interface.
|
||||
*
|
||||
* libOGC tends to foul up if you don't, and sometimes does if you do!
|
||||
***************************************************************************/
|
||||
#ifdef HW_DOL
|
||||
void uselessinquiry ()
|
||||
{
|
||||
dvd[0] = 0;
|
||||
dvd[1] = 0;
|
||||
dvd[2] = 0x12000000;
|
||||
dvd[3] = 0;
|
||||
dvd[4] = 0x20;
|
||||
dvd[5] = 0x80000000;
|
||||
dvd[6] = 0x20;
|
||||
dvd[7] = 1;
|
||||
|
||||
while (dvd[7] & 1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* dvd_motor_off( )
|
||||
* Turns off DVD drive motor so it doesn't make noise (Gamecube only)
|
||||
***************************************************************************/
|
||||
void dvd_motor_off( )
|
||||
{
|
||||
dvd[0] = 0x2e;
|
||||
dvd[1] = 0;
|
||||
dvd[2] = 0xe3000000;
|
||||
dvd[3] = 0;
|
||||
dvd[4] = 0;
|
||||
dvd[5] = 0;
|
||||
dvd[6] = 0;
|
||||
dvd[7] = 1; // Do immediate
|
||||
while (dvd[7] & 1);
|
||||
|
||||
/*** PSO Stops blackscreen at reload ***/
|
||||
dvd[0] = 0x14;
|
||||
dvd[1] = 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* dvd_driveid
|
||||
*
|
||||
* Gets and returns the dvd driveid
|
||||
***************************************************************************/
|
||||
|
||||
int dvd_driveid()
|
||||
{
|
||||
static unsigned char *inquiry=(unsigned char *)0x80000004;
|
||||
|
||||
dvd[0] = 0x2e;
|
||||
dvd[1] = 0;
|
||||
dvd[2] = 0x12000000;
|
||||
dvd[3] = 0;
|
||||
dvd[4] = 0x20;
|
||||
dvd[5] = 0x80000000;
|
||||
dvd[6] = 0x20;
|
||||
dvd[7] = 3;
|
||||
|
||||
while( dvd[7] & 1 )
|
||||
;
|
||||
DCFlushRange((void *)0x80000000, 32);
|
||||
|
||||
return (int)inquiry[2];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* SetDVDDriveType()
|
||||
*
|
||||
* Sets the DVD drive ID for use to determine disc size (1.5 GB or 4.7 GB)
|
||||
***************************************************************************/
|
||||
void SetDVDDriveType()
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
isWii = true;
|
||||
#else
|
||||
int drvid = dvd_driveid ();
|
||||
if ( drvid == 4 || drvid == 6 || drvid == 8 )
|
||||
isWii = false;
|
||||
else
|
||||
isWii = true;
|
||||
#endif
|
||||
}
|
24
source/ngc/dvd.h
Normal file
24
source/ngc/dvd.h
Normal file
@ -0,0 +1,24 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* svpe & crunchy2 June 2007
|
||||
* Tantric September 2008
|
||||
*
|
||||
* dvd.h
|
||||
*
|
||||
* DVD I/O functions
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _NGCDVD_
|
||||
#define _NGCDVD_
|
||||
|
||||
int getpvd ();
|
||||
int ParseDVDdirectory ();
|
||||
int LoadDVDFile (unsigned char *buffer);
|
||||
bool TestDVD();
|
||||
int dvd_read (void *dst, unsigned int len, u64 offset);
|
||||
bool SwitchDVDFolder(char dir[]);
|
||||
void SetDVDDriveType();
|
||||
|
||||
#endif
|
286
source/ngc/fileop.cpp
Normal file
286
source/ngc/fileop.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May 2007
|
||||
* Tantric August 2008
|
||||
*
|
||||
* fileop.cpp
|
||||
*
|
||||
* FAT File operations
|
||||
***************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "vba.h"
|
||||
#include "vbasupport.h"
|
||||
#include "fileop.h"
|
||||
#include "gcunzip.h"
|
||||
#include "video.h"
|
||||
#include "menudraw.h"
|
||||
#include "filesel.h"
|
||||
#include "preferences.h"
|
||||
|
||||
FILE * filehandle;
|
||||
|
||||
extern unsigned char savebuffer[];
|
||||
extern char output[16384];
|
||||
extern int offset;
|
||||
extern int selection;
|
||||
extern char currentdir[MAXPATHLEN];
|
||||
extern FILEENTRIES filelist[MAXFILES];
|
||||
|
||||
/****************************************************************************
|
||||
* fat_is_mounted
|
||||
* to check whether FAT media are detected.
|
||||
***************************************************************************/
|
||||
|
||||
bool FatIsMounted(PARTITION_INTERFACE partition) {
|
||||
char prefix[] = "fatX:/";
|
||||
prefix[3] = partition + '0';
|
||||
DIR_ITER *dir = diropen(prefix);
|
||||
if (dir) {
|
||||
dirclose(dir);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* changeFATInterface
|
||||
* Checks if the device (method) specified is available, and
|
||||
* sets libfat to use the device
|
||||
***************************************************************************/
|
||||
bool ChangeFATInterface(int method, bool silent)
|
||||
{
|
||||
bool devFound = false;
|
||||
|
||||
if(method == METHOD_SD)
|
||||
{
|
||||
// check which SD device is loaded
|
||||
|
||||
#ifdef HW_RVL
|
||||
if (FatIsMounted(PI_INTERNAL_SD))
|
||||
{
|
||||
devFound = true;
|
||||
fatSetDefaultInterface(PI_INTERNAL_SD);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!devFound && FatIsMounted(PI_SDGECKO_A))
|
||||
{
|
||||
devFound = true;
|
||||
fatSetDefaultInterface(PI_SDGECKO_A);
|
||||
}
|
||||
if(!devFound && FatIsMounted(PI_SDGECKO_B))
|
||||
{
|
||||
devFound = true;
|
||||
fatSetDefaultInterface(PI_SDGECKO_B);
|
||||
}
|
||||
if(!devFound)
|
||||
{
|
||||
if(!silent)
|
||||
WaitPrompt ((char *)"SD card not found!");
|
||||
}
|
||||
}
|
||||
else if(method == METHOD_USB)
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
if(FatIsMounted(PI_USBSTORAGE))
|
||||
{
|
||||
devFound = true;
|
||||
fatSetDefaultInterface(PI_USBSTORAGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!silent)
|
||||
WaitPrompt ((char *)"USB flash drive not found!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return devFound;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Browse FAT subdirectories
|
||||
**************************************************************************/
|
||||
int
|
||||
ParseFATdirectory(int method)
|
||||
{
|
||||
int nbfiles = 0;
|
||||
DIR_ITER *fatdir;
|
||||
char filename[MAXPATHLEN];
|
||||
struct stat filestat;
|
||||
char msg[128];
|
||||
|
||||
// initialize selection
|
||||
selection = offset = 0;
|
||||
|
||||
// Clear any existing values
|
||||
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
|
||||
|
||||
// open the directory
|
||||
fatdir = diropen(currentdir);
|
||||
if (fatdir == NULL)
|
||||
{
|
||||
sprintf(msg, "Couldn't open %s", currentdir);
|
||||
WaitPrompt(msg);
|
||||
|
||||
// if we can't open the dir, open root dir
|
||||
sprintf(currentdir,"%s",ROOTFATDIR);
|
||||
|
||||
fatdir = diropen(currentdir);
|
||||
|
||||
if (fatdir == NULL)
|
||||
{
|
||||
sprintf(msg, "Error opening %s", currentdir);
|
||||
WaitPrompt(msg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// index files/folders
|
||||
while(dirnext(fatdir,filename,&filestat) == 0)
|
||||
{
|
||||
if(strcmp(filename,".") != 0)
|
||||
{
|
||||
memset(&filelist[nbfiles], 0, sizeof(FILEENTRIES));
|
||||
strncpy(filelist[nbfiles].filename, filename, MAXPATHLEN);
|
||||
strncpy(filelist[nbfiles].displayname, filename, MAXDISPLAY+1); // crop name for display
|
||||
filelist[nbfiles].length = filestat.st_size;
|
||||
filelist[nbfiles].flags = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1; // flag this as a dir
|
||||
nbfiles++;
|
||||
}
|
||||
}
|
||||
|
||||
// close directory
|
||||
dirclose(fatdir);
|
||||
|
||||
// Sort the file list
|
||||
qsort(filelist, nbfiles, sizeof(FILEENTRIES), FileSortCallback);
|
||||
|
||||
return nbfiles;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* LoadFATFile
|
||||
***************************************************************************/
|
||||
int
|
||||
LoadFATFile (char *filename, int length)
|
||||
{
|
||||
char zipbuffer[2048];
|
||||
char filepath[MAXPATHLEN];
|
||||
FILE *handle;
|
||||
unsigned char *rbuffer;
|
||||
u32 size;
|
||||
|
||||
/* Check filename length */
|
||||
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
|
||||
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
|
||||
else
|
||||
{
|
||||
WaitPrompt((char*) "Maximum filepath length reached!");
|
||||
return -1;
|
||||
}
|
||||
return loadVBAROM(filepath);
|
||||
/*
|
||||
handle = fopen (filepath, "rb");
|
||||
if (handle > 0)
|
||||
{
|
||||
fread (zipbuffer, 1, 2048, handle);
|
||||
|
||||
if (IsZipFile (zipbuffer))
|
||||
{
|
||||
size = UnZipFile (rbuffer, handle); // unzip from FAT
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just load the file up
|
||||
fseek(handle, 0, SEEK_END);
|
||||
length = ftell(handle); // get filesize
|
||||
fseek(handle, 2048, SEEK_SET); // seek back to point where we left off
|
||||
memcpy (rbuffer, zipbuffer, 2048); // copy what we already read
|
||||
fread (rbuffer + 2048, 1, length - 2048, handle);
|
||||
size = length;
|
||||
}
|
||||
fclose (handle);
|
||||
return size;
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitPrompt((char*) "Error opening file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;*/
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Load savebuffer from FAT file
|
||||
***************************************************************************/
|
||||
int
|
||||
LoadBufferFromFAT (char *filepath, bool silent)
|
||||
{
|
||||
FILE *handle;
|
||||
int boffset = 0;
|
||||
int read = 0;
|
||||
|
||||
ClearSaveBuffer ();
|
||||
|
||||
handle = fopen (filepath, "rb");
|
||||
|
||||
if (handle <= 0)
|
||||
{
|
||||
if ( !silent )
|
||||
{
|
||||
char msg[100];
|
||||
sprintf(msg, "Couldn't open %s", filepath);
|
||||
WaitPrompt (msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** This is really nice, just load the file and decode it ***/
|
||||
while ((read = fread (savebuffer + boffset, 1, 1024, handle)) > 0)
|
||||
{
|
||||
boffset += read;
|
||||
}
|
||||
|
||||
fclose (handle);
|
||||
|
||||
return boffset;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Write savebuffer to FAT card file
|
||||
***************************************************************************/
|
||||
int
|
||||
SaveBufferToFAT (char *filepath, int datasize, bool silent)
|
||||
{
|
||||
FILE *handle;
|
||||
|
||||
if (datasize)
|
||||
{
|
||||
handle = fopen (filepath, "wb");
|
||||
|
||||
if (handle <= 0)
|
||||
{
|
||||
char msg[100];
|
||||
sprintf(msg, "Couldn't save %s", filepath);
|
||||
WaitPrompt (msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fwrite (savebuffer, 1, datasize, handle);
|
||||
fclose (handle);
|
||||
}
|
||||
|
||||
ClearSaveBuffer ();
|
||||
return datasize;
|
||||
}
|
34
source/ngc/fileop.h
Normal file
34
source/ngc/fileop.h
Normal file
@ -0,0 +1,34 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May 2007
|
||||
* Tantric August 2008
|
||||
*
|
||||
* fileop.h
|
||||
*
|
||||
* FAT File operations
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _FATFILESC_
|
||||
#define _FATFILESC_
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
#include <fat.h>
|
||||
#include <sys/dir.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define ROOTFATDIR "fat:/"
|
||||
|
||||
bool ChangeFATInterface(int method, bool silent);
|
||||
int ParseFATdirectory(int method);
|
||||
int LoadFATFile (char *filename, int length);
|
||||
int SaveBufferToFAT (char *filepath, int datasize, bool silent);
|
||||
int LoadBufferFromFAT (char *filepath, bool silent);
|
||||
|
||||
extern char currFATdir[MAXPATHLEN];
|
||||
|
||||
#endif
|
587
source/ngc/filesel.cpp
Normal file
587
source/ngc/filesel.cpp
Normal file
@ -0,0 +1,587 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* svpe June 2007
|
||||
* crunchy2 May-July 2007
|
||||
* Tantric August 2008
|
||||
*
|
||||
* filesel.cpp
|
||||
*
|
||||
* Generic file routines - reading, writing, browsing
|
||||
***************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
#include <sys/dir.h>
|
||||
|
||||
#ifdef WII_DVD
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <di/di.h>
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "vba.h"
|
||||
#include "vbasupport.h"
|
||||
#include "vmmem.h"
|
||||
#include "menudraw.h"
|
||||
#include "video.h"
|
||||
#include "filesel.h"
|
||||
#include "fileop.h"
|
||||
#include "memcardop.h"
|
||||
#include "input.h"
|
||||
#include "dvd.h"
|
||||
#include "smbop.h"
|
||||
|
||||
int offset;
|
||||
int selection;
|
||||
char currentdir[MAXPATHLEN];
|
||||
int maxfiles;
|
||||
extern int screenheight;
|
||||
|
||||
int havedir = -1;
|
||||
extern u64 dvddir;
|
||||
extern int dvddirlength;
|
||||
|
||||
int hasloaded = 0;
|
||||
|
||||
// Global file entry table
|
||||
FILEENTRIES filelist[MAXFILES];
|
||||
|
||||
unsigned char savebuffer[SAVEBUFFERSIZE] ATTRIBUTE_ALIGN (32);
|
||||
|
||||
char ROMFilename[512];
|
||||
int ROMSize = 0;
|
||||
|
||||
/****************************************************************************
|
||||
* ClearSaveBuffer ()
|
||||
* Clear the savebuffer
|
||||
***************************************************************************/
|
||||
void
|
||||
ClearSaveBuffer ()
|
||||
{
|
||||
memset (savebuffer, 0, SAVEBUFFERSIZE);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* autoLoadMethod()
|
||||
* Auto-determines and sets the load method
|
||||
* Returns method set
|
||||
****************************************************************************/
|
||||
int autoLoadMethod()
|
||||
{
|
||||
ShowAction ((char*) "Attempting to determine load method...");
|
||||
|
||||
if(ChangeFATInterface(METHOD_SD, SILENT))
|
||||
return METHOD_SD;
|
||||
else if(ChangeFATInterface(METHOD_USB, SILENT))
|
||||
return METHOD_USB;
|
||||
else if(TestDVD())
|
||||
return METHOD_DVD;
|
||||
else if(ConnectShare (SILENT))
|
||||
return METHOD_SMB;
|
||||
else
|
||||
{
|
||||
WaitPrompt((char*) "Unable to auto-determine load method!");
|
||||
return 0; // no method found
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* autoSaveMethod()
|
||||
* Auto-determines and sets the save method
|
||||
* Returns method set
|
||||
****************************************************************************/
|
||||
int autoSaveMethod()
|
||||
{
|
||||
ShowAction ((char*) "Attempting to determine save method...");
|
||||
|
||||
if(ChangeFATInterface(METHOD_SD, SILENT))
|
||||
return METHOD_SD;
|
||||
else if(ChangeFATInterface(METHOD_USB, SILENT))
|
||||
return METHOD_USB;
|
||||
else if(TestCard(CARD_SLOTA, SILENT))
|
||||
return METHOD_MC_SLOTA;
|
||||
else if(TestCard(CARD_SLOTB, SILENT))
|
||||
return METHOD_MC_SLOTB;
|
||||
else if(ConnectShare (SILENT))
|
||||
return METHOD_SMB;
|
||||
else
|
||||
{
|
||||
WaitPrompt((char*) "Unable to auto-determine save method!");
|
||||
return 0; // no method found
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* UpdateDirName()
|
||||
* Update curent directory name for file browser
|
||||
***************************************************************************/
|
||||
int UpdateDirName(int method)
|
||||
{
|
||||
int size=0;
|
||||
char *test;
|
||||
char temp[1024];
|
||||
|
||||
// update DVD directory (does not utilize 'currentdir')
|
||||
if(method == METHOD_DVD)
|
||||
{
|
||||
dvddir = filelist[selection].offset;
|
||||
dvddirlength = filelist[selection].length;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* current directory doesn't change */
|
||||
if (strcmp(filelist[selection].filename,".") == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* go up to parent directory */
|
||||
else if (strcmp(filelist[selection].filename,"..") == 0)
|
||||
{
|
||||
/* determine last subdirectory namelength */
|
||||
sprintf(temp,"%s",currentdir);
|
||||
test = strtok(temp,"/");
|
||||
while (test != NULL)
|
||||
{
|
||||
size = strlen(test);
|
||||
test = strtok(NULL,"/");
|
||||
}
|
||||
|
||||
/* remove last subdirectory name */
|
||||
size = strlen(currentdir) - size - 1;
|
||||
currentdir[size] = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* Open a directory */
|
||||
else
|
||||
{
|
||||
/* test new directory namelength */
|
||||
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
|
||||
{
|
||||
/* update current directory name */
|
||||
sprintf(currentdir, "%s/%s",currentdir, filelist[selection].filename);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitPrompt((char*)"Directory name is too long !");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* FileSortCallback
|
||||
*
|
||||
* Quick sort callback to sort file entries with the following order:
|
||||
* .
|
||||
* ..
|
||||
* <dirs>
|
||||
* <files>
|
||||
***************************************************************************/
|
||||
int FileSortCallback(const void *f1, const void *f2)
|
||||
{
|
||||
/* Special case for implicit directories */
|
||||
if(((FILEENTRIES *)f1)->filename[0] == '.' || ((FILEENTRIES *)f2)->filename[0] == '.')
|
||||
{
|
||||
if(strcmp(((FILEENTRIES *)f1)->filename, ".") == 0) { return -1; }
|
||||
if(strcmp(((FILEENTRIES *)f2)->filename, ".") == 0) { return 1; }
|
||||
if(strcmp(((FILEENTRIES *)f1)->filename, "..") == 0) { return -1; }
|
||||
if(strcmp(((FILEENTRIES *)f2)->filename, "..") == 0) { return 1; }
|
||||
}
|
||||
|
||||
/* If one is a file and one is a directory the directory is first. */
|
||||
if(((FILEENTRIES *)f1)->flags && !(((FILEENTRIES *)f2)->flags)) return -1;
|
||||
if(!(((FILEENTRIES *)f1)->flags) && ((FILEENTRIES *)f2)->flags) return 1;
|
||||
|
||||
return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* StripExt
|
||||
*
|
||||
* Strips an extension from a filename
|
||||
***************************************************************************/
|
||||
|
||||
void StripExt(char* returnstring, char * inputstring)
|
||||
{
|
||||
char* loc_dot;
|
||||
|
||||
strcpy (returnstring, inputstring);
|
||||
loc_dot = strrchr(returnstring,'.');
|
||||
if (loc_dot != NULL)
|
||||
*loc_dot = '\0'; // strip file extension
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* FileSelector
|
||||
*
|
||||
* Let user select a file from the listing
|
||||
***************************************************************************/
|
||||
int FileSelector (int method)
|
||||
{
|
||||
u32 p = 0;
|
||||
u32 wp = 0;
|
||||
u32 ph = 0;
|
||||
u32 wh = 0;
|
||||
signed char gc_ay = 0;
|
||||
signed char gc_sx = 0;
|
||||
signed char wm_ay = 0;
|
||||
signed char wm_sx = 0;
|
||||
|
||||
int haverom = 0;
|
||||
int redraw = 1;
|
||||
int selectit = 0;
|
||||
|
||||
int scroll_delay = 0;
|
||||
bool move_selection = 0;
|
||||
#define SCROLL_INITIAL_DELAY 15
|
||||
#define SCROLL_LOOP_DELAY 2
|
||||
|
||||
while (haverom == 0)
|
||||
{
|
||||
if (redraw)
|
||||
ShowFiles (filelist, maxfiles, offset, selection);
|
||||
redraw = 0;
|
||||
|
||||
VIDEO_WaitVSync(); // slow things down a bit so we don't overread the pads
|
||||
|
||||
gc_ay = PAD_StickY (0);
|
||||
gc_sx = PAD_SubStickX (0);
|
||||
|
||||
p = PAD_ButtonsDown (0);
|
||||
ph = PAD_ButtonsHeld (0);
|
||||
#ifdef HW_RVL
|
||||
wm_ay = WPAD_StickY (0, 0);
|
||||
wm_sx = WPAD_StickX (0, 1);
|
||||
|
||||
wp = WPAD_ButtonsDown (0);
|
||||
wh = WPAD_ButtonsHeld (0);
|
||||
#endif
|
||||
|
||||
/*** Check for exit combo ***/
|
||||
if ( (gc_sx < -70) || (wm_sx < -70) || (wp & WPAD_BUTTON_HOME) || (wp & WPAD_CLASSIC_BUTTON_HOME) )
|
||||
return 0;
|
||||
|
||||
/*** Check buttons, perform actions ***/
|
||||
if ( (p & PAD_BUTTON_A) || selectit || (wp & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) )
|
||||
{
|
||||
if ( selectit )
|
||||
selectit = 0;
|
||||
if (filelist[selection].flags) // This is directory
|
||||
{
|
||||
/* update current directory and set new entry list if directory has changed */
|
||||
int status = UpdateDirName(method);
|
||||
if (status == 1) // ok, open directory
|
||||
{
|
||||
switch (method)
|
||||
{
|
||||
case METHOD_SD:
|
||||
case METHOD_USB:
|
||||
maxfiles = ParseFATdirectory(method);
|
||||
break;
|
||||
|
||||
case METHOD_DVD:
|
||||
maxfiles = ParseDVDdirectory();
|
||||
break;
|
||||
|
||||
case METHOD_SMB:
|
||||
maxfiles = ParseSMBdirectory();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!maxfiles)
|
||||
{
|
||||
WaitPrompt ((char*) "Error reading directory !");
|
||||
haverom = 1; // quit menu
|
||||
}
|
||||
}
|
||||
else if (status == -1) // directory name too long
|
||||
{
|
||||
haverom = 1; // quit menu
|
||||
}
|
||||
}
|
||||
else // this is a file
|
||||
{
|
||||
// store the filename (w/o ext) - used for sram/freeze naming
|
||||
StripExt(ROMFilename, filelist[selection].filename);
|
||||
|
||||
ShowAction ((char *)"Loading...");
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case METHOD_SD:
|
||||
case METHOD_USB:
|
||||
ROMSize = LoadFATFile (filelist[selection].filename, filelist[selection].length);
|
||||
break;
|
||||
|
||||
case METHOD_DVD:
|
||||
dvddir = filelist[selection].offset;
|
||||
dvddirlength = filelist[selection].length;
|
||||
//ROMSize = LoadDVDFile (Memory.ROM);
|
||||
break;
|
||||
|
||||
case METHOD_SMB:
|
||||
//ROMSize = LoadSMBFile (filelist[selection].filename, filelist[selection].length);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ROMSize > 0)
|
||||
{
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitPrompt((char*) "Error loading ROM!");
|
||||
}
|
||||
}
|
||||
redraw = 1;
|
||||
} // End of A
|
||||
if ( (p & PAD_BUTTON_B) || (wp & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)) )
|
||||
{
|
||||
while ( (PAD_ButtonsDown(0) & PAD_BUTTON_B)
|
||||
#ifdef HW_RVL
|
||||
|| (WPAD_ButtonsDown(0) & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B))
|
||||
#endif
|
||||
)
|
||||
VIDEO_WaitVSync();
|
||||
if ( strcmp(filelist[0].filename,"..") == 0 )
|
||||
{
|
||||
selection = 0;
|
||||
selectit = 1;
|
||||
}
|
||||
else if ( strcmp(filelist[1].filename,"..") == 0 )
|
||||
{
|
||||
selection = selectit = 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} // End of B
|
||||
if ( ((p | ph) & PAD_BUTTON_DOWN) || ((wp | wh) & (WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN)) || (gc_ay < -PADCAL) || (wm_ay < -PADCAL) )
|
||||
{
|
||||
if ( (p & PAD_BUTTON_DOWN) || (wp & (WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN)) ) { /*** Button just pressed ***/
|
||||
scroll_delay = SCROLL_INITIAL_DELAY; // reset scroll delay.
|
||||
move_selection = 1; //continue (move selection)
|
||||
}
|
||||
else if (scroll_delay == 0) { /*** Button is held ***/
|
||||
scroll_delay = SCROLL_LOOP_DELAY;
|
||||
move_selection = 1; //continue (move selection)
|
||||
} else {
|
||||
scroll_delay--; // wait
|
||||
}
|
||||
|
||||
if (move_selection)
|
||||
{
|
||||
selection++;
|
||||
if (selection == maxfiles)
|
||||
selection = offset = 0;
|
||||
if ((selection - offset) >= PAGESIZE)
|
||||
offset += PAGESIZE;
|
||||
redraw = 1;
|
||||
move_selection = 0;
|
||||
}
|
||||
} // End of down
|
||||
if ( ((p | ph) & PAD_BUTTON_UP) || ((wp | wh) & (WPAD_BUTTON_UP | WPAD_CLASSIC_BUTTON_UP)) || (gc_ay > PADCAL) || (wm_ay > PADCAL) )
|
||||
{
|
||||
if ( (p & PAD_BUTTON_UP) || (wp & (WPAD_BUTTON_UP | WPAD_CLASSIC_BUTTON_UP)) ) { /*** Button just pressed***/
|
||||
scroll_delay = SCROLL_INITIAL_DELAY; // reset scroll delay.
|
||||
move_selection = 1; //continue (move selection)
|
||||
}
|
||||
else if (scroll_delay == 0) { /*** Button is held ***/
|
||||
scroll_delay = SCROLL_LOOP_DELAY;
|
||||
move_selection = 1; //continue (move selection)
|
||||
} else {
|
||||
scroll_delay--; // wait
|
||||
}
|
||||
|
||||
if (move_selection)
|
||||
{
|
||||
selection--;
|
||||
if (selection < 0) {
|
||||
selection = maxfiles - 1;
|
||||
offset = selection - PAGESIZE + 1;
|
||||
}
|
||||
if (selection < offset)
|
||||
offset -= PAGESIZE;
|
||||
if (offset < 0)
|
||||
offset = 0;
|
||||
redraw = 1;
|
||||
move_selection = 0;
|
||||
}
|
||||
} // End of Up
|
||||
if ( (p & PAD_BUTTON_LEFT) || (wp & (WPAD_BUTTON_LEFT | WPAD_CLASSIC_BUTTON_LEFT)) )
|
||||
{
|
||||
/*** Go back a page ***/
|
||||
selection -= PAGESIZE;
|
||||
if (selection < 0)
|
||||
{
|
||||
selection = maxfiles - 1;
|
||||
offset = selection - PAGESIZE + 1;
|
||||
}
|
||||
if (selection < offset)
|
||||
offset -= PAGESIZE;
|
||||
if (offset < 0)
|
||||
offset = 0;
|
||||
redraw = 1;
|
||||
}
|
||||
if ( (p & PAD_BUTTON_RIGHT) || (wp & (WPAD_BUTTON_RIGHT | WPAD_CLASSIC_BUTTON_RIGHT)) )
|
||||
{
|
||||
/*** Go forward a page ***/
|
||||
selection += PAGESIZE;
|
||||
if (selection > maxfiles - 1)
|
||||
selection = offset = 0;
|
||||
if ((selection - offset) >= PAGESIZE)
|
||||
offset += PAGESIZE;
|
||||
redraw = 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* OpenDVD
|
||||
*
|
||||
* Function to load a DVD directory and display to user.
|
||||
***************************************************************************/
|
||||
int
|
||||
OpenDVD (int method)
|
||||
{
|
||||
if (!getpvd())
|
||||
{
|
||||
ShowAction((char*) "Loading DVD...");
|
||||
#ifdef HW_DOL
|
||||
DVD_Mount(); // mount the DVD unit again
|
||||
#elif WII_DVD
|
||||
u32 val;
|
||||
DI_GetCoverRegister(&val);
|
||||
if(val & 0x1) // True if no disc inside, use (val & 0x2) for true if disc inside.
|
||||
{
|
||||
WaitPrompt((char *)"No disc inserted!");
|
||||
return 0;
|
||||
}
|
||||
DI_Mount();
|
||||
while(DI_GetStatus() & DVD_INIT);
|
||||
#endif
|
||||
|
||||
if (!getpvd())
|
||||
{
|
||||
WaitPrompt ((char *)"Invalid DVD.");
|
||||
return 0; // not a ISO9660 DVD
|
||||
}
|
||||
}
|
||||
|
||||
maxfiles = ParseDVDdirectory(); // load root folder
|
||||
|
||||
// switch to rom folder
|
||||
SwitchDVDFolder(GCSettings.LoadFolder);
|
||||
|
||||
if (maxfiles > 0)
|
||||
{
|
||||
return FileSelector (method);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no entries found
|
||||
WaitPrompt ((char *)"No Files Found!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* OpenSMB
|
||||
*
|
||||
* Function to load from an SMB share
|
||||
***************************************************************************/
|
||||
int
|
||||
OpenSMB (int method)
|
||||
{
|
||||
// Connect to network share
|
||||
if(ConnectShare (NOTSILENT))
|
||||
{
|
||||
// change current dir to root dir
|
||||
sprintf(currentdir, "/%s", GCSettings.LoadFolder);
|
||||
|
||||
maxfiles = ParseSMBdirectory ();
|
||||
if (maxfiles > 0)
|
||||
{
|
||||
return FileSelector (method);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no entries found
|
||||
WaitPrompt ((char *)"No Files Found!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* OpenFAT
|
||||
*
|
||||
* Function to load from FAT
|
||||
***************************************************************************/
|
||||
int
|
||||
OpenFAT (int method)
|
||||
{
|
||||
if(ChangeFATInterface(method, NOTSILENT))
|
||||
{
|
||||
// change current dir to snes roms directory
|
||||
sprintf ( currentdir, "%s/%s", ROOTFATDIR, GCSettings.LoadFolder );
|
||||
|
||||
// Parse initial root directory and get entries list
|
||||
maxfiles = ParseFATdirectory (method);
|
||||
if (maxfiles > 0)
|
||||
{
|
||||
// Select an entry
|
||||
return FileSelector (method);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no entries found
|
||||
WaitPrompt ((char *)"No Files Found!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* OpenROM
|
||||
* Opens device specified by method, displays a list of ROMS
|
||||
***************************************************************************/
|
||||
|
||||
int
|
||||
OpenROM (int method)
|
||||
{
|
||||
int loadROM = 0;
|
||||
|
||||
if(method == METHOD_AUTO)
|
||||
method = autoLoadMethod();
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case METHOD_SD:
|
||||
case METHOD_USB:
|
||||
loadROM = OpenFAT (method);
|
||||
break;
|
||||
case METHOD_DVD:
|
||||
// Load from DVD
|
||||
loadROM = OpenDVD (method);
|
||||
break;
|
||||
case METHOD_SMB:
|
||||
// Load from Network (SMB)
|
||||
loadROM = OpenSMB (method);
|
||||
break;
|
||||
}
|
||||
|
||||
return loadROM;
|
||||
}
|
39
source/ngc/filesel.h
Normal file
39
source/ngc/filesel.h
Normal file
@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May 2007
|
||||
* Tantric August 2008
|
||||
*
|
||||
* filesel.h
|
||||
*
|
||||
* Generic file routines - reading, writing, browsing
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _NGCFILESEL_
|
||||
#define _NGCFILESEL_
|
||||
|
||||
#define SAVEBUFFERSIZE ((512 * 1024) + 2048 + 64 + 4 + 4)
|
||||
#define MAXJOLIET 255
|
||||
#define MAXDISPLAY 54
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 offset;
|
||||
unsigned int length;
|
||||
char flags;
|
||||
char filename[MAXJOLIET + 1];
|
||||
char displayname[MAXDISPLAY + 1];
|
||||
} FILEENTRIES;
|
||||
|
||||
#define MAXFILES 2000 // Restrict to 2000 files per dir
|
||||
extern FILEENTRIES filelist[MAXFILES];
|
||||
|
||||
void ClearSaveBuffer ();
|
||||
int OpenROM (int method);
|
||||
int autoLoadMethod();
|
||||
int autoSaveMethod();
|
||||
int FileSortCallback(const void *f1, const void *f2);
|
||||
void StripExt(char* returnstring, char * inputstring);
|
||||
|
||||
#endif
|
12
source/ngc/fontface.s
Normal file
12
source/ngc/fontface.s
Normal file
@ -0,0 +1,12 @@
|
||||
# Fonts
|
||||
|
||||
.rodata
|
||||
.globl fontface
|
||||
.balign 32
|
||||
fontface:
|
||||
.incbin "../source/ngc/ttf/font.ttf"
|
||||
|
||||
|
||||
.globl fontsize
|
||||
fontsize: .long 28736
|
||||
|
@ -1,302 +0,0 @@
|
||||
/****************************************************************************
|
||||
* VisualBoyAdvance 1.7.2
|
||||
*
|
||||
* Nintendo GameCube Joypad Wrapper
|
||||
****************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#define VBA_BUTTON_A 1
|
||||
#define VBA_BUTTON_B 2
|
||||
#define VBA_BUTTON_SELECT 4
|
||||
#define VBA_BUTTON_START 8
|
||||
#define VBA_RIGHT 16
|
||||
#define VBA_LEFT 32
|
||||
#define VBA_UP 64
|
||||
#define VBA_DOWN 128
|
||||
#define VBA_BUTTON_R 256
|
||||
#define VBA_BUTTON_L 512
|
||||
#define VBA_SPEED 1024
|
||||
#define VBA_CAPTURE 2048
|
||||
|
||||
#ifdef WII_BUILD
|
||||
#include <math.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
int isClassicAvailable = 0;
|
||||
int isWiimoteAvailable = 0;
|
||||
/*
|
||||
#ifndef PI
|
||||
#define PI 3.14159f
|
||||
#endif
|
||||
|
||||
enum { STICK_X, STICK_Y };
|
||||
static int getStickValue(joystick_t* j, int axis, int maxAbsValue){
|
||||
double angle = PI * j->ang/180.0f;
|
||||
double magnitude = (j->mag > 1.0f) ? 1.0f :
|
||||
(j->mag < -1.0f) ? -1.0f : j->mag;
|
||||
double value;
|
||||
if(axis == STICK_X)
|
||||
value = magnitude * sin( angle );
|
||||
else
|
||||
value = magnitude * cos( angle );
|
||||
return (int)(value * maxAbsValue);
|
||||
}*/
|
||||
|
||||
#endif
|
||||
int menuCalled = 0;
|
||||
u32
|
||||
NGCPad()
|
||||
{
|
||||
u32 res = 0;
|
||||
short p;
|
||||
signed char x,
|
||||
y;
|
||||
int padcal = 90;
|
||||
float t;
|
||||
|
||||
#ifdef WII_BUILD
|
||||
//wiimote
|
||||
WPADData *wpad;
|
||||
WPAD_ScanPads();
|
||||
wpad = WPAD_Data(0);
|
||||
if (isWiimoteAvailable)
|
||||
{
|
||||
unsigned short b = wpad->btns_h;
|
||||
|
||||
if (b & WPAD_BUTTON_2)
|
||||
res |= VBA_BUTTON_A;
|
||||
|
||||
if (b & WPAD_BUTTON_1)
|
||||
res |= VBA_BUTTON_B;
|
||||
|
||||
if (b & WPAD_BUTTON_MINUS)
|
||||
res |= VBA_BUTTON_SELECT;
|
||||
|
||||
if (b & WPAD_BUTTON_PLUS)
|
||||
res |= VBA_BUTTON_START;
|
||||
|
||||
if (b & WPAD_BUTTON_RIGHT)
|
||||
res |= VBA_UP;
|
||||
|
||||
if (b & WPAD_BUTTON_LEFT)
|
||||
res |= VBA_DOWN;
|
||||
|
||||
if (b & WPAD_BUTTON_UP)
|
||||
res |= VBA_LEFT;
|
||||
|
||||
if (b & WPAD_BUTTON_DOWN)
|
||||
res |= VBA_RIGHT;
|
||||
|
||||
if (b & WPAD_BUTTON_A)
|
||||
res |= VBA_BUTTON_L;
|
||||
|
||||
if (b & WPAD_BUTTON_B)
|
||||
res |= VBA_BUTTON_R;
|
||||
|
||||
if (b & WPAD_BUTTON_HOME)
|
||||
menuCalled = 1;
|
||||
}
|
||||
//classic controller
|
||||
if (isClassicAvailable)
|
||||
{
|
||||
float mag,ang;
|
||||
int b = wpad->exp.classic.btns;
|
||||
ang = wpad->exp.classic.ljs.ang;
|
||||
mag = wpad->exp.classic.ljs.mag;
|
||||
|
||||
if (mag > 0.4) {
|
||||
if (ang > 292.5 | ang <= 67.5)
|
||||
res |= VBA_UP;
|
||||
if (ang > 22.5 & ang <= 157.5)
|
||||
res |= VBA_RIGHT;
|
||||
if (ang > 113.5 & ang <= 247.5)
|
||||
res |= VBA_DOWN;
|
||||
if (ang > 203.5 & ang <= 337.5)
|
||||
res |= VBA_LEFT;
|
||||
}
|
||||
|
||||
int x_s = 0; //getStickValue(&wpad.exp.classic.ljs, STICK_X, 127);
|
||||
int y_s = 0; //getStickValue(&wpad.exp.classic.ljs, STICK_Y, 127);
|
||||
if (b & CLASSIC_CTRL_BUTTON_A)
|
||||
res |= VBA_BUTTON_A;
|
||||
|
||||
if (b & CLASSIC_CTRL_BUTTON_B)
|
||||
res |= VBA_BUTTON_B;
|
||||
|
||||
if (b & CLASSIC_CTRL_BUTTON_MINUS)
|
||||
res |= VBA_BUTTON_SELECT;
|
||||
|
||||
if (b & CLASSIC_CTRL_BUTTON_PLUS)
|
||||
res |= VBA_BUTTON_START;
|
||||
|
||||
if ((b & CLASSIC_CTRL_BUTTON_UP) || (y_s > 0))
|
||||
res |= VBA_UP;
|
||||
|
||||
if ((b & CLASSIC_CTRL_BUTTON_DOWN) || (y_s < 0))
|
||||
res |= VBA_DOWN;
|
||||
|
||||
if ((b & CLASSIC_CTRL_BUTTON_LEFT) || (x_s < 0))
|
||||
res |= VBA_LEFT;
|
||||
|
||||
if ((b & CLASSIC_CTRL_BUTTON_RIGHT) || (x_s > 0))
|
||||
res |= VBA_RIGHT;
|
||||
|
||||
if (b & CLASSIC_CTRL_BUTTON_FULL_L)
|
||||
res |= VBA_BUTTON_L;
|
||||
|
||||
if (b & CLASSIC_CTRL_BUTTON_FULL_R)
|
||||
res |= VBA_BUTTON_R;
|
||||
|
||||
if (b & CLASSIC_CTRL_BUTTON_HOME)
|
||||
menuCalled = 1;
|
||||
|
||||
}
|
||||
//user needs a GC remote
|
||||
PAD_ScanPads();
|
||||
p = PAD_ButtonsHeld(0);
|
||||
x = PAD_StickX(0);
|
||||
y = PAD_StickY(0);
|
||||
if (x * x + y * y > padcal * padcal)
|
||||
{
|
||||
if (x > 0 && y == 0)
|
||||
res |= VBA_RIGHT;
|
||||
if (x < 0 && y == 0)
|
||||
res |= VBA_LEFT;
|
||||
if (x == 0 && y > 0)
|
||||
res |= VBA_UP;
|
||||
if (x == 0 && y < 0)
|
||||
res |= VBA_DOWN;
|
||||
|
||||
/*** Recalc left / right ***/
|
||||
t = (float) y / x;
|
||||
if (t >= -2.41421356237 && t < 2.41421356237)
|
||||
{
|
||||
if (x >= 0)
|
||||
res |= VBA_RIGHT;
|
||||
else
|
||||
res |= VBA_LEFT;
|
||||
}
|
||||
|
||||
/*** Recalc up / down ***/
|
||||
t = (float) x / y;
|
||||
if (t >= -2.41421356237 && t < 2.41421356237)
|
||||
{
|
||||
if (y >= 0)
|
||||
res |= VBA_UP;
|
||||
else
|
||||
res |= VBA_DOWN;
|
||||
}
|
||||
}
|
||||
if (p & PAD_BUTTON_A)
|
||||
res |= VBA_BUTTON_A;
|
||||
|
||||
if (p & PAD_BUTTON_B)
|
||||
res |= VBA_BUTTON_B;
|
||||
|
||||
if (p & PAD_TRIGGER_Z)
|
||||
res |= VBA_BUTTON_SELECT;
|
||||
|
||||
if (p & PAD_BUTTON_START)
|
||||
res |= VBA_BUTTON_START;
|
||||
|
||||
if (p & PAD_BUTTON_UP)
|
||||
res |= VBA_UP;
|
||||
|
||||
if (p & PAD_BUTTON_DOWN)
|
||||
res |= VBA_DOWN;
|
||||
|
||||
if (p & PAD_BUTTON_LEFT)
|
||||
res |= VBA_LEFT;
|
||||
|
||||
if (p & PAD_BUTTON_RIGHT)
|
||||
res |= VBA_RIGHT;
|
||||
|
||||
if (p & PAD_TRIGGER_L)
|
||||
res |= VBA_BUTTON_L;
|
||||
|
||||
if (p & PAD_TRIGGER_R)
|
||||
res |= VBA_BUTTON_R;
|
||||
|
||||
if((p & PAD_BUTTON_X) && (p & PAD_BUTTON_Y))
|
||||
menuCalled = 1;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef GC_BUILD
|
||||
p = PAD_ButtonsHeld(0);
|
||||
x = PAD_StickX(0);
|
||||
y = PAD_StickY(0);
|
||||
if (x * x + y * y > padcal * padcal)
|
||||
{
|
||||
if (x > 0 && y == 0)
|
||||
res |= VBA_RIGHT;
|
||||
if (x < 0 && y == 0)
|
||||
res |= VBA_LEFT;
|
||||
if (x == 0 && y > 0)
|
||||
res |= VBA_UP;
|
||||
if (x == 0 && y < 0)
|
||||
res |= VBA_DOWN;
|
||||
|
||||
/*** Recalc left / right ***/
|
||||
t = (float) y / x;
|
||||
if (t >= -2.41421356237 && t < 2.41421356237)
|
||||
{
|
||||
if (x >= 0)
|
||||
res |= VBA_RIGHT;
|
||||
else
|
||||
res |= VBA_LEFT;
|
||||
}
|
||||
|
||||
/*** Recalc up / down ***/
|
||||
t = (float) x / y;
|
||||
if (t >= -2.41421356237 && t < 2.41421356237)
|
||||
{
|
||||
if (y >= 0)
|
||||
res |= VBA_UP;
|
||||
else
|
||||
res |= VBA_DOWN;
|
||||
}
|
||||
}
|
||||
if (p & PAD_BUTTON_A)
|
||||
res |= VBA_BUTTON_A;
|
||||
|
||||
if (p & PAD_BUTTON_B)
|
||||
res |= VBA_BUTTON_B;
|
||||
|
||||
if (p & PAD_TRIGGER_Z)
|
||||
res |= VBA_BUTTON_SELECT;
|
||||
|
||||
if (p & PAD_BUTTON_START)
|
||||
res |= VBA_BUTTON_START;
|
||||
|
||||
if ((p & PAD_BUTTON_UP))
|
||||
res |= VBA_UP;
|
||||
|
||||
if ((p & PAD_BUTTON_DOWN))
|
||||
res |= VBA_DOWN;
|
||||
|
||||
if ((p & PAD_BUTTON_LEFT))
|
||||
res |= VBA_LEFT;
|
||||
|
||||
if ((p & PAD_BUTTON_RIGHT))
|
||||
res |= VBA_RIGHT;
|
||||
|
||||
if (p & PAD_TRIGGER_L)
|
||||
res |= VBA_BUTTON_L;
|
||||
|
||||
if (p & PAD_TRIGGER_R)
|
||||
res |= VBA_BUTTON_R;
|
||||
|
||||
if((p & PAD_BUTTON_X) && (p & PAD_BUTTON_Y))
|
||||
menuCalled = 1;
|
||||
#endif
|
||||
|
||||
if ((res & 48) == 48)
|
||||
res &= ~16;
|
||||
if ((res & 192) == 192)
|
||||
res &= ~128;
|
||||
|
||||
return res;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
/****************************************************************************
|
||||
* VisualBoyAdvance 1.7.2
|
||||
*
|
||||
* Nintendo GameCube Joypad Wrapper
|
||||
****************************************************************************/
|
||||
#ifndef __NGCPADH__
|
||||
#define __NGCPADH__
|
||||
|
||||
u32 NGCPad();
|
||||
|
||||
#endif
|
230
source/ngc/gcunzip.cpp
Normal file
230
source/ngc/gcunzip.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* Tantric September 2008
|
||||
*
|
||||
* unzip.cpp
|
||||
*
|
||||
* File unzip routines
|
||||
***************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "dvd.h"
|
||||
#include "smbop.h"
|
||||
#include "video.h"
|
||||
#include "menudraw.h"
|
||||
#include "gcunzip.h"
|
||||
|
||||
/*
|
||||
* PKWare Zip Header - adopted into zip standard
|
||||
*/
|
||||
#define PKZIPID 0x504b0304
|
||||
#define MAXROM 0x500000
|
||||
#define ZIPCHUNK 2048
|
||||
|
||||
/*
|
||||
* Zip files are stored little endian
|
||||
* Support functions for short and int types
|
||||
*/
|
||||
u32
|
||||
FLIP32 (u32 b)
|
||||
{
|
||||
unsigned int c;
|
||||
|
||||
c = (b & 0xff000000) >> 24;
|
||||
c |= (b & 0xff0000) >> 8;
|
||||
c |= (b & 0xff00) << 8;
|
||||
c |= (b & 0xff) << 24;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
u16
|
||||
FLIP16 (u16 b)
|
||||
{
|
||||
u16 c;
|
||||
|
||||
c = (b & 0xff00) >> 8;
|
||||
c |= (b & 0xff) << 8;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* IsZipFile
|
||||
*
|
||||
* Returns TRUE when PKZIPID is first four characters of buffer
|
||||
****************************************************************************/
|
||||
int
|
||||
IsZipFile (char *buffer)
|
||||
{
|
||||
unsigned int *check;
|
||||
|
||||
check = (unsigned int *) buffer;
|
||||
|
||||
if (check[0] == PKZIPID)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* unzip
|
||||
*
|
||||
* It should be noted that there is a limit of 5MB total size for any ROM
|
||||
******************************************************************************/
|
||||
FILE* fatfile; // FAT
|
||||
u64 discoffset; // DVD
|
||||
SMBFILE smbfile; // SMB
|
||||
|
||||
int
|
||||
UnZipBuffer (unsigned char *outbuffer, short where)
|
||||
{
|
||||
PKZIPHEADER pkzip;
|
||||
int zipoffset = 0;
|
||||
int zipchunk = 0;
|
||||
char out[ZIPCHUNK];
|
||||
z_stream zs;
|
||||
int res;
|
||||
int bufferoffset = 0;
|
||||
int readoffset = 0;
|
||||
int have = 0;
|
||||
char readbuffer[ZIPCHUNK];
|
||||
char msg[128];
|
||||
|
||||
/*** Read Zip Header ***/
|
||||
switch (where)
|
||||
{
|
||||
case 0: // SD Card
|
||||
fseek(fatfile, 0, SEEK_SET);
|
||||
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
||||
break;
|
||||
|
||||
case 1: // DVD
|
||||
dvd_read (readbuffer, ZIPCHUNK, discoffset);
|
||||
break;
|
||||
|
||||
case 2: // From SMB
|
||||
SMB_ReadFile(readbuffer, ZIPCHUNK, 0, smbfile);
|
||||
break;
|
||||
}
|
||||
|
||||
/*** Copy PKZip header to local, used as info ***/
|
||||
memcpy (&pkzip, readbuffer, sizeof (PKZIPHEADER));
|
||||
|
||||
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
|
||||
|
||||
sprintf (msg, "Unzipping %d bytes ... Wait",
|
||||
pkzip.uncompressedSize);
|
||||
ShowAction (msg);
|
||||
|
||||
/*** Prepare the zip stream ***/
|
||||
memset (&zs, 0, sizeof (z_stream));
|
||||
zs.zalloc = Z_NULL;
|
||||
zs.zfree = Z_NULL;
|
||||
zs.opaque = Z_NULL;
|
||||
zs.avail_in = 0;
|
||||
zs.next_in = Z_NULL;
|
||||
res = inflateInit2 (&zs, -MAX_WBITS);
|
||||
|
||||
if (res != Z_OK)
|
||||
return 0;
|
||||
|
||||
/*** Set ZipChunk for first pass ***/
|
||||
zipoffset =
|
||||
(sizeof (PKZIPHEADER) + FLIP16 (pkzip.filenameLength) +
|
||||
FLIP16 (pkzip.extraDataLength));
|
||||
zipchunk = ZIPCHUNK - zipoffset;
|
||||
|
||||
/*** Now do it! ***/
|
||||
do
|
||||
{
|
||||
zs.avail_in = zipchunk;
|
||||
zs.next_in = (Bytef *) & readbuffer[zipoffset];
|
||||
|
||||
/*** Now inflate until input buffer is exhausted ***/
|
||||
do
|
||||
{
|
||||
zs.avail_out = ZIPCHUNK;
|
||||
zs.next_out = (Bytef *) & out;
|
||||
|
||||
res = inflate (&zs, Z_NO_FLUSH);
|
||||
|
||||
if (res == Z_MEM_ERROR)
|
||||
{
|
||||
inflateEnd (&zs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
have = ZIPCHUNK - zs.avail_out;
|
||||
if (have)
|
||||
{
|
||||
/*** Copy to normal block buffer ***/
|
||||
memcpy (&outbuffer[bufferoffset], &out, have);
|
||||
bufferoffset += have;
|
||||
}
|
||||
}
|
||||
while (zs.avail_out == 0);
|
||||
|
||||
/*** Readup the next 2k block ***/
|
||||
zipoffset = 0;
|
||||
zipchunk = ZIPCHUNK;
|
||||
|
||||
switch (where)
|
||||
{
|
||||
case 0: // SD Card
|
||||
fread (readbuffer, 1, ZIPCHUNK, fatfile);
|
||||
break;
|
||||
|
||||
case 1: // DVD
|
||||
readoffset += ZIPCHUNK;
|
||||
dvd_read (readbuffer, ZIPCHUNK, discoffset+readoffset);
|
||||
break;
|
||||
|
||||
case 2: // From SMB
|
||||
readoffset += ZIPCHUNK;
|
||||
SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (res != Z_STREAM_END);
|
||||
|
||||
inflateEnd (&zs);
|
||||
|
||||
if (res == Z_STREAM_END)
|
||||
{
|
||||
if (pkzip.uncompressedSize == (u32) bufferoffset)
|
||||
return bufferoffset;
|
||||
else
|
||||
return pkzip.uncompressedSize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
// Reading from FAT
|
||||
int
|
||||
UnZipFile (unsigned char *outbuffer, FILE* infile)
|
||||
{
|
||||
fatfile = infile;
|
||||
return UnZipBuffer(outbuffer, 0);
|
||||
}
|
||||
// Reading from DVD
|
||||
int
|
||||
UnZipFile (unsigned char *outbuffer, u64 inoffset)
|
||||
{
|
||||
discoffset = inoffset;
|
||||
return UnZipBuffer(outbuffer, 1);
|
||||
}
|
||||
// Reading from SMB
|
||||
int
|
||||
UnZipFile (unsigned char *outbuffer, SMBFILE infile)
|
||||
{
|
||||
smbfile = infile;
|
||||
return UnZipBuffer(outbuffer, 2);
|
||||
}
|
44
source/ngc/gcunzip.h
Normal file
44
source/ngc/gcunzip.h
Normal file
@ -0,0 +1,44 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* Tantric September 2008
|
||||
*
|
||||
* unzip.h
|
||||
*
|
||||
* File unzip routines
|
||||
****************************************************************************/
|
||||
#ifndef _UNZIP_
|
||||
#define _UNZIP_
|
||||
|
||||
#include <smb.h>
|
||||
|
||||
extern int IsZipFile (char *buffer);
|
||||
|
||||
int UnZipFile (unsigned char *outbuffer, FILE* infile); // Reading from FAT
|
||||
int UnZipFile (unsigned char *outbuffer, u64 inoffset); // Reading from DVD
|
||||
int UnZipFile (unsigned char *outbuffer, SMBFILE infile); // Reading from SMB
|
||||
|
||||
/*
|
||||
* Zip file header definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int zipid __attribute__ ((__packed__)); // 0x04034b50
|
||||
unsigned short zipversion __attribute__ ((__packed__));
|
||||
unsigned short zipflags __attribute__ ((__packed__));
|
||||
unsigned short compressionMethod __attribute__ ((__packed__));
|
||||
unsigned short lastmodtime __attribute__ ((__packed__));
|
||||
unsigned short lastmoddate __attribute__ ((__packed__));
|
||||
unsigned int crc32 __attribute__ ((__packed__));
|
||||
unsigned int compressedSize __attribute__ ((__packed__));
|
||||
unsigned int uncompressedSize __attribute__ ((__packed__));
|
||||
unsigned short filenameLength __attribute__ ((__packed__));
|
||||
unsigned short extraDataLength __attribute__ ((__packed__));
|
||||
}
|
||||
PKZIPHEADER;
|
||||
|
||||
u32 FLIP32 (u32 b);
|
||||
u16 FLIP16 (u16 b);
|
||||
|
||||
#endif
|
@ -1,264 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Generic GX Support for Emulators
|
||||
* softdev 2007
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* NGC GX Video Functions
|
||||
*
|
||||
* These are pretty standard functions to setup and use GX scaling.
|
||||
****************************************************************************/
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
/*** External 2D Video ***/
|
||||
extern u32 whichfb;
|
||||
extern u32 *xfb[2];
|
||||
extern GXRModeObj *vmode;
|
||||
|
||||
/*** 3D GX ***/
|
||||
#define DEFAULT_FIFO_SIZE ( 256 * 1024 )
|
||||
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
/*** Texture memory ***/
|
||||
static u8 *texturemem;
|
||||
static int texturesize;
|
||||
|
||||
GXTexObj texobj;
|
||||
static Mtx view;
|
||||
static int vwidth, vheight, oldvwidth, oldvheight;
|
||||
|
||||
#define HASPECT 80
|
||||
#define VASPECT 45
|
||||
|
||||
/* New texture based scaler */
|
||||
typedef struct tagcamera
|
||||
{
|
||||
Vector pos;
|
||||
Vector up;
|
||||
Vector view;
|
||||
}
|
||||
camera;
|
||||
|
||||
/*** Square Matrix
|
||||
This structure controls the size of the image on the screen.
|
||||
Think of the output as a -80 x 80 by -60 x 60 graph.
|
||||
***/
|
||||
static s16 square[] ATTRIBUTE_ALIGN(32) = {
|
||||
/*
|
||||
* X, Y, Z
|
||||
* Values set are for roughly 4:3 aspect
|
||||
*/
|
||||
-HASPECT, VASPECT, 0, // 0
|
||||
HASPECT, VASPECT, 0, // 1
|
||||
HASPECT, -VASPECT, 0, // 2
|
||||
-HASPECT, -VASPECT, 0, // 3
|
||||
};
|
||||
|
||||
static camera cam = { {0.0F, 0.0F, 0.0F},
|
||||
{0.0F, 0.5F, 0.0F},
|
||||
{0.0F, 0.0F, -0.5F}
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Scaler Support Functions
|
||||
****************************************************************************/
|
||||
static void draw_init(void)
|
||||
{
|
||||
GX_ClearVtxDesc();
|
||||
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
|
||||
GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX8);
|
||||
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
||||
|
||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
|
||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
|
||||
GX_SetArray(GX_VA_POS, square, 3 * sizeof(s16));
|
||||
|
||||
GX_SetNumTexGens(1);
|
||||
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||
|
||||
GX_InvalidateTexAll();
|
||||
|
||||
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565,
|
||||
GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
}
|
||||
|
||||
static void draw_vert(u8 pos, u8 c, f32 s, f32 t)
|
||||
{
|
||||
GX_Position1x8(pos);
|
||||
GX_Color1x8(c);
|
||||
GX_TexCoord2f32(s, t);
|
||||
}
|
||||
|
||||
static void draw_square(Mtx v)
|
||||
{
|
||||
Mtx m; // model matrix.
|
||||
Mtx mv; // modelview matrix.
|
||||
|
||||
guMtxIdentity(m);
|
||||
guMtxTransApply(m, m, 0, 0, -100);
|
||||
guMtxConcat(v, m, mv);
|
||||
|
||||
GX_LoadPosMtxImm(mv, GX_PNMTX0);
|
||||
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
||||
draw_vert(0, 0, 0.0, 0.0);
|
||||
draw_vert(1, 0, 1.0, 0.0);
|
||||
draw_vert(2, 0, 1.0, 1.0);
|
||||
draw_vert(3, 0, 0.0, 1.0);
|
||||
GX_End();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* StartGX
|
||||
****************************************************************************/
|
||||
void GX_Start(int width, int height, int haspect, int vaspect)
|
||||
{
|
||||
Mtx p;
|
||||
|
||||
/*** Set new aspect (now with crap AR hack!) ***/
|
||||
square[0] = square[9] = (-haspect - 7);
|
||||
square[3] = square[6] = (haspect + 7);
|
||||
square[1] = square[4] = (vaspect + 7);
|
||||
square[7] = square[10] = (-vaspect - 7);
|
||||
|
||||
/*** Allocate 32byte aligned texture memory ***/
|
||||
texturesize = (width * height) * 2;
|
||||
texturemem = (u8 *) memalign(32, texturesize);
|
||||
|
||||
GXColor gxbackground = { 0, 0, 0, 0xff };
|
||||
|
||||
/*** Clear out FIFO area ***/
|
||||
memset(&gp_fifo, 0, DEFAULT_FIFO_SIZE);
|
||||
|
||||
/*** Initialise GX ***/
|
||||
GX_Init(&gp_fifo, DEFAULT_FIFO_SIZE);
|
||||
GX_SetCopyClear(gxbackground, 0x00ffffff);
|
||||
|
||||
GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
||||
GX_SetDispCopyYScale((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
|
||||
GX_SetScissor(0, 0, vmode->fbWidth, vmode->efbHeight);
|
||||
GX_SetDispCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight);
|
||||
GX_SetDispCopyDst(vmode->fbWidth, vmode->xfbHeight);
|
||||
GX_SetCopyFilter(vmode->aa, vmode->sample_pattern, GX_TRUE,
|
||||
vmode->vfilter);
|
||||
GX_SetFieldMode(vmode->field_rendering,
|
||||
((vmode->viHeight ==
|
||||
2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
|
||||
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
||||
GX_SetCullMode(GX_CULL_NONE);
|
||||
GX_CopyDisp(xfb[whichfb ^ 1], GX_TRUE);
|
||||
GX_SetDispCopyGamma(GX_GM_1_0);
|
||||
|
||||
guPerspective(p, 60, 1.33F, 10.0F, 1000.0F);
|
||||
GX_LoadProjectionMtx(p, GX_PERSPECTIVE);
|
||||
memset(texturemem, 0, texturesize);
|
||||
|
||||
/*** Setup for first call to scaler ***/
|
||||
vwidth = vheight = -1;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* GX_Render
|
||||
*
|
||||
* Pass in a buffer, width and height to update as a tiled RGB565 texture
|
||||
****************************************************************************/
|
||||
void GX_Render(int width, int height, u8 * buffer, int pitch)
|
||||
{
|
||||
int h, w;
|
||||
long long int *dst = (long long int *) texturemem;
|
||||
long long int *src1 = (long long int *) buffer;
|
||||
long long int *src2 = (long long int *) (buffer + pitch);
|
||||
long long int *src3 = (long long int *) (buffer + (pitch * 2));
|
||||
long long int *src4 = (long long int *) (buffer + (pitch * 3));
|
||||
int rowpitch = (pitch >> 3) * 3;
|
||||
int rowadjust = ( pitch % 8 ) * 4;
|
||||
char *ra = NULL;
|
||||
|
||||
vwidth = width;
|
||||
vheight = height;
|
||||
|
||||
whichfb ^= 1;
|
||||
|
||||
if ((oldvheight != vheight) || (oldvwidth != vwidth))
|
||||
{
|
||||
/** Update scaling **/
|
||||
oldvwidth = vwidth;
|
||||
oldvheight = vheight;
|
||||
draw_init();
|
||||
memset(&view, 0, sizeof(Mtx));
|
||||
guLookAt(view, &cam.pos, &cam.up, &cam.view);
|
||||
GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
||||
|
||||
}
|
||||
|
||||
GX_InvVtxCache();
|
||||
GX_InvalidateTexAll();
|
||||
GX_SetTevOp(GX_TEVSTAGE0, GX_DECAL);
|
||||
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
|
||||
|
||||
for (h = 0; h < vheight; h += 4)
|
||||
{
|
||||
|
||||
for (w = 0; w < (vwidth >> 2); w++)
|
||||
{
|
||||
*dst++ = *src1++;
|
||||
*dst++ = *src2++;
|
||||
*dst++ = *src3++;
|
||||
*dst++ = *src4++;
|
||||
}
|
||||
|
||||
src1 += rowpitch;
|
||||
src2 += rowpitch;
|
||||
src3 += rowpitch;
|
||||
src4 += rowpitch;
|
||||
|
||||
if ( rowadjust )
|
||||
{
|
||||
ra = (char *)src1;
|
||||
src1 = (long long int *)(ra + rowadjust);
|
||||
ra = (char *)src2;
|
||||
src2 = (long long int *)(ra + rowadjust);
|
||||
ra = (char *)src3;
|
||||
src3 = (long long int *)(ra + rowadjust);
|
||||
ra = (char *)src4;
|
||||
src4 = (long long int *)(ra + rowadjust);
|
||||
}
|
||||
}
|
||||
|
||||
DCFlushRange(texturemem, texturesize);
|
||||
|
||||
GX_SetNumChans(1);
|
||||
GX_LoadTexObj(&texobj, GX_TEXMAP0);
|
||||
|
||||
draw_square(view);
|
||||
|
||||
GX_DrawDone();
|
||||
|
||||
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
||||
GX_SetColorUpdate(GX_TRUE);
|
||||
GX_CopyDisp(xfb[whichfb], GX_TRUE);
|
||||
GX_Flush();
|
||||
|
||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||
VIDEO_Flush();
|
||||
//VIDEO_WaitVSync();
|
||||
|
||||
}
|
354
source/ngc/input.cpp
Normal file
354
source/ngc/input.cpp
Normal file
@ -0,0 +1,354 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May-June 2007
|
||||
* Tantric September 2008
|
||||
*
|
||||
* input.cpp
|
||||
*
|
||||
* Wii/Gamecube controller management
|
||||
***************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <ogcsys.h>
|
||||
#include <unistd.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
|
||||
#include "button_mapping.h"
|
||||
#include "menu.h"
|
||||
#include "video.h"
|
||||
#include "input.h"
|
||||
#include "tbtime.h"
|
||||
|
||||
#define MAXJP 10
|
||||
|
||||
#define VBA_BUTTON_A 1
|
||||
#define VBA_BUTTON_B 2
|
||||
#define VBA_BUTTON_SELECT 4
|
||||
#define VBA_BUTTON_START 8
|
||||
#define VBA_RIGHT 16
|
||||
#define VBA_LEFT 32
|
||||
#define VBA_UP 64
|
||||
#define VBA_DOWN 128
|
||||
#define VBA_BUTTON_R 256
|
||||
#define VBA_BUTTON_L 512
|
||||
#define VBA_SPEED 1024
|
||||
#define VBA_CAPTURE 2048
|
||||
|
||||
// VBA controller buttons
|
||||
// All other pads are mapped to this
|
||||
unsigned int vbapadmap[] = {
|
||||
VBA_BUTTON_A, VBA_BUTTON_B,
|
||||
VBA_BUTTON_SELECT, VBA_BUTTON_START,
|
||||
VBA_UP, VBA_DOWN,
|
||||
VBA_LEFT, VBA_RIGHT,
|
||||
VBA_BUTTON_L, VBA_BUTTON_R
|
||||
};
|
||||
|
||||
/*** Gamecube controller Padmap ***/
|
||||
unsigned int gcpadmap[] = {
|
||||
PAD_BUTTON_A, PAD_BUTTON_B,
|
||||
PAD_TRIGGER_Z, PAD_BUTTON_START,
|
||||
PAD_BUTTON_UP, PAD_BUTTON_DOWN,
|
||||
PAD_BUTTON_LEFT, PAD_BUTTON_RIGHT,
|
||||
PAD_TRIGGER_L, PAD_TRIGGER_R
|
||||
};
|
||||
/*** Wiimote Padmap ***/
|
||||
unsigned int wmpadmap[] = {
|
||||
WPAD_BUTTON_1, WPAD_BUTTON_2,
|
||||
WPAD_BUTTON_MINUS, WPAD_BUTTON_PLUS,
|
||||
WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT,
|
||||
WPAD_BUTTON_UP, WPAD_BUTTON_DOWN,
|
||||
0x0000, 0x0000
|
||||
};
|
||||
/*** Classic Controller Padmap ***/
|
||||
unsigned int ccpadmap[] = {
|
||||
WPAD_CLASSIC_BUTTON_A, WPAD_CLASSIC_BUTTON_B,
|
||||
WPAD_CLASSIC_BUTTON_MINUS, WPAD_CLASSIC_BUTTON_PLUS,
|
||||
WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN,
|
||||
WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT,
|
||||
WPAD_CLASSIC_BUTTON_FULL_L, WPAD_CLASSIC_BUTTON_FULL_R
|
||||
};
|
||||
/*** Nunchuk + wiimote Padmap ***/
|
||||
unsigned int ncpadmap[] = { WPAD_BUTTON_A, WPAD_BUTTON_B,
|
||||
WPAD_NUNCHUK_BUTTON_C, WPAD_NUNCHUK_BUTTON_Z,
|
||||
WPAD_BUTTON_MINUS, WPAD_BUTTON_PLUS,
|
||||
WPAD_BUTTON_2, WPAD_BUTTON_1,
|
||||
WPAD_BUTTON_UP, WPAD_BUTTON_DOWN,
|
||||
WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT
|
||||
};
|
||||
|
||||
#ifdef HW_RVL
|
||||
/****************************************************************************
|
||||
* WPAD_StickX
|
||||
*
|
||||
* Get X value from Wii Joystick (classic, nunchuk) input
|
||||
***************************************************************************/
|
||||
|
||||
s8 WPAD_StickX(u8 chan,u8 right)
|
||||
{
|
||||
float mag = 0.0;
|
||||
float ang = 0.0;
|
||||
WPADData *data = WPAD_Data(chan);
|
||||
|
||||
switch (data->exp.type)
|
||||
{
|
||||
case WPAD_EXP_NUNCHUK:
|
||||
case WPAD_EXP_GUITARHERO3:
|
||||
if (right == 0)
|
||||
{
|
||||
mag = data->exp.nunchuk.js.mag;
|
||||
ang = data->exp.nunchuk.js.ang;
|
||||
}
|
||||
break;
|
||||
|
||||
case WPAD_EXP_CLASSIC:
|
||||
if (right == 0)
|
||||
{
|
||||
mag = data->exp.classic.ljs.mag;
|
||||
ang = data->exp.classic.ljs.ang;
|
||||
}
|
||||
else
|
||||
{
|
||||
mag = data->exp.classic.rjs.mag;
|
||||
ang = data->exp.classic.rjs.ang;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* calculate X value (angle need to be converted into radian) */
|
||||
if (mag > 1.0) mag = 1.0;
|
||||
else if (mag < -1.0) mag = -1.0;
|
||||
double val = mag * sin((PI * ang)/180.0f);
|
||||
|
||||
return (s8)(val * 128.0f);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* WPAD_StickY
|
||||
*
|
||||
* Get Y value from Wii Joystick (classic, nunchuk) input
|
||||
***************************************************************************/
|
||||
|
||||
s8 WPAD_StickY(u8 chan, u8 right)
|
||||
{
|
||||
float mag = 0.0;
|
||||
float ang = 0.0;
|
||||
WPADData *data = WPAD_Data(chan);
|
||||
|
||||
switch (data->exp.type)
|
||||
{
|
||||
case WPAD_EXP_NUNCHUK:
|
||||
case WPAD_EXP_GUITARHERO3:
|
||||
if (right == 0)
|
||||
{
|
||||
mag = data->exp.nunchuk.js.mag;
|
||||
ang = data->exp.nunchuk.js.ang;
|
||||
}
|
||||
break;
|
||||
|
||||
case WPAD_EXP_CLASSIC:
|
||||
if (right == 0)
|
||||
{
|
||||
mag = data->exp.classic.ljs.mag;
|
||||
ang = data->exp.classic.ljs.ang;
|
||||
}
|
||||
else
|
||||
{
|
||||
mag = data->exp.classic.rjs.mag;
|
||||
ang = data->exp.classic.rjs.ang;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* calculate X value (angle need to be converted into radian) */
|
||||
if (mag > 1.0) mag = 1.0;
|
||||
else if (mag < -1.0) mag = -1.0;
|
||||
double val = mag * cos((PI * ang)/180.0f);
|
||||
|
||||
return (s8)(val * 128.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* DecodeJoy
|
||||
*
|
||||
* Reads the changes (buttons pressed, etc) from a controller and reports
|
||||
* these changes to VBA
|
||||
****************************************************************************/
|
||||
|
||||
u32 DecodeJoy(unsigned short pad)
|
||||
{
|
||||
signed char pad_x = PAD_StickX (pad);
|
||||
signed char pad_y = PAD_StickY (pad);
|
||||
u32 jp = PAD_ButtonsHeld (pad);
|
||||
unsigned char J = 0;
|
||||
|
||||
#ifdef HW_RVL
|
||||
signed char wm_ax = 0;
|
||||
signed char wm_ay = 0;
|
||||
u32 wp = 0;
|
||||
wm_ax = WPAD_StickX ((u8)pad, 0);
|
||||
wm_ay = WPAD_StickY ((u8)pad, 0);
|
||||
wp = WPAD_ButtonsHeld (pad);
|
||||
|
||||
u32 exp_type;
|
||||
if ( WPAD_Probe(pad, &exp_type) != 0 ) exp_type = WPAD_EXP_NONE;
|
||||
#endif
|
||||
|
||||
/***
|
||||
Gamecube Joystick input
|
||||
***/
|
||||
// Is XY inside the "zone"?
|
||||
if (pad_x * pad_x + pad_y * pad_y > PADCAL * PADCAL)
|
||||
{
|
||||
if (pad_x > 0 && pad_y == 0) J |= VBA_RIGHT;
|
||||
if (pad_x < 0 && pad_y == 0) J |= VBA_LEFT;
|
||||
if (pad_x == 0 && pad_y > 0) J |= VBA_UP;
|
||||
if (pad_x == 0 && pad_y < 0) J |= VBA_DOWN;
|
||||
|
||||
if (pad_x != 0 && pad_y != 0)
|
||||
{
|
||||
if ((float)pad_y / pad_x >= -2.41421356237 && (float)pad_y / pad_x < 2.41421356237)
|
||||
{
|
||||
if (pad_x >= 0)
|
||||
J |= VBA_RIGHT;
|
||||
else
|
||||
J |= VBA_LEFT;
|
||||
}
|
||||
|
||||
if ((float)pad_x / pad_y >= -2.41421356237 && (float)pad_x / pad_y < 2.41421356237)
|
||||
{
|
||||
if (pad_y >= 0)
|
||||
J |= VBA_UP;
|
||||
else
|
||||
J |= VBA_DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef HW_RVL
|
||||
/***
|
||||
Wii Joystick (classic, nunchuk) input
|
||||
***/
|
||||
// Is XY inside the "zone"?
|
||||
if (wm_ax * wm_ax + wm_ay * wm_ay > PADCAL * PADCAL)
|
||||
{
|
||||
/*** we don't want division by zero ***/
|
||||
if (wm_ax > 0 && wm_ay == 0)
|
||||
J |= VBA_RIGHT;
|
||||
if (wm_ax < 0 && wm_ay == 0)
|
||||
J |= VBA_LEFT;
|
||||
if (wm_ax == 0 && wm_ay > 0)
|
||||
J |= VBA_UP;
|
||||
if (wm_ax == 0 && wm_ay < 0)
|
||||
J |= VBA_DOWN;
|
||||
|
||||
if (wm_ax != 0 && wm_ay != 0)
|
||||
{
|
||||
|
||||
/*** Recalc left / right ***/
|
||||
float t;
|
||||
|
||||
t = (float) wm_ay / wm_ax;
|
||||
if (t >= -2.41421356237 && t < 2.41421356237)
|
||||
{
|
||||
if (wm_ax >= 0)
|
||||
J |= VBA_RIGHT;
|
||||
else
|
||||
J |= VBA_LEFT;
|
||||
}
|
||||
|
||||
/*** Recalc up / down ***/
|
||||
t = (float) wm_ax / wm_ay;
|
||||
if (t >= -2.41421356237 && t < 2.41421356237)
|
||||
{
|
||||
if (wm_ay >= 0)
|
||||
J |= VBA_UP;
|
||||
else
|
||||
J |= VBA_DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*** Report pressed buttons (gamepads) ***/
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAXJP; i++)
|
||||
{
|
||||
if ( (jp & gcpadmap[i]) // gamecube controller
|
||||
#ifdef HW_RVL
|
||||
|| ( (exp_type == WPAD_EXP_NONE) && (wp & wmpadmap[i]) ) // wiimote
|
||||
|| ( (exp_type == WPAD_EXP_CLASSIC) && (wp & ccpadmap[i]) ) // classic controller
|
||||
|| ( (exp_type == WPAD_EXP_NUNCHUK) && (wp & ncpadmap[i]) ) // nunchuk + wiimote
|
||||
#endif
|
||||
)
|
||||
J |= vbapadmap[i];
|
||||
}
|
||||
|
||||
return J;
|
||||
}
|
||||
u32 GetJoy()
|
||||
{
|
||||
short i;
|
||||
int pad = 0;
|
||||
u32 res = 0;
|
||||
|
||||
s8 gc_px = PAD_SubStickX (0);
|
||||
u32 jp = PAD_ButtonsHeld (0); // gamecube controller button info
|
||||
|
||||
#ifdef HW_RVL
|
||||
s8 wm_sx = WPAD_StickX (0,1);
|
||||
u32 wm_pb = WPAD_ButtonsHeld (0); // wiimote / expansion button info
|
||||
#endif
|
||||
|
||||
// request to go back to menu
|
||||
if ((gc_px < -70) || (jp & PAD_BUTTON_START)
|
||||
#ifdef HW_RVL
|
||||
|| (wm_pb & WPAD_BUTTON_HOME)
|
||||
|| (wm_pb & WPAD_CLASSIC_BUTTON_HOME)
|
||||
|| (wm_sx < -70)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/*
|
||||
if (GCSettings.AutoSave == 1)
|
||||
{
|
||||
SaveRAM(GCSettings.SaveMethod, SILENT);
|
||||
}
|
||||
else if (GCSettings.AutoSave == 2)
|
||||
{
|
||||
SaveState(GCSettings.SaveMethod, SILENT);
|
||||
}
|
||||
else if(GCSettings.AutoSave == 3)
|
||||
{
|
||||
SaveRAM(GCSettings.SaveMethod, SILENT);
|
||||
SaveState(GCSettings.SaveMethod, SILENT);
|
||||
}
|
||||
*/
|
||||
mainmenu(3);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = DecodeJoy(pad);
|
||||
if ((res & 48) == 48)
|
||||
res &= ~16;
|
||||
if ((res & 192) == 192)
|
||||
res &= ~128;
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
31
source/ngc/input.h
Normal file
31
source/ngc/input.h
Normal file
@ -0,0 +1,31 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May-June 2007
|
||||
* Tantric September 2008
|
||||
*
|
||||
* input.h
|
||||
*
|
||||
* Wii/Gamecube controller management
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _INPUT_H_
|
||||
#define _INPUT_H_
|
||||
|
||||
#include <gccore.h>
|
||||
|
||||
#define PI 3.14159265f
|
||||
#define PADCAL 50
|
||||
|
||||
extern unsigned int gcpadmap[];
|
||||
extern unsigned int wmpadmap[];
|
||||
extern unsigned int ccpadmap[];
|
||||
extern unsigned int ncpadmap[];
|
||||
|
||||
s8 WPAD_StickX(u8 chan,u8 right);
|
||||
s8 WPAD_StickY(u8 chan, u8 right);
|
||||
|
||||
u32 GetJoy();
|
||||
|
||||
#endif
|
@ -1 +0,0 @@
|
||||
|
419
source/ngc/memcardop.cpp
Normal file
419
source/ngc/memcardop.cpp
Normal file
@ -0,0 +1,419 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May-June 2007
|
||||
* Tantric September 2008
|
||||
*
|
||||
* memcardop.cpp
|
||||
*
|
||||
* Memory Card routines
|
||||
***************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <ogcsys.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "vba.h"
|
||||
#include "video.h"
|
||||
#include "menudraw.h"
|
||||
#include "menu.h"
|
||||
#include "preferences.h"
|
||||
#include "memcardop.h"
|
||||
#include "fileop.h"
|
||||
|
||||
#define VERIFBUFFERSIZE 65536
|
||||
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
|
||||
extern unsigned char savebuffer[];
|
||||
unsigned char verifbuffer[VERIFBUFFERSIZE] ATTRIBUTE_ALIGN (32);
|
||||
card_dir CardDir;
|
||||
card_file CardFile;
|
||||
card_stat CardStatus;
|
||||
|
||||
/****************************************************************************
|
||||
* CardFileExists
|
||||
*
|
||||
* Wrapper to search through the files on the card.
|
||||
* Returns TRUE if found.
|
||||
***************************************************************************/
|
||||
int
|
||||
CardFileExists (char *filename, int slot)
|
||||
{
|
||||
int CardError;
|
||||
|
||||
CardError = CARD_FindFirst (slot, &CardDir, TRUE);
|
||||
while (CardError != CARD_ERROR_NOFILE)
|
||||
{
|
||||
CardError = CARD_FindNext (&CardDir);
|
||||
|
||||
if (strcmp ((char *) CardDir.filename, filename) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* TestCard
|
||||
*
|
||||
* Checks to see if a card is in the card slot specified
|
||||
***************************************************************************/
|
||||
bool TestCard(int slot, bool silent)
|
||||
{
|
||||
// Memory Cards do not work in Wii mode - disable
|
||||
#ifdef HW_RVL
|
||||
return false;
|
||||
#endif
|
||||
|
||||
/*** Initialize Card System ***/
|
||||
memset (SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("SNES", "00");
|
||||
|
||||
/*** Try to mount the card ***/
|
||||
if (MountCard(slot, silent) == 0)
|
||||
{
|
||||
// Mount successful!
|
||||
if(!silent)
|
||||
{
|
||||
if (slot == CARD_SLOTA)
|
||||
WaitPrompt((char*) "Mounted Slot A Memory Card!");
|
||||
else
|
||||
WaitPrompt((char*) "Mounted Slot B Memory Card!");
|
||||
}
|
||||
CARD_Unmount (slot);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!silent)
|
||||
{
|
||||
if (slot == CARD_SLOTA)
|
||||
WaitPrompt((char*) "Unable to Mount Slot A Memory Card!");
|
||||
else
|
||||
WaitPrompt((char*) "Unable to Mount Slot B Memory Card!");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* MountCard
|
||||
*
|
||||
* Mounts the memory card in the given slot.
|
||||
* Returns the result of the last attempted CARD_Mount command.
|
||||
***************************************************************************/
|
||||
int MountCard(int cslot, bool silent)
|
||||
{
|
||||
int ret = -1;
|
||||
int tries = 0;
|
||||
|
||||
// Mount the card
|
||||
while ( tries < 10 && ret != 0)
|
||||
{
|
||||
EXI_ProbeReset ();
|
||||
ret = CARD_Mount (cslot, SysArea, NULL);
|
||||
VIDEO_WaitVSync ();
|
||||
tries++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Verify Memory Card file against buffer
|
||||
***************************************************************************/
|
||||
int
|
||||
VerifyMCFile (unsigned char *buf, int slot, char *filename, int datasize)
|
||||
{
|
||||
int CardError;
|
||||
unsigned int blocks;
|
||||
unsigned int SectorSize;
|
||||
char msg[80];
|
||||
int bytesleft = 0;
|
||||
int bytesread = 0;
|
||||
|
||||
/*** Initialize Card System ***/
|
||||
memset (SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("SNES", "00");
|
||||
|
||||
/*** Try to mount the card ***/
|
||||
CardError = MountCard(slot, NOTSILENT);
|
||||
|
||||
if (CardError == 0)
|
||||
{
|
||||
/*** Get Sector Size ***/
|
||||
CARD_GetSectorSize (slot, &SectorSize);
|
||||
|
||||
if (!CardFileExists (filename, slot))
|
||||
{
|
||||
CARD_Unmount (slot);
|
||||
WaitPrompt((char*) "Unable to open file for verify!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset (&CardFile, 0, sizeof (CardFile));
|
||||
CardError = CARD_Open (slot, filename, &CardFile);
|
||||
|
||||
blocks = CardFile.len;
|
||||
|
||||
if (blocks < SectorSize)
|
||||
blocks = SectorSize;
|
||||
|
||||
if (blocks % SectorSize)
|
||||
blocks += SectorSize;
|
||||
|
||||
if (blocks > (unsigned int)datasize)
|
||||
blocks = datasize;
|
||||
|
||||
memset (verifbuffer, 0, VERIFBUFFERSIZE);
|
||||
bytesleft = blocks;
|
||||
bytesread = 0;
|
||||
while (bytesleft > 0)
|
||||
{
|
||||
CARD_Read (&CardFile, verifbuffer, SectorSize, bytesread);
|
||||
if ( memcmp (buf + bytesread, verifbuffer, (unsigned int)bytesleft < SectorSize ? bytesleft : SectorSize) )
|
||||
{
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (slot);
|
||||
WaitPrompt((char*) "File did not verify!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bytesleft -= SectorSize;
|
||||
bytesread += SectorSize;
|
||||
|
||||
sprintf (msg, "Verified %d of %d bytes", bytesread, blocks);
|
||||
ShowProgress (msg, bytesread, blocks);
|
||||
}
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (slot);
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
if (slot == CARD_SLOTA)
|
||||
WaitPrompt((char*) "Unable to Mount Slot A Memory Card!");
|
||||
else
|
||||
WaitPrompt((char*) "Unable to Mount Slot B Memory Card!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Load savebuffer from Memory Card file
|
||||
***************************************************************************/
|
||||
int
|
||||
LoadBufferFromMC (unsigned char *buf, int slot, char *filename, bool silent)
|
||||
{
|
||||
int CardError;
|
||||
unsigned int blocks;
|
||||
unsigned int SectorSize;
|
||||
int bytesleft = 0;
|
||||
int bytesread = 0;
|
||||
|
||||
/*** Initialize Card System ***/
|
||||
memset (SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("SNES", "00");
|
||||
|
||||
/*** Try to mount the card ***/
|
||||
CardError = MountCard(slot, NOTSILENT);
|
||||
|
||||
if (CardError == 0)
|
||||
{
|
||||
/*** Get Sector Size ***/
|
||||
CARD_GetSectorSize (slot, &SectorSize);
|
||||
|
||||
if (!CardFileExists (filename, slot))
|
||||
{
|
||||
if (!silent)
|
||||
WaitPrompt((char*) "Unable to open file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset (&CardFile, 0, sizeof (CardFile));
|
||||
CardError = CARD_Open (slot, filename, &CardFile);
|
||||
|
||||
blocks = CardFile.len;
|
||||
|
||||
if (blocks < SectorSize)
|
||||
blocks = SectorSize;
|
||||
|
||||
if (blocks % SectorSize)
|
||||
blocks += SectorSize;
|
||||
|
||||
memset (buf, 0, 0x22000);
|
||||
|
||||
bytesleft = blocks;
|
||||
bytesread = 0;
|
||||
while (bytesleft > 0)
|
||||
{
|
||||
CARD_Read (&CardFile, buf + bytesread, SectorSize, bytesread);
|
||||
bytesleft -= SectorSize;
|
||||
bytesread += SectorSize;
|
||||
}
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (slot);
|
||||
}
|
||||
else
|
||||
if (slot == CARD_SLOTA)
|
||||
WaitPrompt((char*) "Unable to Mount Slot A Memory Card!");
|
||||
else
|
||||
WaitPrompt((char*) "Unable to Mount Slot B Memory Card!");
|
||||
|
||||
return bytesread;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Write savebuffer to Memory Card file
|
||||
***************************************************************************/
|
||||
int
|
||||
SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool silent)
|
||||
{
|
||||
int CardError;
|
||||
unsigned int blocks;
|
||||
unsigned int SectorSize;
|
||||
char msg[80];
|
||||
|
||||
/*** Initialize Card System ***/
|
||||
memset (SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("SNES", "00");
|
||||
|
||||
/*** Try to mount the card ***/
|
||||
CardError = MountCard(slot, NOTSILENT);
|
||||
|
||||
if (CardError == 0)
|
||||
{
|
||||
/*** Get Sector Size ***/
|
||||
CARD_GetSectorSize (slot, &SectorSize);
|
||||
|
||||
if (datasize)
|
||||
{
|
||||
/*** Calculate number of blocks required ***/
|
||||
blocks = (datasize / SectorSize) * SectorSize;
|
||||
if (datasize % SectorSize)
|
||||
blocks += SectorSize;
|
||||
|
||||
/*** Does this file exist ? ***/
|
||||
if (CardFileExists (filename, slot))
|
||||
{
|
||||
/*** Try to open the file ***/
|
||||
CardError = CARD_Open (slot, filename, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
CARD_Unmount (slot);
|
||||
WaitPrompt((char*) "Unable to open card file!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (s32)blocks > CardFile.len ) /*** new data is longer ***/
|
||||
{
|
||||
CARD_Close (&CardFile);
|
||||
|
||||
/*** Try to create temp file to check available space ***/
|
||||
CardError = CARD_Create (slot, "TEMPFILESNES9XGX201", blocks, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
CARD_Unmount (slot);
|
||||
WaitPrompt((char*) "Not enough space to update file!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** Delete the temporary file ***/
|
||||
CARD_Close (&CardFile);
|
||||
CardError = CARD_Delete(slot, "TEMPFILESNES9XGX201");
|
||||
if (CardError)
|
||||
{
|
||||
CARD_Unmount (slot);
|
||||
WaitPrompt((char*) "Unable to delete temporary file!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** Delete the existing shorter file ***/
|
||||
CardError = CARD_Delete(slot, filename);
|
||||
if (CardError)
|
||||
{
|
||||
CARD_Unmount (slot);
|
||||
WaitPrompt((char*) "Unable to delete existing file!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** Create new, longer file ***/
|
||||
CardError = CARD_Create (slot, filename, blocks, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
CARD_Unmount (slot);
|
||||
WaitPrompt((char*) "Unable to create updated card file!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /*** no file existed, create new one ***/
|
||||
{
|
||||
/*** Create new file ***/
|
||||
CardError = CARD_Create (slot, filename, blocks, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
CARD_Unmount (slot);
|
||||
if ( CardError == CARD_ERROR_INSSPACE )
|
||||
WaitPrompt((char*) "Not enough space to create file!");
|
||||
else
|
||||
WaitPrompt((char*) "Unable to create card file!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*** Now, have an open file handle, ready to send out the data ***/
|
||||
CARD_GetStatus (slot, CardFile.filenum, &CardStatus);
|
||||
CardStatus.icon_addr = 0x0;
|
||||
CardStatus.icon_fmt = 2;
|
||||
CardStatus.icon_speed = 1;
|
||||
CardStatus.comment_addr = 2048;
|
||||
CARD_SetStatus (slot, CardFile.filenum, &CardStatus);
|
||||
|
||||
int byteswritten = 0;
|
||||
int bytesleft = blocks;
|
||||
while (bytesleft > 0)
|
||||
{
|
||||
CardError =
|
||||
CARD_Write (&CardFile, buf + byteswritten,
|
||||
SectorSize, byteswritten);
|
||||
bytesleft -= SectorSize;
|
||||
byteswritten += SectorSize;
|
||||
|
||||
sprintf (msg, "Wrote %d of %d bytes", byteswritten, blocks);
|
||||
ShowProgress (msg, byteswritten, blocks);
|
||||
}
|
||||
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (slot);
|
||||
|
||||
if ( GCSettings.VerifySaves )
|
||||
{
|
||||
/*** Verify the written file, but only up to the length we wrote
|
||||
because the file could be longer due to past writes ***/
|
||||
if ( VerifyMCFile (buf, slot, filename, byteswritten) )
|
||||
return byteswritten;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return byteswritten;
|
||||
}
|
||||
else
|
||||
if ( !silent )
|
||||
WaitPrompt((char*) "This game does not appear to use SRAM");
|
||||
}
|
||||
else
|
||||
if (slot == CARD_SLOTA)
|
||||
WaitPrompt((char*) "Unable to Mount Slot A Memory Card!");
|
||||
else
|
||||
WaitPrompt((char*) "Unable to Mount Slot B Memory Card!");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
23
source/ngc/memcardop.h
Normal file
23
source/ngc/memcardop.h
Normal file
@ -0,0 +1,23 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May-June 2007
|
||||
* Tantric September 2008
|
||||
*
|
||||
* memcardop.cpp
|
||||
*
|
||||
* Memory Card routines
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _NGCMCSAVE_
|
||||
#define _NGCMCSAVE_
|
||||
|
||||
int VerifyMCFile (unsigned char *buf, int slot, char *filename, int datasize);
|
||||
|
||||
int LoadBufferFromMC (unsigned char *buf, int slot, char *filename, bool silent);
|
||||
int SaveBufferToMC (unsigned char *buf, int slot, char *filename, int datasize, bool silent);
|
||||
int MountCard(int cslot, bool silent);
|
||||
bool TestCard(int slot, bool silent);
|
||||
|
||||
#endif
|
@ -1,265 +1,731 @@
|
||||
/****************************************************************************
|
||||
* File Selection Menu
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gccore.h>
|
||||
#include "sdfileio.h"
|
||||
|
||||
extern GXRModeObj *vmode; /*** Graphics Mode Object ***/
|
||||
extern u32 *xfb[2]; /*** Framebuffers ***/
|
||||
extern int whichfb; /*** Frame buffer toggle ***/
|
||||
|
||||
/** Bits from SD lib **/
|
||||
|
||||
#define PAGE_SIZE 14
|
||||
|
||||
/*** Use OGC built in font ***/
|
||||
extern u8 console_font_8x16[];
|
||||
|
||||
static u32 forecolour = COLOR_WHITE;
|
||||
static u32 backcolour = COLOR_BLACK;
|
||||
|
||||
/****************************************************************************
|
||||
* MENU_DrawChar
|
||||
****************************************************************************/
|
||||
void MENU_DrawChar( int x, int y, char c, int style )
|
||||
{
|
||||
u8 bits;
|
||||
int offset;
|
||||
int h,w;
|
||||
u32 colour[2];
|
||||
u32 scroffs;
|
||||
|
||||
offset = c << 4;
|
||||
scroffs = ( y * 320 ) + ( x >> 1 );
|
||||
|
||||
for( h = 0; h < 16; h++ )
|
||||
{
|
||||
bits = console_font_8x16[ offset++ ];
|
||||
|
||||
if ( style )
|
||||
{
|
||||
for( w = 0; w < 8; w++ )
|
||||
{
|
||||
xfb[whichfb][scroffs + w] = ( bits & 0x80 ) ? forecolour : backcolour;
|
||||
bits <<= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( w = 0; w < 4; w++ )
|
||||
{
|
||||
colour[0] = ( bits & 0x80 ) ? forecolour : backcolour;
|
||||
colour[1] = ( bits & 0x40 ) ? forecolour : backcolour;
|
||||
|
||||
xfb[whichfb][scroffs + w] = ( colour[0] & 0xFFFF00FF ) | ( colour[1] & 0x0000FF00 );
|
||||
bits <<= 2;
|
||||
}
|
||||
}
|
||||
|
||||
scroffs += 320;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* MENU_DrawString
|
||||
****************************************************************************/
|
||||
void MENU_DrawString( int x, int y, char *msg, int style )
|
||||
{
|
||||
int i,len;
|
||||
|
||||
/* Centred ? */
|
||||
if ( x == -1 )
|
||||
{
|
||||
if ( style )
|
||||
x = strlen(msg) << 4;
|
||||
else
|
||||
x = strlen(msg) << 3;
|
||||
|
||||
x = ( 640 - x ) >> 1;
|
||||
}
|
||||
if((int)strlen(msg) < 36)
|
||||
len = (int)strlen(msg);
|
||||
else
|
||||
len = 36;
|
||||
for ( i = 0; i < len; i++ )
|
||||
{
|
||||
MENU_DrawChar(x,y,msg[i],style);
|
||||
x += ( style ? 16 : 8 );
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* MENU_Draw
|
||||
****************************************************************************/
|
||||
int MENU_Draw( int max, int current, int offset )
|
||||
{
|
||||
int i;
|
||||
int ypos = 30;
|
||||
int xpos = 30;
|
||||
|
||||
for ( i = offset; i < max && ( ( i - offset ) < PAGE_SIZE ); i++ )
|
||||
{
|
||||
if ( i == current )
|
||||
{
|
||||
forecolour = COLOR_BLACK;
|
||||
backcolour = COLOR_WHITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
forecolour = COLOR_WHITE;
|
||||
backcolour = COLOR_BLACK;
|
||||
}
|
||||
MENU_DrawString( xpos, ypos, direntries[i], 1);
|
||||
ypos += 16;
|
||||
}
|
||||
}
|
||||
#ifdef WII_BUILD
|
||||
#include <math.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
extern int isClassicAvailable;
|
||||
extern int isWiimoteAvailable;
|
||||
extern void setup_controllers();
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* MENU_GetLoadFile
|
||||
*
|
||||
* Returns the filename of the selected file
|
||||
***************************************************************************/
|
||||
char *MENU_GetLoadFile( char *whichdir )
|
||||
{
|
||||
int count;
|
||||
char *p = NULL;
|
||||
int quit = 0;
|
||||
int redraw = 1;
|
||||
int current = 0;
|
||||
int offset = 0;
|
||||
u16 buttons;
|
||||
int do_DOWN = 0;
|
||||
int do_UP = 0;
|
||||
int do_A = 0;
|
||||
|
||||
count = gen_getdir( whichdir );
|
||||
|
||||
|
||||
if ( count == 0 )
|
||||
{
|
||||
printf("No ROM files in %s\n", whichdir);
|
||||
while(1);
|
||||
}
|
||||
#ifdef WII_BUILD
|
||||
setup_controllers();
|
||||
#endif
|
||||
if ( count == 1 )
|
||||
return (char*)direntries[0];
|
||||
|
||||
/* Do menu */
|
||||
while ( !quit )
|
||||
{
|
||||
if ( redraw )
|
||||
{
|
||||
whichfb ^= 1;
|
||||
VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK);
|
||||
MENU_Draw( count, current, offset );
|
||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
redraw = 0;
|
||||
}
|
||||
#ifdef WII_BUILD
|
||||
WPAD_ScanPads();
|
||||
WPADData *wpad;
|
||||
wpad = WPAD_Data(0);
|
||||
int b = wpad->exp.classic.btns;
|
||||
unsigned short b1 = wpad->btns_d;
|
||||
if (isClassicAvailable){
|
||||
if (b & CLASSIC_CTRL_BUTTON_DOWN){
|
||||
do_DOWN = 1;
|
||||
do{WPAD_ScanPads(); wpad = WPAD_Data(0);}
|
||||
while (WPAD_ButtonsHeld(0));
|
||||
}
|
||||
else if (b & CLASSIC_CTRL_BUTTON_UP){
|
||||
do_UP = 1;
|
||||
do{WPAD_ScanPads(); wpad = WPAD_Data(0);}
|
||||
while (WPAD_ButtonsHeld(0));
|
||||
}
|
||||
else if (b & CLASSIC_CTRL_BUTTON_A){
|
||||
do_A = 1;
|
||||
do{WPAD_ScanPads(); wpad = WPAD_Data(0);}
|
||||
while (WPAD_ButtonsHeld(0));
|
||||
}
|
||||
}
|
||||
if (isWiimoteAvailable){
|
||||
if (b1 & WPAD_BUTTON_LEFT){
|
||||
do_DOWN = 1;
|
||||
do{WPAD_ScanPads(); wpad = WPAD_Data(0);}
|
||||
while (WPAD_ButtonsHeld(0));
|
||||
}
|
||||
else if (b1 & WPAD_BUTTON_RIGHT){
|
||||
do_UP = 1;
|
||||
do{WPAD_ScanPads(); wpad = WPAD_Data(0);}
|
||||
while (WPAD_ButtonsHeld(0));
|
||||
}
|
||||
else if (b1 & WPAD_BUTTON_2){
|
||||
do_A = 1;
|
||||
do{WPAD_ScanPads(); wpad = WPAD_Data(0);}
|
||||
while (WPAD_ButtonsHeld(0));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
buttons = PAD_ButtonsDown(0);
|
||||
if(buttons & PAD_BUTTON_DOWN)
|
||||
do_DOWN = 1;
|
||||
else if(buttons & PAD_BUTTON_UP)
|
||||
do_UP = 1;
|
||||
else if(buttons & PAD_BUTTON_A)
|
||||
do_A = 1;
|
||||
if (do_DOWN)
|
||||
{
|
||||
do_DOWN=0;
|
||||
current++;
|
||||
if ( current == count )
|
||||
current = 0;
|
||||
|
||||
if ( ( current % PAGE_SIZE ) == 0 )
|
||||
offset = current;
|
||||
|
||||
redraw = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( do_UP )
|
||||
{
|
||||
do_UP=0;
|
||||
current--;
|
||||
if ( current < 0 ) current = count - 1;
|
||||
offset = ( current / PAGE_SIZE ) * PAGE_SIZE;
|
||||
redraw = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( do_A )
|
||||
{
|
||||
do_A=0;
|
||||
quit = 1;
|
||||
p = (char*)direntries[current];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
whichfb ^= 1;
|
||||
VIDEO_ClearFrameBuffer(vmode, xfb[whichfb], COLOR_BLACK);
|
||||
forecolour = COLOR_WHITE;
|
||||
backcolour = COLOR_BLACK;
|
||||
MENU_DrawString(-1, 240, "Loading ... Wait", 1);
|
||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
return p;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May-June 2007
|
||||
* Tantric August 2008
|
||||
*
|
||||
* menu.cpp
|
||||
*
|
||||
* Menu flow routines - handles all menu logic
|
||||
***************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <ogcsys.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
|
||||
#ifdef WII_DVD
|
||||
extern "C" {
|
||||
#include <di/di.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "vba.h"
|
||||
#include "vbasupport.h"
|
||||
#include "audio.h"
|
||||
#include "video.h"
|
||||
#include "filesel.h"
|
||||
#include "gcunzip.h"
|
||||
#include "smbop.h"
|
||||
#include "memcardop.h"
|
||||
#include "fileop.h"
|
||||
#include "dvd.h"
|
||||
#include "preferences.h"
|
||||
#include "button_mapping.h"
|
||||
#include "menudraw.h"
|
||||
#include "input.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "tbtime.h"
|
||||
}
|
||||
|
||||
extern void DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize);
|
||||
|
||||
extern int menu;
|
||||
extern int ROMSize;
|
||||
|
||||
#define SOFTRESET_ADR ((volatile u32*)0xCC003024)
|
||||
|
||||
/****************************************************************************
|
||||
* Reboot / Exit
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef HW_RVL
|
||||
#define PSOSDLOADID 0x7c6000a6
|
||||
int *psoid = (int *) 0x80001800;
|
||||
void (*PSOReload) () = (void (*)()) 0x80001800;
|
||||
#endif
|
||||
|
||||
void Reboot()
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||
#else
|
||||
#define SOFTRESET_ADR ((volatile u32*)0xCC003024)
|
||||
*SOFTRESET_ADR = 0x00000000;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Load Manager
|
||||
***************************************************************************/
|
||||
|
||||
int
|
||||
LoadManager ()
|
||||
{
|
||||
int loadROM = OpenROM(GCSettings.LoadMethod);
|
||||
|
||||
/***
|
||||
* check for autoloadsram / freeze
|
||||
***/
|
||||
if ( loadROM == 1 ) // if ROM was loaded, load the SRAM & settings
|
||||
{
|
||||
//if ( GCSettings.AutoLoad == 1 )
|
||||
// LoadSRAM(GCSettings.SaveMethod, SILENT);
|
||||
//else if ( GCSettings.AutoLoad == 2 )
|
||||
// NGCUnfreezeGame (GCSettings.SaveMethod, SILENT);
|
||||
|
||||
// setup cheats
|
||||
//SetupCheats();
|
||||
}
|
||||
|
||||
return loadROM;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Preferences Menu
|
||||
***************************************************************************/
|
||||
static int prefmenuCount = 9;
|
||||
static char prefmenu[][50] = {
|
||||
|
||||
"Load Method",
|
||||
"Load Folder",
|
||||
"Save Method",
|
||||
"Save Folder",
|
||||
|
||||
"Auto Load",
|
||||
"Auto Save",
|
||||
"Verify MC Saves",
|
||||
|
||||
"Save Preferences",
|
||||
"Back to Main Menu"
|
||||
};
|
||||
|
||||
void
|
||||
PreferencesMenu ()
|
||||
{
|
||||
int ret = 0;
|
||||
int quit = 0;
|
||||
int oldmenu = menu;
|
||||
menu = 0;
|
||||
while (quit == 0)
|
||||
{
|
||||
// some load/save methods are not implemented - here's where we skip them
|
||||
// they need to be skipped in the order they were enumerated in snes9xGX.h
|
||||
|
||||
// no USB ports on GameCube
|
||||
#ifndef HW_RVL
|
||||
if(GCSettings.LoadMethod == METHOD_USB)
|
||||
GCSettings.LoadMethod++;
|
||||
if(GCSettings.SaveMethod == METHOD_USB)
|
||||
GCSettings.SaveMethod++;
|
||||
#endif
|
||||
|
||||
// check if DVD access in Wii mode is disabled
|
||||
#ifndef WII_DVD
|
||||
if(GCSettings.LoadMethod == METHOD_DVD)
|
||||
GCSettings.LoadMethod++;
|
||||
#endif
|
||||
|
||||
// saving to DVD is impossible
|
||||
if(GCSettings.SaveMethod == METHOD_DVD)
|
||||
GCSettings.SaveMethod++;
|
||||
|
||||
// disable SMB in GC mode (stalls out)
|
||||
#ifndef HW_RVL
|
||||
if(GCSettings.LoadMethod == METHOD_SMB)
|
||||
GCSettings.LoadMethod++;
|
||||
if(GCSettings.SaveMethod == METHOD_SMB)
|
||||
GCSettings.SaveMethod++;
|
||||
#endif
|
||||
|
||||
// disable MC saving in Wii mode - does not work for some reason!
|
||||
#ifdef HW_RVL
|
||||
if(GCSettings.SaveMethod == METHOD_MC_SLOTA)
|
||||
GCSettings.SaveMethod++;
|
||||
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
|
||||
GCSettings.SaveMethod++;
|
||||
#endif
|
||||
|
||||
// correct load/save methods out of bounds
|
||||
if(GCSettings.LoadMethod > 4)
|
||||
GCSettings.LoadMethod = 0;
|
||||
if(GCSettings.SaveMethod > 6)
|
||||
GCSettings.SaveMethod = 0;
|
||||
|
||||
if (GCSettings.LoadMethod == METHOD_AUTO) sprintf (prefmenu[0],"Load Method AUTO");
|
||||
else if (GCSettings.LoadMethod == METHOD_SD) sprintf (prefmenu[0],"Load Method SD");
|
||||
else if (GCSettings.LoadMethod == METHOD_USB) sprintf (prefmenu[0],"Load Method USB");
|
||||
else if (GCSettings.LoadMethod == METHOD_DVD) sprintf (prefmenu[0],"Load Method DVD");
|
||||
else if (GCSettings.LoadMethod == METHOD_SMB) sprintf (prefmenu[0],"Load Method Network");
|
||||
|
||||
sprintf (prefmenu[1], "Load Folder %s", GCSettings.LoadFolder);
|
||||
|
||||
if (GCSettings.SaveMethod == METHOD_AUTO) sprintf (prefmenu[2],"Save Method AUTO");
|
||||
else if (GCSettings.SaveMethod == METHOD_SD) sprintf (prefmenu[2],"Save Method SD");
|
||||
else if (GCSettings.SaveMethod == METHOD_USB) sprintf (prefmenu[2],"Save Method USB");
|
||||
else if (GCSettings.SaveMethod == METHOD_SMB) sprintf (prefmenu[2],"Save Method Network");
|
||||
else if (GCSettings.SaveMethod == METHOD_MC_SLOTA) sprintf (prefmenu[2],"Save Method MC Slot A");
|
||||
else if (GCSettings.SaveMethod == METHOD_MC_SLOTB) sprintf (prefmenu[2],"Save Method MC Slot B");
|
||||
|
||||
sprintf (prefmenu[3], "Save Folder %s", GCSettings.SaveFolder);
|
||||
|
||||
// disable changing load/save directories for now
|
||||
prefmenu[1][0] = '\0';
|
||||
prefmenu[3][0] = '\0';
|
||||
|
||||
if (GCSettings.AutoLoad == 0) sprintf (prefmenu[4],"Auto Load OFF");
|
||||
else if (GCSettings.AutoLoad == 1) sprintf (prefmenu[4],"Auto Load SRAM");
|
||||
else if (GCSettings.AutoLoad == 2) sprintf (prefmenu[4],"Auto Load SNAPSHOT");
|
||||
|
||||
if (GCSettings.AutoSave == 0) sprintf (prefmenu[5],"Auto Save OFF");
|
||||
else if (GCSettings.AutoSave == 1) sprintf (prefmenu[5],"Auto Save SRAM");
|
||||
else if (GCSettings.AutoSave == 2) sprintf (prefmenu[5],"Auto Save SNAPSHOT");
|
||||
else if (GCSettings.AutoSave == 3) sprintf (prefmenu[5],"Auto Save BOTH");
|
||||
|
||||
sprintf (prefmenu[6], "Verify MC Saves %s",
|
||||
GCSettings.VerifySaves == true ? " ON" : "OFF");
|
||||
|
||||
|
||||
ret = RunMenu (prefmenu, prefmenuCount, (char*)"Preferences", 16);
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
GCSettings.LoadMethod ++;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
GCSettings.SaveMethod ++;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
break;
|
||||
|
||||
case 4:
|
||||
GCSettings.AutoLoad ++;
|
||||
if (GCSettings.AutoLoad > 2)
|
||||
GCSettings.AutoLoad = 0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
GCSettings.AutoSave ++;
|
||||
if (GCSettings.AutoSave > 3)
|
||||
GCSettings.AutoSave = 0;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
GCSettings.VerifySaves ^= 1;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
SavePrefs(GCSettings.SaveMethod, NOTSILENT);
|
||||
break;
|
||||
|
||||
case -1: /*** Button B ***/
|
||||
case 8:
|
||||
quit = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
menu = oldmenu;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Game Options Menu
|
||||
***************************************************************************/
|
||||
|
||||
int
|
||||
GameMenu ()
|
||||
{
|
||||
int gamemenuCount = 7;
|
||||
char gamemenu[][50] = {
|
||||
"Return to Game",
|
||||
"Reset Game",
|
||||
"Load SRAM", "Save SRAM",
|
||||
"Load Game Snapshot", "Save Game Snapshot",
|
||||
"Back to Main Menu"
|
||||
};
|
||||
|
||||
int ret, retval = 0;
|
||||
int quit = 0;
|
||||
int oldmenu = menu;
|
||||
menu = 0;
|
||||
|
||||
while (quit == 0)
|
||||
{
|
||||
// disable SRAM/SNAPSHOT saving/loading if AUTO is on
|
||||
|
||||
if (GCSettings.AutoLoad == 1) // Auto Load SRAM
|
||||
gamemenu[2][0] = '\0';
|
||||
else if (GCSettings.AutoLoad == 2) // Auto Load SNAPSHOT
|
||||
gamemenu[4][0] = '\0';
|
||||
|
||||
if (GCSettings.AutoSave == 1) // Auto Save SRAM
|
||||
gamemenu[3][0] = '\0';
|
||||
else if (GCSettings.AutoSave == 2) // Auto Save SNAPSHOT
|
||||
gamemenu[5][0] = '\0';
|
||||
else if (GCSettings.AutoSave == 3) // Auto Save BOTH
|
||||
{
|
||||
gamemenu[3][0] = '\0';
|
||||
gamemenu[5][0] = '\0';
|
||||
}
|
||||
|
||||
ret = RunMenu (gamemenu, gamemenuCount, (char*)"Game Menu");
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case 0: // Return to Game
|
||||
quit = retval = 1;
|
||||
break;
|
||||
|
||||
case 1: // Reset Game
|
||||
emulator.emuReset();
|
||||
quit = retval = 1;
|
||||
break;
|
||||
|
||||
case 2: // Load SRAM
|
||||
//quit = retval = LoadSRAM(GCSettings.SaveMethod, NOTSILENT);
|
||||
break;
|
||||
|
||||
case 3: // Save SRAM
|
||||
//SaveSRAM(GCSettings.SaveMethod, NOTSILENT);
|
||||
break;
|
||||
|
||||
case 4: // Load Freeze
|
||||
//quit = retval = NGCUnfreezeGame (GCSettings.SaveMethod, NOTSILENT);
|
||||
break;
|
||||
|
||||
case 5: // Save Freeze
|
||||
//NGCFreezeGame (GCSettings.SaveMethod, NOTSILENT);
|
||||
//emulator.emuWriteState(statename);
|
||||
break;
|
||||
|
||||
case -1: // Button B
|
||||
case 6: // Return to previous menu
|
||||
retval = 0;
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
menu = oldmenu;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Controller Configuration
|
||||
*
|
||||
* Snes9x 1.51 uses a cmd system to work out which button has been pressed.
|
||||
* Here, I simply move the designated value to the gcpadmaps array, which
|
||||
* saves on updating the cmd sequences.
|
||||
***************************************************************************/
|
||||
u32
|
||||
GetInput (u16 ctrlr_type)
|
||||
{
|
||||
//u32 exp_type;
|
||||
u32 pressed;
|
||||
pressed=0;
|
||||
s8 gc_px = 0;
|
||||
|
||||
while( PAD_ButtonsHeld(0)
|
||||
#ifdef HW_RVL
|
||||
| WPAD_ButtonsHeld(0)
|
||||
#endif
|
||||
) VIDEO_WaitVSync(); // button 'debounce'
|
||||
|
||||
while (pressed == 0)
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
// get input based on controller type
|
||||
if (ctrlr_type == CTRLR_GCPAD)
|
||||
{
|
||||
pressed = PAD_ButtonsHeld (0);
|
||||
gc_px = PAD_SubStickX (0);
|
||||
}
|
||||
#ifdef HW_RVL
|
||||
else
|
||||
{
|
||||
// if ( WPAD_Probe( 0, &exp_type) == 0) // check wiimote and expansion status (first if wiimote is connected & no errors)
|
||||
// {
|
||||
pressed = WPAD_ButtonsHeld (0);
|
||||
|
||||
// if (ctrlr_type != CTRLR_WIIMOTE && exp_type != ctrlr_type+1) // if we need input from an expansion, and its not connected...
|
||||
// pressed = 0;
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
/*** check for exit sequence (c-stick left OR home button) ***/
|
||||
if ( (gc_px < -70) || (pressed & WPAD_BUTTON_HOME) || (pressed & WPAD_CLASSIC_BUTTON_HOME) )
|
||||
return 0;
|
||||
} // end while
|
||||
while( pressed == (PAD_ButtonsHeld(0)
|
||||
#ifdef HW_RVL
|
||||
| WPAD_ButtonsHeld(0)
|
||||
#endif
|
||||
) ) VIDEO_WaitVSync();
|
||||
|
||||
return pressed;
|
||||
} // end GetInput()
|
||||
|
||||
int cfg_text_count = 7;
|
||||
char cfg_text[][50] = {
|
||||
"Remapping ",
|
||||
"Press Any Button",
|
||||
"on the",
|
||||
" ", // identify controller
|
||||
" ",
|
||||
"Press C-Left or",
|
||||
"Home to exit"
|
||||
};
|
||||
|
||||
u32
|
||||
GetButtonMap(u16 ctrlr_type, char* btn_name)
|
||||
{
|
||||
u32 pressed, previous;
|
||||
char temp[50] = "";
|
||||
uint k;
|
||||
pressed = 0; previous = 1;
|
||||
|
||||
switch (ctrlr_type) {
|
||||
case CTRLR_NUNCHUK:
|
||||
strncpy (cfg_text[3], (char*)"NUNCHUK", 7);
|
||||
break;
|
||||
case CTRLR_CLASSIC:
|
||||
strncpy (cfg_text[3], (char*)"CLASSIC", 7);
|
||||
break;
|
||||
case CTRLR_GCPAD:
|
||||
strncpy (cfg_text[3], (char*)"GC PAD", 7);
|
||||
break;
|
||||
case CTRLR_WIIMOTE:
|
||||
strncpy (cfg_text[3], (char*)"WIIMOTE", 7);
|
||||
break;
|
||||
};
|
||||
|
||||
/*** note which button we are remapping ***/
|
||||
sprintf (temp, (char*)"Remapping ");
|
||||
for (k=0; k<9-strlen(btn_name); k++) strcat(temp, " "); // add whitespace padding to align text
|
||||
strncat (temp, btn_name, 9); // snes button we are remapping
|
||||
strncpy (cfg_text[0], temp, 19); // copy this all back to the text we wish to display
|
||||
|
||||
DrawMenu(&cfg_text[0], NULL, cfg_text_count, 1); // display text
|
||||
|
||||
// while (previous != pressed && pressed == 0); // get two consecutive button presses (which are the same)
|
||||
// {
|
||||
// previous = pressed;
|
||||
// VIDEO_WaitVSync(); // slow things down a bit so we don't overread the pads
|
||||
pressed = GetInput(ctrlr_type);
|
||||
// }
|
||||
return pressed;
|
||||
} // end getButtonMap()
|
||||
|
||||
int cfg_btns_count = 11;
|
||||
char cfg_btns_menu[][50] = {
|
||||
"A - ",
|
||||
"B - ",
|
||||
"L TRIG - ",
|
||||
"R TRIG - ",
|
||||
"SELECT - ",
|
||||
"START - ",
|
||||
"UP - ",
|
||||
"DOWN - ",
|
||||
"LEFT - ",
|
||||
"RIGHT - ",
|
||||
"Return to previous"
|
||||
};
|
||||
|
||||
extern unsigned int gcpadmap[];
|
||||
extern unsigned int wmpadmap[];
|
||||
extern unsigned int ccpadmap[];
|
||||
extern unsigned int ncpadmap[];
|
||||
|
||||
void
|
||||
ConfigureButtons (u16 ctrlr_type)
|
||||
{
|
||||
int quit = 0;
|
||||
int ret = 0;
|
||||
int oldmenu = menu;
|
||||
menu = 0;
|
||||
char* menu_title = NULL;
|
||||
u32 pressed;
|
||||
|
||||
unsigned int* currentpadmap = 0;
|
||||
char temp[50] = "";
|
||||
int i, j;
|
||||
uint k;
|
||||
|
||||
/*** Update Menu Title (based on controller we're configuring) ***/
|
||||
switch (ctrlr_type) {
|
||||
case CTRLR_NUNCHUK:
|
||||
menu_title = (char*)"VBA - NUNCHUK";
|
||||
currentpadmap = ncpadmap;
|
||||
break;
|
||||
case CTRLR_CLASSIC:
|
||||
menu_title = (char*)"VBA - CLASSIC";
|
||||
currentpadmap = ccpadmap;
|
||||
break;
|
||||
case CTRLR_GCPAD:
|
||||
menu_title = (char*)"VBA - GC PAD";
|
||||
currentpadmap = gcpadmap;
|
||||
break;
|
||||
case CTRLR_WIIMOTE:
|
||||
menu_title = (char*)"VBA - WIIMOTE";
|
||||
currentpadmap = wmpadmap;
|
||||
break;
|
||||
};
|
||||
|
||||
while (quit == 0)
|
||||
{
|
||||
/*** Update Menu with Current ButtonMap ***/
|
||||
for (i=0; i<10; i++) // vba pad has 10 buttons to config (go thru them)
|
||||
{
|
||||
// get current padmap button name to display
|
||||
for ( j=0;
|
||||
j < ctrlr_def[ctrlr_type].num_btns &&
|
||||
currentpadmap[i] != ctrlr_def[ctrlr_type].map[j].btn // match padmap button press with button names
|
||||
; j++ );
|
||||
|
||||
memset (temp, 0, sizeof(temp));
|
||||
strncpy (temp, cfg_btns_menu[i], 12); // copy vba button information
|
||||
if (currentpadmap[i] == ctrlr_def[ctrlr_type].map[j].btn) // check if a match was made
|
||||
{
|
||||
for (k=0; k<7-strlen(ctrlr_def[ctrlr_type].map[j].name) ;k++) strcat(temp, " "); // add whitespace padding to align text
|
||||
strncat (temp, ctrlr_def[ctrlr_type].map[j].name, 6); // update button map display
|
||||
}
|
||||
else
|
||||
strcat (temp, (char*)"---"); // otherwise, button is 'unmapped'
|
||||
strncpy (cfg_btns_menu[i], temp, 19); // move back updated information
|
||||
|
||||
}
|
||||
|
||||
ret = RunMenu (cfg_btns_menu, cfg_btns_count, menu_title, 16);
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
/*** Change button map ***/
|
||||
// wait for input
|
||||
memset (temp, 0, sizeof(temp));
|
||||
strncpy(temp, cfg_btns_menu[ret], 6); // get the name of the vba button we're changing
|
||||
pressed = GetButtonMap(ctrlr_type, temp); // get a button selection from user
|
||||
// FIX: check if input is valid for this controller
|
||||
if (pressed != 0) // check if a the button was configured, or if the user exited.
|
||||
currentpadmap[ret] = pressed; // update mapping
|
||||
break;
|
||||
|
||||
case -1: /*** Button B ***/
|
||||
case 12:
|
||||
/*** Return ***/
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
menu = oldmenu;
|
||||
} // end configurebuttons()
|
||||
|
||||
int ctlrmenucount = 6;
|
||||
char ctlrmenu[][50] = {
|
||||
"Nunchuk",
|
||||
"Classic Controller",
|
||||
"Wiimote",
|
||||
"Gamecube Pad",
|
||||
"Save Preferences",
|
||||
"Go Back"
|
||||
};
|
||||
|
||||
void
|
||||
ConfigureControllers ()
|
||||
{
|
||||
int quit = 0;
|
||||
int ret = 0;
|
||||
int oldmenu = menu;
|
||||
menu = 0;
|
||||
|
||||
// disable unavailable controller options if in GC mode
|
||||
#ifndef HW_RVL
|
||||
ctlrmenu[4][0] = '\0';
|
||||
ctlrmenu[5][0] = '\0';
|
||||
ctlrmenu[6][0] = '\0';
|
||||
#endif
|
||||
|
||||
while (quit == 0)
|
||||
{
|
||||
|
||||
/*** Controller Config Menu ***/
|
||||
ret = RunMenu (ctlrmenu, ctlrmenucount, (char*)"Configure Controllers");
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
|
||||
case 0:
|
||||
/*** Configure Nunchuk ***/
|
||||
ConfigureButtons (CTRLR_NUNCHUK);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/*** Configure Classic ***/
|
||||
ConfigureButtons (CTRLR_CLASSIC);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/*** Configure Wiimote ***/
|
||||
ConfigureButtons (CTRLR_WIIMOTE);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/*** Configure GC Pad ***/
|
||||
ConfigureButtons (CTRLR_GCPAD);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
/*** Save Preferences Now ***/
|
||||
SavePrefs(GCSettings.SaveMethod, NOTSILENT);
|
||||
break;
|
||||
|
||||
case -1: /*** Button B ***/
|
||||
case 5:
|
||||
/*** Return ***/
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
menu = oldmenu;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Main Menu
|
||||
***************************************************************************/
|
||||
int menucount = 7;
|
||||
char menuitems[][50] = {
|
||||
"Choose Game", "Controller Configuration", "Preferences",
|
||||
"Game Menu",
|
||||
"Credits", "Reset System", "Return to Loader"
|
||||
};
|
||||
|
||||
void
|
||||
mainmenu (int selectedMenu)
|
||||
{
|
||||
tb_t start,end;
|
||||
mftb(&start);
|
||||
StopAudio();
|
||||
|
||||
int quit = 0;
|
||||
int ret;
|
||||
|
||||
// disable game-specific menu items if a ROM isn't loaded
|
||||
if (ROMSize == 0 )
|
||||
menuitems[3][0] = '\0';
|
||||
else
|
||||
sprintf (menuitems[3], "Game Menu");
|
||||
|
||||
VIDEO_WaitVSync ();
|
||||
|
||||
while (quit == 0)
|
||||
{
|
||||
if(selectedMenu >= 0)
|
||||
{
|
||||
ret = selectedMenu;
|
||||
selectedMenu = -1; // default back to main menu
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = RunMenu (menuitems, menucount, (char*)"Main Menu");
|
||||
}
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
// Load ROM Menu
|
||||
quit = LoadManager ();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Configure Controllers
|
||||
ConfigureControllers ();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Preferences
|
||||
PreferencesMenu ();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// Game Options
|
||||
quit = GameMenu ();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// Credits
|
||||
Credits ();
|
||||
WaitButtonA ();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// Reset the Gamecube/Wii
|
||||
Reboot();
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// Exit to Loader
|
||||
#ifdef HW_RVL
|
||||
#ifdef WII_DVD
|
||||
DI_Close();
|
||||
#endif
|
||||
exit(0);
|
||||
#else // gamecube
|
||||
if (psoid[0] == PSOSDLOADID)
|
||||
PSOReload ();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case -1: // Button B
|
||||
// Return to Game
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*** Remove any still held buttons ***/
|
||||
#ifdef HW_RVL
|
||||
while( PAD_ButtonsHeld(0) || WPAD_ButtonsHeld(0) )
|
||||
VIDEO_WaitVSync();
|
||||
#else
|
||||
while( PAD_ButtonsHeld(0) )
|
||||
VIDEO_WaitVSync();
|
||||
#endif
|
||||
|
||||
StartAudio();
|
||||
mftb(&end);
|
||||
loadtimeradjust += tb_diff_msec(&end, &start);
|
||||
}
|
||||
|
19
source/ngc/menu.h
Normal file
19
source/ngc/menu.h
Normal file
@ -0,0 +1,19 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May-June 2007
|
||||
* Tantric August 2008
|
||||
*
|
||||
* menu.h
|
||||
*
|
||||
* Menu flow routines - handles all menu logic
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _NGCMENU_
|
||||
|
||||
#define _NGCMENU_
|
||||
|
||||
void mainmenu (int selectedMenu);
|
||||
|
||||
#endif
|
920
source/ngc/menudraw.cpp
Normal file
920
source/ngc/menudraw.cpp
Normal file
@ -0,0 +1,920 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 June 2007
|
||||
* Tantric August 2008
|
||||
*
|
||||
* menudraw.cpp
|
||||
*
|
||||
* Menu drawing routines
|
||||
*
|
||||
* Uses libfreetype 2.2.1 compiled for GC with TTF support only.
|
||||
* TTF only reduces the library by some 900k bytes!
|
||||
*
|
||||
* **WARNING***
|
||||
*
|
||||
* ONLY USE GUARANTEED PATENT FREE FONTS.
|
||||
***************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <ogcsys.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
#include <ft2build.h>
|
||||
#include <zlib.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include "video.h"
|
||||
#include "menudraw.h"
|
||||
#include "vba.h"
|
||||
#include "filesel.h"
|
||||
#include "dvd.h"
|
||||
#include "input.h"
|
||||
|
||||
/*** Globals ***/
|
||||
FT_Library ftlibrary;
|
||||
FT_Face face;
|
||||
FT_GlyphSlot slot;
|
||||
FT_UInt glyph_index;
|
||||
static unsigned int fonthi, fontlo;
|
||||
|
||||
extern char fontface[]; /*** From fontface.s ***/
|
||||
extern int fontsize; /*** From fontface.s ***/
|
||||
extern int screenheight;
|
||||
extern unsigned int *xfb[2];
|
||||
extern int whichfb;
|
||||
|
||||
/*** Permanent backdrop ***/
|
||||
#ifdef HW_RVL
|
||||
u32 *backdrop;
|
||||
#else
|
||||
static u32 *backdrop;
|
||||
#endif
|
||||
unsigned int getcolour (u8 r1, u8 g1, u8 b1);
|
||||
void DrawLineFast( int startx, int endx, int y, u8 r, u8 g, u8 b );
|
||||
u32 getrgb( u32 ycbr, u32 low );
|
||||
|
||||
/****************************************************************************
|
||||
* Initialisation of libfreetype
|
||||
***************************************************************************/
|
||||
int
|
||||
FT_Init ()
|
||||
{
|
||||
|
||||
int err;
|
||||
|
||||
err = FT_Init_FreeType (&ftlibrary);
|
||||
if (err)
|
||||
return 1;
|
||||
|
||||
err =
|
||||
FT_New_Memory_Face (ftlibrary, (FT_Byte *) fontface, fontsize, 0, &face);
|
||||
if (err)
|
||||
return 1;
|
||||
|
||||
setfontsize (16);
|
||||
setfontcolour (0xff, 0xff, 0xff);
|
||||
|
||||
slot = face->glyph;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* setfontsize
|
||||
*
|
||||
* Set the screen font size in pixels
|
||||
***************************************************************************/
|
||||
void
|
||||
setfontsize (int pixelsize)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = FT_Set_Pixel_Sizes (face, 0, pixelsize);
|
||||
|
||||
if (err)
|
||||
printf ("Error setting pixel sizes!");
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DrawCharacter
|
||||
* Draws a single character on the screen
|
||||
***************************************************************************/
|
||||
static void
|
||||
DrawCharacter (FT_Bitmap * bmp, FT_Int x, FT_Int y)
|
||||
{
|
||||
FT_Int i, j, p, q;
|
||||
FT_Int x_max = x + bmp->width;
|
||||
FT_Int y_max = y + bmp->rows;
|
||||
int spos;
|
||||
unsigned int pixel;
|
||||
int c;
|
||||
|
||||
for (i = x, p = 0; i < x_max; i++, p++)
|
||||
{
|
||||
for (j = y, q = 0; j < y_max; j++, q++)
|
||||
{
|
||||
if (i < 0 || j < 0 || i >= 640 || j >= screenheight)
|
||||
continue;
|
||||
|
||||
/*** Convert pixel position to GC int sizes ***/
|
||||
spos = (j * 320) + (i >> 1);
|
||||
|
||||
pixel = xfb[whichfb][spos];
|
||||
c = bmp->buffer[q * bmp->width + p];
|
||||
|
||||
/*** Cool Anti-Aliasing doesn't work too well at hires on GC ***/
|
||||
if (c > 128)
|
||||
{
|
||||
if (i & 1)
|
||||
pixel = (pixel & 0xffff0000) | fontlo;
|
||||
else
|
||||
pixel = ((pixel & 0xffff) | fonthi);
|
||||
|
||||
xfb[whichfb][spos] = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DrawText
|
||||
*
|
||||
* Place the font bitmap on the screen
|
||||
***************************************************************************/
|
||||
void
|
||||
DrawText (int x, int y, char *text)
|
||||
{
|
||||
int px, n;
|
||||
int i;
|
||||
int err;
|
||||
int value, count;
|
||||
|
||||
n = strlen (text);
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
setfontcolour (0x00, 0x00, 0x00);
|
||||
|
||||
/*** x == -1, auto centre ***/
|
||||
if (x == -1)
|
||||
{
|
||||
value = 0;
|
||||
px = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = 1;
|
||||
px = x;
|
||||
}
|
||||
|
||||
for (count = value; count < 2; count++)
|
||||
{
|
||||
/*** Draw the string ***/
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
err = FT_Load_Char (face, text[i], FT_LOAD_RENDER);
|
||||
|
||||
if (err)
|
||||
{
|
||||
printf ("Error %c %d\n", text[i], err);
|
||||
continue; /*** Skip unprintable characters ***/
|
||||
}
|
||||
|
||||
if (count)
|
||||
DrawCharacter (&slot->bitmap, px + slot->bitmap_left,
|
||||
y - slot->bitmap_top);
|
||||
|
||||
px += slot->advance.x >> 6;
|
||||
}
|
||||
|
||||
px = (640 - px) >> 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* setfontcolour
|
||||
*
|
||||
* Uses RGB triple values.
|
||||
***************************************************************************/
|
||||
void
|
||||
setfontcolour (u8 r, u8 g, u8 b)
|
||||
{
|
||||
u32 fontcolour;
|
||||
|
||||
fontcolour = getcolour (r, g, b);
|
||||
fonthi = fontcolour & 0xffff0000;
|
||||
fontlo = fontcolour & 0xffff;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Display credits, legal copyright and licence
|
||||
*
|
||||
* THIS MUST NOT BE REMOVED IN ANY DERIVATIVE WORK.
|
||||
***************************************************************************/
|
||||
void
|
||||
Credits ()
|
||||
{
|
||||
clearscreen ();
|
||||
|
||||
setfontcolour (0x00, 0x00, 0x00);
|
||||
|
||||
setfontsize (28);
|
||||
DrawText (-1, 60, (char*)"Credits");
|
||||
|
||||
int ypos = 25;
|
||||
|
||||
if (screenheight == 480)
|
||||
ypos += 52;
|
||||
else
|
||||
ypos += 32;
|
||||
|
||||
setfontsize (18);
|
||||
DrawText (-1, ypos += 30, (char*)"Technical");
|
||||
|
||||
setfontsize (14);
|
||||
DrawText (-1, ypos += 22, (char*)"Snes9x v1.5.1 - Snes9x Team");
|
||||
DrawText (-1, ypos += 18, (char*)"GameCube Port 2.0 WIP6 and earlier - SoftDev");
|
||||
DrawText (-1, ypos += 18, (char*)"Additional improvements to 2.0 WIP6 - eke-eke");
|
||||
DrawText (-1, ypos += 18, (char*)"GameCube 2.0.1bx enhancements - crunchy2");
|
||||
DrawText (-1, ypos += 18, (char*)"v00x updates - michniewski & Tantric");
|
||||
DrawText (-1, ypos += 18, (char*)"GX - http://www.gc-linux.org");
|
||||
DrawText (-1, ypos += 18, (char*)"libogc - Shagkur & wintermute");
|
||||
|
||||
setfontsize (18);
|
||||
DrawText (-1, ypos += 30, (char*)"Testing");
|
||||
|
||||
setfontsize (14);
|
||||
DrawText (-1, ypos += 22, (char*)"crunchy2 / tehskeen users / others");
|
||||
|
||||
setfontsize (18);
|
||||
DrawText (-1, ypos += 30, (char*)"Documentation");
|
||||
|
||||
setfontsize (14);
|
||||
DrawText (-1, ypos += 22, (char*)"brakken, crunchy2, michniewski");
|
||||
|
||||
setfontsize (12);
|
||||
DrawText (-1, ypos += 50, (char*)"Snes9x - Copyright (c) Snes9x Team 1996 - 2006");
|
||||
DrawText (-1, ypos += 15, (char*)"This software is open source and may be copied, distributed, or modified");
|
||||
DrawText (-1, ypos += 15, (char*)"under the terms of the GNU General Public License (GPL) Version 2.");
|
||||
|
||||
showscreen ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* getcolour
|
||||
*
|
||||
* Simply converts RGB to Y1CbY2Cr format
|
||||
*
|
||||
* I got this from a pastebin, so thanks to whoever originally wrote it!
|
||||
***************************************************************************/
|
||||
|
||||
unsigned int
|
||||
getcolour (u8 r1, u8 g1, u8 b1)
|
||||
{
|
||||
int y1, cb1, cr1, y2, cb2, cr2, cb, cr;
|
||||
u8 r2, g2, b2;
|
||||
|
||||
r2 = r1;
|
||||
g2 = g1;
|
||||
b2 = b1;
|
||||
|
||||
y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000;
|
||||
cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000;
|
||||
cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000;
|
||||
|
||||
y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000;
|
||||
cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000;
|
||||
cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000;
|
||||
|
||||
cb = (cb1 + cb2) >> 1;
|
||||
cr = (cr1 + cr2) >> 1;
|
||||
|
||||
return ((y1 << 24) | (cb << 16) | (y2 << 8) | cr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Wait for user to press A
|
||||
***************************************************************************/
|
||||
void
|
||||
WaitButtonA ()
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
while ( (PAD_ButtonsDown (0) & PAD_BUTTON_A) || (WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) ) VIDEO_WaitVSync();
|
||||
while (!(PAD_ButtonsDown (0) & PAD_BUTTON_A) && !(WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) ) VIDEO_WaitVSync();
|
||||
#else
|
||||
while ( PAD_ButtonsDown (0) & PAD_BUTTON_A ) VIDEO_WaitVSync();
|
||||
while (!(PAD_ButtonsDown (0) & PAD_BUTTON_A) ) VIDEO_WaitVSync();
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Wait for user to press A or B. Returns 0 = B; 1 = A
|
||||
***************************************************************************/
|
||||
|
||||
int
|
||||
WaitButtonAB ()
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
u32 gc_btns, wm_btns;
|
||||
|
||||
while ( (PAD_ButtonsDown (0) & (PAD_BUTTON_A | PAD_BUTTON_B))
|
||||
|| (WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_A | WPAD_CLASSIC_BUTTON_B))
|
||||
) VIDEO_WaitVSync();
|
||||
|
||||
while ( TRUE )
|
||||
{
|
||||
gc_btns = PAD_ButtonsDown (0);
|
||||
wm_btns = WPAD_ButtonsDown (0);
|
||||
if ( (gc_btns & PAD_BUTTON_A) || (wm_btns & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) )
|
||||
return 1;
|
||||
else if ( (gc_btns & PAD_BUTTON_B) || (wm_btns & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)) )
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
u32 gc_btns;
|
||||
|
||||
while ( (PAD_ButtonsDown (0) & (PAD_BUTTON_A | PAD_BUTTON_B)) ) VIDEO_WaitVSync();
|
||||
|
||||
while ( TRUE )
|
||||
{
|
||||
gc_btns = PAD_ButtonsDown (0);
|
||||
if ( gc_btns & PAD_BUTTON_A )
|
||||
return 1;
|
||||
else if ( gc_btns & PAD_BUTTON_B )
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Show a prompt
|
||||
***************************************************************************/
|
||||
void
|
||||
WaitPrompt (char *msg)
|
||||
{
|
||||
int ypos = (screenheight - 64) >> 1;
|
||||
|
||||
if (screenheight == 480)
|
||||
ypos += 52;
|
||||
else
|
||||
ypos += 32;
|
||||
|
||||
clearscreen ();
|
||||
DrawText (-1, ypos, msg);
|
||||
ypos += 30;
|
||||
DrawText (-1, ypos, (char*)"Press A to continue");
|
||||
showscreen ();
|
||||
WaitButtonA ();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Show a prompt with choice of two options. Returns 1 if A button was pressed
|
||||
and 0 if B button was pressed.
|
||||
***************************************************************************/
|
||||
int
|
||||
WaitPromptChoice (char *msg, char *bmsg, char *amsg)
|
||||
{
|
||||
int ypos = (screenheight - 64) >> 1;
|
||||
|
||||
if (screenheight == 480)
|
||||
ypos += 37;
|
||||
else
|
||||
ypos += 17;
|
||||
|
||||
clearscreen ();
|
||||
DrawText (-1, ypos, msg);
|
||||
ypos += 60;
|
||||
char txt[80];
|
||||
sprintf (txt, "B = %s : A = %s", bmsg, amsg);
|
||||
DrawText (-1, ypos, txt);
|
||||
showscreen ();
|
||||
return WaitButtonAB ();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Show an action in progress
|
||||
***************************************************************************/
|
||||
void
|
||||
ShowAction (char *msg)
|
||||
{
|
||||
int ypos = (screenheight - 30) >> 1;
|
||||
|
||||
if (screenheight == 480)
|
||||
ypos += 52;
|
||||
else
|
||||
ypos += 32;
|
||||
|
||||
clearscreen ();
|
||||
DrawText (-1, ypos, msg);
|
||||
showscreen ();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Generic Menu Routines
|
||||
***************************************************************************/
|
||||
void
|
||||
DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize, int x)
|
||||
{
|
||||
int i, w = 0;
|
||||
int ypos = 0;
|
||||
int n = 1;
|
||||
int line_height;
|
||||
|
||||
ypos = 45;
|
||||
|
||||
if (screenheight == 480)
|
||||
ypos += 52;
|
||||
else
|
||||
ypos += 32;
|
||||
|
||||
clearscreen ();
|
||||
|
||||
setfontcolour (0, 0, 0);
|
||||
|
||||
if (title != NULL)
|
||||
{
|
||||
setfontsize (28);
|
||||
DrawText (-1, 60, title);
|
||||
}
|
||||
|
||||
setfontsize (12);
|
||||
DrawText (510, screenheight - 20, VERSIONSTR);
|
||||
|
||||
// Draw menu items
|
||||
|
||||
setfontsize (fontsize); // set font size
|
||||
|
||||
line_height = (fontsize + 8);
|
||||
|
||||
for (i = 0; i < maxitems; i++)
|
||||
{
|
||||
if(strlen(items[i]) > 0)
|
||||
{
|
||||
if ( items[i] == NULL )
|
||||
ypos -= line_height;
|
||||
else if (i == selected)
|
||||
{
|
||||
for( w = 0; w < line_height; w++ )
|
||||
DrawLineFast( 30, 610, n * line_height + (ypos-line_height+6) + w, 0x80, 0x80, 0x80 );
|
||||
|
||||
setfontcolour (0xff, 0xff, 0xff);
|
||||
DrawText (x, n * line_height + ypos, items[i]);
|
||||
setfontcolour (0x00, 0x00, 0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText (x, n * line_height + ypos, items[i]);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
showscreen ();
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* FindMenuItem
|
||||
*
|
||||
* Help function to find the next visible menu item on the list
|
||||
* Supports menu wrap-around
|
||||
***************************************************************************/
|
||||
|
||||
int FindMenuItem(char items[][50], int maxitems, int currentItem, int direction)
|
||||
{
|
||||
int nextItem = currentItem + direction;
|
||||
|
||||
if(nextItem < 0)
|
||||
nextItem = maxitems-1;
|
||||
else if(nextItem >= maxitems)
|
||||
nextItem = 0;
|
||||
|
||||
if(strlen(items[nextItem]) > 0)
|
||||
return nextItem;
|
||||
else
|
||||
return FindMenuItem(&items[0], maxitems, nextItem, direction);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* RunMenu
|
||||
*
|
||||
* Call this with the menu array defined in menu.cpp
|
||||
* It's here to keep all the font / interface stuff together.
|
||||
***************************************************************************/
|
||||
int menu = 0;
|
||||
|
||||
int
|
||||
RunMenu (char items[][50], int maxitems, char *title, int fontsize, int x)
|
||||
{
|
||||
int redraw = 1;
|
||||
int quit = 0;
|
||||
int ret = 0;
|
||||
|
||||
u32 p = 0;
|
||||
u32 wp = 0;
|
||||
signed char gc_ay = 0;
|
||||
signed char wm_ay = 0;
|
||||
|
||||
while (quit == 0)
|
||||
{
|
||||
if (redraw)
|
||||
{
|
||||
DrawMenu (&items[0], title, maxitems, menu, fontsize);
|
||||
redraw = 0;
|
||||
}
|
||||
|
||||
gc_ay = PAD_StickY (0);
|
||||
p = PAD_ButtonsDown (0);
|
||||
#ifdef HW_RVL
|
||||
wm_ay = WPAD_StickY (0,0);
|
||||
wp = WPAD_ButtonsDown (0);
|
||||
#endif
|
||||
|
||||
|
||||
VIDEO_WaitVSync(); // slow things down a bit so we don't overread the pads
|
||||
|
||||
/*** Look for up ***/
|
||||
if ( (p & PAD_BUTTON_UP) || (wp & (WPAD_BUTTON_UP | WPAD_CLASSIC_BUTTON_UP)) || (gc_ay > PADCAL) || (wm_ay > PADCAL) )
|
||||
{
|
||||
redraw = 1;
|
||||
menu = FindMenuItem(&items[0], maxitems, menu, -1);
|
||||
}
|
||||
|
||||
/*** Look for down ***/
|
||||
if ( (p & PAD_BUTTON_DOWN) || (wp & (WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN)) || (gc_ay < -PADCAL) || (wm_ay < -PADCAL) )
|
||||
{
|
||||
redraw = 1;
|
||||
menu = FindMenuItem(&items[0], maxitems, menu, +1);
|
||||
}
|
||||
|
||||
if ((p & PAD_BUTTON_A) || (wp & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)))
|
||||
{
|
||||
quit = 1;
|
||||
ret = menu;
|
||||
}
|
||||
|
||||
if ((p & PAD_BUTTON_B) || (wp & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)))
|
||||
{
|
||||
quit = -1;
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*** Wait for B button to be released before proceeding ***/
|
||||
while ( (PAD_ButtonsDown(0) & PAD_BUTTON_B)
|
||||
#ifdef HW_RVL
|
||||
|| (WPAD_ButtonsDown(0) & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
ret = -1;
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Showfile screen
|
||||
*
|
||||
* Display the file selection to the user
|
||||
***************************************************************************/
|
||||
|
||||
void
|
||||
ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection)
|
||||
{
|
||||
int i, j;
|
||||
char text[MAXPATHLEN];
|
||||
int ypos;
|
||||
int w;
|
||||
|
||||
clearscreen ();
|
||||
|
||||
setfontsize (28);
|
||||
DrawText (-1, 60, (char*)"Choose Game");
|
||||
|
||||
setfontsize(18);
|
||||
|
||||
ypos = (screenheight - ((PAGESIZE - 1) * 20)) >> 1;
|
||||
|
||||
if (screenheight == 480)
|
||||
ypos += 24;
|
||||
else
|
||||
ypos += 10;
|
||||
|
||||
j = 0;
|
||||
for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++)
|
||||
{
|
||||
if (filelist[i].flags) // if a dir
|
||||
{
|
||||
strcpy (text, "[");
|
||||
strcat (text, filelist[i].displayname);
|
||||
strcat (text, "]");
|
||||
}
|
||||
else
|
||||
{
|
||||
// hide file extension on listing (.7z, .fig, .smc)
|
||||
StripExt(text, filelist[i].displayname);
|
||||
}
|
||||
if (j == (selection - offset))
|
||||
{
|
||||
/*** Highlighted text entry ***/
|
||||
for ( w = 0; w < 20; w++ )
|
||||
DrawLineFast( 30, 610, ( j * 20 ) + (ypos-16) + w, 0x80, 0x80, 0x80 );
|
||||
|
||||
setfontcolour (0x00, 0x00, 0xe0);
|
||||
DrawText (50, (j * 20) + ypos, text);
|
||||
setfontcolour (0x00, 0x00, 0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*** Normal entry ***/
|
||||
DrawText (50, (j * 20) + ypos, text);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
showscreen ();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Cheats screen
|
||||
*
|
||||
* Displays a scrollable list of cheats to the user
|
||||
***************************************************************************/
|
||||
|
||||
void
|
||||
ShowCheats (char items[][50], char itemvalues[][50], int maxitems, int offset, int selection)
|
||||
{
|
||||
int i, j = 0;
|
||||
int ypos;
|
||||
int w;
|
||||
|
||||
clearscreen ();
|
||||
|
||||
setfontsize (28);
|
||||
DrawText (-1, 60, (char*)"Cheats");
|
||||
|
||||
setfontsize(18);
|
||||
|
||||
ypos = (screenheight - ((PAGESIZE - 1) * 20)) >> 1;
|
||||
|
||||
if (screenheight == 480)
|
||||
ypos += 24;
|
||||
else
|
||||
ypos += 10;
|
||||
|
||||
for (i = offset; i < (offset + PAGESIZE) && (i < maxitems); i++)
|
||||
{
|
||||
if (i == selection)
|
||||
{
|
||||
/*** Highlighted text entry ***/
|
||||
for ( w = 0; w < 20; w++ )
|
||||
DrawLineFast( 30, 610, ( j * 20 ) + (ypos-16) + w, 0x80, 0x80, 0x80 );
|
||||
|
||||
DrawText (150, (j * 20) + ypos, items[i]);
|
||||
DrawText (400, (j * 20) + ypos, itemvalues[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*** Normal entry ***/
|
||||
DrawText (150, (j * 20) + ypos, items[i]);
|
||||
DrawText (400, (j * 20) + ypos, itemvalues[i]);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
showscreen ();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* DrawLine
|
||||
*
|
||||
* Quick'n'Dirty Bresenham line drawing routine.
|
||||
***************************************************************************/
|
||||
#define SIGN(x) ((x<0)?-1:((x>0)?1:0))
|
||||
|
||||
void
|
||||
DrawLine (int x1, int y1, int x2, int y2, u8 r, u8 g, u8 b)
|
||||
{
|
||||
u32 colour, pixel;
|
||||
u32 colourhi, colourlo;
|
||||
int i, dx, dy, sdx, sdy, dxabs, dyabs, x, y, px, py;
|
||||
int sp;
|
||||
|
||||
colour = getcolour (r, g, b);
|
||||
colourhi = colour & 0xffff0000;
|
||||
colourlo = colour & 0xffff;
|
||||
|
||||
dx = x2 - x1; /*** Horizontal distance ***/
|
||||
dy = y2 - y1; /*** Vertical distance ***/
|
||||
|
||||
dxabs = abs (dx);
|
||||
dyabs = abs (dy);
|
||||
sdx = SIGN (dx);
|
||||
sdy = SIGN (dy);
|
||||
x = dyabs >> 1;
|
||||
y = dxabs >> 1;
|
||||
px = x1;
|
||||
py = y1;
|
||||
|
||||
sp = (py * 320) + (px >> 1);
|
||||
pixel = xfb[whichfb][sp];
|
||||
/*** Plot this pixel ***/
|
||||
if (px & 1)
|
||||
xfb[whichfb][sp] = (pixel & 0xffff0000) | colourlo;
|
||||
else
|
||||
xfb[whichfb][sp] = (pixel & 0xffff) | colourhi;
|
||||
|
||||
if (dxabs >= dyabs) /*** Mostly horizontal ***/
|
||||
{
|
||||
for (i = 0; i < dxabs; i++)
|
||||
{
|
||||
y += dyabs;
|
||||
if (y >= dxabs)
|
||||
{
|
||||
y -= dxabs;
|
||||
py += sdy;
|
||||
}
|
||||
|
||||
px += sdx;
|
||||
|
||||
sp = (py * 320) + (px >> 1);
|
||||
pixel = xfb[whichfb][sp];
|
||||
|
||||
if (px & 1)
|
||||
xfb[whichfb][sp] = (pixel & 0xffff0000) | colourlo;
|
||||
else
|
||||
xfb[whichfb][sp] = (pixel & 0xffff) | colourhi;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < dyabs; i++)
|
||||
{
|
||||
x += dxabs;
|
||||
if (x >= dyabs)
|
||||
{
|
||||
x -= dyabs;
|
||||
px += sdx;
|
||||
}
|
||||
|
||||
py += sdy;
|
||||
|
||||
sp = (py * 320) + (px >> 1);
|
||||
pixel = xfb[whichfb][sp];
|
||||
|
||||
if (px & 1)
|
||||
xfb[whichfb][sp] = (pixel & 0xffff0000) | colourlo;
|
||||
else
|
||||
xfb[whichfb][sp] = (pixel & 0xffff) | colourhi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Progress Bar
|
||||
*
|
||||
* Show the user what's happening
|
||||
***************************************************************************/
|
||||
void
|
||||
ShowProgress (char *msg, int done, int total)
|
||||
{
|
||||
int ypos = (screenheight - 30) >> 1;
|
||||
|
||||
if (screenheight == 480)
|
||||
ypos += 52;
|
||||
else
|
||||
ypos += 32;
|
||||
|
||||
int xpos;
|
||||
int i;
|
||||
|
||||
clearscreen ();
|
||||
DrawText (-1, ypos, msg);
|
||||
|
||||
/*** Draw a white outline box ***/
|
||||
for (i = 380; i < 401; i++)
|
||||
DrawLine (100, i, 540, i, 0xff, 0xff, 0xff);
|
||||
|
||||
/*** Show progess ***/
|
||||
xpos = (int) (((float) done / (float) total) * 438);
|
||||
|
||||
for (i = 381; i < 400; i++)
|
||||
DrawLine (101, i, 101 + xpos, i, 0x00, 0x00, 0x80);
|
||||
|
||||
showscreen ();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DrawPolygon
|
||||
***************************************************************************/
|
||||
void
|
||||
DrawPolygon (int vertices, int varray[], u8 r, u8 g, u8 b)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vertices - 1; i++)
|
||||
{
|
||||
DrawLine (varray[(i << 1)], varray[(i << 1) + 1], varray[(i << 1) + 2],
|
||||
varray[(i << 1) + 3], r, g, b);
|
||||
}
|
||||
|
||||
DrawLine (varray[0], varray[1], varray[(vertices << 1) - 2],
|
||||
varray[(vertices << 1) - 1], r, g, b);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Draw Line Fast
|
||||
*
|
||||
* This routine requires that start and endx are 32bit aligned.
|
||||
* It tries to perform a semi-transparency over the existing image.
|
||||
***************************************************************************/
|
||||
|
||||
#define SRCWEIGHT 0.7f
|
||||
#define DSTWEIGHT (1.0f - SRCWEIGHT)
|
||||
|
||||
static inline u8 c_adjust( u8 c , float weight )
|
||||
{
|
||||
return (u8)((float)c * weight);
|
||||
}
|
||||
|
||||
void DrawLineFast( int startx, int endx, int y, u8 r, u8 g, u8 b )
|
||||
{
|
||||
int width;
|
||||
u32 offset;
|
||||
int i;
|
||||
u32 colour, clo, chi;
|
||||
u32 lo,hi;
|
||||
u8 *s, *d;
|
||||
|
||||
//colour = getcolour(r, g, b);
|
||||
colour = ( r << 16 | g << 8 | b );
|
||||
d = (u8 *)&colour;
|
||||
d[1] = c_adjust(d[1], DSTWEIGHT);
|
||||
d[2] = c_adjust(d[2], DSTWEIGHT);
|
||||
d[3] = c_adjust(d[3], DSTWEIGHT);
|
||||
|
||||
width = ( endx - startx ) >> 1;
|
||||
offset = ( y << 8 ) + ( y << 6 ) + ( startx >> 1 );
|
||||
|
||||
for ( i = 0; i < width; i++ )
|
||||
{
|
||||
lo = getrgb(xfb[whichfb][offset], 0);
|
||||
hi = getrgb(xfb[whichfb][offset], 1);
|
||||
|
||||
s = (u8 *)&hi;
|
||||
s[1] = ( ( c_adjust(s[1],SRCWEIGHT) ) + d[1] );
|
||||
s[2] = ( ( c_adjust(s[2],SRCWEIGHT) ) + d[2] );
|
||||
s[3] = ( ( c_adjust(s[3],SRCWEIGHT) ) + d[3] );
|
||||
|
||||
s = (u8 *)&lo;
|
||||
s[1] = ( ( c_adjust(s[1],SRCWEIGHT) ) + d[1] );
|
||||
s[2] = ( ( c_adjust(s[2],SRCWEIGHT) ) + d[2] );
|
||||
s[3] = ( ( c_adjust(s[3],SRCWEIGHT) ) + d[3] );
|
||||
|
||||
clo = getcolour( s[1], s[2], s[3] );
|
||||
s = (u8 *)&hi;
|
||||
chi = getcolour( s[1], s[2], s[3] );
|
||||
|
||||
xfb[whichfb][offset++] = (chi & 0xffff0000 ) | ( clo & 0xffff) ;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Ok, I'm useless with Y1CBY2CR colour.
|
||||
* So convert back to RGB so I can work with it -;)
|
||||
***************************************************************************/
|
||||
u32 getrgb( u32 ycbr, u32 low )
|
||||
{
|
||||
u8 r,g,b;
|
||||
u32 y;
|
||||
s8 cb,cr;
|
||||
|
||||
if ( low )
|
||||
y = ( ycbr & 0xff00 ) >> 8;
|
||||
else
|
||||
y = ( ycbr & 0xff000000 ) >> 24;
|
||||
|
||||
cr = ycbr & 0xff;
|
||||
cb = ( ycbr & 0xff0000 ) >> 16;
|
||||
|
||||
cr -= 128;
|
||||
cb -= 128;
|
||||
|
||||
r = (u8)((float)y + 1.371 * (float)cr);
|
||||
g = (u8)((float)y - 0.698 * (float)cr - 0.336 * (float)cb);
|
||||
b = (u8)((float)y + 1.732 * (float)cb);
|
||||
|
||||
return (u32)( r << 16 | g << 8 | b );
|
||||
|
||||
}
|
46
source/ngc/menudraw.h
Normal file
46
source/ngc/menudraw.h
Normal file
@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 June 2007
|
||||
* Tantric August 2008
|
||||
*
|
||||
* menudraw.h
|
||||
*
|
||||
* Menu drawing routines
|
||||
*
|
||||
* Uses libfreetype 2.2.1 compiled for GC with TTF support only.
|
||||
* TTF only reduces the library by some 900k bytes!
|
||||
*
|
||||
* **WARNING***
|
||||
*
|
||||
* ONLY USE GUARANTEED PATENT FREE FONTS.
|
||||
***************************************************************************/
|
||||
#ifndef _NGCMENUDRAW_
|
||||
#define _NGCMENUDRAW_
|
||||
|
||||
#include "filesel.h"
|
||||
|
||||
#define PAGESIZE 17 // max item listing on a screen
|
||||
|
||||
int FT_Init ();
|
||||
void setfontsize (int pixelsize);
|
||||
void setfontcolour (u8 r, u8 g, u8 b);
|
||||
void DrawText (int x, int y, char *text);
|
||||
void unpackbackdrop ();
|
||||
void Credits ();
|
||||
void RomInfo ();
|
||||
void WaitButtonA ();
|
||||
int RunMenu (char items[][50], int maxitems, char *title, int fontsize = 20, int x = -1);
|
||||
void DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize = 20, int x = -1);
|
||||
void ShowCheats (char items[][50], char itemvalues[][50], int maxitems, int offset, int selection);
|
||||
void ShowFiles (FILEENTRIES filelist[], int maxfiles, int offset, int selection);
|
||||
|
||||
void WaitPrompt (char *msg);
|
||||
int WaitPromptChoice (char *msg, char* bmsg, char* amsg);
|
||||
void ShowAction (char *msg);
|
||||
void ShowProgress (char *msg, int done, int total);
|
||||
void DrawPolygon (int vertices, int *varray, u8 r, u8 g, u8 b);
|
||||
void DrawLineFast( int startx, int endx, int y, u8 r, u8 g, u8 b );
|
||||
|
||||
#endif
|
392
source/ngc/preferences.cpp
Normal file
392
source/ngc/preferences.cpp
Normal file
@ -0,0 +1,392 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* Tantric September 2008
|
||||
*
|
||||
* preferences.cpp
|
||||
*
|
||||
* Preferences save/load to XML file
|
||||
***************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
#include <mxml.h>
|
||||
|
||||
#include "vba.h"
|
||||
#include "images/saveicon.h"
|
||||
#include "menudraw.h"
|
||||
#include "memcardop.h"
|
||||
#include "fileop.h"
|
||||
#include "smbop.h"
|
||||
#include "filesel.h"
|
||||
|
||||
extern unsigned char savebuffer[];
|
||||
extern int currconfig[4];
|
||||
|
||||
// button map configurations
|
||||
extern unsigned int gcpadmap[];
|
||||
extern unsigned int wmpadmap[];
|
||||
extern unsigned int ccpadmap[];
|
||||
extern unsigned int ncpadmap[];
|
||||
|
||||
#define PREFS_FILE_NAME "SNES9xGX.xml"
|
||||
|
||||
char prefscomment[2][32];
|
||||
|
||||
/****************************************************************************
|
||||
* Prepare Preferences Data
|
||||
*
|
||||
* This sets up the save buffer for saving.
|
||||
***************************************************************************/
|
||||
mxml_node_t *xml;
|
||||
mxml_node_t *data;
|
||||
mxml_node_t *section;
|
||||
mxml_node_t *item;
|
||||
mxml_node_t *elem;
|
||||
|
||||
char temp[200];
|
||||
|
||||
const char * toStr(int i)
|
||||
{
|
||||
sprintf(temp, "%d", i);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void createXMLSection(const char * name, const char * description)
|
||||
{
|
||||
section = mxmlNewElement(data, "section");
|
||||
mxmlElementSetAttr(section, "name", name);
|
||||
mxmlElementSetAttr(section, "description", description);
|
||||
}
|
||||
|
||||
void createXMLSetting(const char * name, const char * description, const char * value)
|
||||
{
|
||||
item = mxmlNewElement(section, "setting");
|
||||
mxmlElementSetAttr(item, "name", name);
|
||||
mxmlElementSetAttr(item, "value", value);
|
||||
mxmlElementSetAttr(item, "description", description);
|
||||
}
|
||||
|
||||
void createXMLController(unsigned int controller[], const char * name, const char * description)
|
||||
{
|
||||
item = mxmlNewElement(section, "controller");
|
||||
mxmlElementSetAttr(item, "name", name);
|
||||
mxmlElementSetAttr(item, "description", description);
|
||||
|
||||
// create buttons
|
||||
for(int i=0; i < 12; i++)
|
||||
{
|
||||
elem = mxmlNewElement(item, "button");
|
||||
mxmlElementSetAttr(elem, "number", toStr(i));
|
||||
mxmlElementSetAttr(elem, "assignment", toStr(controller[i]));
|
||||
}
|
||||
}
|
||||
|
||||
const char * XMLSaveCallback(mxml_node_t *node, int where)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = node->value.element.name;
|
||||
|
||||
if(where == MXML_WS_BEFORE_CLOSE)
|
||||
{
|
||||
if(!strcmp(name, "file") || !strcmp(name, "section"))
|
||||
return ("\n");
|
||||
else if(!strcmp(name, "controller"))
|
||||
return ("\n\t");
|
||||
}
|
||||
if (where == MXML_WS_BEFORE_OPEN)
|
||||
{
|
||||
if(!strcmp(name, "file"))
|
||||
return ("\n");
|
||||
else if(!strcmp(name, "section"))
|
||||
return ("\n\n");
|
||||
else if(!strcmp(name, "setting") || !strcmp(name, "controller"))
|
||||
return ("\n\t");
|
||||
else if(!strcmp(name, "button"))
|
||||
return ("\n\t\t");
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
preparePrefsData (int method)
|
||||
{
|
||||
int offset = 0;
|
||||
memset (savebuffer, 0, SAVEBUFFERSIZE);
|
||||
|
||||
// add save icon and comments for Memory Card saves
|
||||
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
||||
{
|
||||
offset = sizeof (saveicon);
|
||||
|
||||
// Copy in save icon
|
||||
memcpy (savebuffer, saveicon, offset);
|
||||
|
||||
// And the comments
|
||||
sprintf (prefscomment[0], "%s Prefs", VERSIONSTR);
|
||||
sprintf (prefscomment[1], "Preferences");
|
||||
memcpy (savebuffer + offset, prefscomment, 64);
|
||||
offset += 64;
|
||||
}
|
||||
|
||||
xml = mxmlNewXML("1.0");
|
||||
mxmlSetWrapMargin(0); // disable line wrapping
|
||||
|
||||
data = mxmlNewElement(xml, "file");
|
||||
mxmlElementSetAttr(data, "version",VERSIONSTR);
|
||||
|
||||
createXMLSection("File", "File Settings");
|
||||
|
||||
createXMLSetting("AutoLoad", "Auto Load", toStr(GCSettings.AutoLoad));
|
||||
createXMLSetting("AutoSave", "Auto Save", toStr(GCSettings.AutoSave));
|
||||
createXMLSetting("LoadMethod", "Load Method", toStr(GCSettings.LoadMethod));
|
||||
createXMLSetting("SaveMethod", "Save Method", toStr(GCSettings.SaveMethod));
|
||||
createXMLSetting("LoadFolder", "Load Folder", GCSettings.LoadFolder);
|
||||
createXMLSetting("SaveFolder", "Save Folder", GCSettings.SaveFolder);
|
||||
createXMLSetting("CheatFolder", "Cheats Folder", GCSettings.CheatFolder);
|
||||
createXMLSetting("VerifySaves", "Verify Memory Card Saves", toStr(GCSettings.VerifySaves));
|
||||
|
||||
createXMLSection("Network", "Network Settings");
|
||||
|
||||
createXMLSetting("smbip", "Share Computer IP", GCSettings.smbip);
|
||||
createXMLSetting("smbshare", "Share Name", GCSettings.smbshare);
|
||||
createXMLSetting("smbuser", "Share Username", GCSettings.smbuser);
|
||||
createXMLSetting("smbpwd", "Share Password", GCSettings.smbpwd);
|
||||
|
||||
createXMLSection("Emulation", "Emulation Settings");
|
||||
|
||||
createXMLSection("Controller", "Controller Settings");
|
||||
|
||||
createXMLController(gcpadmap, "gcpadmap", "GameCube Pad");
|
||||
createXMLController(wmpadmap, "wmpadmap", "Wiimote");
|
||||
createXMLController(ccpadmap, "ccpadmap", "Classic Controller");
|
||||
createXMLController(ncpadmap, "ncpadmap", "Nunchuk");
|
||||
|
||||
int datasize = mxmlSaveString(xml, (char *)savebuffer, SAVEBUFFERSIZE, XMLSaveCallback);
|
||||
|
||||
mxmlDelete(xml);
|
||||
|
||||
return datasize;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* loadXMLSetting
|
||||
*
|
||||
* Load XML elements into variables for an individual variable
|
||||
***************************************************************************/
|
||||
|
||||
void loadXMLSetting(char * var, const char * name)
|
||||
{
|
||||
item = mxmlFindElement(xml, xml, "setting", "name", name, MXML_DESCEND);
|
||||
if(item)
|
||||
sprintf(var, "%s", mxmlElementGetAttr(item, "value"));
|
||||
}
|
||||
void loadXMLSetting(int * var, const char * name)
|
||||
{
|
||||
item = mxmlFindElement(xml, xml, "setting", "name", name, MXML_DESCEND);
|
||||
if(item)
|
||||
*var = atoi(mxmlElementGetAttr(item, "value"));
|
||||
}
|
||||
void loadXMLSetting(bool * var, const char * name)
|
||||
{
|
||||
item = mxmlFindElement(xml, xml, "setting", "name", name, MXML_DESCEND);
|
||||
if(item)
|
||||
*var = atoi(mxmlElementGetAttr(item, "value"));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* loadXMLController
|
||||
*
|
||||
* Load XML elements into variables for a controller mapping
|
||||
***************************************************************************/
|
||||
|
||||
void loadXMLController(unsigned int controller[], const char * name)
|
||||
{
|
||||
item = mxmlFindElement(xml, xml, "controller", "name", name, MXML_DESCEND);
|
||||
|
||||
if(item)
|
||||
{
|
||||
// populate buttons
|
||||
for(int i=0; i < 12; i++)
|
||||
{
|
||||
elem = mxmlFindElement(item, xml, "button", "number", toStr(i), MXML_DESCEND);
|
||||
if(elem)
|
||||
controller[i] = atoi(mxmlElementGetAttr(elem, "assignment"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* decodePrefsData
|
||||
*
|
||||
* Decodes preferences - parses XML and loads preferences into the variables
|
||||
***************************************************************************/
|
||||
|
||||
bool
|
||||
decodePrefsData (int method)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
// skip save icon and comments for Memory Card saves
|
||||
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
||||
{
|
||||
offset = sizeof (saveicon);
|
||||
offset += 64; // sizeof prefscomment
|
||||
}
|
||||
|
||||
xml = mxmlLoadString(NULL, (char *)savebuffer+offset, MXML_TEXT_CALLBACK);
|
||||
|
||||
// check settings version
|
||||
// we don't do anything with the version #, but we'll store it anyway
|
||||
char * version;
|
||||
item = mxmlFindElement(xml, xml, "file", "version", NULL, MXML_DESCEND);
|
||||
if(item) // a version entry exists
|
||||
version = (char *)mxmlElementGetAttr(item, "version");
|
||||
else // version # not found, must be invalid
|
||||
return false;
|
||||
|
||||
// File Settings
|
||||
|
||||
loadXMLSetting(&GCSettings.AutoLoad, "AutoLoad");
|
||||
loadXMLSetting(&GCSettings.AutoSave, "AutoSave");
|
||||
loadXMLSetting(&GCSettings.LoadMethod, "LoadMethod");
|
||||
loadXMLSetting(&GCSettings.SaveMethod, "SaveMethod");
|
||||
loadXMLSetting(GCSettings.LoadFolder, "LoadFolder");
|
||||
loadXMLSetting(GCSettings.SaveFolder, "SaveFolder");
|
||||
loadXMLSetting(GCSettings.CheatFolder, "CheatFolder");
|
||||
loadXMLSetting(&GCSettings.VerifySaves, "VerifySaves");
|
||||
|
||||
// Network Settings
|
||||
|
||||
loadXMLSetting(GCSettings.smbip, "smbip");
|
||||
loadXMLSetting(GCSettings.smbshare, "smbshare");
|
||||
loadXMLSetting(GCSettings.smbuser, "smbuser");
|
||||
loadXMLSetting(GCSettings.smbpwd, "smbpwd");
|
||||
|
||||
// Emulation Settings
|
||||
|
||||
// Controller Settings
|
||||
|
||||
loadXMLController(gcpadmap, "gcpadmap");
|
||||
loadXMLController(wmpadmap, "wmpadmap");
|
||||
loadXMLController(ccpadmap, "ccpadmap");
|
||||
loadXMLController(ncpadmap, "ncpadmap");
|
||||
|
||||
mxmlDelete(xml);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Save Preferences
|
||||
***************************************************************************/
|
||||
bool
|
||||
SavePrefs (int method, bool silent)
|
||||
{
|
||||
if(method == METHOD_AUTO)
|
||||
method = autoSaveMethod();
|
||||
|
||||
char filepath[1024];
|
||||
int datasize;
|
||||
int offset = 0;
|
||||
|
||||
datasize = preparePrefsData (method);
|
||||
|
||||
if (!silent)
|
||||
ShowAction ((char*) "Saving preferences...");
|
||||
|
||||
if(method == METHOD_SD || method == METHOD_USB)
|
||||
{
|
||||
if(ChangeFATInterface(method, NOTSILENT))
|
||||
{
|
||||
sprintf (filepath, "%s/%s/%s", ROOTFATDIR, GCSettings.SaveFolder, PREFS_FILE_NAME);
|
||||
offset = SaveBufferToFAT (filepath, datasize, silent);
|
||||
}
|
||||
}
|
||||
else if(method == METHOD_SMB)
|
||||
{
|
||||
sprintf (filepath, "%s/%s", GCSettings.SaveFolder, PREFS_FILE_NAME);
|
||||
offset = SaveBufferToSMB (filepath, datasize, silent);
|
||||
}
|
||||
else if(method == METHOD_MC_SLOTA)
|
||||
{
|
||||
offset = SaveBufferToMC (savebuffer, CARD_SLOTA, (char *)PREFS_FILE_NAME, datasize, silent);
|
||||
}
|
||||
else if(method == METHOD_MC_SLOTB)
|
||||
{
|
||||
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent);
|
||||
}
|
||||
|
||||
if (offset > 0)
|
||||
{
|
||||
if (!silent)
|
||||
WaitPrompt ((char *)"Preferences saved");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Load Preferences from specified method
|
||||
***************************************************************************/
|
||||
bool
|
||||
LoadPrefsFromMethod (int method)
|
||||
{
|
||||
bool retval = false;
|
||||
char filepath[1024];
|
||||
int offset = 0;
|
||||
|
||||
if(method == METHOD_SD || method == METHOD_USB)
|
||||
{
|
||||
if(ChangeFATInterface(method, NOTSILENT))
|
||||
{
|
||||
sprintf (filepath, "%s/%s/%s", ROOTFATDIR, GCSettings.SaveFolder, PREFS_FILE_NAME);
|
||||
offset = LoadBufferFromFAT (filepath, SILENT);
|
||||
}
|
||||
}
|
||||
else if(method == METHOD_SMB)
|
||||
{
|
||||
sprintf (filepath, "%s/%s", GCSettings.SaveFolder, PREFS_FILE_NAME);
|
||||
offset = LoadBufferFromSMB (filepath, SILENT);
|
||||
}
|
||||
else if(method == METHOD_MC_SLOTA)
|
||||
{
|
||||
offset = LoadBufferFromMC (savebuffer, CARD_SLOTA, (char *)PREFS_FILE_NAME, SILENT);
|
||||
}
|
||||
else if(method == METHOD_MC_SLOTB)
|
||||
{
|
||||
offset = LoadBufferFromMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, SILENT);
|
||||
}
|
||||
|
||||
if (offset > 0)
|
||||
retval = decodePrefsData (method);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Load Preferences
|
||||
* Checks sources consecutively until we find a preference file
|
||||
***************************************************************************/
|
||||
bool LoadPrefs()
|
||||
{
|
||||
ShowAction ((char*) "Loading preferences...");
|
||||
bool prefFound = false;
|
||||
if(ChangeFATInterface(METHOD_SD, SILENT))
|
||||
prefFound = LoadPrefsFromMethod(METHOD_SD);
|
||||
if(!prefFound && ChangeFATInterface(METHOD_USB, SILENT))
|
||||
prefFound = LoadPrefsFromMethod(METHOD_USB);
|
||||
if(!prefFound && TestCard(CARD_SLOTA, SILENT))
|
||||
prefFound = LoadPrefsFromMethod(METHOD_MC_SLOTA);
|
||||
if(!prefFound && TestCard(CARD_SLOTB, SILENT))
|
||||
prefFound = LoadPrefsFromMethod(METHOD_MC_SLOTB);
|
||||
if(!prefFound && ConnectShare (SILENT))
|
||||
prefFound = LoadPrefsFromMethod(METHOD_SMB);
|
||||
|
||||
return prefFound;
|
||||
}
|
12
source/ngc/preferences.h
Normal file
12
source/ngc/preferences.h
Normal file
@ -0,0 +1,12 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* Tantric September 2008
|
||||
*
|
||||
* preferences.h
|
||||
*
|
||||
* Preferences save/load to XML file
|
||||
***************************************************************************/
|
||||
|
||||
bool SavePrefs (int method, bool silent);
|
||||
bool LoadPrefs ();
|
@ -50,7 +50,7 @@ int gen_fread( void *buffer, int len, int block, FILE* f )
|
||||
* SD Card fclose
|
||||
*/
|
||||
void gen_fclose( FILE* f )
|
||||
{
|
||||
{
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ int gen_fgetc( FILE* f )
|
||||
return fgetc(f);
|
||||
}
|
||||
|
||||
static struct stat _fstat;
|
||||
static struct stat _fstat;
|
||||
char filename[1024];
|
||||
int fcount = 0;
|
||||
|
||||
@ -83,15 +83,15 @@ int fcount = 0;
|
||||
int gen_getdir( char *thisdir )
|
||||
{
|
||||
memset(&direntries[0],0,MAXDIRENTRIES*255);
|
||||
|
||||
|
||||
DIR_ITER* dp = diropen( thisdir );
|
||||
|
||||
|
||||
if ( dp )
|
||||
{
|
||||
while ( dirnext(dp, filename, &_fstat) == 0 )
|
||||
{
|
||||
|
||||
// Skip any sub directories
|
||||
|
||||
// Skip any sub directories
|
||||
if ( !(_fstat.st_mode & S_IFDIR) )
|
||||
{
|
||||
memcpy(&direntries[fcount],&filename,strlen(filename));
|
||||
@ -100,9 +100,9 @@ int gen_getdir( char *thisdir )
|
||||
}
|
||||
dirclose(dp);
|
||||
}
|
||||
else
|
||||
else
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
return fcount;
|
||||
|
||||
|
339
source/ngc/smbop.cpp
Normal file
339
source/ngc/smbop.cpp
Normal file
@ -0,0 +1,339 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May 2007
|
||||
* Tantric August 2008
|
||||
*
|
||||
* smbload.cpp
|
||||
*
|
||||
* SMB support routines
|
||||
****************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
#include <network.h>
|
||||
#include <smb.h>
|
||||
#include <zlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "vba.h"
|
||||
#include "smbop.h"
|
||||
#include "gcunzip.h"
|
||||
#include "video.h"
|
||||
#include "menudraw.h"
|
||||
#include "filesel.h"
|
||||
|
||||
bool networkInit = false;
|
||||
bool networkShareInit = false;
|
||||
unsigned int SMBTimer = 0;
|
||||
#define SMBTIMEOUT ( 3600 ) // Some implementations timeout in 10 minutes
|
||||
|
||||
SMBCONN smbconn;
|
||||
#define ZIPCHUNK 16384
|
||||
|
||||
extern unsigned char savebuffer[];
|
||||
extern char output[16384];
|
||||
extern int offset;
|
||||
extern int selection;
|
||||
extern char currentdir[MAXPATHLEN];
|
||||
extern FILEENTRIES filelist[MAXFILES];
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* InitializeNetwork
|
||||
* Initializes the Wii/GameCube network interface
|
||||
****************************************************************************/
|
||||
|
||||
bool InitializeNetwork(bool silent)
|
||||
{
|
||||
ShowAction ((char*) "Initializing network...");
|
||||
s32 result;
|
||||
|
||||
while ((result = net_init()) == -EAGAIN);
|
||||
|
||||
if (result >= 0)
|
||||
{
|
||||
char myIP[16];
|
||||
|
||||
if (if_config(myIP, NULL, NULL, true) < 0)
|
||||
{
|
||||
if(!silent)
|
||||
WaitPrompt((char*) "Error reading IP address.");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!silent)
|
||||
WaitPrompt((char*) "Unable to initialize network.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Mount SMB Share
|
||||
****************************************************************************/
|
||||
|
||||
bool
|
||||
ConnectShare (bool silent)
|
||||
{
|
||||
// Crashes or stalls system in GameCube mode - so disable
|
||||
#ifndef HW_RVL
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// check that all parameter have been set
|
||||
if(strlen(GCSettings.smbuser) == 0 ||
|
||||
strlen(GCSettings.smbpwd) == 0 ||
|
||||
strlen(GCSettings.smbshare) == 0 ||
|
||||
strlen(GCSettings.smbip) == 0)
|
||||
{
|
||||
if(!silent)
|
||||
WaitPrompt((char*) "Invalid network settings. Check SNES9xGX.xml.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!networkInit)
|
||||
networkInit = InitializeNetwork(silent);
|
||||
|
||||
if(networkInit)
|
||||
{
|
||||
// connection may have expired
|
||||
if (networkShareInit && SMBTimer > SMBTIMEOUT)
|
||||
{
|
||||
networkShareInit = false;
|
||||
SMBTimer = 0;
|
||||
SMB_Close(smbconn);
|
||||
}
|
||||
|
||||
if(!networkShareInit)
|
||||
{
|
||||
if(!silent)
|
||||
ShowAction ((char*) "Connecting to network share...");
|
||||
|
||||
if(SMB_Connect(&smbconn, GCSettings.smbuser, GCSettings.smbpwd,
|
||||
GCSettings.smbgcid, GCSettings.smbsvid, GCSettings.smbshare, GCSettings.smbip) == SMB_SUCCESS)
|
||||
networkShareInit = true;
|
||||
}
|
||||
|
||||
if(!networkShareInit && !silent)
|
||||
WaitPrompt ((char*) "Failed to connect to network share.");
|
||||
}
|
||||
|
||||
return networkShareInit;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* SMBPath
|
||||
*
|
||||
* Returns a SMB-style path
|
||||
*****************************************************************************/
|
||||
|
||||
char * SMBPath(char * path)
|
||||
{
|
||||
// fix path - replace all '/' with '\'
|
||||
for(uint i=0; i < strlen(path); i++)
|
||||
if(path[i] == '/')
|
||||
path[i] = '\\';
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* parseSMBDirectory
|
||||
*
|
||||
* Load the directory and put in the filelist array
|
||||
*****************************************************************************/
|
||||
int
|
||||
ParseSMBdirectory ()
|
||||
{
|
||||
if(!ConnectShare (NOTSILENT))
|
||||
return 0;
|
||||
|
||||
int filecount = 0;
|
||||
char searchpath[1024];
|
||||
SMBDIRENTRY smbdir;
|
||||
|
||||
// initialize selection
|
||||
selection = offset = 0;
|
||||
|
||||
// Clear any existing values
|
||||
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
|
||||
|
||||
if(strlen(currentdir) <= 1) // root
|
||||
sprintf(searchpath, "*");
|
||||
else
|
||||
sprintf(searchpath, "%s/*", currentdir);
|
||||
|
||||
if (SMB_FindFirst
|
||||
(SMBPath(searchpath), SMB_SRCH_READONLY | SMB_SRCH_DIRECTORY, &smbdir, smbconn) != SMB_SUCCESS)
|
||||
{
|
||||
char msg[200];
|
||||
sprintf(msg, "Could not open %s", currentdir);
|
||||
WaitPrompt (msg);
|
||||
|
||||
// if we can't open the dir, open root dir
|
||||
sprintf(searchpath, "/");
|
||||
sprintf(searchpath,"*");
|
||||
|
||||
if (SMB_FindFirst
|
||||
(SMBPath(searchpath), SMB_SRCH_READONLY | SMB_SRCH_DIRECTORY, &smbdir, smbconn) != SMB_SUCCESS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// index files/folders
|
||||
do
|
||||
{
|
||||
if(strcmp(smbdir.name,".") != 0 &&
|
||||
!(strlen(currentdir) <= 1 && strcmp(smbdir.name,"..") == 0))
|
||||
{
|
||||
memset (&filelist[filecount], 0, sizeof (FILEENTRIES));
|
||||
filelist[filecount].length = smbdir.size_low;
|
||||
smbdir.name[MAXJOLIET] = 0;
|
||||
|
||||
if(smbdir.attributes == SMB_SRCH_DIRECTORY)
|
||||
filelist[filecount].flags = 1; // flag this as a dir
|
||||
else
|
||||
filelist[filecount].flags = 0;
|
||||
|
||||
// Update display name
|
||||
memcpy (&filelist[filecount].displayname, smbdir.name, MAXDISPLAY);
|
||||
filelist[filecount].displayname[MAXDISPLAY] = 0;
|
||||
|
||||
strcpy (filelist[filecount].filename, smbdir.name);
|
||||
filecount++;
|
||||
}
|
||||
} while (SMB_FindNext (&smbdir, smbconn) == SMB_SUCCESS);
|
||||
|
||||
// close directory
|
||||
SMB_FindClose (smbconn);
|
||||
|
||||
// Sort the file list
|
||||
qsort(filelist, filecount, sizeof(FILEENTRIES), FileSortCallback);
|
||||
|
||||
return filecount;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Load SMB file
|
||||
****************************************************************************/
|
||||
int
|
||||
LoadSMBFile (char *filename, int length)
|
||||
{
|
||||
char filepath[MAXPATHLEN];
|
||||
|
||||
/* Check filename length */
|
||||
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
|
||||
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
|
||||
else
|
||||
{
|
||||
WaitPrompt((char*) "Maximum filepath length reached!");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
//return LoadBufferFromSMB((char *)Memory.ROM, SMBPath(filepath), NOTSILENT);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Write savebuffer to SMB file
|
||||
****************************************************************************/
|
||||
int
|
||||
SaveBufferToSMB (char *filepath, int datasize, bool silent)
|
||||
{
|
||||
if(!ConnectShare (NOTSILENT))
|
||||
return 0;
|
||||
|
||||
SMBFILE smbfile;
|
||||
int dsize = datasize;
|
||||
int wrote = 0;
|
||||
int boffset = 0;
|
||||
|
||||
smbfile =
|
||||
SMB_OpenFile (SMBPath(filepath), SMB_OPEN_WRITING | SMB_DENY_NONE,
|
||||
SMB_OF_CREATE | SMB_OF_TRUNCATE, smbconn);
|
||||
|
||||
if (smbfile)
|
||||
{
|
||||
while (dsize > 0)
|
||||
{
|
||||
if (dsize > 1024)
|
||||
wrote =
|
||||
SMB_WriteFile ((char *) savebuffer + boffset, 1024, boffset, smbfile);
|
||||
else
|
||||
wrote =
|
||||
SMB_WriteFile ((char *) savebuffer + boffset, dsize, boffset, smbfile);
|
||||
|
||||
boffset += wrote;
|
||||
dsize -= wrote;
|
||||
}
|
||||
SMB_CloseFile (smbfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
char msg[100];
|
||||
sprintf(msg, "Couldn't save SMB: %s", SMBPath(filepath));
|
||||
WaitPrompt (msg);
|
||||
}
|
||||
|
||||
ClearSaveBuffer ();
|
||||
return boffset;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Load up a buffer from SMB file
|
||||
****************************************************************************/
|
||||
|
||||
// no buffer is specified - so use savebuffer
|
||||
int
|
||||
LoadBufferFromSMB (char *filepath, bool silent)
|
||||
{
|
||||
ClearSaveBuffer ();
|
||||
return LoadBufferFromSMB((char *)savebuffer, filepath, silent);
|
||||
}
|
||||
|
||||
int
|
||||
LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent)
|
||||
{
|
||||
if(!ConnectShare (NOTSILENT))
|
||||
return 0;
|
||||
|
||||
SMBFILE smbfile;
|
||||
int ret;
|
||||
int boffset = 0;
|
||||
|
||||
smbfile =
|
||||
SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn);
|
||||
|
||||
if (!smbfile)
|
||||
{
|
||||
if(!silent)
|
||||
{
|
||||
char msg[100];
|
||||
sprintf(msg, "Couldn't open SMB: %s", SMBPath(filepath));
|
||||
WaitPrompt (msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile);
|
||||
|
||||
if (IsZipFile (sbuffer))
|
||||
{
|
||||
boffset = UnZipFile ((unsigned char *)sbuffer, smbfile); // unzip from SMB
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just load the file up
|
||||
while ((ret = SMB_ReadFile (sbuffer + boffset, 1024, boffset, smbfile)) > 0)
|
||||
boffset += ret;
|
||||
}
|
||||
SMB_CloseFile (smbfile);
|
||||
|
||||
return boffset;
|
||||
}
|
27
source/ngc/smbop.h
Normal file
27
source/ngc/smbop.h
Normal file
@ -0,0 +1,27 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May 2007
|
||||
* Tantric August 2008
|
||||
*
|
||||
* smbload.h
|
||||
*
|
||||
* SMB support routines
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _NGCSMB_
|
||||
|
||||
#define _NGCSMB_
|
||||
|
||||
bool InitializeNetwork(bool silent);
|
||||
bool ConnectShare (bool silent);
|
||||
char * SMBPath(char * path);
|
||||
int UpdateSMBdirname();
|
||||
int ParseSMBdirectory ();
|
||||
int LoadSMBFile (char *filename, int length);
|
||||
int LoadBufferFromSMB (char *filepath, bool silent);
|
||||
int LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent);
|
||||
int SaveBufferToSMB (char *filepath, int datasize, bool silent);
|
||||
|
||||
#endif
|
@ -3,10 +3,9 @@
|
||||
****************************************************************************/
|
||||
#ifndef __TMBINCTIMER__
|
||||
#define __TMBINCTIMER__
|
||||
#ifdef WII_BUILD
|
||||
#ifdef HW_RVL
|
||||
#define TB_CLOCK 60750000 //WII
|
||||
#endif
|
||||
#ifdef GC_BUILD
|
||||
#else
|
||||
#define TB_CLOCK 40500000
|
||||
#endif
|
||||
#define mftb(rval) ({unsigned long u; do { \
|
||||
|
107
source/ngc/vba.cpp
Normal file
107
source/ngc/vba.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/****************************************************************************
|
||||
* VisualBoyAdvance 1.7.2
|
||||
* Nintendo GameCube Wrapper
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ogcsys.h>
|
||||
#include <unistd.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
#include <sdcard/card_cmn.h>
|
||||
#include <sdcard/wiisd_io.h>
|
||||
#include <sdcard/card_io.h>
|
||||
#include <fat.h>
|
||||
|
||||
#ifdef WII_DVD
|
||||
extern "C" {
|
||||
#include <di/di.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "vbasupport.h"
|
||||
#include "audio.h"
|
||||
#include "dvd.h"
|
||||
#include "smbop.h"
|
||||
#include "menu.h"
|
||||
#include "menudraw.h"
|
||||
#include "input.h"
|
||||
#include "video.h"
|
||||
#include "vbaconfig.h"
|
||||
|
||||
extern int ROMSize;
|
||||
extern int emulating;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* main
|
||||
*
|
||||
* Program entry
|
||||
****************************************************************************/
|
||||
int main()
|
||||
{
|
||||
#ifdef WII_DVD
|
||||
DI_Init(); // first
|
||||
#endif
|
||||
|
||||
int selectedMenu = -1;
|
||||
|
||||
PAD_Init (); /*** Initialise pads for input ***/
|
||||
#ifdef HW_RVL
|
||||
WPAD_Init();
|
||||
// read wiimote accelerometer and IR data
|
||||
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
|
||||
WPAD_SetVRes(WPAD_CHAN_ALL,640,480);
|
||||
#endif
|
||||
|
||||
InitialiseVideo();
|
||||
|
||||
// Initialise freetype font system
|
||||
if (FT_Init ())
|
||||
{
|
||||
printf ("Cannot initialise font subsystem!\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
// Initialize libFAT for SD and USB
|
||||
fatInitDefault();
|
||||
|
||||
// Initialize DVD subsystem (GameCube only)
|
||||
#ifndef HW_RVL
|
||||
DVD_Init ();
|
||||
#endif
|
||||
|
||||
// Check if DVD drive belongs to a Wii
|
||||
SetDVDDriveType();
|
||||
|
||||
InitialiseSound();
|
||||
|
||||
InitialisePalette();
|
||||
|
||||
// Set defaults
|
||||
DefaultSettings ();
|
||||
|
||||
while (ROMSize == 0)
|
||||
{
|
||||
mainmenu (selectedMenu);
|
||||
}
|
||||
|
||||
//Main loop
|
||||
while(1)
|
||||
{
|
||||
while (emulating)
|
||||
{
|
||||
emulator.emuMain(emulator.emuCount);
|
||||
}
|
||||
}
|
||||
|
||||
// Never leaving here
|
||||
while(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
56
source/ngc/vba.h
Normal file
56
source/ngc/vba.h
Normal file
@ -0,0 +1,56 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May 2007-July 2007
|
||||
* Tantric September 2008
|
||||
*
|
||||
* snes9xGX.h
|
||||
*
|
||||
* This file controls overall program flow. Most things start and end here!
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _VBA_H_
|
||||
#define _VBA_H_
|
||||
|
||||
#include <gccore.h>
|
||||
|
||||
#define VERSIONNUM "1.0.0"
|
||||
#define VERSIONSTR "VBA 1.0.0"
|
||||
|
||||
#define NOTSILENT 0
|
||||
#define SILENT 1
|
||||
|
||||
enum {
|
||||
METHOD_AUTO,
|
||||
METHOD_SD,
|
||||
METHOD_USB,
|
||||
METHOD_DVD,
|
||||
METHOD_SMB,
|
||||
METHOD_MC_SLOTA,
|
||||
METHOD_MC_SLOTB
|
||||
};
|
||||
|
||||
struct SGCSettings{
|
||||
int AutoLoad;
|
||||
int AutoSave;
|
||||
int LoadMethod; // For ROMS: Auto, SD, DVD, USB, Network (SMB)
|
||||
int SaveMethod; // For SRAM, Freeze, Prefs: Auto, SD, Memory Card Slot A, Memory Card Slot B, USB, SMB
|
||||
char LoadFolder[200]; // Path to game files
|
||||
char SaveFolder[200]; // Path to save files
|
||||
char CheatFolder[200]; // Path to cheat files
|
||||
char gcip[16];
|
||||
char gwip[16];
|
||||
char mask[16];
|
||||
char smbip[16];
|
||||
char smbuser[20];
|
||||
char smbpwd[20];
|
||||
char smbgcid[20];
|
||||
char smbsvid[20];
|
||||
char smbshare[20];
|
||||
int VerifySaves;
|
||||
};
|
||||
|
||||
extern struct SGCSettings GCSettings;
|
||||
|
||||
#endif
|
@ -1,837 +0,0 @@
|
||||
/****************************************************************************
|
||||
* VisualBoyAdvance 1.7.2
|
||||
* Nintendo GameCube Wrapper
|
||||
****************************************************************************/
|
||||
#include <gccore.h>
|
||||
#include <ogcsys.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
|
||||
#ifdef WII_BUILD
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <ogc/conf.h>
|
||||
#include <math.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
extern s32 CONF_Init(void);
|
||||
}
|
||||
|
||||
extern int isClassicAvailable;
|
||||
extern int isWiimoteAvailable;
|
||||
|
||||
void setup_controllers()
|
||||
{ /* Doesn't work, either always returns
|
||||
WiimoteAvailable only or apparently switches
|
||||
REALLY fast between the two. WTF.
|
||||
|
||||
WPAD_ScanPads();
|
||||
WPADData pad;
|
||||
WPAD_ReadEvent(0, &pad);
|
||||
// User can use just wiimote
|
||||
if(pad.exp.type == WPAD_EXP_NONE)
|
||||
{
|
||||
isClassicAvailable = 0;
|
||||
isWiimoteAvailable = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// User can use a Classic controller
|
||||
else if(pad.exp.type == WPAD_EXP_CLASSIC)
|
||||
{
|
||||
isClassicAvailable = 1;
|
||||
WPAD_SetDataFormat(0, WPAD_FMT_BTNS);
|
||||
return;
|
||||
}
|
||||
// User will have to use a GC controller
|
||||
else
|
||||
{
|
||||
isClassicAvailable = 0;
|
||||
isWiimoteAvailable = 0;
|
||||
return;
|
||||
}
|
||||
*/
|
||||
isClassicAvailable = 1;
|
||||
isWiimoteAvailable = 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "mixer.h"
|
||||
#include "gcpad.h"
|
||||
#include "vmmem.h"
|
||||
#include "pal60.h"
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "gx_supp.h"
|
||||
#include "tbtime.h"
|
||||
#include "sdfileio.h"
|
||||
}
|
||||
|
||||
/** VBA **/
|
||||
#include "GBA.h"
|
||||
#include "agbprint.h"
|
||||
#include "Flash.h"
|
||||
#include "Port.h"
|
||||
#include "RTC.h"
|
||||
#include "Sound.h"
|
||||
#include "Text.h"
|
||||
#include "unzip.h"
|
||||
#include "Util.h"
|
||||
#include "gb/GB.h"
|
||||
#include "gb/gbGlobals.h"
|
||||
|
||||
/**
|
||||
* Globals
|
||||
*/
|
||||
int RGB_LOW_BITS_MASK=0x821;
|
||||
int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
||||
u16 systemGbPalette[24];
|
||||
int systemDebug = 0;
|
||||
int emulating = 0;
|
||||
int systemFrameSkip = 0;
|
||||
int systemRedShift = 0;
|
||||
int systemBlueShift = 0;
|
||||
int systemGreenShift = 0;
|
||||
int systemColorDepth = 0;
|
||||
int sensorX = 2047;
|
||||
int sensorY = 2047;
|
||||
u16 systemColorMap16[0x10000];
|
||||
//u32 systemColorMap32[0x10000];
|
||||
u32 *systemColorMap32 = (u32 *)&systemColorMap16;
|
||||
bool systemSoundOn = false;
|
||||
int systemVerbose = 0;
|
||||
int cartridgeType = 0;
|
||||
int srcWidth = 0;
|
||||
int srcHeight = 0;
|
||||
int destWidth = 0;
|
||||
int destHeight = 0;
|
||||
int srcPitch = 0;
|
||||
int saveExists = 0;
|
||||
extern int menuCalled;
|
||||
#define WITHGX 1
|
||||
#define DEBUGON 0
|
||||
|
||||
|
||||
|
||||
#if DEBUGON
|
||||
const char *dbg_local_ip = "192.168.1.32";
|
||||
const char *dbg_netmask = "255.255.255.0";
|
||||
const char *dbg_gw = "192.168.1.100";
|
||||
#endif
|
||||
|
||||
/*** 2D Video Globals ***/
|
||||
GXRModeObj *vmode; /*** Graphics Mode Object ***/
|
||||
u32 *xfb[2] = { NULL, NULL }; /*** Framebuffers ***/
|
||||
int whichfb = 0; /*** Frame buffer toggle ***/
|
||||
|
||||
void debuggerOutput(char *, u32)
|
||||
{}
|
||||
|
||||
void (*dbgOutput)(char *, u32) = debuggerOutput;
|
||||
|
||||
/**
|
||||
* Locals
|
||||
*/
|
||||
|
||||
extern char *MENU_GetLoadFile( char *whichdir );
|
||||
extern void MENU_DrawString( int x, int y, char *msg, int style );
|
||||
|
||||
struct EmulatedSystem emulator =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
false,
|
||||
0
|
||||
};
|
||||
|
||||
static tb_t start, now;
|
||||
static u8 soundbuffer[3200] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
u32 loadtimeradjust;
|
||||
|
||||
void doScan(u32 blah)
|
||||
{
|
||||
PAD_ScanPads();
|
||||
}
|
||||
|
||||
|
||||
int throttle = 100;
|
||||
u32 throttleLastTime = 0;
|
||||
|
||||
char filename[1024]; //rom file name
|
||||
char batfilename[1024]; //battery save file name
|
||||
char statename[1024]; //savestate file name
|
||||
/****************************************************************************
|
||||
* Initialise Video
|
||||
*
|
||||
* Before doing anything in libogc, it's recommended to configure a video
|
||||
* output.
|
||||
****************************************************************************/
|
||||
static void
|
||||
Initialise (void)
|
||||
{
|
||||
VIDEO_Init (); /*** ALWAYS CALL FIRST IN ANY LIBOGC PROJECT!
|
||||
Not only does it initialise the video
|
||||
subsystem, but also sets up the ogc os
|
||||
***/
|
||||
#if DEBUGON
|
||||
DEBUG_Init(2424);
|
||||
_break();
|
||||
#endif
|
||||
|
||||
PAD_Init (); /*** Initialise pads for input ***/
|
||||
#ifdef WII_BUILD
|
||||
CONF_Init();
|
||||
WPAD_Init();
|
||||
setup_controllers();
|
||||
#endif
|
||||
vmode = VIDEO_GetPreferredMode(NULL);
|
||||
|
||||
/*** Now configure the framebuffer.
|
||||
Really a framebuffer is just a chunk of memory
|
||||
to hold the display line by line.
|
||||
***/
|
||||
|
||||
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
||||
/*** I prefer also to have a second buffer for double-buffering.
|
||||
This is not needed for the console demo.
|
||||
***/
|
||||
xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
||||
|
||||
/*** Define a console ***/
|
||||
console_init (xfb[0], 20, 64, vmode->fbWidth, vmode->xfbHeight,
|
||||
vmode->fbWidth * 2);
|
||||
|
||||
/*** Let libogc configure the mode ***/
|
||||
VIDEO_Configure (vmode);
|
||||
|
||||
/*** Clear framebuffer to black ***/
|
||||
VIDEO_ClearFrameBuffer (vmode, xfb[0], COLOR_BLACK);
|
||||
VIDEO_ClearFrameBuffer (vmode, xfb[1], COLOR_BLACK);
|
||||
|
||||
/*** Set the framebuffer to be displayed at next VBlank ***/
|
||||
VIDEO_SetNextFramebuffer (xfb[0]);
|
||||
|
||||
/*** Get the PAD status updated by libogc ***/
|
||||
VIDEO_SetPreRetraceCallback (doScan);
|
||||
VIDEO_SetBlack (0);
|
||||
/*
|
||||
int i;
|
||||
u32 *vreg = (u32 *)0xCC002000;
|
||||
for ( i = 0; i < 64; i++ )
|
||||
vreg[i] = vpal60[i]; */
|
||||
|
||||
/*** Update the video for next vblank ***/
|
||||
VIDEO_Flush ();
|
||||
|
||||
VIDEO_WaitVSync (); /*** Wait for VBL ***/
|
||||
if (vmode->viTVMode & VI_NON_INTERLACE)
|
||||
VIDEO_WaitVSync ();
|
||||
|
||||
}
|
||||
|
||||
void systemMessage(int num, const char *msg, ...)
|
||||
{
|
||||
/*** For now ... do nothing ***/
|
||||
}
|
||||
|
||||
void GC_Sleep(u32 dwMiliseconds)
|
||||
{
|
||||
int nVBlanks = (dwMiliseconds / 16);
|
||||
while (nVBlanks-- > 0)
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
}
|
||||
|
||||
void systemFrame()
|
||||
{}
|
||||
|
||||
void systemScreenCapture(int a)
|
||||
{}
|
||||
|
||||
void systemShowSpeed(int speed)
|
||||
{}
|
||||
static u32 autoFrameSkipLastTime = 0;
|
||||
static int frameskipadjust = 0;
|
||||
|
||||
void write_save()
|
||||
{
|
||||
emulator.emuWriteBattery(batfilename);
|
||||
}
|
||||
|
||||
void system10Frames(int rate)
|
||||
{
|
||||
if ( cartridgeType == 1 )
|
||||
return;
|
||||
|
||||
u32 time = systemGetClock();
|
||||
u32 diff = time - autoFrameSkipLastTime;
|
||||
int speed = 100;
|
||||
|
||||
if(diff)
|
||||
speed = (1000000/rate)/diff;
|
||||
/* char temp[512];
|
||||
sprintf(temp,"Speed: %i",speed);
|
||||
MENU_DrawString( -1, 450,temp , 1 ); */
|
||||
|
||||
if(speed >= 98)
|
||||
{
|
||||
frameskipadjust++;
|
||||
|
||||
if(frameskipadjust >= 3)
|
||||
{
|
||||
frameskipadjust=0;
|
||||
if(systemFrameSkip > 0)
|
||||
systemFrameSkip--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(speed < 80)
|
||||
frameskipadjust -= (90 - speed)/5;
|
||||
else if(systemFrameSkip < 9)
|
||||
frameskipadjust--;
|
||||
|
||||
if(frameskipadjust <= -2)
|
||||
{
|
||||
frameskipadjust += 2;
|
||||
if(systemFrameSkip < 9)
|
||||
systemFrameSkip++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( cartridgeType == 1 )
|
||||
return;
|
||||
|
||||
|
||||
/*
|
||||
if(systemSaveUpdateCounter) {
|
||||
char temp[512];
|
||||
sprintf(temp,"Writing Save To Disk");
|
||||
MENU_DrawString( -1, 450,temp , 1 );
|
||||
} */
|
||||
|
||||
if(systemSaveUpdateCounter) {
|
||||
if(--systemSaveUpdateCounter <= SYSTEM_SAVE_NOT_UPDATED) {
|
||||
write_save();
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
||||
}
|
||||
}
|
||||
|
||||
autoFrameSkipLastTime = time;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void systemUpdateMotionSensor()
|
||||
{}
|
||||
|
||||
void systemGbBorderOn()
|
||||
{}
|
||||
|
||||
void systemWriteDataToSoundBuffer()
|
||||
{
|
||||
MIXER_AddSamples((u8 *)soundFinalWave, (cartridgeType == 1));
|
||||
}
|
||||
|
||||
void systemSoundPause()
|
||||
{}
|
||||
|
||||
void systemSoundResume()
|
||||
{}
|
||||
|
||||
void systemSoundReset()
|
||||
{}
|
||||
|
||||
void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast)
|
||||
{}
|
||||
|
||||
void systemSoundShutdown()
|
||||
{}
|
||||
|
||||
static void AudioPlayer( void )
|
||||
{
|
||||
AUDIO_StopDMA();
|
||||
MIXER_GetSamples(soundbuffer, 3200);
|
||||
DCFlushRange(soundbuffer,3200);
|
||||
AUDIO_InitDMA((u32)soundbuffer,3200);
|
||||
AUDIO_StartDMA();
|
||||
}
|
||||
|
||||
bool systemSoundInit()
|
||||
{
|
||||
AUDIO_Init(NULL);
|
||||
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ);
|
||||
AUDIO_RegisterDMACallback(AudioPlayer);
|
||||
memset(soundbuffer, 0, 3200);
|
||||
|
||||
//printf("Audio Inited\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static void AudioDeInit()
|
||||
{
|
||||
AUDIO_StopDMA();
|
||||
}
|
||||
|
||||
bool systemPauseOnFrame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int systemGetSensorX()
|
||||
{
|
||||
return sensorX;
|
||||
}
|
||||
|
||||
int systemGetSensorY()
|
||||
{
|
||||
return sensorY;
|
||||
}
|
||||
|
||||
bool systemCanChangeSoundQuality()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* systemReadJoypads
|
||||
****************************************************************************/
|
||||
bool systemReadJoypads()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 systemReadJoypad(int which)
|
||||
{
|
||||
return NGCPad();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* systemGetClock
|
||||
*
|
||||
* Returns number of milliseconds since program start
|
||||
****************************************************************************/
|
||||
u32 systemGetClock( void )
|
||||
{
|
||||
mftb(&now);
|
||||
return tb_diff_msec(&now, &start) - loadtimeradjust;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* systemDrawScreen
|
||||
****************************************************************************/
|
||||
void systemDrawScreen()
|
||||
{
|
||||
/** GB / GBC Have oodles of time - so sync on VSync **/
|
||||
#if WITHGX
|
||||
GX_Render( srcWidth, srcHeight, pix, srcPitch );
|
||||
#endif
|
||||
#ifdef WII_BUILD
|
||||
|
||||
VIDEO_WaitVSync ();
|
||||
|
||||
#endif
|
||||
#ifdef GC_BUILD
|
||||
if ( cartridgeType == 1 )
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Showdir
|
||||
****************************************************************************/
|
||||
int ShowDir( char *whichdir )
|
||||
{
|
||||
int count;
|
||||
int i;
|
||||
count = gen_getdir( whichdir );
|
||||
printf("Found %d files\n",count);
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
printf("%s\n", direntries[i]);
|
||||
while(1);
|
||||
}
|
||||
|
||||
/*
|
||||
Asks user to select a ROM
|
||||
*/
|
||||
void chooseRom() {
|
||||
//char *fname = "Sonic Advance 3.GBA";
|
||||
char *fname = NULL;
|
||||
memset(filename,0,1024);
|
||||
memset(batfilename,0,1024);
|
||||
fname = MENU_GetLoadFile( "/VBA/ROMS" );
|
||||
sprintf(filename, "/VBA/ROMS/%s", fname);
|
||||
|
||||
// construct battery save file name
|
||||
strcpy(batfilename, "/VBA/SAVES/");
|
||||
strncat(batfilename,fname,strlen(fname)-4);
|
||||
strcat(batfilename,".SAV");
|
||||
|
||||
// construct savestate name
|
||||
strcpy(statename, "/VBA/SAVES/");
|
||||
strncat(statename,fname,strlen(fname)-4);
|
||||
strcat(statename,".SGM");
|
||||
}
|
||||
|
||||
/*
|
||||
Checks to see if a previous SRAM/Flash save exists
|
||||
If it does, it prompts the user to load it or not
|
||||
*/
|
||||
void checkSave() {
|
||||
FILE* f = gen_fopen(statename, "rb");
|
||||
if (f != NULL) {
|
||||
gen_fclose(f);
|
||||
whichfb^=1;
|
||||
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], COLOR_BLACK);
|
||||
MENU_DrawString( 140, 50,"Quick Save State Exists" , 1 );
|
||||
MENU_DrawString( 140, 80,"Do you wish to load it?" , 1 );
|
||||
MENU_DrawString( -1, 170,"(L) or (+) YES" , 1 );
|
||||
MENU_DrawString( -1, 200,"(R) or (-) NO" , 1 );
|
||||
VIDEO_WaitVSync ();
|
||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
while(1) {
|
||||
WPADData *wpad;
|
||||
WPAD_ScanPads();
|
||||
wpad = WPAD_Data(0);
|
||||
if (isWiimoteAvailable) {
|
||||
unsigned short b = wpad->btns_h;
|
||||
if(b & WPAD_BUTTON_PLUS) {
|
||||
saveExists = 1;
|
||||
break;
|
||||
}
|
||||
if(b & WPAD_BUTTON_MINUS) break;
|
||||
}
|
||||
if (isClassicAvailable) {
|
||||
unsigned short b = wpad->exp.classic.btns;
|
||||
if(b & CLASSIC_CTRL_BUTTON_PLUS) {
|
||||
saveExists = 1;
|
||||
break;
|
||||
}
|
||||
if(b & CLASSIC_CTRL_BUTTON_MINUS) break;
|
||||
}
|
||||
u16 buttons = PAD_ButtonsHeld(0);
|
||||
if(buttons & PAD_TRIGGER_R){
|
||||
break;
|
||||
}
|
||||
if(buttons & PAD_TRIGGER_L){
|
||||
saveExists = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], COLOR_BLACK);
|
||||
VIDEO_WaitVSync ();
|
||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void askSound() {
|
||||
soundOffFlag = false;
|
||||
soundLowPass = true;
|
||||
}
|
||||
|
||||
|
||||
int ingameMenu() {
|
||||
tb_t start,end;
|
||||
mftb(&start);
|
||||
char temp[512];
|
||||
u16 buttons;
|
||||
AudioDeInit();
|
||||
whichfb^=1;
|
||||
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], COLOR_BLACK);
|
||||
MENU_DrawString( 140, 50,"VisualBoyAdvance 1.7.2" , 1 );
|
||||
|
||||
#ifdef GC_BUILD
|
||||
MENU_DrawString( 140, 80,"Nintendo Gamecube Port" , 1 );
|
||||
MENU_DrawString( -1, 170,"(B) - Resume play" , 1 );
|
||||
MENU_DrawString( -1, 200,"(L) - Write Quicksave" , 1 );
|
||||
MENU_DrawString( -1, 230,"(R) - Reset game" , 1 );
|
||||
MENU_DrawString( -1, 320,"(Z) - Return to loader" , 1 );
|
||||
#endif
|
||||
#ifdef WII_BUILD
|
||||
MENU_DrawString( 140, 80,"Nintendo Wii Port" , 1 );
|
||||
MENU_DrawString( -1, 170,"(B) or (Home) - Resume play" , 1 );
|
||||
MENU_DrawString( -1, 200,"(L) or (+) - Write Quicksave" , 1 );
|
||||
MENU_DrawString( -1, 230,"(R) or (-) - Reset game" , 1 );
|
||||
MENU_DrawString( -1, 320,"(Z) or (A+B) - Return to loader" , 1 );
|
||||
#endif
|
||||
|
||||
sprintf(temp,"Frameskip: Auto (Currently %i)",systemFrameSkip);
|
||||
MENU_DrawString( -1, 450,temp , 1 );
|
||||
|
||||
VIDEO_WaitVSync ();
|
||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
|
||||
//wait for user to let go of menu calling button
|
||||
do{buttons = PAD_ButtonsHeld(0);}
|
||||
while((buttons & PAD_BUTTON_A)||(buttons & PAD_BUTTON_B));
|
||||
//wait for user to let go of home button
|
||||
#ifdef WII_BUILD
|
||||
WPADData *wpad;
|
||||
int btn;
|
||||
if(isWiimoteAvailable)
|
||||
do{WPAD_ScanPads(); wpad = WPAD_Data(0); btn = wpad->btns_h;}
|
||||
while(btn & WPAD_BUTTON_HOME);
|
||||
if(isClassicAvailable)
|
||||
do{WPAD_ScanPads(); wpad = WPAD_Data(0); btn = wpad->exp.classic.btns;}
|
||||
while(btn & CLASSIC_CTRL_BUTTON_HOME);
|
||||
#endif
|
||||
|
||||
while(1){
|
||||
|
||||
#ifdef WII_BUILD
|
||||
WPADData *wpad;
|
||||
WPAD_ScanPads();
|
||||
wpad = WPAD_Data(0);
|
||||
if (isWiimoteAvailable)
|
||||
{
|
||||
unsigned short b = wpad->btns_h;
|
||||
if(b & WPAD_BUTTON_MINUS){ //Reset game
|
||||
emulator.emuReset();
|
||||
break;
|
||||
}
|
||||
if(b & WPAD_BUTTON_PLUS) { //Write save
|
||||
emulator.emuWriteState(statename);
|
||||
GC_Sleep(1500);
|
||||
break;
|
||||
}
|
||||
if((b & WPAD_BUTTON_A) && (b & WPAD_BUTTON_B)) { //Return to loader
|
||||
void (*reload)() = (void(*)())0x80001800;
|
||||
reload();
|
||||
}
|
||||
if(b & WPAD_BUTTON_HOME) { //Resume play
|
||||
do{WPAD_ScanPads(); wpad = WPAD_Data(0); b = wpad->btns_h;}
|
||||
while(b & WPAD_BUTTON_HOME); //wait for home
|
||||
break;
|
||||
}
|
||||
/* if(b & WPAD_BUTTON_2) { //back to menu
|
||||
INSERT BACK-TO-MENU HERE
|
||||
} */
|
||||
}
|
||||
if (isClassicAvailable)
|
||||
{
|
||||
int b = wpad->exp.classic.btns;
|
||||
if(b & CLASSIC_CTRL_BUTTON_MINUS){ //Reset game
|
||||
emulator.emuReset();
|
||||
break;
|
||||
}
|
||||
if(b & CLASSIC_CTRL_BUTTON_PLUS) { //Write save
|
||||
emulator.emuWriteState(statename);
|
||||
break;
|
||||
}
|
||||
if((b & CLASSIC_CTRL_BUTTON_A) && (b & CLASSIC_CTRL_BUTTON_B)) { //Return to loader
|
||||
void (*reload)() = (void(*)())0x80001800;
|
||||
reload();
|
||||
}
|
||||
if(b & CLASSIC_CTRL_BUTTON_HOME) { //Resume play
|
||||
do{WPAD_ScanPads(); wpad = WPAD_Data(0); b = wpad->exp.classic.btns;}
|
||||
while(b & CLASSIC_CTRL_BUTTON_HOME); //wait for home button
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
u16 buttons = PAD_ButtonsHeld(0); //grab pad buttons
|
||||
|
||||
if(buttons & PAD_TRIGGER_R){ //Reset game
|
||||
emulator.emuReset();
|
||||
break;
|
||||
}
|
||||
if(buttons & PAD_TRIGGER_L) { //Write save
|
||||
emulator.emuWriteState(statename);
|
||||
break;
|
||||
}
|
||||
if(buttons & PAD_TRIGGER_Z) { //Return to loader
|
||||
void (*reload)() = (void(*)())0x80001800;
|
||||
reload();
|
||||
}
|
||||
if(buttons & PAD_BUTTON_B) { //Resume play
|
||||
break;
|
||||
}
|
||||
}
|
||||
AudioPlayer();
|
||||
mftb(&end);
|
||||
loadtimeradjust += tb_diff_msec(&end, &start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* main
|
||||
*
|
||||
* Program entry
|
||||
****************************************************************************/
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
int vAspect = 0;
|
||||
int hAspect = 0;
|
||||
|
||||
Initialise();
|
||||
|
||||
printf("\n\n\nVisualBoyAdvance 1.7.2\n");
|
||||
printf("Nintendo Wii Port\n");
|
||||
|
||||
|
||||
/** Kick off SD Lib **/
|
||||
SDInit();
|
||||
|
||||
|
||||
/** Build GBPalette **/
|
||||
for( i = 0; i < 24; )
|
||||
{
|
||||
systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10);
|
||||
systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10);
|
||||
systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10);
|
||||
systemGbPalette[i++] = 0;
|
||||
}
|
||||
/** Set palette etc - Fixed to RGB565 **/
|
||||
systemColorDepth = 16;
|
||||
systemRedShift = 11;
|
||||
systemGreenShift = 6;
|
||||
systemBlueShift = 0;
|
||||
for(i = 0; i < 0x10000; i++)
|
||||
{
|
||||
systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
|
||||
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
||||
(((i & 0x7c00) >> 10) << systemBlueShift);
|
||||
}
|
||||
|
||||
//Main loop
|
||||
while(1) {
|
||||
cartridgeType = 0;
|
||||
srcWidth = 0;
|
||||
srcHeight = 0;
|
||||
destWidth = 0;
|
||||
destHeight = 0;
|
||||
srcPitch = 0;
|
||||
|
||||
chooseRom();
|
||||
checkSave();
|
||||
|
||||
IMAGE_TYPE type = utilFindType(filename);
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case IMAGE_GBA:
|
||||
printf("GameBoy Advance Image\n");
|
||||
cartridgeType = 2;
|
||||
emulator = GBASystem;
|
||||
srcWidth = 240;
|
||||
srcHeight = 160;
|
||||
VMCPULoadROM(filename);
|
||||
/* Actual Visual Aspect is 1.57 */
|
||||
hAspect = 70;
|
||||
vAspect = 46;
|
||||
srcPitch = 484;
|
||||
soundQuality = 2;
|
||||
soundBufferLen = 1470;
|
||||
cpuSaveType = 0;
|
||||
break;
|
||||
|
||||
case IMAGE_GB:
|
||||
printf("GameBoy Image\n");
|
||||
cartridgeType = 1;
|
||||
emulator = GBSystem;
|
||||
srcWidth = 160;
|
||||
srcHeight = 144;
|
||||
gbLoadRom(filename);
|
||||
/* Actual physical aspect is 1.0 */
|
||||
hAspect = 60;
|
||||
vAspect = 46;
|
||||
srcPitch = 324;
|
||||
soundQuality = 1;
|
||||
soundBufferLen = 1470 * 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown Image\n");
|
||||
while(1);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/** Set defaults **/
|
||||
flashSetSize(0x10000);
|
||||
rtcEnable(true);
|
||||
agbPrintEnable(false);
|
||||
askSound();
|
||||
|
||||
#if WITHGX
|
||||
/** Set GX **/
|
||||
GX_Start( srcWidth, srcHeight, hAspect, vAspect );
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if ( cartridgeType == 1 )
|
||||
{
|
||||
gbSoundReset();
|
||||
gbSoundSetQuality(soundQuality);
|
||||
}
|
||||
else
|
||||
{
|
||||
soundSetQuality(soundQuality);
|
||||
CPUInit("/VBA/BIOS/BIOS.GBA", 1);
|
||||
CPUReset();
|
||||
}
|
||||
|
||||
emulator.emuReadBattery(batfilename);
|
||||
if (saveExists){
|
||||
emulator.emuReadState(statename);
|
||||
saveExists = 0;
|
||||
}
|
||||
|
||||
soundVolume = 0;
|
||||
systemSoundOn = true;
|
||||
|
||||
soundInit();
|
||||
AudioPlayer();
|
||||
|
||||
emulating = 1;
|
||||
/** Start system clock **/
|
||||
mftb(&start);
|
||||
|
||||
while ( emulating )
|
||||
{
|
||||
emulator.emuMain(emulator.emuCount);
|
||||
if(menuCalled) {
|
||||
if(ingameMenu())
|
||||
break;
|
||||
menuCalled = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Never **/
|
||||
while(1);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
53
source/ngc/vbaconfig.cpp
Normal file
53
source/ngc/vbaconfig.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May 2007
|
||||
* Tantric September 2008
|
||||
*
|
||||
* s9xconfig.cpp
|
||||
*
|
||||
* Configuration parameters are here for easy maintenance.
|
||||
* Refer to Snes9x.h for all combinations.
|
||||
* The defaults used here are taken directly from porting.html
|
||||
***************************************************************************/
|
||||
|
||||
#include <gccore.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "vba.h"
|
||||
#include "smbop.h"
|
||||
|
||||
struct SGCSettings GCSettings;
|
||||
|
||||
void
|
||||
DefaultSettings ()
|
||||
{
|
||||
/************** GameCube/Wii Settings *********************/
|
||||
GCSettings.LoadMethod = METHOD_AUTO; // Auto, SD, DVD, USB, Network (SMB)
|
||||
GCSettings.SaveMethod = METHOD_AUTO; // Auto, SD, Memory Card Slot A, Memory Card Slot B, USB, Network (SMB)
|
||||
sprintf (GCSettings.LoadFolder,"vba/roms"); // Path to game files
|
||||
sprintf (GCSettings.SaveFolder,"vba/saves"); // Path to save files
|
||||
sprintf (GCSettings.CheatFolder,"vba/cheats"); // Path to cheat files
|
||||
GCSettings.AutoLoad = 1;
|
||||
GCSettings.AutoSave = 1;
|
||||
|
||||
// custom SMB settings
|
||||
strncpy (GCSettings.smbip, "", 15); // IP Address of share server
|
||||
strncpy (GCSettings.smbuser, "", 19); // Your share user
|
||||
strncpy (GCSettings.smbpwd, "", 19); // Your share user password
|
||||
strncpy (GCSettings.smbshare, "", 19); // Share name on server
|
||||
|
||||
GCSettings.smbip[15] = 0;
|
||||
GCSettings.smbuser[19] = 0;
|
||||
GCSettings.smbpwd[19] = 0;
|
||||
GCSettings.smbshare[19] = 0;
|
||||
|
||||
GCSettings.gcip[0] = 0;
|
||||
GCSettings.gwip[0] = 0;
|
||||
GCSettings.mask[0] = 0;
|
||||
GCSettings.smbsvid[0] = 0;
|
||||
GCSettings.smbgcid[0] = 0;
|
||||
|
||||
GCSettings.VerifySaves = 0;
|
||||
}
|
21
source/ngc/vbaconfig.h
Normal file
21
source/ngc/vbaconfig.h
Normal file
@ -0,0 +1,21 @@
|
||||
/****************************************************************************
|
||||
* Snes9x 1.51 Nintendo Wii/Gamecube Port
|
||||
*
|
||||
* softdev July 2006
|
||||
* crunchy2 May 2007
|
||||
* Tantric September 2008
|
||||
*
|
||||
* s9xconfig.h
|
||||
*
|
||||
* Configuration parameters are here for easy maintenance.
|
||||
* Refer to Snes9x.h for all combinations.
|
||||
* The defaults used here are taken directly from porting.html
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _VBACONFIG_
|
||||
|
||||
#define _VBACONFIG_
|
||||
|
||||
void DefaultSettings ();
|
||||
|
||||
#endif
|
474
source/ngc/vbasupport.cpp
Normal file
474
source/ngc/vbasupport.cpp
Normal file
@ -0,0 +1,474 @@
|
||||
|
||||
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "GBA.h"
|
||||
#include "agbprint.h"
|
||||
#include "Flash.h"
|
||||
#include "Port.h"
|
||||
#include "RTC.h"
|
||||
#include "Sound.h"
|
||||
#include "Text.h"
|
||||
#include "unzip.h"
|
||||
#include "Util.h"
|
||||
#include "gb/GB.h"
|
||||
#include "gb/gbGlobals.h"
|
||||
|
||||
|
||||
#include "audio.h"
|
||||
#include "vmmem.h"
|
||||
#include "pal60.h"
|
||||
#include "input.h"
|
||||
#include "video.h"
|
||||
#include "menudraw.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "tbtime.h"
|
||||
#include "sdfileio.h"
|
||||
}
|
||||
|
||||
/**
|
||||
* Globals
|
||||
*/
|
||||
int RGB_LOW_BITS_MASK=0x821;
|
||||
int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
||||
|
||||
int systemDebug = 0;
|
||||
int emulating = 0;
|
||||
|
||||
int sensorX = 2047;
|
||||
int sensorY = 2047;
|
||||
|
||||
int systemFrameSkip = 0;
|
||||
bool systemSoundOn = false;
|
||||
int systemVerbose = 0;
|
||||
int cartridgeType = 0;
|
||||
int srcWidth = 0;
|
||||
int srcHeight = 0;
|
||||
int destWidth = 0;
|
||||
int destHeight = 0;
|
||||
int srcPitch = 0;
|
||||
int saveExists = 0;
|
||||
|
||||
int systemRedShift = 0;
|
||||
int systemBlueShift = 0;
|
||||
int systemGreenShift = 0;
|
||||
int systemColorDepth = 0;
|
||||
u16 systemGbPalette[24];
|
||||
u16 systemColorMap16[0x10000];
|
||||
//u32 systemColorMap32[0x10000];
|
||||
u32 *systemColorMap32 = (u32 *)&systemColorMap16;
|
||||
|
||||
/*** 2D Video Globals ***/
|
||||
extern u32 whichfb;
|
||||
extern u32 *xfb[2];
|
||||
extern GXRModeObj *vmode;
|
||||
|
||||
struct EmulatedSystem emulator =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
false,
|
||||
0
|
||||
};
|
||||
|
||||
static tb_t start, now;
|
||||
|
||||
u32 loadtimeradjust;
|
||||
|
||||
int throttle = 100;
|
||||
u32 throttleLastTime = 0;
|
||||
|
||||
int vAspect = 0;
|
||||
int hAspect = 0;
|
||||
|
||||
//char filename[1024]; //rom file name
|
||||
//char batfilename[1024]; //battery save file name
|
||||
//char statename[1024]; //savestate file name
|
||||
|
||||
void debuggerOutput(char *, u32)
|
||||
{}
|
||||
|
||||
void (*dbgOutput)(char *, u32) = debuggerOutput;
|
||||
|
||||
void systemMessage(int num, const char *msg, ...)
|
||||
{
|
||||
/*** For now ... do nothing ***/
|
||||
}
|
||||
|
||||
void GC_Sleep(u32 dwMiliseconds)
|
||||
{
|
||||
int nVBlanks = (dwMiliseconds / 16);
|
||||
while (nVBlanks-- > 0)
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
}
|
||||
|
||||
void systemFrame()
|
||||
{}
|
||||
|
||||
void systemScreenCapture(int a)
|
||||
{}
|
||||
|
||||
void systemShowSpeed(int speed)
|
||||
{}
|
||||
static u32 autoFrameSkipLastTime = 0;
|
||||
static int frameskipadjust = 0;
|
||||
|
||||
void write_save()
|
||||
{
|
||||
//emulator.emuWriteBattery(batfilename);
|
||||
}
|
||||
|
||||
void system10Frames(int rate)
|
||||
{
|
||||
if ( cartridgeType == 1 )
|
||||
return;
|
||||
|
||||
u32 time = systemGetClock();
|
||||
u32 diff = time - autoFrameSkipLastTime;
|
||||
int speed = 100;
|
||||
|
||||
if(diff)
|
||||
speed = (1000000/rate)/diff;
|
||||
/* char temp[512];
|
||||
sprintf(temp,"Speed: %i",speed);
|
||||
MENU_DrawString( -1, 450,temp , 1 ); */
|
||||
|
||||
if(speed >= 98)
|
||||
{
|
||||
frameskipadjust++;
|
||||
|
||||
if(frameskipadjust >= 3)
|
||||
{
|
||||
frameskipadjust=0;
|
||||
if(systemFrameSkip > 0)
|
||||
systemFrameSkip--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(speed < 80)
|
||||
frameskipadjust -= (90 - speed)/5;
|
||||
else if(systemFrameSkip < 9)
|
||||
frameskipadjust--;
|
||||
|
||||
if(frameskipadjust <= -2)
|
||||
{
|
||||
frameskipadjust += 2;
|
||||
if(systemFrameSkip < 9)
|
||||
systemFrameSkip++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( cartridgeType == 1 )
|
||||
return;
|
||||
|
||||
|
||||
/*
|
||||
if(systemSaveUpdateCounter) {
|
||||
char temp[512];
|
||||
sprintf(temp,"Writing Save To Disk");
|
||||
MENU_DrawString( -1, 450,temp , 1 );
|
||||
} */
|
||||
|
||||
if(systemSaveUpdateCounter) {
|
||||
if(--systemSaveUpdateCounter <= SYSTEM_SAVE_NOT_UPDATED) {
|
||||
write_save();
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
||||
}
|
||||
}
|
||||
|
||||
autoFrameSkipLastTime = time;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void systemUpdateMotionSensor()
|
||||
{}
|
||||
|
||||
void systemGbBorderOn()
|
||||
{}
|
||||
|
||||
void systemWriteDataToSoundBuffer()
|
||||
{
|
||||
MIXER_AddSamples((u8 *)soundFinalWave, (cartridgeType == 1));
|
||||
}
|
||||
|
||||
void systemSoundPause()
|
||||
{}
|
||||
|
||||
void systemSoundResume()
|
||||
{}
|
||||
|
||||
void systemSoundReset()
|
||||
{}
|
||||
|
||||
void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast)
|
||||
{}
|
||||
|
||||
void systemSoundShutdown()
|
||||
{}
|
||||
|
||||
bool systemSoundInit()
|
||||
{
|
||||
//memset(soundbuffer, 0, 3200);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool systemPauseOnFrame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int systemGetSensorX()
|
||||
{
|
||||
return sensorX;
|
||||
}
|
||||
|
||||
int systemGetSensorY()
|
||||
{
|
||||
return sensorY;
|
||||
}
|
||||
|
||||
bool systemCanChangeSoundQuality()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* systemReadJoypads
|
||||
****************************************************************************/
|
||||
bool systemReadJoypads()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 systemReadJoypad(int which)
|
||||
{
|
||||
return GetJoy();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* systemGetClock
|
||||
*
|
||||
* Returns number of milliseconds since program start
|
||||
****************************************************************************/
|
||||
u32 systemGetClock( void )
|
||||
{
|
||||
mftb(&now);
|
||||
return tb_diff_msec(&now, &start) - loadtimeradjust;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* systemDrawScreen
|
||||
****************************************************************************/
|
||||
void systemDrawScreen()
|
||||
{
|
||||
/** GB / GBC Have oodles of time - so sync on VSync **/
|
||||
GX_Render( srcWidth, srcHeight, pix, srcPitch );
|
||||
|
||||
#ifdef HW_RVL
|
||||
VIDEO_WaitVSync ();
|
||||
#else
|
||||
if ( cartridgeType == 1 )
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Checks to see if a previous SRAM/Flash save exists
|
||||
If it does, it prompts the user to load it or not
|
||||
*/
|
||||
void checkSave() {
|
||||
/* FILE* f = gen_fopen(statename, "rb");
|
||||
if (f != NULL) {
|
||||
gen_fclose(f);
|
||||
whichfb^=1;
|
||||
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], COLOR_BLACK);
|
||||
//MENU_DrawString( 140, 50,"Quick Save State Exists" , 1 );
|
||||
//MENU_DrawString( 140, 80,"Do you wish to load it?" , 1 );
|
||||
//MENU_DrawString( -1, 170,"(L) or (+) YES" , 1 );
|
||||
//MENU_DrawString( -1, 200,"(R) or (-) NO" , 1 );
|
||||
VIDEO_WaitVSync ();
|
||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
while(1) {
|
||||
WPADData *wpad;
|
||||
WPAD_ScanPads();
|
||||
wpad = WPAD_Data(0);
|
||||
if (isWiimoteAvailable) {
|
||||
unsigned short b = wpad->btns_h;
|
||||
if(b & WPAD_BUTTON_PLUS) {
|
||||
saveExists = 1;
|
||||
break;
|
||||
}
|
||||
if(b & WPAD_BUTTON_MINUS) break;
|
||||
}
|
||||
if (isClassicAvailable) {
|
||||
unsigned short b = wpad->exp.classic.btns;
|
||||
if(b & CLASSIC_CTRL_BUTTON_PLUS) {
|
||||
saveExists = 1;
|
||||
break;
|
||||
}
|
||||
if(b & CLASSIC_CTRL_BUTTON_MINUS) break;
|
||||
}
|
||||
u16 buttons = PAD_ButtonsHeld(0);
|
||||
if(buttons & PAD_TRIGGER_R){
|
||||
break;
|
||||
}
|
||||
if(buttons & PAD_TRIGGER_L){
|
||||
saveExists = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], COLOR_BLACK);
|
||||
VIDEO_WaitVSync ();
|
||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
void askSound() {
|
||||
soundOffFlag = false;
|
||||
soundLowPass = true;
|
||||
}
|
||||
|
||||
int loadVBAROM(char filename[])
|
||||
{
|
||||
cartridgeType = 0;
|
||||
srcWidth = 0;
|
||||
srcHeight = 0;
|
||||
destWidth = 0;
|
||||
destHeight = 0;
|
||||
srcPitch = 0;
|
||||
|
||||
IMAGE_TYPE type = utilFindType(filename);
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case IMAGE_GBA:
|
||||
//WaitPrompt("GameBoy Advance Image");
|
||||
cartridgeType = 2;
|
||||
emulator = GBASystem;
|
||||
srcWidth = 240;
|
||||
srcHeight = 160;
|
||||
VMCPULoadROM(filename);
|
||||
/* Actual Visual Aspect is 1.57 */
|
||||
hAspect = 70;
|
||||
vAspect = 46;
|
||||
srcPitch = 484;
|
||||
soundQuality = 2;
|
||||
soundBufferLen = 1470;
|
||||
cpuSaveType = 0;
|
||||
break;
|
||||
|
||||
case IMAGE_GB:
|
||||
//WaitPrompt("GameBoy Image");
|
||||
cartridgeType = 1;
|
||||
emulator = GBSystem;
|
||||
srcWidth = 160;
|
||||
srcHeight = 144;
|
||||
gbLoadRom(filename);
|
||||
/* Actual physical aspect is 1.0 */
|
||||
hAspect = 60;
|
||||
vAspect = 46;
|
||||
srcPitch = 324;
|
||||
soundQuality = 1;
|
||||
soundBufferLen = 1470 * 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
WaitPrompt((char *)"Unknown Image");
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/** Set defaults **/
|
||||
flashSetSize(0x10000);
|
||||
rtcEnable(true);
|
||||
agbPrintEnable(false);
|
||||
askSound();
|
||||
|
||||
/** Setup GX **/
|
||||
GX_Render_Init( srcWidth, srcHeight, hAspect, vAspect );
|
||||
|
||||
if ( cartridgeType == 1 )
|
||||
{
|
||||
gbSoundReset();
|
||||
gbSoundSetQuality(soundQuality);
|
||||
}
|
||||
else
|
||||
{
|
||||
soundSetQuality(soundQuality);
|
||||
CPUInit("/VBA/BIOS/BIOS.GBA", 1);
|
||||
CPUReset();
|
||||
}
|
||||
|
||||
// emulator.emuReadBattery(batfilename);
|
||||
if (saveExists)
|
||||
{
|
||||
//emulator.emuReadState(statename);
|
||||
saveExists = 0;
|
||||
}
|
||||
|
||||
soundVolume = 0;
|
||||
systemSoundOn = true;
|
||||
|
||||
soundInit();
|
||||
//AudioPlayer();
|
||||
|
||||
emulating = 1;
|
||||
|
||||
/** Start system clock **/
|
||||
mftb(&start);
|
||||
|
||||
//emulator.emuReset();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void InitialisePalette()
|
||||
{
|
||||
int i;
|
||||
/** Build GBPalette **/
|
||||
for( i = 0; i < 24; )
|
||||
{
|
||||
systemGbPalette[i++] = (0x1f) | (0x1f << 5) | (0x1f << 10);
|
||||
systemGbPalette[i++] = (0x15) | (0x15 << 5) | (0x15 << 10);
|
||||
systemGbPalette[i++] = (0x0c) | (0x0c << 5) | (0x0c << 10);
|
||||
systemGbPalette[i++] = 0;
|
||||
}
|
||||
/** Set palette etc - Fixed to RGB565 **/
|
||||
systemColorDepth = 16;
|
||||
systemRedShift = 11;
|
||||
systemGreenShift = 6;
|
||||
systemBlueShift = 0;
|
||||
for(i = 0; i < 0x10000; i++)
|
||||
{
|
||||
systemColorMap16[i] =
|
||||
((i & 0x1f) << systemRedShift) |
|
||||
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
||||
(((i & 0x7c00) >> 10) << systemBlueShift);
|
||||
}
|
||||
}
|
6
source/ngc/vbasupport.h
Normal file
6
source/ngc/vbasupport.h
Normal file
@ -0,0 +1,6 @@
|
||||
#include "System.h"
|
||||
|
||||
extern struct EmulatedSystem emulator;
|
||||
extern u32 loadtimeradjust;
|
||||
int loadVBAROM(char filename[]);
|
||||
void InitialisePalette();
|
342
source/ngc/video.cpp
Normal file
342
source/ngc/video.cpp
Normal file
@ -0,0 +1,342 @@
|
||||
/****************************************************************************
|
||||
* Generic GX Support for Emulators
|
||||
* softdev 2007
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* NGC GX Video Functions
|
||||
*
|
||||
* These are pretty standard functions to setup and use GX scaling.
|
||||
****************************************************************************/
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
|
||||
/*** External 2D Video ***/
|
||||
/*** 2D Video Globals ***/
|
||||
GXRModeObj *vmode; /*** Graphics Mode Object ***/
|
||||
u32 *xfb[2] = { NULL, NULL }; /*** Framebuffers ***/
|
||||
int whichfb = 0; /*** Frame buffer toggle ***/
|
||||
|
||||
int screenheight;
|
||||
|
||||
/*** 3D GX ***/
|
||||
#define DEFAULT_FIFO_SIZE ( 256 * 1024 )
|
||||
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
/*** Texture memory ***/
|
||||
static u8 *texturemem;
|
||||
static int texturesize;
|
||||
|
||||
GXTexObj texobj;
|
||||
static Mtx view;
|
||||
static int vwidth, vheight, oldvwidth, oldvheight;
|
||||
unsigned int copynow = GX_FALSE;
|
||||
|
||||
#define HASPECT 80
|
||||
#define VASPECT 45
|
||||
|
||||
/* New texture based scaler */
|
||||
typedef struct tagcamera
|
||||
{
|
||||
Vector pos;
|
||||
Vector up;
|
||||
Vector view;
|
||||
}
|
||||
camera;
|
||||
|
||||
/*** Square Matrix
|
||||
This structure controls the size of the image on the screen.
|
||||
Think of the output as a -80 x 80 by -60 x 60 graph.
|
||||
***/
|
||||
static s16 square[] ATTRIBUTE_ALIGN(32) = {
|
||||
/*
|
||||
* X, Y, Z
|
||||
* Values set are for roughly 4:3 aspect
|
||||
*/
|
||||
-HASPECT, VASPECT, 0, // 0
|
||||
HASPECT, VASPECT, 0, // 1
|
||||
HASPECT, -VASPECT, 0, // 2
|
||||
-HASPECT, -VASPECT, 0, // 3
|
||||
};
|
||||
|
||||
static camera cam = { {0.0F, 0.0F, 0.0F},
|
||||
{0.0F, 0.5F, 0.0F},
|
||||
{0.0F, 0.0F, -0.5F}
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* StartGX
|
||||
****************************************************************************/
|
||||
void GX_Start()
|
||||
{
|
||||
Mtx p;
|
||||
|
||||
GXColor gxbackground = { 0, 0, 0, 0xff };
|
||||
|
||||
/*** Clear out FIFO area ***/
|
||||
memset(&gp_fifo, 0, DEFAULT_FIFO_SIZE);
|
||||
|
||||
/*** Initialise GX ***/
|
||||
GX_Init(&gp_fifo, DEFAULT_FIFO_SIZE);
|
||||
GX_SetCopyClear(gxbackground, 0x00ffffff);
|
||||
|
||||
GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
||||
GX_SetDispCopyYScale((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
|
||||
GX_SetScissor(0, 0, vmode->fbWidth, vmode->efbHeight);
|
||||
GX_SetDispCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight);
|
||||
GX_SetDispCopyDst(vmode->fbWidth, vmode->xfbHeight);
|
||||
GX_SetCopyFilter(vmode->aa, vmode->sample_pattern, GX_TRUE,
|
||||
vmode->vfilter);
|
||||
GX_SetFieldMode(vmode->field_rendering,
|
||||
((vmode->viHeight ==
|
||||
2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
|
||||
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
||||
GX_SetCullMode(GX_CULL_NONE);
|
||||
GX_CopyDisp(xfb[whichfb ^ 1], GX_TRUE);
|
||||
GX_SetDispCopyGamma(GX_GM_1_0);
|
||||
|
||||
guPerspective(p, 60, 1.33F, 10.0F, 1000.0F);
|
||||
GX_LoadProjectionMtx(p, GX_PERSPECTIVE);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* UpdatePadsCB
|
||||
*
|
||||
* called by postRetraceCallback in InitGCVideo - scans gcpad and wpad
|
||||
***************************************************************************/
|
||||
void
|
||||
UpdatePadsCB ()
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
WPAD_ScanPads();
|
||||
#endif
|
||||
PAD_ScanPads();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Initialise Video
|
||||
*
|
||||
* Before doing anything in libogc, it's recommended to configure a video
|
||||
* output.
|
||||
****************************************************************************/
|
||||
void InitialiseVideo ()
|
||||
{
|
||||
/*** Start VIDEO Subsystem ***/
|
||||
VIDEO_Init();
|
||||
|
||||
vmode = VIDEO_GetPreferredMode(NULL);
|
||||
VIDEO_Configure(vmode);
|
||||
|
||||
screenheight = vmode->xfbHeight;
|
||||
|
||||
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
||||
xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
|
||||
|
||||
VIDEO_SetNextFramebuffer(xfb[0]);
|
||||
VIDEO_SetBlack(FALSE);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
|
||||
if(vmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
|
||||
VIDEO_SetPostRetraceCallback((VIRetraceCallback)UpdatePadsCB);
|
||||
VIDEO_SetNextFramebuffer(xfb[0]);
|
||||
|
||||
GX_Start();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Scaler Support Functions
|
||||
****************************************************************************/
|
||||
static void draw_init(void)
|
||||
{
|
||||
GX_ClearVtxDesc();
|
||||
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
|
||||
GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX8);
|
||||
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
||||
|
||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
|
||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
|
||||
GX_SetArray(GX_VA_POS, square, 3 * sizeof(s16));
|
||||
|
||||
GX_SetNumTexGens(1);
|
||||
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||
|
||||
GX_InvalidateTexAll();
|
||||
|
||||
GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565,
|
||||
GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
}
|
||||
|
||||
static void draw_vert(u8 pos, u8 c, f32 s, f32 t)
|
||||
{
|
||||
GX_Position1x8(pos);
|
||||
GX_Color1x8(c);
|
||||
GX_TexCoord2f32(s, t);
|
||||
}
|
||||
|
||||
static void draw_square(Mtx v)
|
||||
{
|
||||
Mtx m; // model matrix.
|
||||
Mtx mv; // modelview matrix.
|
||||
|
||||
guMtxIdentity(m);
|
||||
guMtxTransApply(m, m, 0, 0, -100);
|
||||
guMtxConcat(v, m, mv);
|
||||
|
||||
GX_LoadPosMtxImm(mv, GX_PNMTX0);
|
||||
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
||||
draw_vert(0, 0, 0.0, 0.0);
|
||||
draw_vert(1, 0, 1.0, 0.0);
|
||||
draw_vert(2, 0, 1.0, 1.0);
|
||||
draw_vert(3, 0, 0.0, 1.0);
|
||||
GX_End();
|
||||
}
|
||||
|
||||
void GX_Render_Init(int width, int height, int haspect, int vaspect)
|
||||
{
|
||||
/*** Set new aspect (now with crap AR hack!) ***/
|
||||
square[0] = square[9] = (-haspect - 7);
|
||||
square[3] = square[6] = (haspect + 7);
|
||||
square[1] = square[4] = (vaspect + 7);
|
||||
square[7] = square[10] = (-vaspect - 7);
|
||||
|
||||
/*** Allocate 32byte aligned texture memory ***/
|
||||
texturesize = (width * height) * 2;
|
||||
texturemem = (u8 *) memalign(32, texturesize);
|
||||
|
||||
memset(texturemem, 0, texturesize);
|
||||
|
||||
/*** Setup for first call to scaler ***/
|
||||
vwidth = vheight = -1;
|
||||
}
|
||||
/****************************************************************************
|
||||
* GX_Render
|
||||
*
|
||||
* Pass in a buffer, width and height to update as a tiled RGB565 texture
|
||||
****************************************************************************/
|
||||
void GX_Render(int width, int height, u8 * buffer, int pitch)
|
||||
{
|
||||
int h, w;
|
||||
long long int *dst = (long long int *) texturemem;
|
||||
long long int *src1 = (long long int *) buffer;
|
||||
long long int *src2 = (long long int *) (buffer + pitch);
|
||||
long long int *src3 = (long long int *) (buffer + (pitch * 2));
|
||||
long long int *src4 = (long long int *) (buffer + (pitch * 3));
|
||||
int rowpitch = (pitch >> 3) * 3;
|
||||
int rowadjust = ( pitch % 8 ) * 4;
|
||||
char *ra = NULL;
|
||||
|
||||
vwidth = width;
|
||||
vheight = height;
|
||||
|
||||
whichfb ^= 1;
|
||||
|
||||
if ((oldvheight != vheight) || (oldvwidth != vwidth))
|
||||
{
|
||||
/** Update scaling **/
|
||||
oldvwidth = vwidth;
|
||||
oldvheight = vheight;
|
||||
draw_init();
|
||||
memset(&view, 0, sizeof(Mtx));
|
||||
guLookAt(view, &cam.pos, &cam.up, &cam.view);
|
||||
GX_SetViewport(0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
|
||||
}
|
||||
|
||||
GX_InvVtxCache();
|
||||
GX_InvalidateTexAll();
|
||||
GX_SetTevOp(GX_TEVSTAGE0, GX_DECAL);
|
||||
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
|
||||
|
||||
for (h = 0; h < vheight; h += 4)
|
||||
{
|
||||
for (w = 0; w < (vwidth >> 2); w++)
|
||||
{
|
||||
*dst++ = *src1++;
|
||||
*dst++ = *src2++;
|
||||
*dst++ = *src3++;
|
||||
*dst++ = *src4++;
|
||||
}
|
||||
|
||||
src1 += rowpitch;
|
||||
src2 += rowpitch;
|
||||
src3 += rowpitch;
|
||||
src4 += rowpitch;
|
||||
|
||||
if ( rowadjust )
|
||||
{
|
||||
ra = (char *)src1;
|
||||
src1 = (long long int *)(ra + rowadjust);
|
||||
ra = (char *)src2;
|
||||
src2 = (long long int *)(ra + rowadjust);
|
||||
ra = (char *)src3;
|
||||
src3 = (long long int *)(ra + rowadjust);
|
||||
ra = (char *)src4;
|
||||
src4 = (long long int *)(ra + rowadjust);
|
||||
}
|
||||
}
|
||||
|
||||
DCFlushRange(texturemem, texturesize);
|
||||
|
||||
GX_SetNumChans(1);
|
||||
GX_LoadTexObj(&texobj, GX_TEXMAP0);
|
||||
|
||||
draw_square(view);
|
||||
|
||||
GX_DrawDone();
|
||||
|
||||
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
||||
GX_SetColorUpdate(GX_TRUE);
|
||||
GX_CopyDisp(xfb[whichfb], GX_TRUE);
|
||||
GX_Flush();
|
||||
|
||||
VIDEO_SetNextFramebuffer(xfb[whichfb]);
|
||||
VIDEO_Flush();
|
||||
//VIDEO_WaitVSync();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Drawing screen
|
||||
***************************************************************************/
|
||||
void
|
||||
clearscreen (int c)
|
||||
{
|
||||
int colour = COLOR_WHITE;
|
||||
|
||||
whichfb ^= 1;
|
||||
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], colour);
|
||||
#ifdef HW_RVL
|
||||
// on wii copy from memory
|
||||
//memcpy ((char *) xfb[whichfb], (char *) backdrop, 640 * screenheight * 2);
|
||||
#else
|
||||
// on gc copy from aram
|
||||
//ARAMFetch ((char *) xfb[whichfb], (char *) AR_BACKDROP, 640 * screenheight * 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
showscreen ()
|
||||
{
|
||||
copynow = GX_FALSE;
|
||||
VIDEO_SetNextFramebuffer (xfb[whichfb]);
|
||||
VIDEO_Flush ();
|
||||
VIDEO_WaitVSync ();
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* Generic GX Scaler
|
||||
* Generic GX Scaler
|
||||
* softdev 2007
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -23,7 +23,10 @@
|
||||
#ifndef __GXHDR__
|
||||
#define __GXHDR__
|
||||
|
||||
void GX_Start(int width, int height, int haspect, int vaspect);
|
||||
void InitialiseVideo ();
|
||||
void GX_Render_Init(int width, int height, int haspect, int vaspect);
|
||||
void GX_Render(int width, int height, u8 * buffer, int pitch);
|
||||
void clearscreen (int colour = COLOR_BLACK);
|
||||
void showscreen ();
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
#ifdef WII_BUILD
|
||||
#ifdef HW_RVL
|
||||
/****************************************************************************
|
||||
* VisualBoyAdvance 1.7.2
|
||||
*
|
||||
@ -17,6 +17,8 @@
|
||||
#include "Util.h"
|
||||
#include "Port.h"
|
||||
|
||||
#include "menudraw.h"
|
||||
|
||||
extern "C" {
|
||||
#include "tbtime.h"
|
||||
}
|
||||
@ -33,7 +35,7 @@ static u32 GBAROMSize = 0;
|
||||
static char romfilename[1024];
|
||||
|
||||
/**
|
||||
* GBA Memory
|
||||
* GBA Memory
|
||||
*/
|
||||
#define WORKRAM 0x40000
|
||||
#define BIOS 0x4000
|
||||
@ -47,7 +49,7 @@ static char romfilename[1024];
|
||||
VRAM + OAM + PIX + IOMEM )
|
||||
|
||||
extern void CPUUpdateRenderBuffers(bool force);
|
||||
extern void MENU_DrawString( int x, int y, char *msg, int style );
|
||||
|
||||
/****************************************************************************
|
||||
* VMAllocGBA
|
||||
*
|
||||
@ -102,34 +104,34 @@ int VMCPULoadROM( char *filename )
|
||||
VMAllocGBA();
|
||||
|
||||
GBAROMSize = 0;
|
||||
|
||||
/*sprintf(temp,"Filename %s\n", filename);
|
||||
MENU_DrawString( -1, 230,temp , 1 );
|
||||
*/
|
||||
|
||||
sprintf(temp,"Filename %s\n", filename);
|
||||
//WaitPrompt(temp);
|
||||
|
||||
romfile = gen_fopen(filename, "rb");
|
||||
if ( romfile == NULL )
|
||||
{
|
||||
MENU_DrawString( -1, 400,"Error opening file!" , 1 );
|
||||
while(1);
|
||||
WaitPrompt((char*) "Error opening file!");
|
||||
//while(1);
|
||||
VMClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
fseek(romfile, 0, SEEK_END);
|
||||
GBAROMSize = ftell(romfile);
|
||||
fseek(romfile, 0, SEEK_SET);
|
||||
|
||||
|
||||
sprintf(temp,"ROM Size %dMb (%dMBit)", GBAROMSize/1024/1024,(GBAROMSize*8)/1024/1024);
|
||||
MENU_DrawString( -1, 150,temp , 1 );
|
||||
|
||||
//WaitPrompt(temp);
|
||||
|
||||
rom = (u8 *)MEM2Storage;
|
||||
|
||||
|
||||
/* Always use MEM2, regardless of ROM size */
|
||||
res = gen_fread(rom, 1, GBAROMSize, romfile);
|
||||
|
||||
if ( (u32)res != GBAROMSize )
|
||||
{
|
||||
MENU_DrawString( -1, 400,"Error reading file!" , 1 );
|
||||
WaitPrompt((char*) "Error reading file!");
|
||||
while(1);
|
||||
}
|
||||
strcpy( romfilename, filename );
|
||||
@ -183,7 +185,7 @@ u16 VMRead16( u32 address )
|
||||
****************************************************************************/
|
||||
u8 VMRead8( u32 address )
|
||||
{
|
||||
|
||||
|
||||
if ( address >= GBAROMSize )
|
||||
{
|
||||
return ( address >> 1 ) & 0xff;
|
||||
@ -193,8 +195,7 @@ u8 VMRead8( u32 address )
|
||||
return (u8)rom[address];
|
||||
|
||||
}
|
||||
#endif
|
||||
#ifdef GC_BUILD
|
||||
#else
|
||||
/****************************************************************************
|
||||
* VisualBoyAdvance 1.7.2
|
||||
*
|
||||
@ -211,6 +212,8 @@ u8 VMRead8( u32 address )
|
||||
#include "Util.h"
|
||||
#include "Port.h"
|
||||
|
||||
#include "menudraw.h"
|
||||
|
||||
extern "C" {
|
||||
#include "tbtime.h"
|
||||
}
|
||||
@ -248,7 +251,7 @@ static u32 GBAROMSize = 0;
|
||||
static char romfilename[1024];
|
||||
|
||||
/**
|
||||
* GBA Memory
|
||||
* GBA Memory
|
||||
*/
|
||||
#define WORKRAM 0x40000
|
||||
#define BIOS 0x4000
|
||||
@ -376,6 +379,7 @@ static void VMClose( void )
|
||||
int VMCPULoadROM( char *filename )
|
||||
{
|
||||
int res;
|
||||
char msg[512];
|
||||
|
||||
/** Fix VM **/
|
||||
VMClose();
|
||||
@ -389,7 +393,7 @@ int VMCPULoadROM( char *filename )
|
||||
romfile = gen_fopen(filename, "rb");
|
||||
if ( romfile == NULL )
|
||||
{
|
||||
printf("Error opening file!\n");
|
||||
WaitPrompt((char*) "Error opening file!");
|
||||
while(1);
|
||||
VMClose();
|
||||
return 0;
|
||||
@ -401,7 +405,8 @@ int VMCPULoadROM( char *filename )
|
||||
res = gen_fread(rom, 1, (1 << VMSHIFTBITS), romfile);
|
||||
if ( res != (1 << VMSHIFTBITS ) )
|
||||
{
|
||||
printf("Error reading file! %i \n",res);
|
||||
sprintf(msg, "Error reading file! %i \n",res);
|
||||
WaitPrompt(msg);
|
||||
while(1);
|
||||
}
|
||||
|
||||
@ -431,13 +436,15 @@ static void VMNewPage( int pageid )
|
||||
{
|
||||
int res;
|
||||
tb_t start,end;
|
||||
char msg[512];
|
||||
|
||||
mftb(&start);
|
||||
|
||||
res = gen_fseek( romfile, pageid << VMSHIFTBITS, SEEK_SET );
|
||||
if ( ! res )
|
||||
{
|
||||
printf("Seek error! - Offset %08x %d\n", pageid << VMSHIFTBITS, res);
|
||||
sprintf(msg, "Seek error! - Offset %08x %d\n", pageid << VMSHIFTBITS, res);
|
||||
WaitPrompt(msg);
|
||||
while(1);
|
||||
}
|
||||
|
||||
@ -446,7 +453,8 @@ static void VMNewPage( int pageid )
|
||||
res = gen_fread( vmpage[pageid].pageptr, 1, 1 << VMSHIFTBITS, romfile );
|
||||
if ( res != ( 1 << VMSHIFTBITS ) )
|
||||
{
|
||||
printf("Error reading! %d bytes only\n", res);
|
||||
sprintf(msg, "Error reading! %d bytes only\n", res);
|
||||
WaitPrompt(msg);
|
||||
while(1);
|
||||
}
|
||||
|
||||
@ -481,6 +489,7 @@ u32 VMRead32( u32 address )
|
||||
{
|
||||
int pageid;
|
||||
u32 badaddress;
|
||||
char msg[512];
|
||||
//printf("VM32 : Request %08x\n", address);
|
||||
|
||||
if ( address >= GBAROMSize )
|
||||
@ -504,8 +513,9 @@ u32 VMRead32( u32 address )
|
||||
return READ32LE( vmpage[pageid].pageptr + ( address & VMSHIFTMASK ) );
|
||||
|
||||
default:
|
||||
printf("VM32 : Unknown page type! (%d) [%d]\n", vmpage[pageid].pagetype, pageid);
|
||||
while(1);
|
||||
sprintf(msg, "VM32 : Unknown page type! (%d) [%d]", vmpage[pageid].pagetype, pageid);
|
||||
WaitPrompt(msg);
|
||||
while(1);
|
||||
}
|
||||
|
||||
/* Can never get here ... but stops gcc bitchin' */
|
||||
@ -543,7 +553,7 @@ u16 VMRead16( u32 address )
|
||||
return READ16LE( vmpage[pageid].pageptr + ( address & VMSHIFTMASK ) );
|
||||
|
||||
default:
|
||||
printf("VM16 : Unknown page type!\n");
|
||||
WaitPrompt((char*) "VM16 : Unknown page type!");
|
||||
while(1);
|
||||
}
|
||||
|
||||
@ -582,7 +592,7 @@ u8 VMRead8( u32 address )
|
||||
return (u8)vmpage[pageid].pageptr[ (address & VMSHIFTMASK) ];
|
||||
|
||||
default:
|
||||
printf("VM8 : Unknown page type!\n");
|
||||
WaitPrompt((char*) "VM8 : Unknown page type!");
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user