2008-08-06 03:09:59 +02:00
|
|
|
/****************************************************************************
|
2008-09-12 07:28:40 +02:00
|
|
|
* Snes9x 1.51 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
|
2008-09-12 07:28:40 +02:00
|
|
|
* Tantric September 2008
|
2008-08-06 03:09:59 +02:00
|
|
|
*
|
|
|
|
* s9xsupport.cpp
|
|
|
|
*
|
|
|
|
* This file contains the supporting functions defined in porting.html, with
|
|
|
|
* others taken from unix/x11.cpp and unix/unix.cpp
|
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>
|
2008-08-06 03:09:59 +02:00
|
|
|
|
|
|
|
#include "snes9x.h"
|
|
|
|
#include "memmap.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "cpuexec.h"
|
|
|
|
#include "ppu.h"
|
|
|
|
#include "apu.h"
|
|
|
|
#include "display.h"
|
|
|
|
#include "gfx.h"
|
|
|
|
#include "soundux.h"
|
|
|
|
#include "spc700.h"
|
|
|
|
#include "spc7110.h"
|
|
|
|
#include "controls.h"
|
|
|
|
|
2008-09-09 19:36:48 +02:00
|
|
|
#include "snes9xGX.h"
|
2008-08-06 03:09:59 +02:00
|
|
|
#include "video.h"
|
|
|
|
#include "audio.h"
|
|
|
|
|
|
|
|
extern u32 FrameTimer;
|
|
|
|
|
2008-08-06 03:39:43 +02:00
|
|
|
long long prev;
|
|
|
|
long long now;
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2008-09-12 07:28:40 +02:00
|
|
|
extern "C" {
|
|
|
|
|
|
|
|
long long gettime();
|
|
|
|
u32 diff_usec(long long start,long long end);
|
|
|
|
|
|
|
|
}
|
2008-08-06 03:09:59 +02:00
|
|
|
|
|
|
|
/*** Miscellaneous Functions ***/
|
|
|
|
void
|
|
|
|
S9xMessage (int /*type */ , int /*number */ , const char *message)
|
|
|
|
{
|
|
|
|
#define MAX_MESSAGE_LEN (36 * 3)
|
|
|
|
|
|
|
|
static char buffer[MAX_MESSAGE_LEN + 1];
|
|
|
|
strncpy (buffer, message, MAX_MESSAGE_LEN);
|
|
|
|
buffer[MAX_MESSAGE_LEN] = 0;
|
|
|
|
S9xSetInfoString (buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
S9xExit ()
|
|
|
|
{
|
|
|
|
/*** Nintendo Gamecube will NEVER get here ... unless
|
|
|
|
something major went wrong !!
|
2008-09-08 01:50:57 +02:00
|
|
|
|
2008-08-06 03:09:59 +02:00
|
|
|
In which case, I'll settle for a reboot first -;)
|
|
|
|
***/
|
|
|
|
}
|
|
|
|
|
|
|
|
/*** File based functions ***/
|
|
|
|
const char *
|
|
|
|
S9xChooseFilename (bool8 read_only)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
S9xChooseMovieFilename (bool8 read_only)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
S9xGetDirectory (enum s9x_getdirtype dirtype)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
S9xGetFilename (const char *ex, enum s9x_getdirtype dirtype)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
S9xGetFilenameInc (const char *e, enum s9x_getdirtype dirtype)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*** Memory based functions ***/
|
|
|
|
void
|
|
|
|
S9xAutoSaveSRAM ()
|
|
|
|
{
|
2008-09-08 01:50:57 +02:00
|
|
|
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*** Sound based functions ***/
|
|
|
|
void
|
|
|
|
S9xToggleSoundChannel (int c)
|
|
|
|
{
|
|
|
|
if (c == 8)
|
|
|
|
so.sound_switch = 255;
|
|
|
|
else
|
|
|
|
so.sound_switch ^= 1 << c;
|
|
|
|
S9xSetSoundControl (so.sound_switch);
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* OpenSoundDevice
|
|
|
|
*
|
|
|
|
* Main initialisation for NGC sound system
|
2008-09-12 07:28:40 +02:00
|
|
|
***************************************************************************/
|
2008-08-06 03:09:59 +02:00
|
|
|
bool8
|
|
|
|
S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size)
|
|
|
|
{
|
|
|
|
so.stereo = TRUE;
|
|
|
|
so.playback_rate = 32000;
|
|
|
|
so.sixteen_bit = TRUE;
|
|
|
|
so.encoded = 0;
|
|
|
|
so.buffer_size = 4096;
|
|
|
|
so.sound_switch = 255;
|
|
|
|
S9xSetPlaybackRate (so.playback_rate);
|
|
|
|
|
|
|
|
InitGCAudio ();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*** Deprecated function. NGC uses threaded sound ***/
|
|
|
|
void
|
|
|
|
S9xGenerateSound ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/* eke-eke */
|
|
|
|
void S9xInitSync()
|
2008-09-08 01:50:57 +02:00
|
|
|
{
|
2008-08-06 03:09:59 +02:00
|
|
|
FrameTimer = 0;
|
2008-08-06 03:39:43 +02:00
|
|
|
prev = gettime();
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*** Synchronisation ***/
|
2008-08-06 03:39:43 +02:00
|
|
|
extern int timerstyle;
|
|
|
|
|
|
|
|
void S9xSyncSpeed ()
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
|
|
|
uint32 skipFrms = Settings.SkipFrames;
|
2008-09-08 01:50:57 +02:00
|
|
|
|
2008-08-06 03:09:59 +02:00
|
|
|
if ( Settings.TurboMode )
|
|
|
|
skipFrms = Settings.TurboSkipFrames;
|
|
|
|
|
2008-08-06 03:39:43 +02:00
|
|
|
if ( timerstyle == 0 ) /* use NGC vertical sync (VSYNC) with NTSC roms */
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
|
|
|
while (FrameTimer == 0)
|
|
|
|
{
|
|
|
|
usleep (50);
|
|
|
|
}
|
2008-09-08 01:50:57 +02:00
|
|
|
|
2008-08-06 03:09:59 +02:00
|
|
|
if (FrameTimer > skipFrms)
|
|
|
|
FrameTimer = skipFrms;
|
2008-09-08 01:50:57 +02:00
|
|
|
|
2008-08-06 03:09:59 +02:00
|
|
|
if ((FrameTimer > 1) && (IPPU.SkippedFrames < skipFrms))
|
|
|
|
{
|
|
|
|
IPPU.SkippedFrames++;
|
|
|
|
IPPU.RenderThisFrame = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IPPU.SkippedFrames = 0;
|
|
|
|
IPPU.RenderThisFrame = TRUE;
|
|
|
|
}
|
|
|
|
}
|
2008-09-08 01:50:57 +02:00
|
|
|
else /* use internal timer for PAL roms */
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
|
|
|
unsigned int timediffallowed = Settings.TurboMode ? 0 : Settings.FrameTime;
|
2008-08-06 03:39:43 +02:00
|
|
|
now = gettime();
|
2008-09-08 01:50:57 +02:00
|
|
|
|
2008-08-06 03:39:43 +02:00
|
|
|
if (diff_usec(prev, now) > timediffallowed)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2008-08-06 03:39:43 +02:00
|
|
|
/*while ( diff_usec((prev, now) < timediffallowed * 2) {
|
|
|
|
now = gettime();
|
2008-08-06 03:09:59 +02:00
|
|
|
}*/
|
|
|
|
|
|
|
|
/* 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 ***/
|
2008-08-06 03:39:43 +02:00
|
|
|
while (diff_usec(prev, now) < timediffallowed) now=gettime();
|
2008-08-06 03:09:59 +02:00
|
|
|
IPPU.RenderThisFrame = TRUE;
|
|
|
|
IPPU.SkippedFrames = 0;
|
|
|
|
}
|
|
|
|
|
2008-08-06 03:39:43 +02:00
|
|
|
prev = now;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
2008-09-08 01:50:57 +02:00
|
|
|
|
2008-08-06 03:09:59 +02:00
|
|
|
if ( !Settings.TurboMode )
|
|
|
|
FrameTimer--;
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*** Video / Display related functions ***/
|
|
|
|
bool8
|
|
|
|
S9xInitUpdate ()
|
|
|
|
{
|
|
|
|
/***
|
|
|
|
* Is this necessary in 1.50 ?
|
|
|
|
* memset (GFX.Screen, 0, IMAGE_WIDTH * IMAGE_HEIGHT * 2);
|
|
|
|
*/
|
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8
|
|
|
|
S9xDeinitUpdate (int Width, int Height)
|
|
|
|
{
|
|
|
|
update_video (Width, Height);
|
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8
|
|
|
|
S9xContinueUpdate (int Width, int Height)
|
|
|
|
{
|
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
S9xSetPalette ()
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*** Input functions ***/
|
|
|
|
void
|
|
|
|
S9xHandlePortCommand (s9xcommand_t cmd, int16 data1, int16 data2)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
S9xPollButton (uint32 id, bool * pressed)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
S9xPollAxis (uint32 id, int16 * value)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
S9xPollPointer (uint32 id, int16 * x, int16 * y)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
S9xLoadSDD1Data ()
|
|
|
|
{
|
|
|
|
|
|
|
|
Memory.FreeSDD1Data ();
|
|
|
|
|
|
|
|
Settings.SDD1Pack = FALSE;
|
|
|
|
|
|
|
|
if (strncmp (Memory.ROMName, "Star Ocean", 10) == 0)
|
|
|
|
Settings.SDD1Pack = TRUE;
|
|
|
|
|
|
|
|
if (strncmp (Memory.ROMName, "STREET FIGHTER ALPHA2", 21) == 0)
|
|
|
|
Settings.SDD1Pack = TRUE;
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
2008-09-12 07:28:40 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Note that these are DUMMY functions, and only allow Snes9x to
|
|
|
|
* compile. Where possible, they will return an error signal.
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/*** splitpath function ***/
|
|
|
|
void
|
|
|
|
_splitpath (char const *buffer, char *drive, char *dir, char *fname,
|
|
|
|
char *ext)
|
|
|
|
{
|
|
|
|
return; /*** Do nothing - NGC code should NEVER call a function which relies on it ***/
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_makepath (char *filename, const char *drive, const char *dir,
|
|
|
|
const char *fname, const char *ext)
|
|
|
|
{
|
|
|
|
return; /*** Do nothing - NGC code should NEVER call a function which relies on it ***/
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
S9xBasename (char *name)
|
|
|
|
{
|
|
|
|
return name;
|
|
|
|
}
|