- fix windows keyboard shortcuts and pause (recently broken)

- maybe fix crashy savestates?
- do a bunch of valgrinding to fix memory problems
- add spu to savestate (still need to add mmu and fifos); tweak savestate variables a little bit.
This commit is contained in:
zeromus 2008-09-26 06:24:36 +00:00
parent c42e035d50
commit 099f683f4a
13 changed files with 211 additions and 69 deletions

View File

@ -191,11 +191,7 @@ void GPU_Reset(GPU *g, u8 l)
g->sprMem = ARM9Mem.ARM9_BOBJ;
// GPU core B
g->dispx_st = (REG_DISPx*)(&ARM9Mem.ARM9_REG[REG_DISPB]);
if (osdB==NULL)
{
delete osdB;
osdB=NULL;
}
delete osdB;
osdB = new OSDCLASS(1);
}
else
@ -204,40 +200,19 @@ void GPU_Reset(GPU *g, u8 l)
g->sprMem = ARM9Mem.ARM9_AOBJ;
// GPU core A
g->dispx_st = (REG_DISPx*)(&ARM9Mem.ARM9_REG[0]);
if (osdA==NULL)
{
delete osdA;
osdA=NULL;
}
delete osdA;
osdA = new OSDCLASS(0);
}
if (osd==NULL)
{
delete osd;
osd=NULL;
}
delete osd;
osd = new OSDCLASS(-1);
}
void GPU_DeInit(GPU * gpu)
{
if (osd==NULL)
{
delete osd;
osd=NULL;
}
if (osdA==NULL)
{
delete osdA;
osdA=NULL;
}
if (osdB==NULL)
{
delete osdB;
osdB=NULL;
}
delete osd; osd=NULL;
delete osdA; osdA=NULL;
delete osdB; osdB=NULL;
free(gpu);
}

View File

@ -70,7 +70,7 @@ OSDCLASS::~OSDCLASS()
{
LOG("OSD_Deinit (%s)\n",name);
delete old_msg;
delete[] old_msg;
}
void OSDCLASS::setOffset(u16 ofs)
@ -155,6 +155,6 @@ void OSDCLASS::addFixed(u16 x, u16 y, const char *fmt, ...)
x+=OSD_FONT_WIDTH+2;
old_msg[i]=msg[i];
}
old_msg[512]=0;
old_msg[511]=0;
needUpdate = true;
}

View File

@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "MMU.h"
#include "SPU.h"
#include "mem.h"
#include "readwrite.h"
#include "armcpu.h"
SPU_struct *SPU_core = 0;
@ -77,7 +77,7 @@ int SPU_ChangeSoundCore(int coreid, int buffersize)
{
int i;
delete SPU_user;
delete SPU_user; SPU_user = 0;
// Make sure the old core is freed
if (SNDCore)
@ -155,11 +155,6 @@ void SPU_SetVolume(int volume)
//////////////////////////////////////////////////////////////////////////////
void SPU_struct::reset()
{
memset((void *)channels, 0, sizeof(channel_struct) * 16);
}
void SPU_Reset(void)
{
int i;
@ -167,12 +162,23 @@ void SPU_Reset(void)
SPU_core->reset();
if(SPU_user) SPU_user->reset();
if(SNDCore && SPU_user) {
SNDCore->DeInit();
SNDCore->Init(SPU_user->bufsize*2);
//todo - check success?
}
// Reset Registers
for (i = 0x400; i < 0x51D; i++)
T1WriteByte(MMU.ARM7_REG, i, 0);
}
//////////////////////////////////////////////////////////////////////////////
void SPU_struct::reset()
{
memset((void *)channels, 0, sizeof(channel_struct) * 16);
memset(sndbuf,0,bufsize*2*4);
memset(outbuf,0,bufsize*2*2);
}
SPU_struct::SPU_struct(int buffersize)
: bufpos(0)
@ -181,11 +187,9 @@ SPU_struct::SPU_struct(int buffersize)
, outbuf(0)
, bufsize(buffersize)
{
reset();
sndbuf = new s32[buffersize*2];
outbuf = new s16[buffersize*2];
memset(sndbuf,0,buffersize*2*4);
memset(outbuf,0,buffersize*2*2);
reset();
}
SPU_struct::~SPU_struct()
@ -1207,6 +1211,9 @@ void SPU_Emulate_core()
void SPU_Emulate_user()
{
if(!SPU_user)
return;
u32 audiosize;
// Check to see how much free space there is
@ -1427,3 +1434,76 @@ void SNDFileSetVolume(int volume)
//////////////////////////////////////////////////////////////////////////////
void spu_savestate(std::ostream* os)
{
//version
write32le(0,os);
SPU_struct *spu = SPU_core;
for(int j=0;j<16;j++) {
channel_struct &chan = spu->channels[j];
write8le(chan.vol,os);
write8le(chan.datashift,os);
write8le(chan.hold,os);
write8le(chan.pan,os);
write8le(chan.waveduty,os);
write8le(chan.repeat,os);
write8le(chan.format,os);
write8le(chan.status,os);
write32le(chan.addr,os);
write16le(chan.timer,os);
write16le(chan.loopstart,os);
write32le(chan.length,os);
write64le(double_to_u64(chan.sampcnt),os);
write64le(double_to_u64(chan.sampinc),os);
write32le(chan.lastsampcnt,os);
write16le(chan.pcm16b,os);
write16le(chan.pcm16b_last,os);
write32le(chan.index,os);
}
}
bool spu_loadstate(std::istream* is)
{
//read version
int version;
if(read32le(&version,is) != 1) return false;
if(version != 0) return false;
SPU_struct *spu = SPU_core;
for(int j=0;j<16;j++) {
channel_struct &chan = spu->channels[j];
read8le(&chan.vol,is);
read8le(&chan.datashift,is);
read8le(&chan.hold,is);
read8le(&chan.pan,is);
read8le(&chan.waveduty,is);
read8le(&chan.repeat,is);
read8le(&chan.format,is);
read8le(&chan.status,is);
read32le(&chan.addr,is);
read16le(&chan.timer,is);
read16le(&chan.loopstart,is);
read32le(&chan.length,is);
u64 temp;
read64le(&temp,is); chan.sampcnt = u64_to_double(temp);
read64le(&temp,is); chan.sampinc = u64_to_double(temp);
read32le(&chan.lastsampcnt,is);
read16le(&chan.pcm16b,is);
read16le(&chan.pcm16b_last,is);
read32le(&chan.index,is);
//fixup the pointers which we had are supposed to keep cached
chan.buf8 = (s8*)&MMU.MMU_MEM[1][(chan.addr>>20)&0xFF][(chan.addr & MMU.MMU_MASK[1][(chan.addr >> 20) & 0xFF])];
chan.buf16 = (s16*)chan.buf8;
}
//copy the core spu (the more accurate) to the user spu
if(SPU_user) {
memcpy(SPU_core->channels,SPU_user->channels,sizeof(SPU_core->channels));
}
return true;
}

View File

@ -21,6 +21,7 @@
#define SPU_H
#include "types.h"
#include <iosfwd>
#define SNDCORE_DEFAULT -1
#define SNDCORE_DUMMY 0
@ -104,4 +105,7 @@ void SPU_Emulate_user(void);
extern SPU_struct *SPU_core;
extern int spu_core_samples;
void spu_savestate(std::ostream* os);
bool spu_loadstate(std::istream* is);
#endif

View File

@ -100,9 +100,11 @@ int FsReadNext(void * search, FsEntry * entry) {
}
void FsClose(void * search) {
DIR * dir = ((FsLinuxDir *) search)->dir;
FsLinuxDir *linuxdir = (FsLinuxDir *) search;
DIR * dir = linuxdir->dir;
closedir(dir);
free(linuxdir->path);
free(search);
}

View File

@ -133,7 +133,7 @@ static float cacheLightDirection[4][4];
#define RENDER_BACK_SURFACE 0X40
//-------------poly and vertex lists
//-------------poly and vertex lists and such things
POLYLIST polylists[2];
POLYLIST* polylist = &polylists[0];
VERTLIST vertlists[2];
@ -154,6 +154,9 @@ static void twiddleLists() {
vertlist->count = 0;
}
static BOOL flushPending = FALSE;
static u32 flush_wbuffer;
static u32 flush_sortmode;
//------------------------------------------------------------
static void makeTables() {
@ -187,6 +190,7 @@ void gfx3d_reset()
{
gfx3d = GFX3D();
flushPending = FALSE;
listTwiddle = 1;
twiddleLists();
@ -1355,14 +1359,9 @@ void gfx3d_glCallList(unsigned long v)
}
}
static bool flushPending = false;
static u32 flush_wbuffer;
static u32 flush_sortmode;
void gfx3d_glFlush(unsigned long v)
{
flushPending = true;
flushPending = TRUE;
gfx3d.wbuffer = (v&1)!=0;
gfx3d.sortmode = ((v>>1)&1)!=0;
@ -1399,7 +1398,7 @@ void gfx3d_VBlankSignal()
//the 3d buffers are swapped when a vblank begins.
//so, if we have a redraw pending, now is a safe time to do it
if(!flushPending) return;
flushPending = false;
flushPending = FALSE;
gpu3D->NDS_3D_Render();
}
@ -1519,6 +1518,7 @@ SFORMAT SF_GFX3D[]={
{ &dsEmission, 2|SS_RLSB, "GMEM" },
{ &triStripToggle, 4|SS_RLSB, "GTST" },
{ &listTwiddle, 4|SS_RLSB, "GLTW" },
{ &flushPending, 4|SS_RLSB, "GFLP" },
{ &gfx3d.enableTexturing, 4|SS_RLSB, "GSET" },
{ &gfx3d.enableAlphaTest, 4|SS_RLSB, "GSEA" },
{ &gfx3d.enableAlphaBlending, 4|SS_RLSB, "GSEB" },

View File

@ -182,7 +182,7 @@ void mc_reset_com(memory_chip_t *mc)
void mc_realloc(memory_chip_t *mc, int type, u32 size)
{
if(mc->data) free(mc->data);
if(mc->data) delete[] mc->data;
mc_init(mc, type);
mc_alloc(mc, size);
}

View File

@ -1,6 +1,27 @@
#include "readwrite.h"
#include "types.h"
//well. just for the sake of consistency
int write8le(u8 b, FILE *fp)
{
return((fwrite(&b,1,1,fp)<1)?0:1);
}
//well. just for the sake of consistency
int write8le(u8 b, std::ostream *os)
{
os->write((char*)&b,1);
return 1;
}
//well. just for the sake of consistency
int read8le(u8 *Bufo, std::istream *is)
{
if(is->read((char*)Bufo,1).gcount() != 1)
return 0;
return 1;
}
///writes a little endian 16bit value to the specified file
int write16le(u16 b, FILE *fp)
{
@ -10,6 +31,17 @@ int write16le(u16 b, FILE *fp)
return((fwrite(s,1,2,fp)<2)?0:2);
}
///writes a little endian 16bit value to the specified file
int write16le(u16 b, std::ostream *os)
{
u8 s[2];
s[0]=b;
s[1]=b>>8;
os->write((char*)&s,2);
return 2;
}
///writes a little endian 32bit value to the specified file
int write32le(u32 b, FILE *fp)
{
@ -89,7 +121,6 @@ int read64le(u64 *Bufo, std::istream *is)
return 1;
}
int read32le(u32 *Bufo, std::istream *is)
{
u32 buf;

View File

@ -4,13 +4,20 @@
#include "types.h"
#include <iostream>
//well. just for the sake of consistency
int write8le(u8 b, FILE *fp);
int write8le(u8 b, std::ostream *os);
int write16le(u16 b, FILE *fp);
int write16le(u16 b, std::ostream* os);
int write32le(u32 b, FILE *fp);
int write32le(u32 b, std::ostream* os);
int write64le(u64 b, std::ostream* os);
int read64le(u64 *Bufo, std::istream *is);
int read32le(u32 *Bufo, std::istream *is);
inline int read32le(int *Bufo, std::istream *is) { return read32le((u32*)Bufo,is); }
int read32le(u32 *Bufo, FILE *fp);
int read16le(u16 *Bufo, std::istream *is);
inline int read16le(s16 *Bufo, std::istream* is) { return read16le((u16*)Bufo,is); }
int read8le(u8 *Bufo, std::istream *is);
#endif

View File

@ -128,7 +128,12 @@ SFORMAT SF_MEM[]={
{ ARM9Mem.ARM9_ITCM, 0x8000, "ITCM" },
{ ARM9Mem.ARM9_DTCM, 0x4000, "DTCM" },
{ ARM9Mem.MAIN_MEM, 0x400000, "WRAM" },
{ ARM9Mem.ARM9_REG, 0x10000, "9REG" },
//NOTE - this is not as large as the allocated memory.
//the memory is overlarge due to the way our memory map system is setup
//but there are actually no more registers than this
{ ARM9Mem.ARM9_REG, 0x2000, "9REG" },
{ ARM9Mem.ARM9_VMEM, 0x800, "VMEM" },
{ ARM9Mem.ARM9_OAM, 0x800, "OAMS" },
{ ARM9Mem.ARM9_ABG, 0x80000, "ABGM" },
@ -504,6 +509,7 @@ static void writechunks(std::ostream* os) {
savestate_WriteChunk(os,3,SF_MEM);
savestate_WriteChunk(os,4,SF_NDS);
savestate_WriteChunk(os,5,gpu_savestate);
savestate_WriteChunk(os,7,spu_savestate);
savestate_WriteChunk(os,60,SF_GFX3D);
savestate_WriteChunk(os,61,gfx3d_savestate);
savestate_WriteChunk(os,0xFFFFFFFF,(SFORMAT*)0);
@ -526,6 +532,7 @@ static bool ReadStateChunks(std::istream* is, s32 totalsize)
case 3: if(!ReadStateChunk(is,SF_MEM,size)) ret=false; break;
case 4: if(!ReadStateChunk(is,SF_NDS,size)) ret=false; break;
case 5: if(!gpu_loadstate(is)) ret=false; break;
case 7: if(!spu_loadstate(is)) ret=false; break;
case 60: if(!ReadStateChunk(is,SF_GFX3D,size)) ret=false; break;
case 61: if(!gfx3d_loadstate(is)) ret=false; break;
default:
@ -591,6 +598,18 @@ bool savestate_load(std::istream* is)
is->read((char*)&buf[0],len);
}
//GO!! READ THE SAVESTATE
//THERE IS NO GOING BACK NOW
//reset the emulator first to clean out the host's state
//NDS_Reset();
//************* OH NO **********************
//we arent saving something we need to!
//maybe MMU state or maybe FIFO
//I will have to look into this soon
//hack
SPU_Reset();
memorystream mstemp(&buf);
bool x = ReadStateChunks(&mstemp,(s32)len);

View File

@ -228,5 +228,23 @@ inline void FlipByteOrder(u8 *src, u32 count)
#define printlog(X) ((void)(X))
#endif
inline u64 double_to_u64(double d) {
union {
u64 a;
double b;
} fuxor;
fuxor.b = d;
return fuxor.a;
}
inline double u64_to_double(u64 u) {
union {
u64 a;
double b;
} fuxor;
fuxor.a = u;
return fuxor.b;
}
#endif

View File

@ -1023,10 +1023,6 @@
RelativePath="..\NDSSystem.h"
>
</File>
<File
RelativePath=".\NintendoDS(tm)_logo.bmp"
>
</File>
<File
RelativePath="..\OGLRender.cpp"
>

View File

@ -104,6 +104,7 @@ WINCLASS *MainWindow=NULL;
//HWND hwnd;
//HDC hdc;
HACCEL hAccel;
HINSTANCE hAppInst;
RECT MainWindowRect;
@ -667,12 +668,16 @@ void Display()
void CheckMessages()
{
MSG msg;
HWND hwnd = MainWindow->getHWnd();
while( PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE ) )
{
if( GetMessage( &msg, 0, 0, 0)>0 )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if(!TranslateAccelerator(hwnd,hAccel,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
}
@ -749,9 +754,6 @@ DWORD WINAPI run( LPVOID lpParameter)
DRV_AviSoundUpdate(SPU_core->outbuf,spu_core_samples);
DRV_AviVideoUpdate((u16*)GPU_screen);
//check win32 messages
CheckMessages();
Input_Process();
Input_Post();
@ -837,9 +839,13 @@ DWORD WINAPI run( LPVOID lpParameter)
}
frameCounter++;
if (frameCounterDisplay) osd->addFixed(200, 30, "%d",frameCounter);
CheckMessages();
}
paused = TRUE;
Sleep(500);
paused = TRUE;
CheckMessages();
Sleep(100);
}
if (lpDDClipPrimary!=NULL) IDirectDraw7_Release(lpDDClipPrimary);
if (lpPrimarySurface != NULL) IDirectDraw7_Release(lpPrimarySurface);
@ -1014,7 +1020,6 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
MSG messages; /* Here messages to the application are saved */
char text[80];
HACCEL hAccel;
hAppInst=hThisInstance;
init_configured_features( &my_config);
@ -1170,7 +1175,10 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
sndcoretype = GetPrivateProfileInt("Sound","SoundCore", SNDCORE_DIRECTX, IniName);
sndbuffersize = GetPrivateProfileInt("Sound","SoundBufferSize", 735 * 4, IniName);
if (SPU_ChangeSoundCore(sndcoretype, sndbuffersize) != 0)
EnterCriticalSection(&win_sync);
int spu_ret = SPU_ChangeSoundCore(sndcoretype, sndbuffersize);
LeaveCriticalSection(&win_sync);
if(spu_ret != 0)
{
MessageBox(MainWindow->getHWnd(),"Unable to initialize DirectSound","Error",MB_OK);
return -1;
@ -2307,7 +2315,9 @@ LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
sscanf(tempstr, "%d", &sndbuffersize);
WritePrivateProfileString("Sound", "SoundBufferSize", tempstr, IniName);
EnterCriticalSection(&win_sync);
SPU_ChangeSoundCore(sndcoretype, sndbuffersize);
LeaveCriticalSection(&win_sync);
// Write Volume
sndvolume = SendDlgItemMessage(hDlg, IDC_SLVOLUME, TBM_GETPOS, 0, 0);