mirror of
https://github.com/open-goal/jak-project
synced 2026-06-16 06:46:07 -04:00
revamp the gfx+display systems a bit (#739)
* revamp gfx and display systems a bit * Use some fancy c++ pointers instead of just raw pointers * Tidy some things up. * clang * clang 2 * fixes * fixesss * error detection when making display
This commit is contained in:
@@ -49,6 +49,13 @@
|
||||
"name" : "Run - Runtime (with kernel)",
|
||||
"args" : [ "-fakeiso", "-debug", "-v", "-nodisplay" ]
|
||||
},
|
||||
{
|
||||
"type" : "default",
|
||||
"project" : "CMakeLists.txt",
|
||||
"projectTarget" : "gk.exe (bin\\gk.exe)",
|
||||
"name" : "Run - Runtime (with kernel + display)",
|
||||
"args" : [ "-fakeiso", "-debug", "-v" ]
|
||||
},
|
||||
{
|
||||
"type" : "default",
|
||||
"project" : "CMakeLists.txt",
|
||||
|
||||
@@ -73,6 +73,7 @@ set(RUNTIME_SOURCE
|
||||
overlord/stream.cpp
|
||||
graphics/gfx.cpp
|
||||
graphics/display.cpp
|
||||
graphics/pipelines/opengl.cpp
|
||||
system/vm/dmac.cpp
|
||||
system/vm/vm.cpp)
|
||||
|
||||
|
||||
+112
-35
@@ -4,51 +4,128 @@
|
||||
*/
|
||||
|
||||
#include "display.h"
|
||||
#include "gfx.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
|
||||
namespace Display {
|
||||
/* ****************************** */
|
||||
/* Internal functions */
|
||||
/* ****************************** */
|
||||
|
||||
GLFWwindow* display = NULL;
|
||||
namespace {
|
||||
|
||||
void InitDisplay(int width, int height, const char* title, GLFWwindow*& d) {
|
||||
if (d) {
|
||||
lg::warn("InitDisplay has already created a display window");
|
||||
return;
|
||||
}
|
||||
|
||||
// request OpenGL 3.0 (placeholder)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
d = glfwCreateWindow(width, height, title, NULL, NULL);
|
||||
|
||||
if (!d) {
|
||||
lg::error("InitDisplay failed - Could not create display window");
|
||||
return;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(d);
|
||||
if (!gladLoadGL()) {
|
||||
lg::error("GL init fail");
|
||||
KillDisplay(d);
|
||||
return;
|
||||
}
|
||||
|
||||
// enable vsync by default
|
||||
glfwSwapInterval(1);
|
||||
|
||||
lg::debug("init display #x{}", (uintptr_t)d);
|
||||
bool renderer_is_correct(const GfxRendererModule* renderer, GfxPipeline pipeline) {
|
||||
return renderer->pipeline == pipeline;
|
||||
}
|
||||
|
||||
void KillDisplay(GLFWwindow*& d) {
|
||||
lg::debug("kill display #x{}", (uintptr_t)d);
|
||||
if (!d) {
|
||||
lg::warn("KillDisplay called when no display was available");
|
||||
void set_main_display(std::shared_ptr<GfxDisplay> display) {
|
||||
if (Display::g_displays.size() > 0) {
|
||||
Display::g_displays[0] = display;
|
||||
} else {
|
||||
Display::g_displays.push_back(display);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/* ****************************** */
|
||||
/* GfxDisplay */
|
||||
/* ****************************** */
|
||||
|
||||
GfxDisplay::GfxDisplay(GLFWwindow* a_window) {
|
||||
set_renderer(GfxPipeline::OpenGL);
|
||||
set_window(a_window);
|
||||
}
|
||||
|
||||
GfxDisplay::~GfxDisplay() {
|
||||
m_renderer->kill_display(this);
|
||||
// window_generic_ptr = nullptr;
|
||||
}
|
||||
|
||||
void GfxDisplay::set_renderer(GfxPipeline pipeline) {
|
||||
if (is_active()) {
|
||||
lg::error("Can't change display's renderer while window exists.");
|
||||
return;
|
||||
}
|
||||
if (m_renderer != nullptr) {
|
||||
lg::error("A display changed renderer unexpectedly.");
|
||||
return;
|
||||
}
|
||||
|
||||
glfwDestroyWindow(d);
|
||||
d = NULL;
|
||||
m_renderer = Gfx::GetRenderer(pipeline);
|
||||
}
|
||||
|
||||
void GfxDisplay::set_window(GLFWwindow* window) {
|
||||
if (!renderer_is_correct(m_renderer, GfxPipeline::OpenGL)) {
|
||||
lg::error("Can't set OpenGL window when using {}", m_renderer->name);
|
||||
return;
|
||||
}
|
||||
if (is_active()) {
|
||||
lg::error("Already have a window. Close window first.");
|
||||
return;
|
||||
}
|
||||
|
||||
this->window_glfw = window;
|
||||
}
|
||||
|
||||
void GfxDisplay::set_title(const char* title) {
|
||||
if (!is_active()) {
|
||||
lg::error("No window to set title `{}`.", title);
|
||||
return;
|
||||
}
|
||||
|
||||
m_title = title;
|
||||
}
|
||||
|
||||
void GfxDisplay::render_graphics() {
|
||||
m_renderer->render_display(this);
|
||||
}
|
||||
|
||||
/* ****************************** */
|
||||
/* DISPLAY */
|
||||
/* ****************************** */
|
||||
|
||||
namespace Display {
|
||||
|
||||
std::vector<std::shared_ptr<GfxDisplay>> g_displays;
|
||||
std::shared_ptr<GfxDisplay> GetMainDisplay() {
|
||||
if (g_displays.size() == 0)
|
||||
return NULL;
|
||||
return g_displays.front()->is_active() ? g_displays.front() : NULL;
|
||||
}
|
||||
|
||||
int InitMainDisplay(int width, int height, const char* title, GfxSettings& settings) {
|
||||
if (GetMainDisplay() != NULL) {
|
||||
lg::warn("InitMainDisplay called when main display already exists.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto display = settings.renderer->make_main_display(width, height, title, settings);
|
||||
if (display == NULL) {
|
||||
lg::error("Failed to make main display.");
|
||||
return 1;
|
||||
}
|
||||
set_main_display(display);
|
||||
}
|
||||
|
||||
void KillDisplay(std::shared_ptr<GfxDisplay> display) {
|
||||
// lg::debug("kill display #x{:x}", (uintptr_t)display);
|
||||
if (!display->is_active()) {
|
||||
lg::warn("display #x{:x} cant be killed because it is not active");
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetMainDisplay() == display) {
|
||||
// killing the main display, kill all children displays too!
|
||||
for (int i = 1; i < g_displays.size(); ++i) {
|
||||
KillDisplay(g_displays.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
// find this display in the list and remove it from there
|
||||
// if everything went right the smart pointer should delete the display.
|
||||
auto this_disp = std::find(g_displays.begin(), g_displays.end(), display);
|
||||
g_displays.erase(this_disp);
|
||||
}
|
||||
|
||||
} // namespace Display
|
||||
|
||||
+38
-11
@@ -5,21 +5,48 @@
|
||||
* Display for graphics. This is the game window, distinct from the runtime console.
|
||||
*/
|
||||
|
||||
#ifndef RUNTIME_DISPLAY_H
|
||||
#define RUNTIME_DISPLAY_H
|
||||
#include "pipelines/opengl.h"
|
||||
#include "gfx.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "opengl.h"
|
||||
// a GfxDisplay class is equivalent to a window that displays stuff. This holds an actual internal
|
||||
// window pointer used by whichever renderer. It also contains functions for setting and
|
||||
// retrieving certain window parameters.
|
||||
class GfxDisplay {
|
||||
const char* m_title;
|
||||
|
||||
const GfxRendererModule* m_renderer = nullptr;
|
||||
|
||||
public:
|
||||
GfxDisplay(GLFWwindow* a_window); // OpenGL window constructor
|
||||
~GfxDisplay(); // destructor - this calls the renderer's function for getting rid of a window,
|
||||
// and we can then get rid of the GfxDisplay itself
|
||||
|
||||
// all kinds of windows for the display
|
||||
union {
|
||||
void* window_generic_ptr = nullptr;
|
||||
GLFWwindow* window_glfw;
|
||||
};
|
||||
|
||||
bool is_active() const { return window_generic_ptr != nullptr; }
|
||||
void set_renderer(GfxPipeline pipeline);
|
||||
void set_window(GLFWwindow* window);
|
||||
void set_title(const char* title);
|
||||
const char* get_title() const { return m_title; }
|
||||
|
||||
void render_graphics();
|
||||
};
|
||||
|
||||
namespace Display {
|
||||
|
||||
// TODO - eventually we might actually want to support having multiple windows and viewpoints
|
||||
// so it would be nice if we didn't end up designing this system such that this MUST be
|
||||
// a single window.
|
||||
extern GLFWwindow* display;
|
||||
// a list of displays. the first one is the "main" display, all others are spectator-like extra
|
||||
// views.
|
||||
extern std::vector<std::shared_ptr<GfxDisplay>> g_displays;
|
||||
|
||||
void InitDisplay(int width, int height, const char* title, GLFWwindow*& d);
|
||||
void KillDisplay(GLFWwindow*& d);
|
||||
int InitMainDisplay(int width, int height, const char* title, GfxSettings& settings);
|
||||
void KillDisplay(std::shared_ptr<GfxDisplay> display);
|
||||
|
||||
std::shared_ptr<GfxDisplay> GetMainDisplay();
|
||||
|
||||
} // namespace Display
|
||||
|
||||
#endif // RUNTIME_DISPLAY_H
|
||||
|
||||
+48
-31
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* @file gfx.cpp
|
||||
* Graphics component for the runtime. Handles some low-level routines.
|
||||
* Graphics component for the runtime. Abstraction layer for the main graphics routines.
|
||||
*/
|
||||
|
||||
#include "gfx.h"
|
||||
@@ -9,62 +9,79 @@
|
||||
#include "game/runtime.h"
|
||||
#include "display.h"
|
||||
|
||||
#include "opengl.h"
|
||||
#include "pipelines/opengl.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// initializes a gfx settings.
|
||||
// TODO save and load from file
|
||||
void InitSettings(GfxSettings& settings) {
|
||||
// use opengl by default for now
|
||||
settings.renderer = Gfx::GetRenderer(GfxPipeline::OpenGL); // Gfx::renderers[0];
|
||||
|
||||
// 1 screen update per frame
|
||||
settings.vsync = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
void GlfwErrorCallback(int err, const char* msg) {
|
||||
lg::error("GLFW ERR {}: " + std::string(msg), err);
|
||||
GfxVertex g_vertices_temp[VERTEX_BUFFER_LENGTH_TEMP];
|
||||
|
||||
GfxSettings g_settings;
|
||||
// const std::vector<const GfxRendererModule*> renderers = {&moduleOpenGL};
|
||||
|
||||
const GfxRendererModule* GetRenderer(GfxPipeline pipeline) {
|
||||
switch (pipeline) {
|
||||
case GfxPipeline::Invalid:
|
||||
lg::error("Requested invalid graphics pipeline!");
|
||||
return NULL;
|
||||
break;
|
||||
case GfxPipeline::OpenGL:
|
||||
return &moduleOpenGL;
|
||||
default:
|
||||
lg::error("Unknown graphics pipeline {}", (u64)pipeline);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
u32 Init() {
|
||||
if (glfwSetErrorCallback(GlfwErrorCallback) != NULL) {
|
||||
lg::warn("glfwSetErrorCallback has been re-set!");
|
||||
}
|
||||
lg::info("GFX Init");
|
||||
// initialize settings
|
||||
InitSettings(g_settings);
|
||||
|
||||
if (!glfwInit()) {
|
||||
lg::error("glfwInit error");
|
||||
if (g_settings.renderer->init()) {
|
||||
lg::error("Gfx::Init error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (g_main_thread_id != std::this_thread::get_id()) {
|
||||
lg::warn("ran Gfx::Init outside main thread. Init display elsewhere?");
|
||||
} else {
|
||||
Display::InitDisplay(640, 480, "testy", Display::display);
|
||||
Display::InitMainDisplay(640, 480, "testy", g_settings);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Loop(std::function<bool()> f) {
|
||||
lg::info("GFX Loop");
|
||||
while (f()) {
|
||||
// run display-specific things
|
||||
if (Display::display) {
|
||||
// check if we have a display
|
||||
if (Display::GetMainDisplay()) {
|
||||
// lg::debug("run display");
|
||||
glfwMakeContextCurrent(Display::display);
|
||||
|
||||
// render graphics
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glfwSwapBuffers(Display::display);
|
||||
|
||||
// poll events TODO integrate input with cpad
|
||||
glfwPollEvents();
|
||||
|
||||
// exit if display window was closed
|
||||
if (glfwWindowShouldClose(Display::display)) {
|
||||
// Display::KillDisplay(Display::display);
|
||||
MasterExit = 2;
|
||||
}
|
||||
Display::GetMainDisplay()->render_graphics();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 Exit() {
|
||||
lg::debug("gfx exit");
|
||||
Display::KillDisplay(Display::display);
|
||||
glfwTerminate();
|
||||
glfwSetErrorCallback(NULL);
|
||||
lg::info("GFX Exit");
|
||||
Display::KillDisplay(Display::GetMainDisplay());
|
||||
g_settings.renderer->exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+51
-7
@@ -2,23 +2,67 @@
|
||||
|
||||
/*!
|
||||
* @file gfx.h
|
||||
* Graphics component for the runtime. Handles some low-level routines.
|
||||
* Graphics component for the runtime. Abstraction layer for the main graphics routines.
|
||||
*/
|
||||
|
||||
#ifndef RUNTIME_GFX_H
|
||||
#define RUNTIME_GFX_H
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "common/common_types.h"
|
||||
#include "display.h"
|
||||
#include "game/kernel/kboot.h"
|
||||
|
||||
// forward declarations
|
||||
struct GfxSettings;
|
||||
class GfxDisplay;
|
||||
|
||||
// enum for rendering pipeline
|
||||
enum class GfxPipeline { Invalid = 0, OpenGL };
|
||||
|
||||
// module for the different rendering pipelines
|
||||
struct GfxRendererModule {
|
||||
std::function<int()> init;
|
||||
std::function<std::shared_ptr<GfxDisplay>(int w, int h, const char* title, GfxSettings& settings)>
|
||||
make_main_display;
|
||||
std::function<void(GfxDisplay* display)> kill_display;
|
||||
std::function<void(GfxDisplay* display)> render_display;
|
||||
std::function<void()> exit;
|
||||
|
||||
GfxPipeline pipeline;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
// store settings related to the gfx systems
|
||||
struct GfxSettings {
|
||||
const GfxRendererModule* renderer; // which rendering pipeline to use.
|
||||
|
||||
int vsync; // (temp) number of screen update per frame
|
||||
};
|
||||
|
||||
// struct for a single vertex. this should in theory be renderer-agnostic
|
||||
struct GfxVertex {
|
||||
// x y z
|
||||
float x, y, z;
|
||||
|
||||
// rgba or the full u32 thing.
|
||||
union {
|
||||
u32 rgba;
|
||||
struct {
|
||||
u8 r, g, b, a;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
static constexpr int VERTEX_BUFFER_LENGTH_TEMP = 4096;
|
||||
extern GfxVertex g_vertices_temp[VERTEX_BUFFER_LENGTH_TEMP];
|
||||
|
||||
extern GfxSettings g_settings;
|
||||
// extern const std::vector<const GfxRendererModule*> renderers;
|
||||
|
||||
const GfxRendererModule* GetRenderer(GfxPipeline pipeline);
|
||||
|
||||
u32 Init();
|
||||
void Loop(std::function<bool()> f);
|
||||
u32 Exit();
|
||||
|
||||
} // namespace Gfx
|
||||
|
||||
#endif // RUNTIME_GFX_H
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
* @file opengl.h
|
||||
* OpenGL includes.
|
||||
*/
|
||||
|
||||
#ifndef RUNTIME_OPENGL_H
|
||||
#define RUNTIME_OPENGL_H
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#endif // RUNTIME_OPENGL_H
|
||||
@@ -0,0 +1,127 @@
|
||||
/*!
|
||||
* @file opengl.cpp
|
||||
* Lower-level OpenGL implementation.
|
||||
*/
|
||||
|
||||
#include "opengl.h"
|
||||
|
||||
#include "game/graphics/gfx.h"
|
||||
#include "game/graphics/display.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
#include <memory>
|
||||
|
||||
namespace {
|
||||
|
||||
void SetDisplayCallbacks(GLFWwindow* d) {
|
||||
glfwSetKeyCallback(d, [](GLFWwindow* window, int key, int scancode, int action, int mods) {
|
||||
if (action == GlfwKeyAction::Press) {
|
||||
lg::debug("KEY PRESS: key: {} scancode: {} mods: {:X}", key, scancode, mods);
|
||||
} else if (action == GlfwKeyAction::Release) {
|
||||
lg::debug("KEY RELEASE: key: {} scancode: {} mods: {:X}", key, scancode, mods);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ErrorCallback(int err, const char* msg) {
|
||||
lg::error("GLFW ERR {}: " + std::string(msg), err);
|
||||
}
|
||||
|
||||
bool HasError() {
|
||||
return glfwGetError(NULL) != GLFW_NO_ERROR;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
static bool gl_inited = false;
|
||||
static int gl_init() {
|
||||
if (glfwSetErrorCallback(ErrorCallback) != NULL) {
|
||||
lg::warn("glfwSetErrorCallback has been re-set!");
|
||||
}
|
||||
|
||||
if (glfwInit() == GLFW_FALSE) {
|
||||
lg::error("glfwInit error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// request OpenGL 3.0 (placeholder)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gl_exit() {
|
||||
glfwTerminate();
|
||||
glfwSetErrorCallback(NULL);
|
||||
}
|
||||
|
||||
static std::shared_ptr<GfxDisplay> gl_make_main_display(int width,
|
||||
int height,
|
||||
const char* title,
|
||||
GfxSettings& settings) {
|
||||
GLFWwindow* window = glfwCreateWindow(width, height, title, NULL, NULL);
|
||||
|
||||
if (!window) {
|
||||
lg::error("gl_make_main_display failed - Could not create display window");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
if (!gl_inited && !gladLoadGL()) {
|
||||
lg::error("GL init fail");
|
||||
return NULL;
|
||||
}
|
||||
gl_inited = true;
|
||||
|
||||
// enable vsync by default
|
||||
// glfwSwapInterval(1);
|
||||
glfwSwapInterval(settings.vsync);
|
||||
|
||||
SetDisplayCallbacks(window);
|
||||
|
||||
if (HasError()) {
|
||||
lg::error("gl_make_main_display error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::shared_ptr<GfxDisplay> display = std::make_shared<GfxDisplay>(window);
|
||||
// lg::debug("init display #x{:x}", (uintptr_t)display);
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
static void gl_kill_display(GfxDisplay* display) {
|
||||
glfwDestroyWindow(display->window_glfw);
|
||||
}
|
||||
|
||||
static void gl_render_display(GfxDisplay* display) {
|
||||
GLFWwindow* window = display->window_glfw;
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
// render graphics
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
|
||||
// poll events TODO integrate input with cpad
|
||||
glfwPollEvents();
|
||||
|
||||
// exit if display window was closed
|
||||
if (glfwWindowShouldClose(window)) {
|
||||
// Display::KillDisplay(window);
|
||||
MasterExit = 2;
|
||||
}
|
||||
}
|
||||
|
||||
const GfxRendererModule moduleOpenGL = {
|
||||
gl_init, // init
|
||||
gl_make_main_display, // make_main_display
|
||||
gl_kill_display, // kill_display
|
||||
gl_render_display, // render_display
|
||||
gl_exit, // exit
|
||||
GfxPipeline::OpenGL, // pipeline
|
||||
"OpenGL 3.0" // name
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
* @file opengl.h
|
||||
* OpenGL includes.
|
||||
*/
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "game/graphics/gfx.h"
|
||||
|
||||
enum GlfwKeyAction {
|
||||
Release = GLFW_RELEASE, // falling edge of key press
|
||||
Press = GLFW_PRESS, // rising edge of key press
|
||||
Repeat = GLFW_REPEAT // repeated input on hold e.g. when typing something
|
||||
};
|
||||
|
||||
extern const GfxRendererModule moduleOpenGL;
|
||||
@@ -48,9 +48,7 @@
|
||||
#include "game/overlord/stream.h"
|
||||
#include "game/overlord/sbank.h"
|
||||
|
||||
#include "game/graphics/opengl.h"
|
||||
#include "game/graphics/gfx.h"
|
||||
#include "game/graphics/display.h"
|
||||
|
||||
#include "game/system/vm/vm.h"
|
||||
#include "game/system/vm/dmac.h"
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
* Not meant to work as a full DMAC emulator, just enough to inspect DMA packets.
|
||||
*/
|
||||
|
||||
#ifndef VM_DMAC_H
|
||||
#define VM_DMAC_H
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "game/kernel/Ptr.h"
|
||||
|
||||
@@ -73,5 +70,3 @@ static_assert(alignof(DmaChannelRegisters) == 0x10, "DmaChannelRegisters unalign
|
||||
void dmac_init_globals();
|
||||
|
||||
} // namespace VM
|
||||
|
||||
#endif // VM_DMAC_H
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
* Not an emulator!
|
||||
*/
|
||||
|
||||
#ifndef VM_H
|
||||
#define VM_H
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace VM {
|
||||
@@ -33,5 +30,3 @@ void unsubscribe_component();
|
||||
u64 get_vm_ptr(u32 ptr);
|
||||
|
||||
} // namespace VM
|
||||
|
||||
#endif // VM_H
|
||||
|
||||
Reference in New Issue
Block a user