deleted gekko's common files
This commit is contained in:
		| @@ -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_ |  | ||||||
		Reference in New Issue
	
	Block a user