mirror of https://github.com/yuzu-mirror/yuzu
				
				
				
			deleted gekko's common files
							parent
							
								
									27474060e1
								
							
						
					
					
						commit
						72325bef1d
					
				@ -1,36 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    atomic.h
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-02-11
 | 
			
		||||
 * @brief   Cross-platform atomic operations
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_ATOMIC_H_
 | 
			
		||||
#define COMMON_ATOMIC_H_
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#include "atomic_win32.h"
 | 
			
		||||
#else
 | 
			
		||||
#include "atomic_gcc.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_ATOMIC_H_
 | 
			
		||||
@ -1,72 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    atomic_gcc.h
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-06-28
 | 
			
		||||
 * @brief   Cross-platform atomic operations - GCC
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_ATOMIC_GCC_H_
 | 
			
		||||
#define COMMON_ATOMIC_GCC_H_
 | 
			
		||||
 | 
			
		||||
#include "types.h"
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
inline void AtomicAdd(volatile u32& target, u32 value) {
 | 
			
		||||
    __sync_add_and_fetch(&target, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicAnd(volatile u32& target, u32 value) {
 | 
			
		||||
    __sync_and_and_fetch(&target, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicDecrement(volatile u32& target) {
 | 
			
		||||
    __sync_add_and_fetch(&target, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicIncrement(volatile u32& target) {
 | 
			
		||||
    __sync_add_and_fetch(&target, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline u32 AtomicLoad(volatile u32& src) {
 | 
			
		||||
    return src;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline u32 AtomicLoadAcquire(volatile u32& src) {
 | 
			
		||||
    u32 result = src;
 | 
			
		||||
    __asm__ __volatile__ ( "":::"memory" );
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicOr(volatile u32& target, u32 value) {
 | 
			
		||||
    __sync_or_and_fetch(&target, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicStore(volatile u32& dest, u32 value) {
 | 
			
		||||
    dest = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
 | 
			
		||||
    __sync_lock_test_and_set(&dest, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_ATOMIC_GCC_H_
 | 
			
		||||
@ -1,76 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    atomic_win32.h
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-06-28
 | 
			
		||||
 * @brief   Cross-platform atomic operations - Windows/Visual C++
 | 
			
		||||
 * @remark  Taken from Dolphin Emulator (http://code.google.com/p/dolphin-emu/)
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_ATOMIC_WIN32_H_
 | 
			
		||||
#define COMMON_ATOMIC_WIN32_H_
 | 
			
		||||
 | 
			
		||||
#include "types.h"
 | 
			
		||||
 | 
			
		||||
#include <intrin.h>
 | 
			
		||||
#include <Windows.h>
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
inline void AtomicAdd(volatile u32& target, u32 value) {
 | 
			
		||||
    InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicAnd(volatile u32& target, u32 value) {
 | 
			
		||||
    _InterlockedAnd((volatile LONG*)&target, (LONG)value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicIncrement(volatile u32& target) {
 | 
			
		||||
    InterlockedIncrement((volatile LONG*)&target);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicDecrement(volatile u32& target) {
 | 
			
		||||
    InterlockedDecrement((volatile LONG*)&target);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline u32 AtomicLoad(volatile u32& src) {
 | 
			
		||||
    return src;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline u32 AtomicLoadAcquire(volatile u32& src) {
 | 
			
		||||
    u32 result = src;
 | 
			
		||||
    _ReadBarrier();
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicOr(volatile u32& target, u32 value) {
 | 
			
		||||
    _InterlockedOr((volatile LONG*)&target, (LONG)value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicStore(volatile u32& dest, u32 value) {
 | 
			
		||||
    dest = value;
 | 
			
		||||
}
 | 
			
		||||
inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
 | 
			
		||||
    _WriteBarrier();
 | 
			
		||||
    dest = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_ATOMIC_WIN32_H_
 | 
			
		||||
@ -1,246 +0,0 @@
 | 
			
		||||
/*!
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * \file    common.h
 | 
			
		||||
 * \author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * \date    2012-02-04
 | 
			
		||||
 * \brief   Common header for using the common library
 | 
			
		||||
 *
 | 
			
		||||
 * \section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_COMMON_H_
 | 
			
		||||
#define COMMON_COMMON_H_
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Preprocessor stuff
 | 
			
		||||
 | 
			
		||||
#define GEKKO_QUOTE_INPLACE(x) # x
 | 
			
		||||
#define GEKKO_QUOTE(x) GEKKO_QUOTE_INPLACE(x)
 | 
			
		||||
#define __FILE__LINE__ __FILE__ "(" GEKKO_QUOTE(__LINE__) ") : "
 | 
			
		||||
#define GEKKO_TODO(x) __FILE__LINE__ x "\n"
 | 
			
		||||
 | 
			
		||||
#if EMU_PLATFORM == PLATFORM_WINDOWS
 | 
			
		||||
 | 
			
		||||
// All inline assembly is x86 right now!
 | 
			
		||||
#ifdef EMU_ARCHITECTURE_X86
 | 
			
		||||
#define USE_INLINE_ASM_X86
 | 
			
		||||
#endif // EMU_ARCHITECTURE_X86
 | 
			
		||||
 | 
			
		||||
#pragma warning( disable : 4786 )	//disable the truncated 255 character limit warning for debug identifiers
 | 
			
		||||
 | 
			
		||||
#ifdef LEAK_DETECT
 | 
			
		||||
#define _CRTDBG_MAP_ALLOC
 | 
			
		||||
#define _INC_MALLOC
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <crtdbg.h>
 | 
			
		||||
#endif // LEAK_DETECT
 | 
			
		||||
 | 
			
		||||
#define TODO( x )  message( __FILE__LINE__" TODO :   " #x "\n" )
 | 
			
		||||
#define todo( x )  message( __FILE__LINE__" TODO :   " #x "\n" ) 
 | 
			
		||||
 | 
			
		||||
#endif // PLATFORM_WINDOWS
 | 
			
		||||
 | 
			
		||||
#define E_OK					0
 | 
			
		||||
#define E_ERR					1
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Includes
 | 
			
		||||
#include <xmmintrin.h>
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// C Includes
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <cstdarg>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
#include <csignal>
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// C++ Includes
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// OS-Specific Includes
 | 
			
		||||
#if EMU_PLATFORM == PLATFORM_WINDOWS
 | 
			
		||||
  #include <direct.h>
 | 
			
		||||
  #include <windows.h>
 | 
			
		||||
  #include <commctrl.h>
 | 
			
		||||
  #include <commdlg.h>
 | 
			
		||||
  #include <shlwapi.h>
 | 
			
		||||
  #include <shlobj.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Big Endian bit Access (Bits numbered ascending from leftmost to rightmost)
 | 
			
		||||
#define BIT_0	 0x80000000
 | 
			
		||||
#define BIT_1	 0x40000000
 | 
			
		||||
#define BIT_2	 0x20000000
 | 
			
		||||
#define BIT_3	 0x10000000
 | 
			
		||||
#define BIT_4	 0x8000000
 | 
			
		||||
#define BIT_5	 0x4000000
 | 
			
		||||
#define BIT_6	 0x2000000
 | 
			
		||||
#define BIT_7	 0x1000000
 | 
			
		||||
#define BIT_8	 0x800000
 | 
			
		||||
#define BIT_9	 0x400000
 | 
			
		||||
#define BIT_10 0x200000
 | 
			
		||||
#define BIT_11 0x100000
 | 
			
		||||
#define BIT_12 0x80000
 | 
			
		||||
#define BIT_13 0x40000
 | 
			
		||||
#define BIT_14 0x20000
 | 
			
		||||
#define BIT_15 0x10000
 | 
			
		||||
#define BIT_16 0x8000
 | 
			
		||||
#define BIT_17 0x4000
 | 
			
		||||
#define BIT_18 0x2000
 | 
			
		||||
#define BIT_19 0x1000
 | 
			
		||||
#define BIT_20 0x800
 | 
			
		||||
#define BIT_21 0x400
 | 
			
		||||
#define BIT_22 0x200
 | 
			
		||||
#define BIT_23 0x100
 | 
			
		||||
#define BIT_24 0x80
 | 
			
		||||
#define BIT_25 0x40
 | 
			
		||||
#define BIT_26 0x20
 | 
			
		||||
#define BIT_27 0x10
 | 
			
		||||
#define BIT_28 0x8
 | 
			
		||||
#define BIT_29 0x4
 | 
			
		||||
#define BIT_30 0x2
 | 
			
		||||
#define BIT_31 0x1
 | 
			
		||||
 | 
			
		||||
#define SIGNED_BIT8	 ((u8)	1 << 7)
 | 
			
		||||
#define SIGNED_BIT16 ((u16)	1 << 15)
 | 
			
		||||
#define SIGNED_BIT32 ((u32)	1 << 31)
 | 
			
		||||
#define SIGNED_BIT64 ((u64)	1 << 63)
 | 
			
		||||
 | 
			
		||||
// A macro to disallow the copy constructor and operator= functions
 | 
			
		||||
// This should be used in the private: declarations for a class
 | 
			
		||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
 | 
			
		||||
  TypeName(const TypeName&);               \
 | 
			
		||||
  void operator=(const TypeName&)
 | 
			
		||||
 | 
			
		||||
#ifdef _DEBUG
 | 
			
		||||
	#ifndef _DEBUGSPEED
 | 
			
		||||
		#define DEBUG_EMU
 | 
			
		||||
		#define DEBUG_GX
 | 
			
		||||
	#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_EMU
 | 
			
		||||
#define ASSERT_T(cond,str) if((cond)) printf("#!\tERROR: ASSERTION FAILED: %s !\n", str);
 | 
			
		||||
#define ASSERT_F(cond,str) if(!(cond)) printf("#!\tERROR: ASSERTION FAILED: %s !\n", str);
 | 
			
		||||
#else
 | 
			
		||||
#define ASSERT_T(cond,str)
 | 
			
		||||
#define ASSERT_F(cond,str)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void DisplayError (char * Message, ...);
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#  ifdef LEAK_DETECT
 | 
			
		||||
#    undef malloc
 | 
			
		||||
#    define DEBUG_NEW		new(_NORMAL_BLOCK,__FILE__, __LINE__)
 | 
			
		||||
#    define new DEBUG_NEW
 | 
			
		||||
#    define malloc(s)		_malloc_dbg(s,_NORMAL_BLOCK,__FILE__,__LINE__)
 | 
			
		||||
#    define realloc(p, s)	_realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)
 | 
			
		||||
#    define free(p)			_free_dbg(p, _NORMAL_BLOCK)
 | 
			
		||||
#  endif
 | 
			
		||||
#  define U64(a) a ## ui64
 | 
			
		||||
#  define S64(a) a ## si64
 | 
			
		||||
#else //gcc
 | 
			
		||||
#  define U64(a) a ## ull
 | 
			
		||||
#  define S64(a) a ## sll
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#include "types.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "atomic.h"
 | 
			
		||||
#include "misc_utils.h"
 | 
			
		||||
#include "x86_utils.h"
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
__inline static s16 toSHORT(u16 x)
 | 
			
		||||
{
 | 
			
		||||
	return *(s16*)&x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static f32 toFLOAT(u32 x)
 | 
			
		||||
{
 | 
			
		||||
	return *(f32*)&x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static f32 toFLOATS(s32 x)
 | 
			
		||||
{
 | 
			
		||||
	return *(f32*)&x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static f64 toDOUBLE(u64 x)
 | 
			
		||||
{
 | 
			
		||||
	return *(f64*)&x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef void(*optable)(void);
 | 
			
		||||
typedef	void(EMU_FASTCALL *hwtable)(u32, u32*);
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Fast Macros
 | 
			
		||||
 | 
			
		||||
#define MIN(a,b)	((a)<(b)?(a):(b))
 | 
			
		||||
#define MAX(a,b)	((a)>(b)?(a):(b))
 | 
			
		||||
 | 
			
		||||
#define CLAMP(X,min,max)	(((X) > max) ? max : (((X) < min) ? min : (X)))
 | 
			
		||||
 | 
			
		||||
__inline static u32 BSWAP24(u32 x)
 | 
			
		||||
{	
 | 
			
		||||
	return (((x & 0xff0000) >> 16) | (x & 0xff00) | ((x & 0xff) << 16));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if _MSC_VER > 1200
 | 
			
		||||
 | 
			
		||||
#define BSWAP16(x) _byteswap_ushort(x)
 | 
			
		||||
#define BSWAP32(x) _byteswap_ulong(x)
 | 
			
		||||
#define BSWAP64(x) 	_byteswap_uint64(x)
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
__inline static u16 BSWAP16(u16 x)
 | 
			
		||||
{
 | 
			
		||||
  return ((x)>>8) | ((x)<<8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u32 BSWAP32(u32 x)
 | 
			
		||||
{
 | 
			
		||||
  return (BSWAP16((x)&0xffff)<<16) | (BSWAP16((x)>>16));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u64 BSWAP64(u64 x)
 | 
			
		||||
{
 | 
			
		||||
  return (u64)(((u64)BSWAP32((u32)(x&0xffffffff)))<<32) | (BSWAP32((u32)(x>>32)));
 | 
			
		||||
} 
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_COMMON_H_
 | 
			
		||||
@ -1,118 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    config.cpp
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-02-19
 | 
			
		||||
 * @brief   Emulator configuration class - all config settings stored here
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "xml.h"
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
Config* g_config;
 | 
			
		||||
 | 
			
		||||
Config::Config() {
 | 
			
		||||
    ResolutionType default_res;
 | 
			
		||||
    RendererConfig default_renderer_config;
 | 
			
		||||
 | 
			
		||||
    default_renderer_config.enable_wireframe = false;
 | 
			
		||||
    default_renderer_config.enable_shaders = true;
 | 
			
		||||
    default_renderer_config.enable_texture_dumping = false;
 | 
			
		||||
    default_renderer_config.enable_textures = true;
 | 
			
		||||
    default_renderer_config.anti_aliasing_mode = 0;
 | 
			
		||||
    default_renderer_config.anistropic_filtering_mode = 0;
 | 
			
		||||
 | 
			
		||||
    default_res.width = 640;
 | 
			
		||||
    default_res.height = 480;
 | 
			
		||||
 | 
			
		||||
    set_program_dir("", MAX_PATH);
 | 
			
		||||
    set_enable_multicore(true);
 | 
			
		||||
    set_enable_idle_skipping(false);
 | 
			
		||||
    set_enable_hle(true);
 | 
			
		||||
    set_enable_auto_boot(true);
 | 
			
		||||
    set_enable_cheats(false);
 | 
			
		||||
    set_default_boot_file("", MAX_PATH);
 | 
			
		||||
    memset(dvd_image_paths_, 0, sizeof(dvd_image_paths_));
 | 
			
		||||
    set_enable_show_fps(true);
 | 
			
		||||
    set_enable_dump_opcode0(false);
 | 
			
		||||
    set_enable_pause_on_unknown_opcode(true);
 | 
			
		||||
    set_enable_dump_gcm_reads(false);
 | 
			
		||||
    set_enable_ipl(false);
 | 
			
		||||
    set_powerpc_core(CPU_INTERPRETER);
 | 
			
		||||
    set_powerpc_frequency(486);
 | 
			
		||||
    
 | 
			
		||||
    memset(renderer_config_, 0, sizeof(renderer_config_));
 | 
			
		||||
    set_renderer_config(RENDERER_OPENGL_3, default_renderer_config);
 | 
			
		||||
    set_current_renderer(RENDERER_OPENGL_3);
 | 
			
		||||
 | 
			
		||||
    set_enable_fullscreen(false);
 | 
			
		||||
    set_window_resolution(default_res);
 | 
			
		||||
    set_fullscreen_resolution(default_res);
 | 
			
		||||
 | 
			
		||||
    memset(controller_ports_, 0, sizeof(controller_ports_));
 | 
			
		||||
    memset(mem_slots_, 0, sizeof(mem_slots_));
 | 
			
		||||
 | 
			
		||||
    memset(patches_, 0, sizeof(patches_));
 | 
			
		||||
    memset(cheats_, 0, sizeof(patches_));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Config::~Config() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ConfigManager::ConfigManager() {
 | 
			
		||||
    set_program_dir("", MAX_PATH);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ConfigManager::~ConfigManager() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Reload a game-specific configuration
 | 
			
		||||
 * @param id Game id (to load game specific configuration)
 | 
			
		||||
 */
 | 
			
		||||
void ConfigManager::ReloadGameConfig(const char* id) {
 | 
			
		||||
    char full_filename[MAX_PATH];
 | 
			
		||||
    sprintf(full_filename, "user/games/%s.xml", id);
 | 
			
		||||
    common::LoadXMLConfig(*g_config, full_filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Reload the userconfig file
 | 
			
		||||
void ConfigManager::ReloadUserConfig() {
 | 
			
		||||
    common::LoadXMLConfig(*g_config, "userconf.xml");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Reload the sysconfig file
 | 
			
		||||
void ConfigManager::ReloadSysConfig() {
 | 
			
		||||
    common::LoadXMLConfig(*g_config, "sysconf.xml");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Reload all configurations
 | 
			
		||||
void ConfigManager::ReloadConfig(const char* game_id) {
 | 
			
		||||
    delete g_config;
 | 
			
		||||
	g_config = new Config();
 | 
			
		||||
    g_config->set_program_dir(program_dir_, MAX_PATH);
 | 
			
		||||
    ReloadSysConfig();
 | 
			
		||||
    ReloadUserConfig();
 | 
			
		||||
    ReloadGameConfig(game_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namspace
 | 
			
		||||
@ -1,345 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    config.h
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-02-11
 | 
			
		||||
 * @brief   Emulator configuration class - all config settings stored here
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_CONFIG_H_
 | 
			
		||||
#define COMMON_CONFIG_H_
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
#define MAX_SEARCH_PATHS    16  ///< Maximum paths to search for files in
 | 
			
		||||
 | 
			
		||||
/// If you need more than this... you're just lazy ;-)
 | 
			
		||||
#define MAX_PATCHES_PER_GAME    128 ///< Maximum patches allowed per game
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
/// Class for storing emulator configuration(s)
 | 
			
		||||
class Config {
 | 
			
		||||
public:
 | 
			
		||||
    Config();
 | 
			
		||||
    ~Config();
 | 
			
		||||
 | 
			
		||||
    /// Struct used for defining game-specific patches
 | 
			
		||||
    struct Patch {
 | 
			
		||||
        u32 address;    ///< Address to patch
 | 
			
		||||
        u32 data;       ///< Data to write at the specified address
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Struct used for configuring what is inserted in a memory slot
 | 
			
		||||
    struct MemSlot {
 | 
			
		||||
        u8 device;      ///< Memory slot device (0 - memcard)
 | 
			
		||||
        bool enable;    ///< Enable (plugged in?)
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum Control {
 | 
			
		||||
        BUTTON_A = 0,
 | 
			
		||||
        BUTTON_B,
 | 
			
		||||
        BUTTON_X,
 | 
			
		||||
        BUTTON_Y,
 | 
			
		||||
        TRIGGER_L,
 | 
			
		||||
        TRIGGER_R,
 | 
			
		||||
        BUTTON_Z,
 | 
			
		||||
        BUTTON_START,
 | 
			
		||||
        ANALOG_UP,
 | 
			
		||||
        ANALOG_DOWN,
 | 
			
		||||
        ANALOG_LEFT,
 | 
			
		||||
        ANALOG_RIGHT,
 | 
			
		||||
        C_UP,
 | 
			
		||||
        C_DOWN,
 | 
			
		||||
        C_LEFT,
 | 
			
		||||
        C_RIGHT,
 | 
			
		||||
        DPAD_UP,
 | 
			
		||||
        DPAD_DOWN,
 | 
			
		||||
        DPAD_LEFT,
 | 
			
		||||
        DPAD_RIGHT,
 | 
			
		||||
        NUM_CONTROLS
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Struct used for defining a keyboard configuration for a GameCube controller
 | 
			
		||||
    /// Reads/Writes from/to members should be atomic
 | 
			
		||||
    struct KeyboardController {
 | 
			
		||||
        bool enable;                ///< Is the keyboard configation enabled?
 | 
			
		||||
        int key_code[NUM_CONTROLS];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Struct used for defining a joypad configuration for a GameCube controller
 | 
			
		||||
    /// We'll make another struct in case the user wants seperate joypad config
 | 
			
		||||
    struct JoypadController {
 | 
			
		||||
        bool enable;                ///< Is the joypad configation enabled?
 | 
			
		||||
        int key_code[NUM_CONTROLS];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Struct used for configuring what is inserted in a controller port
 | 
			
		||||
    typedef struct {
 | 
			
		||||
        u8 device;                  ///< Controller port device (0 - controller)
 | 
			
		||||
        bool enable;                ///< Enable (plugged in?)
 | 
			
		||||
        KeyboardController keys;    ///< Keyboard configuration for controller (if used)
 | 
			
		||||
        JoypadController pads;      ///< Joypad configuration for controller (if used)
 | 
			
		||||
    } ControllerPort;
 | 
			
		||||
 | 
			
		||||
    /// Enum for supported CPU types
 | 
			
		||||
    enum CPUCoreType {
 | 
			
		||||
        CPU_NULL = 0,       ///< No CPU core
 | 
			
		||||
        CPU_INTERPRETER,    ///< Interpreter CPU core
 | 
			
		||||
        CPU_DYNAREC,        ///< Dynamic recompiler CPU core
 | 
			
		||||
        NUMBER_OF_CPU_CONFIGS
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Struct used for defining a renderer configuration
 | 
			
		||||
    struct RendererConfig {
 | 
			
		||||
        bool enable_wireframe;
 | 
			
		||||
        bool enable_shaders;
 | 
			
		||||
        bool enable_texture_dumping;
 | 
			
		||||
        bool enable_textures;
 | 
			
		||||
        int anti_aliasing_mode;
 | 
			
		||||
        int anistropic_filtering_mode;
 | 
			
		||||
    } ;
 | 
			
		||||
 | 
			
		||||
    /// Struct used for configuring a screen resolution
 | 
			
		||||
    struct ResolutionType {
 | 
			
		||||
        int width;
 | 
			
		||||
        int height;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Enum for supported video cores
 | 
			
		||||
    enum RendererType {
 | 
			
		||||
        RENDERER_NULL,          ///< No video core
 | 
			
		||||
        RENDERER_OPENGL_2,      ///< OpenGL 2.0 core
 | 
			
		||||
        RENDERER_OPENGL_3,      ///< OpenGL 3.0 core (not implemented)
 | 
			
		||||
        RENDERER_DIRECTX9,      ///< DirectX9 core (not implemented)
 | 
			
		||||
        RENDERER_DIRECTX10,     ///< DirectX10 core (not implemented)
 | 
			
		||||
        RENDERER_DIRECTX11,     ///< DirectX11 core (not implemented)
 | 
			
		||||
        RENDERER_SOFTWARE,      ///< Software  core (not implemented)
 | 
			
		||||
        RENDERER_HARDWARE,      ///< Hardware core (not implemented- this would be a driver)
 | 
			
		||||
        NUMBER_OF_VIDEO_CONFIGS
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    char* program_dir() { return program_dir_; }
 | 
			
		||||
    void set_program_dir(const char* val, size_t size) { strcpy(program_dir_, val); }
 | 
			
		||||
 | 
			
		||||
    bool enable_multicore() { return enable_multicore_; }
 | 
			
		||||
    bool enable_idle_skipping() {return enable_idle_skipping_; }
 | 
			
		||||
    bool enable_hle() { return enable_hle_; }
 | 
			
		||||
    bool enable_auto_boot() { return enable_auto_boot_; }
 | 
			
		||||
    bool enable_cheats() { return enable_cheats_; }
 | 
			
		||||
    void set_enable_multicore(bool val) { enable_multicore_ = val; }
 | 
			
		||||
    void set_enable_idle_skipping(bool val) {enable_idle_skipping_ = val; }
 | 
			
		||||
    void set_enable_hle(bool val) { enable_hle_ = val; }
 | 
			
		||||
    void set_enable_auto_boot(bool val) { enable_auto_boot_ = val; }
 | 
			
		||||
    void set_enable_cheats(bool val) { enable_cheats_ = val; }
 | 
			
		||||
 | 
			
		||||
    char* default_boot_file() { return default_boot_file_; }
 | 
			
		||||
    char* dvd_image_path(int path) { return dvd_image_paths_[path]; }
 | 
			
		||||
    void set_default_boot_file(const char* val, size_t size) { strcpy(default_boot_file_, val); }
 | 
			
		||||
    void set_dvd_image_path(int path, char* val, size_t size) { strcpy(dvd_image_paths_[path], val); }
 | 
			
		||||
 | 
			
		||||
    bool enable_show_fps() { return enable_show_fps_; }
 | 
			
		||||
    bool enable_dump_opcode0() { return enable_dump_opcode0_; }
 | 
			
		||||
    bool enable_pause_on_unknown_opcode() { return enable_pause_on_unknown_opcode_; }
 | 
			
		||||
    bool enable_dump_gcm_reads() { return enable_dump_gcm_reads_; }
 | 
			
		||||
    void set_enable_show_fps(bool val) { enable_show_fps_ = val; }
 | 
			
		||||
    void set_enable_dump_opcode0(bool val) { enable_dump_opcode0_ = val; }
 | 
			
		||||
    void set_enable_pause_on_unknown_opcode(bool val) { enable_pause_on_unknown_opcode_ = val; }
 | 
			
		||||
    void set_enable_dump_gcm_reads(bool val) { enable_dump_gcm_reads_ = val; }
 | 
			
		||||
 | 
			
		||||
    bool enable_ipl() { return enable_ipl_; }
 | 
			
		||||
    void set_enable_ipl(bool val) { enable_ipl_ = val; }
 | 
			
		||||
 | 
			
		||||
    Patch patches(int patch) { return patches_[patch]; }
 | 
			
		||||
    Patch cheats(int cheat) { return cheats_[cheat]; }
 | 
			
		||||
    void set_patches(int patch, Patch val) { patches_[patch] = val; }
 | 
			
		||||
    void set_cheats(int cheat, Patch val) { cheats_[cheat] = val; }
 | 
			
		||||
 | 
			
		||||
    CPUCoreType powerpc_core() { return powerpc_core_; }
 | 
			
		||||
    void set_powerpc_core(CPUCoreType val) { powerpc_core_ = val; }
 | 
			
		||||
 | 
			
		||||
    int powerpc_frequency() { return powerpc_frequency_; }
 | 
			
		||||
    void set_powerpc_frequency(int val) { powerpc_frequency_ = val; }
 | 
			
		||||
 | 
			
		||||
    RendererType current_renderer() { return current_renderer_; }
 | 
			
		||||
    void set_current_renderer(RendererType val) { current_renderer_ = val; }
 | 
			
		||||
 | 
			
		||||
    RendererConfig renderer_config(RendererType val) { return renderer_config_[val]; }
 | 
			
		||||
    RendererConfig current_renderer_config() { return renderer_config_[current_renderer_]; }
 | 
			
		||||
    void set_renderer_config(RendererType renderer, RendererConfig config) { 
 | 
			
		||||
        renderer_config_[renderer] = config;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool enable_fullscreen() { return enable_fullscreen_; }
 | 
			
		||||
    void set_enable_fullscreen(bool val) { enable_fullscreen_ = val; }
 | 
			
		||||
 | 
			
		||||
    ResolutionType window_resolution() { return window_resolution_; }
 | 
			
		||||
    ResolutionType fullscreen_resolution() { return fullscreen_resolution_; }
 | 
			
		||||
    void set_window_resolution(ResolutionType val) { window_resolution_ = val; }
 | 
			
		||||
    void set_fullscreen_resolution(ResolutionType val) { fullscreen_resolution_ = val; }
 | 
			
		||||
 | 
			
		||||
    // TODO: Should be const, but pending removal of some gekko_qt hacks
 | 
			
		||||
    /*const */ControllerPort& controller_ports(int port) { return controller_ports_[port]; }
 | 
			
		||||
    void set_controller_ports(int port, ControllerPort val) { controller_ports_[port] = val; }
 | 
			
		||||
 | 
			
		||||
    MemSlot mem_slots(int slot) { return mem_slots_[slot]; }
 | 
			
		||||
    void set_mem_slots(int slot, MemSlot val) { mem_slots_[slot] = val; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Gets a RenderType from a string (used from XML)
 | 
			
		||||
     * @param renderer_str Renderer name string, see XML schema for list
 | 
			
		||||
     * @return Corresponding RenderType
 | 
			
		||||
     */
 | 
			
		||||
    static inline RendererType StringToRenderType(const char* renderer_str) {
 | 
			
		||||
        if (E_OK == _stricmp(renderer_str, "opengl2")) {
 | 
			
		||||
            return RENDERER_OPENGL_2;
 | 
			
		||||
        } else if (E_OK == _stricmp(renderer_str, "opengl3")) {
 | 
			
		||||
            return RENDERER_OPENGL_3;
 | 
			
		||||
        } else if (E_OK == _stricmp(renderer_str, "directx9")) {
 | 
			
		||||
            return RENDERER_DIRECTX9;
 | 
			
		||||
        } else if (E_OK == _stricmp(renderer_str, "directx10")) {
 | 
			
		||||
            return RENDERER_DIRECTX10;
 | 
			
		||||
        } else if (E_OK == _stricmp(renderer_str, "directx11")) {
 | 
			
		||||
            return RENDERER_DIRECTX11;
 | 
			
		||||
        } else if (E_OK == _stricmp(renderer_str, "software")) {
 | 
			
		||||
            return RENDERER_SOFTWARE;
 | 
			
		||||
        } else if (E_OK == _stricmp(renderer_str, "hardware")) {
 | 
			
		||||
            return RENDERER_HARDWARE;
 | 
			
		||||
        } else {
 | 
			
		||||
            return RENDERER_NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Gets the renderer string from the type
 | 
			
		||||
     * @param renderer Renderer to get string for
 | 
			
		||||
     * @return Renderer string name
 | 
			
		||||
     */
 | 
			
		||||
    static std::string RenderTypeToString(RendererType renderer) {
 | 
			
		||||
        switch (renderer) {
 | 
			
		||||
        case RENDERER_OPENGL_2:
 | 
			
		||||
            return "opengl2";
 | 
			
		||||
        case RENDERER_OPENGL_3:
 | 
			
		||||
            return "opengl3";
 | 
			
		||||
        case RENDERER_DIRECTX9:
 | 
			
		||||
            return "directx9";
 | 
			
		||||
        case RENDERER_DIRECTX10:
 | 
			
		||||
            return "directx10";
 | 
			
		||||
        case RENDERER_DIRECTX11:
 | 
			
		||||
            return "directx11";
 | 
			
		||||
        case RENDERER_SOFTWARE:
 | 
			
		||||
            return "software";
 | 
			
		||||
        case RENDERER_HARDWARE:
 | 
			
		||||
            return "hardware";
 | 
			
		||||
        }
 | 
			
		||||
        return "null";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Gets the CPU string from the type
 | 
			
		||||
     * @param cpu CPU to get string for
 | 
			
		||||
     * @param cpu_str String result
 | 
			
		||||
     * @param size Max size to write to string
 | 
			
		||||
     */
 | 
			
		||||
    static std::string CPUCoreTypeToString(CPUCoreType cpu) {
 | 
			
		||||
        switch (cpu) {
 | 
			
		||||
        case CPU_INTERPRETER:
 | 
			
		||||
            return "interpreter";
 | 
			
		||||
        case CPU_DYNAREC:
 | 
			
		||||
            return "dynarec";
 | 
			
		||||
        }
 | 
			
		||||
        return "null";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    char program_dir_[MAX_PATH];
 | 
			
		||||
 | 
			
		||||
    bool enable_multicore_;
 | 
			
		||||
    bool enable_idle_skipping_;
 | 
			
		||||
    bool enable_hle_;
 | 
			
		||||
    bool enable_auto_boot_;
 | 
			
		||||
    bool enable_cheats_;
 | 
			
		||||
 | 
			
		||||
    char default_boot_file_[MAX_PATH];
 | 
			
		||||
    char dvd_image_paths_[MAX_SEARCH_PATHS][MAX_PATH];
 | 
			
		||||
 | 
			
		||||
    bool enable_show_fps_;
 | 
			
		||||
    bool enable_dump_opcode0_;
 | 
			
		||||
    bool enable_pause_on_unknown_opcode_;
 | 
			
		||||
    bool enable_dump_gcm_reads_;
 | 
			
		||||
 | 
			
		||||
    bool enable_ipl_;
 | 
			
		||||
 | 
			
		||||
    Patch patches_[MAX_PATCHES_PER_GAME];
 | 
			
		||||
    Patch cheats_[MAX_PATCHES_PER_GAME];
 | 
			
		||||
 | 
			
		||||
    CPUCoreType powerpc_core_;
 | 
			
		||||
 | 
			
		||||
    int powerpc_frequency_;
 | 
			
		||||
 | 
			
		||||
    bool enable_fullscreen_;
 | 
			
		||||
 | 
			
		||||
    RendererType current_renderer_;
 | 
			
		||||
    
 | 
			
		||||
    ResolutionType window_resolution_;
 | 
			
		||||
    ResolutionType fullscreen_resolution_;
 | 
			
		||||
 | 
			
		||||
    RendererConfig renderer_config_[NUMBER_OF_VIDEO_CONFIGS];
 | 
			
		||||
 | 
			
		||||
    MemSlot mem_slots_[2];
 | 
			
		||||
    ControllerPort controller_ports_[4];
 | 
			
		||||
 | 
			
		||||
    DISALLOW_COPY_AND_ASSIGN(Config);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ConfigManager {
 | 
			
		||||
public:
 | 
			
		||||
    ConfigManager();
 | 
			
		||||
    ~ConfigManager();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Reload a game-specific configuration
 | 
			
		||||
     * @param id Game id (to load game specific configuration)
 | 
			
		||||
     */
 | 
			
		||||
    void ReloadGameConfig(const char* id);
 | 
			
		||||
 | 
			
		||||
    /// Reload the userconfig file
 | 
			
		||||
    void ReloadUserConfig();
 | 
			
		||||
 | 
			
		||||
    // Reload the sysconfig file
 | 
			
		||||
    void ReloadSysConfig();
 | 
			
		||||
 | 
			
		||||
    /// Reload all configurations
 | 
			
		||||
    void ReloadConfig(const char* game_id);
 | 
			
		||||
 | 
			
		||||
    char* program_dir() { return program_dir_; }
 | 
			
		||||
 | 
			
		||||
    void set_program_dir(const char* val, size_t size) { strcpy(program_dir_, val); }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    char program_dir_[MAX_PATH]; ///< Program directory, used for loading config files
 | 
			
		||||
 | 
			
		||||
    DISALLOW_COPY_AND_ASSIGN(ConfigManager);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern Config* g_config; ///< Global configuration for emulator
 | 
			
		||||
 | 
			
		||||
} // namspace
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_CONFIG_H_
 | 
			
		||||
@ -1,86 +0,0 @@
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "crc.h"
 | 
			
		||||
 | 
			
		||||
u32	crc32_table[4][256];
 | 
			
		||||
 | 
			
		||||
u32 Reflect(u32 ref, u8 Count)
 | 
			
		||||
{
 | 
			
		||||
     u32 value = 0;
 | 
			
		||||
 | 
			
		||||
      // Swap bit 0 for bit 7
 | 
			
		||||
      // bit 1 for bit 6, etc.
 | 
			
		||||
      for(int i = 1; i < (Count + 1); i++)
 | 
			
		||||
      {
 | 
			
		||||
            if(ref & 1)
 | 
			
		||||
                  value |= 1 << (Count - i);
 | 
			
		||||
            ref >>= 1;
 | 
			
		||||
      }
 | 
			
		||||
      return value; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Init_CRC32_Table()
 | 
			
		||||
{
 | 
			
		||||
    // This is the official polynomial used by CRC-32
 | 
			
		||||
    // in PKZip, WinZip and Ethernet.
 | 
			
		||||
    u32 ulPolynomial = 0x04c11db7;
 | 
			
		||||
 | 
			
		||||
    // 256 values representing ASCII character codes.
 | 
			
		||||
	for(int x = 0; x < 4; x++)
 | 
			
		||||
	{
 | 
			
		||||
		for(int i = 0; i <= 0xFF; i++)
 | 
			
		||||
		{
 | 
			
		||||
			crc32_table[x][i]=Reflect(i, 8) << 24;
 | 
			
		||||
			for (int j = 0; j < 8; j++)
 | 
			
		||||
					crc32_table[x][i] = (crc32_table[x][i] << 1) ^ (crc32_table[x][i] & (1 << 31) ? (ulPolynomial + (x * 8)) : 0);
 | 
			
		||||
			crc32_table[x][i] = Reflect(crc32_table[x][i], 32);
 | 
			
		||||
		} 
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 GenerateCRC(u8 *StartAddr, u32 len)
 | 
			
		||||
{
 | 
			
		||||
	u32  ulCRC = -1;
 | 
			
		||||
 | 
			
		||||
	// Perform the algorithm on each character
 | 
			
		||||
	// in the string, using the lookup table values.
 | 
			
		||||
	for(; len > 7; len-=8)
 | 
			
		||||
	{
 | 
			
		||||
		ulCRC ^= *(u32 *)StartAddr;
 | 
			
		||||
		ulCRC = crc32_table[3][((ulCRC) & 0xFF)] ^
 | 
			
		||||
			    crc32_table[2][((ulCRC >> 8) & 0xFF)] ^
 | 
			
		||||
			    crc32_table[1][((ulCRC >> 16) & 0xFF)] ^
 | 
			
		||||
				crc32_table[0][((ulCRC >> 24))];
 | 
			
		||||
		ulCRC ^= *(u32 *)(StartAddr + 4);
 | 
			
		||||
		ulCRC = crc32_table[3][((ulCRC) & 0xFF)] ^
 | 
			
		||||
			    crc32_table[2][((ulCRC >> 8) & 0xFF)] ^
 | 
			
		||||
			    crc32_table[1][((ulCRC >> 16) & 0xFF)] ^
 | 
			
		||||
				crc32_table[0][((ulCRC >> 24))];
 | 
			
		||||
		StartAddr+=8;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(len > 3)
 | 
			
		||||
	{
 | 
			
		||||
		ulCRC ^= *(u32 *)StartAddr;
 | 
			
		||||
		ulCRC = crc32_table[3][((ulCRC) & 0xFF)] ^
 | 
			
		||||
			    crc32_table[2][((ulCRC >> 8) & 0xFF)] ^
 | 
			
		||||
			    crc32_table[1][((ulCRC >> 16) & 0xFF)] ^
 | 
			
		||||
				crc32_table[0][((ulCRC >> 24))];
 | 
			
		||||
		StartAddr+=4;
 | 
			
		||||
		len -= 4;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch(len)
 | 
			
		||||
	{
 | 
			
		||||
		case 3:
 | 
			
		||||
			ulCRC = crc32_table[0][(ulCRC & 0xFF) ^ *StartAddr] ^ (ulCRC >> 8);
 | 
			
		||||
			StartAddr++;
 | 
			
		||||
		case 2:
 | 
			
		||||
			ulCRC = crc32_table[0][(ulCRC & 0xFF) ^ *StartAddr] ^ (ulCRC >> 8);
 | 
			
		||||
			StartAddr++;
 | 
			
		||||
		case 1:
 | 
			
		||||
			ulCRC = crc32_table[0][(ulCRC & 0xFF) ^ *StartAddr] ^ (ulCRC >> 8);
 | 
			
		||||
			StartAddr++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ulCRC;
 | 
			
		||||
}
 | 
			
		||||
@ -1,81 +0,0 @@
 | 
			
		||||
#ifndef COMMON_CRC_H_
 | 
			
		||||
#define COMMON_CRC_H_
 | 
			
		||||
 | 
			
		||||
#include "types.h"
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
 | 
			
		||||
#define CRC_ROTL(crc) crc32_table[3][((crc) & 0xFF)] ^ crc32_table[2][((crc >> 8) & 0xFF)] ^ \
 | 
			
		||||
        crc32_table[1][((crc >> 16) & 0xFF)] ^ crc32_table[0][((crc >> 24))]
 | 
			
		||||
 | 
			
		||||
// Some definitions for using the X86 CRC32 instruction on different platforms. Keep in mind, you 
 | 
			
		||||
// should check for X86/X64 architecture support before using these, as well as for SSE 4.2 (see the
 | 
			
		||||
// x86_utils module).
 | 
			
		||||
 | 
			
		||||
#if defined(EMU_ARCHITECTURE_X86) || defined(EMU_ARCHITECTURE_X64)
 | 
			
		||||
 | 
			
		||||
#if EMU_PLATFORM == PLATFORM_WINDOWS
 | 
			
		||||
 | 
			
		||||
#include <nmmintrin.h>
 | 
			
		||||
 | 
			
		||||
#ifdef EMU_ARCHITECTURE_X64
 | 
			
		||||
static inline u64 InlineCrc32_U64(u64 crc, u64 value) {
 | 
			
		||||
    return _mm_crc32_u64(crc, value);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
static inline u32 InlineCrc32_U32(u32 crc, u64 value) {
 | 
			
		||||
    return _mm_crc32_u32(crc, static_cast<u32>(value));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u32 InlineCrc32_U8(u32 crc, u8 value) {
 | 
			
		||||
    return _mm_crc32_u8(crc, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#elif GCC_VERSION_AVAILABLE(4, 5) && defined(__SSE4_2__)
 | 
			
		||||
 | 
			
		||||
extern inline unsigned int __attribute__((
 | 
			
		||||
    __gnu_inline__, __always_inline__, __artificial__))
 | 
			
		||||
InlineCrc32_U8(unsigned int __C, unsigned char __V) {
 | 
			
		||||
    return __builtin_ia32_crc32qi(__C, __V);
 | 
			
		||||
}
 | 
			
		||||
#ifdef EMU_ARCHITECTURE_X64
 | 
			
		||||
extern inline unsigned long long __attribute__((
 | 
			
		||||
    __gnu_inline__, __always_inline__, __artificial__))
 | 
			
		||||
InlineCrc32_U64(unsigned long long __C, unsigned long long __V) {
 | 
			
		||||
    return __builtin_ia32_crc32di(__C, __V);
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
extern inline unsigned int __attribute__((
 | 
			
		||||
    __gnu_inline__, __always_inline__, __artificial__))
 | 
			
		||||
InlineCrc32_U32(unsigned int __C, unsigned int __V) {
 | 
			
		||||
    return __builtin_ia32_crc32si (__C, __V);
 | 
			
		||||
}
 | 
			
		||||
#endif  // EMU_ARCHITECTURE_X64
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// GCC 4.4.x and earlier: use inline asm, or msse4.2 flag not set
 | 
			
		||||
 | 
			
		||||
static inline u64 InlineCrc32_U64(u64 crc, u64 value) {
 | 
			
		||||
    asm("crc32q %[value], %[crc]\n" : [crc] "+r" (crc) : [value] "rm" (value));
 | 
			
		||||
    return crc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u32 InlineCrc32_U32(u32 crc, u64 value) {
 | 
			
		||||
    asm("crc32l %[value], %[crc]\n" : [crc] "+r" (crc) : [value] "rm" (value));
 | 
			
		||||
    return crc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u32 InlineCrc32_U8(u32 crc, u8 value) {
 | 
			
		||||
    asm("crc32b %[value], %[crc]\n" : [crc] "+r" (crc) : [value] "rm" (value));
 | 
			
		||||
    return crc;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // EMU_ARCHITECTURE_X86 or EMU_ARCHITECTURE_X64
 | 
			
		||||
 | 
			
		||||
extern u32 crc32_table[4][256];
 | 
			
		||||
 | 
			
		||||
void Init_CRC32_Table();
 | 
			
		||||
u32 GenerateCRC(u8 *StartAddr, u32 Len);
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_CRC_H_
 | 
			
		||||
@ -1,451 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
* Copyright (C) 2005-2013 Gekko Emulator
 | 
			
		||||
*
 | 
			
		||||
* @file    file_utils.cpp
 | 
			
		||||
* @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
* @date    2013-01-27
 | 
			
		||||
* @brief   Crossplatform file utility functions
 | 
			
		||||
* @remark  Borrowed from Dolphin Emulator
 | 
			
		||||
*
 | 
			
		||||
* @section LICENSE
 | 
			
		||||
* 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; either version 2 of
 | 
			
		||||
* the License, or (at your option) any later version.
 | 
			
		||||
*
 | 
			
		||||
* 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 for more details at
 | 
			
		||||
* http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
*
 | 
			
		||||
* Official project repository can be found at:
 | 
			
		||||
* http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "types.h"
 | 
			
		||||
#include "file_utils.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <shlobj.h>		// for SHGetFolderPath
 | 
			
		||||
#include <shellapi.h>
 | 
			
		||||
#include <commdlg.h>	// for GetSaveFileName
 | 
			
		||||
#include <io.h>
 | 
			
		||||
#include <direct.h>		// getcwd
 | 
			
		||||
#else
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__APPLE__)
 | 
			
		||||
#include <CoreFoundation/CFString.h>
 | 
			
		||||
#include <CoreFoundation/CFURL.h>
 | 
			
		||||
#include <CoreFoundation/CFBundle.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#ifndef S_ISDIR
 | 
			
		||||
#define S_ISDIR(m)  (((m)&S_IFMT) == S_IFDIR)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BSD4_4
 | 
			
		||||
#define stat64 stat
 | 
			
		||||
#define fstat64 fstat
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#define __strdup _strdup
 | 
			
		||||
#define __getcwd _getcwd
 | 
			
		||||
#define __chdir _chdir
 | 
			
		||||
 | 
			
		||||
#define fseeko _fseeki64
 | 
			
		||||
#define ftello _ftelli64
 | 
			
		||||
#define atoll _atoi64
 | 
			
		||||
#define stat64 _stat64
 | 
			
		||||
#define fstat64 _fstat64
 | 
			
		||||
#define fileno _fileno
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
#define __strdup strdup
 | 
			
		||||
#define __getcwd getcwd
 | 
			
		||||
#define __chdir chdir
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
// Remove any ending forward slashes from directory paths
 | 
			
		||||
// Modifies argument.
 | 
			
		||||
static void StripTailDirSlashes(std::string &fname) {
 | 
			
		||||
    if (fname.length() > 1)  {
 | 
			
		||||
        size_t i = fname.length() - 1;
 | 
			
		||||
        while (fname[i] == '/') {
 | 
			
		||||
            fname[i--] = '\0';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns true if file filename exists
 | 
			
		||||
bool FileExists(const std::string &filename) {
 | 
			
		||||
    struct stat64 file_info;
 | 
			
		||||
    std::string copy(filename);
 | 
			
		||||
    StripTailDirSlashes(copy);
 | 
			
		||||
    return (stat64(copy.c_str(), &file_info) == 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns true if filename is a directory
 | 
			
		||||
bool IsDirectory(const std::string &filename) {
 | 
			
		||||
    struct stat64 file_info;
 | 
			
		||||
    std::string copy(filename);
 | 
			
		||||
    StripTailDirSlashes(copy);
 | 
			
		||||
    if (stat64(copy.c_str(), &file_info) < 0) {
 | 
			
		||||
        LOG_WARNING(TCOMMON, "IsDirectory: stat failed on %s", filename.c_str());
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return S_ISDIR(file_info.st_mode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Deletes a given filename, return true on success
 | 
			
		||||
// Doesn't supports deleting a directory
 | 
			
		||||
bool DeleteFile(const std::string &filename) {
 | 
			
		||||
    LOG_INFO(TCOMMON, "Delete: file %s", filename.c_str());
 | 
			
		||||
    // Return true because we care about the file no 
 | 
			
		||||
    // being there, not the actual delete.
 | 
			
		||||
    if (!FileExists(filename)) {
 | 
			
		||||
        LOG_WARNING(TCOMMON, "Delete: %s does not exists", filename.c_str());
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    // We can't delete a directory
 | 
			
		||||
    if (IsDirectory(filename)) {
 | 
			
		||||
        LOG_WARNING(TCOMMON, "Delete failed: %s is a directory", filename.c_str());
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    if (!DeleteFile(filename.c_str())) {
 | 
			
		||||
        LOG_WARNING(TCOMMON, "Delete: DeleteFile failed on %s", filename.c_str());
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    if (unlink(filename.c_str()) == -1) {
 | 
			
		||||
        LOG_WARNING(TCOMMON, "Delete: unlink failed on %s", filename.c_str());
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns true if successful, or path already exists.
 | 
			
		||||
bool CreateDir(const std::string &path) {
 | 
			
		||||
    LOG_INFO(TCOMMON, "CreateDir: directory %s", path.c_str());
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    if (::CreateDirectory(path.c_str(), NULL)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    DWORD error = GetLastError();
 | 
			
		||||
    if (error == ERROR_ALREADY_EXISTS)
 | 
			
		||||
    {
 | 
			
		||||
        LOG_WARNING(TCOMMON, "CreateDir: CreateDirectory failed on %s: already exists", path.c_str());
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    LOG_ERROR(TCOMMON, "CreateDir: CreateDirectory failed on %s: %i", path.c_str(), error);
 | 
			
		||||
    return false;
 | 
			
		||||
#else
 | 
			
		||||
    if (mkdir(path.c_str(), 0755) == 0) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    int err = errno;
 | 
			
		||||
    if (err == EEXIST) {
 | 
			
		||||
        LOG_WARNING(TCOMMON, "CreateDir: mkdir failed on %s: already exists", path.c_str());
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    LOG_ERROR(TCOMMON, "CreateDir: mkdir failed on %s: %s", path.c_str(), strerror(err));
 | 
			
		||||
    return false;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Creates the full path of fullPath returns true on success
 | 
			
		||||
bool CreateFullPath(const std::string &fullPath) {
 | 
			
		||||
    int panicCounter = 100;
 | 
			
		||||
    LOG_INFO(TCOMMON, "CreateFullPath: path %s", fullPath.c_str());
 | 
			
		||||
 | 
			
		||||
    if (FileExists(fullPath)) {
 | 
			
		||||
        LOG_INFO(TCOMMON, "CreateFullPath: path exists %s", fullPath.c_str());
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    size_t position = 0;
 | 
			
		||||
    while (1) {
 | 
			
		||||
        // Find next sub path
 | 
			
		||||
        position = fullPath.find('/', position);
 | 
			
		||||
 | 
			
		||||
        // we're done, yay!
 | 
			
		||||
        if (position == fullPath.npos) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        std::string subPath = fullPath.substr(0, position);
 | 
			
		||||
        if (!IsDirectory(subPath)) CreateDir(subPath);
 | 
			
		||||
 | 
			
		||||
        // A safety check
 | 
			
		||||
        panicCounter--;
 | 
			
		||||
        if (panicCounter <= 0) {
 | 
			
		||||
            LOG_ERROR(TCOMMON, "CreateFullPath: directory structure too deep");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        position++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Deletes a directory filename, returns true on success
 | 
			
		||||
bool DeleteDir(const std::string &filename) {
 | 
			
		||||
    LOG_INFO(TCOMMON, "DeleteDir: directory %s", filename.c_str());
 | 
			
		||||
    // check if a directory
 | 
			
		||||
    if (!IsDirectory(filename)) {
 | 
			
		||||
        LOG_ERROR(TCOMMON, "DeleteDir: Not a directory %s", filename.c_str());
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    if (::RemoveDirectory(filename.c_str()))
 | 
			
		||||
        return true;
 | 
			
		||||
#else
 | 
			
		||||
    if (rmdir(filename.c_str()) == 0)
 | 
			
		||||
        return true;
 | 
			
		||||
#endif
 | 
			
		||||
    LOG_ERROR(TCOMMON, "DeleteDir: %s", filename.c_str());
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// renames file srcFilename to destFilename, returns true on success 
 | 
			
		||||
bool RenameFile(const std::string &srcFilename, const std::string &destFilename) {
 | 
			
		||||
    LOG_INFO(TCOMMON, "Rename: %s --> %s", 
 | 
			
		||||
        srcFilename.c_str(), destFilename.c_str());
 | 
			
		||||
    if (rename(srcFilename.c_str(), destFilename.c_str()) == 0)
 | 
			
		||||
        return true;
 | 
			
		||||
    LOG_ERROR(TCOMMON, "Rename: failed %s --> %s", srcFilename.c_str(), destFilename.c_str());
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// copies file srcFilename to destFilename, returns true on success 
 | 
			
		||||
bool CopyFile(const std::string &srcFilename, const std::string &destFilename) {
 | 
			
		||||
    LOG_INFO(TCOMMON, "Copy: %s --> %s", 
 | 
			
		||||
        srcFilename.c_str(), destFilename.c_str());
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    if (::CopyFile(srcFilename.c_str(), destFilename.c_str(), FALSE))
 | 
			
		||||
        return true;
 | 
			
		||||
 | 
			
		||||
    LOG_ERROR(TCOMMON, "Copy: failed %s --> %s", srcFilename.c_str(), destFilename.c_str());
 | 
			
		||||
    return false;
 | 
			
		||||
#else
 | 
			
		||||
    char buffer[1024];
 | 
			
		||||
 | 
			
		||||
    // Open input file
 | 
			
		||||
    FILE *input = fopen(srcFilename.c_str(), "rb");
 | 
			
		||||
    if (!input) {
 | 
			
		||||
        LOG_ERROR(TCOMMON, "Copy: input failed %s --> %s", srcFilename.c_str(), 
 | 
			
		||||
            destFilename.c_str());
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    // open output file
 | 
			
		||||
    FILE *output = fopen(destFilename.c_str(), "wb");
 | 
			
		||||
    if (!output) {
 | 
			
		||||
        fclose(input);
 | 
			
		||||
        LOG_ERROR(TCOMMON, "Copy: output failed %s --> %s", srcFilename.c_str(), 
 | 
			
		||||
            destFilename.c_str());
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    // copy loop
 | 
			
		||||
    while (!feof(input)) {
 | 
			
		||||
        // read input
 | 
			
		||||
        int rnum = fread(buffer, sizeof(char), 1024, input);
 | 
			
		||||
        if (rnum != 1024) {
 | 
			
		||||
            if (ferror(input) != 0) {
 | 
			
		||||
                LOG_ERROR(TCOMMON, "Copy: failed reading from source, %s --> %s", 
 | 
			
		||||
                    srcFilename.c_str(), destFilename.c_str());
 | 
			
		||||
                goto bail;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // write output
 | 
			
		||||
        int wnum = fwrite(buffer, sizeof(char), rnum, output);
 | 
			
		||||
        if (wnum != rnum) {
 | 
			
		||||
            LOG_ERROR(TCOMMON, "Copy: failed writing to output, %s --> %s", 
 | 
			
		||||
                srcFilename.c_str(), destFilename.c_str());
 | 
			
		||||
            goto bail;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // close flushs
 | 
			
		||||
    fclose(input);
 | 
			
		||||
    fclose(output);
 | 
			
		||||
    return true;
 | 
			
		||||
bail:
 | 
			
		||||
    if (input)
 | 
			
		||||
        fclose(input);
 | 
			
		||||
    if (output)
 | 
			
		||||
        fclose(output);
 | 
			
		||||
    return false;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns the size of filename (64bit)
 | 
			
		||||
u64 GetFileSize(const std::string &filename) {
 | 
			
		||||
    if (!FileExists(filename)) {
 | 
			
		||||
        LOG_WARNING(TCOMMON, "GetSize: failed %s: No such file", filename.c_str());
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (IsDirectory(filename)) {
 | 
			
		||||
        LOG_WARNING(TCOMMON, "GetSize: failed %s: is a directory", filename.c_str());
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    struct stat64 buf;
 | 
			
		||||
    if (stat64(filename.c_str(), &buf) == 0) {
 | 
			
		||||
        LOG_DEBUG(TCOMMON, "GetSize: %s: %lld", filename.c_str(), (long long)buf.st_size);
 | 
			
		||||
        return buf.st_size;
 | 
			
		||||
    }
 | 
			
		||||
    LOG_ERROR(TCOMMON, "GetSize: Stat failed %s", filename.c_str());
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Overloaded GetSize, accepts file descriptor
 | 
			
		||||
u64 GetFileSize(const int fd) {
 | 
			
		||||
	struct stat64 buf;
 | 
			
		||||
	if (fstat64(fd, &buf) != 0) {
 | 
			
		||||
		LOG_ERROR(TCOMMON, "GetSize: stat failed %i", fd);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	return buf.st_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Overloaded GetSize, accepts FILE*
 | 
			
		||||
u64 GetFileSize(FILE *f) {
 | 
			
		||||
	// can't use off_t here because it can be 32-bit
 | 
			
		||||
	u64 pos = ftello(f);
 | 
			
		||||
	if (fseeko(f, 0, SEEK_END) != 0) {
 | 
			
		||||
		LOG_ERROR(TCOMMON, "GetSize: seek failed %p", f);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	u64 size = ftello(f);
 | 
			
		||||
	if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) {
 | 
			
		||||
		LOG_ERROR(TCOMMON, "GetSize: seek failed %p", f);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	return size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// creates an empty file filename, returns true on success 
 | 
			
		||||
bool CreateEmptyFile(const std::string &filename) {
 | 
			
		||||
    LOG_INFO(TCOMMON, "CreateEmptyFile: %s", filename.c_str()); 
 | 
			
		||||
 | 
			
		||||
    FILE *pFile = fopen(filename.c_str(), "wb");
 | 
			
		||||
    if (!pFile) {
 | 
			
		||||
        LOG_ERROR(TCOMMON, "CreateEmptyFile: failed %s", filename.c_str());
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    fclose(pFile);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Deletes the given directory and anything under it. Returns true on success.
 | 
			
		||||
bool DeleteDirRecursively(const std::string &directory) {
 | 
			
		||||
    LOG_INFO(TCOMMON, "DeleteDirRecursively: %s", directory.c_str());
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    // Find the first file in the directory.
 | 
			
		||||
    WIN32_FIND_DATA ffd;
 | 
			
		||||
    HANDLE hFind = FindFirstFile((directory + "\\*").c_str(), &ffd);
 | 
			
		||||
 | 
			
		||||
    if (hFind == INVALID_HANDLE_VALUE) {
 | 
			
		||||
        FindClose(hFind);
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // windows loop
 | 
			
		||||
    do {
 | 
			
		||||
        const std::string virtualName = ffd.cFileName;
 | 
			
		||||
#else
 | 
			
		||||
    struct dirent dirent, *result = NULL;
 | 
			
		||||
    DIR *dirp = opendir(directory.c_str());
 | 
			
		||||
    if (!dirp) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    // non windows loop
 | 
			
		||||
    while (!readdir_r(dirp, &dirent, &result) && result) {
 | 
			
		||||
        const std::string virtualName = result->d_name;
 | 
			
		||||
#endif
 | 
			
		||||
        // check for "." and ".."
 | 
			
		||||
        if (((virtualName[0] == '.') && (virtualName[1] == '\0')) ||
 | 
			
		||||
            ((virtualName[0] == '.') && (virtualName[1] == '.') && 
 | 
			
		||||
            (virtualName[2] == '\0'))) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        std::string newPath = directory + '/' + virtualName;
 | 
			
		||||
        if (IsDirectory(newPath)) {
 | 
			
		||||
            if (!DeleteDirRecursively(newPath))
 | 
			
		||||
                return false;
 | 
			
		||||
        } else {
 | 
			
		||||
            if (!DeleteFile(newPath))
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    } while (FindNextFile(hFind, &ffd) != 0);
 | 
			
		||||
    FindClose(hFind);
 | 
			
		||||
#else
 | 
			
		||||
    }
 | 
			
		||||
    closedir(dirp);
 | 
			
		||||
#endif
 | 
			
		||||
    DeleteDir(directory);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns the current directory
 | 
			
		||||
std::string GetCurrentDir() {
 | 
			
		||||
    char *dir;
 | 
			
		||||
    // Get the current working directory (getcwd uses malloc) 
 | 
			
		||||
    if (!(dir = __getcwd(NULL, 0))) {
 | 
			
		||||
 | 
			
		||||
        LOG_ERROR(TCOMMON, "GetCurrentDirectory failed:");
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    std::string strDir = dir;
 | 
			
		||||
    free(dir);
 | 
			
		||||
    return strDir;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sets the current directory to the given directory
 | 
			
		||||
bool SetCurrentDir(const std::string &directory) {
 | 
			
		||||
    return __chdir(directory.c_str()) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool WriteStringToFile(bool text_file, const std::string &str, const char *filename) {
 | 
			
		||||
    FILE *f = fopen(filename, text_file ? "w" : "wb");
 | 
			
		||||
    if (!f) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    size_t len = str.size();
 | 
			
		||||
    if (len != fwrite(str.data(), 1, str.size(), f)) {
 | 
			
		||||
        fclose(f);
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    fclose(f);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ReadFileToString(bool text_file, const char *filename, std::string &str) {
 | 
			
		||||
    FILE *f = fopen(filename, text_file ? "r" : "rb");
 | 
			
		||||
    if (!f) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    size_t len = (size_t)GetFileSize(f);
 | 
			
		||||
    char *buf = new char[len + 1];
 | 
			
		||||
    buf[fread(buf, 1, len, f)] = 0;
 | 
			
		||||
    str = std::string(buf, len);
 | 
			
		||||
    fclose(f);
 | 
			
		||||
    delete [] buf;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
@ -1,90 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
* Copyright (C) 2005-2013 Gekko Emulator
 | 
			
		||||
*
 | 
			
		||||
* @file    file_utils.h
 | 
			
		||||
* @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
* @date    2013-01-27
 | 
			
		||||
* @brief   Crossplatform file utility functions
 | 
			
		||||
* @remark  Borrowed from Dolphin Emulator
 | 
			
		||||
*
 | 
			
		||||
* @section LICENSE
 | 
			
		||||
* 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; either version 2 of
 | 
			
		||||
* the License, or (at your option) any later version.
 | 
			
		||||
*
 | 
			
		||||
* 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 for more details at
 | 
			
		||||
* http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
*
 | 
			
		||||
* Official project repository can be found at:
 | 
			
		||||
* http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_FILE_UTILS_H_
 | 
			
		||||
#define COMMON_FILE_UTILS_H_
 | 
			
		||||
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
// Returns true if file filename exists
 | 
			
		||||
bool FileExists(const std::string &filename);
 | 
			
		||||
 | 
			
		||||
// Returns true if filename is a directory
 | 
			
		||||
bool IsDirectory(const std::string &filename);
 | 
			
		||||
 | 
			
		||||
// Returns the size of filename (64bit)
 | 
			
		||||
u64 GetFileSize(const std::string &filename);
 | 
			
		||||
 | 
			
		||||
// Overloaded GetSize, accepts file descriptor
 | 
			
		||||
u64 GetFileSize(const int fd);
 | 
			
		||||
 | 
			
		||||
// Overloaded GetSize, accepts FILE*
 | 
			
		||||
u64 GetFileSize(FILE *f);
 | 
			
		||||
 | 
			
		||||
// Returns true if successful, or path already exists.
 | 
			
		||||
bool CreateDir(const std::string &filename);
 | 
			
		||||
 | 
			
		||||
// Creates the full path of fullPath returns true on success
 | 
			
		||||
bool CreateFullPath(const std::string &fullPath);
 | 
			
		||||
 | 
			
		||||
// Deletes a given filename, return true on success
 | 
			
		||||
// Doesn't supports deleting a directory
 | 
			
		||||
bool DeleteFile(const std::string &filename);
 | 
			
		||||
 | 
			
		||||
// Deletes a directory filename, returns true on success
 | 
			
		||||
bool DeleteDir(const std::string &filename);
 | 
			
		||||
 | 
			
		||||
// renames file srcFilename to destFilename, returns true on success 
 | 
			
		||||
bool RenameFile(const std::string &srcFilename, const std::string &destFilename);
 | 
			
		||||
 | 
			
		||||
// copies file srcFilename to destFilename, returns true on success 
 | 
			
		||||
bool CopyFile(const std::string &srcFilename, const std::string &destFilename);
 | 
			
		||||
 | 
			
		||||
// creates an empty file filename, returns true on success 
 | 
			
		||||
bool CreateEmptyFile(const std::string &filename);
 | 
			
		||||
 | 
			
		||||
// deletes the given directory and anything under it. Returns true on success.
 | 
			
		||||
bool DeleteDirRecursively(const std::string &directory);
 | 
			
		||||
 | 
			
		||||
// Returns the current directory
 | 
			
		||||
std::string GetCurrentDir();
 | 
			
		||||
 | 
			
		||||
// Set the current directory to given directory
 | 
			
		||||
bool SetCurrentDir(const std::string &directory);
 | 
			
		||||
 | 
			
		||||
bool WriteStringToFile(bool text_file, const std::string &str, const char *filename);
 | 
			
		||||
bool ReadFileToString(bool text_file, const char *filename, std::string &str);
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_FILE_UTILS_H_
 | 
			
		||||
@ -1,241 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    hash.cpp
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-12-05
 | 
			
		||||
 * @brief   General purpose hash function
 | 
			
		||||
 * @remark  Some functions borrowed from Dolphin Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "crc.h"
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
/// Block mix - combine the key bits with the hash bits and scramble everything
 | 
			
		||||
inline void bmix64(u64& h1, u64& h2, u64& k1, u64& k2, u64& c1, u64& c2) {
 | 
			
		||||
    k1 *= c1; 
 | 
			
		||||
    k1  = _rotl64(k1,23); 
 | 
			
		||||
    k1 *= c2;
 | 
			
		||||
    h1 ^= k1;
 | 
			
		||||
    h1 += h2;
 | 
			
		||||
 | 
			
		||||
    h2 = _rotl64(h2,41);
 | 
			
		||||
 | 
			
		||||
    k2 *= c2; 
 | 
			
		||||
    k2  = _rotl64(k2,23);
 | 
			
		||||
    k2 *= c1;
 | 
			
		||||
    h2 ^= k2;
 | 
			
		||||
    h2 += h1;
 | 
			
		||||
 | 
			
		||||
    h1 = h1*3 + 0x52dce729;
 | 
			
		||||
    h2 = h2*3 + 0x38495ab5;
 | 
			
		||||
 | 
			
		||||
    c1 = c1*5 + 0x7b7d159c;
 | 
			
		||||
    c2 = c2*5 + 0x6bce6396;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Finalization mix - avalanches all bits to within 0.05% bias
 | 
			
		||||
inline u64 fmix64(u64 k) {
 | 
			
		||||
    k ^= k >> 33;
 | 
			
		||||
    k *= 0xff51afd7ed558ccd;
 | 
			
		||||
    k ^= k >> 33;
 | 
			
		||||
    k *= 0xc4ceb9fe1a85ec53;
 | 
			
		||||
    k ^= k >> 33;
 | 
			
		||||
    return k;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define ROTL32(x,y)     rotl32(x,y)
 | 
			
		||||
 | 
			
		||||
inline uint32_t fmix ( uint32_t h )
 | 
			
		||||
{
 | 
			
		||||
  h ^= h >> 16;
 | 
			
		||||
  h *= 0x85ebca6b;
 | 
			
		||||
  h ^= h >> 13;
 | 
			
		||||
  h *= 0xc2b2ae35;
 | 
			
		||||
  h ^= h >> 16;
 | 
			
		||||
 | 
			
		||||
  return h;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 __compute_murmur_hash3_32(const u8 *src, int len, u32 samples) {
 | 
			
		||||
    u32 h = len;
 | 
			
		||||
    u32 step = (len >> 2);
 | 
			
		||||
    const u32 *data = (const u32*)src;
 | 
			
		||||
    const u32 *end = data + step;
 | 
			
		||||
    if (samples == 0) {
 | 
			
		||||
        samples = std::max(step, 1u);
 | 
			
		||||
    }
 | 
			
		||||
    step  = step / samples;
 | 
			
		||||
    if(step < 1) { 
 | 
			
		||||
        step = 1;
 | 
			
		||||
    }
 | 
			
		||||
    u32 h1 = 0x2f6af274;
 | 
			
		||||
    const u32 c1 = 0xcc9e2d51;
 | 
			
		||||
    const u32 c2 = 0x1b873593;
 | 
			
		||||
 | 
			
		||||
    while (data < end) {
 | 
			
		||||
        u32 k1 = data[0];
 | 
			
		||||
 | 
			
		||||
        k1 *= c1;
 | 
			
		||||
        k1 = (k1 << 15) | (k1 >> (32 - 15));
 | 
			
		||||
        k1 *= c2;
 | 
			
		||||
 | 
			
		||||
        h1 ^= k1;
 | 
			
		||||
        h1 = (h1 << 15) | (h1 >> (32 - 13)); 
 | 
			
		||||
        h1 = h1*5+0xe6546b64;
 | 
			
		||||
 | 
			
		||||
        data += step;
 | 
			
		||||
    }
 | 
			
		||||
    const u8 * tail = (const u8*)(data);
 | 
			
		||||
 | 
			
		||||
    u32 k1 = 0;
 | 
			
		||||
 | 
			
		||||
    switch(len & 3) {
 | 
			
		||||
    case 3: 
 | 
			
		||||
        k1 ^= tail[2] << 16;
 | 
			
		||||
    case 2: 
 | 
			
		||||
        k1 ^= tail[1] << 8;
 | 
			
		||||
    case 1: 
 | 
			
		||||
        k1 ^= tail[0];
 | 
			
		||||
        k1 *= c1; 
 | 
			
		||||
        k1 = (k1 << 15) | (k1 >> (32 - 15));
 | 
			
		||||
        k1 *= c2; 
 | 
			
		||||
        h1 ^= k1;
 | 
			
		||||
    };
 | 
			
		||||
    h1 ^= len;
 | 
			
		||||
    h1 = fmix(h1);
 | 
			
		||||
 | 
			
		||||
    return h1;
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// MurmurHash is a non-cryptographic hash function suitable for general hash-based lookup
 | 
			
		||||
u64 __compute_murmur_hash3_64(const u8 *src, int len, u32 samples) {
 | 
			
		||||
    const u8 * data = (const u8*)src;
 | 
			
		||||
    const int nblocks = len / 16;
 | 
			
		||||
    u32 step = (len / 8);
 | 
			
		||||
    if(samples == 0) {
 | 
			
		||||
        samples = std::max(step, 1u);
 | 
			
		||||
    }
 | 
			
		||||
    step = step / samples;
 | 
			
		||||
    if(step < 1) {
 | 
			
		||||
        step = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    u64 h1 = 0x9368e53c2f6af274;
 | 
			
		||||
    u64 h2 = 0x586dcd208f7cd3fd;
 | 
			
		||||
 | 
			
		||||
    u64 c1 = 0x87c37b91114253d5;
 | 
			
		||||
    u64 c2 = 0x4cf5ad432745937f;
 | 
			
		||||
 | 
			
		||||
    const u64* blocks = (const u64*)(data);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < nblocks; i+=step) {
 | 
			
		||||
        u64 k1 = blocks[(i * 2) + 0];
 | 
			
		||||
        u64 k2 = blocks[(i * 2) + 1];
 | 
			
		||||
 | 
			
		||||
        bmix64(h1,h2,k1,k2,c1,c2);
 | 
			
		||||
    }
 | 
			
		||||
    const u8* tail = (const u8*)(data + nblocks * 16);
 | 
			
		||||
 | 
			
		||||
    u64 k1 = 0;
 | 
			
		||||
    u64 k2 = 0;
 | 
			
		||||
 | 
			
		||||
    switch (len & 15) {
 | 
			
		||||
    case 15: k2 ^= u64(tail[14]) << 48;
 | 
			
		||||
    case 14: k2 ^= u64(tail[13]) << 40;
 | 
			
		||||
    case 13: k2 ^= u64(tail[12]) << 32;
 | 
			
		||||
    case 12: k2 ^= u64(tail[11]) << 24;
 | 
			
		||||
    case 11: k2 ^= u64(tail[10]) << 16;
 | 
			
		||||
    case 10: k2 ^= u64(tail[ 9]) << 8;
 | 
			
		||||
    case  9: k2 ^= u64(tail[ 8]) << 0;
 | 
			
		||||
 | 
			
		||||
    case  8: k1 ^= u64(tail[ 7]) << 56;
 | 
			
		||||
    case  7: k1 ^= u64(tail[ 6]) << 48;
 | 
			
		||||
    case  6: k1 ^= u64(tail[ 5]) << 40;
 | 
			
		||||
    case  5: k1 ^= u64(tail[ 4]) << 32;
 | 
			
		||||
    case  4: k1 ^= u64(tail[ 3]) << 24;
 | 
			
		||||
    case  3: k1 ^= u64(tail[ 2]) << 16;
 | 
			
		||||
    case  2: k1 ^= u64(tail[ 1]) << 8;
 | 
			
		||||
    case  1: k1 ^= u64(tail[ 0]) << 0;
 | 
			
		||||
             bmix64(h1, h2, k1, k2, c1, c2);
 | 
			
		||||
    };
 | 
			
		||||
    h2 ^= len;
 | 
			
		||||
 | 
			
		||||
    h1 += h2;
 | 
			
		||||
    h2 += h1;
 | 
			
		||||
 | 
			
		||||
    h1 = fmix64(h1);
 | 
			
		||||
    h2 = fmix64(h2);
 | 
			
		||||
 | 
			
		||||
    h1 += h2;
 | 
			
		||||
 | 
			
		||||
    return h1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// CRC32 hash using the SSE4.2 instruction
 | 
			
		||||
u64 __compute_crc32_sse4(const u8 *src, int len, u32 samples) {
 | 
			
		||||
    u32 h = len;
 | 
			
		||||
    u32 step = (len >> 2);
 | 
			
		||||
    const u32 *data = (const u32*)src;
 | 
			
		||||
    const u32 *end = data + step;
 | 
			
		||||
    if (samples == 0) {
 | 
			
		||||
        samples = std::max(step, 1u);
 | 
			
		||||
    }
 | 
			
		||||
    step  = step / samples;
 | 
			
		||||
    if(step < 1) { 
 | 
			
		||||
        step = 1;
 | 
			
		||||
    }
 | 
			
		||||
    while (data < end) {
 | 
			
		||||
        h = InlineCrc32_U32(h, data[0]);
 | 
			
		||||
        data += step;
 | 
			
		||||
    }
 | 
			
		||||
    const u8 *data2 = (const u8*)end;
 | 
			
		||||
    return (u64)InlineCrc32_U32(h, u32(data2[0]));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compute an efficient 64-bit hash (optimized for Intel hardware)
 | 
			
		||||
 * @param src Source data buffer to compute hash for
 | 
			
		||||
 * @param len Length of data buffer to compute hash for
 | 
			
		||||
 * @param samples Number of samples to compute hash for
 | 
			
		||||
 * @remark Borrowed from Dolphin Emulator
 | 
			
		||||
 */
 | 
			
		||||
Hash64 GetHash64(const u8 *src, int len, u32 samples) {
 | 
			
		||||
#if defined(EMU_ARCHITECTURE_X86) || defined(EMU_ARCHITECTURE_X64)
 | 
			
		||||
    // TODO(ShizZy): Move somewhere common so we dont need to instantiate this more than once
 | 
			
		||||
    static X86Utils x86_utils; 
 | 
			
		||||
    if (x86_utils.IsExtensionSupported(X86Utils::kExtensionX86_SSE4_2)) {
 | 
			
		||||
        return __compute_crc32_sse4(src, len, samples);
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
#ifdef EMU_ARCHITECTURE_X64
 | 
			
		||||
        return __compute_murmur_hash3_64(src, len, samples);
 | 
			
		||||
#else
 | 
			
		||||
        return __compute_murmur_hash3_32(src, len, samples);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    return __compute_murmur_hash3_32(src, len, samples);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
@ -1,46 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    hash.h
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-12-05
 | 
			
		||||
 * @brief   General purpose hash function
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_HASH_H_
 | 
			
		||||
#define COMMON_HASH_H_
 | 
			
		||||
 | 
			
		||||
#include "types.h"
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
typedef u64 Hash64;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compute an efficient 64-bit hash (optimized for Intel hardware)
 | 
			
		||||
 * @param src Source data buffer to compute hash for
 | 
			
		||||
 * @param len Length of data buffer to compute hash for
 | 
			
		||||
 * @param samples Number of samples to compute hash for
 | 
			
		||||
 * @remark Borrowed from Dolphin Emulator
 | 
			
		||||
 */
 | 
			
		||||
Hash64 GetHash64(const u8 *src, int len, u32 samples);
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_HASH_H_
 | 
			
		||||
@ -1,116 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    hash_container.h
 | 
			
		||||
 * @author  ShizZy <shizzy@6bit.net>
 | 
			
		||||
 * @date    2012-11-29
 | 
			
		||||
 * @brief   Container object for storing a hash lookup
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_HASH_CONTAINER_H_
 | 
			
		||||
#define COMMON_HASH_CONTAINER_H_
 | 
			
		||||
 | 
			
		||||
#include <map>
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
/// Hash container generic interface - Don't use directly, use a derived class
 | 
			
		||||
template <class HashType, class ValueType> class HashContainer {
 | 
			
		||||
    /**
 | 
			
		||||
     * Add (or update if already exists) a value at the specified hash in the container
 | 
			
		||||
     * @param hash Hash to use
 | 
			
		||||
     * @param value Value to update at given hash in the container
 | 
			
		||||
     */
 | 
			
		||||
    ValueType* Update(HashType hash, ValueType value);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Remove a hash entry in the hash container
 | 
			
		||||
     * @param hash Hash value of entry to remove
 | 
			
		||||
     */
 | 
			
		||||
    void Remove(HashType hash);
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Fetch the value at at the given hash from the hash container
 | 
			
		||||
     * @param hash Hash value of entry to fetch
 | 
			
		||||
     * @return Pointer to value stored at hash location on success (index was found), otherwise NULL
 | 
			
		||||
     */
 | 
			
		||||
    ValueType* FetchFromHash(HashType hash);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Fetch the value at at the given integer index from the hash container
 | 
			
		||||
     * @param hash Hash value of entry to fetch
 | 
			
		||||
     * @return Pointer to value stored at hash location on success (index was found), otherwise NULL
 | 
			
		||||
     */
 | 
			
		||||
    ValueType* FetchFromIndex(int index);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the size of the hash container
 | 
			
		||||
     * @return Number of elements in the hash container
 | 
			
		||||
     */
 | 
			
		||||
    int Size();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Hash container implemented using STL map
 | 
			
		||||
template <class HashType, class ValueType> class HashContainer_STLMap : 
 | 
			
		||||
    public HashContainer<HashType, ValueType> {
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    HashContainer_STLMap() {
 | 
			
		||||
    }
 | 
			
		||||
    ~HashContainer_STLMap() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ValueType* Update(HashType hash, ValueType value) {
 | 
			
		||||
        map_[hash] = value;
 | 
			
		||||
        return &map_[hash];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Remove(HashType hash) {
 | 
			
		||||
        map_.erase(hash);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ValueType* FetchFromHash(HashType hash) {
 | 
			
		||||
        typename std::map<HashType, ValueType>::iterator itr = map_.find(hash);
 | 
			
		||||
        if (itr == map_.end()) {
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
        return &itr->second;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ValueType* FetchFromIndex(int index) {
 | 
			
		||||
	    typename std::map<HashType, ValueType>::iterator itr = map_.begin();
 | 
			
		||||
        int i = 0;
 | 
			
		||||
 	    for (; i < index; ++i) {
 | 
			
		||||
 	        ++itr;
 | 
			
		||||
        }
 | 
			
		||||
        if (i < index) {
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
        return &itr->second;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int Size() {
 | 
			
		||||
        return static_cast<int>(map_.size());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    std::map<HashType, ValueType> map_;
 | 
			
		||||
 | 
			
		||||
    DISALLOW_COPY_AND_ASSIGN(HashContainer_STLMap);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_HASH_CONTAINER_H_
 | 
			
		||||
@ -1,152 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    log.cpp
 | 
			
		||||
 * @author  ShizZy <shizzy@6bit.net>
 | 
			
		||||
 * @date    2012-02-11
 | 
			
		||||
 * @brief   Common logging routines used throughout the project
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "timer.h"
 | 
			
		||||
 | 
			
		||||
namespace logger {
 | 
			
		||||
 | 
			
		||||
LogContainer* g_logs[NUMBER_OF_LOGS]; ///< List of pointers to all logs
 | 
			
		||||
 | 
			
		||||
/// LogContainer constructor
 | 
			
		||||
LogContainer::LogContainer(const char* name, const char* desc, bool enable = false) {
 | 
			
		||||
	strncpy(name_, name, 128);
 | 
			
		||||
	strncpy(desc_, desc, 32);
 | 
			
		||||
	level_ = LWARNING;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Asks the user a yes or no question
 | 
			
		||||
SysUserResponse AskYesNo(const char* fmt, ...) {
 | 
			
		||||
    char    c;
 | 
			
		||||
    va_list arg;
 | 
			
		||||
 | 
			
		||||
    va_start(arg, fmt);
 | 
			
		||||
    printf("\n** Question **\n");
 | 
			
		||||
    vprintf(fmt, arg);
 | 
			
		||||
    va_end(arg);
 | 
			
		||||
 | 
			
		||||
    printf("  Response? (y/n) ");
 | 
			
		||||
    while (1) {
 | 
			
		||||
        c = getchar();
 | 
			
		||||
        if (c == 'y' || c == 'Y') {
 | 
			
		||||
            return SYS_USER_YES;
 | 
			
		||||
        }
 | 
			
		||||
        if (c == 'n' || c == 'N') {
 | 
			
		||||
            return SYS_USER_NO;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return SYS_USER_NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//// Log routine used by everything
 | 
			
		||||
void LogGeneric(LogLevel level, LogType type, const char *file, int line, bool append, const char* fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
    char msg[kMaxMsgLength];
 | 
			
		||||
    static const char level_to_char[8] = "-NECWID";
 | 
			
		||||
    static char last_char = '\n';
 | 
			
		||||
    static LogType last_type;
 | 
			
		||||
    
 | 
			
		||||
    va_list arg;
 | 
			
		||||
    va_start(arg, fmt);
 | 
			
		||||
 | 
			
		||||
    if (type >= NUMBER_OF_LOGS) {
 | 
			
		||||
        LOG_ERROR(TCOMMON, "Unknown logger type %d", type);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Format the log message
 | 
			
		||||
    if (append) {
 | 
			
		||||
        sprintf(msg, "%s", fmt);
 | 
			
		||||
    } else {
 | 
			
		||||
        // char time_str[16];
 | 
			
		||||
        // u32 time_elapsed = common::GetTimeElapsed();
 | 
			
		||||
        // common::TicksToFormattedString(time_elapsed, time_str);
 | 
			
		||||
        sprintf(msg, "%c[%s] %s", level_to_char[(int)level], g_logs[type]->name(), fmt);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If the last message didn't have a line break, print one
 | 
			
		||||
    if ('\n' != last_char && '\r' != last_char && !append && last_type != TOS_REPORT && 
 | 
			
		||||
        last_type != TOS_HLE) {
 | 
			
		||||
        printf("\n");
 | 
			
		||||
    }
 | 
			
		||||
    last_char = msg[strlen(msg)-1];
 | 
			
		||||
    last_type = type;
 | 
			
		||||
 | 
			
		||||
    // Print the log message to stdout
 | 
			
		||||
    vprintf(msg, arg);
 | 
			
		||||
    va_end(arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Forces a controlled system crash rather before it catches fire (debug)
 | 
			
		||||
void Crash() {
 | 
			
		||||
    LOG_CRASH(TCOMMON, "*** SYSTEM CRASHED ***\n");
 | 
			
		||||
    LOG_CRASH(TCOMMON, "Fatal error, system could not recover.\n");
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#ifdef USE_INLINE_ASM_X86
 | 
			
		||||
    __asm int 3
 | 
			
		||||
#endif
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
    asm("int $3");
 | 
			
		||||
#else
 | 
			
		||||
    LOG_CRASH(TCOMMON, "Exiting...\n");
 | 
			
		||||
    exit(0);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Initialize the logging system
 | 
			
		||||
void Init() {
 | 
			
		||||
    g_logs[TNULL]       = new LogContainer("NULL",      "Null");
 | 
			
		||||
    g_logs[TAI]         = new LogContainer("AI",        "AudioInterface");
 | 
			
		||||
    g_logs[TBOOT]       = new LogContainer("BOOT",      "Boot");
 | 
			
		||||
    g_logs[TCOMMON]     = new LogContainer("COMMON",    "Common");
 | 
			
		||||
    g_logs[TCONFIG]     = new LogContainer("CONFIG",    "Configuration");
 | 
			
		||||
    g_logs[TCORE]       = new LogContainer("CORE",      "SysCore");
 | 
			
		||||
    g_logs[TCP]         = new LogContainer("CP",        "CommandProcessor");
 | 
			
		||||
    g_logs[TDI]         = new LogContainer("DI",        "DVDInterface");
 | 
			
		||||
    g_logs[TDSP]        = new LogContainer("DSP",       "DSP");
 | 
			
		||||
    g_logs[TDVD]        = new LogContainer("DVD",       "GCM/ISO");
 | 
			
		||||
    g_logs[TEXI]        = new LogContainer("EXI",       "ExternalInterface");
 | 
			
		||||
    g_logs[TGP]         = new LogContainer("GP",        "GraphicsProcessor");
 | 
			
		||||
    g_logs[THLE]        = new LogContainer("HLE",       "HLE");
 | 
			
		||||
    g_logs[THW]         = new LogContainer("HW",        "Hardware");
 | 
			
		||||
    g_logs[TJOYPAD]     = new LogContainer("JOYPAD",    "Joypad");
 | 
			
		||||
    g_logs[TMASTER]     = new LogContainer("*",         "Master Log");
 | 
			
		||||
    g_logs[TMEM]        = new LogContainer("MEM",       "Memory");
 | 
			
		||||
    g_logs[TMI]         = new LogContainer("MI",        "MemoryInterface");
 | 
			
		||||
    g_logs[TOS_HLE]     = new LogContainer("OSHLE",     "OSHLE");
 | 
			
		||||
    g_logs[TOS_REPORT]  = new LogContainer("OSREPORT",  "OSREPORT");
 | 
			
		||||
    g_logs[TPE]         = new LogContainer("PE",        "PixelEngine");
 | 
			
		||||
    g_logs[TPI]         = new LogContainer("PI",        "ProcessorInterface");
 | 
			
		||||
    g_logs[TPOWERPC]    = new LogContainer("PPC",       "PowerPC");
 | 
			
		||||
    g_logs[TSI]         = new LogContainer("SI",        "SerialInterface");
 | 
			
		||||
    g_logs[TVI]         = new LogContainer("VI",        "VideoInterface");
 | 
			
		||||
    g_logs[TVIDEO]      = new LogContainer("VIDEO",     "VideoCore");
 | 
			
		||||
 | 
			
		||||
    LOG_NOTICE(TCOMMON, "%d logger(s) initalized ok", NUMBER_OF_LOGS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
@ -1,216 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    log.h
 | 
			
		||||
 * @author  ShizZy <shizzy@6bit.net>
 | 
			
		||||
 * @date    2012-02-11
 | 
			
		||||
 * @brief   Common logging routines used throughout the project
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_LOG_H_
 | 
			
		||||
#define COMMON_LOG_H_
 | 
			
		||||
 | 
			
		||||
#include "SDL.h" // Used for threading/mutexes
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Logging Macros
 | 
			
		||||
 | 
			
		||||
#if defined(_DEBUG) || defined(DEBUG) || defined(LOGGING)
 | 
			
		||||
/// Debug mode, show all logs
 | 
			
		||||
#define MAX_LOG_LEVEL logger::LDEBUG
 | 
			
		||||
#else
 | 
			
		||||
/// Non debug mode, only show critical logs
 | 
			
		||||
#define MAX_LOG_LEVEL logger::LWARNING
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Logs a message ** Don't use directly **
 | 
			
		||||
#define _LOG_GENERIC(level, type, ...) \
 | 
			
		||||
    if (level <= MAX_LOG_LEVEL) { \
 | 
			
		||||
        LogGeneric(level, type, __FILE__, __LINE__, false, __VA_ARGS__); \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/// Used for appending to the last logged message
 | 
			
		||||
#define LOG_APPEND(level, type, ...) \
 | 
			
		||||
    if (logger::level <= MAX_LOG_LEVEL) { \
 | 
			
		||||
        logger::LogGeneric(logger::level, logger::type, __FILE__, __LINE__, true, __VA_ARGS__); \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/// Use this for printing an IMPORTANT notice to the logger
 | 
			
		||||
#define LOG_NOTICE(type, ...) _LOG_GENERIC(logger::LNOTICE, logger::type, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
/// Use this for printing an error message to the logger
 | 
			
		||||
#define LOG_ERROR(type, ...) _LOG_GENERIC(logger::LERROR, logger::type, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
/// Use this for printing a crash report to the logger
 | 
			
		||||
#define LOG_CRASH(type, ...) _LOG_GENERIC(logger::LCRASH, logger::type, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
/// Use this for printing a warning to the logger
 | 
			
		||||
#define LOG_WARNING(type, ...) _LOG_GENERIC(logger::LWARNING, logger::type, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
/// Use this for printing general information to the logger
 | 
			
		||||
#define LOG_INFO(type, ...) _LOG_GENERIC(logger::LINFO, logger::type, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
#if defined(_DEBUG) || defined(DEBUG) || defined(LOGGING)
 | 
			
		||||
 | 
			
		||||
/// Use this for printing a debug message to the logger
 | 
			
		||||
#define LOG_DEBUG(type, ...) _LOG_GENERIC(logger::LDEBUG, logger::type, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
/// Used for debug-mode assertions
 | 
			
		||||
#define _ASSERT_DBG(_type_, _cond_) \
 | 
			
		||||
    if (!(_cond_)) { \
 | 
			
		||||
        LOG_ERROR(_type_, "Error...\n\n  Line: %d\n  File: %s\n  Time: %s\n", \
 | 
			
		||||
                  __LINE__, __FILE__, __TIME__); \
 | 
			
		||||
        if (!logger::AskYesNo("*** Assertion (see log)***\n")) logger::Crash(); \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/// Used for message-specified debug-mode assertions
 | 
			
		||||
#define _ASSERT_DBG_MSG(_type_, _cond_, ...) \
 | 
			
		||||
    if (!(_cond_)) { \
 | 
			
		||||
        LOG_ERROR(_type_, __VA_ARGS__); \
 | 
			
		||||
        if (!logger::AskYesNo(__VA_ARGS__)) logger::Crash(); \
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
#define _ASSERT_DBG(_type_, _cond_, ...)
 | 
			
		||||
#define _ASSERT_DBG_MSG(_type_, _cond_, ...)
 | 
			
		||||
#define LOG_DEBUG(type, ...) 
 | 
			
		||||
#endif 
 | 
			
		||||
 | 
			
		||||
/// Used for general purpose assertions, CRITICAL operations only
 | 
			
		||||
#define _ASSERT_MSG(_type_, _cond_, ...) \
 | 
			
		||||
    if (!(_cond_)) { \
 | 
			
		||||
        if (!logger::AskYesNo(__VA_ARGS__)) logger::Crash(); \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////////////////////////// 
 | 
			
		||||
// Logger
 | 
			
		||||
 | 
			
		||||
namespace logger {
 | 
			
		||||
 | 
			
		||||
const int kMaxMsgLength = 1024; ///<  Maximum message length
 | 
			
		||||
 | 
			
		||||
/// Used for handling responses to system functions that require them
 | 
			
		||||
typedef enum {
 | 
			
		||||
    SYS_USER_NO = 0,    ///< User response for 'No'
 | 
			
		||||
    SYS_USER_YES,       ///< User response for 'Yes'
 | 
			
		||||
    SYS_USER_OK,        ///< User response for 'Okay'
 | 
			
		||||
    SYS_USER_ABORT,     ///< User response for 'Abort'
 | 
			
		||||
    SYS_USER_RETRY,     ///< User response for 'Retry'
 | 
			
		||||
    SYS_USER_CANCEL,    ///< User response for 'Cancel'
 | 
			
		||||
} SysUserResponse;
 | 
			
		||||
 | 
			
		||||
/// Level of logging
 | 
			
		||||
typedef enum {
 | 
			
		||||
    LNULL = 0,  ///< Logs with this level won't get logged
 | 
			
		||||
    LNOTICE,    ///< Notice: A general message to the user
 | 
			
		||||
    LERROR,     ///< Error: For failure messages
 | 
			
		||||
    LCRASH,     ///< Crash: Used for crash reports
 | 
			
		||||
    LWARNING,   ///< Warning: For potentially bad things, but not fatal
 | 
			
		||||
    LINFO,      ///< Info: Information message
 | 
			
		||||
    LDEBUG      ///< Debug: Debug-only information
 | 
			
		||||
} LogLevel;
 | 
			
		||||
 | 
			
		||||
/// Type of logging
 | 
			
		||||
typedef enum {
 | 
			
		||||
    TNULL = 0,
 | 
			
		||||
    TAI,
 | 
			
		||||
    TBOOT,
 | 
			
		||||
    TCOMMON,
 | 
			
		||||
    TCONFIG,
 | 
			
		||||
    TCORE,
 | 
			
		||||
    TCP,
 | 
			
		||||
    TDI,
 | 
			
		||||
    TDSP,
 | 
			
		||||
    TDVD,
 | 
			
		||||
    TEXI,
 | 
			
		||||
    TGP,
 | 
			
		||||
    THLE,
 | 
			
		||||
    THW,
 | 
			
		||||
    TJOYPAD,
 | 
			
		||||
    TMASTER,
 | 
			
		||||
    TMEM,
 | 
			
		||||
    TMI,
 | 
			
		||||
    TOS_HLE,
 | 
			
		||||
    TOS_REPORT,
 | 
			
		||||
    TPE,
 | 
			
		||||
    TPI,
 | 
			
		||||
    TPOWERPC,
 | 
			
		||||
    TSI,
 | 
			
		||||
    TVI,
 | 
			
		||||
    TVIDEO,
 | 
			
		||||
    NUMBER_OF_LOGS  ///< Number of logs - must be last
 | 
			
		||||
} LogType;
 | 
			
		||||
 | 
			
		||||
/// Used for implementing a logger for a subsystem
 | 
			
		||||
class LogContainer
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    LogContainer(const char* name, const char* desc, bool enable);
 | 
			
		||||
    ~LogContainer() {}
 | 
			
		||||
 | 
			
		||||
    const char* name() const { return name_; }
 | 
			
		||||
    const char* desc() const { return desc_; }
 | 
			
		||||
 | 
			
		||||
    bool enabled() const { return enabled_; }
 | 
			
		||||
    void set_enabled(bool enabled) { enabled_ = enabled; }
 | 
			
		||||
 | 
			
		||||
    LogLevel level() const { return level_;	}
 | 
			
		||||
    void set_level(LogLevel level) { level_ = level; }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    char name_[32];             ///< Name of the logger (e.g. "SI")
 | 
			
		||||
    char desc_[128];            ///< Description of the logger (e.g. "Serial Interface")
 | 
			
		||||
    bool enabled_;              ///< Whether or not the logger is enabled
 | 
			
		||||
 | 
			
		||||
    LogLevel    level_;         ///< Level of the logger (e.g. Notice, Error, Warning, etc.)
 | 
			
		||||
 | 
			
		||||
    SDL_mutex*  listener_lock_; ///< Mutex for multithreaded access
 | 
			
		||||
 | 
			
		||||
    DISALLOW_COPY_AND_ASSIGN(LogContainer);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Function Prototypes
 | 
			
		||||
 | 
			
		||||
/*! 
 | 
			
		||||
 * \brief Log routine used by everything
 | 
			
		||||
 * \param level Log level to use
 | 
			
		||||
 * \param type Log type to use
 | 
			
		||||
 * \param file Filename of file where error occured
 | 
			
		||||
 * \param line Linenumber of file where error occured
 | 
			
		||||
 * \param fmt Formatted message
 | 
			
		||||
 */
 | 
			
		||||
void LogGeneric(LogLevel level, LogType type, const char *file, int line, bool append, const char* fmt, ...);
 | 
			
		||||
 | 
			
		||||
/// Forces a controlled system crash rather before it catches fire (debug)
 | 
			
		||||
void Crash();
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 * \brief Asks the user a yes or no question
 | 
			
		||||
 * \param fmt Question formatted message 
 | 
			
		||||
 * \return SysUserResponse response
 | 
			
		||||
 */
 | 
			
		||||
SysUserResponse AskYesNo(const char* fmt, ...);
 | 
			
		||||
 | 
			
		||||
/// Initialize the logging system
 | 
			
		||||
void Init();
 | 
			
		||||
 | 
			
		||||
} // namespace log
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_LOG_H
 | 
			
		||||
@ -1,91 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    misc_utils.cpp
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-03-06
 | 
			
		||||
 * @brief   Miscellaneous functions/utilities that are used everywhere
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "misc_utils.h"
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
/// Make a string lowercase
 | 
			
		||||
void LowerStr(char* str) {
 | 
			
		||||
    for (int i = 0; str[i]; i++) {
 | 
			
		||||
        str[i] = tolower(str[ i ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Make a string uppercase
 | 
			
		||||
void UpperStr(char* str) {
 | 
			
		||||
    for (int i=0; i < strlen(str); i++) {
 | 
			
		||||
        if(str[i] >= 'a' && str[i] <= 'z') {
 | 
			
		||||
            str[i] &= 0xDF;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Format a std::string using C-style sprintf formatting
 | 
			
		||||
std::string FormatStr(const char* format, ...) {
 | 
			
		||||
    va_list args;
 | 
			
		||||
    char *buf = NULL;
 | 
			
		||||
#if EMU_PLATFORM == PLATFORM_WINDOWS
 | 
			
		||||
    int required = 0;
 | 
			
		||||
 | 
			
		||||
    va_start(args, format);
 | 
			
		||||
    required = _vscprintf(format, args);
 | 
			
		||||
    buf = new char[required + 1];
 | 
			
		||||
    vsnprintf(buf, required, format, args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
 | 
			
		||||
    buf[required] = '\0';
 | 
			
		||||
    std::string temp = buf;
 | 
			
		||||
    delete[] buf;
 | 
			
		||||
#else
 | 
			
		||||
    va_start(args, format);
 | 
			
		||||
    vasprintf(&buf, format, args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
 | 
			
		||||
    std::string temp = buf;
 | 
			
		||||
    free(buf);
 | 
			
		||||
#endif
 | 
			
		||||
    return temp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Check if a file exists
 | 
			
		||||
bool FileExists(char* filename) {
 | 
			
		||||
    std::ifstream ifile(filename);
 | 
			
		||||
    if (!ifile) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    ifile.close();
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Gets the size of a file
 | 
			
		||||
size_t FileSize(FILE* file) {
 | 
			
		||||
    size_t pos = ftell(file);
 | 
			
		||||
    fseek(file, 0L, SEEK_END);
 | 
			
		||||
    size_t res = ftell(file);
 | 
			
		||||
    fseek(file, pos, SEEK_SET);
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
@ -1,58 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    misc_utils.h
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-03-06
 | 
			
		||||
 * @brief   Miscellaneous functions/utilities that are used everywhere
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Make a string lowercase
 | 
			
		||||
 * @param str String to make lowercase
 | 
			
		||||
 */
 | 
			
		||||
void LowerStr(char* str);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Make a string uppercase
 | 
			
		||||
 * @param str String to make uppercase
 | 
			
		||||
 */
 | 
			
		||||
void UpperStr(char* str);
 | 
			
		||||
 | 
			
		||||
/// Format a std::string using C-style sprintf formatting
 | 
			
		||||
std::string FormatStr(const char* format, ...);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Check if a file exists on the users computer
 | 
			
		||||
 * @param filename Filename of file to check for
 | 
			
		||||
 * @return true on exists, false otherwise
 | 
			
		||||
 */
 | 
			
		||||
bool FileExists(char* filename);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Gets the size of a file
 | 
			
		||||
 * @param file Pointer to file to get size of
 | 
			
		||||
 * @return true Size of file, in bytes
 | 
			
		||||
 */
 | 
			
		||||
size_t FileSize(FILE* file);
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
@ -1,135 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    platform.h
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-02-11
 | 
			
		||||
 * @brief   Platform detection macros for portable compilation
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_PLATFORM_H_
 | 
			
		||||
#define COMMON_PLATFORM_H_
 | 
			
		||||
 | 
			
		||||
#include "types.h"
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Platform definitions
 | 
			
		||||
 | 
			
		||||
/// Enumeration for defining the supported platforms
 | 
			
		||||
#define PLATFORM_NULL 0
 | 
			
		||||
#define PLATFORM_WINDOWS 1
 | 
			
		||||
#define PLATFORM_MACOSX 2
 | 
			
		||||
#define PLATFORM_LINUX 3
 | 
			
		||||
#define PLATFORM_ANDROID 4
 | 
			
		||||
#define PLATFORM_IOS 5
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Platform detection
 | 
			
		||||
extern char *kGekkoOS;
 | 
			
		||||
 | 
			
		||||
#ifndef EMU_PLATFORM
 | 
			
		||||
 | 
			
		||||
#if defined( __WIN32__ ) || defined( _WIN32 )
 | 
			
		||||
#define EMU_PLATFORM PLATFORM_WINDOWS
 | 
			
		||||
 | 
			
		||||
#elif defined( __APPLE__ ) || defined( __APPLE_CC__ )
 | 
			
		||||
#define EMU_PLATFORM PLATFORM_MAXOSX
 | 
			
		||||
 | 
			
		||||
#elif defined(__linux__)
 | 
			
		||||
#define EMU_PLATFORM PLATFORM_LINUX
 | 
			
		||||
 | 
			
		||||
#else // Assume linux otherwise
 | 
			
		||||
#define EMU_PLATFORM PLATFORM_LINUX
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__x86_64__) || defined(_M_X64) || defined(__alpha__) || defined(__ia64__)
 | 
			
		||||
#define EMU_ARCHITECTURE_X64
 | 
			
		||||
#else
 | 
			
		||||
#define EMU_ARCHITECTURE_X86
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Compiler-Specific Definitions
 | 
			
		||||
 | 
			
		||||
#if EMU_PLATFORM == PLATFORM_WINDOWS
 | 
			
		||||
 | 
			
		||||
#define NOMINMAX
 | 
			
		||||
#define EMU_FASTCALL __fastcall
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#define EMU_FASTCALL __attribute__((fastcall))
 | 
			
		||||
#define __stdcall
 | 
			
		||||
#define __cdecl
 | 
			
		||||
 | 
			
		||||
#define LONG long
 | 
			
		||||
#define BOOL bool
 | 
			
		||||
#define DWORD u32
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if EMU_PLATFORM != PLATFORM_WINDOWS
 | 
			
		||||
 | 
			
		||||
// TODO: Hacks..
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#define MAX_PATH PATH_MAX
 | 
			
		||||
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#define stricmp(str1, str2) strcasecmp(str1, str2)
 | 
			
		||||
#define _stricmp(str1, str2) strcasecmp(str1, str2)
 | 
			
		||||
#define _snprintf snprintf
 | 
			
		||||
#define _getcwd getcwd
 | 
			
		||||
#define _tzset tzset
 | 
			
		||||
 | 
			
		||||
typedef void EXCEPTION_POINTERS;
 | 
			
		||||
 | 
			
		||||
inline u32 _rotl(u32 x, int shift) {
 | 
			
		||||
    shift &= 31;
 | 
			
		||||
    if (0 == shift) {
 | 
			
		||||
        return x;
 | 
			
		||||
    }
 | 
			
		||||
    return (x << shift) | (x >> (32 - shift));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline u64 _rotl64(u64 x, u32 shift){
 | 
			
		||||
    u32 n = shift % 64;
 | 
			
		||||
    return (x << n) | (x >> (64 - n));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline u32 _rotr(u32 x, int shift) {
 | 
			
		||||
    shift &= 31;
 | 
			
		||||
    if (0 == shift) {
 | 
			
		||||
        return x;
 | 
			
		||||
    }
 | 
			
		||||
    return (x >> shift) | (x << (32 - shift));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline u64 _rotr64(u64 x, u32 shift){
 | 
			
		||||
    u32 n = shift % 64;
 | 
			
		||||
    return (x >> n) | (x << (64 - n));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define GCC_VERSION_AVAILABLE(major, minor) (defined(__GNUC__) &&  (__GNUC__ > (major) || \
 | 
			
		||||
    (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_PLATFORM_H_
 | 
			
		||||
@ -1,152 +0,0 @@
 | 
			
		||||
#ifndef CONDITION_VARIABLE_H_
 | 
			
		||||
#define CONDITION_VARIABLE_H_
 | 
			
		||||
 | 
			
		||||
#define GCC_VER(x,y,z)	((x) * 10000 + (y) * 100 + (z))
 | 
			
		||||
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
 | 
			
		||||
 | 
			
		||||
#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__
 | 
			
		||||
// GCC 4.4 provides <condition_variable>
 | 
			
		||||
#include <condition_variable>
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// partial std::condition_variable implementation for win32/pthread
 | 
			
		||||
 | 
			
		||||
#include "std_mutex.h"
 | 
			
		||||
 | 
			
		||||
#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
 | 
			
		||||
#define USE_RVALUE_REFERENCES
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) && defined(_M_X64)
 | 
			
		||||
#define USE_CONDITION_VARIABLES
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
#define USE_EVENTS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace std
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class condition_variable
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
    typedef CONDITION_VARIABLE native_type;
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    typedef HANDLE native_type;
 | 
			
		||||
#else
 | 
			
		||||
    typedef pthread_cond_t native_type;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
#ifdef USE_EVENTS
 | 
			
		||||
    typedef native_type native_handle_type;
 | 
			
		||||
#else
 | 
			
		||||
    typedef native_type* native_handle_type;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    condition_variable()
 | 
			
		||||
    {
 | 
			
		||||
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
        InitializeConditionVariable(&m_handle);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
        m_handle = CreateEvent(NULL, false, false, NULL);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_cond_init(&m_handle, NULL);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~condition_variable()
 | 
			
		||||
    {
 | 
			
		||||
#if defined(_WIN32) && !defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
        CloseHandle(m_handle);
 | 
			
		||||
#elif !defined(_WIN32)
 | 
			
		||||
        pthread_cond_destroy(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    condition_variable(const condition_variable&) /*= delete*/;
 | 
			
		||||
    condition_variable& operator=(const condition_variable&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
    void notify_one()
 | 
			
		||||
    {
 | 
			
		||||
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
        WakeConditionVariable(&m_handle);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
        SetEvent(m_handle);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_cond_signal(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void notify_all()
 | 
			
		||||
    {
 | 
			
		||||
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
        WakeAllConditionVariable(&m_handle);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
        // TODO: broken
 | 
			
		||||
        SetEvent(m_handle);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_cond_broadcast(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void wait(unique_lock<mutex>& lock)
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#ifdef USE_SRWLOCKS
 | 
			
		||||
        SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0);
 | 
			
		||||
#elif defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
        SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE);
 | 
			
		||||
#else
 | 
			
		||||
        // TODO: broken, the unlock and wait need to be atomic
 | 
			
		||||
        lock.unlock();
 | 
			
		||||
        WaitForSingleObject(m_handle, INFINITE);
 | 
			
		||||
        lock.lock();
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
        pthread_cond_wait(&m_handle, lock.mutex()->native_handle());
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class Predicate>
 | 
			
		||||
    void wait(unique_lock<mutex>& lock, Predicate pred)
 | 
			
		||||
    {
 | 
			
		||||
        while (!pred())
 | 
			
		||||
            wait(lock);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //template <class Clock, class Duration>
 | 
			
		||||
    //cv_status wait_until(unique_lock<mutex>& lock,
 | 
			
		||||
    //	const chrono::time_point<Clock, Duration>& abs_time);
 | 
			
		||||
 | 
			
		||||
    //template <class Clock, class Duration, class Predicate>
 | 
			
		||||
    //	bool wait_until(unique_lock<mutex>& lock,
 | 
			
		||||
    //	const chrono::time_point<Clock, Duration>& abs_time,
 | 
			
		||||
    //	Predicate pred);
 | 
			
		||||
 | 
			
		||||
    //template <class Rep, class Period>
 | 
			
		||||
    //cv_status wait_for(unique_lock<mutex>& lock,
 | 
			
		||||
    //	const chrono::duration<Rep, Period>& rel_time);
 | 
			
		||||
 | 
			
		||||
    //template <class Rep, class Period, class Predicate>
 | 
			
		||||
    //	bool wait_for(unique_lock<mutex>& lock,
 | 
			
		||||
    //	const chrono::duration<Rep, Period>& rel_time,
 | 
			
		||||
    //	Predicate pred);
 | 
			
		||||
 | 
			
		||||
    native_handle_type native_handle()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef USE_EVENTS
 | 
			
		||||
        return m_handle;
 | 
			
		||||
#else
 | 
			
		||||
        return &m_handle;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    native_type m_handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,354 +0,0 @@
 | 
			
		||||
#ifndef MUTEX_H_
 | 
			
		||||
#define MUTEX_H_
 | 
			
		||||
 | 
			
		||||
#define GCC_VER(x,y,z)	((x) * 10000 + (y) * 100 + (z))
 | 
			
		||||
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
 | 
			
		||||
 | 
			
		||||
#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__
 | 
			
		||||
// GCC 4.4 provides <mutex>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// partial <mutex> implementation for win32/pthread
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
// WIN32
 | 
			
		||||
#define WIN32_LEAN_AND_MEAN
 | 
			
		||||
#include <Windows.h>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
// POSIX
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
 | 
			
		||||
#define USE_RVALUE_REFERENCES
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) && defined(_M_X64)
 | 
			
		||||
#define USE_SRWLOCKS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace std
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class recursive_mutex
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    typedef CRITICAL_SECTION native_type;
 | 
			
		||||
#else
 | 
			
		||||
    typedef pthread_mutex_t native_type;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    typedef native_type* native_handle_type;
 | 
			
		||||
 | 
			
		||||
    recursive_mutex(const recursive_mutex&) /*= delete*/;
 | 
			
		||||
    recursive_mutex& operator=(const recursive_mutex&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
    recursive_mutex()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        InitializeCriticalSection(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_mutexattr_t attr;
 | 
			
		||||
        pthread_mutexattr_init(&attr);
 | 
			
		||||
        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
 | 
			
		||||
        pthread_mutex_init(&m_handle, &attr);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~recursive_mutex()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        DeleteCriticalSection(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_mutex_destroy(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void lock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        EnterCriticalSection(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_mutex_lock(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        LeaveCriticalSection(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_mutex_unlock(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        return (0 != TryEnterCriticalSection(&m_handle));
 | 
			
		||||
#else
 | 
			
		||||
        return !pthread_mutex_trylock(&m_handle);
 | 
			
		||||
#endif	
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    native_handle_type native_handle()
 | 
			
		||||
    {
 | 
			
		||||
        return &m_handle;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    native_type m_handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined(_WIN32) || defined(USE_SRWLOCKS)
 | 
			
		||||
 | 
			
		||||
class mutex
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    typedef SRWLOCK native_type;
 | 
			
		||||
#else
 | 
			
		||||
    typedef pthread_mutex_t native_type;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    typedef native_type* native_handle_type;
 | 
			
		||||
 | 
			
		||||
    mutex(const mutex&) /*= delete*/;
 | 
			
		||||
    mutex& operator=(const mutex&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
    mutex()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        InitializeSRWLock(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_mutex_init(&m_handle, NULL);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~mutex()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#else
 | 
			
		||||
        pthread_mutex_destroy(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void lock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        AcquireSRWLockExclusive(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_mutex_lock(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        ReleaseSRWLockExclusive(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_mutex_unlock(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        // XXX TryAcquireSRWLockExclusive requires Windows 7!
 | 
			
		||||
        // return (0 != TryAcquireSRWLockExclusive(&m_handle));
 | 
			
		||||
        return false;
 | 
			
		||||
#else
 | 
			
		||||
        return !pthread_mutex_trylock(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    native_handle_type native_handle()
 | 
			
		||||
    {
 | 
			
		||||
        return &m_handle;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    native_type m_handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
typedef recursive_mutex mutex;	// just use CriticalSections
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum defer_lock_t { defer_lock };
 | 
			
		||||
enum try_to_lock_t { try_to_lock };
 | 
			
		||||
enum adopt_lock_t { adopt_lock };
 | 
			
		||||
 | 
			
		||||
template <class Mutex>
 | 
			
		||||
class lock_guard
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    typedef Mutex mutex_type;
 | 
			
		||||
 | 
			
		||||
    explicit lock_guard(mutex_type& m)
 | 
			
		||||
        : pm(m)
 | 
			
		||||
    {
 | 
			
		||||
        m.lock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lock_guard(mutex_type& m, adopt_lock_t)
 | 
			
		||||
        : pm(m)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~lock_guard()
 | 
			
		||||
    {
 | 
			
		||||
        pm.unlock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lock_guard(lock_guard const&) /*= delete*/;
 | 
			
		||||
    lock_guard& operator=(lock_guard const&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    mutex_type& pm;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Mutex>
 | 
			
		||||
class unique_lock
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    typedef Mutex mutex_type;
 | 
			
		||||
 | 
			
		||||
    unique_lock()
 | 
			
		||||
        : pm(NULL), owns(false)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    /*explicit*/ unique_lock(mutex_type& m)
 | 
			
		||||
        : pm(&m), owns(true)
 | 
			
		||||
    {
 | 
			
		||||
        m.lock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unique_lock(mutex_type& m, defer_lock_t)
 | 
			
		||||
        : pm(&m), owns(false)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    unique_lock(mutex_type& m, try_to_lock_t)
 | 
			
		||||
        : pm(&m), owns(m.try_lock())
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    unique_lock(mutex_type& m, adopt_lock_t)
 | 
			
		||||
        : pm(&m), owns(true)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    //template <class Clock, class Duration>
 | 
			
		||||
    //unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
 | 
			
		||||
 | 
			
		||||
    //template <class Rep, class Period>
 | 
			
		||||
    //unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
 | 
			
		||||
 | 
			
		||||
    ~unique_lock()
 | 
			
		||||
    {
 | 
			
		||||
        if (owns_lock())
 | 
			
		||||
            mutex()->unlock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef USE_RVALUE_REFERENCES
 | 
			
		||||
    unique_lock& operator=(const unique_lock&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
    unique_lock& operator=(unique_lock&& other)
 | 
			
		||||
    {
 | 
			
		||||
#else
 | 
			
		||||
    unique_lock& operator=(const unique_lock& u)
 | 
			
		||||
    {
 | 
			
		||||
        // ugly const_cast to get around lack of rvalue references
 | 
			
		||||
        unique_lock& other = const_cast<unique_lock&>(u);
 | 
			
		||||
#endif
 | 
			
		||||
        swap(other);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef USE_RVALUE_REFERENCES
 | 
			
		||||
    unique_lock(const unique_lock&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
    unique_lock(unique_lock&& other)
 | 
			
		||||
        : pm(NULL), owns(false)
 | 
			
		||||
    {
 | 
			
		||||
#else
 | 
			
		||||
    unique_lock(const unique_lock& u)
 | 
			
		||||
        : pm(NULL), owns(false)
 | 
			
		||||
    {
 | 
			
		||||
        // ugly const_cast to get around lack of rvalue references
 | 
			
		||||
        unique_lock& other = const_cast<unique_lock&>(u);	
 | 
			
		||||
#endif
 | 
			
		||||
        swap(other);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void lock()
 | 
			
		||||
    {
 | 
			
		||||
        mutex()->lock();
 | 
			
		||||
        owns = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
        owns = mutex()->try_lock();
 | 
			
		||||
        return owns;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //template <class Rep, class Period>
 | 
			
		||||
    //bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
 | 
			
		||||
    //template <class Clock, class Duration>
 | 
			
		||||
    //bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
 | 
			
		||||
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
        mutex()->unlock();
 | 
			
		||||
        owns = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(unique_lock& u)
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(pm, u.pm);
 | 
			
		||||
        std::swap(owns, u.owns);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mutex_type* release()
 | 
			
		||||
    {
 | 
			
		||||
        return mutex();
 | 
			
		||||
        pm = NULL;
 | 
			
		||||
        owns = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool owns_lock() const
 | 
			
		||||
    {
 | 
			
		||||
        return owns;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //explicit operator bool () const
 | 
			
		||||
    //{
 | 
			
		||||
    //	return owns_lock();
 | 
			
		||||
    //}
 | 
			
		||||
 | 
			
		||||
    mutex_type* mutex() const
 | 
			
		||||
    {
 | 
			
		||||
        return pm;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    mutex_type* pm;
 | 
			
		||||
    bool owns;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Mutex>
 | 
			
		||||
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y)
 | 
			
		||||
{
 | 
			
		||||
    x.swap(y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,309 +0,0 @@
 | 
			
		||||
#ifndef STD_THREAD_H_
 | 
			
		||||
#define STD_THREAD_H_
 | 
			
		||||
 | 
			
		||||
#define GCC_VER(x,y,z)	((x) * 10000 + (y) * 100 + (z))
 | 
			
		||||
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
 | 
			
		||||
 | 
			
		||||
#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__
 | 
			
		||||
// GCC 4.4 provides <thread>
 | 
			
		||||
#ifndef _GLIBCXX_USE_SCHED_YIELD
 | 
			
		||||
#define _GLIBCXX_USE_SCHED_YIELD
 | 
			
		||||
#endif
 | 
			
		||||
#include <thread>
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// partial std::thread implementation for win32/pthread
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
 | 
			
		||||
#define USE_RVALUE_REFERENCES
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
#import <Foundation/NSAutoreleasePool.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
// WIN32
 | 
			
		||||
 | 
			
		||||
#define WIN32_LEAN_AND_MEAN
 | 
			
		||||
#include <Windows.h>
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && defined(_MT)
 | 
			
		||||
// When linking with LIBCMT (the multithreaded C library), Microsoft recommends
 | 
			
		||||
// using _beginthreadex instead of CreateThread.
 | 
			
		||||
#define USE_BEGINTHREADEX
 | 
			
		||||
#include <process.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef USE_BEGINTHREADEX
 | 
			
		||||
#define THREAD_ID unsigned
 | 
			
		||||
#define THREAD_RETURN unsigned __stdcall
 | 
			
		||||
#else
 | 
			
		||||
#define THREAD_ID DWORD
 | 
			
		||||
#define THREAD_RETURN DWORD WINAPI
 | 
			
		||||
#endif
 | 
			
		||||
#define THREAD_HANDLE HANDLE
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
// PTHREAD
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#ifndef _POSIX_THREADS
 | 
			
		||||
#error unsupported platform (no pthreads?)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
#define THREAD_ID pthread_t
 | 
			
		||||
#define THREAD_HANDLE pthread_t
 | 
			
		||||
#define THREAD_RETURN void*
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace std
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class thread
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    typedef THREAD_HANDLE native_handle_type;
 | 
			
		||||
 | 
			
		||||
    class id
 | 
			
		||||
    {
 | 
			
		||||
        friend class thread;
 | 
			
		||||
    public:
 | 
			
		||||
        id() : m_thread(0) {}
 | 
			
		||||
        id(THREAD_ID _id) : m_thread(_id) {}
 | 
			
		||||
 | 
			
		||||
        bool operator==(const id& rhs) const
 | 
			
		||||
        {
 | 
			
		||||
            return m_thread == rhs.m_thread;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool operator!=(const id& rhs) const
 | 
			
		||||
        {
 | 
			
		||||
            return !(*this == rhs);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool operator<(const id& rhs) const
 | 
			
		||||
        {
 | 
			
		||||
            return m_thread < rhs.m_thread;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        THREAD_ID m_thread;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // no variadic template support in msvc
 | 
			
		||||
    //template <typename C, typename... A>
 | 
			
		||||
    //thread(C&& func, A&&... args);
 | 
			
		||||
 | 
			
		||||
    template <typename C>
 | 
			
		||||
    thread(C func)
 | 
			
		||||
    {
 | 
			
		||||
        StartThread(new Func<C>(func));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename C, typename A>
 | 
			
		||||
    thread(C func, A arg)
 | 
			
		||||
    {
 | 
			
		||||
        StartThread(new FuncArg<C, A>(func, arg));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    thread() /*= default;*/ {}
 | 
			
		||||
 | 
			
		||||
#ifdef USE_RVALUE_REFERENCES
 | 
			
		||||
    thread(const thread&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
    thread(thread&& other)
 | 
			
		||||
    {
 | 
			
		||||
#else
 | 
			
		||||
    thread(const thread& t)
 | 
			
		||||
    {
 | 
			
		||||
        // ugly const_cast to get around lack of rvalue references
 | 
			
		||||
        thread& other = const_cast<thread&>(t);
 | 
			
		||||
#endif
 | 
			
		||||
        swap(other);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef USE_RVALUE_REFERENCES
 | 
			
		||||
    thread& operator=(const thread&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
    thread& operator=(thread&& other)
 | 
			
		||||
    {
 | 
			
		||||
#else
 | 
			
		||||
    thread& operator=(const thread& t)
 | 
			
		||||
    {
 | 
			
		||||
        // ugly const_cast to get around lack of rvalue references
 | 
			
		||||
        thread& other = const_cast<thread&>(t);
 | 
			
		||||
#endif
 | 
			
		||||
        if (joinable())
 | 
			
		||||
            detach();
 | 
			
		||||
        swap(other);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~thread()
 | 
			
		||||
    {
 | 
			
		||||
        if (joinable())
 | 
			
		||||
            detach();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool joinable() const
 | 
			
		||||
    {
 | 
			
		||||
        return m_id != id();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    id get_id() const
 | 
			
		||||
    {
 | 
			
		||||
        return m_id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    native_handle_type native_handle()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        return m_handle;
 | 
			
		||||
#else
 | 
			
		||||
        return m_id.m_thread;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void join()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        WaitForSingleObject(m_handle, INFINITE);
 | 
			
		||||
        detach();
 | 
			
		||||
#else
 | 
			
		||||
        pthread_join(m_id.m_thread, NULL);
 | 
			
		||||
        m_id = id();
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void detach()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        CloseHandle(m_handle);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_detach(m_id.m_thread);
 | 
			
		||||
#endif
 | 
			
		||||
        m_id = id();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(thread& other)
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(m_id, other.m_id);
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        std::swap(m_handle, other.m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static unsigned hardware_concurrency()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        SYSTEM_INFO sysinfo;
 | 
			
		||||
        GetSystemInfo(&sysinfo);
 | 
			
		||||
        return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);
 | 
			
		||||
#else
 | 
			
		||||
        return 0;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    id m_id;
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    native_handle_type m_handle;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template <typename F>
 | 
			
		||||
    void StartThread(F* param)
 | 
			
		||||
    {
 | 
			
		||||
#ifdef USE_BEGINTHREADEX
 | 
			
		||||
        m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
        m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
 | 
			
		||||
#else
 | 
			
		||||
        pthread_attr_t attr;
 | 
			
		||||
        pthread_attr_init(&attr);
 | 
			
		||||
        pthread_attr_setstacksize(&attr, 1024 * 1024);
 | 
			
		||||
        if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param))
 | 
			
		||||
            m_id = id();
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename C>
 | 
			
		||||
    class Func
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        Func(C _func) : func(_func) {}
 | 
			
		||||
 | 
			
		||||
        void Run() { func(); }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        C const func;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template <typename C, typename A>
 | 
			
		||||
    class FuncArg
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        FuncArg(C _func, A _arg) : func(_func), arg(_arg) {}
 | 
			
		||||
 | 
			
		||||
        void Run() { func(arg); }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        C const func;
 | 
			
		||||
        A arg;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template <typename F>
 | 
			
		||||
    static THREAD_RETURN RunAndDelete(void* param)
 | 
			
		||||
    {
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 | 
			
		||||
#endif
 | 
			
		||||
        static_cast<F*>(param)->Run();
 | 
			
		||||
        delete static_cast<F*>(param);
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
        [pool release];
 | 
			
		||||
#endif
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
namespace this_thread
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    inline void yield()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        SwitchToThread();
 | 
			
		||||
#else
 | 
			
		||||
        sleep(0);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline thread::id get_id()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
        return GetCurrentThreadId();
 | 
			
		||||
#else
 | 
			
		||||
        return pthread_self();
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}	// namespace this_thread
 | 
			
		||||
 | 
			
		||||
}	// namespace std
 | 
			
		||||
 | 
			
		||||
#undef USE_RVALUE_REFERENCES
 | 
			
		||||
#undef USE_BEGINTHREADEX
 | 
			
		||||
#undef THREAD_ID
 | 
			
		||||
#undef THREAD_RETURN
 | 
			
		||||
#undef THREAD_HANDLE
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,46 +0,0 @@
 | 
			
		||||
/*!
 | 
			
		||||
* Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
*
 | 
			
		||||
* \file    timer.h
 | 
			
		||||
* \author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
* \date    2012-02-11
 | 
			
		||||
* \brief   Common time and timer routines
 | 
			
		||||
*
 | 
			
		||||
 * \section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "SDL.h"
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "timer.h"
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
/// Converts a ticks (miliseconds) u64 to a formatted string
 | 
			
		||||
void TicksToFormattedString(u32 ticks, char* formatted_string) {
 | 
			
		||||
    u32 hh = ticks / (1000 * 60 * 60);
 | 
			
		||||
    ticks -= hh * (1000 * 60 * 60);
 | 
			
		||||
 | 
			
		||||
    u32 mm = ticks / (1000 * 60);
 | 
			
		||||
    ticks -= mm * (1000 * 60);
 | 
			
		||||
 | 
			
		||||
    u32 ss = ticks / 1000;
 | 
			
		||||
    ticks -= ss * 1000;
 | 
			
		||||
 | 
			
		||||
    sprintf(formatted_string, "%02d:%02d:%03d", mm, ss, ticks);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
@ -1,51 +0,0 @@
 | 
			
		||||
/*!
 | 
			
		||||
* Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
*
 | 
			
		||||
* \file    timer.h
 | 
			
		||||
* \author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
* \date    2012-02-11
 | 
			
		||||
* \brief   Common time and timer routines
 | 
			
		||||
*
 | 
			
		||||
 * \section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_TIMER_H_
 | 
			
		||||
#define COMMON_TIMER_H_
 | 
			
		||||
 | 
			
		||||
#include "types.h"
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 * \brief Gets Get the number of milliseconds since initialization
 | 
			
		||||
 * \return Unsigned integer of ticks since software initialization
 | 
			
		||||
 */
 | 
			
		||||
static inline u32 GetTimeElapsed() {
 | 
			
		||||
    return SDL_GetTicks();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 * \brief Converts a ticks (miliseconds) u32 to a formatted string
 | 
			
		||||
 * \param ticks Ticks (32-bit unsigned integer)
 | 
			
		||||
 * \param formatted_string Pointer to formatted string result
 | 
			
		||||
 */
 | 
			
		||||
void TicksToFormattedString(u32 ticks, char* formatted_string);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_TIMER_H_
 | 
			
		||||
@ -1,119 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    types.h
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-02-11
 | 
			
		||||
 * @brief   Common types used throughout the project
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_TYPES_H_
 | 
			
		||||
#define COMMON_TYPES_H_
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <xmmintrin.h> // data_types__m128.cpp
 | 
			
		||||
 | 
			
		||||
typedef unsigned char       u8;     ///< 8-bit unsigned byte
 | 
			
		||||
typedef unsigned short      u16;    ///< 16-bit unsigned short
 | 
			
		||||
typedef unsigned int        u32;    ///< 32-bit unsigned word
 | 
			
		||||
 | 
			
		||||
typedef signed char         s8;     ///< 8-bit signed byte
 | 
			
		||||
typedef signed short        s16;    ///< 16-bit signed short
 | 
			
		||||
typedef signed int          s32;    ///< 32-bit signed word
 | 
			
		||||
 | 
			
		||||
typedef signed int          x32;    ///< S15.16 fixed point int 
 | 
			
		||||
 | 
			
		||||
typedef float               f32;    ///< 32-bit floating point
 | 
			
		||||
typedef double              f64;    ///< 64-bit floating point
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
 | 
			
		||||
typedef unsigned __int64    u64;    ///< 64-bit unsigned int
 | 
			
		||||
typedef signed __int64      s64;    ///< 64-bit signed int
 | 
			
		||||
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
 | 
			
		||||
typedef signed long long    s64;    ///< 64-bit unsigned int
 | 
			
		||||
typedef unsigned long long  u64;    ///< 64-bit signed int
 | 
			
		||||
 | 
			
		||||
#define U64(a) a ## ull
 | 
			
		||||
#define S64(a) a ## sll
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Union for fast 16-bit type casting
 | 
			
		||||
union t16 {
 | 
			
		||||
	u8	_u8[2];             ///< 8-bit unsigned char(s)
 | 
			
		||||
	u16 _u16;               ///< 16-bit unsigned shorts(s)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Union for fast 32-bit type casting
 | 
			
		||||
union t32 {
 | 
			
		||||
    f32 _f32;               ///< 32-bit floating point(s)
 | 
			
		||||
    u32 _u32;               ///< 32-bit unsigned int(s)
 | 
			
		||||
    x32 _x32;               ///< 32-bit fixed point(s)
 | 
			
		||||
    u16 _u16[2];            ///< 16-bit unsigned shorts(s)
 | 
			
		||||
    u8  _u8[4];             ///< 8-bit unsigned char(s)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Union for fast 64-bit type casting
 | 
			
		||||
union t64 {
 | 
			
		||||
    f64 _f64;               ///< 64-bit floating point
 | 
			
		||||
    u64 _u64;               ///< 64-bit unsigned long
 | 
			
		||||
    f32 _f32[2];            ///< 32-bit floating point(s)
 | 
			
		||||
    u32 _u32[2];            ///< 32-bit unsigned int(s)
 | 
			
		||||
    x32 _x32[2];            ///< 32-bit fixed point(s)
 | 
			
		||||
    u16 _u16[4];            ///< 16-bit unsigned shorts(s)
 | 
			
		||||
    u8  _u8[8];             ///< 8-bit unsigned char(s)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Union for fast 128-bit type casting
 | 
			
		||||
union t128 {
 | 
			
		||||
    struct
 | 
			
		||||
    {
 | 
			
		||||
        t64 ps0;            ///< 64-bit paired single 0
 | 
			
		||||
        t64 ps1;            ///< 64-bit paired single 1
 | 
			
		||||
    };
 | 
			
		||||
    __m128  a;              ///< 128-bit floating point (__m128 maps to the XMM[0-7] registers)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Rectangle data structure
 | 
			
		||||
class Rect {
 | 
			
		||||
public:
 | 
			
		||||
    Rect(int x0=0, int y0=0, int x1=0, int y1=0) {
 | 
			
		||||
        x0_ = x0;
 | 
			
		||||
        y0_ = y0;
 | 
			
		||||
        x1_ = x1;
 | 
			
		||||
        y1_ = y1;
 | 
			
		||||
    }
 | 
			
		||||
    ~Rect() { }
 | 
			
		||||
 | 
			
		||||
    int x0_;    ///< Rect top left X-coordinate
 | 
			
		||||
    int y0_;    ///< Rect top left Y-coordinate
 | 
			
		||||
    int x1_;    ///< Rect bottom left X-coordinate
 | 
			
		||||
    int y1_;    ///< Rect bottom right Y-coordinate
 | 
			
		||||
 | 
			
		||||
    inline u32 width() const { return abs(x1_ - x0_); }
 | 
			
		||||
    inline u32 height() const { return abs(y1_ - y0_); }
 | 
			
		||||
 | 
			
		||||
    inline bool operator == (const Rect& val) const {
 | 
			
		||||
        return (x0_ == val.x0_ && y0_ == val.y0_ && x1_ == val.x1_ && y1_ == val.y1_);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_TYPES_H_
 | 
			
		||||
@ -1,236 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    x86_utils.cpp
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-12-23
 | 
			
		||||
 * @brief   Utilities for the x86 architecture
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "x86_utils.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#define _interlockedbittestandset workaround_ms_header_bug_platform_sdk6_set
 | 
			
		||||
#define _interlockedbittestandreset workaround_ms_header_bug_platform_sdk6_reset
 | 
			
		||||
#define _interlockedbittestandset64 workaround_ms_header_bug_platform_sdk6_set64
 | 
			
		||||
#define _interlockedbittestandreset64 workaround_ms_header_bug_platform_sdk6_reset64
 | 
			
		||||
#include <intrin.h>
 | 
			
		||||
#undef _interlockedbittestandset
 | 
			
		||||
#undef _interlockedbittestandreset
 | 
			
		||||
#undef _interlockedbittestandset64
 | 
			
		||||
#undef _interlockedbittestandreset64
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
//#include <config/i386/cpuid.h>
 | 
			
		||||
#include <xmmintrin.h>
 | 
			
		||||
 | 
			
		||||
#if defined __FreeBSD__
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <machine/cpufunc.h>
 | 
			
		||||
#else
 | 
			
		||||
static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
 | 
			
		||||
    unsigned int *ecx, unsigned int *edx)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _LP64
 | 
			
		||||
    // Note: EBX is reserved on Mac OS X and in PIC on Linux, so it has to
 | 
			
		||||
    // restored at the end of the asm block.
 | 
			
		||||
    __asm__ (
 | 
			
		||||
        "cpuid;"
 | 
			
		||||
        "movl  %%ebx,%1;"
 | 
			
		||||
        : "=a" (*eax),
 | 
			
		||||
        "=S" (*ebx),
 | 
			
		||||
        "=c" (*ecx),
 | 
			
		||||
        "=d" (*edx)
 | 
			
		||||
        : "a"  (*eax)
 | 
			
		||||
        : "rbx"
 | 
			
		||||
        );
 | 
			
		||||
#else
 | 
			
		||||
    __asm__ (
 | 
			
		||||
        "cpuid;"
 | 
			
		||||
        "movl  %%ebx,%1;"
 | 
			
		||||
        : "=a" (*eax),
 | 
			
		||||
        "=S" (*ebx),
 | 
			
		||||
        "=c" (*ecx),
 | 
			
		||||
        "=d" (*edx)
 | 
			
		||||
        : "a"  (*eax)
 | 
			
		||||
        : "ebx"
 | 
			
		||||
        );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void __cpuid(int info[4], int x)
 | 
			
		||||
{
 | 
			
		||||
#if defined __FreeBSD__
 | 
			
		||||
    do_cpuid((unsigned int)x, (unsigned int*)info);
 | 
			
		||||
#else
 | 
			
		||||
    unsigned int eax = x, ebx = 0, ecx = 0, edx = 0;
 | 
			
		||||
    do_cpuid(&eax, &ebx, &ecx, &edx);
 | 
			
		||||
    info[0] = eax;
 | 
			
		||||
    info[1] = ebx;
 | 
			
		||||
    info[2] = ecx;
 | 
			
		||||
    info[3] = edx;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
X86Utils::X86Utils() {
 | 
			
		||||
    memset(this, 0, sizeof(*this));
 | 
			
		||||
#ifdef _M_IX86
 | 
			
		||||
 | 
			
		||||
#elif defined (_M_X64)
 | 
			
		||||
    support_x64_os_ = true;
 | 
			
		||||
    support_sse_ = true;
 | 
			
		||||
    support_sse2_ = true;
 | 
			
		||||
#endif
 | 
			
		||||
    num_cores_ = 1;
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#ifdef _M_IX86
 | 
			
		||||
    int f64 = 0;
 | 
			
		||||
    IsWow64Process(GetCurrentProcess(), &f64);
 | 
			
		||||
    support_x64_os_ = (f64 == 1) ? true : false;
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
    // Assume CPU supports the CPUID instruction. Those that don't can barely
 | 
			
		||||
    // boot modern OS:es anyway.
 | 
			
		||||
    int cpu_id[4];
 | 
			
		||||
    char cpu_string[32];
 | 
			
		||||
    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
 | 
			
		||||
    *((int *)cpu_string) = cpu_id[1];
 | 
			
		||||
    *((int *)(cpu_string + 4)) = cpu_id[3];
 | 
			
		||||
    *((int *)(cpu_string + 8)) = cpu_id[2];
 | 
			
		||||
    __cpuid(cpu_id, 0x80000000);
 | 
			
		||||
    u32 max_ex_fn = cpu_id[0];
 | 
			
		||||
    if (!strcmp(cpu_string, "GenuineIntel")) {
 | 
			
		||||
        cpu_vendor_ = kVendorX86_Intel;
 | 
			
		||||
    } else if (!strcmp(cpu_string, "AuthenticAMD")) {
 | 
			
		||||
        cpu_vendor_ = kVendorX86_AMD;
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_vendor_ = kVendorX86_None;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Detect family and other misc stuff.
 | 
			
		||||
    bool ht = false;
 | 
			
		||||
    support_hyper_threading_ = ht;
 | 
			
		||||
    logical_cpu_count_ = 1;
 | 
			
		||||
    if (max_std_fn >= 1) {
 | 
			
		||||
        __cpuid(cpu_id, 0x00000001);
 | 
			
		||||
        logical_cpu_count_ = (cpu_id[1] >> 16) & 0xFF;
 | 
			
		||||
        ht = (cpu_id[3] >> 28) & 1;
 | 
			
		||||
 | 
			
		||||
        if ((cpu_id[3] >> 25) & 1) support_sse_ = true;
 | 
			
		||||
        if ((cpu_id[3] >> 26) & 1) support_sse2_ = true;
 | 
			
		||||
        if ((cpu_id[2])       & 1) support_sse3_ = true;
 | 
			
		||||
        if ((cpu_id[2] >> 9)  & 1) support_ssse3_ = true;
 | 
			
		||||
        if ((cpu_id[2] >> 19) & 1) support_sse4_1_ = true;
 | 
			
		||||
        if ((cpu_id[2] >> 20) & 1) support_sse4_2_ = true;
 | 
			
		||||
    }
 | 
			
		||||
    if (max_ex_fn >= 0x80000004) {
 | 
			
		||||
        // Extract brand string
 | 
			
		||||
        __cpuid(cpu_id, 0x80000002);
 | 
			
		||||
//        memcpy(brand_string, cpu_id, sizeof(cpu_id));
 | 
			
		||||
        __cpuid(cpu_id, 0x80000003);
 | 
			
		||||
//        memcpy(brand_string + 16, cpu_id, sizeof(cpu_id));
 | 
			
		||||
        __cpuid(cpu_id, 0x80000004);
 | 
			
		||||
//        memcpy(brand_string + 32, cpu_id, sizeof(cpu_id));
 | 
			
		||||
    }
 | 
			
		||||
    num_cores_ = (logical_cpu_count_ == 0) ? 1 : logical_cpu_count_;
 | 
			
		||||
 | 
			
		||||
    if (max_ex_fn >= 0x80000008) {
 | 
			
		||||
        // Get number of cores. This is a bit complicated. Following AMD manual here.
 | 
			
		||||
        __cpuid(cpu_id, 0x80000008);
 | 
			
		||||
        int apic_id_core_id_size = (cpu_id[2] >> 12) & 0xF;
 | 
			
		||||
        if (apic_id_core_id_size == 0) {
 | 
			
		||||
            if (ht) {
 | 
			
		||||
                // New mechanism for modern Intel CPUs.
 | 
			
		||||
                if (cpu_vendor_ == kVendorX86_Intel) {
 | 
			
		||||
                    __cpuid(cpu_id, 0x00000004);
 | 
			
		||||
                    int cores_x_package = ((cpu_id[0] >> 26) & 0x3F) + 1;
 | 
			
		||||
                    support_hyper_threading_ = (cores_x_package < logical_cpu_count_);
 | 
			
		||||
                    cores_x_package = ((logical_cpu_count_ % cores_x_package) == 0) ? cores_x_package : 1;
 | 
			
		||||
                    num_cores_ = (cores_x_package > 1) ? cores_x_package : num_cores_;
 | 
			
		||||
                    logical_cpu_count_ /= cores_x_package;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            // Use AMD's new method.
 | 
			
		||||
            num_cores_ = (cpu_id[2] & 0xFF) + 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    LOG_NOTICE(TCOMMON, "CPU detected (%s)", this->Summary().c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
X86Utils::~X86Utils() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if an X86 extension is supported by the current architecture
 | 
			
		||||
 * @param extension ExtensionX86 extension support to check for
 | 
			
		||||
 * @return True if the extension is supported, otherwise false
 | 
			
		||||
 */
 | 
			
		||||
bool X86Utils::IsExtensionSupported(X86Utils::ExtensionX86 extension) {
 | 
			
		||||
    switch (extension) {
 | 
			
		||||
    case kExtensionX86_SSE:
 | 
			
		||||
        return support_sse_;
 | 
			
		||||
    case kExtensionX86_SSE2:
 | 
			
		||||
        return support_sse2_;
 | 
			
		||||
    case kExtensionX86_SSE3:
 | 
			
		||||
        return support_sse3_;
 | 
			
		||||
    case kExtensionX86_SSSE3:
 | 
			
		||||
        return support_ssse3_;
 | 
			
		||||
    case kExtensionX86_SSE4_1:
 | 
			
		||||
        return support_sse4_1_;
 | 
			
		||||
    case kExtensionX86_SSE4_2:
 | 
			
		||||
        return support_sse4_2_;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets a string summary of the X86 CPU information, suitable for printing
 | 
			
		||||
 * @return String summary
 | 
			
		||||
 */
 | 
			
		||||
std::string X86Utils::Summary() {
 | 
			
		||||
    const char* cpu_vendors[] = {
 | 
			
		||||
        "Unknown", "Intel", "AMD"
 | 
			
		||||
    };
 | 
			
		||||
    std::string res;
 | 
			
		||||
    res = FormatStr("%s, %d core%s", cpu_vendors[cpu_vendor_], num_cores_, (num_cores_ > 1) ? "s" : "");
 | 
			
		||||
    if (support_sse4_2_) {
 | 
			
		||||
        res += FormatStr(" (%i logical threads per physical core)", logical_cpu_count_);
 | 
			
		||||
    }
 | 
			
		||||
    if (support_sse_) res += ", SSE";
 | 
			
		||||
    if (support_sse2_) res += ", SSE2";
 | 
			
		||||
    if (support_sse3_) res += ", SSE3";
 | 
			
		||||
    if (support_ssse3_) res += ", SSSE3";
 | 
			
		||||
    if (support_sse4_1_) res += ", SSE4.1";
 | 
			
		||||
    if (support_sse4_2_) res += ", SSE4.2";
 | 
			
		||||
    if (support_hyper_threading_) res += ", HTT";
 | 
			
		||||
    //if (bLongMode) res += ", 64-bit support";
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
@ -1,92 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    x86_utils.h
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-02-11
 | 
			
		||||
 * @brief   Utilities for the x86 architecture
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_X86_UTILS_
 | 
			
		||||
#define COMMON_X86_UTILS_
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include "types.h"
 | 
			
		||||
 | 
			
		||||
// Common namespace
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
class X86Utils {
 | 
			
		||||
public:
 | 
			
		||||
    /// Enumeration of X86 vendors
 | 
			
		||||
    enum VendorX86 {
 | 
			
		||||
        kVendorX86_None = 0,
 | 
			
		||||
        kVendorX86_Intel,
 | 
			
		||||
        kVendorX86_AMD,
 | 
			
		||||
        kVendorX86_NumberOf
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Enumeration of X86 extensions
 | 
			
		||||
    enum ExtensionX86 {
 | 
			
		||||
        kExtensionX86_None = 0,
 | 
			
		||||
        kExtensionX86_SSE,
 | 
			
		||||
        kExtensionX86_SSE2,
 | 
			
		||||
        kExtensionX86_SSE3,
 | 
			
		||||
        kExtensionX86_SSSE3,
 | 
			
		||||
        kExtensionX86_SSE4_1,
 | 
			
		||||
        kExtensionX86_SSE4_2,
 | 
			
		||||
        kExtensionX86_NumberOf
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    X86Utils();
 | 
			
		||||
    ~X86Utils();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if an X86 extension is supported by the current architecture
 | 
			
		||||
     * @param extension ExtensionX86 extension support to check for
 | 
			
		||||
     * @return True if the extension is supported, otherwise false
 | 
			
		||||
     */
 | 
			
		||||
    bool IsExtensionSupported(ExtensionX86 extension);
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets a string summary of the X86 CPU information, suitable for printing
 | 
			
		||||
     * @return String summary
 | 
			
		||||
     */
 | 
			
		||||
    std::string Summary();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    bool support_x64_os_;
 | 
			
		||||
    bool support_x64_cpu_;
 | 
			
		||||
    bool support_hyper_threading_;
 | 
			
		||||
    
 | 
			
		||||
    int num_cores_;
 | 
			
		||||
    int logical_cpu_count_;
 | 
			
		||||
 | 
			
		||||
    bool support_sse_;
 | 
			
		||||
    bool support_sse2_;
 | 
			
		||||
    bool support_sse3_;
 | 
			
		||||
    bool support_ssse3_;
 | 
			
		||||
    bool support_sse4_1_;
 | 
			
		||||
    bool support_sse4_2_;
 | 
			
		||||
 | 
			
		||||
    VendorX86 cpu_vendor_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,487 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    xml.h
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-02-12
 | 
			
		||||
 * @brief   Used for parsing XML configurations
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
 | 
			
		||||
#include <rapidxml.hpp>
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "misc_utils.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
 | 
			
		||||
/// Gets a RapidXML boolean element value
 | 
			
		||||
static bool GetXMLElementAsBool(rapidxml::xml_node<> *node, const char* element_name) {
 | 
			
		||||
    rapidxml::xml_node<> *sub_node = node->first_node(element_name);
 | 
			
		||||
    if (sub_node) {
 | 
			
		||||
        return (E_OK == _stricmp(sub_node->value(), "true")) ? true : false;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Gets a RapidXML string element value
 | 
			
		||||
static char* GetXMLElementAsString(rapidxml::xml_node<> *node, const char* element_name, 
 | 
			
		||||
    char* element_value) {
 | 
			
		||||
    rapidxml::xml_node<> *sub_node = node->first_node(element_name);
 | 
			
		||||
    if (sub_node) {
 | 
			
		||||
        strcpy(element_value, sub_node->value());
 | 
			
		||||
        return element_value;
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Gets a RapidXML integer element value
 | 
			
		||||
static int GetXMLElementAsInt(rapidxml::xml_node<> *node, const char* element_name) {
 | 
			
		||||
    rapidxml::xml_node<> *sub_node = node->first_node(element_name);
 | 
			
		||||
    if (sub_node) {
 | 
			
		||||
        return atoi(sub_node->value());
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Parse the "General" XML group
 | 
			
		||||
 * @param node RapidXML node for the "General" XML group
 | 
			
		||||
 * @param config Config class object to parse data into
 | 
			
		||||
 */
 | 
			
		||||
void ParseGeneralNode(rapidxml::xml_node<> *node, Config& config) {
 | 
			
		||||
    // Don't parse the node if it doesn't exist!
 | 
			
		||||
    if (!node) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    char temp_str[MAX_PATH];
 | 
			
		||||
    config.set_enable_multicore(GetXMLElementAsBool(node, "EnableMultiCore"));
 | 
			
		||||
    config.set_enable_idle_skipping(GetXMLElementAsBool(node, "EnableIdleSkipping"));
 | 
			
		||||
    config.set_enable_hle(GetXMLElementAsBool(node, "EnableHLE"));
 | 
			
		||||
    config.set_enable_auto_boot(GetXMLElementAsBool(node, "EnableAutoBoot"));
 | 
			
		||||
    config.set_enable_cheats(GetXMLElementAsBool(node, "EnableCheats"));
 | 
			
		||||
    config.set_default_boot_file(GetXMLElementAsString(node, "DefaultBootFile", temp_str), MAX_PATH);
 | 
			
		||||
 | 
			
		||||
    // Parse all search paths in the DVDImagePaths node
 | 
			
		||||
    rapidxml::xml_node<> *sub_node = node->first_node("DVDImagePaths");
 | 
			
		||||
    if (sub_node) {
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        for (rapidxml::xml_node<> *elem = sub_node->first_node("Path"); elem; 
 | 
			
		||||
            elem = elem->next_sibling()) {
 | 
			
		||||
            
 | 
			
		||||
            config.set_dvd_image_path(i, elem->value(), MAX_PATH);
 | 
			
		||||
            LOG_NOTICE(TCONFIG, "Adding %s to DVD image search paths...\n", 
 | 
			
		||||
                config.dvd_image_path(i));
 | 
			
		||||
            i++;
 | 
			
		||||
            // Stop if we have parsed the maximum paths
 | 
			
		||||
            if (MAX_SEARCH_PATHS < i) {
 | 
			
		||||
                LOG_WARNING(TCONFIG, "Maximum number of DVDImagePath search paths is %d, not parsing"
 | 
			
		||||
                    " any more!", MAX_SEARCH_PATHS);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Parse the "Debug" XML group
 | 
			
		||||
 * @param node RapidXML node for the "Debug" XML group
 | 
			
		||||
 * @param config Config class object to parse data into
 | 
			
		||||
 */
 | 
			
		||||
void ParseDebugNode(rapidxml::xml_node<> *node, Config& config) {
 | 
			
		||||
    // Don't parse the node if it doesn't exist!
 | 
			
		||||
    if (!node) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    config.set_enable_show_fps(GetXMLElementAsBool(node, "EnableShowFPS"));
 | 
			
		||||
    config.set_enable_dump_opcode0(GetXMLElementAsBool(node, "EnableDumpOpcode0"));
 | 
			
		||||
    config.set_enable_pause_on_unknown_opcode(GetXMLElementAsBool(node, 
 | 
			
		||||
        "EnablePauseOnUnknownOpcode"));
 | 
			
		||||
    config.set_enable_dump_gcm_reads(GetXMLElementAsBool(node, "EnableDumpGCMReads"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Parse the "Patches" and "Cheats" XML group
 | 
			
		||||
 * @param node RapidXML node for the "Patches" or "Cheats" XML group
 | 
			
		||||
 * @param config Config class object to parse data into
 | 
			
		||||
 */
 | 
			
		||||
void ParsePatchesNode(rapidxml::xml_node<> *node, Config& config, const char* node_name) {
 | 
			
		||||
    int i = 0;
 | 
			
		||||
    char node_name_str[8];
 | 
			
		||||
    
 | 
			
		||||
    // Get lowercase section name
 | 
			
		||||
    strcpy(node_name_str, node_name);
 | 
			
		||||
 | 
			
		||||
    // TODO: not available on Unix
 | 
			
		||||
    common::LowerStr(node_name_str);
 | 
			
		||||
    
 | 
			
		||||
    // Parse all search patches in the Patches node
 | 
			
		||||
    rapidxml::xml_node<> *sub_node = node->first_node(node_name);
 | 
			
		||||
    if (sub_node) {
 | 
			
		||||
        for (rapidxml::xml_node<> *elem = sub_node->first_node("Patch"); elem; 
 | 
			
		||||
            elem = elem->next_sibling()) {
 | 
			
		||||
 | 
			
		||||
            // Get enable attribute (note: defaults to true)
 | 
			
		||||
            rapidxml::xml_attribute<> *attr = elem->first_attribute("enable");
 | 
			
		||||
            if (attr) {
 | 
			
		||||
                if (E_OK == _stricmp(attr->value(), "false")) {
 | 
			
		||||
                    continue; // Patch is disabled, skip it
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // Get address attribute
 | 
			
		||||
            attr = elem->first_attribute("address");
 | 
			
		||||
            if (!attr) {
 | 
			
		||||
                LOG_ERROR(TCONFIG, "Patch without 'address' attribute illegal!");
 | 
			
		||||
                continue;
 | 
			
		||||
            } else {
 | 
			
		||||
                u32 data = 0;
 | 
			
		||||
                u32 address = 0;
 | 
			
		||||
                {
 | 
			
		||||
                    // Convert address hexstring to unsigned int
 | 
			
		||||
                    std::stringstream ss;
 | 
			
		||||
                    ss << std::hex << attr->value();
 | 
			
		||||
                    ss >> address;
 | 
			
		||||
                }
 | 
			
		||||
                attr = elem->first_attribute("instr");
 | 
			
		||||
 | 
			
		||||
                // Get "data" attribute if no "instr" attribute
 | 
			
		||||
                if (!attr) {
 | 
			
		||||
                    attr = elem->first_attribute("data");
 | 
			
		||||
                    // Neither found - error
 | 
			
		||||
                    if (!attr) {
 | 
			
		||||
                        LOG_ERROR(TCONFIG, "Patch without 'instr' or 'data' attributes "
 | 
			
		||||
                            "illegal!");
 | 
			
		||||
                        continue;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        // Found data, convert hexstring to unsigned int
 | 
			
		||||
                        std::stringstream ss;
 | 
			
		||||
                        ss << std::hex << attr->value();
 | 
			
		||||
                        ss >> data;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    // Found instr
 | 
			
		||||
                    char instr_str[4];
 | 
			
		||||
                    
 | 
			
		||||
                    // Convert to lowercase
 | 
			
		||||
                    strcpy(instr_str, attr->value());
 | 
			
		||||
                    // TODO: not available on Unix
 | 
			
		||||
                    common::LowerStr(instr_str);
 | 
			
		||||
 | 
			
		||||
                    // Convert instruction to equivalent PPC bytecode
 | 
			
		||||
                    //  TODO(ShizZy): Pull this out to the PowerPC modules at some point
 | 
			
		||||
                    if (E_OK == _stricmp(instr_str, "blr")) {
 | 
			
		||||
                        data = 0x4E800020; // PowerPC BLR instruction bytecode
 | 
			
		||||
                    } else if (E_OK == _stricmp(instr_str, "nop")) {
 | 
			
		||||
                        data = 0x60000000; // PowerPC NOP instruction bytecode
 | 
			
		||||
                    } else {
 | 
			
		||||
                        LOG_ERROR(TCONFIG, "Patch with invalid 'instr' attribute illegal!");
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                Config::Patch patch = { address, data };
 | 
			
		||||
 | 
			
		||||
                if (E_OK == _stricmp(node_name_str, "patches")) {
 | 
			
		||||
                    LOG_NOTICE(TCONFIG, "Adding patch addr=0x%08x data=0x%08x to patches...\n",
 | 
			
		||||
                        address, data, node_name_str);
 | 
			
		||||
                    config.set_patches(i, patch);
 | 
			
		||||
                } else if (E_OK == _stricmp(node_name_str, "cheats")) {
 | 
			
		||||
                    LOG_NOTICE(TCONFIG, "Adding cheat addr=0x%08x data=0x%08x to cheats...\n",
 | 
			
		||||
                        address, data, node_name_str);
 | 
			
		||||
                    config.set_cheats(i, patch);
 | 
			
		||||
                } else {
 | 
			
		||||
                    LOG_ERROR(TCONFIG, "Unexpected patch type %s, ignoring...", node_name_str);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Stop if we have parsed the maximum patches
 | 
			
		||||
                if (MAX_PATCHES_PER_GAME < ++i) {
 | 
			
		||||
                    LOG_WARNING(TCONFIG, "Maximum number of patches search paths is %d, not parsing"
 | 
			
		||||
                        " any more!", MAX_PATCHES_PER_GAME);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Parse the "Boot" XML group
 | 
			
		||||
 * @param node RapidXML node for the "Boot" XML group
 | 
			
		||||
 * @param config Config class object to parse data into
 | 
			
		||||
 */
 | 
			
		||||
void ParseBootNode(rapidxml::xml_node<> *node, Config& config) {
 | 
			
		||||
    // Don't parse the node if it doesn't exist!
 | 
			
		||||
    if (!node) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    config.set_enable_ipl(GetXMLElementAsBool(node, "EnableIPL"));
 | 
			
		||||
    
 | 
			
		||||
    ParsePatchesNode(node, config, "Patches");
 | 
			
		||||
    ParsePatchesNode(node, config, "Cheats");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Parse the "Video" XML group
 | 
			
		||||
 * @param node RapidXML node for the "Video" XML group
 | 
			
		||||
 * @param config Config class object to parse data into
 | 
			
		||||
 */
 | 
			
		||||
void ParsePowerPCNode(rapidxml::xml_node<> *node, Config& config) {
 | 
			
		||||
    // Don't parse the node if it doesn't exist!
 | 
			
		||||
    if (!node) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    rapidxml::xml_attribute<> *attr = node->first_attribute("core");
 | 
			
		||||
 | 
			
		||||
    // Attribute not found - error
 | 
			
		||||
    if (!attr) {
 | 
			
		||||
        LOG_ERROR(TCONFIG, "PowerPC without 'core' attribute illegal!");
 | 
			
		||||
    } else {
 | 
			
		||||
        char core_str[12] = "null";
 | 
			
		||||
        
 | 
			
		||||
        // Convert to lowercase
 | 
			
		||||
        strcpy(core_str, attr->value());
 | 
			
		||||
        // TODO: not available on Unix
 | 
			
		||||
        common::LowerStr(core_str);
 | 
			
		||||
 | 
			
		||||
        // Use interpreter core
 | 
			
		||||
        if (E_OK == _stricmp(core_str, "interpreter")) {
 | 
			
		||||
            config.set_powerpc_core(Config::CPU_INTERPRETER);   // Interpreter selected
 | 
			
		||||
        // Use dynarec core
 | 
			
		||||
        } else if (E_OK == _stricmp(core_str, "dynarec")) {
 | 
			
		||||
            config.set_powerpc_core(Config::CPU_DYNAREC);       // Dynarec selected
 | 
			
		||||
        // Unsupported type
 | 
			
		||||
        } else {
 | 
			
		||||
            LOG_ERROR(TCONFIG, "Invalid PowerPC type %s for attribute 'core' selected!", 
 | 
			
		||||
                core_str);
 | 
			
		||||
        }
 | 
			
		||||
        // Set frequency
 | 
			
		||||
        attr = node->first_attribute("freq");
 | 
			
		||||
        if (attr) {
 | 
			
		||||
            config.set_powerpc_frequency(atoi(attr->value()));
 | 
			
		||||
        }
 | 
			
		||||
        LOG_NOTICE(TCONFIG, "Configured core=%s freq=%d", core_str, config.powerpc_frequency());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Parse the "Video" XML group
 | 
			
		||||
 * @param node RapidXML node for the "Video" XML group
 | 
			
		||||
 * @param config Config class object to parse data into
 | 
			
		||||
 */
 | 
			
		||||
void ParseVideoNode(rapidxml::xml_node<> *node, Config& config) {
 | 
			
		||||
    char res_str[512];
 | 
			
		||||
    Config::ResolutionType res;
 | 
			
		||||
 | 
			
		||||
    // Don't parse the node if it doesn't exist!
 | 
			
		||||
    if (!node) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    config.set_enable_fullscreen(GetXMLElementAsBool(node, "EnableFullscreen"));
 | 
			
		||||
    
 | 
			
		||||
    // Set resolutions
 | 
			
		||||
    GetXMLElementAsString(node, "WindowResolution", res_str);
 | 
			
		||||
    sscanf(res_str, "%d_%d", &res.width, &res.height);
 | 
			
		||||
    config.set_window_resolution(res);
 | 
			
		||||
    GetXMLElementAsString(node, "FullscreenResolution", res_str);
 | 
			
		||||
    sscanf(res_str, "%d_%d", &res.width, &res.height);
 | 
			
		||||
    config.set_fullscreen_resolution(res);
 | 
			
		||||
 | 
			
		||||
    // Parse all search renderer nodes
 | 
			
		||||
    for (rapidxml::xml_node<> *elem = node->first_node("Renderer"); 1; ) {
 | 
			
		||||
        Config::RendererConfig renderer_config;
 | 
			
		||||
 | 
			
		||||
        rapidxml::xml_attribute<> *attr = elem->first_attribute("name");
 | 
			
		||||
 | 
			
		||||
        Config::RendererType type = Config::StringToRenderType(attr->value());
 | 
			
		||||
        
 | 
			
		||||
        renderer_config.enable_wireframe = GetXMLElementAsBool(elem, "EnableWireframe");
 | 
			
		||||
        renderer_config.enable_shaders = GetXMLElementAsBool(elem, "EnableShaders");
 | 
			
		||||
        renderer_config.enable_textures = GetXMLElementAsBool(elem, "EnableTextures");
 | 
			
		||||
        renderer_config.enable_texture_dumping = GetXMLElementAsBool(elem, "EnableTextureDumping");
 | 
			
		||||
        renderer_config.anti_aliasing_mode = GetXMLElementAsInt(elem, "AntiAliasingMode");
 | 
			
		||||
        renderer_config.anistropic_filtering_mode = GetXMLElementAsInt(elem, "AnistropicFilteringMode");
 | 
			
		||||
 | 
			
		||||
        config.set_renderer_config(type, renderer_config);
 | 
			
		||||
 | 
			
		||||
        LOG_NOTICE(TCONFIG, "Renderer %s configured", attr->value());
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Parse the "Devices" XML group
 | 
			
		||||
 * @param node RapidXML node for the "Devices" XML group
 | 
			
		||||
 * @param config Config class object to parse data into
 | 
			
		||||
 */
 | 
			
		||||
void ParseDevicesNode(rapidxml::xml_node<> *node, Config& config) {
 | 
			
		||||
    // Don't parse the node if it doesn't exist!c
 | 
			
		||||
    if (!node) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // Parse GameCube section
 | 
			
		||||
    rapidxml::xml_node<> *gamecube_node = node->first_node("GameCube");
 | 
			
		||||
    if (!gamecube_node) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // Parse all MemSlot nodes
 | 
			
		||||
    for (rapidxml::xml_node<> *elem = gamecube_node->first_node("MemSlot"); elem; 
 | 
			
		||||
        elem = elem->next_sibling("MemSlot")) {
 | 
			
		||||
        Config::MemSlot slot_config;
 | 
			
		||||
 | 
			
		||||
        // Select MemSlot a or b
 | 
			
		||||
        rapidxml::xml_attribute<> *attr = elem->first_attribute("slot");
 | 
			
		||||
        int slot = (E_OK == _stricmp(attr->value(), "a")) ? 0 : 1;
 | 
			
		||||
        
 | 
			
		||||
        // Enable
 | 
			
		||||
        attr = elem->first_attribute("enable");
 | 
			
		||||
        slot_config.enable = (E_OK == _stricmp(attr->value(), "true")) ? true : false;
 | 
			
		||||
 | 
			
		||||
        // Select device
 | 
			
		||||
        attr = elem->first_attribute("device");
 | 
			
		||||
        slot_config.device = 0; // Only support memcards right now
 | 
			
		||||
 | 
			
		||||
        LOG_NOTICE(TCONFIG, "Configured MemSlot[%d]=%s enabled=%s", slot, attr->value(), 
 | 
			
		||||
            slot_config.enable ? "true" : "false");
 | 
			
		||||
 | 
			
		||||
        config.set_mem_slots(slot, slot_config);
 | 
			
		||||
    }
 | 
			
		||||
    // Parse all ControlerPort nodes
 | 
			
		||||
    for (rapidxml::xml_node<> *elem = gamecube_node->first_node("ControllerPort"); elem; 
 | 
			
		||||
            elem = elem->next_sibling("ControllerPort")) {
 | 
			
		||||
        Config::ControllerPort port_config;
 | 
			
		||||
 | 
			
		||||
        // Select MemSlot a or b
 | 
			
		||||
        rapidxml::xml_attribute<> *attr = elem->first_attribute("port");
 | 
			
		||||
        int port = atoi(attr->value());
 | 
			
		||||
 | 
			
		||||
        // Enable
 | 
			
		||||
        attr = elem->first_attribute("enable");
 | 
			
		||||
        port_config.enable = (E_OK == _stricmp(attr->value(), "true")) ? true : false;
 | 
			
		||||
        
 | 
			
		||||
        // Select device
 | 
			
		||||
        attr = elem->first_attribute("device");
 | 
			
		||||
        port_config.device = 0; // Only support memcards right now
 | 
			
		||||
 | 
			
		||||
        LOG_NOTICE(TCONFIG, "Configured ControllerPort[%d]=%s enabled=%s", port, attr->value(),
 | 
			
		||||
            port_config.enable ? "true" : "false");
 | 
			
		||||
 | 
			
		||||
        // Parse keyboard configuration - TODO: Move to EmuWindow (?)
 | 
			
		||||
        rapidxml::xml_node<> *keyboard_node = elem->first_node("KeyboardController");
 | 
			
		||||
        if (keyboard_node) {
 | 
			
		||||
            attr = keyboard_node->first_attribute("enable");
 | 
			
		||||
            port_config.keys.enable = (E_OK == _stricmp(attr->value(), "true")) ? true : false;
 | 
			
		||||
            port_config.keys.key_code[Config::BUTTON_A] = GetXMLElementAsInt(keyboard_node, "AKey");
 | 
			
		||||
            port_config.keys.key_code[Config::BUTTON_B] = GetXMLElementAsInt(keyboard_node, "BKey");
 | 
			
		||||
            port_config.keys.key_code[Config::BUTTON_X] = GetXMLElementAsInt(keyboard_node, "XKey");
 | 
			
		||||
            port_config.keys.key_code[Config::BUTTON_Y] = GetXMLElementAsInt(keyboard_node, "YKey");
 | 
			
		||||
            port_config.keys.key_code[Config::TRIGGER_L] = GetXMLElementAsInt(keyboard_node, "LKey");
 | 
			
		||||
            port_config.keys.key_code[Config::TRIGGER_R] = GetXMLElementAsInt(keyboard_node, "RKey");
 | 
			
		||||
            port_config.keys.key_code[Config::BUTTON_Z] = GetXMLElementAsInt(keyboard_node, "ZKey");
 | 
			
		||||
            port_config.keys.key_code[Config::BUTTON_START] = GetXMLElementAsInt(keyboard_node, "StartKey");
 | 
			
		||||
            port_config.keys.key_code[Config::ANALOG_UP] = GetXMLElementAsInt(keyboard_node, "AnalogUpKey");
 | 
			
		||||
            port_config.keys.key_code[Config::ANALOG_DOWN] = GetXMLElementAsInt(keyboard_node, "AnalogDownKey");
 | 
			
		||||
            port_config.keys.key_code[Config::ANALOG_LEFT] = GetXMLElementAsInt(keyboard_node, "AnalogLeftKey");
 | 
			
		||||
            port_config.keys.key_code[Config::ANALOG_RIGHT] = GetXMLElementAsInt(keyboard_node, "AnalogRightKey");
 | 
			
		||||
            port_config.keys.key_code[Config::C_UP] = GetXMLElementAsInt(keyboard_node, "CUpKey");
 | 
			
		||||
            port_config.keys.key_code[Config::C_DOWN] = GetXMLElementAsInt(keyboard_node, "CDownKey");
 | 
			
		||||
            port_config.keys.key_code[Config::C_LEFT] = GetXMLElementAsInt(keyboard_node, "CLeftKey");
 | 
			
		||||
            port_config.keys.key_code[Config::C_RIGHT] = GetXMLElementAsInt(keyboard_node, "CRightKey");
 | 
			
		||||
            port_config.keys.key_code[Config::DPAD_UP] = GetXMLElementAsInt(keyboard_node, "DPadUpKey");
 | 
			
		||||
            port_config.keys.key_code[Config::DPAD_DOWN] = GetXMLElementAsInt(keyboard_node, "DPadDownKey");
 | 
			
		||||
            port_config.keys.key_code[Config::DPAD_LEFT] = GetXMLElementAsInt(keyboard_node, "DPadLeftKey");
 | 
			
		||||
            port_config.keys.key_code[Config::DPAD_RIGHT] = GetXMLElementAsInt(keyboard_node, "DPadRightKey");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Parse joypad configuration
 | 
			
		||||
        rapidxml::xml_node<> *joypad_node = elem->first_node("JoypadController");
 | 
			
		||||
        if (joypad_node) {
 | 
			
		||||
            attr = joypad_node->first_attribute("enable");
 | 
			
		||||
            port_config.pads.enable = (E_OK == _stricmp(attr->value(), "true")) ? true : false;
 | 
			
		||||
            port_config.pads.key_code[Config::BUTTON_A] = GetXMLElementAsInt(joypad_node, "AKey");
 | 
			
		||||
            port_config.pads.key_code[Config::BUTTON_B] = GetXMLElementAsInt(joypad_node, "BKey");
 | 
			
		||||
            port_config.pads.key_code[Config::BUTTON_X] = GetXMLElementAsInt(joypad_node, "XKey");
 | 
			
		||||
            port_config.pads.key_code[Config::BUTTON_Y] = GetXMLElementAsInt(joypad_node, "YKey");
 | 
			
		||||
            port_config.pads.key_code[Config::TRIGGER_L] = GetXMLElementAsInt(joypad_node, "LKey");
 | 
			
		||||
            port_config.pads.key_code[Config::TRIGGER_R] = GetXMLElementAsInt(joypad_node, "RKey");
 | 
			
		||||
            port_config.pads.key_code[Config::BUTTON_Z] = GetXMLElementAsInt(joypad_node, "ZKey");
 | 
			
		||||
            port_config.pads.key_code[Config::BUTTON_START] = GetXMLElementAsInt(joypad_node, "StartKey");
 | 
			
		||||
            port_config.pads.key_code[Config::ANALOG_UP] = GetXMLElementAsInt(joypad_node, "AnalogUpKey");
 | 
			
		||||
            port_config.pads.key_code[Config::ANALOG_DOWN] = GetXMLElementAsInt(joypad_node, "AnalogDownKey");
 | 
			
		||||
            port_config.pads.key_code[Config::ANALOG_LEFT] = GetXMLElementAsInt(joypad_node, "AnalogLeftKey");
 | 
			
		||||
            port_config.pads.key_code[Config::ANALOG_RIGHT] = GetXMLElementAsInt(joypad_node, "AnalogRightKey");
 | 
			
		||||
            port_config.pads.key_code[Config::C_UP] = GetXMLElementAsInt(joypad_node, "CUpKey");
 | 
			
		||||
            port_config.pads.key_code[Config::C_DOWN] = GetXMLElementAsInt(joypad_node, "CDownKey");
 | 
			
		||||
            port_config.pads.key_code[Config::C_LEFT] = GetXMLElementAsInt(joypad_node, "CLeftKey");
 | 
			
		||||
            port_config.pads.key_code[Config::C_RIGHT] = GetXMLElementAsInt(joypad_node, "CRightKey");
 | 
			
		||||
            port_config.pads.key_code[Config::DPAD_UP] = GetXMLElementAsInt(joypad_node, "DPadUpKey");
 | 
			
		||||
            port_config.pads.key_code[Config::DPAD_DOWN] = GetXMLElementAsInt(joypad_node, "DPadDownKey");
 | 
			
		||||
            port_config.pads.key_code[Config::DPAD_LEFT] = GetXMLElementAsInt(joypad_node, "DPadLeftKey");
 | 
			
		||||
            port_config.pads.key_code[Config::DPAD_RIGHT] = GetXMLElementAsInt(joypad_node, "DPadRightKey");
 | 
			
		||||
        }
 | 
			
		||||
        config.set_controller_ports(port, port_config);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Loads/parses an XML configuration file
 | 
			
		||||
void LoadXMLConfig(Config& config, const char* filename) {
 | 
			
		||||
    // Open the XML file
 | 
			
		||||
    char full_filename[MAX_PATH];
 | 
			
		||||
    strcpy(full_filename, config.program_dir());
 | 
			
		||||
    strcat(full_filename, filename);
 | 
			
		||||
    std::ifstream ifs(full_filename);
 | 
			
		||||
 | 
			
		||||
    // Check that the file is valid
 | 
			
		||||
    if (ifs.fail()) {
 | 
			
		||||
        LOG_ERROR(TCONFIG, "XML configuration file %s failed to open!", filename);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // Read and parse XML string
 | 
			
		||||
    std::string xml_str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
 | 
			
		||||
    rapidxml::xml_document<> doc;
 | 
			
		||||
    doc.parse<0>(const_cast<char *>(xml_str.c_str()));  
 | 
			
		||||
 | 
			
		||||
    // Try to load a system configuration
 | 
			
		||||
    rapidxml::xml_node<> *node = doc.first_node("SysConfig");
 | 
			
		||||
 | 
			
		||||
    // Try to load a game configuation
 | 
			
		||||
    if (!node) {
 | 
			
		||||
        node = doc.first_node("GameConfig");
 | 
			
		||||
    }
 | 
			
		||||
    // Try to load a user configuation
 | 
			
		||||
    if (!node) {
 | 
			
		||||
        node = doc.first_node("UserConfig");
 | 
			
		||||
    }
 | 
			
		||||
    // Not proper XML format
 | 
			
		||||
    if (!node) {
 | 
			
		||||
        LOG_ERROR(TCONFIG, "XML configuration file incorrect format %s!", filename)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // Parse all sub nodes into the config
 | 
			
		||||
    ParseGeneralNode(node->first_node("General"),   config);
 | 
			
		||||
    ParseDebugNode(node->first_node("Debug"),       config);
 | 
			
		||||
    ParseBootNode(node->first_node("Boot"),         config);
 | 
			
		||||
    ParsePowerPCNode(node->first_node("PowerPC"),   config);
 | 
			
		||||
    ParseVideoNode(node->first_node("Video"),       config);
 | 
			
		||||
    ParseDevicesNode(node->first_node("Devices"),   config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
@ -1,41 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2005-2012 Gekko Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    xml.h
 | 
			
		||||
 * @author  ShizZy <shizzy247@gmail.com>
 | 
			
		||||
 * @date    2012-02-12
 | 
			
		||||
 * @brief   Used for parsing XML configurations
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 for more details at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COMMON_XML_H_
 | 
			
		||||
#define COMMON_XML_H_
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Loads/parses an XML configuration file
 | 
			
		||||
 * @param config Reference to configuration object to populate
 | 
			
		||||
 * @param filename Filename of XMl file to load
 | 
			
		||||
 */
 | 
			
		||||
void LoadXMLConfig(Config& config, const char* filename);
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
#endif // COMMON_XML_H_
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue