mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
Merge large parts of nakeee's "Soap" branch into trunk, after fixing a few crash bugs in FileUtil.cpp.
Not really anything interesting, just some better comments, some slightly more portable/cleaner code in places. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2459 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -22,7 +22,6 @@
|
||||
using namespace Gen;
|
||||
|
||||
// Shared code between Win64 and Unix64
|
||||
// ====================================
|
||||
|
||||
// Sets up a __cdecl function.
|
||||
void XEmitter::ABI_EmitPrologue(int maxCallParams)
|
||||
@ -53,14 +52,14 @@ void XEmitter::ABI_EmitEpilogue(int maxCallParams)
|
||||
RET();
|
||||
#else
|
||||
#error Arch not supported
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _M_IX86 // All32
|
||||
|
||||
// Shared code between Win32 and Unix32
|
||||
// ====================================
|
||||
|
||||
void XEmitter::ABI_CallFunction(void *func) {
|
||||
ABI_AlignStack(0);
|
||||
CALL(func);
|
||||
@ -160,8 +159,9 @@ void XEmitter::ABI_RestoreStack(unsigned int frameSize) {
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#else //64bit
|
||||
|
||||
// Common functions
|
||||
void XEmitter::ABI_CallFunction(void *func) {
|
||||
CALL(func);
|
||||
}
|
||||
@ -221,7 +221,6 @@ void XEmitter::ABI_RestoreStack(unsigned int /*frameSize*/) {
|
||||
#ifdef _WIN32
|
||||
|
||||
// Win64 Specific Code
|
||||
// ====================================
|
||||
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
|
||||
//we only want to do this once
|
||||
PUSH(RBX);
|
||||
@ -249,7 +248,6 @@ void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() {
|
||||
}
|
||||
|
||||
// Win64 Specific Code
|
||||
// ====================================
|
||||
void XEmitter::ABI_PushAllCallerSavedRegsAndAdjustStack() {
|
||||
PUSH(RCX);
|
||||
PUSH(RDX);
|
||||
@ -277,7 +275,6 @@ void XEmitter::ABI_PopAllCallerSavedRegsAndAdjustStack() {
|
||||
|
||||
#else
|
||||
// Unix64 Specific Code
|
||||
// ====================================
|
||||
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
|
||||
PUSH(RBX);
|
||||
PUSH(RBP);
|
||||
@ -322,7 +319,8 @@ void XEmitter::ABI_PopAllCallerSavedRegsAndAdjustStack() {
|
||||
POP(RCX);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // WIN32
|
||||
|
||||
#endif // 32bit
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -45,8 +45,7 @@
|
||||
// Callee-save: RBX RBP R12 R13 R14 R15
|
||||
// Parameters: RDI RSI RDX RCX R8 R9
|
||||
|
||||
#ifdef _M_IX86
|
||||
// 32 bit calling convention, shared by all
|
||||
#ifdef _M_IX86 // 32 bit calling convention, shared by all
|
||||
|
||||
// 32-bit don't pass parameters in regs, but these are convenient to have anyway when we have to
|
||||
// choose regs to put stuff in.
|
||||
@ -54,21 +53,19 @@
|
||||
#define ABI_PARAM2 RDX
|
||||
|
||||
// There are no ABI_PARAM* here, since args are pushed.
|
||||
|
||||
// === 32-bit bog standard cdecl, shared between linux and windows ============================
|
||||
// 32-bit bog standard cdecl, shared between linux and windows
|
||||
// MacOSX 32-bit is same as System V with a few exceptions that we probably don't care much about.
|
||||
#else
|
||||
// 64 bit calling convention
|
||||
|
||||
#ifdef _WIN32
|
||||
// === 64-bit Windows - the really exotic calling convention ==================================
|
||||
#else // 64 bit calling convention
|
||||
|
||||
#ifdef _WIN32 // 64-bit Windows - the really exotic calling convention
|
||||
|
||||
#define ABI_PARAM1 RCX
|
||||
#define ABI_PARAM2 RDX
|
||||
#define ABI_PARAM3 R8
|
||||
#define ABI_PARAM4 R9
|
||||
#else
|
||||
// === 64-bit Unix (hopefully MacOSX too) =====================================================
|
||||
|
||||
#else //64-bit Unix (hopefully MacOSX too)
|
||||
|
||||
#define ABI_PARAM1 RDI
|
||||
#define ABI_PARAM2 RSI
|
||||
@ -83,3 +80,4 @@
|
||||
|
||||
#endif // _JIT_ABI_H
|
||||
|
||||
|
||||
|
@ -35,29 +35,29 @@
|
||||
static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
|
||||
unsigned int *ecx, unsigned int *edx)
|
||||
{
|
||||
#ifdef _LP64
|
||||
#ifdef _LP64
|
||||
__asm__("cpuid"
|
||||
: "=a" (*eax),
|
||||
"=b" (*ebx),
|
||||
"=c" (*ecx),
|
||||
"=d" (*edx)
|
||||
: "a" (*eax)
|
||||
);
|
||||
#else
|
||||
: "=a" (*eax),
|
||||
"=b" (*ebx),
|
||||
"=c" (*ecx),
|
||||
"=d" (*edx)
|
||||
: "a" (*eax)
|
||||
);
|
||||
#else
|
||||
// Note: EBX is reserved on Mac OS X and in PIC on Linux, so it has to be
|
||||
// restored at the end of the asm block.
|
||||
__asm__(
|
||||
"pushl %%ebx;"
|
||||
"cpuid;"
|
||||
"movl %%ebx,%1;"
|
||||
"popl %%ebx;"
|
||||
: "=a" (*eax),
|
||||
"=r" (*ebx),
|
||||
"=c" (*ecx),
|
||||
"=d" (*edx)
|
||||
: "a" (*eax)
|
||||
);
|
||||
#endif
|
||||
"pushl %%ebx;"
|
||||
"cpuid;"
|
||||
"movl %%ebx,%1;"
|
||||
"popl %%ebx;"
|
||||
: "=a" (*eax),
|
||||
"=r" (*ebx),
|
||||
"=c" (*ecx),
|
||||
"=d" (*edx)
|
||||
: "a" (*eax)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __cpuid(int info[4], int x)
|
||||
@ -78,6 +78,7 @@ void __cpuid(int info[4], int x)
|
||||
|
||||
CPUInfo cpu_info;
|
||||
|
||||
// Detects the various cpu features
|
||||
void CPUInfo::Detect()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
@ -88,26 +89,26 @@ void CPUInfo::Detect()
|
||||
OS64bit = true;
|
||||
#endif
|
||||
num_cores = 1;
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _M_IX86
|
||||
BOOL f64 = FALSE;
|
||||
OS64bit = IsWow64Process(GetCurrentProcess(), &f64) && f64;
|
||||
bool f64 = false;
|
||||
OS64bit = IsWow64Process(GetCurrentProcess(), (PBOOL)(&f64)) && f64;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// Set obvious defaults, for extra safety
|
||||
if (Mode64bit)
|
||||
{
|
||||
if (Mode64bit) {
|
||||
bSSE = true;
|
||||
bSSE2 = true;
|
||||
bLongMode = true;
|
||||
}
|
||||
|
||||
// Assume CPU supports the CPUID instruction. Those that don't can barely boot modern OS:es anyway.
|
||||
|
||||
// Assume CPU supports the CPUID instruction. Those that don't can barely
|
||||
// boot modern OS:es anyway.
|
||||
int cpu_id[4];
|
||||
memset(cpu_string, 0, sizeof(cpu_string));
|
||||
|
||||
|
||||
// Detect CPU's CPUID capabilities, and grab cpu string
|
||||
__cpuid(cpu_id, 0x00000000);
|
||||
u32 max_std_fn = cpu_id[0]; // EAX
|
||||
@ -122,10 +123,10 @@ void CPUInfo::Detect()
|
||||
vendor = VENDOR_AMD;
|
||||
else
|
||||
vendor = VENDOR_OTHER;
|
||||
|
||||
|
||||
// Set reasonable default brand string even if brand string not available.
|
||||
strcpy(brand_string, cpu_string);
|
||||
|
||||
|
||||
// Detect family and other misc stuff.
|
||||
bool HTT = false;
|
||||
int logical_cpu_count = 1;
|
||||
@ -182,6 +183,7 @@ void CPUInfo::Detect()
|
||||
}
|
||||
}
|
||||
|
||||
// Turn the cpu info into a string we can show
|
||||
std::string CPUInfo::Summarize()
|
||||
{
|
||||
std::string sum;
|
||||
|
@ -15,6 +15,7 @@
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
// Detect the cpu, so we'll know which optimizations to use
|
||||
#ifndef _CPUDETECT_H
|
||||
#define _CPUDETECT_H
|
||||
|
||||
@ -30,13 +31,13 @@ enum CPUVendor
|
||||
struct CPUInfo
|
||||
{
|
||||
CPUVendor vendor;
|
||||
|
||||
|
||||
char cpu_string[0x21];
|
||||
char brand_string[0x41];
|
||||
bool OS64bit;
|
||||
bool CPU64bit;
|
||||
bool Mode64bit;
|
||||
|
||||
|
||||
bool hyper_threaded;
|
||||
int num_cores;
|
||||
|
||||
@ -51,8 +52,11 @@ struct CPUInfo
|
||||
bool bSSE4A;
|
||||
bool bLAHFSAHF64;
|
||||
bool bLongMode;
|
||||
|
||||
|
||||
// Detects the various cpu features
|
||||
void Detect();
|
||||
|
||||
// Turn the cpu info into a string we can show
|
||||
std::string Summarize();
|
||||
};
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "Common.h"
|
||||
#include "FileUtil.h"
|
||||
|
||||
template <class T>
|
||||
struct LinkedListItem : public T
|
||||
@ -41,15 +42,11 @@ struct LinkedListItem : public T
|
||||
LinkedListItem<T> *next;
|
||||
};
|
||||
|
||||
|
||||
// Wrapper class
|
||||
class PointerWrap
|
||||
{
|
||||
public:
|
||||
/* READ is when we read from the save state file, WRITE is when we write to the
|
||||
save state file. This enumareted list is also defined in pluginspecs.h. Didn't
|
||||
want to couple them. */
|
||||
enum Mode
|
||||
{
|
||||
enum Mode {
|
||||
MODE_READ = 1,
|
||||
MODE_WRITE,
|
||||
MODE_MEASURE,
|
||||
@ -68,8 +65,7 @@ public:
|
||||
|
||||
void DoVoid(void *data, int size)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
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
|
||||
@ -84,22 +80,21 @@ public:
|
||||
// TODO
|
||||
PanicAlert("Do(map<>) does not yet work.");
|
||||
}
|
||||
|
||||
|
||||
// Store vectors.
|
||||
template<class T>
|
||||
void Do(std::vector<T> &x) {
|
||||
// TODO
|
||||
PanicAlert("Do(vector<>) does not yet work.");
|
||||
}
|
||||
|
||||
|
||||
// Store strings.
|
||||
void Do(std::string &x)
|
||||
{
|
||||
int stringLen = (int)x.length() + 1;
|
||||
Do(stringLen);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
|
||||
switch (mode) {
|
||||
case MODE_READ: x = (char*)*ptr; break;
|
||||
case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break;
|
||||
case MODE_MEASURE: break;
|
||||
@ -110,33 +105,29 @@ public:
|
||||
void DoBuffer(u8** pBuffer, u32& _Size)
|
||||
{
|
||||
Do(_Size);
|
||||
|
||||
if (_Size > 0)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
|
||||
if (_Size > 0) {
|
||||
switch (mode) {
|
||||
case MODE_READ: *pBuffer = new u8[_Size]; memcpy(*pBuffer, *ptr, _Size); break;
|
||||
case MODE_WRITE: memcpy(*ptr, *pBuffer, _Size); break;
|
||||
case MODE_MEASURE: break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
*pBuffer = NULL;
|
||||
}
|
||||
(*ptr) += _Size;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void DoArray(T *x, int count) {
|
||||
void DoArray(T *x, int count) {
|
||||
DoVoid((void *)x, sizeof(T) * count);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Do(T &x) {
|
||||
DoVoid((void *)&x, sizeof(x));
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void DoLinkedList(LinkedListItem<T> **list_start) {
|
||||
// TODO
|
||||
@ -148,85 +139,129 @@ public:
|
||||
class CChunkFileReader
|
||||
{
|
||||
public:
|
||||
// Load file template
|
||||
template<class T>
|
||||
static bool Load(const std::string& _rFilename, int _Revision, T& _class)
|
||||
static bool Load(const std::string& _rFilename, int _Revision, T& _class)
|
||||
{
|
||||
FILE* pFile = fopen(_rFilename.c_str(), "rb");
|
||||
if (pFile)
|
||||
{
|
||||
// get size
|
||||
fseek(pFile, 0, SEEK_END);
|
||||
size_t FileSize = ftell(pFile);
|
||||
fseek(pFile, 0, SEEK_SET);
|
||||
|
||||
INFO_LOG(COMMON, "ChunkReader: Loading %s" , _rFilename.c_str());
|
||||
|
||||
if (FileSize < sizeof(SChunkHeader))
|
||||
{
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the header
|
||||
SChunkHeader Header;
|
||||
fread(&Header, sizeof(SChunkHeader), 1, pFile);
|
||||
if (Header.Revision != _Revision)
|
||||
{
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
// get size
|
||||
int sz = (int)(FileSize - sizeof(SChunkHeader));
|
||||
if (Header.ExpectedSize != sz)
|
||||
{
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the state
|
||||
u8* buffer = new u8[sz];
|
||||
fread(buffer, 1, sz, pFile);
|
||||
fclose(pFile);
|
||||
|
||||
u8 *ptr = buffer;
|
||||
PointerWrap p(&ptr, PointerWrap::MODE_READ);
|
||||
_class.DoState(p);
|
||||
delete [] buffer;
|
||||
|
||||
return true;
|
||||
if (! File::Exists(_rFilename.c_str()))
|
||||
return false;
|
||||
|
||||
// Check file size
|
||||
u64 fileSize = File::GetSize(_rFilename.c_str());
|
||||
u64 headerSize = sizeof(SChunkHeader);
|
||||
if (fileSize < headerSize) {
|
||||
ERROR_LOG(COMMON,"ChunkReader: File too small");
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
FILE* pFile;
|
||||
if (! (pFile = fopen(_rFilename.c_str(), "rb"))) {
|
||||
ERROR_LOG(COMMON,"ChunkReader: Can't open file for reading");
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the header
|
||||
SChunkHeader header;
|
||||
if (fread(&header, 1, headerSize, pFile) != headerSize) {
|
||||
fclose(pFile);
|
||||
ERROR_LOG(COMMON,"ChunkReader: Bad header size");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check revision
|
||||
if (header.Revision != _Revision) {
|
||||
fclose(pFile);
|
||||
ERROR_LOG(COMMON,"ChunkReader: Wrong file revision, got %d expected %d",
|
||||
header.Revision, _Revision);
|
||||
return false;
|
||||
}
|
||||
|
||||
// get size
|
||||
int sz = (int)(fileSize - headerSize);
|
||||
if (header.ExpectedSize != sz) {
|
||||
fclose(pFile);
|
||||
ERROR_LOG(COMMON,"ChunkReader: Bad file size, got %d expected %d",
|
||||
sz, header.ExpectedSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the state
|
||||
u8* buffer = new u8[sz];
|
||||
if ((int)fread(buffer, 1, sz, pFile) != sz) {
|
||||
fclose(pFile);
|
||||
ERROR_LOG(COMMON,"ChunkReader: Error reading file");
|
||||
return false;
|
||||
}
|
||||
|
||||
// done reading
|
||||
if (fclose(pFile)) {
|
||||
ERROR_LOG(COMMON,"ChunkReader: Error closing file! might be corrupted!");
|
||||
// should never happen!
|
||||
return false;
|
||||
}
|
||||
|
||||
u8 *ptr = buffer;
|
||||
PointerWrap p(&ptr, PointerWrap::MODE_READ);
|
||||
_class.DoState(p);
|
||||
delete [] buffer;
|
||||
|
||||
INFO_LOG(COMMON, "ChunkReader: Done loading %s" , _rFilename.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Save file template
|
||||
template<class T>
|
||||
static bool Save(const std::string& _rFilename, int _Revision, T& _class)
|
||||
{
|
||||
FILE* pFile = fopen(_rFilename.c_str(), "wb");
|
||||
if (pFile)
|
||||
{
|
||||
u8 *ptr = 0;
|
||||
PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
|
||||
_class.DoState(p);
|
||||
size_t sz = (size_t)ptr;
|
||||
u8 *buffer = new u8[sz];
|
||||
ptr = buffer;
|
||||
p.SetMode(PointerWrap::MODE_WRITE);
|
||||
_class.DoState(p);
|
||||
FILE* pFile;
|
||||
|
||||
SChunkHeader Header;
|
||||
Header.Compress = 0;
|
||||
Header.Revision = _Revision;
|
||||
Header.ExpectedSize = (int)sz;
|
||||
|
||||
fwrite(&Header, sizeof(SChunkHeader), 1, pFile);
|
||||
fwrite(buffer, sz, 1, pFile);
|
||||
fclose(pFile);
|
||||
|
||||
return true;
|
||||
INFO_LOG(COMMON, "ChunkReader: Writing %s" , _rFilename.c_str());
|
||||
|
||||
if (! (pFile = fopen(_rFilename.c_str(), "wb"))) {
|
||||
ERROR_LOG(COMMON,"ChunkReader: Error opening file for write");
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
// Get data
|
||||
u8 *ptr = 0;
|
||||
PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
|
||||
_class.DoState(p);
|
||||
size_t sz = (size_t)ptr;
|
||||
u8 *buffer = new u8[sz];
|
||||
ptr = buffer;
|
||||
p.SetMode(PointerWrap::MODE_WRITE);
|
||||
_class.DoState(p);
|
||||
|
||||
// Create header
|
||||
SChunkHeader header;
|
||||
header.Compress = 0;
|
||||
header.Revision = _Revision;
|
||||
header.ExpectedSize = (int)sz;
|
||||
|
||||
// Write to file
|
||||
if (fwrite(&header, sizeof(SChunkHeader), 1, pFile) != 1) {
|
||||
ERROR_LOG(COMMON,"ChunkReader: Failed writing header");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fwrite(buffer, sz, 1, pFile) != 1) {
|
||||
ERROR_LOG(COMMON,"ChunkReader: Failed writing data");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fclose(pFile)) {
|
||||
ERROR_LOG(COMMON,"ChunkReader: Error closing file! might be corrupted!");
|
||||
return false;
|
||||
}
|
||||
|
||||
INFO_LOG(COMMON,"ChunkReader: Done writing %s",
|
||||
_rFilename.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
struct SChunkHeader
|
||||
{
|
||||
|
@ -18,51 +18,28 @@
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Settings
|
||||
// -----------------
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#define _CRTDBG_MAP_ALLOC_NEW
|
||||
#define CHECK_HEAP_INTEGRITY()
|
||||
//////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include
|
||||
// -----------------
|
||||
#ifdef _WIN32
|
||||
#ifdef _DEBUG
|
||||
#include <crtdbg.h>
|
||||
#undef CHECK_HEAP_INTEGRITY
|
||||
#define CHECK_HEAP_INTEGRITY() {if (!_CrtCheckMemory()) PanicAlert("memory corruption detected. see log.");}
|
||||
#endif
|
||||
|
||||
/* Turn on logging with debugging, _DEBUG and DEBUGFAST are still added through
|
||||
preprocessor definitions only */
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
#define LOGGING
|
||||
#endif
|
||||
|
||||
#include "../../../PluginSpecs/CommonTypes.h"
|
||||
#define HAVE_WIIUSE 1
|
||||
#define HAVE_WX 1
|
||||
#else
|
||||
#include "CommonTypes.h"
|
||||
#include "Config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Paths.h"
|
||||
///////////////////////////////////
|
||||
// Force enable logging in the right modes. For some reason, something had changed
|
||||
// so that debugfast no longer logged.
|
||||
#ifdef _DEBUG
|
||||
#undef LOGGING
|
||||
#define LOGGING 1
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGFAST
|
||||
#undef LOGGING
|
||||
#define LOGGING 1
|
||||
#endif
|
||||
|
||||
#include "Log.h"
|
||||
#include "CommonTypes.h"
|
||||
#include "MsgHandler.h"
|
||||
#include "CommonPaths.h"
|
||||
#include "CommonFuncs.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Settings
|
||||
// -----------------
|
||||
|
||||
// Darwin ABI requires that stack frames be aligned to 16-byte boundaries.
|
||||
// This probably wouldn't break anyone either, but hey
|
||||
@ -72,325 +49,73 @@
|
||||
#define STACKALIGN
|
||||
#endif
|
||||
|
||||
|
||||
// Function Cross-Compatibility
|
||||
#ifdef _WIN32
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#define unlink _unlink
|
||||
#define snprintf _snprintf
|
||||
#else
|
||||
#define _stricmp strcasecmp
|
||||
#define _strnicmp strncasecmp
|
||||
#define _unlink unlink
|
||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#endif
|
||||
|
||||
// Check MSC ver
|
||||
#if !defined _MSC_VER || _MSC_VER <= 1000
|
||||
#error needs at least version 1000 of MSC
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// By default, MS' stdio implementation does not support 64-bit offsets.
|
||||
// This little hack fixes that, keeping the code portable to linux where fseek and fread
|
||||
// do support 64-bit offsets in modern distributions.
|
||||
#define fseek _fseeki64
|
||||
#define ftell _ftelli64
|
||||
// Memory leak check defines
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#define _CRTDBG_MAP_ALLOC_NEW
|
||||
#define CHECK_HEAP_INTEGRITY()
|
||||
|
||||
#define atoll _atoi64
|
||||
|
||||
#define POSIX 0
|
||||
#define NOMINMAX
|
||||
|
||||
#if _M_IX86
|
||||
#define Crash() {__asm int 3}
|
||||
#else
|
||||
#if _MSC_VER > 1000
|
||||
extern "C" {
|
||||
__declspec(dllimport) void __stdcall DebugBreak(void);
|
||||
}
|
||||
#define Crash() {DebugBreak();}
|
||||
#else
|
||||
#error fixme
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif __GNUC__
|
||||
#define POSIX 1
|
||||
#define MAX_PATH 260
|
||||
#define stricmp strcasecmp
|
||||
#define Crash() {asm ("int $3");}
|
||||
#ifdef _LP64
|
||||
#define _M_X64 1
|
||||
#else
|
||||
#define _M_IX86 1
|
||||
#endif
|
||||
#endif
|
||||
#define POSIX 0
|
||||
#define NOMINMAX
|
||||
|
||||
// Alignment
|
||||
#define GC_ALIGNED16(x) __declspec(align(16)) x
|
||||
#define GC_ALIGNED32(x) __declspec(align(32)) x
|
||||
#define GC_ALIGNED64(x) __declspec(align(64)) x
|
||||
#define GC_ALIGNED16_DECL(x) __declspec(align(16)) x
|
||||
#define GC_ALIGNED64_DECL(x) __declspec(align(64)) x
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Since they are always around on windows
|
||||
#define HAVE_WIIUSE 1
|
||||
#define HAVE_WX 1
|
||||
|
||||
#define GC_ALIGNED16(x) __declspec(align(16)) x
|
||||
#define GC_ALIGNED32(x) __declspec(align(32)) x
|
||||
#define GC_ALIGNED64(x) __declspec(align(64)) x
|
||||
#define GC_ALIGNED16_DECL(x) __declspec(align(16)) x
|
||||
#define GC_ALIGNED64_DECL(x) __declspec(align(64)) x
|
||||
|
||||
#else
|
||||
|
||||
#define GC_ALIGNED16(x) __attribute((aligned(16))) x
|
||||
#define GC_ALIGNED32(x) __attribute((aligned(16))) x
|
||||
#define GC_ALIGNED64(x) __attribute((aligned(64))) x
|
||||
#define GC_ALIGNED16_DECL(x) __attribute((aligned(16))) x
|
||||
#define GC_ALIGNED64_DECL(x) __attribute((aligned(64))) x
|
||||
|
||||
#endif
|
||||
|
||||
// Various Windows compatibility
|
||||
|
||||
#if !defined(_WIN32)
|
||||
inline u32 _rotl(u32 x, int shift) {
|
||||
shift &= 31;
|
||||
if (!shift) return x;
|
||||
return (x << shift) | (x >> (32 - shift));
|
||||
}
|
||||
|
||||
inline u32 _rotr(u32 x, int shift) {
|
||||
shift &= 31;
|
||||
if (!shift) return x;
|
||||
return (x >> shift) | (x << (32 - shift));
|
||||
}
|
||||
|
||||
#define LONG int
|
||||
|
||||
|
||||
#ifndef __forceinline
|
||||
#define __forceinline inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (_M_IX86) && defined (_WIN32)
|
||||
#define HWCALL __cdecl
|
||||
#else
|
||||
#define HWCALL
|
||||
#endif
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
template<class T>
|
||||
inline T min(const T& a, const T& b) {return a > b ? b : a;}
|
||||
template<class T>
|
||||
inline T max(const T& a, const T& b) {return a > b ? a : b;}
|
||||
///////////////////////////////////
|
||||
|
||||
|
||||
|
||||
// **************************************************************************************
|
||||
// Utility functions
|
||||
// **************************************************************************************
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Byte ordering
|
||||
// -----------------
|
||||
namespace Common
|
||||
namespace
|
||||
{
|
||||
inline u8 swap8(u8 _data) {return(_data);}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
inline u16 swap16(u16 _data) {return(_byteswap_ushort(_data));}
|
||||
inline u32 swap32(u32 _data) {return(_byteswap_ulong(_data));}
|
||||
inline u64 swap64(u64 _data) {return(_byteswap_uint64(_data));}
|
||||
|
||||
#elif __linux__
|
||||
}
|
||||
#include <byteswap.h>
|
||||
namespace Common
|
||||
{
|
||||
inline u16 swap16(u16 _data) {return(bswap_16(_data));}
|
||||
inline u32 swap32(u32 _data) {return(bswap_32(_data));}
|
||||
inline u64 swap64(u64 _data) {return(bswap_64(_data));}
|
||||
|
||||
|
||||
#else
|
||||
inline u16 swap16(u16 data) {return((data >> 8) | (data << 8));}
|
||||
inline u32 swap32(u32 data) {return((swap16(data) << 16) | swap16(data >> 16));}
|
||||
inline u64 swap64(u64 data) {return(((u64)swap32(data) << 32) | swap32(data >> 32));}
|
||||
#endif
|
||||
|
||||
inline u16 swap16(u8* _pData) {return(swap16(*(u16*)_pData));}
|
||||
inline u32 swap32(u8* _pData) {return(swap32(*(u32*)_pData));}
|
||||
inline u64 swap64(u8* _pData) {return(swap64(*(u64*)_pData));}
|
||||
|
||||
|
||||
} // end of namespace Common
|
||||
///////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Message alerts
|
||||
// -----------------
|
||||
enum MSG_TYPE
|
||||
{
|
||||
INFORMATION,
|
||||
QUESTION,
|
||||
WARNING,
|
||||
};
|
||||
|
||||
typedef bool (*MsgAlertHandler)(const char* caption, const char* text,
|
||||
bool yes_no, int Style);
|
||||
void RegisterMsgAlertHandler(MsgAlertHandler handler);
|
||||
extern bool MsgAlert(const char* caption, bool yes_no, int Style, const char* format, ...);
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SuccessAlert(format, ...) MsgAlert("Information", false, INFORMATION, format, __VA_ARGS__)
|
||||
#define PanicAlert(format, ...) MsgAlert("Warning", false, WARNING, format, __VA_ARGS__)
|
||||
#define PanicYesNo(format, ...) MsgAlert("Warning", true, WARNING, format, __VA_ARGS__)
|
||||
#define AskYesNo(format, ...) MsgAlert("Question", true, QUESTION, format, __VA_ARGS__)
|
||||
#else
|
||||
#define SuccessAlert(format, ...) MsgAlert("SUCCESS", false, INFORMATION, format, ##__VA_ARGS__)
|
||||
#define PanicAlert(format, ...) MsgAlert("PANIC", false, WARNING, format, ##__VA_ARGS__)
|
||||
#define PanicYesNo(format, ...) MsgAlert("PANIC", true, WARNING, format, ##__VA_ARGS__)
|
||||
#define AskYesNo(format, ...) MsgAlert("ASK", true, QUESTION, format, ##__VA_ARGS__)
|
||||
#endif
|
||||
///////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Logging
|
||||
// -----------------
|
||||
|
||||
// dummy class
|
||||
class LogTypes
|
||||
{
|
||||
public:
|
||||
enum LOG_TYPE
|
||||
{
|
||||
MASTER_LOG,
|
||||
BOOT,
|
||||
PIXELENGINE,
|
||||
COMMANDPROCESSOR,
|
||||
VIDEOINTERFACE,
|
||||
SERIALINTERFACE,
|
||||
PERIPHERALINTERFACE,
|
||||
MEMMAP,
|
||||
DSPINTERFACE,
|
||||
STREAMINGINTERFACE,
|
||||
DVDINTERFACE,
|
||||
GPFIFO,
|
||||
EXPANSIONINTERFACE,
|
||||
AUDIO_INTERFACE,
|
||||
GEKKO,
|
||||
HLE,
|
||||
DSPHLE,
|
||||
VIDEO,
|
||||
AUDIO,
|
||||
DYNA_REC,
|
||||
CONSOLE,
|
||||
OSREPORT,
|
||||
WII_IOB,
|
||||
WII_IPC,
|
||||
WII_IPC_HLE,
|
||||
WII_IPC_DVD,
|
||||
WII_IPC_ES,
|
||||
WII_IPC_FILEIO,
|
||||
WII_IPC_SD,
|
||||
WII_IPC_NET,
|
||||
WII_IPC_WIIMOTE,
|
||||
ACTIONREPLAY,
|
||||
NUMBER_OF_LOGS
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef LOGGING
|
||||
extern void __Log(int logNumber, const char* text, ...);
|
||||
extern void __Logv(int log, int v, const char *format, ...);
|
||||
|
||||
void Host_UpdateLogDisplay();
|
||||
|
||||
// Logging macros. LOGGING is turned on from earlier in this file
|
||||
|
||||
#ifdef _WIN32
|
||||
#define LOG(t, ...) __Log(LogTypes::t, __VA_ARGS__);
|
||||
#define LOGV(t,v, ...) __Log(LogTypes::t + (v)*100, __VA_ARGS__);
|
||||
#define LOGP(t, ...) __Log(t, __VA_ARGS__);
|
||||
#define LOGVP(t,v, ...) __Log(t + (v)*100, __VA_ARGS__);
|
||||
#else
|
||||
#define LOG(t, ...) __Log(LogTypes::t, ##__VA_ARGS__);
|
||||
#define LOGV(t,v, ...) __Log(LogTypes::t + (v)*100, ##__VA_ARGS__);
|
||||
#define LOGP(t, ...) __Log(t, ##__VA_ARGS__);
|
||||
#define LOGVP(t,v, ...) __Log(t + (v)*100, ##__VA_ARGS__);
|
||||
#endif
|
||||
|
||||
#define _dbg_assert_(_t_, _a_) \
|
||||
if (!(_a_)){\
|
||||
LOG(_t_, "Error...\n\n Line: %d\n File: %s\n Time: %s\n\nIgnore and continue?", \
|
||||
__LINE__, __FILE__, __TIME__); \
|
||||
if (!PanicYesNo("*** Assertion (see log)***\n")){Crash();} \
|
||||
}
|
||||
#define _dbg_assert_msg_(_t_, _a_, ...)\
|
||||
if (!(_a_)){\
|
||||
LOG(_t_, __VA_ARGS__); \
|
||||
if (!PanicYesNo(__VA_ARGS__)){Crash();} \
|
||||
}
|
||||
#define _dbg_update_() Host_UpdateLogDisplay();
|
||||
|
||||
#else
|
||||
|
||||
#define LOG(_t_, ...)
|
||||
#define LOGV(_t_,_v_, ...)
|
||||
#define LOGP(_t_, ...)
|
||||
#define LOGVP(_t_,_v_, ...)
|
||||
#define _dbg_clear_()
|
||||
#ifndef _dbg_assert_
|
||||
#define _dbg_assert_(_t_, _a_) ;
|
||||
#define _dbg_assert_msg_(_t_, _a_, _desc_, ...) ;
|
||||
#endif
|
||||
#define _dbg_update_() ;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _assert_(_a_) _dbg_assert_(MASTER_LOG, _a_)
|
||||
#define _assert_msg_(_t_, _a_, _fmt_, ...)\
|
||||
if (!(_a_)){\
|
||||
if (!PanicYesNo(_fmt_, __VA_ARGS__)){Crash();} \
|
||||
}
|
||||
#else
|
||||
#define _assert_(a)
|
||||
#define _assert_msg_(...)
|
||||
#endif
|
||||
///////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compile time asserts
|
||||
// -----------------
|
||||
namespace
|
||||
{
|
||||
|
||||
// it is very risky to mix _SECURE_SCL=0 and _SECURE_SCL=1 compiled libraries
|
||||
// it is possible that you overwrite memory if you do it
|
||||
#ifdef _WIN32
|
||||
// it is VERY DANGEROUS to mix _SECURE_SCL=0 and _SECURE_SCL=1 compiled libraries.
|
||||
// You will get bizarre crash bugs whenever you use STL.
|
||||
#ifndef _SECURE_SCL
|
||||
#error Please define _SECURE_SCL=0 in the project settings
|
||||
#error Please define _SECURE_SCL=0 in the project settings
|
||||
#else
|
||||
template <bool> struct CompileTimeAssert;
|
||||
template<> struct CompileTimeAssert<true> {};
|
||||
CompileTimeAssert<_SECURE_SCL==0> x;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
///////////////////////////////////////
|
||||
|
||||
// Debug definions
|
||||
#if defined(_DEBUG)
|
||||
#include <crtdbg.h>
|
||||
#undef CHECK_HEAP_INTEGRITY
|
||||
#define CHECK_HEAP_INTEGRITY() {if (!_CrtCheckMemory()) PanicAlert("memory corruption detected. see log.");}
|
||||
#endif // end DEBUG/FAST
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SLEEP(x) Sleep(x)
|
||||
#else
|
||||
#define SLEEP(x) usleep(x*1000)
|
||||
#endif
|
||||
#else // Not windows
|
||||
|
||||
#endif // _COMMON_H
|
||||
#include "Config.h" // Scons defines
|
||||
// General defines
|
||||
#define POSIX 1
|
||||
#define MAX_PATH 260
|
||||
|
||||
// Windows compatibility
|
||||
#define __forceinline inline
|
||||
|
||||
#ifdef _LP64
|
||||
#define _M_X64 1
|
||||
#else
|
||||
#define _M_IX86 1
|
||||
#endif
|
||||
// Alignment
|
||||
#define GC_ALIGNED16(x) __attribute((aligned(16))) x
|
||||
#define GC_ALIGNED32(x) __attribute((aligned(16))) x
|
||||
#define GC_ALIGNED64(x) __attribute((aligned(64))) x
|
||||
#define GC_ALIGNED16_DECL(x) __attribute((aligned(16))) x
|
||||
#define GC_ALIGNED64_DECL(x) __attribute((aligned(64))) x
|
||||
#endif // WIN32
|
||||
|
||||
#endif // COMMON_H
|
||||
|
110
Source/Core/Common/Src/CommonFuncs.h
Normal file
110
Source/Core/Common/Src/CommonFuncs.h
Normal file
@ -0,0 +1,110 @@
|
||||
// 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 COMMONFUNCS_H
|
||||
#define COMMONFUNCS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SLEEP(x) Sleep(x)
|
||||
#else
|
||||
#define SLEEP(x) usleep(x*1000)
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <errno.h>
|
||||
#include <byteswap.h>
|
||||
// go to debugger mode
|
||||
#define Crash() {asm ("int $3");}
|
||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
inline u32 _rotl(u32 x, int shift) {
|
||||
shift &= 31;
|
||||
if (!shift) return x;
|
||||
return (x << shift) | (x >> (32 - shift));
|
||||
}
|
||||
|
||||
inline u32 _rotr(u32 x, int shift) {
|
||||
shift &= 31;
|
||||
if (!shift) return x;
|
||||
return (x >> shift) | (x << (32 - shift));
|
||||
}
|
||||
#define SLEEP(x) usleep(x*1000)
|
||||
#else // WIN32
|
||||
// Function Cross-Compatibility
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#define unlink _unlink
|
||||
#define snprintf _snprintf
|
||||
char* strndup (char const *s, size_t n);
|
||||
|
||||
// 64 bit offsets for windows
|
||||
#define fseek _fseeki64
|
||||
#define ftell _ftelli64
|
||||
#define atoll _atoi64
|
||||
#define stat64 _stat64
|
||||
#define SLEEP(x) Sleep(x)
|
||||
|
||||
#if _M_IX86
|
||||
#define Crash() {__asm int 3}
|
||||
#else
|
||||
extern "C" {
|
||||
__declspec(dllimport) void __stdcall DebugBreak(void);
|
||||
}
|
||||
#define Crash() {DebugBreak();}
|
||||
#endif // M_IX86
|
||||
#endif // WIN32 ndef
|
||||
|
||||
// Dolphin's min and max functions
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
template<class T>
|
||||
inline T min(const T& a, const T& b) {return a > b ? b : a;}
|
||||
template<class T>
|
||||
inline T max(const T& a, const T& b) {return a > b ? a : b;}
|
||||
|
||||
// Generic function to get last error message.
|
||||
// Call directly after the command or use the error num.
|
||||
// This function might change the error code.
|
||||
// Defined in Misc.cpp.
|
||||
const char* GetLastErrorMsg();
|
||||
|
||||
namespace Common
|
||||
{
|
||||
inline u8 swap8(u8 _data) {return _data;}
|
||||
|
||||
#ifdef _WIN32
|
||||
inline u16 swap16(u16 _data) {return _byteswap_ushort(_data);}
|
||||
inline u32 swap32(u32 _data) {return _byteswap_ulong (_data);}
|
||||
inline u64 swap64(u64 _data) {return _byteswap_uint64(_data);}
|
||||
#elif __linux__
|
||||
inline u16 swap16(u16 _data) {return bswap_16(_data);}
|
||||
inline u32 swap32(u32 _data) {return bswap_32(_data);}
|
||||
inline u64 swap64(u64 _data) {return bswap_64(_data);}
|
||||
#else
|
||||
// Slow generic implementation.
|
||||
inline u16 swap16(u16 data) {return (data >> 8) | (data << 8);}
|
||||
inline u32 swap32(u32 data) {return (swap16(data) << 16) | swap16(data >> 16);}
|
||||
inline u64 swap64(u64 data) {return ((u64)swap32(data) << 32) | swap32(data >> 32);}
|
||||
#endif
|
||||
|
||||
inline u16 swap16(const u8* _pData) {return swap16(*(const u16*)_pData);}
|
||||
inline u32 swap32(const u8* _pData) {return swap32(*(const u32*)_pData);}
|
||||
inline u64 swap64(const u8* _pData) {return swap64(*(const u64*)_pData);}
|
||||
|
||||
} // namespace Common
|
||||
|
||||
#endif // COMMONFUNCS
|
@ -1,130 +1,159 @@
|
||||
#ifndef PATHS_H
|
||||
#define PATHS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PLUGIN_PREFIX ""
|
||||
#define PLUGIN_SUFFIX ".dll"
|
||||
#else
|
||||
#ifdef __APPLE__
|
||||
#define PLUGIN_PREFIX "lib"
|
||||
#define PLUGIN_SUFFIX ".dylib"
|
||||
#else
|
||||
#define PLUGIN_PREFIX "lib"
|
||||
#define PLUGIN_SUFFIX ".so"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DIR_SEP "/"
|
||||
#define DIR_SEP_CHR '/'
|
||||
|
||||
#define PLUGINS_DIR "Plugins"
|
||||
#define ROOT_DIR "."
|
||||
#define USERDATA_DIR "User"
|
||||
#define SYSDATA_DIR "Sys"
|
||||
|
||||
// Dirs in both User and Sys
|
||||
#define EUR_DIR "EUR"
|
||||
#define USA_DIR "USA"
|
||||
#define JAP_DIR "JAP"
|
||||
|
||||
// Dirs in User
|
||||
#define GC_USER_DIR "GC"
|
||||
#define WII_USER_DIR "Wii"
|
||||
#define WII_SYSCONF_DIR "shared2/sys"
|
||||
#define CONFIG_DIR "Config"
|
||||
#define GAMECONFIG_DIR "GameConfig"
|
||||
#define MAPS_DIR "Maps"
|
||||
#define CACHE_DIR "Cache"
|
||||
#define STATESAVES_DIR "StateSaves"
|
||||
#define SCREENSHOTS_DIR "ScreenShots"
|
||||
#define DUMP_DIR "Dump"
|
||||
#define LOGS_DIR "Logs"
|
||||
#define MAIL_LOGS_DIR "Mail"
|
||||
|
||||
// Dirs in Sys
|
||||
#define GC_SYS_DIR "GC"
|
||||
#define WII_SYS_DIR "Wii"
|
||||
|
||||
// Filenames
|
||||
#define DOLPHIN_CONFIG "Dolphin.ini"
|
||||
#define DEBUGGER_CONFIG "Debugger.ini"
|
||||
#define TOTALDB "totaldb.dsy"
|
||||
|
||||
#define DEFAULT_GFX_PLUGIN PLUGIN_PREFIX "Plugin_VideoOGL" PLUGIN_SUFFIX
|
||||
#define DEFAULT_DSP_PLUGIN PLUGIN_PREFIX "Plugin_DSP_HLE" PLUGIN_SUFFIX
|
||||
#define DEFAULT_PAD_PLUGIN PLUGIN_PREFIX "Plugin_PadSimple" PLUGIN_SUFFIX
|
||||
#define DEFAULT_WIIMOTE_PLUGIN PLUGIN_PREFIX "Plugin_Wiimote" PLUGIN_SUFFIX
|
||||
|
||||
#define FONT_ANSI "font_ansi.bin"
|
||||
#define FONT_SJIS "font_sjis.bin"
|
||||
|
||||
#define DSP_ROM "dsp_rom.bin"
|
||||
#define DSP_COEF "dsp_coef.bin"
|
||||
|
||||
#define GC_IPL "IPL.bin"
|
||||
#define GC_SRAM "SRAM.raw"
|
||||
#define GC_MEMCARDA "MemoryCardA"
|
||||
#define GC_MEMCARDB "MemoryCardB"
|
||||
|
||||
#define WII_EUR_SETTING "setting-eur.txt"
|
||||
#define WII_USA_SETTING "setting-usa.txt"
|
||||
#define WII_JAP_SETTING "setting-jpn.txt"
|
||||
#define WII_SYSCONF "SYSCONF"
|
||||
|
||||
#define MEMORY_DUMP_FILE "mainram.dump"
|
||||
|
||||
// Shorts - dirs
|
||||
// User dirs
|
||||
#define FULL_USERDATA_DIR ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP
|
||||
#define FULL_GC_USER_DIR FULL_USERDATA_DIR GC_USER_DIR DIR_SEP
|
||||
//#define GC_USER_EUR_DIR FULL_GC_USER_DIR EUR_DIR
|
||||
//#define GC_USER_USA_DIR FULL_GC_USER_DIR USA_DIR
|
||||
//#define GC_USER_JAP_DIR FULL_GC_USER_DIR JAP_DIR
|
||||
|
||||
#define FULL_WII_USER_DIR FULL_USERDATA_DIR WII_USER_DIR DIR_SEP
|
||||
#define FULL_WII_ROOT_DIR FULL_USERDATA_DIR WII_USER_DIR // This is the "root" for Wii fs, so that it may be used with created devices
|
||||
|
||||
#define FULL_GAMECONFIG_DIR FULL_USERDATA_DIR GAMECONFIG_DIR DIR_SEP
|
||||
#define FULL_CONFIG_DIR FULL_USERDATA_DIR CONFIG_DIR DIR_SEP
|
||||
#define FULL_CACHE_DIR FULL_USERDATA_DIR CACHE_DIR DIR_SEP
|
||||
#define FULL_STATESAVES_DIR FULL_USERDATA_DIR STATESAVES_DIR DIR_SEP
|
||||
#define FULL_SCREENSHOTS_DIR FULL_USERDATA_DIR SCREENSHOTS_DIR DIR_SEP
|
||||
#define FULL_DUMP_DIR FULL_USERDATA_DIR DUMP_DIR DIR_SEP
|
||||
#define FULL_LOGS_DIR FULL_USERDATA_DIR LOGS_DIR DIR_SEP
|
||||
#define FULL_MAIL_LOGS_DIR FULL_LOGS_DIR MAIL_LOGS_DIR DIR_SEP
|
||||
#define FULL_MAPS_DIR FULL_USERDATA_DIR MAPS_DIR DIR_SEP
|
||||
|
||||
// Sys dirs
|
||||
#define FULL_SYSDATA_DIR ROOT_DIR DIR_SEP SYSDATA_DIR DIR_SEP
|
||||
|
||||
#define FULL_GC_SYS_DIR FULL_SYSDATA_DIR GC_SYS_DIR DIR_SEP
|
||||
//#define GC_SYS_EUR_DIR FULL_GC_SYS_DIR EUR_DIR
|
||||
//#define GC_SYS_USA_DIR FULL_GC_SYS_DIR USA_DIR
|
||||
//#define GC_SYS_JAP_DIR FULL_GC_SYS_DIR JAP_DIR
|
||||
|
||||
#define FULL_WII_SYS_DIR FULL_SYSDATA_DIR WII_SYS_DIR DIR_SEP
|
||||
|
||||
// Shorts - files
|
||||
// User files
|
||||
#define CONFIG_FILE FULL_CONFIG_DIR DOLPHIN_CONFIG
|
||||
#define DEBUGGER_CONFIG_FILE FULL_CONFIG_DIR DEBUGGER_CONFIG
|
||||
|
||||
#define TOTALDB_FILE FULL_SYSDATA_DIR TOTALDB
|
||||
#define MAINRAM_DUMP_FILE FULL_DUMP_DIR MEMORY_DUMP_FILE
|
||||
#define GC_SRAM_FILE FULL_USERDATA_DIR GC_USER_DIR DIR_SEP GC_SRAM
|
||||
|
||||
// Sys files
|
||||
#define FONT_ANSI_FILE FULL_GC_SYS_DIR FONT_ANSI
|
||||
#define FONT_SJIS_FILE FULL_GC_SYS_DIR FONT_SJIS
|
||||
|
||||
#define DSP_ROM_FILE FULL_GC_SYS_DIR DSP_ROM
|
||||
#define DSP_COEF_FILE FULL_GC_SYS_DIR DSP_COEF
|
||||
|
||||
#define WII_EUR_SETTING_FILE FULL_WII_SYS_DIR WII_EUR_SETTING
|
||||
#define WII_USA_SETTING_FILE FULL_WII_SYS_DIR WII_USA_SETTING
|
||||
#define WII_JAP_SETTING_FILE FULL_WII_SYS_DIR WII_JAP_SETTING
|
||||
#define WII_SYSCONF_FILE FULL_WII_USER_DIR WII_SYSCONF_DIR DIR_SEP WII_SYSCONF
|
||||
|
||||
#define FULL_WII_MENU_DIR FULL_WII_USER_DIR "title" DIR_SEP "00000001" DIR_SEP "00000002" DIR_SEP "content"
|
||||
|
||||
#endif // PATHS_H
|
||||
// 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 COMMON_PATHS_H
|
||||
#define COMMON_PATHS_H
|
||||
|
||||
// Library suffix/prefix
|
||||
#ifdef _WIN32
|
||||
#define PLUGIN_PREFIX ""
|
||||
#define PLUGIN_SUFFIX ".dll"
|
||||
#elif defined __APPLE__
|
||||
#define PLUGIN_PREFIX "lib"
|
||||
#define PLUGIN_SUFFIX ".dylib"
|
||||
#else
|
||||
#define PLUGIN_PREFIX "lib"
|
||||
#define PLUGIN_SUFFIX ".so"
|
||||
#endif
|
||||
|
||||
// Directory seperators, do we need this?
|
||||
#define DIR_SEP "/"
|
||||
#define DIR_SEP_CHR '/'
|
||||
|
||||
#define PLUGINS_DIR "Plugins"
|
||||
#define ROOT_DIR "."
|
||||
#define USERDATA_DIR "User"
|
||||
#define SYSDATA_DIR "Sys"
|
||||
|
||||
// Where data directory is
|
||||
#ifdef _WIN32
|
||||
#define DOLPHIN_DATA_DIR "Dolphin"
|
||||
#elif defined __APPLE__
|
||||
#define DOLPHIN_DATA_DIR "Library/Application Support/Dolphin"
|
||||
#else
|
||||
#define DOLPHIN_DATA_DIR ".dolphin"
|
||||
#endif
|
||||
|
||||
// Dirs in both User and Sys
|
||||
#define EUR_DIR "EUR"
|
||||
#define USA_DIR "USA"
|
||||
#define JAP_DIR "JAP"
|
||||
|
||||
// Dirs in User
|
||||
#define GC_USER_DIR "GC"
|
||||
#define WII_USER_DIR "Wii"
|
||||
#define WII_SYSCONF_DIR "shared2/sys"
|
||||
#define CONFIG_DIR "Config"
|
||||
#define GAMECONFIG_DIR "GameConfig"
|
||||
#define MAPS_DIR "Maps"
|
||||
#define CACHE_DIR "Cache"
|
||||
#define STATESAVES_DIR "StateSaves"
|
||||
#define SCREENSHOTS_DIR "ScreenShots"
|
||||
#define DUMP_DIR "Dump"
|
||||
#define LOGS_DIR "Logs"
|
||||
#define MAIL_LOGS_DIR "Mail"
|
||||
|
||||
// Dirs in Sys
|
||||
#define GC_SYS_DIR "GC"
|
||||
#define WII_SYS_DIR "Wii"
|
||||
|
||||
// Filenames
|
||||
#define DOLPHIN_CONFIG "Dolphin.ini"
|
||||
#define DEBUGGER_CONFIG "Debugger.ini"
|
||||
#define LOGGER_CONFIG "Logger.ini"
|
||||
#define TOTALDB "totaldb.dsy"
|
||||
|
||||
#define DEFAULT_GFX_PLUGIN PLUGIN_PREFIX "Plugin_VideoOGL" PLUGIN_SUFFIX
|
||||
#define DEFAULT_DSP_PLUGIN PLUGIN_PREFIX "Plugin_DSP_HLE" PLUGIN_SUFFIX
|
||||
#define DEFAULT_PAD_PLUGIN PLUGIN_PREFIX "Plugin_PadSimple" PLUGIN_SUFFIX
|
||||
#define DEFAULT_WIIMOTE_PLUGIN PLUGIN_PREFIX "Plugin_Wiimote" PLUGIN_SUFFIX
|
||||
|
||||
#define FONT_ANSI "font_ansi.bin"
|
||||
#define FONT_SJIS "font_sjis.bin"
|
||||
|
||||
#define DSP_ROM "dsp_rom.bin"
|
||||
#define DSP_COEF "dsp_coef.bin"
|
||||
|
||||
#define GC_IPL "IPL.bin"
|
||||
#define GC_SRAM "SRAM.raw"
|
||||
#define GC_MEMCARDA "MemoryCardA"
|
||||
#define GC_MEMCARDB "MemoryCardB"
|
||||
|
||||
#define WII_EUR_SETTING "setting-eur.txt"
|
||||
#define WII_USA_SETTING "setting-usa.txt"
|
||||
#define WII_JAP_SETTING "setting-jpn.txt"
|
||||
#define WII_SYSCONF "SYSCONF"
|
||||
|
||||
#define MEMORY_DUMP_FILE "mainram.dump"
|
||||
|
||||
// Shorts - dirs
|
||||
// User dirs
|
||||
#define FULL_USERDATA_DIR ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP
|
||||
|
||||
#define FULL_GC_USER_DIR FULL_USERDATA_DIR GC_USER_DIR DIR_SEP
|
||||
//#define GC_USER_EUR_DIR FULL_GC_USER_DIR EUR_DIR
|
||||
//#define GC_USER_USA_DIR FULL_GC_USER_DIR USA_DIR
|
||||
//#define GC_USER_JAP_DIR FULL_GC_USER_DIR JAP_DIR
|
||||
|
||||
#define FULL_WII_USER_DIR FULL_USERDATA_DIR WII_USER_DIR DIR_SEP
|
||||
#define FULL_WII_ROOT_DIR FULL_USERDATA_DIR WII_USER_DIR // This is the "root" for Wii fs, so that it may be used with created devices
|
||||
|
||||
#define FULL_GAMECONFIG_DIR FULL_USERDATA_DIR GAMECONFIG_DIR DIR_SEP
|
||||
#define FULL_CONFIG_DIR FULL_USERDATA_DIR CONFIG_DIR DIR_SEP
|
||||
#define FULL_CACHE_DIR FULL_USERDATA_DIR CACHE_DIR DIR_SEP
|
||||
#define FULL_STATESAVES_DIR FULL_USERDATA_DIR STATESAVES_DIR DIR_SEP
|
||||
#define FULL_SCREENSHOTS_DIR FULL_USERDATA_DIR SCREENSHOTS_DIR DIR_SEP
|
||||
#define FULL_DUMP_DIR FULL_USERDATA_DIR DUMP_DIR DIR_SEP
|
||||
#define FULL_LOGS_DIR FULL_USERDATA_DIR LOGS_DIR DIR_SEP
|
||||
#define FULL_MAIL_LOGS_DIR FULL_LOGS_DIR MAIL_LOGS_DIR DIR_SEP
|
||||
#define FULL_MAPS_DIR FULL_USERDATA_DIR MAPS_DIR DIR_SEP
|
||||
|
||||
// Sys dirs
|
||||
#define FULL_SYSDATA_DIR ROOT_DIR DIR_SEP SYSDATA_DIR DIR_SEP
|
||||
|
||||
#define FULL_GC_SYS_DIR FULL_SYSDATA_DIR GC_SYS_DIR DIR_SEP
|
||||
//#define GC_SYS_EUR_DIR FULL_GC_SYS_DIR EUR_DIR
|
||||
//#define GC_SYS_USA_DIR FULL_GC_SYS_DIR USA_DIR
|
||||
//#define GC_SYS_JAP_DIR FULL_GC_SYS_DIR JAP_DIR
|
||||
|
||||
#define FULL_WII_SYS_DIR FULL_SYSDATA_DIR WII_SYS_DIR DIR_SEP
|
||||
|
||||
// Shorts - files
|
||||
// User files
|
||||
#define CONFIG_FILE FULL_CONFIG_DIR DOLPHIN_CONFIG
|
||||
#define DEBUGGER_CONFIG_FILE FULL_CONFIG_DIR DEBUGGER_CONFIG
|
||||
#define LOGGER_CONFIG_FILE FULL_CONFIG_DIR LOGGER_CONFIG
|
||||
|
||||
#define TOTALDB_FILE FULL_SYSDATA_DIR TOTALDB
|
||||
#define MAINRAM_DUMP_FILE FULL_DUMP_DIR MEMORY_DUMP_FILE
|
||||
#define GC_SRAM_FILE FULL_USERDATA_DIR GC_USER_DIR DIR_SEP GC_SRAM
|
||||
|
||||
// Sys files
|
||||
#define FONT_ANSI_FILE FULL_GC_SYS_DIR FONT_ANSI
|
||||
#define FONT_SJIS_FILE FULL_GC_SYS_DIR FONT_SJIS
|
||||
|
||||
#define DSP_ROM_FILE FULL_GC_SYS_DIR DSP_ROM
|
||||
#define DSP_COEF_FILE FULL_GC_SYS_DIR DSP_COEF
|
||||
|
||||
#define WII_EUR_SETTING_FILE FULL_WII_SYS_DIR WII_EUR_SETTING
|
||||
#define WII_USA_SETTING_FILE FULL_WII_SYS_DIR WII_USA_SETTING
|
||||
#define WII_JAP_SETTING_FILE FULL_WII_SYS_DIR WII_JAP_SETTING
|
||||
#define WII_SYSCONF_FILE FULL_WII_USER_DIR WII_SYSCONF_DIR DIR_SEP WII_SYSCONF
|
||||
|
||||
#define FULL_WII_MENU_DIR FULL_WII_USER_DIR "title" DIR_SEP "00000001" DIR_SEP "00000002" DIR_SEP "content"
|
||||
|
||||
#endif // COMMON_PATHS_H
|
58
Source/Core/Common/Src/CommonTypes.h
Normal file
58
Source/Core/Common/Src/CommonTypes.h
Normal file
@ -0,0 +1,58 @@
|
||||
// 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/
|
||||
|
||||
|
||||
// This header contains type definitions that are shared between the Dolphin
|
||||
// core and the plugin specs. Any definitions that are only used by the core
|
||||
// should be placed in "Common.h" instead.
|
||||
|
||||
#ifndef _COMMONTYPES_H
|
||||
#define _COMMONTYPES_H
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
typedef unsigned __int8 u8;
|
||||
typedef unsigned __int16 u16;
|
||||
typedef unsigned __int32 u32;
|
||||
typedef unsigned __int64 u64;
|
||||
|
||||
typedef signed __int8 s8;
|
||||
typedef signed __int16 s16;
|
||||
typedef signed __int32 s32;
|
||||
typedef signed __int64 s64;
|
||||
|
||||
#else
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
typedef char s8;
|
||||
typedef short s16;
|
||||
typedef int s32;
|
||||
typedef long long s64;
|
||||
|
||||
// For using windows lock code
|
||||
#define TCHAR char
|
||||
#define LONG int
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
#endif // _COMMONTYPES_H
|
@ -15,8 +15,10 @@
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
// All plugins from Core > Plugins are loaded and unloaded with this class when
|
||||
// Dolphin is started and stopped.
|
||||
/*
|
||||
All plugins from Core > Plugins are loaded and unloaded with this class when
|
||||
Dolpin is started and stopped.
|
||||
*/
|
||||
|
||||
#include <string.h> // System
|
||||
#ifdef _WIN32
|
||||
@ -32,113 +34,116 @@
|
||||
#include "DynamicLibrary.h"
|
||||
#include "ConsoleWindow.h"
|
||||
|
||||
|
||||
DynamicLibrary::DynamicLibrary()
|
||||
{
|
||||
library = 0;
|
||||
}
|
||||
|
||||
std::string GetLastErrorAsString()
|
||||
// Gets the last dll error as string
|
||||
const char *DllGetLastError()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LPVOID lpMsgBuf = 0;
|
||||
DWORD error = GetLastError();
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
error,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0, NULL);
|
||||
std::string s;
|
||||
if (lpMsgBuf)
|
||||
{
|
||||
s = ((char *)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
} else {
|
||||
s = StringFromFormat("(unknown error %08x)", error);
|
||||
}
|
||||
return s;
|
||||
#else
|
||||
static std::string errstr;
|
||||
char *tmp = dlerror();
|
||||
if (tmp)
|
||||
errstr = tmp;
|
||||
|
||||
return errstr;
|
||||
#endif
|
||||
return GetLastErrorMsg();
|
||||
#else // not win32
|
||||
return dlerror();
|
||||
#endif // WIN32
|
||||
}
|
||||
|
||||
/* Function: Loading means loading the dll with LoadLibrary() to get an
|
||||
instance to the dll. This is done when Dolphin is started to determine
|
||||
which dlls are good, and before opening the Config and Debugging windows
|
||||
from Plugin.cpp and before opening the dll for running the emulation in
|
||||
Video_...cpp in Core. Since this is fairly slow, TODO: think about
|
||||
implementing some sort of cache.
|
||||
|
||||
Called from: The Dolphin Core */
|
||||
/* Loads the dll with LoadLibrary() or dlopen. This function is called on
|
||||
start to scan for plugin, and before opening the Config and Debugging
|
||||
windows. It is also called from core to load the plugins when the
|
||||
emulation starts.
|
||||
|
||||
Returns 0 on failure and 1 on success
|
||||
|
||||
TODO: think about implementing some sort of cache for the plugin info.
|
||||
*/
|
||||
int DynamicLibrary::Load(const char* filename)
|
||||
{
|
||||
if (!filename || strlen(filename) == 0)
|
||||
{
|
||||
LOG(MASTER_LOG, "Missing filename of dynamic library to load");
|
||||
PanicAlert("Missing filename of dynamic library to load");
|
||||
|
||||
INFO_LOG(COMMON, "DL: Loading dynamic library %s", filename);
|
||||
|
||||
if (!filename || strlen(filename) == 0) {
|
||||
ERROR_LOG(COMMON, "DL: Missing filename to load");
|
||||
return 0;
|
||||
}
|
||||
if (IsLoaded())
|
||||
{
|
||||
LOG(MASTER_LOG, "Trying to load already loaded library %s", filename);
|
||||
return 2;
|
||||
|
||||
if (IsLoaded()) {
|
||||
INFO_LOG(COMMON, "DL: library %s already loaded", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Console::Print("LoadLibrary: %s", filename);
|
||||
#ifdef _WIN32
|
||||
library = LoadLibrary(filename);
|
||||
#else
|
||||
// RTLD_NOW: resolve all symbols on load
|
||||
// RTLD_LOCAL: don't resolve symbols for other libraries
|
||||
library = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
|
||||
#endif
|
||||
Console::Print(" %p\n", library);
|
||||
if (!library)
|
||||
{
|
||||
LOG(MASTER_LOG, "Error loading DLL %s: %s", filename, GetLastErrorAsString().c_str());
|
||||
PanicAlert("Error loading DLL %s: %s\n", filename, GetLastErrorAsString().c_str());
|
||||
|
||||
DEBUG_LOG(COMMON, "DL: LoadLibrary: %s(%p)", filename, library);
|
||||
|
||||
if (!library) {
|
||||
ERROR_LOG(COMMON, "DL: Error loading DLL %s: %s", filename,
|
||||
DllGetLastError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
library_file = filename;
|
||||
|
||||
INFO_LOG(COMMON, "DL: Done loading dynamic library %s", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Frees one instances of the dynamic library. Note that on most systems use
|
||||
reference count to decide when to actually remove the library from memory.
|
||||
|
||||
Return 0 on failure and 1 on success
|
||||
*/
|
||||
int DynamicLibrary::Unload()
|
||||
{
|
||||
int retval;
|
||||
if (!IsLoaded())
|
||||
{
|
||||
PanicAlert("Error unloading DLL %s: not loaded", library_file.c_str());
|
||||
return 0;
|
||||
}
|
||||
INFO_LOG(COMMON, "DL: Unloading dynamic library %s", library_file.c_str());
|
||||
int retval;
|
||||
if (!IsLoaded()) { // library != null
|
||||
ERROR_LOG(COMMON, "DL: Unload failed for %s: not loaded",
|
||||
library_file.c_str());
|
||||
PanicAlert("DL: Unload failed %s: not loaded",
|
||||
library_file.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
Console::Print("FreeLibrary: %s %p\n", library_file.c_str(), library);
|
||||
DEBUG_LOG(COMMON, "DL: FreeLibrary: %s %p\n",
|
||||
library_file.c_str(), library);
|
||||
#ifdef _WIN32
|
||||
retval = FreeLibrary(library);
|
||||
retval = FreeLibrary(library);
|
||||
#else
|
||||
retval = dlclose(library) ? 0 : 1;
|
||||
retval = dlclose(library)?0:1;
|
||||
#endif
|
||||
|
||||
if (!retval)
|
||||
{
|
||||
PanicAlert("Error unloading DLL %s: %s", library_file.c_str(),
|
||||
GetLastErrorAsString().c_str());
|
||||
}
|
||||
library = 0;
|
||||
return retval;
|
||||
if (! retval) {
|
||||
ERROR_LOG(COMMON, "DL: Unload failed %s: %s",
|
||||
library_file.c_str(),
|
||||
DllGetLastError());
|
||||
}
|
||||
library = 0;
|
||||
|
||||
INFO_LOG(COMMON, "DL: Done unloading dynamic library %s",
|
||||
library_file.c_str());
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Returns the address where symbol funcname is loaded or NULL on failure
|
||||
void* DynamicLibrary::Get(const char* funcname) const
|
||||
{
|
||||
void* retval;
|
||||
|
||||
INFO_LOG(COMMON, "DL: Getting symbol %s: %s", library_file.c_str(),
|
||||
funcname);
|
||||
|
||||
if (!library)
|
||||
{
|
||||
PanicAlert("Can't find function %s - Library not loaded.");
|
||||
ERROR_LOG(COMMON, "DL: Get failed %s - Library not loaded");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -150,9 +155,14 @@ void* DynamicLibrary::Get(const char* funcname) const
|
||||
|
||||
if (!retval)
|
||||
{
|
||||
LOG(MASTER_LOG, "Symbol %s missing in %s (error: %s)\n", funcname, library_file.c_str(), GetLastErrorAsString().c_str());
|
||||
PanicAlert("Symbol %s missing in %s (error: %s)\n", funcname, library_file.c_str(), GetLastErrorAsString().c_str());
|
||||
ERROR_LOG(COMMON, "DL: Symbol %s missing in %s (error: %s)\n",
|
||||
funcname, library_file.c_str(),
|
||||
DllGetLastError());
|
||||
}
|
||||
|
||||
INFO_LOG(COMMON, "DL: Done getting symbol %s: %s", library_file.c_str(),
|
||||
funcname);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,19 +24,31 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
// Abstracts the (few) differences between dynamically loading DLLs under Windows
|
||||
// and .so / .dylib under Linux/MacOSX.
|
||||
/* Abstracts the (few) differences between dynamically loading DLLs under
|
||||
Windows and .so / .dylib under Linux/MacOSX. */
|
||||
class DynamicLibrary
|
||||
{
|
||||
public:
|
||||
DynamicLibrary();
|
||||
|
||||
// Loads the library filename
|
||||
int Load(const char *filename);
|
||||
|
||||
// Unload the current library
|
||||
int Unload();
|
||||
|
||||
// Gets a pointer to the function symbol of funcname by getting it from the
|
||||
// share object
|
||||
void *Get(const char *funcname) const;
|
||||
|
||||
// Returns true is the library is loaded
|
||||
bool IsLoaded() const { return library != 0; }
|
||||
|
||||
private:
|
||||
// name of the library file
|
||||
std::string library_file;
|
||||
|
||||
// Library handle
|
||||
#ifdef _WIN32
|
||||
HINSTANCE library;
|
||||
#else
|
||||
@ -44,4 +56,4 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // DYNAMICLIBRARY
|
||||
|
@ -32,106 +32,118 @@
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
#include <CoreFoundation/CFString.h>
|
||||
#include <CoreFoundation/CFUrl.h>
|
||||
#include <CoreFoundation/CFBundle.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
/*
|
||||
This namespace has various generic functions related to files and paths.
|
||||
The code still needs a ton of cleanup.
|
||||
REMEMBER: strdup considered harmful!
|
||||
*/
|
||||
namespace File
|
||||
{
|
||||
|
||||
|
||||
// =======================================================
|
||||
// Remove any ending forward slashes from directory paths
|
||||
// -------------
|
||||
inline void StripTailDirSlashes(std::string& fname)
|
||||
// Modifies argument.
|
||||
inline char *StripTailDirSlashes(char *fname)
|
||||
{
|
||||
// Make sure it's not a blank string
|
||||
if(fname.length() > 0)
|
||||
{
|
||||
while(fname.at(fname.length() - 1) == DIR_SEP_CHR)
|
||||
fname.resize(fname.length() - 1);
|
||||
}
|
||||
int len = (int)strlen(fname);
|
||||
int i = len - 1;
|
||||
if (len > 1)
|
||||
while (fname[i] == DIR_SEP_CHR)
|
||||
fname[i--] = '\0';
|
||||
return fname;
|
||||
}
|
||||
// =============
|
||||
|
||||
|
||||
// Returns true if file filename exists
|
||||
bool Exists(const char *filename)
|
||||
{
|
||||
struct stat file_info;
|
||||
|
||||
char *copy = StripTailDirSlashes(strdup(filename));
|
||||
int result = stat(copy, &file_info);
|
||||
|
||||
std::string copy = filename;
|
||||
StripTailDirSlashes(copy);
|
||||
if (result < 0)
|
||||
{
|
||||
WARN_LOG(COMMON, "Exist: stat failed on %s: %s", filename,
|
||||
GetLastErrorMsg());
|
||||
}
|
||||
free(copy);
|
||||
|
||||
int result = stat(copy.c_str(), &file_info);
|
||||
return (result == 0);
|
||||
}
|
||||
|
||||
// Returns true if filename is a directory
|
||||
bool IsDirectory(const char *filename)
|
||||
{
|
||||
struct stat file_info;
|
||||
std::string copy = filename;
|
||||
StripTailDirSlashes(copy);
|
||||
|
||||
int result = stat(copy.c_str(), &file_info);
|
||||
if (result == 0)
|
||||
return S_ISDIR(file_info.st_mode);
|
||||
else
|
||||
char *copy = StripTailDirSlashes(strdup(filename));
|
||||
|
||||
int result = stat(copy, &file_info);
|
||||
free(copy);
|
||||
|
||||
if (result < 0) {
|
||||
WARN_LOG(COMMON, "IsDirectory: stat failed on %s: %s",
|
||||
filename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
return S_ISDIR(file_info.st_mode);
|
||||
}
|
||||
|
||||
// Deletes a given filename, return true on success
|
||||
// Doesn't supports deleting a directory
|
||||
bool Delete(const char *filename)
|
||||
{
|
||||
if (!Exists(filename))
|
||||
return false;
|
||||
if (IsDirectory(filename))
|
||||
INFO_LOG(COMMON, "Delete: file %s\n", filename);
|
||||
|
||||
// Return true because we care about the file no
|
||||
// being there, not the actual delete.
|
||||
if (!Exists(filename)) {
|
||||
WARN_LOG(COMMON, "Delete: %s does not exists", filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We can't delete a directory
|
||||
if (IsDirectory(filename)) {
|
||||
WARN_LOG(COMMON, "Delete: %s is a directory", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
DeleteFile(filename);
|
||||
if (!DeleteFile(filename)) {
|
||||
WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s",
|
||||
filename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
unlink(filename);
|
||||
if (unlink(filename) == -1) {
|
||||
WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s",
|
||||
filename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string SanitizePath(const char *filename)
|
||||
{
|
||||
|
||||
std::string copy = filename;
|
||||
#ifdef _WIN32
|
||||
for (size_t i = 0; i < copy.size(); i++)
|
||||
if (copy[i] == '/')
|
||||
copy[i] = '\\';
|
||||
#else
|
||||
// Should we do the otherway around?
|
||||
#endif
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Returns true if successful, or path already exists.
|
||||
bool CreateDir(const char *path)
|
||||
{
|
||||
INFO_LOG(COMMON, "CreateDir: directory %s\n", path);
|
||||
#ifdef _WIN32
|
||||
if (::CreateDirectory(path, NULL))
|
||||
return true;
|
||||
DWORD error = GetLastError();
|
||||
if (error == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
// PanicAlert("%s already exists", path);
|
||||
if (error == ERROR_ALREADY_EXISTS) {
|
||||
WARN_LOG(COMMON, "CreateDir: CreateDirectory failed on %s: already exists", path);
|
||||
return true;
|
||||
}
|
||||
PanicAlert("Error creating directory %s: %i", path, error);
|
||||
ERROR_LOG(COMMON, "CreateDir: CreateDirectory failed on %s: %i", path, error);
|
||||
return false;
|
||||
#else
|
||||
if (mkdir(path, 0755) == 0)
|
||||
@ -139,434 +151,374 @@ bool CreateDir(const char *path)
|
||||
|
||||
int err = errno;
|
||||
|
||||
if (err == EEXIST)
|
||||
{
|
||||
// PanicAlert("%s already exists", path);
|
||||
if (err == EEXIST) {
|
||||
WARN_LOG(COMMON, "CreateDir: mkdir failed on %s: already exists", path);
|
||||
return true;
|
||||
}
|
||||
|
||||
PanicAlert("Error creating directory %s: %s", path, strerror(err));
|
||||
ERROR_LOG(COMMON, "CreateDir: mkdir failed on %s: %s", path, strerror(err));
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create several dirs
|
||||
bool CreateDirectoryStructure(const std::string& _rFullPath)
|
||||
// Creates the full path of fullPath returns true on success
|
||||
bool CreateFullPath(const char *fullPath)
|
||||
{
|
||||
int PanicCounter = 10;
|
||||
|
||||
size_t Position = 0;
|
||||
while(true)
|
||||
{
|
||||
int panicCounter = 100;
|
||||
INFO_LOG(COMMON, "CreateFullPath: path %s\n", fullPath);
|
||||
|
||||
const char *position = fullPath;
|
||||
while (true) {
|
||||
// Find next sub path, support both \ and / directory separators
|
||||
{
|
||||
size_t nextPosition = _rFullPath.find(DIR_SEP_CHR, Position);
|
||||
Position = nextPosition;
|
||||
position = strchr(position, DIR_SEP_CHR);
|
||||
|
||||
if (Position == std::string::npos)
|
||||
return true;
|
||||
|
||||
Position++;
|
||||
}
|
||||
// we're done, yay!
|
||||
if (! position)
|
||||
return true;
|
||||
|
||||
position++;
|
||||
|
||||
// Create next sub path
|
||||
std::string SubPath = _rFullPath.substr(0, Position);
|
||||
if (!SubPath.empty())
|
||||
{
|
||||
if (!File::IsDirectory(SubPath.c_str()))
|
||||
{
|
||||
File::CreateDir(SubPath.c_str());
|
||||
LOG(WII_IPC_FILEIO, " CreateSubDir %s", SubPath.c_str());
|
||||
int sLen = (int)(position - fullPath);
|
||||
if (sLen > 0) {
|
||||
char *subPath = strndup(fullPath, sLen);
|
||||
if (!File::IsDirectory(subPath)) {
|
||||
File::CreateDir(subPath);
|
||||
}
|
||||
free(subPath);
|
||||
}
|
||||
|
||||
// A safety check
|
||||
PanicCounter--;
|
||||
if (PanicCounter <= 0)
|
||||
{
|
||||
PanicAlert("CreateDirectoryStruct creates way to much dirs...");
|
||||
panicCounter--;
|
||||
if (panicCounter <= 0) {
|
||||
ERROR_LOG(COMMON, "CreateFullPath: directory stracture too deep");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Deletes a directory filename, returns true on success
|
||||
bool DeleteDir(const char *filename)
|
||||
{
|
||||
INFO_LOG(COMMON, "DeleteDir: directory %s", filename);
|
||||
|
||||
if (!File::IsDirectory(filename))
|
||||
// check if a directory
|
||||
if (!File::IsDirectory(filename)) {
|
||||
ERROR_LOG(COMMON, "DeleteDir: Not a directory %s",
|
||||
filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
return ::RemoveDirectory (filename) ? true : false;
|
||||
if (::RemoveDirectory(filename))
|
||||
return true;
|
||||
#else
|
||||
if (rmdir(filename) == 0)
|
||||
return true;
|
||||
|
||||
int err = errno;
|
||||
|
||||
PanicAlert("Error removing directory %s",strerror(err));
|
||||
return false;
|
||||
if (rmdir(filename) == 0)
|
||||
return true;
|
||||
#endif
|
||||
ERROR_LOG(COMMON, "DeleteDir: %s: %s",
|
||||
filename, GetLastErrorMsg());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// renames file srcFilename to destFilename, returns true on success
|
||||
bool Rename(const char *srcFilename, const char *destFilename)
|
||||
{
|
||||
return (rename(srcFilename, destFilename) == 0);
|
||||
INFO_LOG(COMMON, "Rename: %s --> %s",
|
||||
srcFilename, destFilename);
|
||||
if (rename(srcFilename, destFilename) == 0)
|
||||
return true;
|
||||
ERROR_LOG(COMMON, "Rename: failed %s --> %s: %s",
|
||||
srcFilename, destFilename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
// copies file srcFilename to destFilename, returns true on success
|
||||
bool Copy(const char *srcFilename, const char *destFilename)
|
||||
{
|
||||
INFO_LOG(COMMON, "Copy: %s --> %s",
|
||||
srcFilename, destFilename);
|
||||
#ifdef _WIN32
|
||||
return (CopyFile(srcFilename, destFilename, FALSE) == TRUE) ? true : false;
|
||||
if (CopyFile(srcFilename, destFilename, FALSE))
|
||||
return true;
|
||||
|
||||
ERROR_LOG(COMMON, "Copy: failed %s --> %s: %s",
|
||||
srcFilename, destFilename, GetLastErrorMsg());
|
||||
return false;
|
||||
#else
|
||||
|
||||
// buffer size
|
||||
#define BSIZE 1024
|
||||
|
||||
int rnum, wnum, err;
|
||||
char buffer[BSIZE];
|
||||
FILE *output, *input;
|
||||
|
||||
if (! (input = fopen(srcFilename, "r"))) {
|
||||
err = errno;
|
||||
PanicAlert("Error copying from %s: %s", srcFilename, strerror(err));
|
||||
return false;
|
||||
}
|
||||
char buffer[BSIZE];
|
||||
|
||||
if (! (output = fopen(destFilename, "w"))) {
|
||||
err = errno;
|
||||
PanicAlert("Error copying to %s: %s", destFilename, strerror(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
while(! feof(input)) {
|
||||
if((rnum = fread(buffer, sizeof(char), BSIZE, input)) != BSIZE) {
|
||||
if(ferror(input) != 0){
|
||||
PanicAlert("can't read source file\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if((wnum = fwrite(buffer, sizeof(char), rnum, output))!= rnum){
|
||||
PanicAlert("can't write output file\n");
|
||||
// Open input file
|
||||
FILE *input = fopen(srcFilename, "rb");
|
||||
if (!input)
|
||||
{
|
||||
ERROR_LOG(COMMON, "Copy: input failed %s --> %s: %s",
|
||||
srcFilename, destFilename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(input);
|
||||
fclose(output);
|
||||
|
||||
return true;
|
||||
/*
|
||||
std::ifstream ifs(srcFilename, std::ios::binary);
|
||||
std::ofstream ofs(destFilename, std::ios::binary);
|
||||
|
||||
ofs << ifs.rdbuf();
|
||||
// open output file
|
||||
FILE *output = fopen(destFilename, "wb");
|
||||
if (!output)
|
||||
{
|
||||
fclose(input);
|
||||
ERROR_LOG(COMMON, "Copy: output failed %s --> %s: %s",
|
||||
srcFilename, destFilename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
ifs.close();
|
||||
ofs.close();
|
||||
|
||||
return true;*/
|
||||
// copy loop
|
||||
while (!feof(input))
|
||||
{
|
||||
// read input
|
||||
int rnum = fread(buffer, sizeof(char), BSIZE, input);
|
||||
if (rnum != BSIZE)
|
||||
{
|
||||
if (ferror(input) != 0) {
|
||||
ERROR_LOG(COMMON,
|
||||
"Copy: failed reading from source, %s --> %s: %s",
|
||||
srcFilename, destFilename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// write output
|
||||
int wnum = fwrite(buffer, sizeof(char), rnum, output)
|
||||
if (wnum != rnum)
|
||||
{
|
||||
ERROR_LOG(COMMON,
|
||||
"Copy: failed writing to output, %s --> %s: %s",
|
||||
srcFilename, destFilename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// close flushs
|
||||
fclose(input);
|
||||
fclose(output);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string GetUserDirectory()
|
||||
// Returns a pointer to a string with a Dolphin data dir in the user's home directory.
|
||||
// To be used in "multi-user" mode (that is, installed).
|
||||
const char *GetUserDirectory()
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
#ifdef _WIN32
|
||||
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, path)))
|
||||
{
|
||||
//return std::string(path);
|
||||
// Make sure we only need to do it once
|
||||
static char path[MAX_PATH] = {0};
|
||||
if (strlen(path) > 0)
|
||||
return path;
|
||||
|
||||
/* I dont understand this, I got "E:\Documents and Settings\All Users\Application Data"
|
||||
from this */
|
||||
return std::string("");
|
||||
}
|
||||
return std::string("");
|
||||
#ifdef WIN32
|
||||
char homedir[MAX_PATH];
|
||||
if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path)))
|
||||
return NULL;
|
||||
#else
|
||||
char *homedir = getenv("HOME");
|
||||
if (!homedir)
|
||||
return std::string("");
|
||||
#ifdef __APPLE__
|
||||
snprintf(path, sizeof(path), "%s/Library/Application Support/Dolphin", homedir);
|
||||
#else
|
||||
snprintf(path, sizeof(path), "%s/.dolphin", homedir); // XXX changeme as appropriate
|
||||
return NULL;
|
||||
#endif
|
||||
#endif
|
||||
return std::string(path);
|
||||
|
||||
snprintf(path, sizeof(path), "%s" DIR_SEP DOLPHIN_DATA_DIR, homedir);
|
||||
INFO_LOG(COMMON, "GetUserDirectory: Setting to %s:", path);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
//osx specific functions
|
||||
#if defined(__APPLE__)
|
||||
|
||||
std::string GetBundleDirectory()
|
||||
{
|
||||
|
||||
// Plugin path will be Dolphin.app/Contents/PlugIns
|
||||
CFURLRef BundleRef;
|
||||
char AppBundlePath[MAXPATHLEN];
|
||||
|
||||
// Get the main bundle for the app
|
||||
BundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
|
||||
|
||||
CFStringRef BundlePath = CFURLCopyFileSystemPath(BundleRef, kCFURLPOSIXPathStyle);
|
||||
CFStringGetFileSystemRepresentation(BundlePath, AppBundlePath, sizeof(AppBundlePath));
|
||||
|
||||
CFRelease(BundleRef);
|
||||
CFRelease(BundlePath);
|
||||
|
||||
return AppBundlePath;
|
||||
|
||||
|
||||
}
|
||||
std::string GetPluginsDirectory()
|
||||
{
|
||||
|
||||
CFURLRef PluginDirRef;
|
||||
char PluginPath[MAXPATHLEN];
|
||||
|
||||
PluginDirRef = CFBundleCopyBuiltInPlugInsURL(CFBundleGetMainBundle());
|
||||
|
||||
CFStringRef PluginDirPath = CFURLCopyFileSystemPath(PluginDirRef, kCFURLPOSIXPathStyle);
|
||||
CFStringGetFileSystemRepresentation(PluginDirPath, PluginPath, sizeof(PluginPath));
|
||||
|
||||
CFRelease(PluginDirRef);
|
||||
CFRelease(PluginDirPath);
|
||||
|
||||
std::string PluginsDir = GetBundleDirectory();
|
||||
PluginsDir += DIR_SEP;
|
||||
PluginsDir += PluginPath;
|
||||
|
||||
return PluginsDir;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
// Returns the size of filename (64bit)
|
||||
u64 GetSize(const char *filename)
|
||||
{
|
||||
if (!Exists(filename))
|
||||
if (!Exists(filename)) {
|
||||
WARN_LOG(COMMON, "GetSize: failed %s: No such file"
|
||||
,filename);
|
||||
return 0;
|
||||
#ifdef _WIN32
|
||||
// stat doesn't support 64-bit file sizes on Win32.
|
||||
FILE *pFile = fopen(filename, "rb");
|
||||
if (pFile)
|
||||
{
|
||||
fseek(pFile, 0, SEEK_END);
|
||||
u64 pos = ftell(pFile);
|
||||
fclose(pFile);
|
||||
return pos;
|
||||
}
|
||||
#else
|
||||
struct stat buf;
|
||||
if (stat(filename, &buf) == 0) {
|
||||
return buf.st_size;
|
||||
}
|
||||
int err = errno;
|
||||
PanicAlert("Error accessing %s: %s", filename, strerror(err));
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
if (IsDirectory(filename)) {
|
||||
WARN_LOG(COMMON, "GetSize: failed %s: is a directory"
|
||||
,filename);
|
||||
return 0;
|
||||
}
|
||||
// on windows it's actually _stat64 defined in commonFuncs
|
||||
struct stat64 buf;
|
||||
if (stat64(filename, &buf) == 0) {
|
||||
return buf.st_size;
|
||||
}
|
||||
|
||||
ERROR_LOG(COMMON, "GetSize: Stat failed %s: %s",
|
||||
filename, GetLastErrorMsg());
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static bool ReadFoundFile(const WIN32_FIND_DATA& ffd, FSTEntry& entry)
|
||||
{
|
||||
// ignore files starting with a .
|
||||
if(strncmp(ffd.cFileName, ".", 1) == 0)
|
||||
return false;
|
||||
|
||||
entry.virtualName = ffd.cFileName;
|
||||
|
||||
if(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
entry.isDirectory = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.isDirectory = false;
|
||||
entry.size = ffd.nFileSizeLow;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 ScanDirectoryTree(const std::string& _Directory, FSTEntry& parentEntry)
|
||||
{
|
||||
// Find the first file in the directory.
|
||||
WIN32_FIND_DATA ffd;
|
||||
std::string searchName = _Directory + "\\*";
|
||||
HANDLE hFind = FindFirstFile(searchName.c_str(), &ffd);
|
||||
|
||||
u32 foundEntries = 0;
|
||||
|
||||
if (hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
FSTEntry entry;
|
||||
|
||||
if(ReadFoundFile(ffd, entry))
|
||||
{
|
||||
entry.physicalName = _Directory + "\\" + entry.virtualName;
|
||||
if(entry.isDirectory)
|
||||
{
|
||||
u32 childEntries = ScanDirectoryTree(entry.physicalName, entry);
|
||||
entry.size = childEntries;
|
||||
foundEntries += childEntries;
|
||||
}
|
||||
|
||||
++foundEntries;
|
||||
|
||||
parentEntry.children.push_back(entry);
|
||||
}
|
||||
} while (FindNextFile(hFind, &ffd) != 0);
|
||||
}
|
||||
|
||||
FindClose(hFind);
|
||||
|
||||
return foundEntries;
|
||||
}
|
||||
#else
|
||||
u32 ScanDirectoryTree(const std::string& _Directory, FSTEntry& parentEntry)
|
||||
{
|
||||
u32 foundEntries = 0;
|
||||
|
||||
struct dirent dirent, *result = NULL;
|
||||
|
||||
// Find the first file in the directory.
|
||||
DIR *dirp = opendir(_Directory.c_str());
|
||||
|
||||
while (!readdir_r(dirp, &dirent, &result) && result) {
|
||||
FSTEntry entry;
|
||||
if (result->d_name[0]=='.') continue;
|
||||
entry.virtualName = result->d_name;
|
||||
entry.physicalName = _Directory + "/" + entry.virtualName;
|
||||
if (IsDirectory(entry.physicalName.c_str())) {
|
||||
entry.isDirectory = true;
|
||||
entry.size = ScanDirectoryTree(entry.physicalName, entry);
|
||||
foundEntries += entry.size;
|
||||
} else {
|
||||
entry.isDirectory = false;
|
||||
entry.size = GetSize(entry.physicalName.c_str());
|
||||
}
|
||||
|
||||
++foundEntries;
|
||||
|
||||
parentEntry.children.push_back(entry);
|
||||
}
|
||||
closedir(dirp);
|
||||
|
||||
return foundEntries;
|
||||
}
|
||||
#endif
|
||||
|
||||
// creates an empty file filename, returns true on success
|
||||
bool CreateEmptyFile(const char *filename)
|
||||
{
|
||||
FILE* pFile = fopen(filename, "wb");
|
||||
if (pFile == NULL)
|
||||
return false;
|
||||
INFO_LOG(COMMON, "CreateEmptyFile: %s", filename);
|
||||
|
||||
FILE *pFile = fopen(filename, "wb");
|
||||
if (!pFile) {
|
||||
ERROR_LOG(COMMON, "CreateEmptyFile: failed %s: %s",
|
||||
filename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
fclose(pFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DeleteDirRecursively(const std::string& _Directory)
|
||||
// Scans the directory tree gets, starting from _Directory and adds the
|
||||
// results into parentEntry. Returns the number of files+directories found
|
||||
u32 ScanDirectoryTree(const char *directory, FSTEntry& parentEntry)
|
||||
{
|
||||
INFO_LOG(COMMON, "ScanDirectoryTree: directory %s", directory);
|
||||
// How many files + directories we found
|
||||
u32 foundEntries = 0;
|
||||
char *virtualName;
|
||||
#ifdef _WIN32
|
||||
|
||||
bool Result = false;
|
||||
|
||||
// Find the first file in the directory.
|
||||
WIN32_FIND_DATA ffd;
|
||||
std::string searchName = _Directory + "\\*";
|
||||
HANDLE hFind = FindFirstFile(searchName.c_str(), &ffd);
|
||||
char searchName[MAX_PATH + 3];
|
||||
strncpy(searchName, directory, MAX_PATH);
|
||||
strcat(searchName, "\\*");
|
||||
|
||||
if (hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
// check for "." and ".."
|
||||
if (((ffd.cFileName[0] == '.') && (ffd.cFileName[1] == 0x00)) ||
|
||||
((ffd.cFileName[0] == '.') && (ffd.cFileName[1] == '.') && (ffd.cFileName[2] == 0x00)))
|
||||
continue;
|
||||
|
||||
// build path
|
||||
std::string newPath(_Directory);
|
||||
newPath += '\\';
|
||||
newPath += ffd.cFileName;
|
||||
|
||||
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
if (!File::DeleteDirRecursively(newPath))
|
||||
goto error_jmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!File::Delete(newPath.c_str()))
|
||||
goto error_jmp;
|
||||
}
|
||||
|
||||
} while (FindNextFile(hFind, &ffd) != 0);
|
||||
HANDLE hFind = FindFirstFile(searchName, &ffd);
|
||||
if (hFind == INVALID_HANDLE_VALUE) {
|
||||
FindClose(hFind);
|
||||
return foundEntries;
|
||||
}
|
||||
|
||||
if (!File::DeleteDir(_Directory.c_str()))
|
||||
goto error_jmp;
|
||||
|
||||
Result = true;
|
||||
|
||||
error_jmp:
|
||||
|
||||
FindClose(hFind);
|
||||
|
||||
return Result;
|
||||
// windows loop
|
||||
do {
|
||||
FSTEntry entry;
|
||||
virtualName = ffd.cFileName;
|
||||
#else
|
||||
// taken from http://www.dreamincode.net/code/snippet2700.htm
|
||||
DIR *pdir = NULL;
|
||||
pdir = opendir (_Directory.c_str());
|
||||
struct dirent *pent = NULL;
|
||||
|
||||
if (pdir == NULL) {
|
||||
return false;
|
||||
}
|
||||
struct dirent dirent, *result = NULL;
|
||||
|
||||
DIR *dirp = opendir(directory);
|
||||
if (!dirp)
|
||||
return 0;
|
||||
|
||||
char file[256];
|
||||
|
||||
int counter = 1;
|
||||
|
||||
while ((pent = readdir(pdir))) {
|
||||
if (counter > 2) {
|
||||
for (int i = 0; i < 256; i++) file[i] = '\0';
|
||||
strcat(file, _Directory.c_str());
|
||||
if (pent == NULL) {
|
||||
return false;
|
||||
}
|
||||
strcat(file, pent->d_name);
|
||||
if (IsDirectory(file) == true) {
|
||||
DeleteDir(file);
|
||||
} else {
|
||||
remove(file);
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
|
||||
return DeleteDir(_Directory.c_str());
|
||||
// non windows loop
|
||||
while (!readdir_r(dirp, &dirent, &result) && result) {
|
||||
FSTEntry entry;
|
||||
virtualName = result->d_name;
|
||||
#endif
|
||||
// check for "." and ".."
|
||||
if (((virtualName[0] == '.') && (virtualName[1] == '\0')) ||
|
||||
((virtualName[0] == '.') && (virtualName[1] == '.') &&
|
||||
(virtualName[2] == '\0')))
|
||||
continue;
|
||||
entry.virtualName = virtualName;
|
||||
entry.physicalName = directory;
|
||||
entry.physicalName += DIR_SEP + entry.virtualName;
|
||||
|
||||
if (IsDirectory(entry.physicalName.c_str())) {
|
||||
entry.isDirectory = true;
|
||||
// is a directory, lets go inside
|
||||
entry.size = ScanDirectoryTree(entry.physicalName.c_str(), entry);
|
||||
foundEntries += (u32)entry.size;
|
||||
} else { // is a file
|
||||
entry.isDirectory = false;
|
||||
entry.size = GetSize(entry.physicalName.c_str());
|
||||
}
|
||||
++foundEntries;
|
||||
// Push into the tree
|
||||
parentEntry.children.push_back(entry);
|
||||
#ifdef _WIN32
|
||||
} while (FindNextFile(hFind, &ffd) != 0);
|
||||
FindClose(hFind);
|
||||
#else
|
||||
}
|
||||
closedir(dirp);
|
||||
#endif
|
||||
// Return number of entries found.
|
||||
return foundEntries;
|
||||
}
|
||||
|
||||
void GetCurrentDirectory(std::string& _rDirectory)
|
||||
|
||||
// deletes the given directory and anything under it. Returns true on
|
||||
// success.
|
||||
bool DeleteDirRecursively(const char *directory)
|
||||
{
|
||||
char tmpBuffer[MAX_PATH+1];
|
||||
_rDirectory = getcwd(tmpBuffer, MAX_PATH);
|
||||
INFO_LOG(COMMON, "DeleteDirRecursively: %s", directory);
|
||||
#ifdef _WIN32
|
||||
// Find the first file in the directory.
|
||||
WIN32_FIND_DATA ffd;
|
||||
char searchName[MAX_PATH + 3] = {0};
|
||||
|
||||
strncpy(searchName, directory, MAX_PATH);
|
||||
strcat(searchName, "\\*");
|
||||
|
||||
HANDLE hFind = FindFirstFile(searchName, &ffd);
|
||||
|
||||
if (hFind == INVALID_HANDLE_VALUE) {
|
||||
FindClose(hFind);
|
||||
return false;
|
||||
}
|
||||
|
||||
// windows loop
|
||||
do {
|
||||
char *virtualName = ffd.cFileName;
|
||||
#else
|
||||
struct dirent dirent, *result = NULL;
|
||||
DIR *dirp = opendir(directory);
|
||||
if (!dirp)
|
||||
return false;
|
||||
|
||||
// non windows loop
|
||||
while (!readdir_r(dirp, &dirent, &result) && result) {
|
||||
char *virtualName = result->d_name;
|
||||
#endif
|
||||
|
||||
// check for "." and ".."
|
||||
if (((virtualName[0] == '.') && (virtualName[1] == '\0')) ||
|
||||
((virtualName[0] == '.') && (virtualName[1] == '.') &&
|
||||
(virtualName[2] == '\0')))
|
||||
continue;
|
||||
|
||||
char newPath[MAX_PATH];
|
||||
sprintf(newPath, "%s%c%s", directory, DIR_SEP_CHR, virtualName);
|
||||
if (IsDirectory(newPath)) {
|
||||
if (!DeleteDirRecursively(newPath))
|
||||
return false;
|
||||
} else {
|
||||
if (!File::Delete(newPath))
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
} while (FindNextFile(hFind, &ffd) != 0);
|
||||
FindClose(hFind);
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
File::DeleteDir(directory);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetCurrentDirectory(const std::string& _rDirectory)
|
||||
// Returns the current directory, caller should free
|
||||
const char *GetCurrentDirectory()
|
||||
{
|
||||
return chdir(_rDirectory.c_str()) == 0;
|
||||
const char *dir;
|
||||
// Get the current working directory (getcwd uses malloc)
|
||||
if (!(dir = getcwd(NULL, 0))) {
|
||||
|
||||
ERROR_LOG(COMMON, "GetCurrentDirectory failed: %s",
|
||||
GetLastErrorMsg());
|
||||
return NULL;
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
// Sets the current directory to the given directory
|
||||
bool SetCurrentDirectory(const char *_rDirectory)
|
||||
{
|
||||
return chdir(_rDirectory) == 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -20,45 +20,73 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <string.h>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
/*
|
||||
This namespace has various generic functions related to files and paths.
|
||||
*/
|
||||
namespace File
|
||||
{
|
||||
|
||||
|
||||
// FileSystem tree node/
|
||||
struct FSTEntry
|
||||
{
|
||||
bool isDirectory;
|
||||
u32 size; // file length or number of entries from children
|
||||
u64 size; // file length or number of entries from children
|
||||
std::string physicalName; // name on disk
|
||||
std::string virtualName; // name in FST names table
|
||||
std::vector<FSTEntry> children;
|
||||
};
|
||||
|
||||
std::string SanitizePath(const char *filename);
|
||||
|
||||
// Returns true if file filename exists
|
||||
bool Exists(const char *filename);
|
||||
|
||||
// Returns true if filename is a directory
|
||||
bool IsDirectory(const char *filename);
|
||||
bool IsDisk(const char *filename);
|
||||
bool CreateDir(const char *filename);
|
||||
bool CreateDirectoryStructure(const std::string& _rFullPath);
|
||||
bool Delete(const char *filename);
|
||||
bool DeleteDir(const char *filename);
|
||||
bool Rename(const char *srcFilename, const char *destFilename);
|
||||
bool Copy(const char *srcFilename, const char *destFilename);
|
||||
|
||||
// Returns the size of filename (64bit)
|
||||
u64 GetSize(const char *filename);
|
||||
std::string GetUserDirectory();
|
||||
|
||||
// Returns true if successful, or path already exists.
|
||||
bool CreateDir(const char *filename);
|
||||
|
||||
// Creates the full path of fullPath returns true on success
|
||||
bool CreateFullPath(const char *fullPath);
|
||||
|
||||
// Deletes a given filename, return true on success
|
||||
// Doesn't supports deleting a directory
|
||||
bool Delete(const char *filename);
|
||||
|
||||
// Deletes a directory filename, returns true on success
|
||||
bool DeleteDir(const char *filename);
|
||||
|
||||
// renames file srcFilename to destFilename, returns true on success
|
||||
bool Rename(const char *srcFilename, const char *destFilename);
|
||||
|
||||
// copies file srcFilename to destFilename, returns true on success
|
||||
bool Copy(const char *srcFilename, const char *destFilename);
|
||||
|
||||
// creates an empty file filename, returns true on success
|
||||
bool CreateEmptyFile(const char *filename);
|
||||
|
||||
u32 ScanDirectoryTree(const std::string& _Directory, FSTEntry& parentEntry);
|
||||
|
||||
bool DeleteDirRecursively(const std::string& _Directory);
|
||||
void GetCurrentDirectory(std::string& _rDirectory);
|
||||
bool SetCurrentDirectory(const std::string& _rDirectory);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
std::string GetPluginsDirectory();
|
||||
#endif
|
||||
|
||||
|
||||
// Scans the directory tree gets, starting from _Directory and adds the
|
||||
// results into parentEntry. Returns the number of files+directories found
|
||||
u32 ScanDirectoryTree(const char *directory, FSTEntry& parentEntry);
|
||||
|
||||
// deletes the given directory and anything under it. Returns true on success.
|
||||
bool DeleteDirRecursively(const char *directory);
|
||||
|
||||
// Returns the current directory, caller should free
|
||||
const char *GetCurrentDirectory();
|
||||
|
||||
// Set the current directory to given directory
|
||||
bool SetCurrentDirectory(const char *directory);
|
||||
|
||||
// Returns a pointer to a string with the dolphin data dir
|
||||
const char *GetUserDirectory();
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _HASH_H
|
||||
#define _HASH_H
|
||||
|
||||
@ -24,5 +25,4 @@ u32 HashAdler32(const u8* data, size_t len); // Fairly accurate, slightl
|
||||
u32 HashFNV(const u8* ptr, int length); // Another fast and decent hash
|
||||
u32 HashEctor(const u8* ptr, int length); // JUNK. DO NOT USE FOR NEW THINGS
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -459,10 +459,10 @@ bool IniFile::Get(const char* sectionName, const char* key, std::vector<std::str
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 subEnd;
|
||||
|
||||
// ignore starting , if any
|
||||
u32 subStart = temp.find_first_not_of(",");
|
||||
size_t subStart = temp.find_first_not_of(",");
|
||||
size_t subEnd;
|
||||
|
||||
// split by ,
|
||||
while (subStart != std::string::npos) {
|
||||
|
147
Source/Core/Common/Src/Log.h
Normal file
147
Source/Core/Common/Src/Log.h
Normal file
@ -0,0 +1,147 @@
|
||||
// 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 _LOG_H
|
||||
#define _LOG_H
|
||||
|
||||
namespace LogTypes
|
||||
{
|
||||
|
||||
enum LOG_TYPE {
|
||||
ACTIONREPLAY,
|
||||
AUDIO,
|
||||
AUDIO_INTERFACE,
|
||||
BOOT,
|
||||
COMMANDPROCESSOR,
|
||||
COMMON,
|
||||
CONSOLE,
|
||||
DSPHLE,
|
||||
DSPINTERFACE,
|
||||
DVDINTERFACE,
|
||||
DYNA_REC,
|
||||
EXPANSIONINTERFACE,
|
||||
GEKKO,
|
||||
GPFIFO,
|
||||
HLE,
|
||||
MASTER_LOG,
|
||||
MEMMAP,
|
||||
OSREPORT,
|
||||
PERIPHERALINTERFACE,
|
||||
PIXELENGINE,
|
||||
SERIALINTERFACE,
|
||||
STREAMINGINTERFACE,
|
||||
VIDEO,
|
||||
VIDEOINTERFACE,
|
||||
WII_IOB,
|
||||
WII_IPC,
|
||||
WII_IPC_DVD,
|
||||
WII_IPC_ES,
|
||||
WII_IPC_FILEIO,
|
||||
WII_IPC_HLE,
|
||||
WII_IPC_NET,
|
||||
WII_IPC_SD,
|
||||
WII_IPC_WIIMOTE,
|
||||
|
||||
NUMBER_OF_LOGS // Must be last
|
||||
};
|
||||
|
||||
enum LOG_LEVELS {
|
||||
LERROR, // Bad errors - that still don't deserve a PanicAlert.
|
||||
LWARNING, // Something is suspicious.
|
||||
LINFO, // General information.
|
||||
LDEBUG, // Strictly for detailed debugging - might make things slow.
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#ifdef LOGGING
|
||||
|
||||
extern void __Log(int logNumber, const char* text, ...);
|
||||
extern void __Logv(int log, int v, const char *format, ...);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define LOG(t, ...) __Log(LogTypes::t, __VA_ARGS__);
|
||||
#define LOGV(t, v, ...) __Log(LogTypes::t + (v)*100, __VA_ARGS__);
|
||||
#define LOGP(t, ...) __Log(t, __VA_ARGS__);
|
||||
#define LOGVP(t, v, ...) __Log(t + (v)*100, __VA_ARGS__);
|
||||
#define ERROR_LOG(t, ...) {LOGV(t, LogTypes::LERROR, __VA_ARGS__)}
|
||||
#define WARN_LOG(t, ...) {LOGV(t, LogTypes::LINFO, __VA_ARGS__)}
|
||||
#define INFO_LOG(t, ...) {LOGV(t, LogTypes::LWARNING, __VA_ARGS__)}
|
||||
#define DEBUG_LOG(t ,...) {LOGV(t, LogTypes::LDEBUG, __VA_ARGS__)}
|
||||
|
||||
#else
|
||||
|
||||
#define LOG(t, ...) __Log(LogTypes::t, ##__VA_ARGS__);
|
||||
#define LOGV(t,v, ...) __Log(LogTypes::t + (v)*100, ##__VA_ARGS__);
|
||||
#define LOGP(t, ...) __Log(t, ##__VA_ARGS__);
|
||||
#define LOGVP(t,v, ...) __Log(t + (v)*100, ##__VA_ARGS__);
|
||||
#define ERROR_LOG(t,...) {LOGV(t, LogTypes::LERROR, ##__VA_ARGS__)}
|
||||
#define WARN_LOG(t,...) {LOGV(t, LogTypes::LINFO, ##__VA_ARGS__)}
|
||||
#define INFO_LOG(t,...) {LOGV(t, LogTypes::LWARNING, ##__VA_ARGS__)}
|
||||
#define DEBUG_LOG(t,...) {LOGV(t, LogTypes::LDEBUG, ##__VA_ARGS__)}
|
||||
|
||||
#endif // WIN32
|
||||
|
||||
#define _dbg_assert_(_t_, _a_) \
|
||||
if (!(_a_)) {\
|
||||
LOG(_t_, "Error...\n\n Line: %d\n File: %s\n Time: %s\n\nIgnore and continue?", \
|
||||
__LINE__, __FILE__, __TIME__); \
|
||||
if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \
|
||||
}
|
||||
#define _dbg_assert_msg_(_t_, _a_, ...)\
|
||||
if (!(_a_)) {\
|
||||
LOG(_t_, __VA_ARGS__); \
|
||||
if (!PanicYesNo(__VA_ARGS__)) {Crash();} \
|
||||
}
|
||||
#define _dbg_update_() Host_UpdateLogDisplay();
|
||||
|
||||
#else
|
||||
|
||||
#define LOG(_t_, ...)
|
||||
#define LOGV(_t_, _v_, ...)
|
||||
#define LOGP(_t_, ...)
|
||||
#define LOGVP(_t_, _v_, ...)
|
||||
|
||||
#define _dbg_clear_()
|
||||
#define _dbg_update_() ;
|
||||
|
||||
#ifndef _dbg_assert_
|
||||
#define _dbg_assert_(_t_, _a_) ;
|
||||
#define _dbg_assert_msg_(_t_, _a_, _desc_, ...) ;
|
||||
#endif
|
||||
|
||||
#define ERROR_LOG(t, ...) ;
|
||||
#define WARN_LOG(t, ...) ;
|
||||
#define INFO_LOG(t ,...) ;
|
||||
#define DEBUG_LOG(t, ...) ;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _assert_(_a_) _dbg_assert_(MASTER_LOG, _a_)
|
||||
#define _assert_msg_(_t_, _a_, _fmt_, ...)\
|
||||
if (!(_a_)) {\
|
||||
if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \
|
||||
}
|
||||
#else
|
||||
#define _assert_(a)
|
||||
#define _assert_msg_(...)
|
||||
#endif
|
||||
|
||||
#endif // LOG_H
|
50
Source/Core/Common/Src/Misc.cpp
Normal file
50
Source/Core/Common/Src/Misc.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
// 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 "Common.h"
|
||||
|
||||
// Generic function to get last error message.
|
||||
// Call directly after the command or use the error num.
|
||||
// This function might change the error code.
|
||||
const char *GetLastErrorMsg()
|
||||
{
|
||||
// FIXME : not thread safe.
|
||||
// Caused by sloppy use in logging in FileUtil.cpp, primarily. What to do, what to do ...
|
||||
static char errStr[255] = {0};
|
||||
#ifdef _WIN32
|
||||
DWORD dw = GetLastError();
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) errStr, 254, NULL );
|
||||
#else
|
||||
// Thread safe (XSI-compliant)
|
||||
strerror_r(errno, errStr, 255);
|
||||
#endif
|
||||
return errStr;
|
||||
}
|
||||
|
||||
char *strndup (char const *s, size_t n)
|
||||
{
|
||||
size_t len = strnlen(s, n);
|
||||
char *dup = (char *)malloc(len + 1);
|
||||
|
||||
if (dup == NULL)
|
||||
return NULL;
|
||||
|
||||
dup[len] = '\0';
|
||||
return (char *)memcpy(dup, s, len);
|
||||
}
|
45
Source/Core/Common/Src/MsgHandler.h
Normal file
45
Source/Core/Common/Src/MsgHandler.h
Normal file
@ -0,0 +1,45 @@
|
||||
// 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 MSGHANDLER_H
|
||||
#define MSGHANDLER_H
|
||||
// Message alerts
|
||||
enum MSG_TYPE
|
||||
{
|
||||
INFORMATION,
|
||||
QUESTION,
|
||||
WARNING,
|
||||
};
|
||||
|
||||
typedef bool (*MsgAlertHandler)(const char* caption, const char* text,
|
||||
bool yes_no, int Style);
|
||||
void RegisterMsgAlertHandler(MsgAlertHandler handler);
|
||||
extern bool MsgAlert(const char* caption, bool yes_no, int Style, const char* format, ...);
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SuccessAlert(format, ...) MsgAlert("Information", false, INFORMATION, format, __VA_ARGS__)
|
||||
#define PanicAlert(format, ...) MsgAlert("Warning", false, WARNING, format, __VA_ARGS__)
|
||||
#define PanicYesNo(format, ...) MsgAlert("Warning", true, WARNING, format, __VA_ARGS__)
|
||||
#define AskYesNo(format, ...) MsgAlert("Question", true, QUESTION, format, __VA_ARGS__)
|
||||
#else
|
||||
#define SuccessAlert(format, ...) MsgAlert("SUCCESS", false, INFORMATION, format, ##__VA_ARGS__)
|
||||
#define PanicAlert(format, ...) MsgAlert("PANIC", false, WARNING, format, ##__VA_ARGS__)
|
||||
#define PanicYesNo(format, ...) MsgAlert("PANIC", true, WARNING, format, ##__VA_ARGS__)
|
||||
#define AskYesNo(format, ...) MsgAlert("ASK", true, QUESTION, format, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#endif //MSGHANDLER
|
@ -17,6 +17,7 @@ files = [
|
||||
"FileUtil.cpp",
|
||||
"MappedFile.cpp",
|
||||
"MathUtil.cpp",
|
||||
"Misc.cpp",
|
||||
"MemArena.cpp",
|
||||
"MemoryUtil.cpp",
|
||||
"Plugin.cpp",
|
||||
|
@ -80,10 +80,10 @@ u32 Ascii2Hex(std::string _Text)
|
||||
if (Length > 4)
|
||||
Length = 4;
|
||||
|
||||
for (int i = 0; i < Length; i++)
|
||||
for (int i = 0; i < (int)Length; i++)
|
||||
{
|
||||
// Add up the values, for example RSPE becomes, 0x52000000, then 0x52530000 and so on
|
||||
Result += _Text.c_str()[i] << (Length - 1 - i)*8;
|
||||
Result += _Text.c_str()[i] << ((Length - 1 - i) * 8);
|
||||
}
|
||||
// Return the value
|
||||
return Result;
|
||||
|
Reference in New Issue
Block a user