2008-08-06 03:09:59 +02:00
|
|
|
/****************************************************************************
|
2010-01-27 23:20:37 +01:00
|
|
|
* Snes9x Nintendo Wii/Gamecube Port
|
2008-08-06 03:09:59 +02:00
|
|
|
*
|
|
|
|
* softdev July 2006
|
|
|
|
* crunchy2 May 2007
|
2008-09-23 06:13:33 +02:00
|
|
|
* Michniewski 2008
|
2010-01-27 23:20:37 +01:00
|
|
|
* Tantric 2008-2010
|
2008-08-06 03:09:59 +02:00
|
|
|
*
|
|
|
|
* s9xsupport.cpp
|
|
|
|
*
|
2009-11-25 07:35:14 +01:00
|
|
|
* Snes9x support functions
|
2008-09-12 07:28:40 +02:00
|
|
|
***************************************************************************/
|
2008-08-06 03:09:59 +02:00
|
|
|
|
|
|
|
#include <gccore.h>
|
|
|
|
#include <ogcsys.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2008-08-06 03:39:43 +02:00
|
|
|
#include <unistd.h>
|
2009-05-21 07:58:19 +02:00
|
|
|
#include <ogc/lwp_watchdog.h>
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2010-03-22 00:43:54 +01:00
|
|
|
#include "snes9xgx.h"
|
2008-08-06 03:09:59 +02:00
|
|
|
#include "video.h"
|
|
|
|
#include "audio.h"
|
2010-03-22 00:43:54 +01:00
|
|
|
#include "snes9x/snes9x.h"
|
|
|
|
#include "snes9x/memmap.h"
|
|
|
|
#include "snes9x/display.h"
|
|
|
|
#include "snes9x/apu/apu.h"
|
|
|
|
#include "snes9x/controls.h"
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2010-01-27 23:08:56 +01:00
|
|
|
#define MAX_MESSAGE_LEN (36 * 3)
|
|
|
|
|
2009-05-25 08:47:37 +02:00
|
|
|
static long long prev;
|
|
|
|
static long long now;
|
2008-08-06 03:09:59 +02:00
|
|
|
|
|
|
|
/*** Miscellaneous Functions ***/
|
2009-11-25 07:35:14 +01:00
|
|
|
void S9xExit()
|
|
|
|
{
|
|
|
|
ExitApp();
|
|
|
|
}
|
|
|
|
|
2009-06-15 10:23:19 +02:00
|
|
|
void S9xMessage(int /*type */, int /*number */, const char *message)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2009-06-15 10:23:19 +02:00
|
|
|
static char buffer[MAX_MESSAGE_LEN + 1];
|
|
|
|
strncpy(buffer, message, MAX_MESSAGE_LEN);
|
|
|
|
buffer[MAX_MESSAGE_LEN] = 0;
|
|
|
|
S9xSetInfoString(buffer);
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
2009-06-15 10:23:19 +02:00
|
|
|
void S9xAutoSaveSRAM()
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2008-09-08 01:50:57 +02:00
|
|
|
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*** Sound based functions ***/
|
2009-06-15 10:23:19 +02:00
|
|
|
void S9xToggleSoundChannel(int c)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2010-01-27 23:08:56 +01:00
|
|
|
static int sound_switch = 255;
|
|
|
|
|
|
|
|
if (c == 8)
|
|
|
|
sound_switch = 255;
|
|
|
|
else
|
|
|
|
sound_switch ^= 1 << c;
|
|
|
|
|
|
|
|
S9xSetSoundControl (sound_switch);
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* OpenSoundDevice
|
|
|
|
*
|
2009-11-25 07:35:14 +01:00
|
|
|
* Main initialisation for Wii sound system
|
2008-09-12 07:28:40 +02:00
|
|
|
***************************************************************************/
|
2010-01-27 23:08:56 +01:00
|
|
|
bool8 S9xOpenSoundDevice(void)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2009-06-15 10:23:19 +02:00
|
|
|
InitAudio();
|
|
|
|
return TRUE;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* eke-eke */
|
|
|
|
void S9xInitSync()
|
2008-09-08 01:50:57 +02:00
|
|
|
{
|
2009-06-15 10:23:19 +02:00
|
|
|
FrameTimer = 0;
|
|
|
|
prev = gettime();
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*** Synchronisation ***/
|
2008-08-06 03:39:43 +02:00
|
|
|
|
|
|
|
void S9xSyncSpeed ()
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2010-01-27 23:08:56 +01:00
|
|
|
while (!S9xSyncSound())
|
|
|
|
usleep(10);
|
|
|
|
|
2009-06-15 10:23:19 +02:00
|
|
|
uint32 skipFrms = Settings.SkipFrames;
|
|
|
|
|
|
|
|
if (Settings.TurboMode)
|
|
|
|
skipFrms = Settings.TurboSkipFrames;
|
|
|
|
|
|
|
|
if (timerstyle == 0) /* use NGC vertical sync (VSYNC) with NTSC roms */
|
|
|
|
{
|
|
|
|
while (FrameTimer == 0)
|
|
|
|
{
|
|
|
|
usleep(50);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FrameTimer > skipFrms)
|
|
|
|
FrameTimer = skipFrms;
|
|
|
|
|
|
|
|
if ((FrameTimer > 1) && (IPPU.SkippedFrames < skipFrms))
|
|
|
|
{
|
|
|
|
IPPU.SkippedFrames++;
|
|
|
|
IPPU.RenderThisFrame = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IPPU.SkippedFrames = 0;
|
|
|
|
IPPU.RenderThisFrame = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else /* use internal timer for PAL roms */
|
|
|
|
{
|
|
|
|
unsigned int timediffallowed = Settings.TurboMode ? 0 : Settings.FrameTime;
|
|
|
|
now = gettime();
|
|
|
|
|
|
|
|
if (diff_usec(prev, now) > timediffallowed)
|
|
|
|
{
|
|
|
|
/* Timer has already expired */
|
|
|
|
if (IPPU.SkippedFrames < skipFrms)
|
|
|
|
{
|
|
|
|
IPPU.SkippedFrames++;
|
|
|
|
IPPU.RenderThisFrame = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IPPU.SkippedFrames = 0;
|
|
|
|
IPPU.RenderThisFrame = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*** Ahead - so hold up ***/
|
|
|
|
while (diff_usec(prev, now) < timediffallowed)
|
|
|
|
{
|
|
|
|
now = gettime();
|
|
|
|
usleep(50);
|
|
|
|
}
|
|
|
|
IPPU.RenderThisFrame = TRUE;
|
|
|
|
IPPU.SkippedFrames = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
prev = now;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
2009-06-15 10:23:19 +02:00
|
|
|
if (!Settings.TurboMode)
|
|
|
|
FrameTimer--;
|
|
|
|
return;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*** Video / Display related functions ***/
|
2009-06-15 10:23:19 +02:00
|
|
|
bool8 S9xInitUpdate()
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2009-06-15 10:23:19 +02:00
|
|
|
return (TRUE);
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
2009-06-15 10:23:19 +02:00
|
|
|
bool8 S9xDeinitUpdate(int Width, int Height)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2009-06-15 10:23:19 +02:00
|
|
|
update_video(Width, Height);
|
|
|
|
return (TRUE);
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
2009-06-15 10:23:19 +02:00
|
|
|
bool8 S9xContinueUpdate(int Width, int Height)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2009-06-15 10:23:19 +02:00
|
|
|
return (TRUE);
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
2009-06-15 10:23:19 +02:00
|
|
|
void S9xSetPalette()
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2009-06-15 10:23:19 +02:00
|
|
|
return;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*** Input functions ***/
|
2009-06-15 10:23:19 +02:00
|
|
|
void S9xHandlePortCommand(s9xcommand_t cmd, int16 data1, int16 data2)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2009-06-15 10:23:19 +02:00
|
|
|
return;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
2009-06-15 10:23:19 +02:00
|
|
|
bool S9xPollButton(uint32 id, bool * pressed)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2009-06-15 10:23:19 +02:00
|
|
|
return 0;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
2009-06-15 10:23:19 +02:00
|
|
|
bool S9xPollAxis(uint32 id, int16 * value)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2009-06-15 10:23:19 +02:00
|
|
|
return 0;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
2009-06-15 10:23:19 +02:00
|
|
|
bool S9xPollPointer(uint32 id, int16 * x, int16 * y)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2009-06-15 10:23:19 +02:00
|
|
|
return 0;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
2009-11-25 07:35:14 +01:00
|
|
|
/****************************************************************************
|
|
|
|
* Note that these are DUMMY functions, and only allow Snes9x to
|
|
|
|
* compile. Where possible, they will return an error signal.
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
const char *S9xChooseFilename(bool8 read_only)
|
|
|
|
{
|
2010-01-27 23:08:56 +01:00
|
|
|
ExitApp();
|
2009-11-25 07:35:14 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char * S9xChooseMovieFilename(bool8 read_only)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2010-01-27 23:08:56 +01:00
|
|
|
ExitApp();
|
2009-11-25 07:35:14 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2009-11-25 07:35:14 +01:00
|
|
|
const char * S9xGetDirectory(enum s9x_getdirtype dirtype)
|
|
|
|
{
|
2010-01-27 23:08:56 +01:00
|
|
|
ExitApp();
|
2009-11-25 07:35:14 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2009-11-25 07:35:14 +01:00
|
|
|
const char * S9xGetFilename(const char *ex, enum s9x_getdirtype dirtype)
|
|
|
|
{
|
2010-01-27 23:08:56 +01:00
|
|
|
ExitApp();
|
2009-11-25 07:35:14 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2009-11-25 07:35:14 +01:00
|
|
|
const char * S9xGetFilenameInc(const char *e, enum s9x_getdirtype dirtype)
|
|
|
|
{
|
2010-01-27 23:08:56 +01:00
|
|
|
ExitApp();
|
2009-11-25 07:35:14 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2010-01-27 23:08:56 +01:00
|
|
|
const char * S9xBasename(const char *name)
|
2009-11-25 07:35:14 +01:00
|
|
|
{
|
2010-01-27 23:08:56 +01:00
|
|
|
ExitApp();
|
2009-11-25 07:35:14 +01:00
|
|
|
return name;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
2008-09-12 07:28:40 +02:00
|
|
|
|
2010-01-27 23:08:56 +01:00
|
|
|
const char * S9xStringInput (const char * s)
|
|
|
|
{
|
|
|
|
ExitApp();
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2009-11-25 07:35:14 +01:00
|
|
|
void _splitpath(char const *buf, char *drive, char *dir, char *fname, char *ext)
|
2008-09-12 07:28:40 +02:00
|
|
|
{
|
2010-01-27 23:08:56 +01:00
|
|
|
ExitApp();
|
2008-09-12 07:28:40 +02:00
|
|
|
}
|
|
|
|
|
2009-06-15 10:23:19 +02:00
|
|
|
void _makepath(char *filename, const char *drive, const char *dir,
|
|
|
|
const char *fname, const char *ext)
|
2008-09-12 07:28:40 +02:00
|
|
|
{
|
2010-01-27 23:08:56 +01:00
|
|
|
ExitApp();
|
|
|
|
}
|
|
|
|
|
|
|
|
int dup(int fildes)
|
|
|
|
{
|
|
|
|
ExitApp();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int access(const char *pathname, int mode)
|
|
|
|
{
|
|
|
|
ExitApp();
|
|
|
|
return 1;
|
2008-09-12 07:28:40 +02:00
|
|
|
}
|