basic emu workin, now we can work on it yes
This commit is contained in:
parent
57efb162d6
commit
90897bd8d6
|
@ -0,0 +1,10 @@
|
||||||
|
[Window][Debug##Default]
|
||||||
|
Pos=60,60
|
||||||
|
Size=400,400
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][Emulator Status]
|
||||||
|
Pos=156,47
|
||||||
|
Size=370,370
|
||||||
|
Collapsed=0
|
||||||
|
|
Binary file not shown.
222
source/app.d
222
source/app.d
|
@ -6,6 +6,168 @@ import glad.gl.all;
|
||||||
import window;
|
import window;
|
||||||
import imgui;
|
import imgui;
|
||||||
|
|
||||||
|
struct Chip8Status {
|
||||||
|
|
||||||
|
//emu ptr
|
||||||
|
Emulator* run_;
|
||||||
|
Chip8* emu_;
|
||||||
|
|
||||||
|
// mem editor
|
||||||
|
// MemoryEditor mem_editor_;
|
||||||
|
|
||||||
|
// state
|
||||||
|
bool status_menu_ = true;
|
||||||
|
int stack_cur_ = -1;
|
||||||
|
|
||||||
|
void initialize(Emulator* run, Chip8* emu) {
|
||||||
|
this.run_ = run;
|
||||||
|
this.emu_ = emu;
|
||||||
|
} // initialize
|
||||||
|
|
||||||
|
alias Callback = float delegate(int idx, const char** out_text);
|
||||||
|
|
||||||
|
static extern(C) bool doCallback(void* ptr, int idx, const (char**) out_text) {
|
||||||
|
|
||||||
|
auto callback = *(cast(Callback*) ptr);
|
||||||
|
callback(idx, out_text);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} // doCallback;
|
||||||
|
|
||||||
|
void getStackFrame(int idx, const (char**) out_text) {
|
||||||
|
|
||||||
|
static char[32] frame_text;
|
||||||
|
|
||||||
|
import core.stdc.stdio : sprintf;
|
||||||
|
sprintf(frame_text.ptr, "0x%04X", emu_.stack[idx]);
|
||||||
|
|
||||||
|
auto p = frame_text.ptr;
|
||||||
|
auto op = cast(char**)out_text;
|
||||||
|
*op = p;
|
||||||
|
|
||||||
|
} // getStackFrame
|
||||||
|
|
||||||
|
void loadShortcut() {
|
||||||
|
|
||||||
|
import std.file : read;
|
||||||
|
|
||||||
|
auto buf = read("programs/sqrt.ch8");
|
||||||
|
emu_.load(0x200, buf); // do ze load yes, will copy all the data in
|
||||||
|
|
||||||
|
} // loadShortcut
|
||||||
|
|
||||||
|
void saveShortcut() {
|
||||||
|
|
||||||
|
} // saveShortcut
|
||||||
|
|
||||||
|
void debugShortcut() {
|
||||||
|
status_menu_ = !status_menu_;
|
||||||
|
} // debugShortcut
|
||||||
|
|
||||||
|
void redrawShortcut() {
|
||||||
|
emu_.draw_flag = true;
|
||||||
|
} // redrawShortcut
|
||||||
|
|
||||||
|
void toggleRunShortcut() {
|
||||||
|
emu_.run_flag = !emu_.run_flag;
|
||||||
|
} // toggleRunShortcut
|
||||||
|
|
||||||
|
void stepShortcut() {
|
||||||
|
emu_.step();
|
||||||
|
} // stepShortcut
|
||||||
|
|
||||||
|
void quitShortcut() {
|
||||||
|
run_.quit();
|
||||||
|
} // quitShortcut
|
||||||
|
|
||||||
|
void draw() {
|
||||||
|
|
||||||
|
if (!status_menu_) return;
|
||||||
|
|
||||||
|
if (igBeginMainMenuBar()) {
|
||||||
|
|
||||||
|
if (igBeginMenu("Menu")) {
|
||||||
|
|
||||||
|
if (igMenuItem("Load", "CTRL+L")) {
|
||||||
|
loadShortcut();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (igMenuItem("Save", "CTRL+S")) {
|
||||||
|
saveShortcut();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (igMenuItem("Debug", "CTRL+D")) {
|
||||||
|
debugShortcut();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (igMenuItem("Quit", "CTRL+Q")) {
|
||||||
|
quitShortcut();
|
||||||
|
}
|
||||||
|
|
||||||
|
igEndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
igEndMainMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
import std.range : chunks;
|
||||||
|
|
||||||
|
igBegin("Emulator Status");
|
||||||
|
|
||||||
|
igBeginChild("General");
|
||||||
|
igText("OpCode: 0x%04X", emu_.cpu.opcode);
|
||||||
|
igText("PC:");
|
||||||
|
igSameLine();
|
||||||
|
igDragInt("##pc", cast(int*)&emu_.cpu.pc, 0.5f, 0, emu_.ram.length);
|
||||||
|
|
||||||
|
igText("Registers (v0 - vF)");
|
||||||
|
igColumns(4, null, false);
|
||||||
|
|
||||||
|
auto n = 0;
|
||||||
|
foreach (ref chunk; emu_.cpu.v[].chunks(4)) {
|
||||||
|
igText("v%0X 0x%02X ", n, chunk[0]);
|
||||||
|
igText("v%0X 0x%02X ", n+1, chunk[1]);
|
||||||
|
igText("v%0X 0x%02X ", n+2, chunk[2]);
|
||||||
|
igText("v%0X 0x%02X ", n+3, chunk[3]);
|
||||||
|
igNextColumn();
|
||||||
|
n += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
igColumns(1, null, false);
|
||||||
|
|
||||||
|
igText("Index Register: 0x%04X", emu_.cpu.i);
|
||||||
|
igText("Delay Timer: 0x%04X", emu_.cpu.delay_timer);
|
||||||
|
igText("Sound Timer: 0x%04X", emu_.cpu.sound_timer);
|
||||||
|
|
||||||
|
if(igButton("Step")) {
|
||||||
|
emu_.step();
|
||||||
|
}
|
||||||
|
|
||||||
|
igSameLine();
|
||||||
|
|
||||||
|
if (igButton((emu_.run_flag) ? "Stop" : "Run")) {
|
||||||
|
emu_.run_flag = !emu_.run_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
igText("Stack");
|
||||||
|
auto d = &getStackFrame;
|
||||||
|
igPushItemWidth(-1);
|
||||||
|
igListBox2("", &stack_cur_, &doCallback, cast(void*)&d, emu_.stack.length, 16);
|
||||||
|
igPopItemWidth();
|
||||||
|
|
||||||
|
igEndChild();
|
||||||
|
igEnd();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// mem_editor_.draw("Emulator Memory", emu_.ram[]);
|
||||||
|
|
||||||
|
} // draw
|
||||||
|
|
||||||
|
} // Chip8Status
|
||||||
|
|
||||||
string doCapture(string sym, uint start, uint end)(){
|
string doCapture(string sym, uint start, uint end)(){
|
||||||
|
|
||||||
import std.string : format;
|
import std.string : format;
|
||||||
|
@ -79,11 +241,11 @@ struct Chip8 {
|
||||||
bool run_flag;
|
bool run_flag;
|
||||||
bool draw_flag;
|
bool draw_flag;
|
||||||
|
|
||||||
void load(size_t offset, in ubyte[] data) {
|
void load(size_t offset, in void[] data) {
|
||||||
|
|
||||||
assert(offset + data.length < ram.length);
|
assert(offset + data.length < ram.length);
|
||||||
|
|
||||||
ram[offset .. offset + data.length] = data[];
|
ram[offset .. offset + data.length] = cast(ubyte[])data[];
|
||||||
|
|
||||||
} // load
|
} // load
|
||||||
|
|
||||||
|
@ -430,9 +592,9 @@ struct Chip8 {
|
||||||
|
|
||||||
} // step
|
} // step
|
||||||
|
|
||||||
void handle_event(ref SDL_Event ev) {
|
void handleEvent(ref SDL_Event ev) {
|
||||||
|
|
||||||
} // handle_event
|
} // handleEvent
|
||||||
|
|
||||||
void tick() {
|
void tick() {
|
||||||
|
|
||||||
|
@ -456,30 +618,28 @@ struct Chip8 {
|
||||||
|
|
||||||
} // Emulator
|
} // Emulator
|
||||||
|
|
||||||
void load_libs() {
|
void loadLibs() {
|
||||||
|
|
||||||
import glad.gl.loader;
|
|
||||||
|
|
||||||
DerelictSDL2.load();
|
DerelictSDL2.load();
|
||||||
DerelictImgui.load();
|
DerelictImgui.load();
|
||||||
auto status = gladLoadGL();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_libs() {
|
void initLibs() {
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
SDL_GL_LoadLibrary(null);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_imgui() {
|
void setupImgui() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
load_libs();
|
loadLibs();
|
||||||
init_libs();
|
initLibs();
|
||||||
|
|
||||||
Emulator emu;
|
Emulator emu;
|
||||||
emu.create();
|
emu.create();
|
||||||
|
@ -491,22 +651,34 @@ struct Emulator {
|
||||||
|
|
||||||
bool running;
|
bool running;
|
||||||
|
|
||||||
|
// debug
|
||||||
|
Chip8Status status;
|
||||||
|
|
||||||
Window window;
|
Window window;
|
||||||
Chip8 chip8;
|
Imgui imgui;
|
||||||
|
Chip8 emu;
|
||||||
|
|
||||||
void create() {
|
void create() {
|
||||||
|
|
||||||
// create window
|
// create window
|
||||||
window.create_window(640, 480);
|
window.createWindow(640, 480);
|
||||||
|
|
||||||
|
// setup imgui
|
||||||
|
imgui.initialize();
|
||||||
|
imgui.createDeviceObjects();
|
||||||
|
|
||||||
|
// setup debug ui
|
||||||
|
status.initialize(&this, &emu);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_events() {
|
void handleEvents() {
|
||||||
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
|
|
||||||
chip8.handle_event(event);
|
imgui.handleEvent(event);
|
||||||
|
emu.handleEvent(event);
|
||||||
|
|
||||||
switch (event.type) with (SDL_EventType) {
|
switch (event.type) with (SDL_EventType) {
|
||||||
case SDL_QUIT: {
|
case SDL_QUIT: {
|
||||||
|
@ -520,14 +692,14 @@ struct Emulator {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // handle_events
|
} // handleEvents
|
||||||
|
|
||||||
void run() {
|
void run() {
|
||||||
|
|
||||||
running = true;
|
running = true;
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
handle_events();
|
handleEvents();
|
||||||
tick();
|
tick();
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
@ -536,10 +708,24 @@ struct Emulator {
|
||||||
|
|
||||||
void tick() {
|
void tick() {
|
||||||
|
|
||||||
|
emu.tick();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw() {
|
void draw() {
|
||||||
|
|
||||||
|
window.renderClear(0x428bca);
|
||||||
|
imgui.newFrame(window);
|
||||||
|
|
||||||
|
status.draw();
|
||||||
|
|
||||||
|
imgui.endFrame();
|
||||||
|
window.renderPresent();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void quit() {
|
||||||
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
117
source/imgui.d
117
source/imgui.d
|
@ -29,6 +29,10 @@ struct Imgui {
|
||||||
int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
|
int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
|
||||||
uint g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0;
|
uint g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0;
|
||||||
|
|
||||||
|
// imgui input related state
|
||||||
|
bool[3] mouse_buttons_pressed;
|
||||||
|
float scroll_wheel = 0.0f;
|
||||||
|
|
||||||
void initialize() {
|
void initialize() {
|
||||||
|
|
||||||
auto io = igGetIO();
|
auto io = igGetIO();
|
||||||
|
@ -52,23 +56,45 @@ struct Imgui {
|
||||||
io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y;
|
io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y;
|
||||||
io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z;
|
io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z;
|
||||||
|
|
||||||
io.RenderDrawListsFn = bindDelegate(&render_draw_lists);
|
io.RenderDrawListsFn = bindDelegate(&renderDrawLists);
|
||||||
io.SetClipboardTextFn = bindDelegate(&set_clipboard_text);
|
io.SetClipboardTextFn = bindDelegate(&setClipboardText);
|
||||||
io.GetClipboardTextFn = bindDelegate(&get_clipboard_text);
|
io.GetClipboardTextFn = bindDelegate(&getClipboardText);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_font_texture() {
|
void createFontTexture() {
|
||||||
|
|
||||||
|
// build texture atlas
|
||||||
|
auto io = igGetIO();
|
||||||
|
|
||||||
|
ubyte* pixels;
|
||||||
|
int width, height;
|
||||||
|
ImFontAtlas_GetTexDataAsRGBA32(io.Fonts, &pixels, &width, &height, null);
|
||||||
|
|
||||||
|
// upload texture to graphics system
|
||||||
|
GLint last_texture;
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||||
|
glGenTextures(1, &g_FontTexture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, g_FontTexture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
|
// store our identifier
|
||||||
|
ImFontAtlas_SetTexID(io.Fonts, cast(void*)g_FontTexture);
|
||||||
|
|
||||||
|
// restore state
|
||||||
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_device_objects() {
|
void createDeviceObjects() {
|
||||||
|
|
||||||
// backup GL state
|
// backup GL state
|
||||||
GLint last_texture, last_array_buffer, last_vertex_array;
|
GLint last_texture, last_array_buffer, last_vertex_array;
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
if (last_texture != 0) glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
if (last_array_buffer != 0) glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
||||||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
if (last_vertex_array != 0) glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
||||||
|
|
||||||
const GLchar *vertex_shader = q{
|
const GLchar *vertex_shader = q{
|
||||||
#version 330
|
#version 330
|
||||||
|
@ -127,7 +153,7 @@ struct Imgui {
|
||||||
glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(void*)ImDrawVert.uv.offsetof);
|
glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(void*)ImDrawVert.uv.offsetof);
|
||||||
glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, ImDrawVert.sizeof, cast(void*)ImDrawVert.col.offsetof);
|
glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, ImDrawVert.sizeof, cast(void*)ImDrawVert.col.offsetof);
|
||||||
|
|
||||||
create_font_texture();
|
createFontTexture();
|
||||||
|
|
||||||
// restore modified GL state
|
// restore modified GL state
|
||||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||||
|
@ -137,7 +163,7 @@ struct Imgui {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern(C) nothrow
|
extern(C) nothrow
|
||||||
void render_draw_lists(ImDrawData* draw_data) {
|
void renderDrawLists(ImDrawData* draw_data) {
|
||||||
|
|
||||||
// avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
// avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||||
auto io = igGetIO();
|
auto io = igGetIO();
|
||||||
|
@ -183,6 +209,7 @@ struct Imgui {
|
||||||
[ 0.0f, 0.0f, -1.0f, 0.0f ],
|
[ 0.0f, 0.0f, -1.0f, 0.0f ],
|
||||||
[-1.0f, 1.0f, 0.0f, 1.0f ],
|
[-1.0f, 1.0f, 0.0f, 1.0f ],
|
||||||
];
|
];
|
||||||
|
|
||||||
glUseProgram(g_ShaderHandle);
|
glUseProgram(g_ShaderHandle);
|
||||||
glUniform1i(g_AttribLocationTex, 0);
|
glUniform1i(g_AttribLocationTex, 0);
|
||||||
glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
||||||
|
@ -236,36 +263,86 @@ struct Imgui {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern(C) nothrow
|
extern(C) nothrow
|
||||||
const(char)* get_clipboard_text(void* user_data) {
|
const(char)* getClipboardText(void* user_data) {
|
||||||
return SDL_GetClipboardText();
|
return SDL_GetClipboardText();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern(C) nothrow
|
extern(C) nothrow
|
||||||
void set_clipboard_text(void* user_data, const (char)* text) {
|
void setClipboardText(void* user_data, const (char)* text) {
|
||||||
SDL_SetClipboardText(text);
|
SDL_SetClipboardText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void new_frame(ref Window win) {
|
void newFrame(ref Window win) {
|
||||||
|
|
||||||
|
auto io = igGetIO();
|
||||||
|
|
||||||
|
int win_w, win_h;
|
||||||
|
win.window_size(win_w, win_h);
|
||||||
|
|
||||||
|
int fbo_w, fbo_h;
|
||||||
|
win.framebuffer_size(fbo_w, fbo_h);
|
||||||
|
|
||||||
|
io.DisplaySize = ImVec2(win_w, win_h);
|
||||||
|
io.DisplayFramebufferScale = ImVec2(cast(float)fbo_w / win_w, cast(float)fbo_h / win_h);
|
||||||
|
|
||||||
|
int m_x, m_y;
|
||||||
|
win.mouse_pos(m_x, m_y);
|
||||||
|
io.MousePos = ImVec2(cast(float)m_x, cast(float)m_y);
|
||||||
|
|
||||||
|
io.MouseDown[0] = mouse_buttons_pressed[0] || (SDL_GetMouseState(null, null) & SDL_BUTTON_LEFT) != 0;
|
||||||
|
mouse_buttons_pressed[0] = false;
|
||||||
|
|
||||||
|
io.MouseDown[1] = mouse_buttons_pressed[0] || (SDL_GetMouseState(null, null) & SDL_BUTTON_MIDDLE) != 0;
|
||||||
|
mouse_buttons_pressed[1] = false;
|
||||||
|
|
||||||
|
io.MouseDown[2] = mouse_buttons_pressed[2] || (SDL_GetMouseState(null, null) & SDL_BUTTON_RIGHT) != 0;
|
||||||
|
mouse_buttons_pressed[2] = false;
|
||||||
|
|
||||||
|
io.MouseWheel = scroll_wheel;
|
||||||
|
scroll_wheel = 0.0f;
|
||||||
|
|
||||||
|
igNewFrame();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_event(ref SDL_Event ev) {
|
void endFrame() {
|
||||||
|
|
||||||
|
igRender();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleEvent(ref SDL_Event ev) {
|
||||||
|
|
||||||
|
auto io = igGetIO();
|
||||||
|
|
||||||
switch (ev.type) with (SDL_EventType) {
|
switch (ev.type) with (SDL_EventType) {
|
||||||
|
|
||||||
case SDL_TEXTINPUT:
|
case SDL_TEXTINPUT:
|
||||||
|
ImGuiIO_AddInputCharacter(cast(ushort)ev.text.text[0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_KEYDOWN, SDL_KEYUP:
|
||||||
|
|
||||||
|
auto mods = ev.key.keysym.mod;
|
||||||
|
io.KeyCtrl = (mods & KMOD_CTRL) != 0;
|
||||||
|
io.KeyShift = (mods & KMOD_SHIFT) != 0;
|
||||||
|
io.KeyAlt = (mods & KMOD_ALT) != 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONUP:
|
|
||||||
|
case SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP:
|
||||||
|
auto btn = ev.button.button;
|
||||||
|
|
||||||
|
if (btn < 4) {
|
||||||
|
mouse_buttons_pressed[btn - 1] = (ev.type == SDL_MOUSEBUTTONDOWN);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_MOUSEWHEEL:
|
case SDL_MOUSEWHEEL:
|
||||||
break;
|
scroll_wheel += ev.wheel.y;
|
||||||
|
|
||||||
case SDL_KEYDOWN:
|
|
||||||
break;
|
|
||||||
case SDL_KEYUP:
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct Window {
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
SDL_GLContext context;
|
SDL_GLContext context;
|
||||||
|
|
||||||
void create_window(int w, int h, const char* title = "Chipd8 Emu") {
|
void createWindow(int w, int h, const char* title = "Chipd8 Emu") {
|
||||||
assert(w > 0, "window width must be > 0");
|
assert(w > 0, "window width must be > 0");
|
||||||
assert(h > 0, "window height must be > 0");
|
assert(h > 0, "window height must be > 0");
|
||||||
|
|
||||||
|
@ -50,46 +50,52 @@ struct Window {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import glad.gl.loader;
|
||||||
|
import std.functional;
|
||||||
|
|
||||||
|
// Check OpenGL properties
|
||||||
|
printf("OpenGL loaded\n");
|
||||||
|
gladLoadGL((const (char)* a) => SDL_GL_GetProcAddress(a));
|
||||||
|
printf("Vendor: %s\n", glGetString(GL_VENDOR));
|
||||||
|
printf("Renderer: %s\n", glGetString(GL_RENDERER));
|
||||||
|
printf("Version: %s\n", glGetString(GL_VERSION));
|
||||||
|
|
||||||
// assign em yes
|
// assign em yes
|
||||||
window = new_win;
|
window = new_win;
|
||||||
context = new_con;
|
context = new_con;
|
||||||
|
|
||||||
atexit(SDL_Quit);
|
atexit(SDL_Quit);
|
||||||
|
|
||||||
} // create_window
|
} // createWindow
|
||||||
|
|
||||||
void handle_event(ref SDL_Event ev) {
|
void handleEvent(ref SDL_Event ev) {
|
||||||
|
|
||||||
}
|
} // handleEvent
|
||||||
|
|
||||||
void render_clear(int colour) {
|
void renderClear(int colour) {
|
||||||
|
|
||||||
auto col = to!GLColor(color, 255);
|
auto col = to!(float[4])(colour, 255);
|
||||||
glClearColor(col[0], col[1], col[2], col[3]);
|
glClearColor(col[0], col[1], col[2], col[3]);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
}
|
} // renderClear
|
||||||
|
|
||||||
void render_present() {
|
void renderPresent() {
|
||||||
|
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(window);
|
||||||
|
|
||||||
|
} // renderPresent
|
||||||
|
|
||||||
|
void mouse_pos(ref int x, ref int y) {
|
||||||
|
SDL_GetMouseState(&x, &y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@property nothrow @nogc {
|
void window_size(ref int w, ref int h) {
|
||||||
|
SDL_GetWindowSize(window, &w, &h);
|
||||||
|
}
|
||||||
|
|
||||||
int[2] window_size() {
|
void framebuffer_size(ref int w, ref int h) {
|
||||||
int w, h;
|
SDL_GL_GetDrawableSize(window, &w, &h);
|
||||||
SDL_GetWindowSize(window, &w, &h);
|
}
|
||||||
return [w, h];
|
|
||||||
}
|
|
||||||
|
|
||||||
int[2] framebuffer_size() {
|
|
||||||
int w, h;
|
|
||||||
SDL_GL_GetDrawableSize(window, &w, &h);
|
|
||||||
return [w, h];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} // Window
|
} // Window
|
Loading…
Reference in New Issue