summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/src/atomic.h36
-rw-r--r--src/common/src/atomic_gcc.h72
-rw-r--r--src/common/src/atomic_win32.h76
-rw-r--r--src/common/src/common.h246
-rw-r--r--src/common/src/config.cpp118
-rw-r--r--src/common/src/config.h345
-rw-r--r--src/common/src/crc.cpp86
-rw-r--r--src/common/src/crc.h81
-rw-r--r--src/common/src/file_utils.cpp451
-rw-r--r--src/common/src/file_utils.h90
-rw-r--r--src/common/src/hash.cpp241
-rw-r--r--src/common/src/hash.h46
-rw-r--r--src/common/src/hash_container.h116
-rw-r--r--src/common/src/log.cpp152
-rw-r--r--src/common/src/log.h216
-rw-r--r--src/common/src/misc_utils.cpp91
-rw-r--r--src/common/src/misc_utils.h58
-rw-r--r--src/common/src/platform.h135
-rw-r--r--src/common/src/std_condition_variable.h152
-rw-r--r--src/common/src/std_mutex.h354
-rw-r--r--src/common/src/std_thread.h309
-rw-r--r--src/common/src/timer.cpp46
-rw-r--r--src/common/src/timer.h51
-rw-r--r--src/common/src/types.h119
-rw-r--r--src/common/src/x86_utils.cpp236
-rw-r--r--src/common/src/x86_utils.h92
-rw-r--r--src/common/src/xml.cpp487
-rw-r--r--src/common/src/xml.h41
28 files changed, 0 insertions, 4543 deletions
diff --git a/src/common/src/atomic.h b/src/common/src/atomic.h
deleted file mode 100644
index a6a03fee3..000000000
--- a/src/common/src/atomic.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file atomic.h
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-02-11
7 * @brief Cross-platform atomic operations
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_ATOMIC_H_
26#define COMMON_ATOMIC_H_
27
28#include "platform.h"
29
30#ifdef _WIN32
31#include "atomic_win32.h"
32#else
33#include "atomic_gcc.h"
34#endif
35
36#endif // COMMON_ATOMIC_H_ \ No newline at end of file
diff --git a/src/common/src/atomic_gcc.h b/src/common/src/atomic_gcc.h
deleted file mode 100644
index 660926561..000000000
--- a/src/common/src/atomic_gcc.h
+++ /dev/null
@@ -1,72 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file atomic_gcc.h
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-06-28
7 * @brief Cross-platform atomic operations - GCC
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_ATOMIC_GCC_H_
26#define COMMON_ATOMIC_GCC_H_
27
28#include "types.h"
29
30namespace common {
31
32inline void AtomicAdd(volatile u32& target, u32 value) {
33 __sync_add_and_fetch(&target, value);
34}
35
36inline void AtomicAnd(volatile u32& target, u32 value) {
37 __sync_and_and_fetch(&target, value);
38}
39
40inline void AtomicDecrement(volatile u32& target) {
41 __sync_add_and_fetch(&target, -1);
42}
43
44inline void AtomicIncrement(volatile u32& target) {
45 __sync_add_and_fetch(&target, 1);
46}
47
48inline u32 AtomicLoad(volatile u32& src) {
49 return src;
50}
51
52inline u32 AtomicLoadAcquire(volatile u32& src) {
53 u32 result = src;
54 __asm__ __volatile__ ( "":::"memory" );
55 return result;
56}
57
58inline void AtomicOr(volatile u32& target, u32 value) {
59 __sync_or_and_fetch(&target, value);
60}
61
62inline void AtomicStore(volatile u32& dest, u32 value) {
63 dest = value;
64}
65
66inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
67 __sync_lock_test_and_set(&dest, value);
68}
69
70} // namespace
71
72#endif // COMMON_ATOMIC_GCC_H_ \ No newline at end of file
diff --git a/src/common/src/atomic_win32.h b/src/common/src/atomic_win32.h
deleted file mode 100644
index 9dc4506cd..000000000
--- a/src/common/src/atomic_win32.h
+++ /dev/null
@@ -1,76 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file atomic_win32.h
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-06-28
7 * @brief Cross-platform atomic operations - Windows/Visual C++
8 * @remark Taken from Dolphin Emulator (http://code.google.com/p/dolphin-emu/)
9 *
10 * @section LICENSE
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details at
20 * http://www.gnu.org/copyleft/gpl.html
21 *
22 * Official project repository can be found at:
23 * http://code.google.com/p/gekko-gc-emu/
24 */
25
26#ifndef COMMON_ATOMIC_WIN32_H_
27#define COMMON_ATOMIC_WIN32_H_
28
29#include "types.h"
30
31#include <intrin.h>
32#include <Windows.h>
33
34namespace common {
35
36inline void AtomicAdd(volatile u32& target, u32 value) {
37 InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value);
38}
39
40inline void AtomicAnd(volatile u32& target, u32 value) {
41 _InterlockedAnd((volatile LONG*)&target, (LONG)value);
42}
43
44inline void AtomicIncrement(volatile u32& target) {
45 InterlockedIncrement((volatile LONG*)&target);
46}
47
48inline void AtomicDecrement(volatile u32& target) {
49 InterlockedDecrement((volatile LONG*)&target);
50}
51
52inline u32 AtomicLoad(volatile u32& src) {
53 return src;
54}
55
56inline u32 AtomicLoadAcquire(volatile u32& src) {
57 u32 result = src;
58 _ReadBarrier();
59 return result;
60}
61
62inline void AtomicOr(volatile u32& target, u32 value) {
63 _InterlockedOr((volatile LONG*)&target, (LONG)value);
64}
65
66inline void AtomicStore(volatile u32& dest, u32 value) {
67 dest = value;
68}
69inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
70 _WriteBarrier();
71 dest = value;
72}
73
74} // namespace
75
76#endif // COMMON_ATOMIC_WIN32_H_ \ No newline at end of file
diff --git a/src/common/src/common.h b/src/common/src/common.h
deleted file mode 100644
index f12cd461d..000000000
--- a/src/common/src/common.h
+++ /dev/null
@@ -1,246 +0,0 @@
1/*!
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * \file common.h
5 * \author ShizZy <shizzy247@gmail.com>
6 * \date 2012-02-04
7 * \brief Common header for using the common library
8 *
9 * \section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_COMMON_H_
26#define COMMON_COMMON_H_
27
28#include "platform.h"
29
30////////////////////////////////////////////////////////////////////////////////
31// Preprocessor stuff
32
33#define GEKKO_QUOTE_INPLACE(x) # x
34#define GEKKO_QUOTE(x) GEKKO_QUOTE_INPLACE(x)
35#define __FILE__LINE__ __FILE__ "(" GEKKO_QUOTE(__LINE__) ") : "
36#define GEKKO_TODO(x) __FILE__LINE__ x "\n"
37
38#if EMU_PLATFORM == PLATFORM_WINDOWS
39
40// All inline assembly is x86 right now!
41#ifdef EMU_ARCHITECTURE_X86
42#define USE_INLINE_ASM_X86
43#endif // EMU_ARCHITECTURE_X86
44
45#pragma warning( disable : 4786 ) //disable the truncated 255 character limit warning for debug identifiers
46
47#ifdef LEAK_DETECT
48#define _CRTDBG_MAP_ALLOC
49#define _INC_MALLOC
50#include <stdlib.h>
51#include <crtdbg.h>
52#endif // LEAK_DETECT
53
54#define TODO( x ) message( __FILE__LINE__" TODO : " #x "\n" )
55#define todo( x ) message( __FILE__LINE__" TODO : " #x "\n" )
56
57#endif // PLATFORM_WINDOWS
58
59#define E_OK 0
60#define E_ERR 1
61
62////////////////////////////////////////////////////////////////////////////////
63// Includes
64#include <xmmintrin.h>
65
66////////////////////////////////////////////////////////////////////////////////
67// C Includes
68#include <cmath>
69#include <cstdarg>
70#include <cstdio>
71#include <cstdlib>
72#include <ctime>
73#include <csignal>
74
75////////////////////////////////////////////////////////////////////////////////
76// C++ Includes
77#include <algorithm>
78#include <fstream>
79#include <iostream>
80#include <map>
81#include <sstream>
82#include <string>
83
84////////////////////////////////////////////////////////////////////////////////
85// OS-Specific Includes
86#if EMU_PLATFORM == PLATFORM_WINDOWS
87 #include <direct.h>
88 #include <windows.h>
89 #include <commctrl.h>
90 #include <commdlg.h>
91 #include <shlwapi.h>
92 #include <shlobj.h>
93#endif
94
95////////////////////////////////////////////////////////////////////////////////
96// Big Endian bit Access (Bits numbered ascending from leftmost to rightmost)
97#define BIT_0 0x80000000
98#define BIT_1 0x40000000
99#define BIT_2 0x20000000
100#define BIT_3 0x10000000
101#define BIT_4 0x8000000
102#define BIT_5 0x4000000
103#define BIT_6 0x2000000
104#define BIT_7 0x1000000
105#define BIT_8 0x800000
106#define BIT_9 0x400000
107#define BIT_10 0x200000
108#define BIT_11 0x100000
109#define BIT_12 0x80000
110#define BIT_13 0x40000
111#define BIT_14 0x20000
112#define BIT_15 0x10000
113#define BIT_16 0x8000
114#define BIT_17 0x4000
115#define BIT_18 0x2000
116#define BIT_19 0x1000
117#define BIT_20 0x800
118#define BIT_21 0x400
119#define BIT_22 0x200
120#define BIT_23 0x100
121#define BIT_24 0x80
122#define BIT_25 0x40
123#define BIT_26 0x20
124#define BIT_27 0x10
125#define BIT_28 0x8
126#define BIT_29 0x4
127#define BIT_30 0x2
128#define BIT_31 0x1
129
130#define SIGNED_BIT8 ((u8) 1 << 7)
131#define SIGNED_BIT16 ((u16) 1 << 15)
132#define SIGNED_BIT32 ((u32) 1 << 31)
133#define SIGNED_BIT64 ((u64) 1 << 63)
134
135// A macro to disallow the copy constructor and operator= functions
136// This should be used in the private: declarations for a class
137#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
138 TypeName(const TypeName&); \
139 void operator=(const TypeName&)
140
141#ifdef _DEBUG
142 #ifndef _DEBUGSPEED
143 #define DEBUG_EMU
144 #define DEBUG_GX
145 #endif
146#endif
147
148#ifdef DEBUG_EMU
149#define ASSERT_T(cond,str) if((cond)) printf("#!\tERROR: ASSERTION FAILED: %s !\n", str);
150#define ASSERT_F(cond,str) if(!(cond)) printf("#!\tERROR: ASSERTION FAILED: %s !\n", str);
151#else
152#define ASSERT_T(cond,str)
153#define ASSERT_F(cond,str)
154#endif
155
156////////////////////////////////////////////////////////////////////////////////
157
158void DisplayError (char * Message, ...);
159
160#ifdef _MSC_VER
161# ifdef LEAK_DETECT
162# undef malloc
163# define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__, __LINE__)
164# define new DEBUG_NEW
165# define malloc(s) _malloc_dbg(s,_NORMAL_BLOCK,__FILE__,__LINE__)
166# define realloc(p, s) _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)
167# define free(p) _free_dbg(p, _NORMAL_BLOCK)
168# endif
169# define U64(a) a ## ui64
170# define S64(a) a ## si64
171#else //gcc
172# define U64(a) a ## ull
173# define S64(a) a ## sll
174#endif
175
176////////////////////////////////////////////////////////////////////////////////
177
178#include "types.h"
179#include "log.h"
180#include "atomic.h"
181#include "misc_utils.h"
182#include "x86_utils.h"
183
184////////////////////////////////////////////////////////////////////////////////
185
186__inline static s16 toSHORT(u16 x)
187{
188 return *(s16*)&x;
189}
190
191__inline static f32 toFLOAT(u32 x)
192{
193 return *(f32*)&x;
194}
195
196__inline static f32 toFLOATS(s32 x)
197{
198 return *(f32*)&x;
199}
200
201__inline static f64 toDOUBLE(u64 x)
202{
203 return *(f64*)&x;
204}
205
206typedef void(*optable)(void);
207typedef void(EMU_FASTCALL *hwtable)(u32, u32*);
208
209////////////////////////////////////////////////////////////////////////////////
210// Fast Macros
211
212#define MIN(a,b) ((a)<(b)?(a):(b))
213#define MAX(a,b) ((a)>(b)?(a):(b))
214
215#define CLAMP(X,min,max) (((X) > max) ? max : (((X) < min) ? min : (X)))
216
217__inline static u32 BSWAP24(u32 x)
218{
219 return (((x & 0xff0000) >> 16) | (x & 0xff00) | ((x & 0xff) << 16));
220}
221
222#if _MSC_VER > 1200
223
224#define BSWAP16(x) _byteswap_ushort(x)
225#define BSWAP32(x) _byteswap_ulong(x)
226#define BSWAP64(x) _byteswap_uint64(x)
227
228#else
229__inline static u16 BSWAP16(u16 x)
230{
231 return ((x)>>8) | ((x)<<8);
232}
233
234__inline static u32 BSWAP32(u32 x)
235{
236 return (BSWAP16((x)&0xffff)<<16) | (BSWAP16((x)>>16));
237}
238
239__inline static u64 BSWAP64(u64 x)
240{
241 return (u64)(((u64)BSWAP32((u32)(x&0xffffffff)))<<32) | (BSWAP32((u32)(x>>32)));
242}
243#endif
244
245
246#endif // COMMON_COMMON_H_
diff --git a/src/common/src/config.cpp b/src/common/src/config.cpp
deleted file mode 100644
index c26789bf8..000000000
--- a/src/common/src/config.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file config.cpp
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-02-19
7 * @brief Emulator configuration class - all config settings stored here
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#include "common.h"
26#include "config.h"
27#include "xml.h"
28
29namespace common {
30
31Config* g_config;
32
33Config::Config() {
34 ResolutionType default_res;
35 RendererConfig default_renderer_config;
36
37 default_renderer_config.enable_wireframe = false;
38 default_renderer_config.enable_shaders = true;
39 default_renderer_config.enable_texture_dumping = false;
40 default_renderer_config.enable_textures = true;
41 default_renderer_config.anti_aliasing_mode = 0;
42 default_renderer_config.anistropic_filtering_mode = 0;
43
44 default_res.width = 640;
45 default_res.height = 480;
46
47 set_program_dir("", MAX_PATH);
48 set_enable_multicore(true);
49 set_enable_idle_skipping(false);
50 set_enable_hle(true);
51 set_enable_auto_boot(true);
52 set_enable_cheats(false);
53 set_default_boot_file("", MAX_PATH);
54 memset(dvd_image_paths_, 0, sizeof(dvd_image_paths_));
55 set_enable_show_fps(true);
56 set_enable_dump_opcode0(false);
57 set_enable_pause_on_unknown_opcode(true);
58 set_enable_dump_gcm_reads(false);
59 set_enable_ipl(false);
60 set_powerpc_core(CPU_INTERPRETER);
61 set_powerpc_frequency(486);
62
63 memset(renderer_config_, 0, sizeof(renderer_config_));
64 set_renderer_config(RENDERER_OPENGL_3, default_renderer_config);
65 set_current_renderer(RENDERER_OPENGL_3);
66
67 set_enable_fullscreen(false);
68 set_window_resolution(default_res);
69 set_fullscreen_resolution(default_res);
70
71 memset(controller_ports_, 0, sizeof(controller_ports_));
72 memset(mem_slots_, 0, sizeof(mem_slots_));
73
74 memset(patches_, 0, sizeof(patches_));
75 memset(cheats_, 0, sizeof(patches_));
76}
77
78Config::~Config() {
79}
80
81ConfigManager::ConfigManager() {
82 set_program_dir("", MAX_PATH);
83}
84
85ConfigManager::~ConfigManager() {
86}
87
88/**
89 * @brief Reload a game-specific configuration
90 * @param id Game id (to load game specific configuration)
91 */
92void ConfigManager::ReloadGameConfig(const char* id) {
93 char full_filename[MAX_PATH];
94 sprintf(full_filename, "user/games/%s.xml", id);
95 common::LoadXMLConfig(*g_config, full_filename);
96}
97
98/// Reload the userconfig file
99void ConfigManager::ReloadUserConfig() {
100 common::LoadXMLConfig(*g_config, "userconf.xml");
101}
102
103/// Reload the sysconfig file
104void ConfigManager::ReloadSysConfig() {
105 common::LoadXMLConfig(*g_config, "sysconf.xml");
106}
107
108/// Reload all configurations
109void ConfigManager::ReloadConfig(const char* game_id) {
110 delete g_config;
111 g_config = new Config();
112 g_config->set_program_dir(program_dir_, MAX_PATH);
113 ReloadSysConfig();
114 ReloadUserConfig();
115 ReloadGameConfig(game_id);
116}
117
118} // namspace \ No newline at end of file
diff --git a/src/common/src/config.h b/src/common/src/config.h
deleted file mode 100644
index 843d0d312..000000000
--- a/src/common/src/config.h
+++ /dev/null
@@ -1,345 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file config.h
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-02-11
7 * @brief Emulator configuration class - all config settings stored here
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_CONFIG_H_
26#define COMMON_CONFIG_H_
27
28#include "common.h"
29
30#define MAX_SEARCH_PATHS 16 ///< Maximum paths to search for files in
31
32/// If you need more than this... you're just lazy ;-)
33#define MAX_PATCHES_PER_GAME 128 ///< Maximum patches allowed per game
34
35namespace common {
36
37/// Class for storing emulator configuration(s)
38class Config {
39public:
40 Config();
41 ~Config();
42
43 /// Struct used for defining game-specific patches
44 struct Patch {
45 u32 address; ///< Address to patch
46 u32 data; ///< Data to write at the specified address
47 };
48
49 /// Struct used for configuring what is inserted in a memory slot
50 struct MemSlot {
51 u8 device; ///< Memory slot device (0 - memcard)
52 bool enable; ///< Enable (plugged in?)
53 };
54
55 enum Control {
56 BUTTON_A = 0,
57 BUTTON_B,
58 BUTTON_X,
59 BUTTON_Y,
60 TRIGGER_L,
61 TRIGGER_R,
62 BUTTON_Z,
63 BUTTON_START,
64 ANALOG_UP,
65 ANALOG_DOWN,
66 ANALOG_LEFT,
67 ANALOG_RIGHT,
68 C_UP,
69 C_DOWN,
70 C_LEFT,
71 C_RIGHT,
72 DPAD_UP,
73 DPAD_DOWN,
74 DPAD_LEFT,
75 DPAD_RIGHT,
76 NUM_CONTROLS
77 };
78
79 /// Struct used for defining a keyboard configuration for a GameCube controller
80 /// Reads/Writes from/to members should be atomic
81 struct KeyboardController {
82 bool enable; ///< Is the keyboard configation enabled?
83 int key_code[NUM_CONTROLS];
84 };
85
86 /// Struct used for defining a joypad configuration for a GameCube controller
87 /// We'll make another struct in case the user wants seperate joypad config
88 struct JoypadController {
89 bool enable; ///< Is the joypad configation enabled?
90 int key_code[NUM_CONTROLS];
91 };
92
93 /// Struct used for configuring what is inserted in a controller port
94 typedef struct {
95 u8 device; ///< Controller port device (0 - controller)
96 bool enable; ///< Enable (plugged in?)
97 KeyboardController keys; ///< Keyboard configuration for controller (if used)
98 JoypadController pads; ///< Joypad configuration for controller (if used)
99 } ControllerPort;
100
101 /// Enum for supported CPU types
102 enum CPUCoreType {
103 CPU_NULL = 0, ///< No CPU core
104 CPU_INTERPRETER, ///< Interpreter CPU core
105 CPU_DYNAREC, ///< Dynamic recompiler CPU core
106 NUMBER_OF_CPU_CONFIGS
107 };
108
109 /// Struct used for defining a renderer configuration
110 struct RendererConfig {
111 bool enable_wireframe;
112 bool enable_shaders;
113 bool enable_texture_dumping;
114 bool enable_textures;
115 int anti_aliasing_mode;
116 int anistropic_filtering_mode;
117 } ;
118
119 /// Struct used for configuring a screen resolution
120 struct ResolutionType {
121 int width;
122 int height;
123 };
124
125 /// Enum for supported video cores
126 enum RendererType {
127 RENDERER_NULL, ///< No video core
128 RENDERER_OPENGL_2, ///< OpenGL 2.0 core
129 RENDERER_OPENGL_3, ///< OpenGL 3.0 core (not implemented)
130 RENDERER_DIRECTX9, ///< DirectX9 core (not implemented)
131 RENDERER_DIRECTX10, ///< DirectX10 core (not implemented)
132 RENDERER_DIRECTX11, ///< DirectX11 core (not implemented)
133 RENDERER_SOFTWARE, ///< Software core (not implemented)
134 RENDERER_HARDWARE, ///< Hardware core (not implemented- this would be a driver)
135 NUMBER_OF_VIDEO_CONFIGS
136 };
137
138 char* program_dir() { return program_dir_; }
139 void set_program_dir(const char* val, size_t size) { strcpy(program_dir_, val); }
140
141 bool enable_multicore() { return enable_multicore_; }
142 bool enable_idle_skipping() {return enable_idle_skipping_; }
143 bool enable_hle() { return enable_hle_; }
144 bool enable_auto_boot() { return enable_auto_boot_; }
145 bool enable_cheats() { return enable_cheats_; }
146 void set_enable_multicore(bool val) { enable_multicore_ = val; }
147 void set_enable_idle_skipping(bool val) {enable_idle_skipping_ = val; }
148 void set_enable_hle(bool val) { enable_hle_ = val; }
149 void set_enable_auto_boot(bool val) { enable_auto_boot_ = val; }
150 void set_enable_cheats(bool val) { enable_cheats_ = val; }
151
152 char* default_boot_file() { return default_boot_file_; }
153 char* dvd_image_path(int path) { return dvd_image_paths_[path]; }
154 void set_default_boot_file(const char* val, size_t size) { strcpy(default_boot_file_, val); }
155 void set_dvd_image_path(int path, char* val, size_t size) { strcpy(dvd_image_paths_[path], val); }
156
157 bool enable_show_fps() { return enable_show_fps_; }
158 bool enable_dump_opcode0() { return enable_dump_opcode0_; }
159 bool enable_pause_on_unknown_opcode() { return enable_pause_on_unknown_opcode_; }
160 bool enable_dump_gcm_reads() { return enable_dump_gcm_reads_; }
161 void set_enable_show_fps(bool val) { enable_show_fps_ = val; }
162 void set_enable_dump_opcode0(bool val) { enable_dump_opcode0_ = val; }
163 void set_enable_pause_on_unknown_opcode(bool val) { enable_pause_on_unknown_opcode_ = val; }
164 void set_enable_dump_gcm_reads(bool val) { enable_dump_gcm_reads_ = val; }
165
166 bool enable_ipl() { return enable_ipl_; }
167 void set_enable_ipl(bool val) { enable_ipl_ = val; }
168
169 Patch patches(int patch) { return patches_[patch]; }
170 Patch cheats(int cheat) { return cheats_[cheat]; }
171 void set_patches(int patch, Patch val) { patches_[patch] = val; }
172 void set_cheats(int cheat, Patch val) { cheats_[cheat] = val; }
173
174 CPUCoreType powerpc_core() { return powerpc_core_; }
175 void set_powerpc_core(CPUCoreType val) { powerpc_core_ = val; }
176
177 int powerpc_frequency() { return powerpc_frequency_; }
178 void set_powerpc_frequency(int val) { powerpc_frequency_ = val; }
179
180 RendererType current_renderer() { return current_renderer_; }
181 void set_current_renderer(RendererType val) { current_renderer_ = val; }
182
183 RendererConfig renderer_config(RendererType val) { return renderer_config_[val]; }
184 RendererConfig current_renderer_config() { return renderer_config_[current_renderer_]; }
185 void set_renderer_config(RendererType renderer, RendererConfig config) {
186 renderer_config_[renderer] = config;
187 }
188
189 bool enable_fullscreen() { return enable_fullscreen_; }
190 void set_enable_fullscreen(bool val) { enable_fullscreen_ = val; }
191
192 ResolutionType window_resolution() { return window_resolution_; }
193 ResolutionType fullscreen_resolution() { return fullscreen_resolution_; }
194 void set_window_resolution(ResolutionType val) { window_resolution_ = val; }
195 void set_fullscreen_resolution(ResolutionType val) { fullscreen_resolution_ = val; }
196
197 // TODO: Should be const, but pending removal of some gekko_qt hacks
198 /*const */ControllerPort& controller_ports(int port) { return controller_ports_[port]; }
199 void set_controller_ports(int port, ControllerPort val) { controller_ports_[port] = val; }
200
201 MemSlot mem_slots(int slot) { return mem_slots_[slot]; }
202 void set_mem_slots(int slot, MemSlot val) { mem_slots_[slot] = val; }
203
204 /**
205 * @brief Gets a RenderType from a string (used from XML)
206 * @param renderer_str Renderer name string, see XML schema for list
207 * @return Corresponding RenderType
208 */
209 static inline RendererType StringToRenderType(const char* renderer_str) {
210 if (E_OK == _stricmp(renderer_str, "opengl2")) {
211 return RENDERER_OPENGL_2;
212 } else if (E_OK == _stricmp(renderer_str, "opengl3")) {
213 return RENDERER_OPENGL_3;
214 } else if (E_OK == _stricmp(renderer_str, "directx9")) {
215 return RENDERER_DIRECTX9;
216 } else if (E_OK == _stricmp(renderer_str, "directx10")) {
217 return RENDERER_DIRECTX10;
218 } else if (E_OK == _stricmp(renderer_str, "directx11")) {
219 return RENDERER_DIRECTX11;
220 } else if (E_OK == _stricmp(renderer_str, "software")) {
221 return RENDERER_SOFTWARE;
222 } else if (E_OK == _stricmp(renderer_str, "hardware")) {
223 return RENDERER_HARDWARE;
224 } else {
225 return RENDERER_NULL;
226 }
227 }
228
229 /**
230 * @brief Gets the renderer string from the type
231 * @param renderer Renderer to get string for
232 * @return Renderer string name
233 */
234 static std::string RenderTypeToString(RendererType renderer) {
235 switch (renderer) {
236 case RENDERER_OPENGL_2:
237 return "opengl2";
238 case RENDERER_OPENGL_3:
239 return "opengl3";
240 case RENDERER_DIRECTX9:
241 return "directx9";
242 case RENDERER_DIRECTX10:
243 return "directx10";
244 case RENDERER_DIRECTX11:
245 return "directx11";
246 case RENDERER_SOFTWARE:
247 return "software";
248 case RENDERER_HARDWARE:
249 return "hardware";
250 }
251 return "null";
252 }
253
254 /**
255 * @brief Gets the CPU string from the type
256 * @param cpu CPU to get string for
257 * @param cpu_str String result
258 * @param size Max size to write to string
259 */
260 static std::string CPUCoreTypeToString(CPUCoreType cpu) {
261 switch (cpu) {
262 case CPU_INTERPRETER:
263 return "interpreter";
264 case CPU_DYNAREC:
265 return "dynarec";
266 }
267 return "null";
268 }
269
270private:
271 char program_dir_[MAX_PATH];
272
273 bool enable_multicore_;
274 bool enable_idle_skipping_;
275 bool enable_hle_;
276 bool enable_auto_boot_;
277 bool enable_cheats_;
278
279 char default_boot_file_[MAX_PATH];
280 char dvd_image_paths_[MAX_SEARCH_PATHS][MAX_PATH];
281
282 bool enable_show_fps_;
283 bool enable_dump_opcode0_;
284 bool enable_pause_on_unknown_opcode_;
285 bool enable_dump_gcm_reads_;
286
287 bool enable_ipl_;
288
289 Patch patches_[MAX_PATCHES_PER_GAME];
290 Patch cheats_[MAX_PATCHES_PER_GAME];
291
292 CPUCoreType powerpc_core_;
293
294 int powerpc_frequency_;
295
296 bool enable_fullscreen_;
297
298 RendererType current_renderer_;
299
300 ResolutionType window_resolution_;
301 ResolutionType fullscreen_resolution_;
302
303 RendererConfig renderer_config_[NUMBER_OF_VIDEO_CONFIGS];
304
305 MemSlot mem_slots_[2];
306 ControllerPort controller_ports_[4];
307
308 DISALLOW_COPY_AND_ASSIGN(Config);
309};
310
311class ConfigManager {
312public:
313 ConfigManager();
314 ~ConfigManager();
315
316 /**
317 * @brief Reload a game-specific configuration
318 * @param id Game id (to load game specific configuration)
319 */
320 void ReloadGameConfig(const char* id);
321
322 /// Reload the userconfig file
323 void ReloadUserConfig();
324
325 // Reload the sysconfig file
326 void ReloadSysConfig();
327
328 /// Reload all configurations
329 void ReloadConfig(const char* game_id);
330
331 char* program_dir() { return program_dir_; }
332
333 void set_program_dir(const char* val, size_t size) { strcpy(program_dir_, val); }
334
335private:
336 char program_dir_[MAX_PATH]; ///< Program directory, used for loading config files
337
338 DISALLOW_COPY_AND_ASSIGN(ConfigManager);
339};
340
341extern Config* g_config; ///< Global configuration for emulator
342
343} // namspace
344
345#endif // COMMON_CONFIG_H_
diff --git a/src/common/src/crc.cpp b/src/common/src/crc.cpp
deleted file mode 100644
index a36dfdad8..000000000
--- a/src/common/src/crc.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
1#include "common.h"
2#include "crc.h"
3
4u32 crc32_table[4][256];
5
6u32 Reflect(u32 ref, u8 Count)
7{
8 u32 value = 0;
9
10 // Swap bit 0 for bit 7
11 // bit 1 for bit 6, etc.
12 for(int i = 1; i < (Count + 1); i++)
13 {
14 if(ref & 1)
15 value |= 1 << (Count - i);
16 ref >>= 1;
17 }
18 return value;
19}
20
21void Init_CRC32_Table()
22{
23 // This is the official polynomial used by CRC-32
24 // in PKZip, WinZip and Ethernet.
25 u32 ulPolynomial = 0x04c11db7;
26
27 // 256 values representing ASCII character codes.
28 for(int x = 0; x < 4; x++)
29 {
30 for(int i = 0; i <= 0xFF; i++)
31 {
32 crc32_table[x][i]=Reflect(i, 8) << 24;
33 for (int j = 0; j < 8; j++)
34 crc32_table[x][i] = (crc32_table[x][i] << 1) ^ (crc32_table[x][i] & (1 << 31) ? (ulPolynomial + (x * 8)) : 0);
35 crc32_table[x][i] = Reflect(crc32_table[x][i], 32);
36 }
37 }
38}
39
40u32 GenerateCRC(u8 *StartAddr, u32 len)
41{
42 u32 ulCRC = -1;
43
44 // Perform the algorithm on each character
45 // in the string, using the lookup table values.
46 for(; len > 7; len-=8)
47 {
48 ulCRC ^= *(u32 *)StartAddr;
49 ulCRC = crc32_table[3][((ulCRC) & 0xFF)] ^
50 crc32_table[2][((ulCRC >> 8) & 0xFF)] ^
51 crc32_table[1][((ulCRC >> 16) & 0xFF)] ^
52 crc32_table[0][((ulCRC >> 24))];
53 ulCRC ^= *(u32 *)(StartAddr + 4);
54 ulCRC = crc32_table[3][((ulCRC) & 0xFF)] ^
55 crc32_table[2][((ulCRC >> 8) & 0xFF)] ^
56 crc32_table[1][((ulCRC >> 16) & 0xFF)] ^
57 crc32_table[0][((ulCRC >> 24))];
58 StartAddr+=8;
59 }
60
61 if(len > 3)
62 {
63 ulCRC ^= *(u32 *)StartAddr;
64 ulCRC = crc32_table[3][((ulCRC) & 0xFF)] ^
65 crc32_table[2][((ulCRC >> 8) & 0xFF)] ^
66 crc32_table[1][((ulCRC >> 16) & 0xFF)] ^
67 crc32_table[0][((ulCRC >> 24))];
68 StartAddr+=4;
69 len -= 4;
70 }
71
72 switch(len)
73 {
74 case 3:
75 ulCRC = crc32_table[0][(ulCRC & 0xFF) ^ *StartAddr] ^ (ulCRC >> 8);
76 StartAddr++;
77 case 2:
78 ulCRC = crc32_table[0][(ulCRC & 0xFF) ^ *StartAddr] ^ (ulCRC >> 8);
79 StartAddr++;
80 case 1:
81 ulCRC = crc32_table[0][(ulCRC & 0xFF) ^ *StartAddr] ^ (ulCRC >> 8);
82 StartAddr++;
83 }
84
85 return ulCRC;
86}
diff --git a/src/common/src/crc.h b/src/common/src/crc.h
deleted file mode 100644
index 2bb3210d8..000000000
--- a/src/common/src/crc.h
+++ /dev/null
@@ -1,81 +0,0 @@
1#ifndef COMMON_CRC_H_
2#define COMMON_CRC_H_
3
4#include "types.h"
5#include "platform.h"
6
7#define CRC_ROTL(crc) crc32_table[3][((crc) & 0xFF)] ^ crc32_table[2][((crc >> 8) & 0xFF)] ^ \
8 crc32_table[1][((crc >> 16) & 0xFF)] ^ crc32_table[0][((crc >> 24))]
9
10// Some definitions for using the X86 CRC32 instruction on different platforms. Keep in mind, you
11// should check for X86/X64 architecture support before using these, as well as for SSE 4.2 (see the
12// x86_utils module).
13
14#if defined(EMU_ARCHITECTURE_X86) || defined(EMU_ARCHITECTURE_X64)
15
16#if EMU_PLATFORM == PLATFORM_WINDOWS
17
18#include <nmmintrin.h>
19
20#ifdef EMU_ARCHITECTURE_X64
21static inline u64 InlineCrc32_U64(u64 crc, u64 value) {
22 return _mm_crc32_u64(crc, value);
23}
24#endif
25static inline u32 InlineCrc32_U32(u32 crc, u64 value) {
26 return _mm_crc32_u32(crc, static_cast<u32>(value));
27}
28
29static inline u32 InlineCrc32_U8(u32 crc, u8 value) {
30 return _mm_crc32_u8(crc, value);
31}
32
33#elif GCC_VERSION_AVAILABLE(4, 5) && defined(__SSE4_2__)
34
35extern inline unsigned int __attribute__((
36 __gnu_inline__, __always_inline__, __artificial__))
37InlineCrc32_U8(unsigned int __C, unsigned char __V) {
38 return __builtin_ia32_crc32qi(__C, __V);
39}
40#ifdef EMU_ARCHITECTURE_X64
41extern inline unsigned long long __attribute__((
42 __gnu_inline__, __always_inline__, __artificial__))
43InlineCrc32_U64(unsigned long long __C, unsigned long long __V) {
44 return __builtin_ia32_crc32di(__C, __V);
45}
46#else
47extern inline unsigned int __attribute__((
48 __gnu_inline__, __always_inline__, __artificial__))
49InlineCrc32_U32(unsigned int __C, unsigned int __V) {
50 return __builtin_ia32_crc32si (__C, __V);
51}
52#endif // EMU_ARCHITECTURE_X64
53
54#else
55
56// GCC 4.4.x and earlier: use inline asm, or msse4.2 flag not set
57
58static inline u64 InlineCrc32_U64(u64 crc, u64 value) {
59 asm("crc32q %[value], %[crc]\n" : [crc] "+r" (crc) : [value] "rm" (value));
60 return crc;
61}
62
63static inline u32 InlineCrc32_U32(u32 crc, u64 value) {
64 asm("crc32l %[value], %[crc]\n" : [crc] "+r" (crc) : [value] "rm" (value));
65 return crc;
66}
67
68static inline u32 InlineCrc32_U8(u32 crc, u8 value) {
69 asm("crc32b %[value], %[crc]\n" : [crc] "+r" (crc) : [value] "rm" (value));
70 return crc;
71}
72#endif
73
74#endif // EMU_ARCHITECTURE_X86 or EMU_ARCHITECTURE_X64
75
76extern u32 crc32_table[4][256];
77
78void Init_CRC32_Table();
79u32 GenerateCRC(u8 *StartAddr, u32 Len);
80
81#endif // COMMON_CRC_H_
diff --git a/src/common/src/file_utils.cpp b/src/common/src/file_utils.cpp
deleted file mode 100644
index 6e792fcde..000000000
--- a/src/common/src/file_utils.cpp
+++ /dev/null
@@ -1,451 +0,0 @@
1/**
2* Copyright (C) 2005-2013 Gekko Emulator
3*
4* @file file_utils.cpp
5* @author ShizZy <shizzy247@gmail.com>
6* @date 2013-01-27
7* @brief Crossplatform file utility functions
8* @remark Borrowed from Dolphin Emulator
9*
10* @section LICENSE
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License as
13* published by the Free Software Foundation; either version 2 of
14* the License, or (at your option) any later version.
15*
16* This program is distributed in the hope that it will be useful, but
17* WITHOUT ANY WARRANTY; without even the implied warranty of
18* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19* General Public License for more details at
20* http://www.gnu.org/copyleft/gpl.html
21*
22* Official project repository can be found at:
23* http://code.google.com/p/gekko-gc-emu/
24*/
25
26#include "types.h"
27#include "file_utils.h"
28
29#ifdef _WIN32
30#include <windows.h>
31#include <shlobj.h> // for SHGetFolderPath
32#include <shellapi.h>
33#include <commdlg.h> // for GetSaveFileName
34#include <io.h>
35#include <direct.h> // getcwd
36#else
37#include <sys/param.h>
38#include <sys/types.h>
39#include <dirent.h>
40#include <errno.h>
41#include <stdlib.h>
42#include <unistd.h>
43#endif
44
45#if defined(__APPLE__)
46#include <CoreFoundation/CFString.h>
47#include <CoreFoundation/CFURL.h>
48#include <CoreFoundation/CFBundle.h>
49#endif
50
51#include <fstream>
52#include <sys/stat.h>
53
54#ifndef S_ISDIR
55#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
56#endif
57
58#ifdef BSD4_4
59#define stat64 stat
60#define fstat64 fstat
61#endif
62
63#ifdef _MSC_VER
64#define __strdup _strdup
65#define __getcwd _getcwd
66#define __chdir _chdir
67
68#define fseeko _fseeki64
69#define ftello _ftelli64
70#define atoll _atoi64
71#define stat64 _stat64
72#define fstat64 _fstat64
73#define fileno _fileno
74
75#else
76#define __strdup strdup
77#define __getcwd getcwd
78#define __chdir chdir
79#endif
80
81namespace common {
82
83// Remove any ending forward slashes from directory paths
84// Modifies argument.
85static void StripTailDirSlashes(std::string &fname) {
86 if (fname.length() > 1) {
87 size_t i = fname.length() - 1;
88 while (fname[i] == '/') {
89 fname[i--] = '\0';
90 }
91 }
92}
93
94// Returns true if file filename exists
95bool FileExists(const std::string &filename) {
96 struct stat64 file_info;
97 std::string copy(filename);
98 StripTailDirSlashes(copy);
99 return (stat64(copy.c_str(), &file_info) == 0);
100}
101
102// Returns true if filename is a directory
103bool IsDirectory(const std::string &filename) {
104 struct stat64 file_info;
105 std::string copy(filename);
106 StripTailDirSlashes(copy);
107 if (stat64(copy.c_str(), &file_info) < 0) {
108 LOG_WARNING(TCOMMON, "IsDirectory: stat failed on %s", filename.c_str());
109 return false;
110 }
111 return S_ISDIR(file_info.st_mode);
112}
113
114// Deletes a given filename, return true on success
115// Doesn't supports deleting a directory
116bool DeleteFile(const std::string &filename) {
117 LOG_INFO(TCOMMON, "Delete: file %s", filename.c_str());
118 // Return true because we care about the file no
119 // being there, not the actual delete.
120 if (!FileExists(filename)) {
121 LOG_WARNING(TCOMMON, "Delete: %s does not exists", filename.c_str());
122 return true;
123 }
124 // We can't delete a directory
125 if (IsDirectory(filename)) {
126 LOG_WARNING(TCOMMON, "Delete failed: %s is a directory", filename.c_str());
127 return false;
128 }
129#ifdef _WIN32
130 if (!DeleteFile(filename.c_str())) {
131 LOG_WARNING(TCOMMON, "Delete: DeleteFile failed on %s", filename.c_str());
132 return false;
133 }
134#else
135 if (unlink(filename.c_str()) == -1) {
136 LOG_WARNING(TCOMMON, "Delete: unlink failed on %s", filename.c_str());
137 return false;
138 }
139#endif
140 return true;
141}
142
143// Returns true if successful, or path already exists.
144bool CreateDir(const std::string &path) {
145 LOG_INFO(TCOMMON, "CreateDir: directory %s", path.c_str());
146#ifdef _WIN32
147 if (::CreateDirectory(path.c_str(), NULL)) {
148 return true;
149 }
150 DWORD error = GetLastError();
151 if (error == ERROR_ALREADY_EXISTS)
152 {
153 LOG_WARNING(TCOMMON, "CreateDir: CreateDirectory failed on %s: already exists", path.c_str());
154 return true;
155 }
156 LOG_ERROR(TCOMMON, "CreateDir: CreateDirectory failed on %s: %i", path.c_str(), error);
157 return false;
158#else
159 if (mkdir(path.c_str(), 0755) == 0) {
160 return true;
161 }
162 int err = errno;
163 if (err == EEXIST) {
164 LOG_WARNING(TCOMMON, "CreateDir: mkdir failed on %s: already exists", path.c_str());
165 return true;
166 }
167 LOG_ERROR(TCOMMON, "CreateDir: mkdir failed on %s: %s", path.c_str(), strerror(err));
168 return false;
169#endif
170}
171
172// Creates the full path of fullPath returns true on success
173bool CreateFullPath(const std::string &fullPath) {
174 int panicCounter = 100;
175 LOG_INFO(TCOMMON, "CreateFullPath: path %s", fullPath.c_str());
176
177 if (FileExists(fullPath)) {
178 LOG_INFO(TCOMMON, "CreateFullPath: path exists %s", fullPath.c_str());
179 return true;
180 }
181
182 size_t position = 0;
183 while (1) {
184 // Find next sub path
185 position = fullPath.find('/', position);
186
187 // we're done, yay!
188 if (position == fullPath.npos) {
189 return true;
190 }
191 std::string subPath = fullPath.substr(0, position);
192 if (!IsDirectory(subPath)) CreateDir(subPath);
193
194 // A safety check
195 panicCounter--;
196 if (panicCounter <= 0) {
197 LOG_ERROR(TCOMMON, "CreateFullPath: directory structure too deep");
198 return false;
199 }
200 position++;
201 }
202}
203
204// Deletes a directory filename, returns true on success
205bool DeleteDir(const std::string &filename) {
206 LOG_INFO(TCOMMON, "DeleteDir: directory %s", filename.c_str());
207 // check if a directory
208 if (!IsDirectory(filename)) {
209 LOG_ERROR(TCOMMON, "DeleteDir: Not a directory %s", filename.c_str());
210 return false;
211 }
212#ifdef _WIN32
213 if (::RemoveDirectory(filename.c_str()))
214 return true;
215#else
216 if (rmdir(filename.c_str()) == 0)
217 return true;
218#endif
219 LOG_ERROR(TCOMMON, "DeleteDir: %s", filename.c_str());
220 return false;
221}
222
223// renames file srcFilename to destFilename, returns true on success
224bool RenameFile(const std::string &srcFilename, const std::string &destFilename) {
225 LOG_INFO(TCOMMON, "Rename: %s --> %s",
226 srcFilename.c_str(), destFilename.c_str());
227 if (rename(srcFilename.c_str(), destFilename.c_str()) == 0)
228 return true;
229 LOG_ERROR(TCOMMON, "Rename: failed %s --> %s", srcFilename.c_str(), destFilename.c_str());
230 return false;
231}
232
233// copies file srcFilename to destFilename, returns true on success
234bool CopyFile(const std::string &srcFilename, const std::string &destFilename) {
235 LOG_INFO(TCOMMON, "Copy: %s --> %s",
236 srcFilename.c_str(), destFilename.c_str());
237#ifdef _WIN32
238 if (::CopyFile(srcFilename.c_str(), destFilename.c_str(), FALSE))
239 return true;
240
241 LOG_ERROR(TCOMMON, "Copy: failed %s --> %s", srcFilename.c_str(), destFilename.c_str());
242 return false;
243#else
244 char buffer[1024];
245
246 // Open input file
247 FILE *input = fopen(srcFilename.c_str(), "rb");
248 if (!input) {
249 LOG_ERROR(TCOMMON, "Copy: input failed %s --> %s", srcFilename.c_str(),
250 destFilename.c_str());
251 return false;
252 }
253 // open output file
254 FILE *output = fopen(destFilename.c_str(), "wb");
255 if (!output) {
256 fclose(input);
257 LOG_ERROR(TCOMMON, "Copy: output failed %s --> %s", srcFilename.c_str(),
258 destFilename.c_str());
259 return false;
260 }
261 // copy loop
262 while (!feof(input)) {
263 // read input
264 int rnum = fread(buffer, sizeof(char), 1024, input);
265 if (rnum != 1024) {
266 if (ferror(input) != 0) {
267 LOG_ERROR(TCOMMON, "Copy: failed reading from source, %s --> %s",
268 srcFilename.c_str(), destFilename.c_str());
269 goto bail;
270 }
271 }
272 // write output
273 int wnum = fwrite(buffer, sizeof(char), rnum, output);
274 if (wnum != rnum) {
275 LOG_ERROR(TCOMMON, "Copy: failed writing to output, %s --> %s",
276 srcFilename.c_str(), destFilename.c_str());
277 goto bail;
278 }
279 }
280 // close flushs
281 fclose(input);
282 fclose(output);
283 return true;
284bail:
285 if (input)
286 fclose(input);
287 if (output)
288 fclose(output);
289 return false;
290#endif
291}
292
293// Returns the size of filename (64bit)
294u64 GetFileSize(const std::string &filename) {
295 if (!FileExists(filename)) {
296 LOG_WARNING(TCOMMON, "GetSize: failed %s: No such file", filename.c_str());
297 return 0;
298 }
299 if (IsDirectory(filename)) {
300 LOG_WARNING(TCOMMON, "GetSize: failed %s: is a directory", filename.c_str());
301 return 0;
302 }
303 struct stat64 buf;
304 if (stat64(filename.c_str(), &buf) == 0) {
305 LOG_DEBUG(TCOMMON, "GetSize: %s: %lld", filename.c_str(), (long long)buf.st_size);
306 return buf.st_size;
307 }
308 LOG_ERROR(TCOMMON, "GetSize: Stat failed %s", filename.c_str());
309 return 0;
310}
311
312// Overloaded GetSize, accepts file descriptor
313u64 GetFileSize(const int fd) {
314 struct stat64 buf;
315 if (fstat64(fd, &buf) != 0) {
316 LOG_ERROR(TCOMMON, "GetSize: stat failed %i", fd);
317 return 0;
318 }
319 return buf.st_size;
320}
321
322// Overloaded GetSize, accepts FILE*
323u64 GetFileSize(FILE *f) {
324 // can't use off_t here because it can be 32-bit
325 u64 pos = ftello(f);
326 if (fseeko(f, 0, SEEK_END) != 0) {
327 LOG_ERROR(TCOMMON, "GetSize: seek failed %p", f);
328 return 0;
329 }
330 u64 size = ftello(f);
331 if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) {
332 LOG_ERROR(TCOMMON, "GetSize: seek failed %p", f);
333 return 0;
334 }
335 return size;
336}
337
338// creates an empty file filename, returns true on success
339bool CreateEmptyFile(const std::string &filename) {
340 LOG_INFO(TCOMMON, "CreateEmptyFile: %s", filename.c_str());
341
342 FILE *pFile = fopen(filename.c_str(), "wb");
343 if (!pFile) {
344 LOG_ERROR(TCOMMON, "CreateEmptyFile: failed %s", filename.c_str());
345 return false;
346 }
347 fclose(pFile);
348 return true;
349}
350
351// Deletes the given directory and anything under it. Returns true on success.
352bool DeleteDirRecursively(const std::string &directory) {
353 LOG_INFO(TCOMMON, "DeleteDirRecursively: %s", directory.c_str());
354#ifdef _WIN32
355 // Find the first file in the directory.
356 WIN32_FIND_DATA ffd;
357 HANDLE hFind = FindFirstFile((directory + "\\*").c_str(), &ffd);
358
359 if (hFind == INVALID_HANDLE_VALUE) {
360 FindClose(hFind);
361 return false;
362 }
363
364 // windows loop
365 do {
366 const std::string virtualName = ffd.cFileName;
367#else
368 struct dirent dirent, *result = NULL;
369 DIR *dirp = opendir(directory.c_str());
370 if (!dirp) {
371 return false;
372 }
373 // non windows loop
374 while (!readdir_r(dirp, &dirent, &result) && result) {
375 const std::string virtualName = result->d_name;
376#endif
377 // check for "." and ".."
378 if (((virtualName[0] == '.') && (virtualName[1] == '\0')) ||
379 ((virtualName[0] == '.') && (virtualName[1] == '.') &&
380 (virtualName[2] == '\0'))) {
381 continue;
382 }
383 std::string newPath = directory + '/' + virtualName;
384 if (IsDirectory(newPath)) {
385 if (!DeleteDirRecursively(newPath))
386 return false;
387 } else {
388 if (!DeleteFile(newPath))
389 return false;
390 }
391
392#ifdef _WIN32
393 } while (FindNextFile(hFind, &ffd) != 0);
394 FindClose(hFind);
395#else
396 }
397 closedir(dirp);
398#endif
399 DeleteDir(directory);
400
401 return true;
402}
403
404// Returns the current directory
405std::string GetCurrentDir() {
406 char *dir;
407 // Get the current working directory (getcwd uses malloc)
408 if (!(dir = __getcwd(NULL, 0))) {
409
410 LOG_ERROR(TCOMMON, "GetCurrentDirectory failed:");
411 return NULL;
412 }
413 std::string strDir = dir;
414 free(dir);
415 return strDir;
416}
417
418// Sets the current directory to the given directory
419bool SetCurrentDir(const std::string &directory) {
420 return __chdir(directory.c_str()) == 0;
421}
422
423bool WriteStringToFile(bool text_file, const std::string &str, const char *filename) {
424 FILE *f = fopen(filename, text_file ? "w" : "wb");
425 if (!f) {
426 return false;
427 }
428 size_t len = str.size();
429 if (len != fwrite(str.data(), 1, str.size(), f)) {
430 fclose(f);
431 return false;
432 }
433 fclose(f);
434 return true;
435}
436
437bool ReadFileToString(bool text_file, const char *filename, std::string &str) {
438 FILE *f = fopen(filename, text_file ? "r" : "rb");
439 if (!f) {
440 return false;
441 }
442 size_t len = (size_t)GetFileSize(f);
443 char *buf = new char[len + 1];
444 buf[fread(buf, 1, len, f)] = 0;
445 str = std::string(buf, len);
446 fclose(f);
447 delete [] buf;
448 return true;
449}
450
451} // namespace
diff --git a/src/common/src/file_utils.h b/src/common/src/file_utils.h
deleted file mode 100644
index 6b93710b9..000000000
--- a/src/common/src/file_utils.h
+++ /dev/null
@@ -1,90 +0,0 @@
1/**
2* Copyright (C) 2005-2013 Gekko Emulator
3*
4* @file file_utils.h
5* @author ShizZy <shizzy247@gmail.com>
6* @date 2013-01-27
7* @brief Crossplatform file utility functions
8* @remark Borrowed from Dolphin Emulator
9*
10* @section LICENSE
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License as
13* published by the Free Software Foundation; either version 2 of
14* the License, or (at your option) any later version.
15*
16* This program is distributed in the hope that it will be useful, but
17* WITHOUT ANY WARRANTY; without even the implied warranty of
18* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19* General Public License for more details at
20* http://www.gnu.org/copyleft/gpl.html
21*
22* Official project repository can be found at:
23* http://code.google.com/p/gekko-gc-emu/
24*/
25
26#ifndef COMMON_FILE_UTILS_H_
27#define COMMON_FILE_UTILS_H_
28
29#include <fstream>
30#include <cstdio>
31#include <string>
32#include <vector>
33#include <string.h>
34
35#include "common.h"
36
37namespace common {
38
39// Returns true if file filename exists
40bool FileExists(const std::string &filename);
41
42// Returns true if filename is a directory
43bool IsDirectory(const std::string &filename);
44
45// Returns the size of filename (64bit)
46u64 GetFileSize(const std::string &filename);
47
48// Overloaded GetSize, accepts file descriptor
49u64 GetFileSize(const int fd);
50
51// Overloaded GetSize, accepts FILE*
52u64 GetFileSize(FILE *f);
53
54// Returns true if successful, or path already exists.
55bool CreateDir(const std::string &filename);
56
57// Creates the full path of fullPath returns true on success
58bool CreateFullPath(const std::string &fullPath);
59
60// Deletes a given filename, return true on success
61// Doesn't supports deleting a directory
62bool DeleteFile(const std::string &filename);
63
64// Deletes a directory filename, returns true on success
65bool DeleteDir(const std::string &filename);
66
67// renames file srcFilename to destFilename, returns true on success
68bool RenameFile(const std::string &srcFilename, const std::string &destFilename);
69
70// copies file srcFilename to destFilename, returns true on success
71bool CopyFile(const std::string &srcFilename, const std::string &destFilename);
72
73// creates an empty file filename, returns true on success
74bool CreateEmptyFile(const std::string &filename);
75
76// deletes the given directory and anything under it. Returns true on success.
77bool DeleteDirRecursively(const std::string &directory);
78
79// Returns the current directory
80std::string GetCurrentDir();
81
82// Set the current directory to given directory
83bool SetCurrentDir(const std::string &directory);
84
85bool WriteStringToFile(bool text_file, const std::string &str, const char *filename);
86bool ReadFileToString(bool text_file, const char *filename, std::string &str);
87
88} // namespace
89
90#endif // COMMON_FILE_UTILS_H_
diff --git a/src/common/src/hash.cpp b/src/common/src/hash.cpp
deleted file mode 100644
index 738d3d353..000000000
--- a/src/common/src/hash.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file hash.cpp
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-12-05
7 * @brief General purpose hash function
8 * @remark Some functions borrowed from Dolphin Emulator
9 *
10 * @section LICENSE
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details at
20 * http://www.gnu.org/copyleft/gpl.html
21 *
22 * Official project repository can be found at:
23 * http://code.google.com/p/gekko-gc-emu/
24 */
25
26#include "crc.h"
27#include "hash.h"
28#include "common.h"
29
30namespace common {
31
32/// Block mix - combine the key bits with the hash bits and scramble everything
33inline void bmix64(u64& h1, u64& h2, u64& k1, u64& k2, u64& c1, u64& c2) {
34 k1 *= c1;
35 k1 = _rotl64(k1,23);
36 k1 *= c2;
37 h1 ^= k1;
38 h1 += h2;
39
40 h2 = _rotl64(h2,41);
41
42 k2 *= c2;
43 k2 = _rotl64(k2,23);
44 k2 *= c1;
45 h2 ^= k2;
46 h2 += h1;
47
48 h1 = h1*3 + 0x52dce729;
49 h2 = h2*3 + 0x38495ab5;
50
51 c1 = c1*5 + 0x7b7d159c;
52 c2 = c2*5 + 0x6bce6396;
53}
54
55/// Finalization mix - avalanches all bits to within 0.05% bias
56inline u64 fmix64(u64 k) {
57 k ^= k >> 33;
58 k *= 0xff51afd7ed558ccd;
59 k ^= k >> 33;
60 k *= 0xc4ceb9fe1a85ec53;
61 k ^= k >> 33;
62 return k;
63}
64
65#define ROTL32(x,y) rotl32(x,y)
66
67inline uint32_t fmix ( uint32_t h )
68{
69 h ^= h >> 16;
70 h *= 0x85ebca6b;
71 h ^= h >> 13;
72 h *= 0xc2b2ae35;
73 h ^= h >> 16;
74
75 return h;
76}
77
78u32 __compute_murmur_hash3_32(const u8 *src, int len, u32 samples) {
79 u32 h = len;
80 u32 step = (len >> 2);
81 const u32 *data = (const u32*)src;
82 const u32 *end = data + step;
83 if (samples == 0) {
84 samples = std::max(step, 1u);
85 }
86 step = step / samples;
87 if(step < 1) {
88 step = 1;
89 }
90 u32 h1 = 0x2f6af274;
91 const u32 c1 = 0xcc9e2d51;
92 const u32 c2 = 0x1b873593;
93
94 while (data < end) {
95 u32 k1 = data[0];
96
97 k1 *= c1;
98 k1 = (k1 << 15) | (k1 >> (32 - 15));
99 k1 *= c2;
100
101 h1 ^= k1;
102 h1 = (h1 << 15) | (h1 >> (32 - 13));
103 h1 = h1*5+0xe6546b64;
104
105 data += step;
106 }
107 const u8 * tail = (const u8*)(data);
108
109 u32 k1 = 0;
110
111 switch(len & 3) {
112 case 3:
113 k1 ^= tail[2] << 16;
114 case 2:
115 k1 ^= tail[1] << 8;
116 case 1:
117 k1 ^= tail[0];
118 k1 *= c1;
119 k1 = (k1 << 15) | (k1 >> (32 - 15));
120 k1 *= c2;
121 h1 ^= k1;
122 };
123 h1 ^= len;
124 h1 = fmix(h1);
125
126 return h1;
127}
128
129
130/// MurmurHash is a non-cryptographic hash function suitable for general hash-based lookup
131u64 __compute_murmur_hash3_64(const u8 *src, int len, u32 samples) {
132 const u8 * data = (const u8*)src;
133 const int nblocks = len / 16;
134 u32 step = (len / 8);
135 if(samples == 0) {
136 samples = std::max(step, 1u);
137 }
138 step = step / samples;
139 if(step < 1) {
140 step = 1;
141 }
142
143 u64 h1 = 0x9368e53c2f6af274;
144 u64 h2 = 0x586dcd208f7cd3fd;
145
146 u64 c1 = 0x87c37b91114253d5;
147 u64 c2 = 0x4cf5ad432745937f;
148
149 const u64* blocks = (const u64*)(data);
150
151 for (int i = 0; i < nblocks; i+=step) {
152 u64 k1 = blocks[(i * 2) + 0];
153 u64 k2 = blocks[(i * 2) + 1];
154
155 bmix64(h1,h2,k1,k2,c1,c2);
156 }
157 const u8* tail = (const u8*)(data + nblocks * 16);
158
159 u64 k1 = 0;
160 u64 k2 = 0;
161
162 switch (len & 15) {
163 case 15: k2 ^= u64(tail[14]) << 48;
164 case 14: k2 ^= u64(tail[13]) << 40;
165 case 13: k2 ^= u64(tail[12]) << 32;
166 case 12: k2 ^= u64(tail[11]) << 24;
167 case 11: k2 ^= u64(tail[10]) << 16;
168 case 10: k2 ^= u64(tail[ 9]) << 8;
169 case 9: k2 ^= u64(tail[ 8]) << 0;
170
171 case 8: k1 ^= u64(tail[ 7]) << 56;
172 case 7: k1 ^= u64(tail[ 6]) << 48;
173 case 6: k1 ^= u64(tail[ 5]) << 40;
174 case 5: k1 ^= u64(tail[ 4]) << 32;
175 case 4: k1 ^= u64(tail[ 3]) << 24;
176 case 3: k1 ^= u64(tail[ 2]) << 16;
177 case 2: k1 ^= u64(tail[ 1]) << 8;
178 case 1: k1 ^= u64(tail[ 0]) << 0;
179 bmix64(h1, h2, k1, k2, c1, c2);
180 };
181 h2 ^= len;
182
183 h1 += h2;
184 h2 += h1;
185
186 h1 = fmix64(h1);
187 h2 = fmix64(h2);
188
189 h1 += h2;
190
191 return h1;
192}
193
194/// CRC32 hash using the SSE4.2 instruction
195u64 __compute_crc32_sse4(const u8 *src, int len, u32 samples) {
196 u32 h = len;
197 u32 step = (len >> 2);
198 const u32 *data = (const u32*)src;
199 const u32 *end = data + step;
200 if (samples == 0) {
201 samples = std::max(step, 1u);
202 }
203 step = step / samples;
204 if(step < 1) {
205 step = 1;
206 }
207 while (data < end) {
208 h = InlineCrc32_U32(h, data[0]);
209 data += step;
210 }
211 const u8 *data2 = (const u8*)end;
212 return (u64)InlineCrc32_U32(h, u32(data2[0]));
213}
214
215/**
216 * Compute an efficient 64-bit hash (optimized for Intel hardware)
217 * @param src Source data buffer to compute hash for
218 * @param len Length of data buffer to compute hash for
219 * @param samples Number of samples to compute hash for
220 * @remark Borrowed from Dolphin Emulator
221 */
222Hash64 GetHash64(const u8 *src, int len, u32 samples) {
223#if defined(EMU_ARCHITECTURE_X86) || defined(EMU_ARCHITECTURE_X64)
224 // TODO(ShizZy): Move somewhere common so we dont need to instantiate this more than once
225 static X86Utils x86_utils;
226 if (x86_utils.IsExtensionSupported(X86Utils::kExtensionX86_SSE4_2)) {
227 return __compute_crc32_sse4(src, len, samples);
228 } else {
229
230#ifdef EMU_ARCHITECTURE_X64
231 return __compute_murmur_hash3_64(src, len, samples);
232#else
233 return __compute_murmur_hash3_32(src, len, samples);
234#endif
235 }
236#else
237 return __compute_murmur_hash3_32(src, len, samples);
238#endif
239}
240
241} // namespace
diff --git a/src/common/src/hash.h b/src/common/src/hash.h
deleted file mode 100644
index 37cbe823c..000000000
--- a/src/common/src/hash.h
+++ /dev/null
@@ -1,46 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file hash.h
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-12-05
7 * @brief General purpose hash function
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_HASH_H_
26#define COMMON_HASH_H_
27
28#include "types.h"
29
30namespace common {
31
32typedef u64 Hash64;
33
34/**
35 * Compute an efficient 64-bit hash (optimized for Intel hardware)
36 * @param src Source data buffer to compute hash for
37 * @param len Length of data buffer to compute hash for
38 * @param samples Number of samples to compute hash for
39 * @remark Borrowed from Dolphin Emulator
40 */
41Hash64 GetHash64(const u8 *src, int len, u32 samples);
42
43} // namespace
44
45
46#endif // COMMON_HASH_H_ \ No newline at end of file
diff --git a/src/common/src/hash_container.h b/src/common/src/hash_container.h
deleted file mode 100644
index ab832f3c7..000000000
--- a/src/common/src/hash_container.h
+++ /dev/null
@@ -1,116 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file hash_container.h
5 * @author ShizZy <shizzy@6bit.net>
6 * @date 2012-11-29
7 * @brief Container object for storing a hash lookup
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_HASH_CONTAINER_H_
26#define COMMON_HASH_CONTAINER_H_
27
28#include <map>
29#include "common.h"
30
31/// Hash container generic interface - Don't use directly, use a derived class
32template <class HashType, class ValueType> class HashContainer {
33 /**
34 * Add (or update if already exists) a value at the specified hash in the container
35 * @param hash Hash to use
36 * @param value Value to update at given hash in the container
37 */
38 ValueType* Update(HashType hash, ValueType value);
39
40 /**
41 * Remove a hash entry in the hash container
42 * @param hash Hash value of entry to remove
43 */
44 void Remove(HashType hash);
45
46 /**
47 * Fetch the value at at the given hash from the hash container
48 * @param hash Hash value of entry to fetch
49 * @return Pointer to value stored at hash location on success (index was found), otherwise NULL
50 */
51 ValueType* FetchFromHash(HashType hash);
52
53 /**
54 * Fetch the value at at the given integer index from the hash container
55 * @param hash Hash value of entry to fetch
56 * @return Pointer to value stored at hash location on success (index was found), otherwise NULL
57 */
58 ValueType* FetchFromIndex(int index);
59
60 /**
61 * Get the size of the hash container
62 * @return Number of elements in the hash container
63 */
64 int Size();
65};
66
67/// Hash container implemented using STL map
68template <class HashType, class ValueType> class HashContainer_STLMap :
69 public HashContainer<HashType, ValueType> {
70
71public:
72 HashContainer_STLMap() {
73 }
74 ~HashContainer_STLMap() {
75 }
76
77 ValueType* Update(HashType hash, ValueType value) {
78 map_[hash] = value;
79 return &map_[hash];
80 }
81
82 void Remove(HashType hash) {
83 map_.erase(hash);
84 }
85
86 ValueType* FetchFromHash(HashType hash) {
87 typename std::map<HashType, ValueType>::iterator itr = map_.find(hash);
88 if (itr == map_.end()) {
89 return NULL;
90 }
91 return &itr->second;
92 }
93
94 ValueType* FetchFromIndex(int index) {
95 typename std::map<HashType, ValueType>::iterator itr = map_.begin();
96 int i = 0;
97 for (; i < index; ++i) {
98 ++itr;
99 }
100 if (i < index) {
101 return NULL;
102 }
103 return &itr->second;
104 }
105
106 int Size() {
107 return static_cast<int>(map_.size());
108 }
109
110private:
111 std::map<HashType, ValueType> map_;
112
113 DISALLOW_COPY_AND_ASSIGN(HashContainer_STLMap);
114};
115
116#endif // COMMON_HASH_CONTAINER_H_
diff --git a/src/common/src/log.cpp b/src/common/src/log.cpp
deleted file mode 100644
index c365b2f70..000000000
--- a/src/common/src/log.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file log.cpp
5 * @author ShizZy <shizzy@6bit.net>
6 * @date 2012-02-11
7 * @brief Common logging routines used throughout the project
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#include <stdarg.h>
26#include <stdlib.h>
27
28#include "common.h"
29#include "timer.h"
30
31namespace logger {
32
33LogContainer* g_logs[NUMBER_OF_LOGS]; ///< List of pointers to all logs
34
35/// LogContainer constructor
36LogContainer::LogContainer(const char* name, const char* desc, bool enable = false) {
37 strncpy(name_, name, 128);
38 strncpy(desc_, desc, 32);
39 level_ = LWARNING;
40}
41
42/// Asks the user a yes or no question
43SysUserResponse AskYesNo(const char* fmt, ...) {
44 char c;
45 va_list arg;
46
47 va_start(arg, fmt);
48 printf("\n** Question **\n");
49 vprintf(fmt, arg);
50 va_end(arg);
51
52 printf(" Response? (y/n) ");
53 while (1) {
54 c = getchar();
55 if (c == 'y' || c == 'Y') {
56 return SYS_USER_YES;
57 }
58 if (c == 'n' || c == 'N') {
59 return SYS_USER_NO;
60 }
61 }
62 return SYS_USER_NO;
63}
64
65//// Log routine used by everything
66void LogGeneric(LogLevel level, LogType type, const char *file, int line, bool append, const char* fmt, ...)
67{
68 char msg[kMaxMsgLength];
69 static const char level_to_char[8] = "-NECWID";
70 static char last_char = '\n';
71 static LogType last_type;
72
73 va_list arg;
74 va_start(arg, fmt);
75
76 if (type >= NUMBER_OF_LOGS) {
77 LOG_ERROR(TCOMMON, "Unknown logger type %d", type);
78 return;
79 }
80
81 // Format the log message
82 if (append) {
83 sprintf(msg, "%s", fmt);
84 } else {
85 // char time_str[16];
86 // u32 time_elapsed = common::GetTimeElapsed();
87 // common::TicksToFormattedString(time_elapsed, time_str);
88 sprintf(msg, "%c[%s] %s", level_to_char[(int)level], g_logs[type]->name(), fmt);
89 }
90
91 // If the last message didn't have a line break, print one
92 if ('\n' != last_char && '\r' != last_char && !append && last_type != TOS_REPORT &&
93 last_type != TOS_HLE) {
94 printf("\n");
95 }
96 last_char = msg[strlen(msg)-1];
97 last_type = type;
98
99 // Print the log message to stdout
100 vprintf(msg, arg);
101 va_end(arg);
102}
103
104/// Forces a controlled system crash rather before it catches fire (debug)
105void Crash() {
106 LOG_CRASH(TCOMMON, "*** SYSTEM CRASHED ***\n");
107 LOG_CRASH(TCOMMON, "Fatal error, system could not recover.\n");
108#ifdef _MSC_VER
109#ifdef USE_INLINE_ASM_X86
110 __asm int 3
111#endif
112#elif defined(__GNUC__)
113 asm("int $3");
114#else
115 LOG_CRASH(TCOMMON, "Exiting...\n");
116 exit(0);
117#endif
118}
119
120/// Initialize the logging system
121void Init() {
122 g_logs[TNULL] = new LogContainer("NULL", "Null");
123 g_logs[TAI] = new LogContainer("AI", "AudioInterface");
124 g_logs[TBOOT] = new LogContainer("BOOT", "Boot");
125 g_logs[TCOMMON] = new LogContainer("COMMON", "Common");
126 g_logs[TCONFIG] = new LogContainer("CONFIG", "Configuration");
127 g_logs[TCORE] = new LogContainer("CORE", "SysCore");
128 g_logs[TCP] = new LogContainer("CP", "CommandProcessor");
129 g_logs[TDI] = new LogContainer("DI", "DVDInterface");
130 g_logs[TDSP] = new LogContainer("DSP", "DSP");
131 g_logs[TDVD] = new LogContainer("DVD", "GCM/ISO");
132 g_logs[TEXI] = new LogContainer("EXI", "ExternalInterface");
133 g_logs[TGP] = new LogContainer("GP", "GraphicsProcessor");
134 g_logs[THLE] = new LogContainer("HLE", "HLE");
135 g_logs[THW] = new LogContainer("HW", "Hardware");
136 g_logs[TJOYPAD] = new LogContainer("JOYPAD", "Joypad");
137 g_logs[TMASTER] = new LogContainer("*", "Master Log");
138 g_logs[TMEM] = new LogContainer("MEM", "Memory");
139 g_logs[TMI] = new LogContainer("MI", "MemoryInterface");
140 g_logs[TOS_HLE] = new LogContainer("OSHLE", "OSHLE");
141 g_logs[TOS_REPORT] = new LogContainer("OSREPORT", "OSREPORT");
142 g_logs[TPE] = new LogContainer("PE", "PixelEngine");
143 g_logs[TPI] = new LogContainer("PI", "ProcessorInterface");
144 g_logs[TPOWERPC] = new LogContainer("PPC", "PowerPC");
145 g_logs[TSI] = new LogContainer("SI", "SerialInterface");
146 g_logs[TVI] = new LogContainer("VI", "VideoInterface");
147 g_logs[TVIDEO] = new LogContainer("VIDEO", "VideoCore");
148
149 LOG_NOTICE(TCOMMON, "%d logger(s) initalized ok", NUMBER_OF_LOGS);
150}
151
152} // namespace
diff --git a/src/common/src/log.h b/src/common/src/log.h
deleted file mode 100644
index 9ce3a30a3..000000000
--- a/src/common/src/log.h
+++ /dev/null
@@ -1,216 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file log.h
5 * @author ShizZy <shizzy@6bit.net>
6 * @date 2012-02-11
7 * @brief Common logging routines used throughout the project
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_LOG_H_
26#define COMMON_LOG_H_
27
28#include "SDL.h" // Used for threading/mutexes
29
30#include "common.h"
31
32////////////////////////////////////////////////////////////////////////////////////////////////////
33// Logging Macros
34
35#if defined(_DEBUG) || defined(DEBUG) || defined(LOGGING)
36/// Debug mode, show all logs
37#define MAX_LOG_LEVEL logger::LDEBUG
38#else
39/// Non debug mode, only show critical logs
40#define MAX_LOG_LEVEL logger::LWARNING
41#endif
42
43/// Logs a message ** Don't use directly **
44#define _LOG_GENERIC(level, type, ...) \
45 if (level <= MAX_LOG_LEVEL) { \
46 LogGeneric(level, type, __FILE__, __LINE__, false, __VA_ARGS__); \
47 }
48
49/// Used for appending to the last logged message
50#define LOG_APPEND(level, type, ...) \
51 if (logger::level <= MAX_LOG_LEVEL) { \
52 logger::LogGeneric(logger::level, logger::type, __FILE__, __LINE__, true, __VA_ARGS__); \
53 }
54
55/// Use this for printing an IMPORTANT notice to the logger
56#define LOG_NOTICE(type, ...) _LOG_GENERIC(logger::LNOTICE, logger::type, __VA_ARGS__)
57
58/// Use this for printing an error message to the logger
59#define LOG_ERROR(type, ...) _LOG_GENERIC(logger::LERROR, logger::type, __VA_ARGS__)
60
61/// Use this for printing a crash report to the logger
62#define LOG_CRASH(type, ...) _LOG_GENERIC(logger::LCRASH, logger::type, __VA_ARGS__)
63
64/// Use this for printing a warning to the logger
65#define LOG_WARNING(type, ...) _LOG_GENERIC(logger::LWARNING, logger::type, __VA_ARGS__)
66
67/// Use this for printing general information to the logger
68#define LOG_INFO(type, ...) _LOG_GENERIC(logger::LINFO, logger::type, __VA_ARGS__)
69
70#if defined(_DEBUG) || defined(DEBUG) || defined(LOGGING)
71
72/// Use this for printing a debug message to the logger
73#define LOG_DEBUG(type, ...) _LOG_GENERIC(logger::LDEBUG, logger::type, __VA_ARGS__)
74
75/// Used for debug-mode assertions
76#define _ASSERT_DBG(_type_, _cond_) \
77 if (!(_cond_)) { \
78 LOG_ERROR(_type_, "Error...\n\n Line: %d\n File: %s\n Time: %s\n", \
79 __LINE__, __FILE__, __TIME__); \
80 if (!logger::AskYesNo("*** Assertion (see log)***\n")) logger::Crash(); \
81 }
82
83/// Used for message-specified debug-mode assertions
84#define _ASSERT_DBG_MSG(_type_, _cond_, ...) \
85 if (!(_cond_)) { \
86 LOG_ERROR(_type_, __VA_ARGS__); \
87 if (!logger::AskYesNo(__VA_ARGS__)) logger::Crash(); \
88 }
89#else
90#define _ASSERT_DBG(_type_, _cond_, ...)
91#define _ASSERT_DBG_MSG(_type_, _cond_, ...)
92#define LOG_DEBUG(type, ...)
93#endif
94
95/// Used for general purpose assertions, CRITICAL operations only
96#define _ASSERT_MSG(_type_, _cond_, ...) \
97 if (!(_cond_)) { \
98 if (!logger::AskYesNo(__VA_ARGS__)) logger::Crash(); \
99 }
100
101////////////////////////////////////////////////////////////////////////////////////////////////////
102// Logger
103
104namespace logger {
105
106const int kMaxMsgLength = 1024; ///< Maximum message length
107
108/// Used for handling responses to system functions that require them
109typedef enum {
110 SYS_USER_NO = 0, ///< User response for 'No'
111 SYS_USER_YES, ///< User response for 'Yes'
112 SYS_USER_OK, ///< User response for 'Okay'
113 SYS_USER_ABORT, ///< User response for 'Abort'
114 SYS_USER_RETRY, ///< User response for 'Retry'
115 SYS_USER_CANCEL, ///< User response for 'Cancel'
116} SysUserResponse;
117
118/// Level of logging
119typedef enum {
120 LNULL = 0, ///< Logs with this level won't get logged
121 LNOTICE, ///< Notice: A general message to the user
122 LERROR, ///< Error: For failure messages
123 LCRASH, ///< Crash: Used for crash reports
124 LWARNING, ///< Warning: For potentially bad things, but not fatal
125 LINFO, ///< Info: Information message
126 LDEBUG ///< Debug: Debug-only information
127} LogLevel;
128
129/// Type of logging
130typedef enum {
131 TNULL = 0,
132 TAI,
133 TBOOT,
134 TCOMMON,
135 TCONFIG,
136 TCORE,
137 TCP,
138 TDI,
139 TDSP,
140 TDVD,
141 TEXI,
142 TGP,
143 THLE,
144 THW,
145 TJOYPAD,
146 TMASTER,
147 TMEM,
148 TMI,
149 TOS_HLE,
150 TOS_REPORT,
151 TPE,
152 TPI,
153 TPOWERPC,
154 TSI,
155 TVI,
156 TVIDEO,
157 NUMBER_OF_LOGS ///< Number of logs - must be last
158} LogType;
159
160/// Used for implementing a logger for a subsystem
161class LogContainer
162{
163public:
164 LogContainer(const char* name, const char* desc, bool enable);
165 ~LogContainer() {}
166
167 const char* name() const { return name_; }
168 const char* desc() const { return desc_; }
169
170 bool enabled() const { return enabled_; }
171 void set_enabled(bool enabled) { enabled_ = enabled; }
172
173 LogLevel level() const { return level_; }
174 void set_level(LogLevel level) { level_ = level; }
175
176private:
177 char name_[32]; ///< Name of the logger (e.g. "SI")
178 char desc_[128]; ///< Description of the logger (e.g. "Serial Interface")
179 bool enabled_; ///< Whether or not the logger is enabled
180
181 LogLevel level_; ///< Level of the logger (e.g. Notice, Error, Warning, etc.)
182
183 SDL_mutex* listener_lock_; ///< Mutex for multithreaded access
184
185 DISALLOW_COPY_AND_ASSIGN(LogContainer);
186};
187
188////////////////////////////////////////////////////////////////////////////////////////////////////
189// Function Prototypes
190
191/*!
192 * \brief Log routine used by everything
193 * \param level Log level to use
194 * \param type Log type to use
195 * \param file Filename of file where error occured
196 * \param line Linenumber of file where error occured
197 * \param fmt Formatted message
198 */
199void LogGeneric(LogLevel level, LogType type, const char *file, int line, bool append, const char* fmt, ...);
200
201/// Forces a controlled system crash rather before it catches fire (debug)
202void Crash();
203
204/*!
205 * \brief Asks the user a yes or no question
206 * \param fmt Question formatted message
207 * \return SysUserResponse response
208 */
209SysUserResponse AskYesNo(const char* fmt, ...);
210
211/// Initialize the logging system
212void Init();
213
214} // namespace log
215
216#endif // COMMON_LOG_H
diff --git a/src/common/src/misc_utils.cpp b/src/common/src/misc_utils.cpp
deleted file mode 100644
index d2a50fb3e..000000000
--- a/src/common/src/misc_utils.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file misc_utils.cpp
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-03-06
7 * @brief Miscellaneous functions/utilities that are used everywhere
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#include "misc_utils.h"
26
27namespace common {
28
29/// Make a string lowercase
30void LowerStr(char* str) {
31 for (int i = 0; str[i]; i++) {
32 str[i] = tolower(str[ i ]);
33 }
34}
35
36/// Make a string uppercase
37void UpperStr(char* str) {
38 for (int i=0; i < strlen(str); i++) {
39 if(str[i] >= 'a' && str[i] <= 'z') {
40 str[i] &= 0xDF;
41 }
42 }
43}
44
45/// Format a std::string using C-style sprintf formatting
46std::string FormatStr(const char* format, ...) {
47 va_list args;
48 char *buf = NULL;
49#if EMU_PLATFORM == PLATFORM_WINDOWS
50 int required = 0;
51
52 va_start(args, format);
53 required = _vscprintf(format, args);
54 buf = new char[required + 1];
55 vsnprintf(buf, required, format, args);
56 va_end(args);
57
58 buf[required] = '\0';
59 std::string temp = buf;
60 delete[] buf;
61#else
62 va_start(args, format);
63 vasprintf(&buf, format, args);
64 va_end(args);
65
66 std::string temp = buf;
67 free(buf);
68#endif
69 return temp;
70}
71
72/// Check if a file exists
73bool FileExists(char* filename) {
74 std::ifstream ifile(filename);
75 if (!ifile) {
76 return false;
77 }
78 ifile.close();
79 return true;
80}
81
82/// Gets the size of a file
83size_t FileSize(FILE* file) {
84 size_t pos = ftell(file);
85 fseek(file, 0L, SEEK_END);
86 size_t res = ftell(file);
87 fseek(file, pos, SEEK_SET);
88 return res;
89}
90
91} // namespace
diff --git a/src/common/src/misc_utils.h b/src/common/src/misc_utils.h
deleted file mode 100644
index b003336cb..000000000
--- a/src/common/src/misc_utils.h
+++ /dev/null
@@ -1,58 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file misc_utils.h
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-03-06
7 * @brief Miscellaneous functions/utilities that are used everywhere
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#include "common.h"
26
27namespace common {
28
29/**
30 * @brief Make a string lowercase
31 * @param str String to make lowercase
32 */
33void LowerStr(char* str);
34
35/**
36 * @brief Make a string uppercase
37 * @param str String to make uppercase
38 */
39void UpperStr(char* str);
40
41/// Format a std::string using C-style sprintf formatting
42std::string FormatStr(const char* format, ...);
43
44/**
45 * @brief Check if a file exists on the users computer
46 * @param filename Filename of file to check for
47 * @return true on exists, false otherwise
48 */
49bool FileExists(char* filename);
50
51/**
52 * @brief Gets the size of a file
53 * @param file Pointer to file to get size of
54 * @return true Size of file, in bytes
55 */
56size_t FileSize(FILE* file);
57
58} // namespace
diff --git a/src/common/src/platform.h b/src/common/src/platform.h
deleted file mode 100644
index efbf3824a..000000000
--- a/src/common/src/platform.h
+++ /dev/null
@@ -1,135 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file platform.h
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-02-11
7 * @brief Platform detection macros for portable compilation
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_PLATFORM_H_
26#define COMMON_PLATFORM_H_
27
28#include "types.h"
29
30////////////////////////////////////////////////////////////////////////////////////////////////////
31// Platform definitions
32
33/// Enumeration for defining the supported platforms
34#define PLATFORM_NULL 0
35#define PLATFORM_WINDOWS 1
36#define PLATFORM_MACOSX 2
37#define PLATFORM_LINUX 3
38#define PLATFORM_ANDROID 4
39#define PLATFORM_IOS 5
40
41////////////////////////////////////////////////////////////////////////////////////////////////////
42// Platform detection
43extern char *kGekkoOS;
44
45#ifndef EMU_PLATFORM
46
47#if defined( __WIN32__ ) || defined( _WIN32 )
48#define EMU_PLATFORM PLATFORM_WINDOWS
49
50#elif defined( __APPLE__ ) || defined( __APPLE_CC__ )
51#define EMU_PLATFORM PLATFORM_MAXOSX
52
53#elif defined(__linux__)
54#define EMU_PLATFORM PLATFORM_LINUX
55
56#else // Assume linux otherwise
57#define EMU_PLATFORM PLATFORM_LINUX
58
59#endif
60
61#endif
62
63#if defined(__x86_64__) || defined(_M_X64) || defined(__alpha__) || defined(__ia64__)
64#define EMU_ARCHITECTURE_X64
65#else
66#define EMU_ARCHITECTURE_X86
67#endif
68
69////////////////////////////////////////////////////////////////////////////////////////////////////
70// Compiler-Specific Definitions
71
72#if EMU_PLATFORM == PLATFORM_WINDOWS
73
74#define NOMINMAX
75#define EMU_FASTCALL __fastcall
76
77#else
78
79#define EMU_FASTCALL __attribute__((fastcall))
80#define __stdcall
81#define __cdecl
82
83#define LONG long
84#define BOOL bool
85#define DWORD u32
86
87#endif
88
89#if EMU_PLATFORM != PLATFORM_WINDOWS
90
91// TODO: Hacks..
92#include <limits.h>
93#define MAX_PATH PATH_MAX
94
95#include <strings.h>
96#define stricmp(str1, str2) strcasecmp(str1, str2)
97#define _stricmp(str1, str2) strcasecmp(str1, str2)
98#define _snprintf snprintf
99#define _getcwd getcwd
100#define _tzset tzset
101
102typedef void EXCEPTION_POINTERS;
103
104inline u32 _rotl(u32 x, int shift) {
105 shift &= 31;
106 if (0 == shift) {
107 return x;
108 }
109 return (x << shift) | (x >> (32 - shift));
110}
111
112inline u64 _rotl64(u64 x, u32 shift){
113 u32 n = shift % 64;
114 return (x << n) | (x >> (64 - n));
115}
116
117inline u32 _rotr(u32 x, int shift) {
118 shift &= 31;
119 if (0 == shift) {
120 return x;
121 }
122 return (x >> shift) | (x << (32 - shift));
123}
124
125inline u64 _rotr64(u64 x, u32 shift){
126 u32 n = shift % 64;
127 return (x >> n) | (x << (64 - n));
128}
129
130#endif
131
132#define GCC_VERSION_AVAILABLE(major, minor) (defined(__GNUC__) && (__GNUC__ > (major) || \
133 (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
134
135#endif // COMMON_PLATFORM_H_
diff --git a/src/common/src/std_condition_variable.h b/src/common/src/std_condition_variable.h
deleted file mode 100644
index e7088725c..000000000
--- a/src/common/src/std_condition_variable.h
+++ /dev/null
@@ -1,152 +0,0 @@
1#ifndef CONDITION_VARIABLE_H_
2#define CONDITION_VARIABLE_H_
3
4#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
5#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
6
7#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__
8// GCC 4.4 provides <condition_variable>
9#include <condition_variable>
10#else
11
12// partial std::condition_variable implementation for win32/pthread
13
14#include "std_mutex.h"
15
16#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
17#define USE_RVALUE_REFERENCES
18#endif
19
20#if defined(_WIN32) && defined(_M_X64)
21#define USE_CONDITION_VARIABLES
22#elif defined(_WIN32)
23#define USE_EVENTS
24#endif
25
26namespace std
27{
28
29class condition_variable
30{
31#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
32 typedef CONDITION_VARIABLE native_type;
33#elif defined(_WIN32)
34 typedef HANDLE native_type;
35#else
36 typedef pthread_cond_t native_type;
37#endif
38
39public:
40
41#ifdef USE_EVENTS
42 typedef native_type native_handle_type;
43#else
44 typedef native_type* native_handle_type;
45#endif
46
47 condition_variable()
48 {
49#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
50 InitializeConditionVariable(&m_handle);
51#elif defined(_WIN32)
52 m_handle = CreateEvent(NULL, false, false, NULL);
53#else
54 pthread_cond_init(&m_handle, NULL);
55#endif
56 }
57
58 ~condition_variable()
59 {
60#if defined(_WIN32) && !defined(USE_CONDITION_VARIABLES)
61 CloseHandle(m_handle);
62#elif !defined(_WIN32)
63 pthread_cond_destroy(&m_handle);
64#endif
65 }
66
67 condition_variable(const condition_variable&) /*= delete*/;
68 condition_variable& operator=(const condition_variable&) /*= delete*/;
69
70 void notify_one()
71 {
72#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
73 WakeConditionVariable(&m_handle);
74#elif defined(_WIN32)
75 SetEvent(m_handle);
76#else
77 pthread_cond_signal(&m_handle);
78#endif
79 }
80
81 void notify_all()
82 {
83#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
84 WakeAllConditionVariable(&m_handle);
85#elif defined(_WIN32)
86 // TODO: broken
87 SetEvent(m_handle);
88#else
89 pthread_cond_broadcast(&m_handle);
90#endif
91 }
92
93 void wait(unique_lock<mutex>& lock)
94 {
95#ifdef _WIN32
96#ifdef USE_SRWLOCKS
97 SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0);
98#elif defined(USE_CONDITION_VARIABLES)
99 SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE);
100#else
101 // TODO: broken, the unlock and wait need to be atomic
102 lock.unlock();
103 WaitForSingleObject(m_handle, INFINITE);
104 lock.lock();
105#endif
106#else
107 pthread_cond_wait(&m_handle, lock.mutex()->native_handle());
108#endif
109 }
110
111 template <class Predicate>
112 void wait(unique_lock<mutex>& lock, Predicate pred)
113 {
114 while (!pred())
115 wait(lock);
116 }
117
118 //template <class Clock, class Duration>
119 //cv_status wait_until(unique_lock<mutex>& lock,
120 // const chrono::time_point<Clock, Duration>& abs_time);
121
122 //template <class Clock, class Duration, class Predicate>
123 // bool wait_until(unique_lock<mutex>& lock,
124 // const chrono::time_point<Clock, Duration>& abs_time,
125 // Predicate pred);
126
127 //template <class Rep, class Period>
128 //cv_status wait_for(unique_lock<mutex>& lock,
129 // const chrono::duration<Rep, Period>& rel_time);
130
131 //template <class Rep, class Period, class Predicate>
132 // bool wait_for(unique_lock<mutex>& lock,
133 // const chrono::duration<Rep, Period>& rel_time,
134 // Predicate pred);
135
136 native_handle_type native_handle()
137 {
138#ifdef USE_EVENTS
139 return m_handle;
140#else
141 return &m_handle;
142#endif
143 }
144
145private:
146 native_type m_handle;
147};
148
149}
150
151#endif
152#endif
diff --git a/src/common/src/std_mutex.h b/src/common/src/std_mutex.h
deleted file mode 100644
index 27c5833f8..000000000
--- a/src/common/src/std_mutex.h
+++ /dev/null
@@ -1,354 +0,0 @@
1#ifndef MUTEX_H_
2#define MUTEX_H_
3
4#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
5#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
6
7#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__
8// GCC 4.4 provides <mutex>
9#include <mutex>
10#else
11
12// partial <mutex> implementation for win32/pthread
13
14#include <algorithm>
15
16#if defined(_WIN32)
17// WIN32
18#define WIN32_LEAN_AND_MEAN
19#include <Windows.h>
20
21#else
22// POSIX
23#include <pthread.h>
24
25#endif
26
27#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
28#define USE_RVALUE_REFERENCES
29#endif
30
31#if defined(_WIN32) && defined(_M_X64)
32#define USE_SRWLOCKS
33#endif
34
35namespace std
36{
37
38class recursive_mutex
39{
40#ifdef _WIN32
41 typedef CRITICAL_SECTION native_type;
42#else
43 typedef pthread_mutex_t native_type;
44#endif
45
46public:
47 typedef native_type* native_handle_type;
48
49 recursive_mutex(const recursive_mutex&) /*= delete*/;
50 recursive_mutex& operator=(const recursive_mutex&) /*= delete*/;
51
52 recursive_mutex()
53 {
54#ifdef _WIN32
55 InitializeCriticalSection(&m_handle);
56#else
57 pthread_mutexattr_t attr;
58 pthread_mutexattr_init(&attr);
59 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
60 pthread_mutex_init(&m_handle, &attr);
61#endif
62 }
63
64 ~recursive_mutex()
65 {
66#ifdef _WIN32
67 DeleteCriticalSection(&m_handle);
68#else
69 pthread_mutex_destroy(&m_handle);
70#endif
71 }
72
73 void lock()
74 {
75#ifdef _WIN32
76 EnterCriticalSection(&m_handle);
77#else
78 pthread_mutex_lock(&m_handle);
79#endif
80 }
81
82 void unlock()
83 {
84#ifdef _WIN32
85 LeaveCriticalSection(&m_handle);
86#else
87 pthread_mutex_unlock(&m_handle);
88#endif
89 }
90
91 bool try_lock()
92 {
93#ifdef _WIN32
94 return (0 != TryEnterCriticalSection(&m_handle));
95#else
96 return !pthread_mutex_trylock(&m_handle);
97#endif
98 }
99
100 native_handle_type native_handle()
101 {
102 return &m_handle;
103 }
104
105private:
106 native_type m_handle;
107};
108
109#if !defined(_WIN32) || defined(USE_SRWLOCKS)
110
111class mutex
112{
113#ifdef _WIN32
114 typedef SRWLOCK native_type;
115#else
116 typedef pthread_mutex_t native_type;
117#endif
118
119public:
120 typedef native_type* native_handle_type;
121
122 mutex(const mutex&) /*= delete*/;
123 mutex& operator=(const mutex&) /*= delete*/;
124
125 mutex()
126 {
127#ifdef _WIN32
128 InitializeSRWLock(&m_handle);
129#else
130 pthread_mutex_init(&m_handle, NULL);
131#endif
132 }
133
134 ~mutex()
135 {
136#ifdef _WIN32
137#else
138 pthread_mutex_destroy(&m_handle);
139#endif
140 }
141
142 void lock()
143 {
144#ifdef _WIN32
145 AcquireSRWLockExclusive(&m_handle);
146#else
147 pthread_mutex_lock(&m_handle);
148#endif
149 }
150
151 void unlock()
152 {
153#ifdef _WIN32
154 ReleaseSRWLockExclusive(&m_handle);
155#else
156 pthread_mutex_unlock(&m_handle);
157#endif
158 }
159
160 bool try_lock()
161 {
162#ifdef _WIN32
163 // XXX TryAcquireSRWLockExclusive requires Windows 7!
164 // return (0 != TryAcquireSRWLockExclusive(&m_handle));
165 return false;
166#else
167 return !pthread_mutex_trylock(&m_handle);
168#endif
169 }
170
171 native_handle_type native_handle()
172 {
173 return &m_handle;
174 }
175
176private:
177 native_type m_handle;
178};
179
180#else
181typedef recursive_mutex mutex; // just use CriticalSections
182
183#endif
184
185enum defer_lock_t { defer_lock };
186enum try_to_lock_t { try_to_lock };
187enum adopt_lock_t { adopt_lock };
188
189template <class Mutex>
190class lock_guard
191{
192public:
193 typedef Mutex mutex_type;
194
195 explicit lock_guard(mutex_type& m)
196 : pm(m)
197 {
198 m.lock();
199 }
200
201 lock_guard(mutex_type& m, adopt_lock_t)
202 : pm(m)
203 {
204 }
205
206 ~lock_guard()
207 {
208 pm.unlock();
209 }
210
211 lock_guard(lock_guard const&) /*= delete*/;
212 lock_guard& operator=(lock_guard const&) /*= delete*/;
213
214private:
215 mutex_type& pm;
216};
217
218template <class Mutex>
219class unique_lock
220{
221public:
222 typedef Mutex mutex_type;
223
224 unique_lock()
225 : pm(NULL), owns(false)
226 {}
227
228 /*explicit*/ unique_lock(mutex_type& m)
229 : pm(&m), owns(true)
230 {
231 m.lock();
232 }
233
234 unique_lock(mutex_type& m, defer_lock_t)
235 : pm(&m), owns(false)
236 {}
237
238 unique_lock(mutex_type& m, try_to_lock_t)
239 : pm(&m), owns(m.try_lock())
240 {}
241
242 unique_lock(mutex_type& m, adopt_lock_t)
243 : pm(&m), owns(true)
244 {}
245
246 //template <class Clock, class Duration>
247 //unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
248
249 //template <class Rep, class Period>
250 //unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
251
252 ~unique_lock()
253 {
254 if (owns_lock())
255 mutex()->unlock();
256 }
257
258#ifdef USE_RVALUE_REFERENCES
259 unique_lock& operator=(const unique_lock&) /*= delete*/;
260
261 unique_lock& operator=(unique_lock&& other)
262 {
263#else
264 unique_lock& operator=(const unique_lock& u)
265 {
266 // ugly const_cast to get around lack of rvalue references
267 unique_lock& other = const_cast<unique_lock&>(u);
268#endif
269 swap(other);
270 return *this;
271 }
272
273#ifdef USE_RVALUE_REFERENCES
274 unique_lock(const unique_lock&) /*= delete*/;
275
276 unique_lock(unique_lock&& other)
277 : pm(NULL), owns(false)
278 {
279#else
280 unique_lock(const unique_lock& u)
281 : pm(NULL), owns(false)
282 {
283 // ugly const_cast to get around lack of rvalue references
284 unique_lock& other = const_cast<unique_lock&>(u);
285#endif
286 swap(other);
287 }
288
289 void lock()
290 {
291 mutex()->lock();
292 owns = true;
293 }
294
295 bool try_lock()
296 {
297 owns = mutex()->try_lock();
298 return owns;
299 }
300
301 //template <class Rep, class Period>
302 //bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
303 //template <class Clock, class Duration>
304 //bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
305
306 void unlock()
307 {
308 mutex()->unlock();
309 owns = false;
310 }
311
312 void swap(unique_lock& u)
313 {
314 std::swap(pm, u.pm);
315 std::swap(owns, u.owns);
316 }
317
318 mutex_type* release()
319 {
320 return mutex();
321 pm = NULL;
322 owns = false;
323 }
324
325 bool owns_lock() const
326 {
327 return owns;
328 }
329
330 //explicit operator bool () const
331 //{
332 // return owns_lock();
333 //}
334
335 mutex_type* mutex() const
336 {
337 return pm;
338 }
339
340private:
341 mutex_type* pm;
342 bool owns;
343};
344
345template <class Mutex>
346void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y)
347{
348 x.swap(y);
349}
350
351}
352
353#endif
354#endif
diff --git a/src/common/src/std_thread.h b/src/common/src/std_thread.h
deleted file mode 100644
index 0580221b2..000000000
--- a/src/common/src/std_thread.h
+++ /dev/null
@@ -1,309 +0,0 @@
1#ifndef STD_THREAD_H_
2#define STD_THREAD_H_
3
4#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
5#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
6
7#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__
8// GCC 4.4 provides <thread>
9#ifndef _GLIBCXX_USE_SCHED_YIELD
10#define _GLIBCXX_USE_SCHED_YIELD
11#endif
12#include <thread>
13#else
14
15// partial std::thread implementation for win32/pthread
16
17#include <algorithm>
18
19#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
20#define USE_RVALUE_REFERENCES
21#endif
22
23#ifdef __APPLE__
24#import <Foundation/NSAutoreleasePool.h>
25#endif
26
27#if defined(_WIN32)
28// WIN32
29
30#define WIN32_LEAN_AND_MEAN
31#include <Windows.h>
32
33#if defined(_MSC_VER) && defined(_MT)
34// When linking with LIBCMT (the multithreaded C library), Microsoft recommends
35// using _beginthreadex instead of CreateThread.
36#define USE_BEGINTHREADEX
37#include <process.h>
38#endif
39
40#ifdef USE_BEGINTHREADEX
41#define THREAD_ID unsigned
42#define THREAD_RETURN unsigned __stdcall
43#else
44#define THREAD_ID DWORD
45#define THREAD_RETURN DWORD WINAPI
46#endif
47#define THREAD_HANDLE HANDLE
48
49#else
50// PTHREAD
51
52#include <unistd.h>
53
54#ifndef _POSIX_THREADS
55#error unsupported platform (no pthreads?)
56#endif
57
58#include <pthread.h>
59
60#define THREAD_ID pthread_t
61#define THREAD_HANDLE pthread_t
62#define THREAD_RETURN void*
63
64#endif
65
66namespace std
67{
68
69class thread
70{
71public:
72 typedef THREAD_HANDLE native_handle_type;
73
74 class id
75 {
76 friend class thread;
77 public:
78 id() : m_thread(0) {}
79 id(THREAD_ID _id) : m_thread(_id) {}
80
81 bool operator==(const id& rhs) const
82 {
83 return m_thread == rhs.m_thread;
84 }
85
86 bool operator!=(const id& rhs) const
87 {
88 return !(*this == rhs);
89 }
90
91 bool operator<(const id& rhs) const
92 {
93 return m_thread < rhs.m_thread;
94 }
95
96 private:
97 THREAD_ID m_thread;
98 };
99
100 // no variadic template support in msvc
101 //template <typename C, typename... A>
102 //thread(C&& func, A&&... args);
103
104 template <typename C>
105 thread(C func)
106 {
107 StartThread(new Func<C>(func));
108 }
109
110 template <typename C, typename A>
111 thread(C func, A arg)
112 {
113 StartThread(new FuncArg<C, A>(func, arg));
114 }
115
116 thread() /*= default;*/ {}
117
118#ifdef USE_RVALUE_REFERENCES
119 thread(const thread&) /*= delete*/;
120
121 thread(thread&& other)
122 {
123#else
124 thread(const thread& t)
125 {
126 // ugly const_cast to get around lack of rvalue references
127 thread& other = const_cast<thread&>(t);
128#endif
129 swap(other);
130 }
131
132#ifdef USE_RVALUE_REFERENCES
133 thread& operator=(const thread&) /*= delete*/;
134
135 thread& operator=(thread&& other)
136 {
137#else
138 thread& operator=(const thread& t)
139 {
140 // ugly const_cast to get around lack of rvalue references
141 thread& other = const_cast<thread&>(t);
142#endif
143 if (joinable())
144 detach();
145 swap(other);
146 return *this;
147 }
148
149 ~thread()
150 {
151 if (joinable())
152 detach();
153 }
154
155 bool joinable() const
156 {
157 return m_id != id();
158 }
159
160 id get_id() const
161 {
162 return m_id;
163 }
164
165 native_handle_type native_handle()
166 {
167#ifdef _WIN32
168 return m_handle;
169#else
170 return m_id.m_thread;
171#endif
172 }
173
174 void join()
175 {
176#ifdef _WIN32
177 WaitForSingleObject(m_handle, INFINITE);
178 detach();
179#else
180 pthread_join(m_id.m_thread, NULL);
181 m_id = id();
182#endif
183 }
184
185 void detach()
186 {
187#ifdef _WIN32
188 CloseHandle(m_handle);
189#else
190 pthread_detach(m_id.m_thread);
191#endif
192 m_id = id();
193 }
194
195 void swap(thread& other)
196 {
197 std::swap(m_id, other.m_id);
198#ifdef _WIN32
199 std::swap(m_handle, other.m_handle);
200#endif
201 }
202
203 static unsigned hardware_concurrency()
204 {
205#ifdef _WIN32
206 SYSTEM_INFO sysinfo;
207 GetSystemInfo(&sysinfo);
208 return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);
209#else
210 return 0;
211#endif
212 }
213
214private:
215 id m_id;
216
217#ifdef _WIN32
218 native_handle_type m_handle;
219#endif
220
221 template <typename F>
222 void StartThread(F* param)
223 {
224#ifdef USE_BEGINTHREADEX
225 m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
226#elif defined(_WIN32)
227 m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
228#else
229 pthread_attr_t attr;
230 pthread_attr_init(&attr);
231 pthread_attr_setstacksize(&attr, 1024 * 1024);
232 if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param))
233 m_id = id();
234#endif
235 }
236
237 template <typename C>
238 class Func
239 {
240 public:
241 Func(C _func) : func(_func) {}
242
243 void Run() { func(); }
244
245 private:
246 C const func;
247 };
248
249 template <typename C, typename A>
250 class FuncArg
251 {
252 public:
253 FuncArg(C _func, A _arg) : func(_func), arg(_arg) {}
254
255 void Run() { func(arg); }
256
257 private:
258 C const func;
259 A arg;
260 };
261
262 template <typename F>
263 static THREAD_RETURN RunAndDelete(void* param)
264 {
265#ifdef __APPLE__
266 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
267#endif
268 static_cast<F*>(param)->Run();
269 delete static_cast<F*>(param);
270#ifdef __APPLE__
271 [pool release];
272#endif
273 return 0;
274 }
275};
276
277namespace this_thread
278{
279
280 inline void yield()
281 {
282#ifdef _WIN32
283 SwitchToThread();
284#else
285 sleep(0);
286#endif
287 }
288
289 inline thread::id get_id()
290 {
291#ifdef _WIN32
292 return GetCurrentThreadId();
293#else
294 return pthread_self();
295#endif
296 }
297
298} // namespace this_thread
299
300} // namespace std
301
302#undef USE_RVALUE_REFERENCES
303#undef USE_BEGINTHREADEX
304#undef THREAD_ID
305#undef THREAD_RETURN
306#undef THREAD_HANDLE
307
308#endif
309#endif
diff --git a/src/common/src/timer.cpp b/src/common/src/timer.cpp
deleted file mode 100644
index c731ffb97..000000000
--- a/src/common/src/timer.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
1/*!
2* Copyright (C) 2005-2012 Gekko Emulator
3*
4* \file timer.h
5* \author ShizZy <shizzy247@gmail.com>
6* \date 2012-02-11
7* \brief Common time and timer routines
8*
9 * \section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#include "SDL.h"
26
27#include "common.h"
28#include "timer.h"
29
30namespace common {
31
32/// Converts a ticks (miliseconds) u64 to a formatted string
33void TicksToFormattedString(u32 ticks, char* formatted_string) {
34 u32 hh = ticks / (1000 * 60 * 60);
35 ticks -= hh * (1000 * 60 * 60);
36
37 u32 mm = ticks / (1000 * 60);
38 ticks -= mm * (1000 * 60);
39
40 u32 ss = ticks / 1000;
41 ticks -= ss * 1000;
42
43 sprintf(formatted_string, "%02d:%02d:%03d", mm, ss, ticks);
44}
45
46} // namespace \ No newline at end of file
diff --git a/src/common/src/timer.h b/src/common/src/timer.h
deleted file mode 100644
index dfbf87dfb..000000000
--- a/src/common/src/timer.h
+++ /dev/null
@@ -1,51 +0,0 @@
1/*!
2* Copyright (C) 2005-2012 Gekko Emulator
3*
4* \file timer.h
5* \author ShizZy <shizzy247@gmail.com>
6* \date 2012-02-11
7* \brief Common time and timer routines
8*
9 * \section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_TIMER_H_
26#define COMMON_TIMER_H_
27
28#include "types.h"
29
30namespace common {
31
32/*!
33 * \brief Gets Get the number of milliseconds since initialization
34 * \return Unsigned integer of ticks since software initialization
35 */
36static inline u32 GetTimeElapsed() {
37 return SDL_GetTicks();
38}
39
40/*!
41 * \brief Converts a ticks (miliseconds) u32 to a formatted string
42 * \param ticks Ticks (32-bit unsigned integer)
43 * \param formatted_string Pointer to formatted string result
44 */
45void TicksToFormattedString(u32 ticks, char* formatted_string);
46
47
48} // namespace
49
50
51#endif // COMMON_TIMER_H_ \ No newline at end of file
diff --git a/src/common/src/types.h b/src/common/src/types.h
deleted file mode 100644
index d1e027957..000000000
--- a/src/common/src/types.h
+++ /dev/null
@@ -1,119 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file types.h
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-02-11
7 * @brief Common types used throughout the project
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_TYPES_H_
26#define COMMON_TYPES_H_
27
28#include <math.h>
29#include <xmmintrin.h> // data_types__m128.cpp
30
31typedef unsigned char u8; ///< 8-bit unsigned byte
32typedef unsigned short u16; ///< 16-bit unsigned short
33typedef unsigned int u32; ///< 32-bit unsigned word
34
35typedef signed char s8; ///< 8-bit signed byte
36typedef signed short s16; ///< 16-bit signed short
37typedef signed int s32; ///< 32-bit signed word
38
39typedef signed int x32; ///< S15.16 fixed point int
40
41typedef float f32; ///< 32-bit floating point
42typedef double f64; ///< 64-bit floating point
43
44#ifdef _MSC_VER
45
46typedef unsigned __int64 u64; ///< 64-bit unsigned int
47typedef signed __int64 s64; ///< 64-bit signed int
48
49#elif defined(__GNUC__)
50
51typedef signed long long s64; ///< 64-bit unsigned int
52typedef unsigned long long u64; ///< 64-bit signed int
53
54#define U64(a) a ## ull
55#define S64(a) a ## sll
56
57#endif
58
59/// Union for fast 16-bit type casting
60union t16 {
61 u8 _u8[2]; ///< 8-bit unsigned char(s)
62 u16 _u16; ///< 16-bit unsigned shorts(s)
63};
64
65/// Union for fast 32-bit type casting
66union t32 {
67 f32 _f32; ///< 32-bit floating point(s)
68 u32 _u32; ///< 32-bit unsigned int(s)
69 x32 _x32; ///< 32-bit fixed point(s)
70 u16 _u16[2]; ///< 16-bit unsigned shorts(s)
71 u8 _u8[4]; ///< 8-bit unsigned char(s)
72};
73
74/// Union for fast 64-bit type casting
75union t64 {
76 f64 _f64; ///< 64-bit floating point
77 u64 _u64; ///< 64-bit unsigned long
78 f32 _f32[2]; ///< 32-bit floating point(s)
79 u32 _u32[2]; ///< 32-bit unsigned int(s)
80 x32 _x32[2]; ///< 32-bit fixed point(s)
81 u16 _u16[4]; ///< 16-bit unsigned shorts(s)
82 u8 _u8[8]; ///< 8-bit unsigned char(s)
83};
84
85/// Union for fast 128-bit type casting
86union t128 {
87 struct
88 {
89 t64 ps0; ///< 64-bit paired single 0
90 t64 ps1; ///< 64-bit paired single 1
91 };
92 __m128 a; ///< 128-bit floating point (__m128 maps to the XMM[0-7] registers)
93};
94
95/// Rectangle data structure
96class Rect {
97public:
98 Rect(int x0=0, int y0=0, int x1=0, int y1=0) {
99 x0_ = x0;
100 y0_ = y0;
101 x1_ = x1;
102 y1_ = y1;
103 }
104 ~Rect() { }
105
106 int x0_; ///< Rect top left X-coordinate
107 int y0_; ///< Rect top left Y-coordinate
108 int x1_; ///< Rect bottom left X-coordinate
109 int y1_; ///< Rect bottom right Y-coordinate
110
111 inline u32 width() const { return abs(x1_ - x0_); }
112 inline u32 height() const { return abs(y1_ - y0_); }
113
114 inline bool operator == (const Rect& val) const {
115 return (x0_ == val.x0_ && y0_ == val.y0_ && x1_ == val.x1_ && y1_ == val.y1_);
116 }
117};
118
119#endif // COMMON_TYPES_H_ \ No newline at end of file
diff --git a/src/common/src/x86_utils.cpp b/src/common/src/x86_utils.cpp
deleted file mode 100644
index 8af6b9868..000000000
--- a/src/common/src/x86_utils.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file x86_utils.cpp
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-12-23
7 * @brief Utilities for the x86 architecture
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#include "common.h"
26#include "x86_utils.h"
27
28#ifdef _WIN32
29#define _interlockedbittestandset workaround_ms_header_bug_platform_sdk6_set
30#define _interlockedbittestandreset workaround_ms_header_bug_platform_sdk6_reset
31#define _interlockedbittestandset64 workaround_ms_header_bug_platform_sdk6_set64
32#define _interlockedbittestandreset64 workaround_ms_header_bug_platform_sdk6_reset64
33#include <intrin.h>
34#undef _interlockedbittestandset
35#undef _interlockedbittestandreset
36#undef _interlockedbittestandset64
37#undef _interlockedbittestandreset64
38#else
39
40//#include <config/i386/cpuid.h>
41#include <xmmintrin.h>
42
43#if defined __FreeBSD__
44#include <sys/types.h>
45#include <machine/cpufunc.h>
46#else
47static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
48 unsigned int *ecx, unsigned int *edx)
49{
50#ifdef _LP64
51 // Note: EBX is reserved on Mac OS X and in PIC on Linux, so it has to
52 // restored at the end of the asm block.
53 __asm__ (
54 "cpuid;"
55 "movl %%ebx,%1;"
56 : "=a" (*eax),
57 "=S" (*ebx),
58 "=c" (*ecx),
59 "=d" (*edx)
60 : "a" (*eax)
61 : "rbx"
62 );
63#else
64 __asm__ (
65 "cpuid;"
66 "movl %%ebx,%1;"
67 : "=a" (*eax),
68 "=S" (*ebx),
69 "=c" (*ecx),
70 "=d" (*edx)
71 : "a" (*eax)
72 : "ebx"
73 );
74#endif
75}
76#endif
77
78static void __cpuid(int info[4], int x)
79{
80#if defined __FreeBSD__
81 do_cpuid((unsigned int)x, (unsigned int*)info);
82#else
83 unsigned int eax = x, ebx = 0, ecx = 0, edx = 0;
84 do_cpuid(&eax, &ebx, &ecx, &edx);
85 info[0] = eax;
86 info[1] = ebx;
87 info[2] = ecx;
88 info[3] = edx;
89#endif
90}
91
92#endif
93
94namespace common {
95
96X86Utils::X86Utils() {
97 memset(this, 0, sizeof(*this));
98#ifdef _M_IX86
99
100#elif defined (_M_X64)
101 support_x64_os_ = true;
102 support_sse_ = true;
103 support_sse2_ = true;
104#endif
105 num_cores_ = 1;
106#ifdef _WIN32
107#ifdef _M_IX86
108 int f64 = 0;
109 IsWow64Process(GetCurrentProcess(), &f64);
110 support_x64_os_ = (f64 == 1) ? true : false;
111#endif
112#endif
113 // Assume CPU supports the CPUID instruction. Those that don't can barely
114 // boot modern OS:es anyway.
115 int cpu_id[4];
116 char cpu_string[32];
117 memset(cpu_string, 0, sizeof(cpu_string));
118
119 // Detect CPU's CPUID capabilities, and grab cpu string
120 __cpuid(cpu_id, 0x00000000);
121 u32 max_std_fn = cpu_id[0]; // EAX
122 *((int *)cpu_string) = cpu_id[1];
123 *((int *)(cpu_string + 4)) = cpu_id[3];
124 *((int *)(cpu_string + 8)) = cpu_id[2];
125 __cpuid(cpu_id, 0x80000000);
126 u32 max_ex_fn = cpu_id[0];
127 if (!strcmp(cpu_string, "GenuineIntel")) {
128 cpu_vendor_ = kVendorX86_Intel;
129 } else if (!strcmp(cpu_string, "AuthenticAMD")) {
130 cpu_vendor_ = kVendorX86_AMD;
131 } else {
132 cpu_vendor_ = kVendorX86_None;
133 }
134
135 // Detect family and other misc stuff.
136 bool ht = false;
137 support_hyper_threading_ = ht;
138 logical_cpu_count_ = 1;
139 if (max_std_fn >= 1) {
140 __cpuid(cpu_id, 0x00000001);
141 logical_cpu_count_ = (cpu_id[1] >> 16) & 0xFF;
142 ht = (cpu_id[3] >> 28) & 1;
143
144 if ((cpu_id[3] >> 25) & 1) support_sse_ = true;
145 if ((cpu_id[3] >> 26) & 1) support_sse2_ = true;
146 if ((cpu_id[2]) & 1) support_sse3_ = true;
147 if ((cpu_id[2] >> 9) & 1) support_ssse3_ = true;
148 if ((cpu_id[2] >> 19) & 1) support_sse4_1_ = true;
149 if ((cpu_id[2] >> 20) & 1) support_sse4_2_ = true;
150 }
151 if (max_ex_fn >= 0x80000004) {
152 // Extract brand string
153 __cpuid(cpu_id, 0x80000002);
154// memcpy(brand_string, cpu_id, sizeof(cpu_id));
155 __cpuid(cpu_id, 0x80000003);
156// memcpy(brand_string + 16, cpu_id, sizeof(cpu_id));
157 __cpuid(cpu_id, 0x80000004);
158// memcpy(brand_string + 32, cpu_id, sizeof(cpu_id));
159 }
160 num_cores_ = (logical_cpu_count_ == 0) ? 1 : logical_cpu_count_;
161
162 if (max_ex_fn >= 0x80000008) {
163 // Get number of cores. This is a bit complicated. Following AMD manual here.
164 __cpuid(cpu_id, 0x80000008);
165 int apic_id_core_id_size = (cpu_id[2] >> 12) & 0xF;
166 if (apic_id_core_id_size == 0) {
167 if (ht) {
168 // New mechanism for modern Intel CPUs.
169 if (cpu_vendor_ == kVendorX86_Intel) {
170 __cpuid(cpu_id, 0x00000004);
171 int cores_x_package = ((cpu_id[0] >> 26) & 0x3F) + 1;
172 support_hyper_threading_ = (cores_x_package < logical_cpu_count_);
173 cores_x_package = ((logical_cpu_count_ % cores_x_package) == 0) ? cores_x_package : 1;
174 num_cores_ = (cores_x_package > 1) ? cores_x_package : num_cores_;
175 logical_cpu_count_ /= cores_x_package;
176 }
177 }
178 } else {
179 // Use AMD's new method.
180 num_cores_ = (cpu_id[2] & 0xFF) + 1;
181 }
182 }
183 LOG_NOTICE(TCOMMON, "CPU detected (%s)", this->Summary().c_str());
184}
185
186X86Utils::~X86Utils() {
187}
188
189/**
190 * Check if an X86 extension is supported by the current architecture
191 * @param extension ExtensionX86 extension support to check for
192 * @return True if the extension is supported, otherwise false
193 */
194bool X86Utils::IsExtensionSupported(X86Utils::ExtensionX86 extension) {
195 switch (extension) {
196 case kExtensionX86_SSE:
197 return support_sse_;
198 case kExtensionX86_SSE2:
199 return support_sse2_;
200 case kExtensionX86_SSE3:
201 return support_sse3_;
202 case kExtensionX86_SSSE3:
203 return support_ssse3_;
204 case kExtensionX86_SSE4_1:
205 return support_sse4_1_;
206 case kExtensionX86_SSE4_2:
207 return support_sse4_2_;
208 }
209 return false;
210}
211
212/**
213 * Gets a string summary of the X86 CPU information, suitable for printing
214 * @return String summary
215 */
216std::string X86Utils::Summary() {
217 const char* cpu_vendors[] = {
218 "Unknown", "Intel", "AMD"
219 };
220 std::string res;
221 res = FormatStr("%s, %d core%s", cpu_vendors[cpu_vendor_], num_cores_, (num_cores_ > 1) ? "s" : "");
222 if (support_sse4_2_) {
223 res += FormatStr(" (%i logical threads per physical core)", logical_cpu_count_);
224 }
225 if (support_sse_) res += ", SSE";
226 if (support_sse2_) res += ", SSE2";
227 if (support_sse3_) res += ", SSE3";
228 if (support_ssse3_) res += ", SSSE3";
229 if (support_sse4_1_) res += ", SSE4.1";
230 if (support_sse4_2_) res += ", SSE4.2";
231 if (support_hyper_threading_) res += ", HTT";
232 //if (bLongMode) res += ", 64-bit support";
233 return res;
234}
235
236} // namespace
diff --git a/src/common/src/x86_utils.h b/src/common/src/x86_utils.h
deleted file mode 100644
index 6dc8c0d92..000000000
--- a/src/common/src/x86_utils.h
+++ /dev/null
@@ -1,92 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file x86_utils.h
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-02-11
7 * @brief Utilities for the x86 architecture
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_X86_UTILS_
26#define COMMON_X86_UTILS_
27
28#include <string>
29#include "types.h"
30
31// Common namespace
32namespace common {
33
34class X86Utils {
35public:
36 /// Enumeration of X86 vendors
37 enum VendorX86 {
38 kVendorX86_None = 0,
39 kVendorX86_Intel,
40 kVendorX86_AMD,
41 kVendorX86_NumberOf
42 };
43
44 /// Enumeration of X86 extensions
45 enum ExtensionX86 {
46 kExtensionX86_None = 0,
47 kExtensionX86_SSE,
48 kExtensionX86_SSE2,
49 kExtensionX86_SSE3,
50 kExtensionX86_SSSE3,
51 kExtensionX86_SSE4_1,
52 kExtensionX86_SSE4_2,
53 kExtensionX86_NumberOf
54 };
55
56 X86Utils();
57 ~X86Utils();
58
59 /**
60 * Check if an X86 extension is supported by the current architecture
61 * @param extension ExtensionX86 extension support to check for
62 * @return True if the extension is supported, otherwise false
63 */
64 bool IsExtensionSupported(ExtensionX86 extension);
65
66 /**
67 * Gets a string summary of the X86 CPU information, suitable for printing
68 * @return String summary
69 */
70 std::string Summary();
71
72private:
73 bool support_x64_os_;
74 bool support_x64_cpu_;
75 bool support_hyper_threading_;
76
77 int num_cores_;
78 int logical_cpu_count_;
79
80 bool support_sse_;
81 bool support_sse2_;
82 bool support_sse3_;
83 bool support_ssse3_;
84 bool support_sse4_1_;
85 bool support_sse4_2_;
86
87 VendorX86 cpu_vendor_;
88};
89
90} // namespace
91
92#endif
diff --git a/src/common/src/xml.cpp b/src/common/src/xml.cpp
deleted file mode 100644
index f4b913890..000000000
--- a/src/common/src/xml.cpp
+++ /dev/null
@@ -1,487 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file xml.h
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-02-12
7 * @brief Used for parsing XML configurations
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#include <iostream>
26#include <fstream>
27
28#include <rapidxml.hpp>
29
30#include "common.h"
31#include "misc_utils.h"
32#include "config.h"
33#include "log.h"
34
35/// Gets a RapidXML boolean element value
36static bool GetXMLElementAsBool(rapidxml::xml_node<> *node, const char* element_name) {
37 rapidxml::xml_node<> *sub_node = node->first_node(element_name);
38 if (sub_node) {
39 return (E_OK == _stricmp(sub_node->value(), "true")) ? true : false;
40 }
41 return false;
42}
43
44/// Gets a RapidXML string element value
45static char* GetXMLElementAsString(rapidxml::xml_node<> *node, const char* element_name,
46 char* element_value) {
47 rapidxml::xml_node<> *sub_node = node->first_node(element_name);
48 if (sub_node) {
49 strcpy(element_value, sub_node->value());
50 return element_value;
51 }
52 return NULL;
53}
54
55/// Gets a RapidXML integer element value
56static int GetXMLElementAsInt(rapidxml::xml_node<> *node, const char* element_name) {
57 rapidxml::xml_node<> *sub_node = node->first_node(element_name);
58 if (sub_node) {
59 return atoi(sub_node->value());
60 }
61 return 0;
62}
63
64namespace common {
65
66/**
67 * @brief Parse the "General" XML group
68 * @param node RapidXML node for the "General" XML group
69 * @param config Config class object to parse data into
70 */
71void ParseGeneralNode(rapidxml::xml_node<> *node, Config& config) {
72 // Don't parse the node if it doesn't exist!
73 if (!node) {
74 return;
75 }
76 char temp_str[MAX_PATH];
77 config.set_enable_multicore(GetXMLElementAsBool(node, "EnableMultiCore"));
78 config.set_enable_idle_skipping(GetXMLElementAsBool(node, "EnableIdleSkipping"));
79 config.set_enable_hle(GetXMLElementAsBool(node, "EnableHLE"));
80 config.set_enable_auto_boot(GetXMLElementAsBool(node, "EnableAutoBoot"));
81 config.set_enable_cheats(GetXMLElementAsBool(node, "EnableCheats"));
82 config.set_default_boot_file(GetXMLElementAsString(node, "DefaultBootFile", temp_str), MAX_PATH);
83
84 // Parse all search paths in the DVDImagePaths node
85 rapidxml::xml_node<> *sub_node = node->first_node("DVDImagePaths");
86 if (sub_node) {
87 int i = 0;
88 for (rapidxml::xml_node<> *elem = sub_node->first_node("Path"); elem;
89 elem = elem->next_sibling()) {
90
91 config.set_dvd_image_path(i, elem->value(), MAX_PATH);
92 LOG_NOTICE(TCONFIG, "Adding %s to DVD image search paths...\n",
93 config.dvd_image_path(i));
94 i++;
95 // Stop if we have parsed the maximum paths
96 if (MAX_SEARCH_PATHS < i) {
97 LOG_WARNING(TCONFIG, "Maximum number of DVDImagePath search paths is %d, not parsing"
98 " any more!", MAX_SEARCH_PATHS);
99 break;
100 }
101 }
102 }
103}
104
105/**
106 * @brief Parse the "Debug" XML group
107 * @param node RapidXML node for the "Debug" XML group
108 * @param config Config class object to parse data into
109 */
110void ParseDebugNode(rapidxml::xml_node<> *node, Config& config) {
111 // Don't parse the node if it doesn't exist!
112 if (!node) {
113 return;
114 }
115 config.set_enable_show_fps(GetXMLElementAsBool(node, "EnableShowFPS"));
116 config.set_enable_dump_opcode0(GetXMLElementAsBool(node, "EnableDumpOpcode0"));
117 config.set_enable_pause_on_unknown_opcode(GetXMLElementAsBool(node,
118 "EnablePauseOnUnknownOpcode"));
119 config.set_enable_dump_gcm_reads(GetXMLElementAsBool(node, "EnableDumpGCMReads"));
120}
121
122/**
123 * @brief Parse the "Patches" and "Cheats" XML group
124 * @param node RapidXML node for the "Patches" or "Cheats" XML group
125 * @param config Config class object to parse data into
126 */
127void ParsePatchesNode(rapidxml::xml_node<> *node, Config& config, const char* node_name) {
128 int i = 0;
129 char node_name_str[8];
130
131 // Get lowercase section name
132 strcpy(node_name_str, node_name);
133
134 // TODO: not available on Unix
135 common::LowerStr(node_name_str);
136
137 // Parse all search patches in the Patches node
138 rapidxml::xml_node<> *sub_node = node->first_node(node_name);
139 if (sub_node) {
140 for (rapidxml::xml_node<> *elem = sub_node->first_node("Patch"); elem;
141 elem = elem->next_sibling()) {
142
143 // Get enable attribute (note: defaults to true)
144 rapidxml::xml_attribute<> *attr = elem->first_attribute("enable");
145 if (attr) {
146 if (E_OK == _stricmp(attr->value(), "false")) {
147 continue; // Patch is disabled, skip it
148 }
149 }
150 // Get address attribute
151 attr = elem->first_attribute("address");
152 if (!attr) {
153 LOG_ERROR(TCONFIG, "Patch without 'address' attribute illegal!");
154 continue;
155 } else {
156 u32 data = 0;
157 u32 address = 0;
158 {
159 // Convert address hexstring to unsigned int
160 std::stringstream ss;
161 ss << std::hex << attr->value();
162 ss >> address;
163 }
164 attr = elem->first_attribute("instr");
165
166 // Get "data" attribute if no "instr" attribute
167 if (!attr) {
168 attr = elem->first_attribute("data");
169 // Neither found - error
170 if (!attr) {
171 LOG_ERROR(TCONFIG, "Patch without 'instr' or 'data' attributes "
172 "illegal!");
173 continue;
174 } else {
175 // Found data, convert hexstring to unsigned int
176 std::stringstream ss;
177 ss << std::hex << attr->value();
178 ss >> data;
179 }
180 } else {
181 // Found instr
182 char instr_str[4];
183
184 // Convert to lowercase
185 strcpy(instr_str, attr->value());
186 // TODO: not available on Unix
187 common::LowerStr(instr_str);
188
189 // Convert instruction to equivalent PPC bytecode
190 // TODO(ShizZy): Pull this out to the PowerPC modules at some point
191 if (E_OK == _stricmp(instr_str, "blr")) {
192 data = 0x4E800020; // PowerPC BLR instruction bytecode
193 } else if (E_OK == _stricmp(instr_str, "nop")) {
194 data = 0x60000000; // PowerPC NOP instruction bytecode
195 } else {
196 LOG_ERROR(TCONFIG, "Patch with invalid 'instr' attribute illegal!");
197 continue;
198 }
199 }
200 Config::Patch patch = { address, data };
201
202 if (E_OK == _stricmp(node_name_str, "patches")) {
203 LOG_NOTICE(TCONFIG, "Adding patch addr=0x%08x data=0x%08x to patches...\n",
204 address, data, node_name_str);
205 config.set_patches(i, patch);
206 } else if (E_OK == _stricmp(node_name_str, "cheats")) {
207 LOG_NOTICE(TCONFIG, "Adding cheat addr=0x%08x data=0x%08x to cheats...\n",
208 address, data, node_name_str);
209 config.set_cheats(i, patch);
210 } else {
211 LOG_ERROR(TCONFIG, "Unexpected patch type %s, ignoring...", node_name_str);
212 }
213
214 // Stop if we have parsed the maximum patches
215 if (MAX_PATCHES_PER_GAME < ++i) {
216 LOG_WARNING(TCONFIG, "Maximum number of patches search paths is %d, not parsing"
217 " any more!", MAX_PATCHES_PER_GAME);
218 break;
219 }
220 }
221 }
222 }
223}
224
225/**
226 * @brief Parse the "Boot" XML group
227 * @param node RapidXML node for the "Boot" XML group
228 * @param config Config class object to parse data into
229 */
230void ParseBootNode(rapidxml::xml_node<> *node, Config& config) {
231 // Don't parse the node if it doesn't exist!
232 if (!node) {
233 return;
234 }
235 config.set_enable_ipl(GetXMLElementAsBool(node, "EnableIPL"));
236
237 ParsePatchesNode(node, config, "Patches");
238 ParsePatchesNode(node, config, "Cheats");
239}
240
241/**
242 * @brief Parse the "Video" XML group
243 * @param node RapidXML node for the "Video" XML group
244 * @param config Config class object to parse data into
245 */
246void ParsePowerPCNode(rapidxml::xml_node<> *node, Config& config) {
247 // Don't parse the node if it doesn't exist!
248 if (!node) {
249 return;
250 }
251 rapidxml::xml_attribute<> *attr = node->first_attribute("core");
252
253 // Attribute not found - error
254 if (!attr) {
255 LOG_ERROR(TCONFIG, "PowerPC without 'core' attribute illegal!");
256 } else {
257 char core_str[12] = "null";
258
259 // Convert to lowercase
260 strcpy(core_str, attr->value());
261 // TODO: not available on Unix
262 common::LowerStr(core_str);
263
264 // Use interpreter core
265 if (E_OK == _stricmp(core_str, "interpreter")) {
266 config.set_powerpc_core(Config::CPU_INTERPRETER); // Interpreter selected
267 // Use dynarec core
268 } else if (E_OK == _stricmp(core_str, "dynarec")) {
269 config.set_powerpc_core(Config::CPU_DYNAREC); // Dynarec selected
270 // Unsupported type
271 } else {
272 LOG_ERROR(TCONFIG, "Invalid PowerPC type %s for attribute 'core' selected!",
273 core_str);
274 }
275 // Set frequency
276 attr = node->first_attribute("freq");
277 if (attr) {
278 config.set_powerpc_frequency(atoi(attr->value()));
279 }
280 LOG_NOTICE(TCONFIG, "Configured core=%s freq=%d", core_str, config.powerpc_frequency());
281 }
282}
283
284/**
285 * @brief Parse the "Video" XML group
286 * @param node RapidXML node for the "Video" XML group
287 * @param config Config class object to parse data into
288 */
289void ParseVideoNode(rapidxml::xml_node<> *node, Config& config) {
290 char res_str[512];
291 Config::ResolutionType res;
292
293 // Don't parse the node if it doesn't exist!
294 if (!node) {
295 return;
296 }
297 config.set_enable_fullscreen(GetXMLElementAsBool(node, "EnableFullscreen"));
298
299 // Set resolutions
300 GetXMLElementAsString(node, "WindowResolution", res_str);
301 sscanf(res_str, "%d_%d", &res.width, &res.height);
302 config.set_window_resolution(res);
303 GetXMLElementAsString(node, "FullscreenResolution", res_str);
304 sscanf(res_str, "%d_%d", &res.width, &res.height);
305 config.set_fullscreen_resolution(res);
306
307 // Parse all search renderer nodes
308 for (rapidxml::xml_node<> *elem = node->first_node("Renderer"); 1; ) {
309 Config::RendererConfig renderer_config;
310
311 rapidxml::xml_attribute<> *attr = elem->first_attribute("name");
312
313 Config::RendererType type = Config::StringToRenderType(attr->value());
314
315 renderer_config.enable_wireframe = GetXMLElementAsBool(elem, "EnableWireframe");
316 renderer_config.enable_shaders = GetXMLElementAsBool(elem, "EnableShaders");
317 renderer_config.enable_textures = GetXMLElementAsBool(elem, "EnableTextures");
318 renderer_config.enable_texture_dumping = GetXMLElementAsBool(elem, "EnableTextureDumping");
319 renderer_config.anti_aliasing_mode = GetXMLElementAsInt(elem, "AntiAliasingMode");
320 renderer_config.anistropic_filtering_mode = GetXMLElementAsInt(elem, "AnistropicFilteringMode");
321
322 config.set_renderer_config(type, renderer_config);
323
324 LOG_NOTICE(TCONFIG, "Renderer %s configured", attr->value());
325
326 break;
327 }
328}
329
330/**
331 * @brief Parse the "Devices" XML group
332 * @param node RapidXML node for the "Devices" XML group
333 * @param config Config class object to parse data into
334 */
335void ParseDevicesNode(rapidxml::xml_node<> *node, Config& config) {
336 // Don't parse the node if it doesn't exist!c
337 if (!node) {
338 return;
339 }
340 // Parse GameCube section
341 rapidxml::xml_node<> *gamecube_node = node->first_node("GameCube");
342 if (!gamecube_node) {
343 return;
344 }
345 // Parse all MemSlot nodes
346 for (rapidxml::xml_node<> *elem = gamecube_node->first_node("MemSlot"); elem;
347 elem = elem->next_sibling("MemSlot")) {
348 Config::MemSlot slot_config;
349
350 // Select MemSlot a or b
351 rapidxml::xml_attribute<> *attr = elem->first_attribute("slot");
352 int slot = (E_OK == _stricmp(attr->value(), "a")) ? 0 : 1;
353
354 // Enable
355 attr = elem->first_attribute("enable");
356 slot_config.enable = (E_OK == _stricmp(attr->value(), "true")) ? true : false;
357
358 // Select device
359 attr = elem->first_attribute("device");
360 slot_config.device = 0; // Only support memcards right now
361
362 LOG_NOTICE(TCONFIG, "Configured MemSlot[%d]=%s enabled=%s", slot, attr->value(),
363 slot_config.enable ? "true" : "false");
364
365 config.set_mem_slots(slot, slot_config);
366 }
367 // Parse all ControlerPort nodes
368 for (rapidxml::xml_node<> *elem = gamecube_node->first_node("ControllerPort"); elem;
369 elem = elem->next_sibling("ControllerPort")) {
370 Config::ControllerPort port_config;
371
372 // Select MemSlot a or b
373 rapidxml::xml_attribute<> *attr = elem->first_attribute("port");
374 int port = atoi(attr->value());
375
376 // Enable
377 attr = elem->first_attribute("enable");
378 port_config.enable = (E_OK == _stricmp(attr->value(), "true")) ? true : false;
379
380 // Select device
381 attr = elem->first_attribute("device");
382 port_config.device = 0; // Only support memcards right now
383
384 LOG_NOTICE(TCONFIG, "Configured ControllerPort[%d]=%s enabled=%s", port, attr->value(),
385 port_config.enable ? "true" : "false");
386
387 // Parse keyboard configuration - TODO: Move to EmuWindow (?)
388 rapidxml::xml_node<> *keyboard_node = elem->first_node("KeyboardController");
389 if (keyboard_node) {
390 attr = keyboard_node->first_attribute("enable");
391 port_config.keys.enable = (E_OK == _stricmp(attr->value(), "true")) ? true : false;
392 port_config.keys.key_code[Config::BUTTON_A] = GetXMLElementAsInt(keyboard_node, "AKey");
393 port_config.keys.key_code[Config::BUTTON_B] = GetXMLElementAsInt(keyboard_node, "BKey");
394 port_config.keys.key_code[Config::BUTTON_X] = GetXMLElementAsInt(keyboard_node, "XKey");
395 port_config.keys.key_code[Config::BUTTON_Y] = GetXMLElementAsInt(keyboard_node, "YKey");
396 port_config.keys.key_code[Config::TRIGGER_L] = GetXMLElementAsInt(keyboard_node, "LKey");
397 port_config.keys.key_code[Config::TRIGGER_R] = GetXMLElementAsInt(keyboard_node, "RKey");
398 port_config.keys.key_code[Config::BUTTON_Z] = GetXMLElementAsInt(keyboard_node, "ZKey");
399 port_config.keys.key_code[Config::BUTTON_START] = GetXMLElementAsInt(keyboard_node, "StartKey");
400 port_config.keys.key_code[Config::ANALOG_UP] = GetXMLElementAsInt(keyboard_node, "AnalogUpKey");
401 port_config.keys.key_code[Config::ANALOG_DOWN] = GetXMLElementAsInt(keyboard_node, "AnalogDownKey");
402 port_config.keys.key_code[Config::ANALOG_LEFT] = GetXMLElementAsInt(keyboard_node, "AnalogLeftKey");
403 port_config.keys.key_code[Config::ANALOG_RIGHT] = GetXMLElementAsInt(keyboard_node, "AnalogRightKey");
404 port_config.keys.key_code[Config::C_UP] = GetXMLElementAsInt(keyboard_node, "CUpKey");
405 port_config.keys.key_code[Config::C_DOWN] = GetXMLElementAsInt(keyboard_node, "CDownKey");
406 port_config.keys.key_code[Config::C_LEFT] = GetXMLElementAsInt(keyboard_node, "CLeftKey");
407 port_config.keys.key_code[Config::C_RIGHT] = GetXMLElementAsInt(keyboard_node, "CRightKey");
408 port_config.keys.key_code[Config::DPAD_UP] = GetXMLElementAsInt(keyboard_node, "DPadUpKey");
409 port_config.keys.key_code[Config::DPAD_DOWN] = GetXMLElementAsInt(keyboard_node, "DPadDownKey");
410 port_config.keys.key_code[Config::DPAD_LEFT] = GetXMLElementAsInt(keyboard_node, "DPadLeftKey");
411 port_config.keys.key_code[Config::DPAD_RIGHT] = GetXMLElementAsInt(keyboard_node, "DPadRightKey");
412 }
413
414 // Parse joypad configuration
415 rapidxml::xml_node<> *joypad_node = elem->first_node("JoypadController");
416 if (joypad_node) {
417 attr = joypad_node->first_attribute("enable");
418 port_config.pads.enable = (E_OK == _stricmp(attr->value(), "true")) ? true : false;
419 port_config.pads.key_code[Config::BUTTON_A] = GetXMLElementAsInt(joypad_node, "AKey");
420 port_config.pads.key_code[Config::BUTTON_B] = GetXMLElementAsInt(joypad_node, "BKey");
421 port_config.pads.key_code[Config::BUTTON_X] = GetXMLElementAsInt(joypad_node, "XKey");
422 port_config.pads.key_code[Config::BUTTON_Y] = GetXMLElementAsInt(joypad_node, "YKey");
423 port_config.pads.key_code[Config::TRIGGER_L] = GetXMLElementAsInt(joypad_node, "LKey");
424 port_config.pads.key_code[Config::TRIGGER_R] = GetXMLElementAsInt(joypad_node, "RKey");
425 port_config.pads.key_code[Config::BUTTON_Z] = GetXMLElementAsInt(joypad_node, "ZKey");
426 port_config.pads.key_code[Config::BUTTON_START] = GetXMLElementAsInt(joypad_node, "StartKey");
427 port_config.pads.key_code[Config::ANALOG_UP] = GetXMLElementAsInt(joypad_node, "AnalogUpKey");
428 port_config.pads.key_code[Config::ANALOG_DOWN] = GetXMLElementAsInt(joypad_node, "AnalogDownKey");
429 port_config.pads.key_code[Config::ANALOG_LEFT] = GetXMLElementAsInt(joypad_node, "AnalogLeftKey");
430 port_config.pads.key_code[Config::ANALOG_RIGHT] = GetXMLElementAsInt(joypad_node, "AnalogRightKey");
431 port_config.pads.key_code[Config::C_UP] = GetXMLElementAsInt(joypad_node, "CUpKey");
432 port_config.pads.key_code[Config::C_DOWN] = GetXMLElementAsInt(joypad_node, "CDownKey");
433 port_config.pads.key_code[Config::C_LEFT] = GetXMLElementAsInt(joypad_node, "CLeftKey");
434 port_config.pads.key_code[Config::C_RIGHT] = GetXMLElementAsInt(joypad_node, "CRightKey");
435 port_config.pads.key_code[Config::DPAD_UP] = GetXMLElementAsInt(joypad_node, "DPadUpKey");
436 port_config.pads.key_code[Config::DPAD_DOWN] = GetXMLElementAsInt(joypad_node, "DPadDownKey");
437 port_config.pads.key_code[Config::DPAD_LEFT] = GetXMLElementAsInt(joypad_node, "DPadLeftKey");
438 port_config.pads.key_code[Config::DPAD_RIGHT] = GetXMLElementAsInt(joypad_node, "DPadRightKey");
439 }
440 config.set_controller_ports(port, port_config);
441 }
442}
443
444/// Loads/parses an XML configuration file
445void LoadXMLConfig(Config& config, const char* filename) {
446 // Open the XML file
447 char full_filename[MAX_PATH];
448 strcpy(full_filename, config.program_dir());
449 strcat(full_filename, filename);
450 std::ifstream ifs(full_filename);
451
452 // Check that the file is valid
453 if (ifs.fail()) {
454 LOG_ERROR(TCONFIG, "XML configuration file %s failed to open!", filename);
455 return;
456 }
457 // Read and parse XML string
458 std::string xml_str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
459 rapidxml::xml_document<> doc;
460 doc.parse<0>(const_cast<char *>(xml_str.c_str()));
461
462 // Try to load a system configuration
463 rapidxml::xml_node<> *node = doc.first_node("SysConfig");
464
465 // Try to load a game configuation
466 if (!node) {
467 node = doc.first_node("GameConfig");
468 }
469 // Try to load a user configuation
470 if (!node) {
471 node = doc.first_node("UserConfig");
472 }
473 // Not proper XML format
474 if (!node) {
475 LOG_ERROR(TCONFIG, "XML configuration file incorrect format %s!", filename)
476 return;
477 }
478 // Parse all sub nodes into the config
479 ParseGeneralNode(node->first_node("General"), config);
480 ParseDebugNode(node->first_node("Debug"), config);
481 ParseBootNode(node->first_node("Boot"), config);
482 ParsePowerPCNode(node->first_node("PowerPC"), config);
483 ParseVideoNode(node->first_node("Video"), config);
484 ParseDevicesNode(node->first_node("Devices"), config);
485}
486
487} // namespace
diff --git a/src/common/src/xml.h b/src/common/src/xml.h
deleted file mode 100644
index 30447649a..000000000
--- a/src/common/src/xml.h
+++ /dev/null
@@ -1,41 +0,0 @@
1/**
2 * Copyright (C) 2005-2012 Gekko Emulator
3 *
4 * @file xml.h
5 * @author ShizZy <shizzy247@gmail.com>
6 * @date 2012-02-12
7 * @brief Used for parsing XML configurations
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#ifndef COMMON_XML_H_
26#define COMMON_XML_H_
27
28#include "common.h"
29
30namespace common {
31
32/**
33 * @brief Loads/parses an XML configuration file
34 * @param config Reference to configuration object to populate
35 * @param filename Filename of XMl file to load
36 */
37void LoadXMLConfig(Config& config, const char* filename);
38
39} // namespace
40
41#endif // COMMON_XML_H_