From 590f294d8e66ee534e6ecb475a62b61e5a0dea84 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Fri, 4 Apr 2014 22:47:10 -0400
Subject: [PATCH 01/28] renamed some functions

---
 src/core/src/mem_map_funcs.cpp | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/core/src/mem_map_funcs.cpp b/src/core/src/mem_map_funcs.cpp
index 18959dc70..446d3ac97 100644
--- a/src/core/src/mem_map_funcs.cpp
+++ b/src/core/src/mem_map_funcs.cpp
@@ -29,7 +29,7 @@
 namespace Memory {
 
 template <typename T>
-inline void ReadFromHardware(T &var, const u32 addr) {
+inline void _Read(T &var, const u32 addr) {
     // TODO: Figure out the fastest order of tests for both read and write (they are probably different).
     // TODO: Make sure this represents the mirrors in a correct way.
 
@@ -55,12 +55,12 @@ inline void ReadFromHardware(T &var, const u32 addr) {
 
     } else {
         _assert_msg_(MEMMAP, false, "unknown hardware read");
-        // WARN_LOG(MEMMAP, "ReadFromHardware: Invalid addr %08x PC %08x LR %08x", addr, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
+        // WARN_LOG(MEMMAP, "_Read: Invalid addr %08x PC %08x LR %08x", addr, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
     }
 }
 
 template <typename T>
-inline void WriteToHardware(u32 addr, const T data) {
+inline void _Write(u32 addr, const T data) {
     // ExeFS:/.code is loaded here:
     if ((addr & 0xFFF00000) == 0x00100000) {
         // TODO(ShizZy): This is dumb... handle correctly. From 3DBrew:
@@ -151,25 +151,25 @@ u8 *GetPointer(const u32 addr) {
 
 u8 Read8(const u32 addr) {
     u8 _var = 0;
-    ReadFromHardware<u8>(_var, addr);
+    _Read<u8>(_var, addr);
     return (u8)_var;
 }
 
 u16 Read16(const u32 addr) {
     u16_le _var = 0;
-    ReadFromHardware<u16_le>(_var, addr);
+    _Read<u16_le>(_var, addr);
     return (u16)_var;
 }
 
 u32 Read32(const u32 addr) {
     u32_le _var = 0;
-    ReadFromHardware<u32_le>(_var, addr);
+    _Read<u32_le>(_var, addr);
     return _var;
 }
 
 u64 Read64(const u32 addr) {
     u64_le _var = 0;
-    ReadFromHardware<u64_le>(_var, addr);
+    _Read<u64_le>(_var, addr);
     return _var;
 }
 
@@ -182,19 +182,19 @@ u32 Read16_ZX(const u32 addr) {
 }
 
 void Write8(const u32 addr, const u8 data) {
-    WriteToHardware<u8>(addr, data);
+    _Write<u8>(addr, data);
 }
 
 void Write16(const u32 addr, const u16 data) {
-    WriteToHardware<u16_le>(addr, data);
+    _Write<u16_le>(addr, data);
 }
 
 void Write32(const u32 addr, const u32 data) {
-    WriteToHardware<u32_le>(addr, data);
+    _Write<u32_le>(addr, data);
 }
 
 void Write64(const u32 addr, const u64 data) {
-    WriteToHardware<u64_le>(addr, data);
+    _Write<u64_le>(addr, data);
 }
 
 } // namespace

From 006bb834dfa48c111e7310b4490ef1eaa55dbe12 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Fri, 4 Apr 2014 22:53:34 -0400
Subject: [PATCH 02/28] added a HW option to logging

---
 src/common/src/log.h           |  2 +-
 src/common/src/log_manager.cpp | 94 +++++++++++++++++-----------------
 2 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/src/common/src/log.h b/src/common/src/log.h
index 9b2da5016..e1d82d387 100644
--- a/src/common/src/log.h
+++ b/src/common/src/log.h
@@ -59,7 +59,7 @@ enum LOG_TYPE {
     WII_IPC_SSL,
     WII_IPC_SD,
     WII_IPC_STM,
-    WII_IPC_WIIMOTE,
+    HW,
     TIME,
     NETPLAY,
 
diff --git a/src/common/src/log_manager.cpp b/src/common/src/log_manager.cpp
index 8c8828e8c..6e98cfcce 100644
--- a/src/common/src/log_manager.cpp
+++ b/src/common/src/log_manager.cpp
@@ -29,53 +29,53 @@ LogManager *LogManager::m_logManager = NULL;
 LogManager::LogManager()
 {
     // create log files
-    m_Log[LogTypes::MASTER_LOG]            = new LogContainer("*",                "Master Log");
-    m_Log[LogTypes::BOOT]                = new LogContainer("BOOT",            "Boot");
-    m_Log[LogTypes::COMMON]                = new LogContainer("COMMON",        "Common");
-    m_Log[LogTypes::DISCIO]                = new LogContainer("DIO",            "Disc IO");
-    m_Log[LogTypes::FILEMON]            = new LogContainer("FileMon",        "File Monitor");
-    m_Log[LogTypes::PAD]                = new LogContainer("PAD",            "Pad");
-    m_Log[LogTypes::PIXELENGINE]        = new LogContainer("PE",            "PixelEngine");
-    m_Log[LogTypes::COMMANDPROCESSOR]    = new LogContainer("CP",            "CommandProc");
-    m_Log[LogTypes::VIDEOINTERFACE]        = new LogContainer("VI",            "VideoInt");
-    m_Log[LogTypes::SERIALINTERFACE]    = new LogContainer("SI",            "SerialInt");
-    m_Log[LogTypes::PROCESSORINTERFACE]    = new LogContainer("PI",            "ProcessorInt");
-    m_Log[LogTypes::MEMMAP]                = new LogContainer("MI",            "MI & memmap");
-    m_Log[LogTypes::SP1]                = new LogContainer("SP1",            "Serial Port 1");
-    m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream",        "StreamingInt");
-    m_Log[LogTypes::DSPINTERFACE]        = new LogContainer("DSP",            "DSPInterface");
-    m_Log[LogTypes::DVDINTERFACE]        = new LogContainer("DVD",            "DVDInterface");
-    m_Log[LogTypes::GPFIFO]                = new LogContainer("GP",            "GPFifo");
-    m_Log[LogTypes::EXPANSIONINTERFACE]    = new LogContainer("EXI",            "ExpansionInt");
-    m_Log[LogTypes::GDB_STUB]            = new LogContainer("GDB_STUB",        "GDB Stub");
-    m_Log[LogTypes::AUDIO_INTERFACE]    = new LogContainer("AI",            "AudioInt");
-    m_Log[LogTypes::ARM11]                = new LogContainer("ARM11",            "ARM11");
-    m_Log[LogTypes::OSHLE]                = new LogContainer("HLE",            "HLE");
-    m_Log[LogTypes::DSPHLE]                = new LogContainer("DSPHLE",        "DSP HLE");
-    m_Log[LogTypes::DSPLLE]                = new LogContainer("DSPLLE",        "DSP LLE");
-    m_Log[LogTypes::DSP_MAIL]            = new LogContainer("DSPMails",        "DSP Mails");
-    m_Log[LogTypes::VIDEO]                = new LogContainer("Video",            "Video Backend");
-    m_Log[LogTypes::AUDIO]                = new LogContainer("Audio",            "Audio Emulator");
-    m_Log[LogTypes::DYNA_REC]            = new LogContainer("JIT",            "Dynamic Recompiler");
-    m_Log[LogTypes::CONSOLE]            = new LogContainer("CONSOLE",        "Dolphin Console");
-    m_Log[LogTypes::OSREPORT]            = new LogContainer("OSREPORT",        "OSReport");
-    m_Log[LogTypes::TIME]                = new LogContainer("Time",            "Core Timing");
-    m_Log[LogTypes::LOADER]                = new LogContainer("Loader",        "Loader");
-    m_Log[LogTypes::FILESYS]            = new LogContainer("FileSys",        "File System");
-    m_Log[LogTypes::WII_IPC_HID]        = new LogContainer("WII_IPC_HID",    "WII IPC HID");
-    m_Log[LogTypes::WII_IPC_HLE]        = new LogContainer("WII_IPC_HLE",    "WII IPC HLE");
-    m_Log[LogTypes::WII_IPC_DVD]        = new LogContainer("WII_IPC_DVD",    "WII IPC DVD");
-    m_Log[LogTypes::WII_IPC_ES]            = new LogContainer("WII_IPC_ES",    "WII IPC ES");
-    m_Log[LogTypes::WII_IPC_FILEIO]        = new LogContainer("WII_IPC_FILEIO","WII IPC FILEIO");
-    m_Log[LogTypes::WII_IPC_SD]            = new LogContainer("WII_IPC_SD",    "WII IPC SD");
-    m_Log[LogTypes::WII_IPC_STM]        = new LogContainer("WII_IPC_STM",    "WII IPC STM");
-    m_Log[LogTypes::WII_IPC_NET]        = new LogContainer("WII_IPC_NET",    "WII IPC NET");
-    m_Log[LogTypes::WII_IPC_WC24]        = new LogContainer("WII_IPC_WC24",    "WII IPC WC24");
-    m_Log[LogTypes::WII_IPC_SSL]        = new LogContainer("WII_IPC_SSL",    "WII IPC SSL");
-    m_Log[LogTypes::WII_IPC_WIIMOTE]    = new LogContainer("WII_IPC_WIIMOTE","WII IPC WIIMOTE");
-    m_Log[LogTypes::ACTIONREPLAY]        = new LogContainer("ActionReplay",    "ActionReplay");
-    m_Log[LogTypes::MEMCARD_MANAGER]    = new LogContainer("MemCard Manager", "MemCard Manager");
-    m_Log[LogTypes::NETPLAY]            = new LogContainer("NETPLAY",        "Netplay");
+    m_Log[LogTypes::MASTER_LOG]         = new LogContainer("*",                 "Master Log");
+    m_Log[LogTypes::BOOT]               = new LogContainer("BOOT",              "Boot");
+    m_Log[LogTypes::COMMON]             = new LogContainer("COMMON",            "Common");
+    m_Log[LogTypes::DISCIO]             = new LogContainer("DIO",               "Disc IO");
+    m_Log[LogTypes::FILEMON]            = new LogContainer("FileMon",           "File Monitor");
+    m_Log[LogTypes::PAD]                = new LogContainer("PAD",               "Pad");
+    m_Log[LogTypes::PIXELENGINE]        = new LogContainer("PE",                "PixelEngine");
+    m_Log[LogTypes::COMMANDPROCESSOR]   = new LogContainer("CP",                "CommandProc");
+    m_Log[LogTypes::VIDEOINTERFACE]     = new LogContainer("VI",                "VideoInt");
+    m_Log[LogTypes::SERIALINTERFACE]    = new LogContainer("SI",                "SerialInt");
+    m_Log[LogTypes::PROCESSORINTERFACE] = new LogContainer("PI",                "ProcessorInt");
+    m_Log[LogTypes::MEMMAP]             = new LogContainer("MI",                "MI & memmap");
+    m_Log[LogTypes::SP1]                = new LogContainer("SP1",               "Serial Port 1");
+    m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream",            "StreamingInt");
+    m_Log[LogTypes::DSPINTERFACE]       = new LogContainer("DSP",               "DSPInterface");
+    m_Log[LogTypes::DVDINTERFACE]       = new LogContainer("DVD",               "DVDInterface");
+    m_Log[LogTypes::GPFIFO]             = new LogContainer("GP",                "GPFifo");
+    m_Log[LogTypes::EXPANSIONINTERFACE] = new LogContainer("EXI",               "ExpansionInt");
+    m_Log[LogTypes::GDB_STUB]           = new LogContainer("GDB_STUB",          "GDB Stub");
+    m_Log[LogTypes::AUDIO_INTERFACE]    = new LogContainer("AI",                "AudioInt");
+    m_Log[LogTypes::ARM11]              = new LogContainer("ARM11",             "ARM11");
+    m_Log[LogTypes::OSHLE]              = new LogContainer("HLE",               "HLE");
+    m_Log[LogTypes::DSPHLE]             = new LogContainer("DSPHLE",            "DSP HLE");
+    m_Log[LogTypes::DSPLLE]             = new LogContainer("DSPLLE",            "DSP LLE");
+    m_Log[LogTypes::DSP_MAIL]           = new LogContainer("DSPMails",          "DSP Mails");
+    m_Log[LogTypes::VIDEO]              = new LogContainer("Video",             "Video Backend");
+    m_Log[LogTypes::AUDIO]              = new LogContainer("Audio",             "Audio Emulator");
+    m_Log[LogTypes::DYNA_REC]           = new LogContainer("JIT",               "JIT");
+    m_Log[LogTypes::CONSOLE]            = new LogContainer("CONSOLE",           "Dolphin Console");
+    m_Log[LogTypes::OSREPORT]           = new LogContainer("OSREPORT",          "OSReport");
+    m_Log[LogTypes::TIME]               = new LogContainer("Time",              "Core Timing");
+    m_Log[LogTypes::LOADER]             = new LogContainer("Loader",            "Loader");
+    m_Log[LogTypes::FILESYS]            = new LogContainer("FileSys",           "File System");
+    m_Log[LogTypes::WII_IPC_HID]        = new LogContainer("WII_IPC_HID",       "WII IPC HID");
+    m_Log[LogTypes::WII_IPC_HLE]        = new LogContainer("WII_IPC_HLE",       "WII IPC HLE");
+    m_Log[LogTypes::WII_IPC_DVD]        = new LogContainer("WII_IPC_DVD",       "WII IPC DVD");
+    m_Log[LogTypes::WII_IPC_ES]         = new LogContainer("WII_IPC_ES",        "WII IPC ES");
+    m_Log[LogTypes::WII_IPC_FILEIO]     = new LogContainer("WII_IPC_FILEIO",    "WII IPC FILEIO");
+    m_Log[LogTypes::WII_IPC_SD]         = new LogContainer("WII_IPC_SD",        "WII IPC SD");
+    m_Log[LogTypes::WII_IPC_STM]        = new LogContainer("WII_IPC_STM",       "WII IPC STM");
+    m_Log[LogTypes::WII_IPC_NET]        = new LogContainer("WII_IPC_NET",       "WII IPC NET");
+    m_Log[LogTypes::WII_IPC_WC24]       = new LogContainer("WII_IPC_WC24",      "WII IPC WC24");
+    m_Log[LogTypes::WII_IPC_SSL]        = new LogContainer("WII_IPC_SSL",       "WII IPC SSL");
+    m_Log[LogTypes::HW]                 = new LogContainer("HARDWARE",          "HARDWARE");
+    m_Log[LogTypes::ACTIONREPLAY]       = new LogContainer("ActionReplay",      "ActionReplay");
+    m_Log[LogTypes::MEMCARD_MANAGER]    = new LogContainer("MemCard Manager",   "MemCard Manager");
+    m_Log[LogTypes::NETPLAY]            = new LogContainer("NETPLAY",           "Netplay");
 
     m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str());
     m_consoleLog = new ConsoleListener();

From 670ac5643a7cda55b7c5d68c99495ade0d14e6e4 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Fri, 4 Apr 2014 23:02:59 -0400
Subject: [PATCH 03/28] added hw module to interface h/w register reads/writes

---
 src/core/core.vcxproj          |  2 +
 src/core/core.vcxproj.filters  |  9 +++++
 src/core/src/hw/hw.cpp         | 70 ++++++++++++++++++++++++++++++++++
 src/core/src/hw/hw.h           | 35 +++++++++++++++++
 src/core/src/mem_map_funcs.cpp |  5 +--
 5 files changed, 118 insertions(+), 3 deletions(-)
 create mode 100644 src/core/src/hw/hw.cpp
 create mode 100644 src/core/src/hw/hw.h

diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index bee9f3046..eb1272b23 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -152,6 +152,7 @@
     <ClCompile Include="src\elf\elf_reader.cpp" />
     <ClCompile Include="src\file_sys\directory_file_system.cpp" />
     <ClCompile Include="src\file_sys\meta_file_system.cpp" />
+    <ClCompile Include="src\hw\hardware.cpp" />
     <ClCompile Include="src\loader.cpp" />
     <ClCompile Include="src\mem_map.cpp" />
     <ClCompile Include="src\mem_map_funcs.cpp" />
@@ -180,6 +181,7 @@
     <ClInclude Include="src\file_sys\directory_file_system.h" />
     <ClInclude Include="src\file_sys\file_sys.h" />
     <ClInclude Include="src\file_sys\meta_file_system.h" />
+    <ClInclude Include="src\hw\hw.h" />
     <ClInclude Include="src\loader.h" />
     <ClInclude Include="src\mem_map.h" />
     <ClInclude Include="src\system.h" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index 45ddf8cf6..f3237ed05 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -46,6 +46,9 @@
     <ClCompile Include="src\arm\interpreter\arm_interpreter.cpp">
       <Filter>arm\interpreter</Filter>
     </ClCompile>
+    <ClCompile Include="src\hw\hardware.cpp">
+      <Filter>hw</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="arm">
@@ -69,6 +72,9 @@
     <Filter Include="arm\interpreter">
       <UniqueIdentifier>{cca8b763-8a80-4478-9bcc-3c979293c357}</UniqueIdentifier>
     </Filter>
+    <Filter Include="hw">
+      <UniqueIdentifier>{d1158fc4-3e0f-431f-9d3b-f30bbfeb4ad5}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\arm\disassembler\arm_disasm.h">
@@ -136,6 +142,9 @@
     <ClInclude Include="src\arm\interpreter\arm_interpreter.h">
       <Filter>arm\interpreter</Filter>
     </ClInclude>
+    <ClInclude Include="src\hw\hw.h">
+      <Filter>hw</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="CMakeLists.txt" />
diff --git a/src/core/src/hw/hw.cpp b/src/core/src/hw/hw.cpp
new file mode 100644
index 000000000..7250bc237
--- /dev/null
+++ b/src/core/src/hw/hw.cpp
@@ -0,0 +1,70 @@
+/**
+ * Copyright (C) 2013 Citrus Emulator
+ *
+ * @file    hw.cpp
+ * @author  bunnei
+ * @date    2014-04-04
+ * @brief   Hardware interface
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
+
+#include "log.h"
+#include "hw/hw.h"
+
+namespace HW {
+
+template <typename T>
+inline void Read(T &var, const u32 addr) {
+    // TODO: Figure out the fastest order of tests for both read and write (they are probably different).
+    // TODO: Make sure this represents the mirrors in a correct way.
+
+    // Could just do a base-relative read, too.... TODO
+
+    //if ((addr & 0x3E000000) == 0x08000000) {
+    //    var = *((const T*)&g_fcram[addr & MEM_FCRAM_MASK]);
+
+    //} else {
+    //    _assert_msg_(HW, false, "unknown hardware read");
+    //}
+}
+
+template <typename T>
+inline void Write(u32 addr, const T data) {
+    //// ExeFS:/.code is loaded here:
+    //if ((addr & 0xFFF00000) == 0x00100000) {
+    //    // TODO(ShizZy): This is dumb... handle correctly. From 3DBrew:
+    //    // http://3dbrew.org/wiki/Memory_layout#ARM11_User-land_memory_regions
+    //    // The ExeFS:/.code is loaded here, executables must be loaded to the 0x00100000 region when
+    //    // the exheader "special memory" flag is clear. The 0x03F00000-byte size restriction only 
+    //    // applies when this flag is clear. Executables are usually loaded to 0x14000000 when the 
+    //    // exheader "special memory" flag is set, however this address can be arbitrary.
+    //    *(T*)&g_fcram[addr & MEM_FCRAM_MASK] = data;
+
+    //// Error out...
+    //} else {
+    //    _assert_msg_(HW, false, "unknown hardware write");
+    //}
+}
+
+
+void Init() {
+}
+
+void Shutdown() {
+}
+
+}
\ No newline at end of file
diff --git a/src/core/src/hw/hw.h b/src/core/src/hw/hw.h
new file mode 100644
index 000000000..dacad4924
--- /dev/null
+++ b/src/core/src/hw/hw.h
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2013 Citrus Emulator
+ *
+ * @file    hw.h
+ * @author  bunnei
+ * @date    2014-04-04
+ * @brief   Hardware interface
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
+
+#include "common_types.h"
+
+namespace HW {
+
+template <typename T>
+inline void Read(T &var, const u32 addr);
+
+template <typename T>
+inline void Write(u32 addr, const T data);
+
+} // namespace
diff --git a/src/core/src/mem_map_funcs.cpp b/src/core/src/mem_map_funcs.cpp
index 446d3ac97..b000571e5 100644
--- a/src/core/src/mem_map_funcs.cpp
+++ b/src/core/src/mem_map_funcs.cpp
@@ -54,8 +54,7 @@ inline void _Read(T &var, const u32 addr) {
         var = *((const T*)&g_fcram[addr & MEM_FCRAM_MASK]);
 
     } else {
-        _assert_msg_(MEMMAP, false, "unknown hardware read");
-        // WARN_LOG(MEMMAP, "_Read: Invalid addr %08x PC %08x LR %08x", addr, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
+        _assert_msg_(MEMMAP, false, "unknown memory read");
     }
 }
 
@@ -104,7 +103,7 @@ inline void _Write(u32 addr, const T data) {
 
     // Error out...
     } else {
-        _assert_msg_(MEMMAP, false, "unknown hardware write");
+        _assert_msg_(MEMMAP, false, "unknown memory write");
     }
 }
 

From 31abc42d3dd8ea6ba23b14afa276bae684d694ef Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 00:01:07 -0400
Subject: [PATCH 04/28] added initial support for hw.cpp module

---
 src/core/core.vcxproj                         |  2 +-
 src/core/core.vcxproj.filters                 |  2 +-
 .../src/arm/interpreter/arm_interpreter.cpp   | 44 +++++++++----------
 src/core/src/core.h                           |  3 ++
 src/core/src/hw/hw.cpp                        | 42 +++++++-----------
 src/core/src/hw/hw.h                          |  6 +++
 src/core/src/mem_map_funcs.cpp                | 18 ++++++--
 src/core/src/system.cpp                       |  4 ++
 8 files changed, 69 insertions(+), 52 deletions(-)

diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index eb1272b23..60ce2427d 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -152,7 +152,7 @@
     <ClCompile Include="src\elf\elf_reader.cpp" />
     <ClCompile Include="src\file_sys\directory_file_system.cpp" />
     <ClCompile Include="src\file_sys\meta_file_system.cpp" />
-    <ClCompile Include="src\hw\hardware.cpp" />
+    <ClCompile Include="src\hw\hw.cpp" />
     <ClCompile Include="src\loader.cpp" />
     <ClCompile Include="src\mem_map.cpp" />
     <ClCompile Include="src\mem_map_funcs.cpp" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index f3237ed05..7b47f5cbf 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -46,7 +46,7 @@
     <ClCompile Include="src\arm\interpreter\arm_interpreter.cpp">
       <Filter>arm\interpreter</Filter>
     </ClCompile>
-    <ClCompile Include="src\hw\hardware.cpp">
+    <ClCompile Include="src\hw\hw.cpp">
       <Filter>hw</Filter>
     </ClCompile>
   </ItemGroup>
diff --git a/src/core/src/arm/interpreter/arm_interpreter.cpp b/src/core/src/arm/interpreter/arm_interpreter.cpp
index 930506963..a74aa26cc 100644
--- a/src/core/src/arm/interpreter/arm_interpreter.cpp
+++ b/src/core/src/arm/interpreter/arm_interpreter.cpp
@@ -1,26 +1,26 @@
 /**
-* Copyright (C) 2013 Citrus Emulator
-*
-* @file    arm_interpreter.h
-* @author  bunnei
-* @date    2014-04-04
-* @brief   ARM interface instance for SkyEye interprerer
-*
-* @section LICENSE
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License as
-* published by the Free Software Foundation; either version 2 of
-* the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details at
-* http://www.gnu.org/copyleft/gpl.html
-*
-* Official project repository can be found at:
-* http://code.google.com/p/gekko-gc-emu/
-*/
+ * Copyright (C) 2013 Citrus Emulator
+ *
+ * @file    arm_interpreter.h
+ * @author  bunnei
+ * @date    2014-04-04
+ * @brief   ARM interface instance for SkyEye interprerer
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
 
 #include "arm_interpreter.h"
 
diff --git a/src/core/src/core.h b/src/core/src/core.h
index f41daca6a..a7d96e4a4 100644
--- a/src/core/src/core.h
+++ b/src/core/src/core.h
@@ -55,6 +55,9 @@ void Stop();
 /// Initialize the core
 int Init();
 
+/// Shutdown the core
+void Shutdown();
+
 ARMul_State* GetState();
 
 } // namespace
diff --git a/src/core/src/hw/hw.cpp b/src/core/src/hw/hw.cpp
index 7250bc237..3e4f2c435 100644
--- a/src/core/src/hw/hw.cpp
+++ b/src/core/src/hw/hw.cpp
@@ -29,42 +29,34 @@ namespace HW {
 
 template <typename T>
 inline void Read(T &var, const u32 addr) {
-    // TODO: Figure out the fastest order of tests for both read and write (they are probably different).
-    // TODO: Make sure this represents the mirrors in a correct way.
-
-    // Could just do a base-relative read, too.... TODO
-
-    //if ((addr & 0x3E000000) == 0x08000000) {
-    //    var = *((const T*)&g_fcram[addr & MEM_FCRAM_MASK]);
-
-    //} else {
-    //    _assert_msg_(HW, false, "unknown hardware read");
-    //}
+    NOTICE_LOG(HW, "Hardware read from address %08X", addr);
 }
 
 template <typename T>
 inline void Write(u32 addr, const T data) {
-    //// ExeFS:/.code is loaded here:
-    //if ((addr & 0xFFF00000) == 0x00100000) {
-    //    // TODO(ShizZy): This is dumb... handle correctly. From 3DBrew:
-    //    // http://3dbrew.org/wiki/Memory_layout#ARM11_User-land_memory_regions
-    //    // The ExeFS:/.code is loaded here, executables must be loaded to the 0x00100000 region when
-    //    // the exheader "special memory" flag is clear. The 0x03F00000-byte size restriction only 
-    //    // applies when this flag is clear. Executables are usually loaded to 0x14000000 when the 
-    //    // exheader "special memory" flag is set, however this address can be arbitrary.
-    //    *(T*)&g_fcram[addr & MEM_FCRAM_MASK] = data;
-
-    //// Error out...
-    //} else {
-    //    _assert_msg_(HW, false, "unknown hardware write");
-    //}
+    NOTICE_LOG(HW, "Hardware write to address %08X", addr);
 }
 
+// Explicitly instantiate template functions because we aren't defining this in the header:
 
+template void Read<u64>(u64 &var, const u32 addr);
+template void Read<u32>(u32 &var, const u32 addr);
+template void Read<u16>(u16 &var, const u32 addr);
+template void Read<u8>(u8 &var, const u32 addr);
+
+template void Write<const u64>(u32 addr, const u64 data);
+template void Write<const u32>(u32 addr, const u32 data);
+template void Write<const u16>(u32 addr, const u16 data);
+template void Write<const u8>(u32 addr, const u8 data);
+
+/// Initialize hardware
 void Init() {
+    NOTICE_LOG(HW, "Hardware initialized OK");
 }
 
+/// Shutdown hardware
 void Shutdown() {
+    NOTICE_LOG(HW, "Hardware shutdown OK");
 }
 
 }
\ No newline at end of file
diff --git a/src/core/src/hw/hw.h b/src/core/src/hw/hw.h
index dacad4924..c69d6525f 100644
--- a/src/core/src/hw/hw.h
+++ b/src/core/src/hw/hw.h
@@ -32,4 +32,10 @@ inline void Read(T &var, const u32 addr);
 template <typename T>
 inline void Write(u32 addr, const T data);
 
+/// Initialize hardware
+void Init();
+
+/// Shutdown hardware
+void Shutdown();
+
 } // namespace
diff --git a/src/core/src/mem_map_funcs.cpp b/src/core/src/mem_map_funcs.cpp
index b000571e5..dc4c2381d 100644
--- a/src/core/src/mem_map_funcs.cpp
+++ b/src/core/src/mem_map_funcs.cpp
@@ -25,6 +25,7 @@
 #include "common.h"
 
 #include "mem_map.h"
+#include "hw/hw.h"
 
 namespace Memory {
 
@@ -32,10 +33,15 @@ template <typename T>
 inline void _Read(T &var, const u32 addr) {
     // TODO: Figure out the fastest order of tests for both read and write (they are probably different).
     // TODO: Make sure this represents the mirrors in a correct way.
-
     // Could just do a base-relative read, too.... TODO
 
-    if ((addr & 0x3E000000) == 0x08000000) {
+    // Hardware I/O register reads
+    // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space
+    if ((addr & 0xFF000000) == 0x10000000 || (addr & 0xFF000000) == 0x1E000000) {
+        HW::Read<T>(var, addr);
+
+    // FCRAM virtual address reads
+    } else if ((addr & 0x3E000000) == 0x08000000) {
         var = *((const T*)&g_fcram[addr & MEM_FCRAM_MASK]);
 
     // Scratchpad memory
@@ -60,8 +66,14 @@ inline void _Read(T &var, const u32 addr) {
 
 template <typename T>
 inline void _Write(u32 addr, const T data) {
+    
+    // Hardware I/O register writes
+    // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space
+    if ((addr & 0xFF000000) == 0x10000000 || (addr & 0xFF000000) == 0x1E000000) {
+        HW::Write<const T>(addr, data);
+    
     // ExeFS:/.code is loaded here:
-    if ((addr & 0xFFF00000) == 0x00100000) {
+    } else if ((addr & 0xFFF00000) == 0x00100000) {
         // TODO(ShizZy): This is dumb... handle correctly. From 3DBrew:
         // http://3dbrew.org/wiki/Memory_layout#ARM11_User-land_memory_regions
         // The ExeFS:/.code is loaded here, executables must be loaded to the 0x00100000 region when
diff --git a/src/core/src/system.cpp b/src/core/src/system.cpp
index 6a2c13c96..1477bab32 100644
--- a/src/core/src/system.cpp
+++ b/src/core/src/system.cpp
@@ -23,6 +23,7 @@
 */
 
 #include "core.h"
+#include "hw/hw.h"
 #include "core_timing.h"
 #include "mem_map.h"
 #include "system.h"
@@ -38,6 +39,7 @@ void UpdateState(State state) {
 void Init(EmuWindow* emu_window) {
 	Core::Init();
 	Memory::Init();
+    HW::Init();
 	CoreTiming::Init();
 }
 
@@ -49,6 +51,8 @@ void RunLoopUntil(u64 global_cycles) {
 }
 
 void Shutdown() {
+    Core::Shutdown();
+    HW::Shutdown();
 	g_ctr_file_system.Shutdown();
 }
 

From c1dfa75845b32d622f145879a9deed4c3e45b754 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 01:23:28 -0400
Subject: [PATCH 05/28] added a tick counter

---
 src/core/src/arm/arm_interface.h | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/core/src/arm/arm_interface.h b/src/core/src/arm/arm_interface.h
index 785234396..80518a779 100644
--- a/src/core/src/arm/arm_interface.h
+++ b/src/core/src/arm/arm_interface.h
@@ -35,13 +35,21 @@ public:
     ~ARM_Interface() {
     }
 
-    virtual void ExecuteInstruction() = 0;
+    void Step() {
+        ExecuteInstruction();
+        ticks_++;
+    }
     
     virtual void SetPC(u32 pc) = 0;
-
     virtual u32 PC() = 0;
-
     virtual u32 Reg(int index) = 0;
+    virtual u32 CPSR() = 0;  
 
-    virtual u32 CPSR() = 0;
+    u64 ticks() { return ticks_; }
+
+private:
+    
+    virtual void ExecuteInstruction() = 0;
+
+    u64 ticks_;
 };

From 9c2355ba4f37585cd0054b3f05251a814ccbc0eb Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 01:23:51 -0400
Subject: [PATCH 06/28] added a module for interfacing to hardware LCD

---
 src/core/src/hw/hw_lcd.cpp | 65 ++++++++++++++++++++++++++++++++++++++
 src/core/src/hw/hw_lcd.h   | 64 +++++++++++++++++++++++++++++++++++++
 2 files changed, 129 insertions(+)
 create mode 100644 src/core/src/hw/hw_lcd.cpp
 create mode 100644 src/core/src/hw/hw_lcd.h

diff --git a/src/core/src/hw/hw_lcd.cpp b/src/core/src/hw/hw_lcd.cpp
new file mode 100644
index 000000000..19e3b4ab4
--- /dev/null
+++ b/src/core/src/hw/hw_lcd.cpp
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2013 Citrus Emulator
+ *
+ * @file    hw_lcd.cpp
+ * @author  bunnei
+ * @date    2014-04-05
+ * @brief   Hardware LCD interface
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
+
+#include "log.h"
+#include "core.h"
+#include "hw_lcd.h"
+
+namespace LCD {
+
+static const u32 kFrameTicks = 268123480 / 30; // 268MHz / 30 frames per second
+
+u64 g_last_ticks = 0; ///< Last CPU ticks
+
+template <typename T>
+inline void Read(T &var, const u32 addr) {
+}
+
+template <typename T>
+inline void Write(u32 addr, const T data) {
+}
+
+/// Update hardware
+void Update() {
+    u64 current_ticks = Core::g_app_core->ticks();
+
+    if ((current_ticks - g_last_ticks) >= kFrameTicks) {
+        g_last_ticks = current_ticks;
+        NOTICE_LOG(LCD, "Update frame");
+    }
+}
+
+/// Initialize hardware
+void Init() {
+    g_last_ticks = Core::g_app_core->ticks();
+
+    NOTICE_LOG(LCD, "LCD initialized OK");
+}
+
+/// Shutdown hardware
+void Shutdown() {
+    NOTICE_LOG(LCD, "LCD shutdown OK");
+}
+
+} // namespace
diff --git a/src/core/src/hw/hw_lcd.h b/src/core/src/hw/hw_lcd.h
new file mode 100644
index 000000000..fa19b1cd4
--- /dev/null
+++ b/src/core/src/hw/hw_lcd.h
@@ -0,0 +1,64 @@
+/**
+ * Copyright (C) 2013 Citrus Emulator
+ *
+ * @file    hw_lcd.h
+ * @author  bunnei
+ * @date    2014-04-05
+ * @brief   Hardware LCD interface
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
+
+#pragma once
+
+#include "common_types.h"
+
+namespace LCD {
+
+enum {
+    TOP_ASPECT_X        = 0x5,
+    TOP_ASPECT_Y        = 0x3,
+    
+    TOP_HEIGHT          = 240,
+    TOP_WIDTH           = 400,
+    BOTTOM_WIDTH        = 320,
+
+    FRAMEBUFFER_SEL     = 0x20184E59,
+    TOP_LEFT_FRAME1     = 0x20184E60,
+    TOP_LEFT_FRAME2     = 0x201CB370,
+    TOP_RIGHT_FRAME1    = 0x20282160,
+    TOP_RIGHT_FRAME2    = 0x202C8670,
+    SUB_FRAME1          = 0x202118E0,
+    SUB_FRAME2          = 0x20249CF0,
+};
+
+template <typename T>
+inline void Read(T &var, const u32 addr);
+
+template <typename T>
+inline void Write(u32 addr, const T data);
+
+/// Update hardware
+void Update();
+
+/// Initialize hardware
+void Init();
+
+/// Shutdown hardware
+void Shutdown();
+
+
+} // namespace

From 6433f4d6f9c1fd0af4eb5689fe1e363584bb9d38 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 01:24:14 -0400
Subject: [PATCH 07/28] added an "Update" method to update all hardware

---
 src/core/src/hw/hw.cpp | 7 +++++++
 src/core/src/hw/hw.h   | 3 +++
 2 files changed, 10 insertions(+)

diff --git a/src/core/src/hw/hw.cpp b/src/core/src/hw/hw.cpp
index 3e4f2c435..50001c87a 100644
--- a/src/core/src/hw/hw.cpp
+++ b/src/core/src/hw/hw.cpp
@@ -24,6 +24,7 @@
 
 #include "log.h"
 #include "hw/hw.h"
+#include "hw/hw_lcd.h"
 
 namespace HW {
 
@@ -49,8 +50,14 @@ template void Write<const u32>(u32 addr, const u32 data);
 template void Write<const u16>(u32 addr, const u16 data);
 template void Write<const u8>(u32 addr, const u8 data);
 
+/// Update hardware
+void Update() {
+    LCD::Update();
+}
+
 /// Initialize hardware
 void Init() {
+    LCD::Init();
     NOTICE_LOG(HW, "Hardware initialized OK");
 }
 
diff --git a/src/core/src/hw/hw.h b/src/core/src/hw/hw.h
index c69d6525f..245822423 100644
--- a/src/core/src/hw/hw.h
+++ b/src/core/src/hw/hw.h
@@ -32,6 +32,9 @@ inline void Read(T &var, const u32 addr);
 template <typename T>
 inline void Write(u32 addr, const T data);
 
+/// Update hardware
+void Update();
+
 /// Initialize hardware
 void Init();
 

From c874c1d06cf94f3b02e60d1ba74b2bad3206b211 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 01:24:54 -0400
Subject: [PATCH 08/28] add hw_lcd.* to VS project files

---
 src/core/core.vcxproj         | 2 ++
 src/core/core.vcxproj.filters | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index 60ce2427d..2edb51214 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -153,6 +153,7 @@
     <ClCompile Include="src\file_sys\directory_file_system.cpp" />
     <ClCompile Include="src\file_sys\meta_file_system.cpp" />
     <ClCompile Include="src\hw\hw.cpp" />
+    <ClCompile Include="src\hw\hw_lcd.cpp" />
     <ClCompile Include="src\loader.cpp" />
     <ClCompile Include="src\mem_map.cpp" />
     <ClCompile Include="src\mem_map_funcs.cpp" />
@@ -182,6 +183,7 @@
     <ClInclude Include="src\file_sys\file_sys.h" />
     <ClInclude Include="src\file_sys\meta_file_system.h" />
     <ClInclude Include="src\hw\hw.h" />
+    <ClInclude Include="src\hw\hw_lcd.h" />
     <ClInclude Include="src\loader.h" />
     <ClInclude Include="src\mem_map.h" />
     <ClInclude Include="src\system.h" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index 7b47f5cbf..0cd208dd6 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -49,6 +49,9 @@
     <ClCompile Include="src\hw\hw.cpp">
       <Filter>hw</Filter>
     </ClCompile>
+    <ClCompile Include="src\hw\hw_lcd.cpp">
+      <Filter>hw</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="arm">
@@ -145,6 +148,9 @@
     <ClInclude Include="src\hw\hw.h">
       <Filter>hw</Filter>
     </ClInclude>
+    <ClInclude Include="src\hw\hw_lcd.h">
+      <Filter>hw</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="CMakeLists.txt" />

From 7509a9b21f9736f19d79ac6238bbc57bb10349c6 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 01:25:13 -0400
Subject: [PATCH 09/28] added LCD logger

---
 src/common/src/log.h           | 2 +-
 src/common/src/log_manager.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/common/src/log.h b/src/common/src/log.h
index e1d82d387..5270ff2d9 100644
--- a/src/common/src/log.h
+++ b/src/common/src/log.h
@@ -58,7 +58,7 @@ enum LOG_TYPE {
     WII_IPC_WC24,
     WII_IPC_SSL,
     WII_IPC_SD,
-    WII_IPC_STM,
+    LCD,
     HW,
     TIME,
     NETPLAY,
diff --git a/src/common/src/log_manager.cpp b/src/common/src/log_manager.cpp
index 6e98cfcce..e37278db7 100644
--- a/src/common/src/log_manager.cpp
+++ b/src/common/src/log_manager.cpp
@@ -68,7 +68,7 @@ LogManager::LogManager()
     m_Log[LogTypes::WII_IPC_ES]         = new LogContainer("WII_IPC_ES",        "WII IPC ES");
     m_Log[LogTypes::WII_IPC_FILEIO]     = new LogContainer("WII_IPC_FILEIO",    "WII IPC FILEIO");
     m_Log[LogTypes::WII_IPC_SD]         = new LogContainer("WII_IPC_SD",        "WII IPC SD");
-    m_Log[LogTypes::WII_IPC_STM]        = new LogContainer("WII_IPC_STM",       "WII IPC STM");
+    m_Log[LogTypes::LCD]                = new LogContainer("LCD",               "LCD");
     m_Log[LogTypes::WII_IPC_NET]        = new LogContainer("WII_IPC_NET",       "WII IPC NET");
     m_Log[LogTypes::WII_IPC_WC24]       = new LogContainer("WII_IPC_WC24",      "WII IPC WC24");
     m_Log[LogTypes::WII_IPC_SSL]        = new LogContainer("WII_IPC_SSL",       "WII IPC SSL");

From 925a894c1b04935772bc3eea904e81c8bef7df13 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 15:22:11 -0400
Subject: [PATCH 10/28] added DISALLOW_COPY_AND_ASSIGN macro

---
 src/common/src/common.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/common/src/common.h b/src/common/src/common.h
index 1ca34e467..3b71d9b3d 100644
--- a/src/common/src/common.h
+++ b/src/common/src/common.h
@@ -163,4 +163,9 @@ enum EMUSTATE_CHANGE
     EMUSTATE_CHANGE_STOP
 };
 
+// This should be used in the private: declarations for a class
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+    TypeName(const TypeName&);               \
+    void operator=(const TypeName&)
+
 #endif // _COMMON_H_

From 02bcb4cfad8ab76b57b6be8a4591bc6f29246909 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 15:22:36 -0400
Subject: [PATCH 11/28] Updated common_types.h to use Gekko's version w/ Rect
 and some useful unions

---
 src/common/src/common_types.h | 132 ++++++++++++++++++++++++++--------
 1 file changed, 102 insertions(+), 30 deletions(-)

diff --git a/src/common/src/common_types.h b/src/common/src/common_types.h
index cbe556c7e..68f237385 100644
--- a/src/common/src/common_types.h
+++ b/src/common/src/common_types.h
@@ -1,50 +1,122 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.
+/**
+ * Copyright (C) 2005-2012 Gekko Emulator
+ *
+ * @file    common_types.h
+ * @author  ShizZy <shizzy247@gmail.com>
+ * @date    2012-02-11
+ * @brief   Common types used throughout the project
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
 
-
-// This header contains type definitions that are shared between the Dolphin core and
-// other parts of the code. Any definitions that are only used by the core should be
-// placed in "common.h" instead.
-
-#ifndef _COMMONTYPES_H_
-#define _COMMONTYPES_H_
+#pragma once 
 
 #ifdef _WIN32
 
 #include <tchar.h>
 
-typedef unsigned __int8 u8;
-typedef unsigned __int16 u16;
-typedef unsigned __int32 u32;
-typedef unsigned __int64 u64;
+typedef unsigned __int8     u8;     ///< 8-bit unsigned byte
+typedef unsigned __int16    u16;    ///< 16-bit unsigned short
+typedef unsigned __int32    u32;    ///< 32-bit unsigned word
+typedef unsigned __int64    u64;    ///< 64-bit unsigned int
 
-typedef signed __int8 s8;
-typedef signed __int16 s16;
-typedef signed __int32 s32;
-typedef signed __int64 s64;
+typedef signed __int8       s8;     ///< 8-bit signed byte
+typedef signed __int16      s16;    ///< 16-bit signed short
+typedef signed __int32      s32;    ///< 32-bit signed word
+typedef signed __int64      s64;    ///< 64-bit signed int
 
 #else
 
-#ifndef GEKKO
+typedef unsigned char       u8;     ///< 8-bit unsigned byte
+typedef unsigned short      u16;    ///< 16-bit unsigned short
+typedef unsigned int        u32;    ///< 32-bit unsigned word
+typedef unsigned long long  u64;    ///< 64-bit unsigned int
 
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef unsigned long long u64;
+typedef signed char         s8;     ///< 8-bit signed byte
+typedef signed short        s16;    ///< 16-bit signed short
+typedef signed int          s32;    ///< 32-bit signed word
+typedef signed long long    s64;    ///< 64-bit signed int
 
-typedef signed char s8;
-typedef signed short s16;
-typedef signed int s32;
-typedef signed long long s64;
-
-#endif
 // For using windows lock code
 #define TCHAR char
 #define LONG int
 
 #endif // _WIN32
 
+typedef float   f32;    ///< 32-bit floating point
+typedef double  f64;    ///< 64-bit floating point
+
 #include "swap.h"
 
-#endif // _COMMONTYPES_H_
+/// Union for fast 16-bit type casting
+union t16 {
+	u8	_u8[2];             ///< 8-bit unsigned char(s)
+	u16 _u16;               ///< 16-bit unsigned shorts(s)
+};
+
+/// Union for fast 32-bit type casting
+union t32 {
+    f32 _f32;               ///< 32-bit floating point(s)
+    u32 _u32;               ///< 32-bit unsigned int(s)
+    s32 _s32;               ///< 32-bit signed int(s)
+    u16 _u16[2];            ///< 16-bit unsigned shorts(s)
+    u8  _u8[4];             ///< 8-bit unsigned char(s)
+};
+
+/// Union for fast 64-bit type casting
+union t64 {
+    f64 _f64;               ///< 64-bit floating point
+    u64 _u64;               ///< 64-bit unsigned long
+    f32 _f32[2];            ///< 32-bit floating point(s)
+    u32 _u32[2];            ///< 32-bit unsigned int(s)
+    s32 _s32[2];            ///< 32-bit signed int(s)
+    u16 _u16[4];            ///< 16-bit unsigned shorts(s)
+    u8  _u8[8];             ///< 8-bit unsigned char(s)
+};
+
+/// Union for fast 128-bit type casting
+union t128 {
+    struct
+    {
+        t64 ps0;            ///< 64-bit paired single 0
+        t64 ps1;            ///< 64-bit paired single 1
+    };
+    __m128  a;              ///< 128-bit floating point (__m128 maps to the XMM[0-7] registers)
+};
+
+/// Rectangle data structure
+class Rect {
+public:
+    Rect(int x0=0, int y0=0, int x1=0, int y1=0) {
+        x0_ = x0;
+        y0_ = y0;
+        x1_ = x1;
+        y1_ = y1;
+    }
+    ~Rect() { }
+
+    int x0_;    ///< Rect top left X-coordinate
+    int y0_;    ///< Rect top left Y-coordinate
+    int x1_;    ///< Rect bottom left X-coordinate
+    int y1_;    ///< Rect bottom right Y-coordinate
+
+    inline u32 width() const { return abs(x1_ - x0_); }
+    inline u32 height() const { return abs(y1_ - y0_); }
+
+    inline bool operator == (const Rect& val) const {
+        return (x0_ == val.x0_ && y0_ == val.y0_ && x1_ == val.x1_ && y1_ == val.y1_);
+    }
+};

From ed15feebf1cc60356e374e3492e6086066a7d09e Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 15:23:59 -0400
Subject: [PATCH 12/28] changed hw_lcd to use ARM core correct tick counter
 instead of [what was actually] just an instruction count. this seems to fix
 timing issues with the 3DS_Homebrew_Pong3Dv2 demo.

---
 src/core/src/arm/arm_interface.h              | 43 ++++++++++++++++---
 .../src/arm/interpreter/arm_interpreter.h     |  7 +++
 src/core/src/hw/hw_lcd.cpp                    |  6 +--
 3 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/src/core/src/arm/arm_interface.h b/src/core/src/arm/arm_interface.h
index 80518a779..daf35b51d 100644
--- a/src/core/src/arm/arm_interface.h
+++ b/src/core/src/arm/arm_interface.h
@@ -24,32 +24,65 @@
 
 #pragma once
 
+#include "common.h"
 #include "common_types.h"
 
 /// Generic ARM11 CPU interface
 class ARM_Interface {
 public:
     ARM_Interface() {
+        num_instructions_ = 0;
     }
 
     ~ARM_Interface() {
     }
 
+    /// Step CPU by one instruction
     void Step() {
         ExecuteInstruction();
-        ticks_++;
+        num_instructions_++;
     }
-    
-    virtual void SetPC(u32 pc) = 0;
+ 
+    /**
+     * Set the Program Counter to an address
+     * @param addr Address to set PC to
+     */
+    virtual void SetPC(u32 addr) = 0;
+
+    /*
+     * Get the current Program Counter
+     * @return Returns current PC
+     */
     virtual u32 PC() = 0;
+
+    /**
+     * Get an ARM register
+     * @param index Register index (0-15)
+     * @return Returns the value in the register
+     */
     virtual u32 Reg(int index) = 0;
+
+    /**
+     * Get the current CPSR register
+     * @return Returns the value of the CPSR register
+     */
     virtual u32 CPSR() = 0;  
 
-    u64 ticks() { return ticks_; }
+    /**
+     * Returns the number of clock ticks since the last rese
+     * @return Returns number of clock ticks
+     */
+    virtual u64 GetTicks() = 0;
+
+    /// Getter for num_instructions_
+    u64 num_instructions() { return num_instructions_; }
 
 private:
     
+    /// Execture next instruction
     virtual void ExecuteInstruction() = 0;
 
-    u64 ticks_;
+    u64 num_instructions_;  ///< Number of instructions executed
+
+    DISALLOW_COPY_AND_ASSIGN(ARM_Interface);
 };
diff --git a/src/core/src/arm/interpreter/arm_interpreter.h b/src/core/src/arm/interpreter/arm_interpreter.h
index 89f871fa9..074149f1b 100644
--- a/src/core/src/arm/interpreter/arm_interpreter.h
+++ b/src/core/src/arm/interpreter/arm_interpreter.h
@@ -24,6 +24,7 @@
 
 #pragma once
 
+#include "common.h"
 #include "common_types.h"
 #include "arm/arm_interface.h"
 
@@ -45,6 +46,12 @@ public:
 
     u32 CPSR();
 
+    u64 GetTicks() {
+        return ARMul_Time(state);
+    }
+
 private:
     ARMul_State* state;
+
+    DISALLOW_COPY_AND_ASSIGN(ARM_Interpreter);
 };
diff --git a/src/core/src/hw/hw_lcd.cpp b/src/core/src/hw/hw_lcd.cpp
index 19e3b4ab4..7e3728346 100644
--- a/src/core/src/hw/hw_lcd.cpp
+++ b/src/core/src/hw/hw_lcd.cpp
@@ -28,7 +28,7 @@
 
 namespace LCD {
 
-static const u32 kFrameTicks = 268123480 / 30; // 268MHz / 30 frames per second
+static const u32 kFrameTicks = 268123480 / 60;  ///< 268MHz / 60 frames per second
 
 u64 g_last_ticks = 0; ///< Last CPU ticks
 
@@ -42,7 +42,7 @@ inline void Write(u32 addr, const T data) {
 
 /// Update hardware
 void Update() {
-    u64 current_ticks = Core::g_app_core->ticks();
+    u64 current_ticks = Core::g_app_core->GetTicks();
 
     if ((current_ticks - g_last_ticks) >= kFrameTicks) {
         g_last_ticks = current_ticks;
@@ -52,7 +52,7 @@ void Update() {
 
 /// Initialize hardware
 void Init() {
-    g_last_ticks = Core::g_app_core->ticks();
+    g_last_ticks = Core::g_app_core->GetTicks();
 
     NOTICE_LOG(LCD, "LCD initialized OK");
 }

From e022717477184df1268901ee097ed0b358f5a38a Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 15:26:03 -0400
Subject: [PATCH 13/28] added g_app_core->Step and HW::Update to
 Core::SingleStep to be consistent with other changes made

---
 src/core/src/core.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/core/src/core.cpp b/src/core/src/core.cpp
index 592805134..4261ff3ef 100644
--- a/src/core/src/core.cpp
+++ b/src/core/src/core.cpp
@@ -25,6 +25,7 @@
 #include "log.h"
 #include "core.h"
 #include "mem_map.h"
+#include "hw/hw.h"
 #include "arm/disassembler/arm_disasm.h"
 #include "arm/interpreter/arm_interpreter.h"
 
@@ -41,7 +42,8 @@ void RunLoop() {
 
 /// Step the CPU one instruction
 void SingleStep() {
-    g_app_core->ExecuteInstruction();
+    g_app_core->Step();
+    HW::Update();
 }
 
 /// Halt the core
@@ -69,6 +71,8 @@ void Shutdown() {
     delete g_disasm;
     delete g_app_core;
     delete g_sys_core;
+
+    NOTICE_LOG(MASTER_LOG, "Core shutdown OK");
 }
 
 } // namespace

From 89fd6eb23742e00630cad7dfe73c241345c04ce0 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 15:47:55 -0400
Subject: [PATCH 14/28] added missing includes to common_types.h

---
 src/common/src/common_types.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/common/src/common_types.h b/src/common/src/common_types.h
index 68f237385..af1cd0e21 100644
--- a/src/common/src/common_types.h
+++ b/src/common/src/common_types.h
@@ -24,6 +24,9 @@
 
 #pragma once 
 
+#include <math.h>
+#include <xmmintrin.h> // data_types__m128.cpp
+
 #ifdef _WIN32
 
 #include <tchar.h>

From 23506defe3f2e9e1eee2968ababc9fb7fca918ae Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 5 Apr 2014 16:04:25 -0400
Subject: [PATCH 15/28] added video_core project to solution

---
 citra.sln                                 |  12 +-
 src/video_core/CMakeLists.txt             |  19 ++++
 src/video_core/src/renderer_base.h        | 116 +++++++++++++++++++
 src/video_core/src/utils.cpp              |  66 +++++++++++
 src/video_core/src/utils.h                |  83 ++++++++++++++
 src/video_core/src/video_core.cpp         |  91 +++++++++++++++
 src/video_core/src/video_core.h           |  48 ++++++++
 src/video_core/video_core.vcxproj         | 129 ++++++++++++++++++++++
 src/video_core/video_core.vcxproj.filters |  15 +++
 9 files changed, 578 insertions(+), 1 deletion(-)
 create mode 100644 src/video_core/CMakeLists.txt
 create mode 100644 src/video_core/src/renderer_base.h
 create mode 100644 src/video_core/src/utils.cpp
 create mode 100644 src/video_core/src/utils.h
 create mode 100644 src/video_core/src/video_core.cpp
 create mode 100644 src/video_core/src/video_core.h
 create mode 100644 src/video_core/video_core.vcxproj
 create mode 100644 src/video_core/video_core.vcxproj.filters

diff --git a/citra.sln b/citra.sln
index ebba4c2f0..399e5cb9b 100644
--- a/citra.sln
+++ b/citra.sln
@@ -1,5 +1,5 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Express 2013 for Windows Desktop
+# Visual Studio 2013
 VisualStudioVersion = 12.0.21005.1
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "src\common\common.vcxproj", "{DFE335FC-755D-4BAA-8452-94434F8A1EDB}"
@@ -21,6 +21,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scm_rev_gen", "src\common\s
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "citra_qt", "src\citra_qt\citra_qt.vcxproj", "{A587F714-490F-407A-9E36-7AB7FA0D7BAB}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "video_core", "src\video_core\video_core.vcxproj", "{6678D1A3-33A6-48A9-878B-48E5D2903D27}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -69,6 +71,14 @@ Global
 		{A587F714-490F-407A-9E36-7AB7FA0D7BAB}.Release|Win32.Build.0 = Release|Win32
 		{A587F714-490F-407A-9E36-7AB7FA0D7BAB}.Release|x64.ActiveCfg = Release|x64
 		{A587F714-490F-407A-9E36-7AB7FA0D7BAB}.Release|x64.Build.0 = Release|x64
+		{6678D1A3-33A6-48A9-878B-48E5D2903D27}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6678D1A3-33A6-48A9-878B-48E5D2903D27}.Debug|Win32.Build.0 = Debug|Win32
+		{6678D1A3-33A6-48A9-878B-48E5D2903D27}.Debug|x64.ActiveCfg = Debug|x64
+		{6678D1A3-33A6-48A9-878B-48E5D2903D27}.Debug|x64.Build.0 = Debug|x64
+		{6678D1A3-33A6-48A9-878B-48E5D2903D27}.Release|Win32.ActiveCfg = Release|Win32
+		{6678D1A3-33A6-48A9-878B-48E5D2903D27}.Release|Win32.Build.0 = Release|Win32
+		{6678D1A3-33A6-48A9-878B-48E5D2903D27}.Release|x64.ActiveCfg = Release|x64
+		{6678D1A3-33A6-48A9-878B-48E5D2903D27}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
new file mode 100644
index 000000000..3f486b8fe
--- /dev/null
+++ b/src/video_core/CMakeLists.txt
@@ -0,0 +1,19 @@
+set(SRCS
+            src/bp_mem.cpp
+            src/cp_mem.cpp
+            src/xf_mem.cpp
+            src/fifo.cpp
+            src/fifo_player.cpp
+            src/vertex_loader.cpp
+            src/vertex_manager.cpp
+            src/video_core.cpp
+            src/shader_manager.cpp
+            src/texture_decoder.cpp
+            src/texture_manager.cpp
+            src/utils.cpp
+            src/renderer_gl3/renderer_gl3.cpp
+            src/renderer_gl3/shader_interface.cpp
+            src/renderer_gl3/texture_interface.cpp
+            src/renderer_gl3/uniform_manager.cpp)
+
+add_library(video_core STATIC ${SRCS})
diff --git a/src/video_core/src/renderer_base.h b/src/video_core/src/renderer_base.h
new file mode 100644
index 000000000..9cd02e0b4
--- /dev/null
+++ b/src/video_core/src/renderer_base.h
@@ -0,0 +1,116 @@
+/**
+ * Copyright (C) 2014 Citra Emulator
+ *
+ * @file    renderer_base.h
+ * @author  bunnei
+ * @date    2014-04-05
+ * @brief   Renderer base class for new video core
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
+
+#pragma once
+
+#include "common.h"
+#include "hash.h"
+
+class RendererBase {
+public:
+
+    /// Used to reference a framebuffer
+    enum kFramebuffer {
+        kFramebuffer_VirtualXFB = 0,
+        kFramebuffer_EFB,
+        kFramebuffer_Texture
+    };
+
+    /// Used for referencing the render modes
+    enum kRenderMode {
+        kRenderMode_None = 0,
+        kRenderMode_Multipass = 1,
+        kRenderMode_ZComp = 2,
+        kRenderMode_UseDstAlpha = 4
+    };
+
+    RendererBase() : current_fps_(0), current_frame_(0) {
+    }
+
+    ~RendererBase() {
+    }
+
+    /** 
+     * Blits the EFB to the external framebuffer (XFB)
+     * @param src_rect Source rectangle in EFB to copy
+     * @param dst_rect Destination rectangle in EFB to copy to
+     * @param dest_height Destination height in pixels
+     */
+    virtual void CopyToXFB(const Rect& src_rect, const Rect& dst_rect) = 0;
+
+    /**
+     * Clear the screen
+     * @param rect Screen rectangle to clear
+     * @param enable_color Enable color clearing
+     * @param enable_alpha Enable alpha clearing
+     * @param enable_z Enable depth clearing
+     * @param color Clear color
+     * @param z Clear depth
+     */
+    virtual void Clear(const Rect& rect, bool enable_color, bool enable_alpha, bool enable_z, 
+        u32 color, u32 z) = 0;
+
+    /**
+     * Set a specific render mode
+     * @param flag Render flags mode to enable
+     */
+    virtual void SetMode(kRenderMode flags) = 0;
+
+    /// Reset the full renderer API to the NULL state
+    virtual void ResetRenderState() = 0;
+
+    /// Restore the full renderer API state - As the game set it
+    virtual void RestoreRenderState() = 0;
+
+    /** 
+     * Set the emulator window to use for renderer
+     * @param window EmuWindow handle to emulator window to use for rendering
+     */
+    virtual void SetWindow(EmuWindow* window) = 0;
+
+    /// Initialize the renderer
+    virtual void Init() = 0;
+
+    /// Shutdown the renderer
+    virtual void ShutDown() = 0;
+
+    /// Converts EFB rectangle coordinates to renderer rectangle coordinates
+    //static Rect EFBToRendererRect(const Rect& rect) {
+	   // return Rect(rect.x0_, kGCEFBHeight - rect.y0_, rect.x1_, kGCEFBHeight - rect.y1_);
+    //}
+
+    // Getter/setter functions:
+    // ------------------------
+
+    f32 current_fps() const { return current_fps_; }
+
+    int current_frame() const { return current_frame_; }
+
+protected:
+    f32 current_fps_;                       ///< Current framerate, should be set by the renderer
+    int current_frame_;                     ///< Current frame, should be set by the renderer
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(RendererBase);
+};
diff --git a/src/video_core/src/utils.cpp b/src/video_core/src/utils.cpp
new file mode 100644
index 000000000..a5e702f67
--- /dev/null
+++ b/src/video_core/src/utils.cpp
@@ -0,0 +1,66 @@
+/**
+ * Copyright (C) 2005-2012 Gekko Emulator
+ *
+ * @file    utils.cpp
+ * @author  ShizZy <shizzy247@gmail.com>
+ * @date    2012-12-28
+ * @brief   Utility functions (in general, not related to emulation) useful for video core
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "utils.h"
+
+namespace VideoCore {
+
+/**
+ * Dumps a texture to TGA
+ * @param filename String filename to dump texture to
+ * @param width Width of texture in pixels
+ * @param height Height of texture in pixels
+ * @param raw_data Raw RGBA8 texture data to dump
+ * @todo This should be moved to some general purpose/common code
+ */
+void DumpTGA(std::string filename, int width, int height, u8* raw_data) {
+    TGAHeader hdr;
+    FILE* fout;
+    u8 r, g, b;
+
+    memset(&hdr, 0, sizeof(hdr));
+    hdr.datatypecode = 2; // uncompressed RGB
+    hdr.bitsperpixel = 24; // 24 bpp
+    hdr.width = width;
+    hdr.height = height;
+
+    fout = fopen(filename.c_str(), "wb");
+    fwrite(&hdr, sizeof(TGAHeader), 1, fout);
+    for (int i = 0; i < height; i++) {
+        for (int j = 0; j < width; j++) {
+            r = raw_data[(4 * (i * width)) + (4 * j) + 0];
+            g = raw_data[(4 * (i * width)) + (4 * j) + 1];
+            b = raw_data[(4 * (i * width)) + (4 * j) + 2];
+            putc(b, fout);
+            putc(g, fout);
+            putc(r, fout);
+        }
+    }
+    fclose(fout);
+}
+
+} // namespace
diff --git a/src/video_core/src/utils.h b/src/video_core/src/utils.h
new file mode 100644
index 000000000..2d7fa4a3a
--- /dev/null
+++ b/src/video_core/src/utils.h
@@ -0,0 +1,83 @@
+/**
+ * Copyright (C) 2005-2012 Gekko Emulator
+ *
+ * @file    utils.h
+ * @author  ShizZy <shizzy247@gmail.com>
+ * @date    2012-12-28
+ * @brief   Utility functions (in general, not related to emulation) useful for video core
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
+
+#pragma once
+
+#include "common_types.h"
+#include <string>
+
+namespace FormatPrecision {
+
+/// Adjust RGBA8 color with RGBA6 precision
+static inline u32 rgba8_with_rgba6(u32 src) {
+	u32 color = src;
+	color &= 0xFCFCFCFC;
+	color |= (color >> 6) & 0x03030303;
+	return color;
+}
+
+/// Adjust RGBA8 color with RGB565 precision
+static inline u32 rgba8_with_rgb565(u32 src) {
+	u32 color = (src & 0xF8FCF8);
+	color |= (color >> 5) & 0x070007;
+	color |= (color >> 6) & 0x000300;
+	color |= 0xFF000000;
+	return color;
+}
+
+/// Adjust Z24 depth value with Z16 precision
+static inline u32 z24_with_z16(u32 src) {
+	return (src & 0xFFFF00) | (src >> 16);
+}
+
+} // namespace
+
+namespace VideoCore {
+
+/// Structure for the TGA texture format (for dumping)
+struct TGAHeader {
+    char  idlength;
+    char  colourmaptype;
+    char  datatypecode;
+    short int colourmaporigin;
+    short int colourmaplength;
+    short int x_origin;
+    short int y_origin;
+    short width;
+    short height;
+    char  bitsperpixel;
+    char  imagedescriptor;
+};
+
+/**
+ * Dumps a texture to TGA
+ * @param filename String filename to dump texture to
+ * @param width Width of texture in pixels
+ * @param height Height of texture in pixels
+ * @param raw_data Raw RGBA8 texture data to dump
+ * @todo This should be moved to some general purpose/common code
+ */
+void DumpTGA(std::string filename, int width, int height, u8* raw_data);
+
+} // namespace
diff --git a/src/video_core/src/video_core.cpp b/src/video_core/src/video_core.cpp
new file mode 100644
index 000000000..8ad45c912
--- /dev/null
+++ b/src/video_core/src/video_core.cpp
@@ -0,0 +1,91 @@
+/**
+ * Copyright (C) 2014 Citra Emulator
+ *
+ * @file    video_core.cpp
+ * @author  bunnei
+ * @date    2014-04-05
+ * @brief   Main module for new video core
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
+
+#include "common.h"
+#include "emu_window.h"
+#include "log.h"
+
+#include "core.h"
+#include "video_core.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Video Core namespace
+
+namespace VideoCore {
+
+EmuWindow*      g_emu_window    = NULL;     ///< Frontend emulator window
+RendererBase*   g_renderer      = NULL;     ///< Renderer plugin
+int             g_current_frame = 0;
+
+int VideoEntry(void*) {
+    if (g_emu_window == NULL) {
+        ERROR_LOG(VIDEO, "VideoCore::VideoEntry called without calling Init()!");
+    }
+    g_emu_window->MakeCurrent();
+    //for(;;) {
+    //    gp::Fifo_DecodeCommand();
+    //}
+    return 0;
+}
+
+/// Start the video core
+void Start() {
+    if (g_emu_window == NULL) {
+        ERROR_LOG(VIDEO, "VideoCore::Start called without calling Init()!");
+    }
+    //if (common::g_config->enable_multicore()) {
+    //    g_emu_window->DoneCurrent();
+    //    g_video_thread = SDL_CreateThread(VideoEntry, NULL, NULL);
+    //    if (g_video_thread == NULL) {
+    //        LOG_ERROR(TVIDEO, "Unable to create thread: %s... Exiting\n", SDL_GetError());
+    //        exit(1);
+    //    }
+    //}
+}
+
+/// Initialize the video core
+void Init(EmuWindow* emu_window) {
+    g_emu_window = emu_window;
+    //g_renderer = new RendererGL3();
+    //g_renderer->SetWindow(g_emu_window);
+    //g_renderer->Init();
+
+    //gp::Fifo_Init();
+    //gp::VertexManager_Init();
+    //gp::VertexLoader_Init();
+    //gp::BP_Init();
+    //gp::CP_Init();
+    //gp::XF_Init();
+
+    g_current_frame = 0;
+
+    NOTICE_LOG(VIDEO, "initialized ok");
+}
+
+/// Shutdown the video core
+void Shutdown() {
+    //delete g_renderer;
+}
+
+} // namespace
diff --git a/src/video_core/src/video_core.h b/src/video_core/src/video_core.h
new file mode 100644
index 000000000..9b80d7715
--- /dev/null
+++ b/src/video_core/src/video_core.h
@@ -0,0 +1,48 @@
+/*!
+ * Copyright (C) 2014 Citra Emulator
+ *
+ * @file    video_core.h
+ * @author  bunnei
+ * @date    2014-04-05
+ * @brief   Main module for new video core
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
+
+#pragma once
+
+#include "common.h"
+#include "emu_window.h"
+#include "renderer_base.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Video Core namespace
+
+namespace VideoCore {
+
+extern RendererBase*   g_renderer;          ///< Renderer plugin
+extern int             g_current_frame;     ///< Current frame
+
+/// Start the video core
+void Start();
+
+/// Initialize the video core
+void Init(EmuWindow* emu_window);
+
+/// Shutdown the video core
+void ShutDown();
+
+} // namespace
diff --git a/src/video_core/video_core.vcxproj b/src/video_core/video_core.vcxproj
new file mode 100644
index 000000000..4a1429745
--- /dev/null
+++ b/src/video_core/video_core.vcxproj
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\utils.cpp" />
+    <ClCompile Include="src\video_core.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="src\renderer_base.h" />
+    <ClInclude Include="src\utils.h" />
+    <ClInclude Include="src\video_core.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="CMakeLists.txt" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{6678D1A3-33A6-48A9-878B-48E5D2903D27}</ProjectGuid>
+    <RootNamespace>input_common</RootNamespace>
+    <ProjectName>video_core</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\..\vsprops\Base.props" />
+    <Import Project="..\..\vsprops\code_generation_debug.props" />
+    <Import Project="..\..\vsprops\optimization_debug.props" />
+    <Import Project="..\..\vsprops\externals.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\..\vsprops\Base.props" />
+    <Import Project="..\..\vsprops\code_generation_debug.props" />
+    <Import Project="..\..\vsprops\optimization_debug.props" />
+    <Import Project="..\..\vsprops\externals.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\..\vsprops\Base.props" />
+    <Import Project="..\..\vsprops\code_generation_release.props" />
+    <Import Project="..\..\vsprops\optimization_release.props" />
+    <Import Project="..\..\vsprops\externals.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\..\vsprops\Base.props" />
+    <Import Project="..\..\vsprops\code_generation_release.props" />
+    <Import Project="..\..\vsprops\optimization_release.props" />
+    <Import Project="..\..\vsprops\externals.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile />
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile />
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile />
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <ClCompile />
+    <ClCompile />
+    <ClCompile />
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile />
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/src/video_core/video_core.vcxproj.filters b/src/video_core/video_core.vcxproj.filters
new file mode 100644
index 000000000..2a84b7edf
--- /dev/null
+++ b/src/video_core/video_core.vcxproj.filters
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="src\video_core.cpp" />
+    <ClCompile Include="src\utils.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="src\renderer_base.h" />
+    <ClInclude Include="src\video_core.h" />
+    <ClInclude Include="src\utils.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="CMakeLists.txt" />
+  </ItemGroup>
+</Project>
\ No newline at end of file

From a604eaee54993befcb4721d7435ccc7c9add782a Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 6 Apr 2014 16:54:28 -0400
Subject: [PATCH 16/28] added project linker reference

---
 src/citra/citra.vcxproj | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/citra/citra.vcxproj b/src/citra/citra.vcxproj
index 8f29e3e63..16157ad04 100644
--- a/src/citra/citra.vcxproj
+++ b/src/citra/citra.vcxproj
@@ -194,6 +194,9 @@
       <LinkLibraryDependencies>true</LinkLibraryDependencies>
       <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
     </ProjectReference>
+    <ProjectReference Include="..\video_core\video_core.vcxproj">
+      <Project>{6678d1a3-33a6-48a9-878b-48e5d2903d27}</Project>
+    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\citra.cpp" />

From e4d1ad4bdacd1b1c57e9b88b1868a770867a5744 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 6 Apr 2014 16:55:05 -0400
Subject: [PATCH 17/28] set window size to correspond to framebuffer sizes

---
 src/citra/src/emu_window/emu_window_glfw.cpp | 4 +++-
 src/citra/src/emu_window/emu_window_glfw.h   | 5 +----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/citra/src/emu_window/emu_window_glfw.cpp b/src/citra/src/emu_window/emu_window_glfw.cpp
index 8edc745b7..4cdb7fbb0 100644
--- a/src/citra/src/emu_window/emu_window_glfw.cpp
+++ b/src/citra/src/emu_window/emu_window_glfw.cpp
@@ -23,6 +23,7 @@
  */
 
 #include "common.h"
+#include "video_core.h"
 #include "emu_window_glfw.h"
 
 static void OnKeyEvent(GLFWwindow* win, int key, int action) {
@@ -54,7 +55,8 @@ EmuWindow_GLFW::EmuWindow_GLFW() {
     }
     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
-    render_window_ = glfwCreateWindow(640, 480, "citra", NULL, NULL);
+    render_window_ = glfwCreateWindow(VideoCore::kScreenTopWidth, 
+        (VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight), "citra", NULL, NULL);
 
     // Setup callbacks
     glfwSetWindowUserPointer(render_window_, this);
diff --git a/src/citra/src/emu_window/emu_window_glfw.h b/src/citra/src/emu_window/emu_window_glfw.h
index 0339b5d68..abca9faa8 100644
--- a/src/citra/src/emu_window/emu_window_glfw.h
+++ b/src/citra/src/emu_window/emu_window_glfw.h
@@ -22,8 +22,7 @@
  * http://code.google.com/p/gekko-gc-emu/
  */
 
-#ifndef CITRA_EMUWINDOW_GLFW_
-#define CITRA_EMUWINDOW_GLFW_
+#pragma once
 
 #include <GL/glew.h>
 #include <GLFW/glfw3.h>
@@ -52,5 +51,3 @@ public:
 private:
 
 };
-
-#endif // CITRA_EMUWINDOW_GLFW_

From 080f847550b028e59f5a37471e00b8a27e6f1b23 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 6 Apr 2014 16:55:39 -0400
Subject: [PATCH 18/28] added initial renderer code

---
 src/video_core/src/renderer_base.h            |  26 +-
 .../src/renderer_opengl/renderer_opengl.cpp   | 340 ++++++++++++++++++
 .../src/renderer_opengl/renderer_opengl.h     | 138 +++++++
 src/video_core/src/video_core.cpp             |  19 +-
 src/video_core/src/video_core.h               |  17 +-
 src/video_core/video_core.vcxproj             |   2 +
 src/video_core/video_core.vcxproj.filters     |  11 +
 vsprops/base.props                            |   2 +-
 8 files changed, 535 insertions(+), 20 deletions(-)
 create mode 100644 src/video_core/src/renderer_opengl/renderer_opengl.cpp
 create mode 100644 src/video_core/src/renderer_opengl/renderer_opengl.h

diff --git a/src/video_core/src/renderer_base.h b/src/video_core/src/renderer_base.h
index 9cd02e0b4..50f1475b2 100644
--- a/src/video_core/src/renderer_base.h
+++ b/src/video_core/src/renderer_base.h
@@ -51,6 +51,9 @@ public:
     ~RendererBase() {
     }
 
+    /// Swap buffers (render frame)
+    virtual void SwapBuffers() = 0;
+
     /** 
      * Blits the EFB to the external framebuffer (XFB)
      * @param src_rect Source rectangle in EFB to copy
@@ -71,6 +74,24 @@ public:
     virtual void Clear(const Rect& rect, bool enable_color, bool enable_alpha, bool enable_z, 
         u32 color, u32 z) = 0;
 
+    /// Sets the renderer viewport location, width, and height
+    virtual void SetViewport(int x, int y, int width, int height) = 0;
+
+    /// Sets the renderer depthrange, znear and zfar
+    virtual void SetDepthRange(double znear, double zfar) = 0;
+
+    /* Sets the scissor box
+     * @param rect Renderer rectangle to set scissor box to
+     */
+    virtual void SetScissorBox(const Rect& rect) = 0;
+
+    /**
+     * Sets the line and point size
+     * @param line_width Line width to use
+     * @param point_size Point size to use
+     */
+    virtual void SetLinePointSize(f32 line_width, f32 point_size) = 0;
+
     /**
      * Set a specific render mode
      * @param flag Render flags mode to enable
@@ -95,11 +116,6 @@ public:
     /// Shutdown the renderer
     virtual void ShutDown() = 0;
 
-    /// Converts EFB rectangle coordinates to renderer rectangle coordinates
-    //static Rect EFBToRendererRect(const Rect& rect) {
-	   // return Rect(rect.x0_, kGCEFBHeight - rect.y0_, rect.x1_, kGCEFBHeight - rect.y1_);
-    //}
-
     // Getter/setter functions:
     // ------------------------
 
diff --git a/src/video_core/src/renderer_opengl/renderer_opengl.cpp b/src/video_core/src/renderer_opengl/renderer_opengl.cpp
new file mode 100644
index 000000000..133740a74
--- /dev/null
+++ b/src/video_core/src/renderer_opengl/renderer_opengl.cpp
@@ -0,0 +1,340 @@
+/**
+ * Copyright (C) 2014 Citra Emulator
+ *
+ * @file    renderer_opengl.cpp
+ * @author  bunnei
+ * @date    2014-04-05
+ * @brief   Renderer for OpenGL 3.x
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
+
+#include "video_core.h"
+#include "renderer_opengl/renderer_opengl.h"
+
+/// RendererOpenGL constructor
+RendererOpenGL::RendererOpenGL() {
+    memset(fbo_, 0, sizeof(fbo_));  
+    memset(fbo_rbo_, 0, sizeof(fbo_rbo_));  
+    memset(fbo_depth_buffers_, 0, sizeof(fbo_depth_buffers_));
+
+    resolution_width_ = max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth);
+    resolution_height_ = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight;
+}
+
+/// RendererOpenGL destructor
+RendererOpenGL::~RendererOpenGL() {
+}
+
+
+/// Swap buffers (render frame)
+void RendererOpenGL::SwapBuffers() {
+
+    glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    ResetRenderState();
+
+    // EFB->XFB copy
+    // TODO(bunnei): This is a hack and does not belong here. The copy should be triggered by some 
+    // register write We're also treating both framebuffers as a single one in OpenGL.
+    Rect framebuffer_size(0, 0, VideoCore::kScreenTopWidth, 
+        VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight);
+    CopyToXFB(framebuffer_size, framebuffer_size);
+
+    // XFB->Window copy
+    RenderFramebuffer();
+
+    // Swap buffers
+    render_window_->PollEvents();
+    render_window_->SwapBuffers();
+
+    // Switch back to EFB and clear
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_EFB]);
+
+    RestoreRenderState();
+}
+
+/** 
+ * Blits the EFB to the external framebuffer (XFB)
+ * @param src_rect Source rectangle in EFB to copy
+ * @param dst_rect Destination rectangle in EFB to copy to
+ * @param dest_height Destination height in pixels
+ */
+void RendererOpenGL::CopyToXFB(const Rect& src_rect, const Rect& dst_rect) {
+    ResetRenderState();
+
+    // Render target is destination framebuffer
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]);
+    glViewport(0, 0, resolution_width_, resolution_height_);
+
+    // Render source is our EFB
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_[kFramebuffer_EFB]);
+    glReadBuffer(GL_COLOR_ATTACHMENT0);
+
+    // Blit
+    glBlitFramebuffer(src_rect.x0_, src_rect.y0_, src_rect.x1_, src_rect.y1_, 
+                      dst_rect.x0_, dst_rect.y1_, dst_rect.x1_, dst_rect.y0_,
+                      GL_COLOR_BUFFER_BIT, GL_LINEAR);
+
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+
+    RestoreRenderState();
+}
+
+/**
+ * Clear the screen
+ * @param rect Screen rectangle to clear
+ * @param enable_color Enable color clearing
+ * @param enable_alpha Enable alpha clearing
+ * @param enable_z Enable depth clearing
+ * @param color Clear color
+ * @param z Clear depth
+ */
+void RendererOpenGL::Clear(const Rect& rect, bool enable_color, bool enable_alpha, bool enable_z, 
+    u32 color, u32 z) {
+    GLboolean const color_mask = enable_color ? GL_TRUE : GL_FALSE;
+    GLboolean const alpha_mask = enable_alpha ? GL_TRUE : GL_FALSE;
+
+    ResetRenderState();
+
+    // Clear color
+    glColorMask(color_mask,  color_mask,  color_mask,  alpha_mask);
+    glClearColor(float((color >> 16) & 0xFF) / 255.0f, float((color >> 8) & 0xFF) / 255.0f,
+        float((color >> 0) & 0xFF) / 255.0f, float((color >> 24) & 0xFF) / 255.0f);
+
+    // Clear depth
+    glDepthMask(enable_z ? GL_TRUE : GL_FALSE);
+    glClearDepth(float(z & 0xFFFFFF) / float(0xFFFFFF));
+
+    // Specify the rectangle of the EFB to clear
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(rect.x0_, rect.y1_, rect.width(), rect.height());
+
+    // Clear it!
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    RestoreRenderState();
+}
+
+/// Sets the renderer viewport location, width, and height
+void RendererOpenGL::SetViewport(int x, int y, int width, int height) {
+    glViewport(x, y, width, height);
+}
+
+/// Sets the renderer depthrange, znear and zfar
+void RendererOpenGL::SetDepthRange(double znear, double zfar) {
+    glDepthRange(znear, zfar);
+}
+
+/* Sets the scissor box
+ * @param rect Renderer rectangle to set scissor box to
+ */
+void RendererOpenGL::SetScissorBox(const Rect& rect) {
+    glScissor(rect.x0_, rect.y1_, rect.width(), rect.height());
+}
+
+/**
+ * Sets the line and point size
+ * @param line_width Line width to use
+ * @param point_size Point size to use
+ */
+void RendererOpenGL::SetLinePointSize(f32 line_width, f32 point_size) {
+    glLineWidth((GLfloat)line_width);
+    glPointSize((GLfloat)point_size);
+}
+
+/**
+ * Set a specific render mode
+ * @param flag Render flags mode to enable
+ */
+void RendererOpenGL::SetMode(kRenderMode flags) {
+    if(flags & kRenderMode_ZComp) {
+        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+    }
+    if(flags & kRenderMode_Multipass) {
+        glEnable(GL_DEPTH_TEST);
+        glDepthMask(GL_FALSE);          
+        glDepthFunc(GL_EQUAL);
+    }
+    if (flags & kRenderMode_UseDstAlpha) {
+        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
+        glDisable(GL_BLEND);
+    }
+    last_mode_ |= flags;
+}
+
+/// Reset the full renderer API to the NULL state
+void RendererOpenGL::ResetRenderState() {
+    glDisable(GL_SCISSOR_TEST);
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_CULL_FACE);
+    glDisable(GL_BLEND);
+    glDepthMask(GL_FALSE);
+    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+}
+
+/// Restore the full renderer API state - As the game set it
+void RendererOpenGL::RestoreRenderState() {
+    
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_EFB]);
+    
+    //gp::XF_UpdateViewport();
+    SetViewport(0, 0, resolution_width_, resolution_height_);
+    SetDepthRange(0.0f, 1.0f);
+    
+    //SetGenerationMode();
+    glEnable(GL_CULL_FACE);
+    glFrontFace(GL_CCW);
+    
+    //glEnable(GL_SCISSOR_TEST);
+    //gp::BP_SetScissorBox();
+    glDisable(GL_SCISSOR_TEST);
+
+    //SetColorMask(gp::g_bp_regs.cmode0);
+    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+    
+    //SetDepthMode();
+    glDisable(GL_DEPTH_TEST);
+    glDepthMask(GL_FALSE);
+
+    //SetBlendMode(gp::g_bp_regs.cmode0, gp::g_bp_regs.cmode1, true);
+    //if (common::g_config->current_renderer_config().enable_wireframe) {
+    //    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+    //} else {
+    //    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+    //}
+}
+
+/// Initialize the FBO
+void RendererOpenGL::InitFramebuffer() {
+    // TODO(en): This should probably be implemented with the top screen and bottom screen as 
+    // separate framebuffers
+
+    // Init the FBOs
+    // -------------
+
+    glGenFramebuffers(kMaxFramebuffers, fbo_); // Generate primary framebuffer
+    glGenRenderbuffers(kMaxFramebuffers, fbo_rbo_); // Generate primary RBOs
+    glGenRenderbuffers(kMaxFramebuffers, fbo_depth_buffers_); // Generate primary depth buffer
+
+    for (int i = 0; i < kMaxFramebuffers; i++) {
+        // Generate color buffer storage
+        glBindRenderbuffer(GL_RENDERBUFFER, fbo_rbo_[i]);
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, resolution_width_, resolution_height_);
+
+        // Generate depth buffer storage
+        glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth_buffers_[i]);
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, resolution_width_, 
+            resolution_height_);
+
+        // Attach the buffers
+        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[i]);
+        glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+            GL_RENDERBUFFER, fbo_depth_buffers_[i]);
+        glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+            GL_RENDERBUFFER, fbo_rbo_[i]);
+
+        // Check for completeness
+        if (GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)) {
+            NOTICE_LOG(RENDER, "framebuffer(%d) initialized ok", i);
+        } else {
+            ERROR_LOG(RENDER, "couldn't create OpenGL frame buffer");
+            exit(1);
+        } 
+    }
+    glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind our frame buffer(s)
+}
+
+/// Blit the FBO to the OpenGL default framebuffer
+void RendererOpenGL::RenderFramebuffer() {
+
+    // Render target is default framebuffer
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+    glViewport(0, 0, resolution_width_, resolution_height_);
+
+    // Render source is our XFB
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]);
+    glReadBuffer(GL_COLOR_ATTACHMENT0);
+
+    // Blit
+    glBlitFramebuffer(0, 0, resolution_width_, resolution_height_, 0, 0, 
+        render_window_->client_area_width(), render_window_->client_area_height(), 
+        GL_COLOR_BUFFER_BIT, GL_LINEAR);
+
+    // Update the FPS count
+    UpdateFramerate();
+
+    // Rebind EFB
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_EFB]);
+
+    current_frame_++;
+}
+
+/// Updates the framerate
+void RendererOpenGL::UpdateFramerate() {
+}
+
+/** 
+ * Set the emulator window to use for renderer
+ * @param window EmuWindow handle to emulator window to use for rendering
+ */
+void RendererOpenGL::SetWindow(EmuWindow* window) {
+    render_window_ = window;
+}
+
+/// Initialize the renderer
+void RendererOpenGL::Init() {
+    render_window_->MakeCurrent();
+    glShadeModel(GL_SMOOTH);
+
+
+    glStencilFunc(GL_ALWAYS, 0, 0);
+    glBlendFunc(GL_ONE, GL_ONE);
+
+    glViewport(0, 0, resolution_width_, resolution_height_);
+
+    glClearDepth(1.0f);
+    glEnable(GL_DEPTH_TEST);
+    glDisable(GL_LIGHTING);
+    glDepthFunc(GL_LEQUAL);
+
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+    glDisable(GL_STENCIL_TEST);
+    glEnable(GL_SCISSOR_TEST);
+
+    glScissor(0, 0, resolution_width_, resolution_height_);
+    glClearDepth(1.0f);
+
+    GLenum err = glewInit();
+    if (GLEW_OK != err) {
+        ERROR_LOG(RENDER, " Failed to initialize GLEW! Error message: \"%s\". Exiting...", 
+            glewGetErrorString(err));
+        exit(-1);
+    }
+
+    // Initialize everything else
+    // --------------------------
+
+    InitFramebuffer();
+
+    NOTICE_LOG(RENDER, "GL_VERSION: %s\n", glGetString(GL_VERSION));
+}
+
+/// Shutdown the renderer
+void RendererOpenGL::ShutDown() {
+}
diff --git a/src/video_core/src/renderer_opengl/renderer_opengl.h b/src/video_core/src/renderer_opengl/renderer_opengl.h
new file mode 100644
index 000000000..0c41977e4
--- /dev/null
+++ b/src/video_core/src/renderer_opengl/renderer_opengl.h
@@ -0,0 +1,138 @@
+/**
+ * Copyright (C) 2014 Citra Emulator
+ *
+ * @file    renderer_opengl.h
+ * @author  bunnei
+ * @date    2014-04-05
+ * @brief   Renderer for OpenGL 3.x
+ *
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Official project repository can be found at:
+ * http://code.google.com/p/gekko-gc-emu/
+ */
+
+#pragma once
+
+#include <GL/glew.h>
+
+
+#include "common.h"
+#include "emu_window.h"
+
+#include "renderer_base.h"
+
+
+class RendererOpenGL : virtual public RendererBase {
+public:
+
+    static const int kMaxFramebuffers = 2;  ///< Maximum number of framebuffers
+
+    RendererOpenGL();
+    ~RendererOpenGL();
+
+    /// Swap buffers (render frame)
+    void SwapBuffers();
+
+    /** 
+     * Blits the EFB to the external framebuffer (XFB)
+     * @param src_rect Source rectangle in EFB to copy
+     * @param dst_rect Destination rectangle in EFB to copy to
+     * @param dest_height Destination height in pixels
+     */
+    void CopyToXFB(const Rect& src_rect, const Rect& dst_rect);
+
+    /**
+     * Clear the screen
+     * @param rect Screen rectangle to clear
+     * @param enable_color Enable color clearing
+     * @param enable_alpha Enable alpha clearing
+     * @param enable_z Enable depth clearing
+     * @param color Clear color
+     * @param z Clear depth
+     */
+    void Clear(const Rect& rect, bool enable_color, bool enable_alpha, bool enable_z, 
+        u32 color, u32 z);
+
+    /// Sets the renderer viewport location, width, and height
+    void SetViewport(int x, int y, int width, int height);
+
+    /// Sets the renderer depthrange, znear and zfar
+    void SetDepthRange(double znear, double zfar);
+
+    /* Sets the scissor box
+     * @param rect Renderer rectangle to set scissor box to
+     */
+    void SetScissorBox(const Rect& rect);
+
+    /**
+     * Sets the line and point size
+     * @param line_width Line width to use
+     * @param point_size Point size to use
+     */
+    void SetLinePointSize(f32 line_width, f32 point_size);
+
+    /**
+     * Set a specific render mode
+     * @param flag Render flags mode to enable
+     */
+    void SetMode(kRenderMode flags);
+
+    /// Reset the full renderer API to the NULL state
+    void ResetRenderState();
+
+    /// Restore the full renderer API state - As the game set it
+    void RestoreRenderState();
+
+    /** 
+     * Set the emulator window to use for renderer
+     * @param window EmuWindow handle to emulator window to use for rendering
+     */
+    void SetWindow(EmuWindow* window);
+
+    /// Initialize the renderer
+    void Init();
+
+    /// Shutdown the renderer
+    void ShutDown();
+
+    // Framebuffer object(s)
+    // ---------------------
+
+    GLuint fbo_[kMaxFramebuffers];  ///< Framebuffer objects
+
+private:
+
+    /// Initialize the FBO
+    void InitFramebuffer();
+
+    // Blit the FBO to the OpenGL default framebuffer
+    void RenderFramebuffer();
+
+    /// Updates the framerate
+    void UpdateFramerate();
+
+    EmuWindow*  render_window_;
+    u32         last_mode_;                         ///< Last render mode
+
+    int resolution_width_;
+    int resolution_height_;
+
+    // Framebuffer object(s)
+    // ---------------------
+
+    GLuint fbo_rbo_[kMaxFramebuffers];              ///< Render buffer objects
+    GLuint fbo_depth_buffers_[kMaxFramebuffers];    ///< Depth buffers objects
+
+    DISALLOW_COPY_AND_ASSIGN(RendererOpenGL);
+};
\ No newline at end of file
diff --git a/src/video_core/src/video_core.cpp b/src/video_core/src/video_core.cpp
index 8ad45c912..52ff90488 100644
--- a/src/video_core/src/video_core.cpp
+++ b/src/video_core/src/video_core.cpp
@@ -27,7 +27,10 @@
 #include "log.h"
 
 #include "core.h"
+
 #include "video_core.h"
+#include "renderer_base.h"
+#include "renderer_opengl/renderer_opengl.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Video Core namespace
@@ -67,16 +70,10 @@ void Start() {
 /// Initialize the video core
 void Init(EmuWindow* emu_window) {
     g_emu_window = emu_window;
-    //g_renderer = new RendererGL3();
-    //g_renderer->SetWindow(g_emu_window);
-    //g_renderer->Init();
-
-    //gp::Fifo_Init();
-    //gp::VertexManager_Init();
-    //gp::VertexLoader_Init();
-    //gp::BP_Init();
-    //gp::CP_Init();
-    //gp::XF_Init();
+    g_emu_window->MakeCurrent();
+    g_renderer = new RendererOpenGL();
+    g_renderer->SetWindow(g_emu_window);
+    g_renderer->Init();
 
     g_current_frame = 0;
 
@@ -85,7 +82,7 @@ void Init(EmuWindow* emu_window) {
 
 /// Shutdown the video core
 void Shutdown() {
-    //delete g_renderer;
+    delete g_renderer;
 }
 
 } // namespace
diff --git a/src/video_core/src/video_core.h b/src/video_core/src/video_core.h
index 9b80d7715..10b8f1105 100644
--- a/src/video_core/src/video_core.h
+++ b/src/video_core/src/video_core.h
@@ -33,8 +33,19 @@
 
 namespace VideoCore {
 
-extern RendererBase*   g_renderer;          ///< Renderer plugin
-extern int             g_current_frame;     ///< Current frame
+// 3DS Video Constants
+// -------------------
+
+static const int kScreenTopWidth        = 400;  ///< 3DS top screen width
+static const int kScreenTopHeight       = 240;  ///< 3DS top screen height
+static const int kScreenBottomWidth     = 320;  ///< 3DS bottom screen width
+static const int kScreenBottomHeight    = 240;  ///< 3DS bottom screen height
+
+//  Video core renderer
+// ---------------------
+
+extern RendererBase*   g_renderer;              ///< Renderer plugin
+extern int             g_current_frame;         ///< Current frame
 
 /// Start the video core
 void Start();
@@ -43,6 +54,6 @@ void Start();
 void Init(EmuWindow* emu_window);
 
 /// Shutdown the video core
-void ShutDown();
+void Shutdown();
 
 } // namespace
diff --git a/src/video_core/video_core.vcxproj b/src/video_core/video_core.vcxproj
index 4a1429745..5c56e9b71 100644
--- a/src/video_core/video_core.vcxproj
+++ b/src/video_core/video_core.vcxproj
@@ -19,11 +19,13 @@
     </ProjectConfiguration>
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="src\renderer_opengl\renderer_opengl.cpp" />
     <ClCompile Include="src\utils.cpp" />
     <ClCompile Include="src\video_core.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\renderer_base.h" />
+    <ClInclude Include="src\renderer_opengl\renderer_opengl.h" />
     <ClInclude Include="src\utils.h" />
     <ClInclude Include="src\video_core.h" />
   </ItemGroup>
diff --git a/src/video_core/video_core.vcxproj.filters b/src/video_core/video_core.vcxproj.filters
index 2a84b7edf..e796fbe21 100644
--- a/src/video_core/video_core.vcxproj.filters
+++ b/src/video_core/video_core.vcxproj.filters
@@ -3,13 +3,24 @@
   <ItemGroup>
     <ClCompile Include="src\video_core.cpp" />
     <ClCompile Include="src\utils.cpp" />
+    <ClCompile Include="src\renderer_opengl\renderer_opengl.cpp">
+      <Filter>renderer_opengl</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\renderer_base.h" />
     <ClInclude Include="src\video_core.h" />
     <ClInclude Include="src\utils.h" />
+    <ClInclude Include="src\renderer_opengl\renderer_opengl.h">
+      <Filter>renderer_opengl</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Text Include="CMakeLists.txt" />
   </ItemGroup>
+  <ItemGroup>
+    <Filter Include="renderer_opengl">
+      <UniqueIdentifier>{e0245557-dbd4-423e-9399-513d5e99f1e4}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/vsprops/base.props b/vsprops/base.props
index 0f59b512b..6241bd44b 100644
--- a/vsprops/base.props
+++ b/vsprops/base.props
@@ -12,7 +12,7 @@
       <StructMemberAlignment>16Bytes</StructMemberAlignment>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <AdditionalIncludeDirectories>$(SolutionDir)src\common\src;$(SolutionDir)src\core\src;$(SolutionDir)src\citra\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)src\common\src;$(SolutionDir)src\core\src;$(SolutionDir)src\video_core\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>
       </PreprocessorDefinitions>
       <RuntimeTypeInfo>false</RuntimeTypeInfo>

From 551b2a52e0c36613a3ce459dcd8b2aac39de707b Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 6 Apr 2014 16:55:54 -0400
Subject: [PATCH 19/28] initialize VideoCore

---
 src/core/src/system.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/core/src/system.cpp b/src/core/src/system.cpp
index 1477bab32..7c829d609 100644
--- a/src/core/src/system.cpp
+++ b/src/core/src/system.cpp
@@ -27,6 +27,7 @@
 #include "core_timing.h"
 #include "mem_map.h"
 #include "system.h"
+#include "video_core.h"
 
 namespace System {
 
@@ -41,6 +42,7 @@ void Init(EmuWindow* emu_window) {
 	Memory::Init();
     HW::Init();
 	CoreTiming::Init();
+    VideoCore::Init(emu_window);
 }
 
 void RunLoopFor(int cycles) {
@@ -53,9 +55,8 @@ void RunLoopUntil(u64 global_cycles) {
 void Shutdown() {
     Core::Shutdown();
     HW::Shutdown();
+    VideoCore::Shutdown();
 	g_ctr_file_system.Shutdown();
 }
 
-
-
 } // namespace

From f0d49253e438dc7e39a2a95598c5ebac59d9ef3c Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 6 Apr 2014 16:56:13 -0400
Subject: [PATCH 20/28] calling SwapBuffers from hw_lcd.cpp

---
 src/core/src/hw/hw_lcd.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/core/src/hw/hw_lcd.cpp b/src/core/src/hw/hw_lcd.cpp
index 7e3728346..072eede32 100644
--- a/src/core/src/hw/hw_lcd.cpp
+++ b/src/core/src/hw/hw_lcd.cpp
@@ -25,6 +25,7 @@
 #include "log.h"
 #include "core.h"
 #include "hw_lcd.h"
+#include "video_core.h"
 
 namespace LCD {
 
@@ -47,6 +48,7 @@ void Update() {
     if ((current_ticks - g_last_ticks) >= kFrameTicks) {
         g_last_ticks = current_ticks;
         NOTICE_LOG(LCD, "Update frame");
+        VideoCore::g_renderer->SwapBuffers();
     }
 }
 

From 071647060935596902cfd79542f3b4cee1694b44 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 6 Apr 2014 16:56:42 -0400
Subject: [PATCH 21/28] added logger option specifically for the renderer

---
 src/common/src/log.h           | 2 +-
 src/common/src/log_manager.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/common/src/log.h b/src/common/src/log.h
index 5270ff2d9..432a307f0 100644
--- a/src/common/src/log.h
+++ b/src/common/src/log.h
@@ -57,7 +57,7 @@ enum LOG_TYPE {
     WII_IPC_NET,
     WII_IPC_WC24,
     WII_IPC_SSL,
-    WII_IPC_SD,
+    RENDER,
     LCD,
     HW,
     TIME,
diff --git a/src/common/src/log_manager.cpp b/src/common/src/log_manager.cpp
index e37278db7..b5b034846 100644
--- a/src/common/src/log_manager.cpp
+++ b/src/common/src/log_manager.cpp
@@ -67,7 +67,7 @@ LogManager::LogManager()
     m_Log[LogTypes::WII_IPC_DVD]        = new LogContainer("WII_IPC_DVD",       "WII IPC DVD");
     m_Log[LogTypes::WII_IPC_ES]         = new LogContainer("WII_IPC_ES",        "WII IPC ES");
     m_Log[LogTypes::WII_IPC_FILEIO]     = new LogContainer("WII_IPC_FILEIO",    "WII IPC FILEIO");
-    m_Log[LogTypes::WII_IPC_SD]         = new LogContainer("WII_IPC_SD",        "WII IPC SD");
+    m_Log[LogTypes::RENDER]             = new LogContainer("RENDER",            "RENDER");
     m_Log[LogTypes::LCD]                = new LogContainer("LCD",               "LCD");
     m_Log[LogTypes::WII_IPC_NET]        = new LogContainer("WII_IPC_NET",       "WII IPC NET");
     m_Log[LogTypes::WII_IPC_WC24]       = new LogContainer("WII_IPC_WC24",      "WII IPC WC24");

From 0727e07462cbae4e7172fc665b44d81b7cad995d Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 6 Apr 2014 16:57:09 -0400
Subject: [PATCH 22/28] added video_core as a dependencie for citra in build
 order

---
 citra.sln | 1 +
 1 file changed, 1 insertion(+)

diff --git a/citra.sln b/citra.sln
index 399e5cb9b..af1f1ee55 100644
--- a/citra.sln
+++ b/citra.sln
@@ -10,6 +10,7 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "citra", "src\citra\citra.vcxproj", "{CE7D2C07-21CE-4590-81AB-2ADA88A2B85F}"
 	ProjectSection(ProjectDependencies) = postProject
 		{69F00340-5C3D-449F-9A80-958435C6CF06} = {69F00340-5C3D-449F-9A80-958435C6CF06}
+		{6678D1A3-33A6-48A9-878B-48E5D2903D27} = {6678D1A3-33A6-48A9-878B-48E5D2903D27}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "src\core\core.vcxproj", "{8AEA7F29-3466-4786-A10D-6A4BD0610977}"

From aa3ae1af49a966f07319d5c51697ed6b6ebea230 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 6 Apr 2014 22:49:54 -0400
Subject: [PATCH 23/28] added "citra" instead of "emu" to title bar

---
 src/common/src/emu_window.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/common/src/emu_window.h b/src/common/src/emu_window.h
index 66de75574..f49367057 100644
--- a/src/common/src/emu_window.h
+++ b/src/common/src/emu_window.h
@@ -81,7 +81,7 @@ public:
 protected:
     EmuWindow() : client_area_width_(640), client_area_height_(480) {
         char window_title[255];
-        sprintf(window_title, "emu [%s|%s] - %s", 
+        sprintf(window_title, "citra [%s|%s] - %s", 
             "null-cpu", 
             "null-renderer", 
             __DATE__);

From aae52e3f8fbf3538c20ca4ab4a5f182ef4c9ac93 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 6 Apr 2014 22:56:08 -0400
Subject: [PATCH 24/28] added hack physical memory reads with
 Memory::GetPointer

---
 src/core/src/mem_map_funcs.cpp | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/core/src/mem_map_funcs.cpp b/src/core/src/mem_map_funcs.cpp
index dc4c2381d..ee2f79278 100644
--- a/src/core/src/mem_map_funcs.cpp
+++ b/src/core/src/mem_map_funcs.cpp
@@ -137,14 +137,21 @@ u8 *GetPointer(const u32 addr) {
     // TODO(bunnei): Just a stub for now... ImplementMe!
     if ((addr & 0x3E000000) == 0x08000000) {
         return g_fcram + (addr & MEM_FCRAM_MASK);
-    }
+
+    // HACK(bunnei): There is no layer yet to translate virtual addresses to physical addresses. 
+    // Until we progress far enough along, we'll accept all physical address reads here. I think 
+    // that this is typically a corner-case from usermode software unless they are trying to do 
+    // bare-metal things (e.g. early 3DS homebrew writes directly to the FB @ 0x20184E60, etc.
+    } else if (((addr & 0xF0000000) == MEM_FCRAM_PADDR) && (addr < (MEM_FCRAM_PADDR_END))) {
+        return g_fcram + (addr & MEM_FCRAM_MASK);
+
     //else if ((addr & 0x3F800000) == 0x04000000) {
     //    return g_vram + (addr & MEM_VRAM_MASK);
     //}
     //else if ((addr & 0x3F000000) >= 0x08000000 && (addr & 0x3F000000) < 0x08000000 + g_MemorySize) {
     //    return m_pRAM + (addr & g_MemoryMask);
     //}
-    else {
+    } else {
         //ERROR_LOG(MEMMAP, "Unknown GetPointer %08x PC %08x LR %08x", addr, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
         ERROR_LOG(MEMMAP, "Unknown GetPointer %08x", addr);
         static bool reported = false;

From 6f7fd741db1b2716753bae2aea75e7dabde92e9f Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 6 Apr 2014 22:56:25 -0400
Subject: [PATCH 25/28] removed log message from hw_lcd

---
 src/core/src/hw/hw_lcd.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/core/src/hw/hw_lcd.cpp b/src/core/src/hw/hw_lcd.cpp
index 072eede32..ee806d5dc 100644
--- a/src/core/src/hw/hw_lcd.cpp
+++ b/src/core/src/hw/hw_lcd.cpp
@@ -47,7 +47,6 @@ void Update() {
 
     if ((current_ticks - g_last_ticks) >= kFrameTicks) {
         g_last_ticks = current_ticks;
-        NOTICE_LOG(LCD, "Update frame");
         VideoCore::g_renderer->SwapBuffers();
     }
 }
@@ -55,7 +54,6 @@ void Update() {
 /// Initialize hardware
 void Init() {
     g_last_ticks = Core::g_app_core->GetTicks();
-
     NOTICE_LOG(LCD, "LCD initialized OK");
 }
 

From 506e6049d3e15410b0bbf3df32477c7d27d55bab Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 6 Apr 2014 22:57:04 -0400
Subject: [PATCH 26/28] added external framebuffer GL handles

---
 .../src/renderer_opengl/renderer_opengl.h           | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/video_core/src/renderer_opengl/renderer_opengl.h b/src/video_core/src/renderer_opengl/renderer_opengl.h
index 0c41977e4..f9fb89d50 100644
--- a/src/video_core/src/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/src/renderer_opengl/renderer_opengl.h
@@ -128,11 +128,20 @@ private:
     int resolution_width_;
     int resolution_height_;
 
-    // Framebuffer object(s)
-    // ---------------------
+    // Render buffers
+    // --------------
 
     GLuint fbo_rbo_[kMaxFramebuffers];              ///< Render buffer objects
     GLuint fbo_depth_buffers_[kMaxFramebuffers];    ///< Depth buffers objects
 
+    // External framebuffers
+    // ---------------------
+
+    GLuint xfb_texture_top_;                         ///< GL handle to top framebuffer texture
+    GLuint xfb_texture_bottom_;                      ///< GL handle to bottom framebuffer texture
+
+    GLuint xfb_top_;
+    GLuint xfb_bottom_;
+
     DISALLOW_COPY_AND_ASSIGN(RendererOpenGL);
 };
\ No newline at end of file

From 8cf851f68a6611980ccabc646a59763bd30c4eff Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Mon, 7 Apr 2014 00:52:34 -0400
Subject: [PATCH 27/28] added support for renderering the external framebuffers

---
 .../src/renderer_opengl/renderer_opengl.cpp   | 159 +++++++++++++++---
 .../src/renderer_opengl/renderer_opengl.h     |   8 +-
 2 files changed, 147 insertions(+), 20 deletions(-)

diff --git a/src/video_core/src/renderer_opengl/renderer_opengl.cpp b/src/video_core/src/renderer_opengl/renderer_opengl.cpp
index 133740a74..27917a5a2 100644
--- a/src/video_core/src/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/src/renderer_opengl/renderer_opengl.cpp
@@ -22,9 +22,31 @@
  * http://code.google.com/p/gekko-gc-emu/
  */
 
+#include "mem_map.h"
 #include "video_core.h"
 #include "renderer_opengl/renderer_opengl.h"
 
+/**
+ * Helper function to flip framebuffer from left-to-right to top-to-bottom
+ * @param addr Address of framebuffer in RAM
+ * @param out Pointer to output buffer with flipped framebuffer
+ * @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei
+ */
+inline void _flip_framebuffer(u32 addr, u8* out) {
+    u8* in = Memory::GetPointer(addr);
+    for (int y = 0; y < VideoCore::kScreenTopHeight; y++) {
+        for (int x = 0; x < VideoCore::kScreenTopWidth; x++) {
+            int in_coord = (VideoCore::kScreenTopHeight * 3 * x) + (VideoCore::kScreenTopHeight * 3)
+                - (3 * y + 3);
+            int out_coord = (VideoCore::kScreenTopWidth * y * 3) + (x * 3);
+
+            out[out_coord + 0] = in[in_coord + 0];
+            out[out_coord + 1] = in[in_coord + 1];
+            out[out_coord + 2] = in[in_coord + 2];
+        }
+    }
+}
+
 /// RendererOpenGL constructor
 RendererOpenGL::RendererOpenGL() {
     memset(fbo_, 0, sizeof(fbo_));  
@@ -33,27 +55,28 @@ RendererOpenGL::RendererOpenGL() {
 
     resolution_width_ = max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth);
     resolution_height_ = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight;
+
+    xfb_texture_top_ = 0;
+    xfb_texture_bottom_ = 0;
+
+    xfb_top_ = 0;
+    xfb_bottom_ = 0;
 }
 
 /// RendererOpenGL destructor
 RendererOpenGL::~RendererOpenGL() {
 }
 
-
 /// Swap buffers (render frame)
 void RendererOpenGL::SwapBuffers() {
 
-    glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
     ResetRenderState();
 
     // EFB->XFB copy
     // TODO(bunnei): This is a hack and does not belong here. The copy should be triggered by some 
     // register write We're also treating both framebuffers as a single one in OpenGL.
-    Rect framebuffer_size(0, 0, VideoCore::kScreenTopWidth, 
-        VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight);
-    CopyToXFB(framebuffer_size, framebuffer_size);
+    Rect framebuffer_size(0, 0, resolution_width_, resolution_height_);
+    RenderXFB(framebuffer_size, framebuffer_size);
 
     // XFB->Window copy
     RenderFramebuffer();
@@ -69,20 +92,34 @@ void RendererOpenGL::SwapBuffers() {
 }
 
 /** 
- * Blits the EFB to the external framebuffer (XFB)
- * @param src_rect Source rectangle in EFB to copy
- * @param dst_rect Destination rectangle in EFB to copy to
- * @param dest_height Destination height in pixels
+ * Renders external framebuffer (XFB)
+ * @param src_rect Source rectangle in XFB to copy
+ * @param dst_rect Destination rectangle in output framebuffer to copy to
  */
-void RendererOpenGL::CopyToXFB(const Rect& src_rect, const Rect& dst_rect) {
+void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) {
+    static u8 xfb_top_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth *3]; 
+    static u8 xfb_bottom_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth *3];     
+
+    _flip_framebuffer(0x20282160, xfb_top_flipped);
+    _flip_framebuffer(0x202118E0, xfb_bottom_flipped);
+
     ResetRenderState();
 
+    // Blit the top framebuffer
+    // ------------------------
+
+    // Update textures with contents of XFB in RAM - top
+    glBindTexture(GL_TEXTURE_2D, xfb_texture_top_);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight,
+        GL_RGB, GL_UNSIGNED_BYTE, xfb_top_flipped);
+    glBindTexture(GL_TEXTURE_2D, 0);
+
     // Render target is destination framebuffer
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]);
-    glViewport(0, 0, resolution_width_, resolution_height_);
+    glViewport(0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight);
 
     // Render source is our EFB
-    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_[kFramebuffer_EFB]);
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, xfb_top_);
     glReadBuffer(GL_COLOR_ATTACHMENT0);
 
     // Blit
@@ -92,9 +129,62 @@ void RendererOpenGL::CopyToXFB(const Rect& src_rect, const Rect& dst_rect) {
 
     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
 
+    // Blit the bottom framebuffer
+    // ---------------------------
+
+    // Update textures with contents of XFB in RAM - bottom
+    glBindTexture(GL_TEXTURE_2D, xfb_texture_bottom_);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight,
+        GL_RGB, GL_UNSIGNED_BYTE, xfb_bottom_flipped);
+    glBindTexture(GL_TEXTURE_2D, 0);
+
+    // Render target is destination framebuffer
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]);
+    glViewport(0, 0,
+        VideoCore::kScreenBottomWidth, VideoCore::kScreenBottomHeight);
+
+    // Render source is our EFB
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, xfb_bottom_);
+    glReadBuffer(GL_COLOR_ATTACHMENT0);
+
+    // Blit
+    int offset = (VideoCore::kScreenTopWidth - VideoCore::kScreenBottomWidth) / 2;
+    glBlitFramebuffer(0,0, VideoCore::kScreenBottomWidth, VideoCore::kScreenBottomHeight, 
+                      offset, VideoCore::kScreenBottomHeight, VideoCore::kScreenBottomWidth + offset, 0,
+                      GL_COLOR_BUFFER_BIT, GL_LINEAR);
+
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+
     RestoreRenderState();
 }
 
+/** 
+ * Blits the EFB to the external framebuffer (XFB)
+ * @param src_rect Source rectangle in EFB to copy
+ * @param dst_rect Destination rectangle in EFB to copy to
+ */
+void RendererOpenGL::CopyToXFB(const Rect& src_rect, const Rect& dst_rect) {
+    ERROR_LOG(RENDER, "CopyToXFB not implemented! No EFB support yet!");
+    //ResetRenderState();
+
+    //// Render target is destination framebuffer
+    //glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[kFramebuffer_VirtualXFB]);
+    //glViewport(0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight);
+
+    //// Render source is our EFB
+    //glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_[kFramebuffer_EFB]);
+    //glReadBuffer(GL_COLOR_ATTACHMENT0);
+
+    //// Blit
+    //glBlitFramebuffer(src_rect.x0_, src_rect.y0_, src_rect.x1_, src_rect.y1_, 
+    //                  dst_rect.x0_, dst_rect.y1_, dst_rect.x1_, dst_rect.y0_,
+    //                  GL_COLOR_BUFFER_BIT, GL_LINEAR);
+
+    //glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+
+    //RestoreRenderState();
+}
+
 /**
  * Clear the screen
  * @param rect Screen rectangle to clear
@@ -234,12 +324,13 @@ void RendererOpenGL::InitFramebuffer() {
     for (int i = 0; i < kMaxFramebuffers; i++) {
         // Generate color buffer storage
         glBindRenderbuffer(GL_RENDERBUFFER, fbo_rbo_[i]);
-        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, resolution_width_, resolution_height_);
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, VideoCore::kScreenTopWidth, 
+            VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight);
 
         // Generate depth buffer storage
         glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth_buffers_[i]);
-        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, resolution_width_, 
-            resolution_height_);
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, VideoCore::kScreenTopWidth, 
+            VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight);
 
         // Attach the buffers
         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_[i]);
@@ -257,6 +348,37 @@ void RendererOpenGL::InitFramebuffer() {
         } 
     }
     glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind our frame buffer(s)
+
+    // Initialize framebuffer textures
+    // -------------------------------
+
+    // Create XFB textures
+    glGenTextures(1, &xfb_texture_top_);  
+    glGenTextures(1, &xfb_texture_bottom_);  
+
+    // Alocate video memorry for XFB textures
+    glBindTexture(GL_TEXTURE_2D, xfb_texture_top_);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight,
+        0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+    glBindTexture(GL_TEXTURE_2D, 0);
+
+    glBindTexture(GL_TEXTURE_2D, xfb_texture_bottom_);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight,
+        0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+    glBindTexture(GL_TEXTURE_2D, 0);
+
+    // Create the FBO and attach color/depth textures
+    glGenFramebuffers(1, &xfb_top_); // Generate framebuffer
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, xfb_top_);
+    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 
+        xfb_texture_top_, 0);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+    glGenFramebuffers(1, &xfb_bottom_); // Generate framebuffer
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, xfb_bottom_);
+    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 
+        xfb_texture_bottom_, 0);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
 /// Blit the FBO to the OpenGL default framebuffer
@@ -272,8 +394,7 @@ void RendererOpenGL::RenderFramebuffer() {
 
     // Blit
     glBlitFramebuffer(0, 0, resolution_width_, resolution_height_, 0, 0, 
-        render_window_->client_area_width(), render_window_->client_area_height(), 
-        GL_COLOR_BUFFER_BIT, GL_LINEAR);
+        resolution_width_, resolution_height_, GL_COLOR_BUFFER_BIT, GL_LINEAR);
 
     // Update the FPS count
     UpdateFramerate();
diff --git a/src/video_core/src/renderer_opengl/renderer_opengl.h b/src/video_core/src/renderer_opengl/renderer_opengl.h
index f9fb89d50..b84afc5d2 100644
--- a/src/video_core/src/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/src/renderer_opengl/renderer_opengl.h
@@ -44,11 +44,17 @@ public:
     /// Swap buffers (render frame)
     void SwapBuffers();
 
+    /** 
+     * Renders external framebuffer (XFB)
+     * @param src_rect Source rectangle in XFB to copy
+     * @param dst_rect Destination rectangle in output framebuffer to copy to
+     */
+    void RenderXFB(const Rect& src_rect, const Rect& dst_rect);
+
     /** 
      * Blits the EFB to the external framebuffer (XFB)
      * @param src_rect Source rectangle in EFB to copy
      * @param dst_rect Destination rectangle in EFB to copy to
-     * @param dest_height Destination height in pixels
      */
     void CopyToXFB(const Rect& src_rect, const Rect& dst_rect);
 

From efef514fd8252e1f07cd1b45455dbb5207f2b0c3 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Mon, 7 Apr 2014 00:53:47 -0400
Subject: [PATCH 28/28] removed unused comments, changed main processing loop
 to be infinite

---
 src/citra/src/citra.cpp | 36 ++----------------------------------
 1 file changed, 2 insertions(+), 34 deletions(-)

diff --git a/src/citra/src/citra.cpp b/src/citra/src/citra.cpp
index 26f5a74eb..746cf083d 100644
--- a/src/citra/src/citra.cpp
+++ b/src/citra/src/citra.cpp
@@ -52,39 +52,6 @@ int __cdecl main(int argc, char **argv) {
 
 	System::Init(emu_window);
 
-    //if (E_OK != Core::Init(emu_window)) {
-    //    LOG_ERROR(TMASTER, "core initialization failed, exiting...");
-    //    core::Kill();
-    //    exit(1);
-    //}
-
-    //// Load a game or die...
-    //if (E_OK == dvd::LoadBootableFile(common::g_config->default_boot_file())) {
-    //    if (common::g_config->enable_auto_boot()) {
-    //        core::Start();
-    //    } else {
-    //        LOG_ERROR(TMASTER, "Autoboot required in no-GUI mode... Exiting!\n");
-    //    }
-    //} else {
-    //    LOG_ERROR(TMASTER, "Failed to load a bootable file... Exiting!\n");
-    //    exit(E_ERR);
-    //}
-    //// run the game
-    //while(core::SYS_DIE != core::g_state) {
-    //    if (core::SYS_RUNNING == core::g_state) {
-    //        if(!(cpu->is_on)) {
-    //            cpu->Start(); // Initialize and start CPU.
-    //        } else {
-    //            for(tight_loop = 0; tight_loop < 10000; ++tight_loop) {
-    //                cpu->execStep();
-    //            }
-    //        }
-    //    } else if (core::SYS_HALTED == core::g_state) {
-    //        core::Stop();
-    //    }
-    //}
-    //core::Kill();
-
     std::string boot_filename = "homebrew.elf";
     std::string error_str;
     
@@ -93,7 +60,8 @@ int __cdecl main(int argc, char **argv) {
     if (!res) {
         ERROR_LOG(BOOT, "Failed to load ROM: %s", error_str.c_str());
     }
-    for (int tight_loop = 0; tight_loop < 10000; ++tight_loop) {
+
+    for (;;) {
         Core::SingleStep();
     }