Просмотр исходного кода

Merge branch 'hardware-interface'

Conflicts:
	src/core/src/core.h
bunnei 12 лет назад
Родитель
Сommit
f446f79da2

+ 12 - 1
citra.sln

@@ -1,5 +1,5 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Express 2013 for Windows Desktop
+# Visual Studio 2013
 VisualStudioVersion = 12.0.21005.1
 VisualStudioVersion = 12.0.21005.1
 MinimumVisualStudioVersion = 10.0.40219.1
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "src\common\common.vcxproj", "{DFE335FC-755D-4BAA-8452-94434F8A1EDB}"
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "src\common\common.vcxproj", "{DFE335FC-755D-4BAA-8452-94434F8A1EDB}"
@@ -10,6 +10,7 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "citra", "src\citra\citra.vcxproj", "{CE7D2C07-21CE-4590-81AB-2ADA88A2B85F}"
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "citra", "src\citra\citra.vcxproj", "{CE7D2C07-21CE-4590-81AB-2ADA88A2B85F}"
 	ProjectSection(ProjectDependencies) = postProject
 	ProjectSection(ProjectDependencies) = postProject
 		{69F00340-5C3D-449F-9A80-958435C6CF06} = {69F00340-5C3D-449F-9A80-958435C6CF06}
 		{69F00340-5C3D-449F-9A80-958435C6CF06} = {69F00340-5C3D-449F-9A80-958435C6CF06}
+		{6678D1A3-33A6-48A9-878B-48E5D2903D27} = {6678D1A3-33A6-48A9-878B-48E5D2903D27}
 	EndProjectSection
 	EndProjectSection
 EndProject
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "src\core\core.vcxproj", "{8AEA7F29-3466-4786-A10D-6A4BD0610977}"
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "src\core\core.vcxproj", "{8AEA7F29-3466-4786-A10D-6A4BD0610977}"
@@ -21,6 +22,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scm_rev_gen", "src\common\s
 EndProject
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "citra_qt", "src\citra_qt\citra_qt.vcxproj", "{A587F714-490F-407A-9E36-7AB7FA0D7BAB}"
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "citra_qt", "src\citra_qt\citra_qt.vcxproj", "{A587F714-490F-407A-9E36-7AB7FA0D7BAB}"
 EndProject
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "video_core", "src\video_core\video_core.vcxproj", "{6678D1A3-33A6-48A9-878B-48E5D2903D27}"
+EndProject
 Global
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
 		Debug|Win32 = Debug|Win32
@@ -69,6 +72,14 @@ Global
 		{A587F714-490F-407A-9E36-7AB7FA0D7BAB}.Release|Win32.Build.0 = Release|Win32
 		{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.ActiveCfg = Release|x64
 		{A587F714-490F-407A-9E36-7AB7FA0D7BAB}.Release|x64.Build.0 = 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
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 		HideSolutionNode = FALSE

+ 3 - 0
src/citra/citra.vcxproj

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

+ 2 - 34
src/citra/src/citra.cpp

@@ -52,39 +52,6 @@ int __cdecl main(int argc, char **argv) {
 
 
 	System::Init(emu_window);
 	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 boot_filename = "homebrew.elf";
     std::string error_str;
     std::string error_str;
     
     
@@ -93,7 +60,8 @@ int __cdecl main(int argc, char **argv) {
     if (!res) {
     if (!res) {
         ERROR_LOG(BOOT, "Failed to load ROM: %s", error_str.c_str());
         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();
         Core::SingleStep();
     }
     }
 
 

+ 3 - 1
src/citra/src/emu_window/emu_window_glfw.cpp

@@ -23,6 +23,7 @@
  */
  */
 
 
 #include "common.h"
 #include "common.h"
+#include "video_core.h"
 #include "emu_window_glfw.h"
 #include "emu_window_glfw.h"
 
 
 static void OnKeyEvent(GLFWwindow* win, int key, int action) {
 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_MAJOR, 3);
     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
     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
     // Setup callbacks
     glfwSetWindowUserPointer(render_window_, this);
     glfwSetWindowUserPointer(render_window_, this);

+ 1 - 4
src/citra/src/emu_window/emu_window_glfw.h

@@ -22,8 +22,7 @@
  * http://code.google.com/p/gekko-gc-emu/
  * http://code.google.com/p/gekko-gc-emu/
  */
  */
 
 
-#ifndef CITRA_EMUWINDOW_GLFW_
-#define CITRA_EMUWINDOW_GLFW_
+#pragma once
 
 
 #include <GL/glew.h>
 #include <GL/glew.h>
 #include <GLFW/glfw3.h>
 #include <GLFW/glfw3.h>
@@ -52,5 +51,3 @@ public:
 private:
 private:
 
 
 };
 };
-
-#endif // CITRA_EMUWINDOW_GLFW_

+ 5 - 0
src/common/src/common.h

@@ -163,4 +163,9 @@ enum EMUSTATE_CHANGE
     EMUSTATE_CHANGE_STOP
     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_
 #endif // _COMMON_H_

+ 104 - 29
src/common/src/common_types.h

@@ -1,50 +1,125 @@
-// 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/
+ */
 
 
+#pragma once 
 
 
-// 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_
+#include <math.h>
+#include <xmmintrin.h> // data_types__m128.cpp
 
 
 #ifdef _WIN32
 #ifdef _WIN32
 
 
 #include <tchar.h>
 #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
 #else
 
 
-#ifndef GEKKO
-
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef unsigned long long u64;
+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 signed char s8;
-typedef signed short s16;
-typedef signed int s32;
-typedef signed long long s64;
+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
 
 
-#endif
 // For using windows lock code
 // For using windows lock code
 #define TCHAR char
 #define TCHAR char
 #define LONG int
 #define LONG int
 
 
 #endif // _WIN32
 #endif // _WIN32
 
 
+typedef float   f32;    ///< 32-bit floating point
+typedef double  f64;    ///< 64-bit floating point
+
 #include "swap.h"
 #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_);
+    }
+};

+ 1 - 1
src/common/src/emu_window.h

@@ -81,7 +81,7 @@ public:
 protected:
 protected:
     EmuWindow() : client_area_width_(640), client_area_height_(480) {
     EmuWindow() : client_area_width_(640), client_area_height_(480) {
         char window_title[255];
         char window_title[255];
-        sprintf(window_title, "emu [%s|%s] - %s", 
+        sprintf(window_title, "citra [%s|%s] - %s", 
             "null-cpu", 
             "null-cpu", 
             "null-renderer", 
             "null-renderer", 
             __DATE__);
             __DATE__);

+ 3 - 3
src/common/src/log.h

@@ -57,9 +57,9 @@ enum LOG_TYPE {
     WII_IPC_NET,
     WII_IPC_NET,
     WII_IPC_WC24,
     WII_IPC_WC24,
     WII_IPC_SSL,
     WII_IPC_SSL,
-    WII_IPC_SD,
-    WII_IPC_STM,
-    WII_IPC_WIIMOTE,
+    RENDER,
+    LCD,
+    HW,
     TIME,
     TIME,
     NETPLAY,
     NETPLAY,
 
 

+ 47 - 47
src/common/src/log_manager.cpp

@@ -29,53 +29,53 @@ LogManager *LogManager::m_logManager = NULL;
 LogManager::LogManager()
 LogManager::LogManager()
 {
 {
     // create log files
     // 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::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");
+    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_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str());
     m_consoleLog = new ConsoleListener();
     m_consoleLog = new ConsoleListener();

+ 4 - 0
src/core/core.vcxproj

@@ -152,6 +152,8 @@
     <ClCompile Include="src\elf\elf_reader.cpp" />
     <ClCompile Include="src\elf\elf_reader.cpp" />
     <ClCompile Include="src\file_sys\directory_file_system.cpp" />
     <ClCompile Include="src\file_sys\directory_file_system.cpp" />
     <ClCompile Include="src\file_sys\meta_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\loader.cpp" />
     <ClCompile Include="src\mem_map.cpp" />
     <ClCompile Include="src\mem_map.cpp" />
     <ClCompile Include="src\mem_map_funcs.cpp" />
     <ClCompile Include="src\mem_map_funcs.cpp" />
@@ -180,6 +182,8 @@
     <ClInclude Include="src\file_sys\directory_file_system.h" />
     <ClInclude Include="src\file_sys\directory_file_system.h" />
     <ClInclude Include="src\file_sys\file_sys.h" />
     <ClInclude Include="src\file_sys\file_sys.h" />
     <ClInclude Include="src\file_sys\meta_file_system.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\loader.h" />
     <ClInclude Include="src\mem_map.h" />
     <ClInclude Include="src\mem_map.h" />
     <ClInclude Include="src\system.h" />
     <ClInclude Include="src\system.h" />

+ 15 - 0
src/core/core.vcxproj.filters

@@ -46,6 +46,12 @@
     <ClCompile Include="src\arm\interpreter\arm_interpreter.cpp">
     <ClCompile Include="src\arm\interpreter\arm_interpreter.cpp">
       <Filter>arm\interpreter</Filter>
       <Filter>arm\interpreter</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="src\hw\hw.cpp">
+      <Filter>hw</Filter>
+    </ClCompile>
+    <ClCompile Include="src\hw\hw_lcd.cpp">
+      <Filter>hw</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <Filter Include="arm">
     <Filter Include="arm">
@@ -69,6 +75,9 @@
     <Filter Include="arm\interpreter">
     <Filter Include="arm\interpreter">
       <UniqueIdentifier>{cca8b763-8a80-4478-9bcc-3c979293c357}</UniqueIdentifier>
       <UniqueIdentifier>{cca8b763-8a80-4478-9bcc-3c979293c357}</UniqueIdentifier>
     </Filter>
     </Filter>
+    <Filter Include="hw">
+      <UniqueIdentifier>{d1158fc4-3e0f-431f-9d3b-f30bbfeb4ad5}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\arm\disassembler\arm_disasm.h">
     <ClInclude Include="src\arm\disassembler\arm_disasm.h">
@@ -136,6 +145,12 @@
     <ClInclude Include="src\arm\interpreter\arm_interpreter.h">
     <ClInclude Include="src\arm\interpreter\arm_interpreter.h">
       <Filter>arm\interpreter</Filter>
       <Filter>arm\interpreter</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="src\hw\hw.h">
+      <Filter>hw</Filter>
+    </ClInclude>
+    <ClInclude Include="src\hw\hw_lcd.h">
+      <Filter>hw</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <None Include="CMakeLists.txt" />
     <None Include="CMakeLists.txt" />

+ 45 - 4
src/core/src/arm/arm_interface.h

@@ -24,24 +24,65 @@
 
 
 #pragma once
 #pragma once
 
 
+#include "common.h"
 #include "common_types.h"
 #include "common_types.h"
 
 
 /// Generic ARM11 CPU interface
 /// Generic ARM11 CPU interface
 class ARM_Interface {
 class ARM_Interface {
 public:
 public:
     ARM_Interface() {
     ARM_Interface() {
+        num_instructions_ = 0;
     }
     }
 
 
     ~ARM_Interface() {
     ~ARM_Interface() {
     }
     }
 
 
-    virtual void ExecuteInstruction() = 0;
-    
-    virtual void SetPC(u32 pc) = 0;
+    /// Step CPU by one instruction
+    void Step() {
+        ExecuteInstruction();
+        num_instructions_++;
+    }
+ 
+    /**
+     * 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;
     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;
     virtual u32 Reg(int index) = 0;
 
 
-    virtual u32 CPSR() = 0;
+    /**
+     * Get the current CPSR register
+     * @return Returns the value of the CPSR register
+     */
+    virtual u32 CPSR() = 0;  
+
+    /**
+     * 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 num_instructions_;  ///< Number of instructions executed
+
+    DISALLOW_COPY_AND_ASSIGN(ARM_Interface);
 };
 };

+ 22 - 22
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"
 #include "arm_interpreter.h"
 
 

+ 7 - 0
src/core/src/arm/interpreter/arm_interpreter.h

@@ -24,6 +24,7 @@
 
 
 #pragma once
 #pragma once
 
 
+#include "common.h"
 #include "common_types.h"
 #include "common_types.h"
 #include "arm/arm_interface.h"
 #include "arm/arm_interface.h"
 
 
@@ -45,6 +46,12 @@ public:
 
 
     u32 CPSR();
     u32 CPSR();
 
 
+    u64 GetTicks() {
+        return ARMul_Time(state);
+    }
+
 private:
 private:
     ARMul_State* state;
     ARMul_State* state;
+
+    DISALLOW_COPY_AND_ASSIGN(ARM_Interpreter);
 };
 };

+ 5 - 1
src/core/src/core.cpp

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

+ 3 - 0
src/core/src/core.h

@@ -55,6 +55,9 @@ void Stop();
 /// Initialize the core
 /// Initialize the core
 int Init();
 int Init();
 
 
+/// Shutdown the core
+void Shutdown();
+
 } // namespace
 } // namespace
 
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////////////////////////

+ 69 - 0
src/core/src/hw/hw.cpp

@@ -0,0 +1,69 @@
+/**
+ * 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"
+#include "hw/hw_lcd.h"
+
+namespace HW {
+
+template <typename T>
+inline void Read(T &var, const u32 addr) {
+    NOTICE_LOG(HW, "Hardware read from address %08X", addr);
+}
+
+template <typename T>
+inline void Write(u32 addr, const T data) {
+    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);
+
+/// Update hardware
+void Update() {
+    LCD::Update();
+}
+
+/// Initialize hardware
+void Init() {
+    LCD::Init();
+    NOTICE_LOG(HW, "Hardware initialized OK");
+}
+
+/// Shutdown hardware
+void Shutdown() {
+    NOTICE_LOG(HW, "Hardware shutdown OK");
+}
+
+}

+ 44 - 0
src/core/src/hw/hw.h

@@ -0,0 +1,44 @@
+/**
+ * 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);
+
+/// Update hardware
+void Update();
+
+/// Initialize hardware
+void Init();
+
+/// Shutdown hardware
+void Shutdown();
+
+} // namespace

+ 65 - 0
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"
+#include "video_core.h"
+
+namespace LCD {
+
+static const u32 kFrameTicks = 268123480 / 60;  ///< 268MHz / 60 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->GetTicks();
+
+    if ((current_ticks - g_last_ticks) >= kFrameTicks) {
+        g_last_ticks = current_ticks;
+        VideoCore::g_renderer->SwapBuffers();
+    }
+}
+
+/// Initialize hardware
+void Init() {
+    g_last_ticks = Core::g_app_core->GetTicks();
+    NOTICE_LOG(LCD, "LCD initialized OK");
+}
+
+/// Shutdown hardware
+void Shutdown() {
+    NOTICE_LOG(LCD, "LCD shutdown OK");
+}
+
+} // namespace

+ 64 - 0
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

+ 36 - 18
src/core/src/mem_map_funcs.cpp

@@ -25,17 +25,23 @@
 #include "common.h"
 #include "common.h"
 
 
 #include "mem_map.h"
 #include "mem_map.h"
+#include "hw/hw.h"
 
 
 namespace Memory {
 namespace Memory {
 
 
 template <typename T>
 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: 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.
     // TODO: Make sure this represents the mirrors in a correct way.
-
     // Could just do a base-relative read, too.... TODO
     // 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]);
         var = *((const T*)&g_fcram[addr & MEM_FCRAM_MASK]);
 
 
     // Scratchpad memory
     // Scratchpad memory
@@ -54,15 +60,20 @@ inline void ReadFromHardware(T &var, const u32 addr) {
         var = *((const T*)&g_fcram[addr & MEM_FCRAM_MASK]);
         var = *((const T*)&g_fcram[addr & MEM_FCRAM_MASK]);
 
 
     } else {
     } 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]);
+        _assert_msg_(MEMMAP, false, "unknown memory read");
     }
     }
 }
 }
 
 
 template <typename T>
 template <typename T>
-inline void WriteToHardware(u32 addr, const T data) {
+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:
     // ExeFS:/.code is loaded here:
-    if ((addr & 0xFFF00000) == 0x00100000) {
+    } else if ((addr & 0xFFF00000) == 0x00100000) {
         // TODO(ShizZy): This is dumb... handle correctly. From 3DBrew:
         // TODO(ShizZy): This is dumb... handle correctly. From 3DBrew:
         // http://3dbrew.org/wiki/Memory_layout#ARM11_User-land_memory_regions
         // 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 ExeFS:/.code is loaded here, executables must be loaded to the 0x00100000 region when
@@ -104,7 +115,7 @@ inline void WriteToHardware(u32 addr, const T data) {
 
 
     // Error out...
     // Error out...
     } else {
     } else {
-        _assert_msg_(MEMMAP, false, "unknown hardware write");
+        _assert_msg_(MEMMAP, false, "unknown memory write");
     }
     }
 }
 }
 
 
@@ -126,14 +137,21 @@ u8 *GetPointer(const u32 addr) {
     // TODO(bunnei): Just a stub for now... ImplementMe!
     // TODO(bunnei): Just a stub for now... ImplementMe!
     if ((addr & 0x3E000000) == 0x08000000) {
     if ((addr & 0x3E000000) == 0x08000000) {
         return g_fcram + (addr & MEM_FCRAM_MASK);
         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) {
     //else if ((addr & 0x3F800000) == 0x04000000) {
     //    return g_vram + (addr & MEM_VRAM_MASK);
     //    return g_vram + (addr & MEM_VRAM_MASK);
     //}
     //}
     //else if ((addr & 0x3F000000) >= 0x08000000 && (addr & 0x3F000000) < 0x08000000 + g_MemorySize) {
     //else if ((addr & 0x3F000000) >= 0x08000000 && (addr & 0x3F000000) < 0x08000000 + g_MemorySize) {
     //    return m_pRAM + (addr & g_MemoryMask);
     //    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 PC %08x LR %08x", addr, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
         ERROR_LOG(MEMMAP, "Unknown GetPointer %08x", addr);
         ERROR_LOG(MEMMAP, "Unknown GetPointer %08x", addr);
         static bool reported = false;
         static bool reported = false;
@@ -151,25 +169,25 @@ u8 *GetPointer(const u32 addr) {
 
 
 u8 Read8(const u32 addr) {
 u8 Read8(const u32 addr) {
     u8 _var = 0;
     u8 _var = 0;
-    ReadFromHardware<u8>(_var, addr);
+    _Read<u8>(_var, addr);
     return (u8)_var;
     return (u8)_var;
 }
 }
 
 
 u16 Read16(const u32 addr) {
 u16 Read16(const u32 addr) {
     u16_le _var = 0;
     u16_le _var = 0;
-    ReadFromHardware<u16_le>(_var, addr);
+    _Read<u16_le>(_var, addr);
     return (u16)_var;
     return (u16)_var;
 }
 }
 
 
 u32 Read32(const u32 addr) {
 u32 Read32(const u32 addr) {
     u32_le _var = 0;
     u32_le _var = 0;
-    ReadFromHardware<u32_le>(_var, addr);
+    _Read<u32_le>(_var, addr);
     return _var;
     return _var;
 }
 }
 
 
 u64 Read64(const u32 addr) {
 u64 Read64(const u32 addr) {
     u64_le _var = 0;
     u64_le _var = 0;
-    ReadFromHardware<u64_le>(_var, addr);
+    _Read<u64_le>(_var, addr);
     return _var;
     return _var;
 }
 }
 
 
@@ -182,19 +200,19 @@ u32 Read16_ZX(const u32 addr) {
 }
 }
 
 
 void Write8(const u32 addr, const u8 data) {
 void Write8(const u32 addr, const u8 data) {
-    WriteToHardware<u8>(addr, data);
+    _Write<u8>(addr, data);
 }
 }
 
 
 void Write16(const u32 addr, const u16 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) {
 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) {
 void Write64(const u32 addr, const u64 data) {
-    WriteToHardware<u64_le>(addr, data);
+    _Write<u64_le>(addr, data);
 }
 }
 
 
 } // namespace
 } // namespace

+ 7 - 2
src/core/src/system.cpp

@@ -23,9 +23,11 @@
 */
 */
 
 
 #include "core.h"
 #include "core.h"
+#include "hw/hw.h"
 #include "core_timing.h"
 #include "core_timing.h"
 #include "mem_map.h"
 #include "mem_map.h"
 #include "system.h"
 #include "system.h"
+#include "video_core.h"
 
 
 namespace System {
 namespace System {
 
 
@@ -38,7 +40,9 @@ void UpdateState(State state) {
 void Init(EmuWindow* emu_window) {
 void Init(EmuWindow* emu_window) {
 	Core::Init();
 	Core::Init();
 	Memory::Init();
 	Memory::Init();
+    HW::Init();
 	CoreTiming::Init();
 	CoreTiming::Init();
+    VideoCore::Init(emu_window);
 }
 }
 
 
 void RunLoopFor(int cycles) {
 void RunLoopFor(int cycles) {
@@ -49,9 +53,10 @@ void RunLoopUntil(u64 global_cycles) {
 }
 }
 
 
 void Shutdown() {
 void Shutdown() {
+    Core::Shutdown();
+    HW::Shutdown();
+    VideoCore::Shutdown();
 	g_ctr_file_system.Shutdown();
 	g_ctr_file_system.Shutdown();
 }
 }
 
 
-
-
 } // namespace
 } // namespace

+ 19 - 0
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})

+ 132 - 0
src/video_core/src/renderer_base.h

@@ -0,0 +1,132 @@
+/**
+ * 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() {
+    }
+
+    /// 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
+     * @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;
+
+    /// 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
+     */
+    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;
+
+    // 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);
+};

+ 461 - 0
src/video_core/src/renderer_opengl/renderer_opengl.cpp

@@ -0,0 +1,461 @@
+/**
+ * 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 "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_));  
+    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;
+
+    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() {
+
+    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, resolution_width_, resolution_height_);
+    RenderXFB(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();
+}
+
+/** 
+ * 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::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, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight);
+
+    // Render source is our EFB
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, xfb_top_);
+    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);
+
+    // 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
+ * @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, VideoCore::kScreenTopWidth, 
+            VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight);
+
+        // Generate depth buffer storage
+        glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth_buffers_[i]);
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, VideoCore::kScreenTopWidth, 
+            VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight);
+
+        // 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)
+
+    // 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
+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, 
+        resolution_width_, resolution_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() {
+}

+ 153 - 0
src/video_core/src/renderer_opengl/renderer_opengl.h

@@ -0,0 +1,153 @@
+/**
+ * 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();
+
+    /** 
+     * 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
+     */
+    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_;
+
+    // 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);
+};

+ 66 - 0
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

+ 83 - 0
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

+ 88 - 0
src/video_core/src/video_core.cpp

@@ -0,0 +1,88 @@
+/**
+ * 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"
+#include "renderer_base.h"
+#include "renderer_opengl/renderer_opengl.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_emu_window->MakeCurrent();
+    g_renderer = new RendererOpenGL();
+    g_renderer->SetWindow(g_emu_window);
+    g_renderer->Init();
+
+    g_current_frame = 0;
+
+    NOTICE_LOG(VIDEO, "initialized ok");
+}
+
+/// Shutdown the video core
+void Shutdown() {
+    delete g_renderer;
+}
+
+} // namespace

+ 59 - 0
src/video_core/src/video_core.h

@@ -0,0 +1,59 @@
+/*!
+ * 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 {
+
+// 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();
+
+/// Initialize the video core
+void Init(EmuWindow* emu_window);
+
+/// Shutdown the video core
+void Shutdown();
+
+} // namespace

+ 131 - 0
src/video_core/video_core.vcxproj

@@ -0,0 +1,131 @@
+<?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\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>
+  <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>

+ 26 - 0
src/video_core/video_core.vcxproj.filters

@@ -0,0 +1,26 @@
+<?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" />
+    <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>

+ 1 - 1
vsprops/base.props

@@ -12,7 +12,7 @@
       <StructMemberAlignment>16Bytes</StructMemberAlignment>
       <StructMemberAlignment>16Bytes</StructMemberAlignment>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
       <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>
       </PreprocessorDefinitions>
       </PreprocessorDefinitions>
       <RuntimeTypeInfo>false</RuntimeTypeInfo>
       <RuntimeTypeInfo>false</RuntimeTypeInfo>