Cleaning up XK's mess, added a simple profiler, minor disasm fix. Too lazy to split it up into individual changes. Savestates not yet working.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@381 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-08-30 12:11:25 +00:00
parent 838f37112e
commit ff0a613427
68 changed files with 421 additions and 1018 deletions

View File

@ -863,7 +863,7 @@ namespace PPCDisasm
static void fdabc(struct DisasmPara_PPC *dp,ppc_word in, const char *name,
int mask,unsigned char dmode)
/* standard floating point instruction: xxxx fD,fA,fB,fC */
/* standard floating point instruction: xxxx fD,fA,fC,fB */
{
static const char *fmt = "f%d,";
char *s = dp->operands;
@ -877,13 +877,13 @@ namespace PPCDisasm
else
err |= (int)PPCGETA(in);
if (mask & 2)
s += sprintf(s,fmt,(int)PPCGETB(in));
else if (PPCGETB(in))
err |= (int)PPCGETB(in);
if (mask & 1)
s += sprintf(s,fmt,(int)PPCGETC(in));
else if (!(mask&8))
else if (PPCGETC(in))
err |= (int)PPCGETC(in);
if (mask & 1)
s += sprintf(s,fmt,(int)PPCGETB(in));
else if (!(mask&8))
err |= (int)PPCGETB(in);
*(s-1) = '\0';
if (err)
ill(dp,in);

View File

@ -20,208 +20,3 @@
#include <stdio.h>
// Not using file mapping, just bog standard fopen and friends. We trust them to be fast
// enough to not be the bottleneck.
ChunkFile::ChunkFile(const char *filename, ChunkFileMode _mode)
{
mode = _mode;
data = 0;
didFail = false;
f = fopen(filename, mode == MODE_WRITE ? "wb" : "rb");
if (!f) {
didFail = true;
return;
}
fseek(f, 0, SEEK_END);
fsize = ftell(f);
eof = fsize;
fseek(f, 0, SEEK_SET);
stack_ptr = 0;
}
ChunkFile::~ChunkFile()
{
if (f)
fclose(f);
}
int ChunkFile::ReadInt()
{
int x;
fread(&x, 4, 1, f);
return x;
}
void ChunkFile::WriteInt(int x)
{
fwrite(&x, 4, 1, f);
}
bool ChunkFile::Do(void *ptr, int size)
{
int sz;
switch (mode) {
case MODE_READ:
sz = ReadInt();
if (sz != size)
return false;
fread(ptr, size, 1, f);
//fseek(f, ((size + 3) & ~3) - size, SEEK_CUR);
break;
case MODE_WRITE:
WriteInt(size);
fwrite(ptr, size, 1, f);
//fseek(f, ((size + 3) & ~3) - size, SEEK_CUR);
break;
case MODE_VERIFY:
sz = ReadInt();
if (sz != size)
return false;
//fseek(f, (size + 3) & ~3, SEEK_CUR);
fseek(f, size, SEEK_CUR);
break;
}
return true;
}
// Do variable size array (probably heap-allocated)
bool ChunkFile::DoArray(void *ptr, int size, int arrSize) {
int sz;
if(ptr == NULL)
return false;
switch (mode) {
case MODE_READ:
sz = ReadInt();
if (sz != size)
return false;
sz = ReadInt();
if (sz != arrSize)
return false;
fread(ptr, size, arrSize, f);
//fseek(f, (((arrSize * size) + 3) & ~3) - (arrSize * size),
// SEEK_CUR);
break;
case MODE_WRITE:
WriteInt(size);
WriteInt(arrSize);
fwrite(ptr, size, arrSize, f);
//fseek(f, (((arrSize * size) + 3) & ~3) - (arrSize * size),
// SEEK_CUR);
break;
case MODE_VERIFY:
sz = ReadInt();
if (sz != size)
return false;
sz = ReadInt();
if (sz != arrSize)
return false;
//for(int i = 0; i < arrSize; i++)
//fseek(f, (size + 3) & ~3, SEEK_CUR);
fseek(f, arrSize * size, SEEK_CUR);
break;
}
return true;
}
//let's get into the business
bool ChunkFile::Descend(const char *cid)
{
return true;
unsigned int id = *reinterpret_cast<const unsigned int*>(cid);
if (mode == MODE_READ)
{
bool found = false;
int startPos = ftell(f);
ChunkInfo temp = stack[stack_ptr];
//save information to restore after the next Ascend
stack[stack_ptr].parentStartLocation = startPos;
stack[stack_ptr].parentEOF = eof;
unsigned int firstID = 0;
//let's search through children..
while (ftell(f) < eof)
{
stack[stack_ptr].ID = ReadInt();
if (firstID == 0)
firstID = stack[stack_ptr].ID|1;
stack[stack_ptr].length = ReadInt();
stack[stack_ptr].startLocation = ftell(f);
if (stack[stack_ptr].ID == id)
{
found = true;
break;
}
else
{
fseek(f, stack[stack_ptr].length, SEEK_CUR); //try next block
}
}
//if we found nothing, return false so the caller can skip this
if (!found)
{
stack[stack_ptr] = temp;
fseek(f, stack[stack_ptr].parentStartLocation, SEEK_SET);
return false;
}
//descend into it
//pos was set inside the loop above
eof = stack[stack_ptr].startLocation + stack[stack_ptr].length;
stack_ptr++;
return true;
}
else
{
//write a chunk id, and prepare for filling in length later
WriteInt(id);
WriteInt(0); //will be filled in by Ascend
stack[stack_ptr].startLocation = ftell(f);
stack_ptr++;
return true;
}
}
//let's ascend out
void ChunkFile::Ascend()
{
return;
if (mode == MODE_READ)
{
//ascend, and restore information
stack_ptr--;
fseek(f, stack[stack_ptr].parentStartLocation, SEEK_SET);
eof = stack[stack_ptr].parentEOF;
}
else
{
stack_ptr--;
//now fill in the written length automatically
int posNow = ftell(f);
fseek(f, stack[stack_ptr].startLocation - 4, SEEK_SET);
WriteInt(posNow - stack[stack_ptr].startLocation);
fseek(f, posNow, SEEK_SET);
}
}
int ChunkFile::GetCurrentChunkSize()
{
if (stack_ptr)
return stack[stack_ptr - 1].length;
else
return 0;
}

View File

@ -15,103 +15,67 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _CHUNKFILE_H
#define _CHUNKFILE_H
#ifndef _POINTERWRAP_H
#define _POINTERWRAP_H
// Class to read/write/verify hierarchical binary file formats.
// Grabbed from one of my older projects and modified heavily.
// Works more like a RIFF file than a Google Protocol Buffer, for example.
#include <stdio.h>
#include <map>
#include <vector>
//TO REMEMBER WHEN USING:
#include "Common.h"
//EITHER a chunk contains ONLY data
//OR it contains ONLY other chunks
//otherwise the scheme breaks...
class ChunkFile
class PointerWrap
{
public:
enum ChunkFileMode
enum Mode // also defined in pluginspecs.h. Didn't want to couple them.
{
MODE_READ,
MODE_WRITE,
MODE_VERIFY,
};
private:
struct ChunkInfo
{
int startLocation;
int parentStartLocation;
int parentEOF;
unsigned int ID;
int length;
MODE_READ = 1,
MODE_WRITE = 2,
MODE_MEASURE = 3,
};
ChunkInfo stack[8];
int stack_ptr;
char *data;
int fsize;
int eof;
ChunkFileMode mode;
FILE *f;
bool didFail;
// Used for internal bookkeeping only.
int ReadInt();
void WriteInt(int x);
u8 **ptr;
Mode mode;
public:
PointerWrap(u8 **ptr_, Mode mode_) : ptr(ptr_), mode(mode_) {}
PointerWrap(unsigned char **ptr_, int mode_) : ptr((u8**)ptr_), mode((Mode)mode_) {}
ChunkFile(const char *filename, ChunkFileMode mode);
~ChunkFile();
void SetMode(Mode mode_) {mode = mode_;}
Mode GetMode() const {return mode;}
u8 **GetPPtr() {return ptr;}
// Only pass 4-character IDs.
bool Descend(const char *id);
void Ascend();
//void Do(int &i);
//bool Do(std::string &s);
bool Do(void *ptr, int size);
bool DoArray(void *ptr, int size, int arrSize);
// Future
// bool DoCompressed(void *ptr, int size)
void DoVoid(void *data, int size)
{
switch (mode)
{
case MODE_READ: memcpy(data, *ptr, size); break;
case MODE_WRITE: memcpy(*ptr, data, size); break;
case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything
default: break; // throw an error?
}
(*ptr) += size;
}
// Store maps to file. Very useful.
template<class T>
bool Do(std::map<unsigned int, T> &x) {
return false;
void Do(std::map<unsigned int, T> &x) {
}
// Store vectors.
// Store vectors.
template<class T>
bool Do(std::vector<T> &x) {
return false;
void Do(std::vector<T> &x) {
}
// Disable size checks to save size for variable size array storing
template<class T>
bool DoArray(T *x, int arrSize) {
return DoArray((void *)x, sizeof(T), arrSize);
}
template<class T>
void DoArray(T *x, int count) {
DoVoid((void *)x, sizeof(T) * count);
}
// Handle everything else
template<class T>
bool Do(T &x) {
return Do((void *)&x, sizeof(x));
void Do(T &x) {
DoVoid((void *)&x, sizeof(x));
}
int GetCurrentChunkSize();
bool failed() {return didFail;}
};
#endif
#endif // _POINTERWRAP_H

View File

@ -118,7 +118,7 @@ void* DynamicLibrary::Get(const char* funcname) const
retval = GetProcAddress(library, funcname);
//if (!retval)
//{
//PanicAlert("Did not find function %s in library %s.", funcname, library_file.c_str());
// PanicAlert("Did not find function %s in library %s.", funcname, library_file.c_str());
//}
#else
retval = dlsym(library, funcname);

View File

@ -775,10 +775,6 @@
RelativePath="..\..\PluginSpecs\PluginSpecs.h"
>
</File>
<File
RelativePath="..\..\PluginSpecs\pluginspecs_compiler.h"
>
</File>
<File
RelativePath="..\..\PluginSpecs\pluginspecs_dsp.h"
>
@ -824,6 +820,14 @@
RelativePath=".\Src\PowerPC\PPCTables.h"
>
</File>
<File
RelativePath=".\Src\PowerPC\Profiler.cpp"
>
</File>
<File
RelativePath=".\Src\PowerPC\Profiler.h"
>
</File>
<File
RelativePath=".\Src\PowerPC\SignatureDB.cpp"
>

View File

@ -71,16 +71,14 @@ void UnregisterAllEvents()
event_types.clear();
}
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
externalEventSection.Enter();
f.Descend("TIME");
f.Do(downcount);
f.Do(slicelength);
f.Do(maxSliceLength);
f.Do(globalTimer);
f.Do(idledCycles);
f.Ascend();
p.Do(downcount);
p.Do(slicelength);
p.Do(maxSliceLength);
p.Do(globalTimer);
p.Do(idledCycles);
externalEventSection.Leave();
}

View File

@ -35,7 +35,7 @@ typedef void (*TimedCallback)(u64 userdata, int cyclesLate);
u64 GetTicks();
u64 GetIdleTicks();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
// The int that the callbacks get is how many cycles late it was.
// So to schedule a new event on a regular basis:
// inside callback:

View File

@ -94,15 +94,13 @@ static int g_SampleRate = 32000;
static int g_DSPSampleRate = 32000;
static u64 g_CPUCyclesPerSample = 0xFFFFFFFFFFFULL;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("AI ");
f.Do(g_AudioRegister);
f.Do(g_LastCPUTime);
f.Do(g_SampleRate);
f.Do(g_DSPSampleRate);
f.Do(g_CPUCyclesPerSample);
f.Ascend();
p.Do(g_AudioRegister);
p.Do(g_LastCPUTime);
p.Do(g_SampleRate);
p.Do(g_DSPSampleRate);
p.Do(g_CPUCyclesPerSample);
}
void GenerateAudioInterrupt();

View File

@ -20,14 +20,14 @@
#ifndef _AUDIOINTERFACE_H
#define _AUDIOINTERFACE_H
class ChunkFile;
class PointerWrap;
namespace AudioInterface
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void Update();

View File

@ -105,19 +105,17 @@ u16 m_tokenReg;
CPFifo fifo; //This one is shared between gfx thread and emulator thread
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("CP ");
f.Do(m_CPStatusReg);
f.Do(m_CPCtrlReg);
f.Do(m_CPClearReg);
f.Do(m_bboxleft);
f.Do(m_bboxtop);
f.Do(m_bboxright);
f.Do(m_bboxbottom);
f.Do(m_tokenReg);
f.Do(fifo);
f.Ascend();
p.Do(m_CPStatusReg);
p.Do(m_CPCtrlReg);
p.Do(m_CPClearReg);
p.Do(m_bboxleft);
p.Do(m_bboxtop);
p.Do(m_bboxright);
p.Do(m_bboxbottom);
p.Do(m_tokenReg);
p.Do(fifo);
}
// function

View File

@ -19,7 +19,7 @@
#define _COMMANDPROCESSOR_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
#ifdef _WIN32
#include <windows.h>
@ -82,7 +82,7 @@ extern CPFifo fifo;
// Init
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
// Read
void HWCALL Read16(u16& _rReturnValue, const u32 _Address);

View File

@ -175,16 +175,14 @@ u16 g_AR_MODE = 0x43; // 0x23 -> Zelda standard mode (standard ARAM access ??)
// 0x43 -> written by OSAudioInit at the UCode upload (upload UCode)
// 0x63 -> ARCheckSize Mode (access AR-registers ??) or no exception ??
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("DSP ");
f.Do(g_ARAM, ARAM_SIZE);
f.Do(g_dspState);
f.Do(g_audioDMA);
f.Do(g_arDMA);
f.Do(g_AR_READY_FLAG);
f.Do(g_AR_MODE);
f.Ascend();
p.DoArray(g_ARAM, ARAM_SIZE);
p.Do(g_dspState);
p.Do(g_audioDMA);
p.Do(g_arDMA);
p.Do(g_AR_READY_FLAG);
p.Do(g_AR_MODE);
}

View File

@ -19,7 +19,7 @@
#define _DSPINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace DSP
{
@ -33,7 +33,7 @@ enum DSPInterruptType
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void GenerateDSPInterrupt(DSPInterruptType _DSPInterruptType, bool _bSet = true);
void GenerateDSPInterruptFromPlugin(DSPInterruptType _DSPInterruptType, bool _bSet = true);

View File

@ -178,13 +178,11 @@ DVDMemStruct dvdMem;
u32 g_ErrorCode = 0x00;
bool g_bDiscInside = true;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("DI ");
f.Do(dvdMem);
f.Do(g_ErrorCode);
f.Do(g_bDiscInside);
f.Ascend();
p.Do(dvdMem);
p.Do(g_ErrorCode);
p.Do(g_bDiscInside);
}
void UpdateInterrupts();

View File

@ -19,14 +19,14 @@
#define _DVDINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace DVDInterface
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void SetDiscInside(bool _DiscInside);

View File

@ -53,11 +53,9 @@ void Shutdown()
g_Channels = 0;
}
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("EXI ");
// TODO: descend all the devices recursively.
f.Ascend();
}
void Update()

View File

@ -18,14 +18,14 @@
#define _EXIINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace ExpansionInterface
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void Update();
void UpdateInterrupts();

View File

@ -44,12 +44,10 @@ u8 GC_ALIGNED32(m_gatherPipe[GATHER_PIPE_SIZE*16]); //more room, for the fastmod
// pipe counter
u32 m_gatherPipeCount = 0;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("FIFO");
f.Do(m_gatherPipe);
f.Do(m_gatherPipeCount);
f.Ascend();
p.Do(m_gatherPipe);
p.Do(m_gatherPipeCount);
}
void Init()

View File

@ -19,7 +19,7 @@
#define _GPFIFO_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace GPFifo
{
@ -36,7 +36,7 @@ extern u32 m_gatherPipeCount;
// Init
void Init();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
// ResetGatherPipe
void ResetGatherPipe();

View File

@ -87,21 +87,19 @@ namespace HW
CoreTiming::UnregisterAllEvents();
}
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("HWst");
PixelEngine::DoState(f);
CommandProcessor::DoState(f);
VideoInterface::DoState(f);
SerialInterface::DoState(f);
CPeripheralInterface::DoState(f);
DSP::DoState(f);
DVDInterface::DoState(f);
GPFifo::DoState(f);
ExpansionInterface::DoState(f);
AudioInterface::DoState(f);
CoreTiming::DoState(f);
WII_IPCInterface::DoState(f);
f.Ascend();
PixelEngine::DoState(p);
CommandProcessor::DoState(p);
VideoInterface::DoState(p);
SerialInterface::DoState(p);
CPeripheralInterface::DoState(p);
DSP::DoState(p);
DVDInterface::DoState(p);
GPFifo::DoState(p);
ExpansionInterface::DoState(p);
AudioInterface::DoState(p);
CoreTiming::DoState(p);
WII_IPCInterface::DoState(p);
}
}

View File

@ -25,7 +25,7 @@ namespace HW
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
}
#endif

View File

@ -21,7 +21,7 @@
#include "Common.h"
class ChunkFile;
class PointerWrap;
typedef void (HWCALL *writeFn8 )(const u8, const u32);
typedef void (HWCALL *writeFn16)(const u16,const u32);
@ -65,7 +65,7 @@ namespace Memory
bool IsInitialized();
bool Init();
bool Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void Clear();
bool AreMemoryBreakpointsActivated();

View File

@ -50,11 +50,9 @@ struct MIMemStruct
// STATE_TO_SAVE
static MIMemStruct miMem;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("MI ");
f.Do(miMem);
f.Ascend();
p.Do(miMem);
}
void Read16(u16& _uReturnValue, const u32 _iAddress)

View File

@ -18,11 +18,11 @@
#define _MEMORYINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace MemoryInterface
{
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void HWCALL Read16(u16& _uReturnValue, const u32 _iAddress);
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);

View File

@ -33,15 +33,13 @@ u32 CPeripheralInterface::Fifo_CPUBase;
u32 CPeripheralInterface::Fifo_CPUEnd;
u32 CPeripheralInterface::Fifo_CPUWritePointer;
void CPeripheralInterface::DoState(ChunkFile &f)
void CPeripheralInterface::DoState(PointerWrap &p)
{
f.Descend("PI ");
f.Do(m_InterruptMask);
f.Do(m_InterruptCause);
f.Do(Fifo_CPUBase);
f.Do(Fifo_CPUEnd);
f.Do(Fifo_CPUWritePointer);
f.Ascend();
p.Do(m_InterruptMask);
p.Do(m_InterruptCause);
p.Do(Fifo_CPUBase);
p.Do(Fifo_CPUEnd);
p.Do(Fifo_CPUWritePointer);
}
void CPeripheralInterface::Init()

View File

@ -19,7 +19,7 @@
#define _PERIPHERALINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
//
// PERIPHERALINTERFACE
@ -98,7 +98,7 @@ public:
static u32 Fifo_CPUWritePointer;
static void Init();
static void DoState(ChunkFile &f);
static void DoState(PointerWrap &p);
static void SetInterrupt(InterruptCause _causemask, bool _bSet=true);

View File

@ -63,14 +63,12 @@ static bool g_bSignalFinishInterrupt;
int et_SetTokenOnMainThread;
int et_SetFinishOnMainThread;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("PE ");
f.Do(g_ctrlReg);
f.Do(g_token);
f.Do(g_bSignalTokenInterrupt);
f.Do(g_bSignalFinishInterrupt);
f.Ascend();
p.Do(g_ctrlReg);
p.Do(g_token);
p.Do(g_bSignalTokenInterrupt);
p.Do(g_bSignalFinishInterrupt);
}
void UpdateInterrupts();

View File

@ -18,12 +18,12 @@
#define _PIXELENGINE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace PixelEngine
{
void Init();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
// Read
void HWCALL Read16(u16& _uReturnValue, const u32 _iAddress);

View File

@ -218,16 +218,14 @@ static USIStatusReg g_StatusReg;
static USIEXIClockCount g_EXIClockCount;
static u8 g_SIBuffer[128];
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("SI ");
f.Do(g_Channel);
f.Do(g_Poll);
f.Do(g_ComCSR);
f.Do(g_StatusReg);
f.Do(g_EXIClockCount);
f.Do(g_SIBuffer);
f.Ascend();
p.Do(g_Channel);
p.Do(g_Poll);
p.Do(g_ComCSR);
p.Do(g_StatusReg);
p.Do(g_EXIClockCount);
p.Do(g_SIBuffer);
}
static void GenerateSIInterrupt(SIInterruptType _SIInterrupt);

View File

@ -19,14 +19,14 @@
#define _SERIALINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace SerialInterface
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void UpdateDevices();

View File

@ -19,7 +19,7 @@
#define _SERIALINTERFACE_DEVICES_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
class ISIDevice
{

View File

@ -12,7 +12,7 @@
#define _STREAMADPCM_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
#define ONE_BLOCK_SIZE 32
#define SAMPLES_PER_BLOCK 28

View File

@ -104,20 +104,18 @@ static u32 TicksPerFrame = 0;
static u32 LineCount = 0;
static u64 LastTime = 0;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("VI ");
f.Do(m_VIDisplayControlRegister);
f.Do(m_FrameBuffer1);
f.Do(m_FrameBuffer2);
f.Do(m_VIInterruptRegister);
f.Do(m_UVIUnknownRegs, 0x1000);
f.Do(HorizontalBeamPos);
f.Do(VerticalBeamPos);
f.Do(TicksPerFrame);
f.Do(LineCount);
f.Do(LastTime);
f.Ascend();
p.Do(m_VIDisplayControlRegister);
p.Do(m_FrameBuffer1);
p.Do(m_FrameBuffer2);
p.Do(m_VIInterruptRegister);
p.DoArray(m_UVIUnknownRegs, 0x1000);
p.Do(HorizontalBeamPos);
p.Do(VerticalBeamPos);
p.Do(TicksPerFrame);
p.Do(LineCount);
p.Do(LastTime);
}
void Init()

View File

@ -18,7 +18,7 @@
#define _VIDEOINTERFACE_H
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace VideoInterface
{
@ -31,7 +31,7 @@ namespace VideoInterface
};
void Init();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void HWCALL Read16(u16& _uReturnValue, const u32 _uAddress);
void HWCALL Read32(u32& _uReturnValue, const u32 _uAddress);

View File

@ -18,14 +18,14 @@
#define _WII_IOBRIDGE_H_
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace WII_IOBridge
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void Update();

View File

@ -93,16 +93,14 @@ u32 g_Address = 0;
u32 g_Reply = 0;
u32 g_SensorBarPower = 0;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("WIPC");
f.Do(g_IPC_Status);
f.Do(g_IPC_Config);
f.Do(g_IPC_Control);
f.Do(g_Address);
f.Do(g_Reply);
f.Do(g_SensorBarPower);
f.Ascend();
p.Do(g_IPC_Status);
p.Do(g_IPC_Config);
p.Do(g_IPC_Control);
p.Do(g_Address);
p.Do(g_Reply);
p.Do(g_SensorBarPower);
}
void UpdateInterrupts();

View File

@ -18,14 +18,14 @@
#define _WII_IPC_H_
#include "Common.h"
class ChunkFile;
class PointerWrap;
namespace WII_IPCInterface
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void Update();
bool IsReady();

View File

@ -32,10 +32,8 @@ typedef void (__cdecl* TVideo_SendFifoData)(BYTE*);
typedef void (__cdecl* TVideo_UpdateXFB)(BYTE*, DWORD, DWORD);
typedef BOOL (__cdecl* TVideo_Screenshot)(TCHAR*);
typedef void (__cdecl* TVideo_EnterLoop)();
typedef void (__cdecl* TVideo_AddMessage)(const char* pstr, unsigned int milliseconds);
typedef void (__cdecl* TVideo_DoState)(ChunkFile &f);
typedef void (__cdecl* TVideo_DoState)(unsigned char **ptr, int mode);
//! Function Pointer
TGetDllInfo g_GetDllInfo = 0;
@ -49,7 +47,7 @@ TVideo_UpdateXFB g_Video_UpdateXFB = 0;
TVideo_Screenshot g_Video_Screenshot = 0;
TVideo_EnterLoop g_Video_EnterLoop = 0;
TVideo_AddMessage g_Video_AddMessage = 0;
TVideo_DoState g_Video_DoState = 0;
TVideo_DoState g_Video_DoState = 0;
//! Library Instance
DynamicLibrary plugin;
@ -91,7 +89,7 @@ bool LoadPlugin(const char *_Filename)
g_Video_Screenshot = reinterpret_cast<TVideo_Screenshot> (plugin.Get("Video_Screenshot"));
g_Video_EnterLoop = reinterpret_cast<TVideo_EnterLoop> (plugin.Get("Video_EnterLoop"));
g_Video_AddMessage = reinterpret_cast<TVideo_AddMessage> (plugin.Get("Video_AddMessage"));
g_Video_DoState = reinterpret_cast<TVideo_DoState> (plugin.Get("Video_DoState"));
g_Video_DoState = reinterpret_cast<TVideo_DoState> (plugin.Get("Video_DoState"));
if ((g_GetDllInfo != 0) &&
(g_DllAbout != 0) &&
@ -176,8 +174,8 @@ void Video_AddMessage(const char* pstr, unsigned int milliseconds)
g_Video_AddMessage(pstr,milliseconds);
}
void Video_DoState(ChunkFile &f) {
g_Video_DoState(f);
void Video_DoState(unsigned char **ptr, int mode) {
g_Video_DoState(ptr, mode);
}
} // end of namespace PluginVideo

View File

@ -44,7 +44,7 @@ void Video_UpdateXFB(BYTE* _pXFB, DWORD _dwHeight, DWORD _dwWidth);
bool Video_Screenshot(TCHAR* _szFilename);
void Video_AddMessage(const char* pstr, unsigned int milliseconds);
void Video_DoState(ChunkFile &f);
void Video_DoState(unsigned char **ptr, int mode);
} // end of namespace PluginVideo

View File

@ -317,15 +317,8 @@ void orcx(UGeckoInstruction _inst)
void slwx(UGeckoInstruction _inst)
{
// TODO(ector): wtf is this code?
/* u32 amount = m_GPR[_inst.RB];
m_GPR[_inst.RA] = (amount&0x20) ? 0 : m_GPR[_inst.RS] << amount;
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
*/
u32 nBits = m_GPR[_inst.RB];
m_GPR[_inst.RA] = (nBits < 32) ? m_GPR[_inst.RS] << nBits : 0;
u32 amount = m_GPR[_inst.RB];
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : m_GPR[_inst.RS] << amount;
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
}
@ -393,7 +386,7 @@ void srawix(UGeckoInstruction _inst)
void srwx(UGeckoInstruction _inst)
{
u32 amount = m_GPR[_inst.RB];
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : (m_GPR[_inst.RS] >> amount);
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : (m_GPR[_inst.RS] >> (amount & 0x1f));
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
}

View File

@ -25,6 +25,7 @@
#include "../../Core.h"
#include "../../CoreTiming.h"
#include "../PowerPC.h"
#include "../Profiler.h"
#include "../PPCTables.h"
#include "../PPCAnalyst.h"
#include "../../HW/Memmap.h"
@ -375,6 +376,7 @@ namespace Jit64
PPCAnalyst::CodeOp *ops = PPCAnalyst::Flatten(emaddress, size, js.st, js.gpa, js.fpa);
const u8 *start = AlignCode4(); //TODO: Test if this or AlignCode16 make a difference from GetCodePtr
b.checkedEntry = start;
b.runCount = 0;
FixupBranch skip = J_CC(CC_NBE);
MOV(32, M(&PC), Imm32(js.blockStart));
JMP(Asm::doTiming, true);
@ -393,6 +395,10 @@ namespace Jit64
SetJumpTarget(b1);
}
if (Profiler::g_ProfileBlocks) {
ADD(32, M(&b.runCount), Imm8(1));
}
//Start up the register allocators
//They use the information in gpa/fpa to preload commonly used registers.
gpr.Start(js.gpa);

View File

@ -186,14 +186,8 @@ void Generate()
enterCode = AlignCode16();
ABI_PushAllCalleeSavedRegsAndAdjustStack();
// INT3();
MOV(64, R(RBX), Imm64((u64)Memory::base));
// if ((u64)GetCodePointers() > 0x80000000ULL) {
// PanicAlert("Code Pointers are above the limit! %p",
// GetCodePointers());
//}
MOV(64, R(R15), Imm64((u64)GetCodePointers())); //It's below 2GB so 32 bits are good enough
const u8 *outerLoop = GetCodePtr();
@ -224,7 +218,7 @@ void Generate()
ADD(32, M(&PowerPC::ppcState.DebugCount), Imm8(1));
}
//grab from list and jump to it
JMPptr(MComplex(R15,RAX,8,0));
JMPptr(MComplex(R15, RAX, 8, 0));
SetJumpTarget(notfound);
//Ok, no block, let's jit

View File

@ -37,8 +37,9 @@ namespace Jit64
u32 originalAddress;
u32 originalFirstOpcode; //to be able to restore
u32 codeSize;
u32 codeSize;
u32 originalSize;
int runCount; // for profiling.
const u8 *checkedEntry;
bool invalid;
};

View File

@ -90,8 +90,8 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size)
int numInternalBranches = 0;
while (true)
{
func.size++;
if (func.size > 1024*16) //weird
func.size += 4;
if (func.size > 1024*16*4) //weird
return false;
UGeckoInstruction instr = (UGeckoInstruction)Memory::ReadUnchecked_U32(addr);
@ -118,7 +118,6 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size)
//a final blr!
//We're done! Looks like we have a neat valid function. Perfect.
//Let's calc the checksum and get outta here
func.size *= 4; // into bytes
func.address = startAddr;
func.analyzed = 1;
func.hash = SignatureDB::ComputeCodeChecksum(startAddr, addr);

View File

@ -238,7 +238,7 @@ GekkoOPTemplate table4_2[] =
{23, Interpreter::ps_sel, Jit64::ps_sel, {"ps_sel", OPTYPE_PS, 0}},
{24, Interpreter::ps_res, Jit64::Default, {"ps_res", OPTYPE_PS, 0}},
{25, Interpreter::ps_mul, Jit64::ps_arith, {"ps_mul", OPTYPE_PS, 0}},
{26, Interpreter::ps_rsqrte, Jit64::ps_rsqrte, {"ps_rsqrte", OPTYPE_PS, 0}},
{26, Interpreter::ps_rsqrte, Jit64::ps_rsqrte, {"ps_rsqrte", OPTYPE_PS, 0, 1}},
{28, Interpreter::ps_msub, Jit64::ps_maddXX, {"ps_msub", OPTYPE_PS, 0}},
{29, Interpreter::ps_madd, Jit64::ps_maddXX, {"ps_madd", OPTYPE_PS, 0}},
{30, Interpreter::ps_nmsub, Jit64::ps_maddXX, {"ps_nmsub", OPTYPE_PS, 0}},

View File

@ -41,12 +41,10 @@ namespace PowerPC
static CoreMode mode;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("PPC ");
f.Do(ppcState);
f.Do(state);
f.Ascend();
p.Do(ppcState);
p.Do(state);
}
void ResetRegisters()

View File

@ -28,7 +28,7 @@
#include "Common.h"
#include "Gekko.h"
class ChunkFile;
class PointerWrap;
namespace PowerPC
{
@ -80,7 +80,7 @@ namespace PowerPC
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void DoState(PointerWrap &p);
void SetMode(CoreMode _coreType);

View File

@ -0,0 +1,75 @@
// Copyright (C) 2003-2008 Dolphin Project.
// 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, version 2.0.
// 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 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Jit64/Jit.h"
#include <vector>
#include <algorithm>
#include "SymbolDB.h"
namespace Profiler
{
bool g_ProfileBlocks;
bool g_ProfileInstructions;
struct BlockStat
{
BlockStat(int bn, int c) : blockNum(bn), cost(c) {}
int blockNum;
int cost;
bool operator <(const BlockStat &other) const {
return cost > other.cost;
}
};
void WriteProfileResults(const char *filename) {
std::vector<BlockStat> stats;
stats.reserve(Jit64::GetNumBlocks());
u64 cost_sum = 0;
for (int i = 0; i < Jit64::GetNumBlocks(); i++)
{
const Jit64::JitBlock *block = Jit64::GetBlock(i);
int cost = (block->originalSize / 4) * block->runCount; // rough heuristic. mem instructions should cost more.
if (block->runCount >= 1) { // Todo: tweak.
stats.push_back(BlockStat(i, cost));
}
cost_sum += cost;
}
sort(stats.begin(), stats.end());
FILE *f = fopen(filename, "w");
if (!f) {
PanicAlert("failed to open %s", filename);
return;
}
fprintf(f, "Profile\n");
for (int i = 0; i < stats.size(); i++)
{
const Jit64::JitBlock *block = Jit64::GetBlock(stats[i].blockNum);
if (block) {
std::string name = g_symbolDB.GetDescription(block->originalAddress);
double percent = 100 * (double)stats[i].cost / (double)cost_sum;
fprintf(f, "%08x - %s - %i (%f%%)\n", block->originalAddress, name.c_str(), stats[i].cost, percent);
}
}
fclose(f);
}
}

View File

@ -0,0 +1,30 @@
// Copyright (C) 2003-2008 Dolphin Project.
// 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, version 2.0.
// 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 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _PROFILER_H
#define _PROFILER_H
namespace Profiler
{
extern bool g_ProfileBlocks;
extern bool g_ProfileInstructions;
void WriteProfileResults(const char *filename);
}
#endif // _PROFILER_H

View File

@ -57,6 +57,7 @@ files = ["Console.cpp",
"PowerPC/PowerPC.cpp",
"PowerPC/PPCAnalyst.cpp",
"PowerPC/PPCTables.cpp",
"PowerPC/Profiler.cpp",
"PowerPC/SignatureDB.cpp",
"PowerPC/SymbolDB.cpp",
"PowerPC/Interpreter/Interpreter.cpp",

View File

@ -4,35 +4,53 @@
#include "CoreTiming.h"
#include "HW/HW.h"
#include "PowerPC/PowerPC.h"
#include "Plugins/Plugin_Video.h"
#include <string>
#include "Plugins/Plugin_Video.h"
#include <string>
static int ev_Save;
static int ev_Load;
static std::string cur_filename;
void DoState(ChunkFile &f)
void DoState(PointerWrap &p)
{
f.Descend("DOLP");
PowerPC::DoState(f);
HW::DoState(f);
PluginVideo::Video_DoState(f);
f.Ascend();
PowerPC::DoState(p);
HW::DoState(p);
PluginVideo::Video_DoState(p.GetPPtr(), p.GetMode());
}
void SaveStateCallback(u64 userdata, int cyclesLate)
{
ChunkFile f(cur_filename.c_str(), ChunkFile::MODE_WRITE);
DoState(f);
u8 *ptr = 0;
PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
DoState(p);
int sz = (int)(u64)ptr;
u8 *buffer = new u8[sz];
ptr = buffer;
p.SetMode(PointerWrap::MODE_WRITE);
DoState(p);
FILE *f = fopen(cur_filename.c_str(), "wb");
fwrite(buffer, sz, 1, f);
fclose(f);
delete [] buffer;
}
void LoadStateCallback(u64 userdata, int cyclesLate)
{
ChunkFile f(cur_filename.c_str(), ChunkFile::MODE_READ);
DoState(f);
// ChunkFile f(cur_filename.c_str(), ChunkFile::MODE_READ);
FILE *f = fopen(cur_filename.c_str(), "r");
fseek(f, 0, SEEK_END);
int sz = ftell(f);
fseek(f, 0, SEEK_SET);
u8 *buffer = new u8[sz];
fread(buffer, sz, 1, f);
fclose(f);
u8 *ptr;
PointerWrap p(&ptr, PointerWrap::MODE_READ);
DoState(p);
}
void State_Init()
@ -56,4 +74,4 @@ void State_Load(const char *filename)
{
cur_filename = filename;
CoreTiming::ScheduleEvent_Threadsafe(0, ev_Load);
}
}

View File

@ -48,6 +48,7 @@
#include "Debugger/PPCDebugInterface.h"
#include "Debugger/Debugger_SymbolMap.h"
#include "PowerPC/PPCAnalyst.h"
#include "PowerPC/Profiler.h"
#include "PowerPC/SymbolDB.h"
#include "PowerPC/SignatureDB.h"
#include "PowerPC/PPCTables.h"
@ -86,6 +87,10 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxFrame)
EVT_MENU(IDM_CLEARCODECACHE, CCodeWindow::OnJitMenu)
EVT_MENU(IDM_LOGINSTRUCTIONS, CCodeWindow::OnJitMenu)
EVT_MENU(IDM_PROFILEBLOCKS, CCodeWindow::OnProfilerMenu)
EVT_MENU(IDM_WRITEPROFILE, CCodeWindow::OnProfilerMenu)
// toolbar
EVT_MENU(IDM_DEBUG_GO, CCodeWindow::OnCodeStep)
EVT_MENU(IDM_STEP, CCodeWindow::OnCodeStep)
@ -275,6 +280,15 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam
pMenuBar->Append(pJitMenu, _T("&JIT"));
}
{
wxMenu *pProfilerMenu = new wxMenu;
pProfilerMenu->Append(IDM_PROFILEBLOCKS, _T("&Profile blocks"), wxEmptyString, wxITEM_CHECK);
pProfilerMenu->AppendSeparator();
pProfilerMenu->Append(IDM_WRITEPROFILE, _T("&Write to profile.txt, show"));
pMenuBar->Append(pProfilerMenu, _T("&Profiler"));
}
SetMenuBar(pMenuBar);
}
@ -295,6 +309,7 @@ void CCodeWindow::OnInterpreter(wxCommandEvent& event)
if (Core::GetState() != Core::CORE_RUN) {
PowerPC::SetMode(UseInterpreter() ? PowerPC::MODE_INTERPRETER : PowerPC::MODE_JIT);
} else {
event.Skip();
wxMessageBox(_T("Please pause the emulator before changing mode."));
}
}
@ -312,6 +327,24 @@ void CCodeWindow::OnJitMenu(wxCommandEvent& event)
}
}
void CCodeWindow::OnProfilerMenu(wxCommandEvent& event)
{
if (Core::GetState() == Core::CORE_RUN) {
event.Skip();
return;
}
switch (event.GetId())
{
case IDM_PROFILEBLOCKS:
Jit64::ClearCache();
Profiler::g_ProfileBlocks = GetMenuBar()->IsChecked(IDM_PROFILEBLOCKS);
break;
case IDM_WRITEPROFILE:
Profiler::WriteProfileResults("profiler.txt");
break;
}
}
void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
{
if (Core::GetState() == Core::CORE_UNINITIALIZED)

View File

@ -93,6 +93,8 @@ class CCodeWindow
IDM_USESIGNATUREFILE,
IDM_USESYMBOLFILE,
IDM_CLEARCODECACHE,
IDM_PROFILEBLOCKS,
IDM_WRITEPROFILE,
};
enum
@ -144,8 +146,10 @@ class CCodeWindow
void OnHostMessage(wxCommandEvent& event);
void OnSymbolsMenu(wxCommandEvent& event);
void OnJitMenu(wxCommandEvent& event);
void OnProfilerMenu(wxCommandEvent& event);
void OnInterpreter(wxCommandEvent& event);
void CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParameter);
void UpdateButtonStates();

View File

@ -32,11 +32,11 @@ static u8 *videoBuffer;
static int size = 0;
static int readptr = 0;
void Fifo_DoState(ChunkFile &f) {
f.Do(size);
f.DoArray(videoBuffer, size);
void Fifo_DoState(PointerWrap &p) {
p.Do(size);
p.DoArray(videoBuffer, size);
f.Do(readptr);
p.Do(readptr);
}
void Fifo_Init()

View File

@ -57,7 +57,7 @@ extern FifoReader fifo;
void Fifo_Init();
void Fifo_Shutdown();
void Fifo_EnterLoop(const SVideoInitialize &video_initialize);
void Fifo_DoState(ChunkFile &f);
void Fifo_DoState(PointerWrap &f);
#endif

View File

@ -23,35 +23,33 @@
#include "TextureDecoder.h"
#include "Fifo.h"
static void DoState(ChunkFile &f) {
static void DoState(PointerWrap &p) {
// BP Memory
f.Do(bpmem);
p.Do(bpmem);
// CP Memory
f.Do(arraybases);
f.Do(arraystrides);
f.Do(MatrixIndexA);
f.Do(MatrixIndexB);
p.Do(arraybases);
p.Do(arraystrides);
p.Do(MatrixIndexA);
p.Do(MatrixIndexB);
// XF Memory
f.Do(xfregs);
p.Do(xfregs);
PanicAlert("video: XFMem");
f.Do(xfmem);
p.Do(xfmem);
PanicAlert("video: Texture decoder");
// Texture decoder
f.Do(texMem);
p.Do(texMem);
// FIFO
PanicAlert("video: FIFO");
Fifo_DoState(f);
Fifo_DoState(p);
//TODO: Check for more pointers in the data structures and make them
// serializable
}
void VideoCommon_DoState(ChunkFile &f) {
void VideoCommon_DoState(PointerWrap &p) {
PanicAlert("Saving state from Video Common Library");
//TODO: Save the video state
f.Descend("VID ");
DoState(f);
f.Ascend();
DoState(p);
PanicAlert("END save video");
}

View File

@ -21,6 +21,6 @@
#include "Common.h"
#include "ChunkFile.h"
void VideoCommon_DoState(ChunkFile &f);
void VideoCommon_DoState(PointerWrap &p);
#endif

View File

@ -58,6 +58,11 @@ extern "C" {
#define PLUGIN_TYPE_COMPILER 5
#define PLUGIN_TYPE_DSP 6
#define STATE_MODE_READ 1
#define STATE_MODE_WRITE 2
#define STATE_MODE_MEASURE 3
typedef struct
{
WORD Version; // Set to 0x0100

View File

@ -1,98 +0,0 @@
//__________________________________________________________________________________________________
// Common compiler plugin spec, version #1.0 maintained by F|RES
//
#ifndef _COMPILER_H_INCLUDED__
#define _COMPILER_H_INCLUDED__
#include "PluginSpecs.h"
#include "ExportProlog.h"
typedef void (*TWriteBigEData)(const unsigned __int8* _pData, const unsigned __int32 _iAddress, const unsigned __int32 _iSize);
typedef void (*TPatchFunction)(DWORD _uAddress, unsigned char* _pMachineCode);
typedef void (*TLog)(char* _pMessage);
typedef struct
{
HWND hWnd;
TPatchFunction pPatchFunction;
TLog pLog;
} SCompilerInitialize;
// __________________________________________________________________________________________________
// Function: GetDllInfo
// Purpose: This function allows the emulator to gather information
// about the DLL by filling in the PluginInfo structure.
// input: a pointer to a PLUGIN_INFO structure that needs to be
// filled by the function. (see def above)
// output: none
//
EXPORT void CALL GetDllInfo(PLUGIN_INFO* _PluginInfo);
// __________________________________________________________________________________________________
// Function: CloseDLL
// Purpose: This function is called when the emulator is closing
// down allowing the DLL to de-initialise.
// input: none
// output: none
//
EXPORT void CALL CloseDLL(void);
// __________________________________________________________________________________________________
// Function: DllAbout
// Purpose: This function is optional function that is provided
// to give further information about the DLL.
// input: a handle to the window that calls this function
// output: none
//
EXPORT void CALL DllAbout(HWND _hParent);
// __________________________________________________________________________________________________
// Function: DllConfig
// Purpose: This function is optional function that is provided
// to allow the user to configure the dll
// input: a handle to the window that calls this function
// output: none
//
EXPORT void CALL DllConfig(HWND _hParent);
// __________________________________________________________________________________________________
// Function:
// Purpose:
// input: SCompilerInitialize
// output: none
//
EXPORT void CALL CompilerInitialize(SCompilerInitialize _CompilerInitialize);
// __________________________________________________________________________________________________
// Function: SetupHeader
// Purpose:
// input:
// output:
//
EXPORT void CALL SetupHeader(char* _szSourceCode);
// __________________________________________________________________________________________________
// Function: CompileSourceCode
// Purpose: This function will compile a NULL-terminated string of C
// source code..
// input: pDest: Pointer to address for the new machine code
// strSourceCode: The NULL-terminated C Source Code string
// output: Size of the Compiled Source, 0 == ERROR
//
EXPORT DWORD CALL CompileSourceCode(char* _szSourceCode, BYTE* _pMachineCode, DWORD _dwMaxSize);
// __________________________________________________________________________________________________
// Function: InsertEventString
// Purpose: This optional function will insert the code in
// EventString[] immediately before every block of compiled code
// returns. Used to check for Interrupts and cyclic tasks.
// input: The Event's C code
// output: TRUE/FALSE for pass or fail
//
EXPORT DWORD CALL InsertEventString(char* _szEventSourceCode);
#include "ExportEpilog.h"
#endif

View File

@ -154,5 +154,13 @@ EXPORT void CALL DSP_Update(int cycles);
//
EXPORT void CALL DSP_SendAIBuffer(unsigned int address, int sample_rate);
// __________________________________________________________________________________________________
// Function: DSP_DoState
// Purpose: Saves/load state
// input/output: ptr
// input: mode
//
EXPORT void CALL PAD_DoState(void *ptr, int mode);
#include "ExportEpilog.h"
#endif

View File

@ -124,14 +124,12 @@ EXPORT void CALL PAD_Rumble(BYTE _numPAD, unsigned int _uType, unsigned int _uSt
EXPORT unsigned int CALL PAD_GetAttachedPads();
// __________________________________________________________________________________________________
// Function: SaveLoadState
// Function: PAD_DoState
// Purpose: Saves/load state
// input: pointer to a 32k scratchpad/saved state
// output: writes or reads to the scratchpad, returning size of data
// TODO: save format should be standardized so that save
// states don't become plugin dependent which would suck
// input/output: ptr
// input: mode
//
EXPORT unsigned int CALL SaveLoadState(char *ptr, BOOL save);
EXPORT void CALL PAD_DoState(void *ptr, int mode);
#include "ExportEpilog.h"
#endif

View File

@ -7,8 +7,6 @@
#include "PluginSpecs.h"
#include "ChunkFile.h"
#include "ExportProlog.h"
typedef void (*TSetPEToken)(const unsigned short _token, const int _bSetTokenAcknowledge);
@ -152,7 +150,6 @@ EXPORT void CALL Video_UpdateXFB(BYTE* _pXFB, DWORD _dwWidth, DWORD _dwHeight);
//
EXPORT BOOL CALL Video_Screenshot(TCHAR* _szFilename);
// __________________________________________________________________________________________________
// Function: Video_EnterLoop
// Purpose: FIXME!
@ -171,11 +168,11 @@ EXPORT void CALL Video_AddMessage(const char* pstr, unsigned int milliseconds);
// __________________________________________________________________________________________________
// Function: Video_DoState
// Purpose: Saves/Loads the current video data state(depends on parameter)
// input: The chunkfile to write to? FIXME
// output: none
// Purpose: Saves/Loads the current video data state (depends on mode parameter)
// input/output: ptr
// input: mode
//
EXPORT void CALL Video_DoState(ChunkFile &f);
EXPORT void CALL Video_DoState(unsigned char **ptr, int mode);
#include "ExportEpilog.h"
#endif

View File

@ -672,74 +672,6 @@
<Filter
Name="win32"
>
<File
RelativePath=".\Src\W32Util\ChunkFile.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
PrecompiledHeaderFile="$(IntDir)/Video_DirectX9.pch"
ForcedIncludeFiles="stdafx.h"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
PrecompiledHeaderFile="$(IntDir)/Video_DirectX9.pch"
ForcedIncludeFiles="stdafx.h"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
PrecompiledHeaderFile="$(IntDir)/Video_DirectX9.pch"
ForcedIncludeFiles="stdafx.h"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
PrecompiledHeaderFile="$(IntDir)/Video_DirectX9.pch"
ForcedIncludeFiles="stdafx.h"
/>
</FileConfiguration>
<FileConfiguration
Name="DebugFast|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
PrecompiledHeaderFile="$(IntDir)/Video_DirectX9.pch"
ForcedIncludeFiles="stdafx.h"
/>
</FileConfiguration>
<FileConfiguration
Name="DebugFast|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
PrecompiledHeaderFile="$(IntDir)/Video_DirectX9.pch"
ForcedIncludeFiles="stdafx.h"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Src\W32Util\ChunkFile.h"
>
</File>
<File
RelativePath=".\Src\W32Util\DialogManager.cpp"
>

View File

@ -3,7 +3,7 @@
#include "Common.h"
const char *GenerateVertexShader(u32 components);
const char *GenerateVertexShader();
// shader variables
#define I_POSNORMALMATRIX "cpnmtx"

View File

@ -1,265 +0,0 @@
#include "ChunkFile.h"
namespace W32Util
{
ChunkFile::ChunkFile(const TCHAR *filename, bool _read)
{
data=0;
fastMode=false;
if (file.Open(filename,_read ? FILE_READ : FILE_WRITE))
{
didFail=false;
}
else
{
didFail=true;
return;
}
int fSize = file.GetSize();
fastMode = _read ? true : false;
if (fastMode)
{
data = new char[fSize];
file.Read(data,fSize);
file.Close();
// MessageBox(theApp->getHWND(),TEXT("FILECLOSED"),TEXT("MOSJ"),0);
}
eof=fSize;
numLevels=0;
read=_read;
pos=0;
didFail=false;
}
ChunkFile::~ChunkFile()
{
if (fastMode && data)
delete [] data;
else
file.Close();
}
int ChunkFile::ReadInt()
{
if (pos<eof)
{
/*
int temp = *(int *)(data+pos);
pos+=4;
*/
pos+=4;
if (fastMode)
return *(int *)(data+pos-4);
else
return file.ReadInt();
}
else
{
return 0;
}
}
void ChunkFile::WriteInt(int i)
{
/*
*(int *)(data+pos) = i;
pos+=4;
*/
file.WriteInt(i);
pos+=4;
}
//let's get into the business
bool ChunkFile::Descend(unsigned int id)
{
id=flipID(id);
if (read)
{
bool found = false;
int startPos = pos;
ChunkInfo temp = stack[numLevels];
//save information to restore after the next Ascend
stack[numLevels].parentStartLocation = pos;
stack[numLevels].parentEOF = eof;
int firstID = 0;
//let's search through children..
while(pos<eof)
{
stack[numLevels].ID = ReadInt();
if (firstID == 0) firstID=stack[numLevels].ID|1;
stack[numLevels].length = ReadInt();
stack[numLevels].startLocation = pos;
if (stack[numLevels].ID == id)
{
found = true;
break;
}
else
{
SeekTo(pos + stack[numLevels].length); //try next block
}
}
//if we found nothing, return false so the caller can skip this
if (!found)
{
/*
pos = startPos;
char temp1[5]; TCHAR temp2[5];
temp1[4]=0; temp2[4]=0;
*(int *)temp1 =id;
TCHAR tempx[256];
for (int i=0; i<4; i++)
temp2[i]=temp1[i];
_stprintf(tempx,TEXT("Couldn't find chunk \"%s\" in file"),temp2);
MessageBox(theApp->getHWND(),tempx,0,0);
*/
stack[numLevels]=temp;
SeekTo(stack[numLevels].parentStartLocation);
return false;
}
//descend into it
//pos was set inside the loop above
eof = stack[numLevels].startLocation + stack[numLevels].length;
numLevels++;
return true;
}
else
{
//write a chunk id, and prepare for filling in length later
WriteInt(id);
WriteInt(0); //will be filled in by Ascend
stack[numLevels].startLocation=pos;
numLevels++;
return true;
}
}
void ChunkFile::SeekTo(int _pos)
{
if (!fastMode)
file.SeekBeg(_pos);
pos=_pos;
}
//let's Ascend out
void ChunkFile::Ascend()
{
if (read)
{
//Ascend, and restore information
numLevels--;
SeekTo(stack[numLevels].parentStartLocation);
eof = stack[numLevels].parentEOF;
}
else
{
numLevels--;
//now fill in the written length automatically
int posNow = pos;
SeekTo(stack[numLevels].startLocation - 4);
WriteInt(posNow-stack[numLevels].startLocation);
SeekTo(posNow);
}
}
//read a block
void ChunkFile::ReadData(void *what, int count)
{
if (fastMode)
memcpy(what,data+pos,count);
else
file.Read(what,count);
pos+=count;
char temp[4]; //discarded
count &= 3;
if (count)
{
count=4-count;
if (!fastMode)
file.Read(temp,count);
pos+=count;
}
}
//write a block
void ChunkFile::WriteData(void *what, int count)
{
/*
memcpy(data+pos,what,count);
pos += count;
*/
file.Write(what,count);
pos+=count;
char temp[5]={0,0,0,0,0};
count &= 3;
if (count)
{
count=4-count;
file.Write(temp,count);
pos+=count;
}
}
/*
void ChunkFile::WriteString(String str)
{
wchar_t *text;
int len=str.length();
#ifdef UNICODE
text = str.getPointer();
#else
text=new wchar_t[len+1];
str.toUnicode(text);
#endif
WriteInt(len);
WriteData((char *)text,len*sizeof(wchar_t));
#ifndef UNICODE
delete [] text;
#endif
}
String ChunkFile::readString()
{
int len=ReadInt();
wchar_t *text = new wchar_t[len+1];
ReadData((char *)text,len*sizeof(wchar_t));
text[len]=0;
#ifdef UNICODE
String s(text);
delete [] text;
return s;
#else
String temp;
temp.fromUnicode(text);
delete [] text;
return temp;
#endif
}
*/
int ChunkFile::GetCurrentChunkSize()
{
if (numLevels)
return stack[numLevels-1].length;
else
return 0;
}
}

View File

@ -1,59 +0,0 @@
#pragma once
//TO REMEMBER WHEN USING:
//EITHER a chunk contains ONLY data
//OR it contains ONLY other chunks
//otherwise the scheme breaks...
#include "File.h"
namespace W32Util
{
inline unsigned int flipID(unsigned int id)
{
return ((id>>24)&0xFF) | ((id>>8)&0xFF00) | ((id<<8)&0xFF0000) | ((id<<24)&0xFF000000);
}
class ChunkFile
{
File file;
struct ChunkInfo
{
int startLocation;
int parentStartLocation;
int parentEOF;
unsigned int ID;
int length;
};
ChunkInfo stack[8];
int numLevels;
char *data;
int pos,eof;
bool fastMode;
bool read;
bool didFail;
void SeekTo(int _pos);
int GetPos() {return pos;}
public:
ChunkFile(const TCHAR *filename, bool _read);
~ChunkFile();
bool Descend(unsigned int id);
void Ascend();
int ReadInt();
void ReadInt(int &i) {i = ReadInt();}
void ReadData(void *data, int count);
// String ReadString();
void WriteInt(int i);
//void WriteString(String str);
void WriteData(void *data, int count);
int GetCurrentChunkSize();
bool Failed() {return didFail;}
};
}

View File

@ -166,8 +166,9 @@ void Video_Initialize(SVideoInitialize* _pVideoInitialize)
}
void Video_DoState(ChunkFile &f) {
VideoCommon_DoState(f);
void Video_DoState(unsigned char **ptr, int mode) {
PointerWrap p(ptr, mode);
VideoCommon_DoState(p);
//PanicAlert("Saving/Loading state from DirectX9");
}

View File

@ -179,8 +179,9 @@ void Video_Initialize(SVideoInitialize* _pVideoInitialize)
}
void Video_DoState(ChunkFile &f) {
VideoCommon_DoState(f);
void Video_DoState(unsigned char **ptr, int mode) {
PointerWrap p(ptr, mode);
VideoCommon_DoState(p);
//PanicAlert("Saving/Loading state from OpenGL");
}