diff --git a/.vscode/launch.json b/.vscode/launch.json index 7e005d7..1b6bf0a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,10 +1,58 @@ { "configurations": [ + { + "name": "(gdb, Linux) Launch hello.elf", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/src/hello.elf", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + }, + { + "name": "(gdb, Linux) Launch gl.elf", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/src/gl.elf", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + }, { "name": "(gdb) Launch gl.elf", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/build/gl.elf", + "program": "${workspaceFolder}/build/src/gl.elf", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", @@ -14,7 +62,7 @@ "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress": "localhost:3263", "debugServerPath": "/usr/bin/flycast", - "debugServerArgs": "${workspaceFolder}/build/gl.elf", + "debugServerArgs": "${workspaceFolder}/build/src/gl.elf", "setupCommands": [ { "description": "Enable pretty-printing for gdb", @@ -33,7 +81,7 @@ "name": "(gdb) Launch cube.elf", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/build/cube.elf", + "program": "${workspaceFolder}/build/src/cube.elf", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", @@ -43,7 +91,7 @@ "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress": "localhost:3263", "debugServerPath": "/usr/bin/flycast", - "debugServerArgs": "${workspaceFolder}/build/cube.elf", + "debugServerArgs": "${workspaceFolder}/build/src/cube.elf", "setupCommands": [ { "description": "Enable pretty-printing for gdb", @@ -62,7 +110,7 @@ "name": "(gdb, lxdream-nitro) Launch cube.elf", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/build/cube.elf", + "program": "${workspaceFolder}/build/src/cube.elf", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", @@ -72,7 +120,36 @@ "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", "miDebuggerServerAddress": "localhost:3263", "debugServerPath": "/home/user/Downloads/lxdream-nitro/builddir/lxdream-nitro", - "debugServerArgs": "-d -g 3263 -e ${workspaceFolder}/build/cube.elf", + "debugServerArgs": "-d -g 3263 -e ${workspaceFolder}/build/src/cube.elf", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set SuperH architechture", + "text": "set architecture sh4" + } + ], + "avoidWindowsConsoleRedirection": false, + "internalConsoleOptions": "openOnSessionStart" + }, + { + "name": "(gdb, lxdream-nitro) Launch gl.elf", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/src/gl.elf", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", + "miDebuggerServerAddress": "localhost:3263", + "debugServerPath": "/home/user/Downloads/lxdream-nitro/builddir/lxdream-nitro", + "debugServerArgs": "-d -g 3263 -e ${workspaceFolder}/build/src/gl.elf", "setupCommands": [ { "description": "Enable pretty-printing for gdb", diff --git a/meson.build b/meson.build index a79a5f4..40af1cc 100644 --- a/meson.build +++ b/meson.build @@ -1,40 +1,5 @@ project('dreamcast-opengl', 'c', 'cpp', default_options: ['cpp_std=c++20']) -cc = meson.get_compiler('c') -kosinc = include_directories('/opt/toolchains/dc/kos/include') -koskernelinc = include_directories('/opt/toolchains/dc/kos/kernel/arch/dreamcast/include') -kosaddonsinc = include_directories('/opt/toolchains/dc/kos/addons/include') -kosportsinc = include_directories('/opt/toolchains/dc/kos-ports/include') - -GL = cc.find_library('GL', required: true) -math = cc.find_library('m', required: true) -stb_image = cc.find_library('stb_image', required: true) subdir('romdisk') -tinyobjloader = subproject('tinyobjloader') -tinyobjloader_dep = tinyobjloader.get_variable('tinyobjloader_dep') -# pcx = cc.find_library('pcx', required: true) -# kosutils = cc.find_library('kosutils', required: true) - -deps = [ - GL, - math, - stb_image, - tinyobjloader_dep -] - -incdirs = [ - kosinc, - koskernelinc, - kosaddonsinc, - kosportsinc -] - -engine = static_library('engine', ['engine.cc'], dependencies: deps, include_directories: incdirs) -engine_dep = declare_dependency(link_with: engine, include_directories: incdirs) - -deps += [engine_dep] - -executable('hello.elf', ['hello.cc'], dependencies: deps, include_directories: incdirs) -executable('gl.elf', ['gl.cc'], dependencies: deps, include_directories: incdirs) -executable('cube.elf', ['cube.cc', romdsk_o], dependencies: deps, include_directories: incdirs) +subdir('src') diff --git a/romdisk/cube.mtl b/romdisk/cube.mtl index 763e0ab..7b389ea 100644 --- a/romdisk/cube.mtl +++ b/romdisk/cube.mtl @@ -1,2 +1,12 @@ # Blender 4.0.2 MTL File: 'None' # www.blender.org + +newmtl Material.002 +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.033988 0.604769 0.801009 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 diff --git a/romdisk/cube.obj b/romdisk/cube.obj index ba883db..953ec95 100644 --- a/romdisk/cube.obj +++ b/romdisk/cube.obj @@ -31,6 +31,7 @@ vt 0.875000 0.500000 vt 0.625000 1.000000 vt 0.875000 0.750000 s 0 +usemtl Material.002 f 2/1/1 3/2/1 1/3/1 f 4/4/2 7/5/2 3/2/2 f 8/6/3 5/7/3 7/5/3 diff --git a/cube.cc b/src/cube.cc similarity index 71% rename from cube.cc rename to src/cube.cc index 1064663..961fcef 100644 --- a/cube.cc +++ b/src/cube.cc @@ -1,12 +1,21 @@ +#ifdef _arch_dreamcast #include #include #include #include #include +#else +#define STB_IMAGE_IMPLEMENTATION +#include +#include +#include +#endif + #include #include -#include "engine.hh" +#include +#include "engine/engine.hh" class Cube : public Engine { unsigned int texture; @@ -31,10 +40,14 @@ void Cube::model() { for (size_t s = 0; s < shapes.size(); s++) { // Loop over faces(polygon) size_t index_offset = 0; + std::vector vertexes {}; + std::vector normals {}; + std::vector textureCoords {}; + for (size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) { size_t fv = size_t(shapes[s].mesh.num_face_vertices[f]); - glBegin(GL_TRIANGLES); + // glBegin(GL_TRIANGLES); // Loop over vertices in the face. for (size_t v = 0; v < fv; v++) { // access to vertex @@ -45,8 +58,10 @@ void Cube::model() { attrib.vertices[3 * size_t(idx.vertex_index) + 1]; tinyobj::real_t vz = attrib.vertices[3 * size_t(idx.vertex_index) + 2]; - glVertex3f(vx, vy, vz); - drawCalls += 1; + Vector3 vertex = {vx, vy, vz}; + vertexes.push_back(vertex); + // glVertex3f(vx, vy, vz); + // drawCalls += 1; // Check if `normal_index` is zero or positive. negative = no @@ -58,8 +73,12 @@ void Cube::model() { attrib.normals[3 * size_t(idx.normal_index) + 1]; tinyobj::real_t nz = attrib.normals[3 * size_t(idx.normal_index) + 2]; - glNormal3f(nx, ny, nz); - drawCalls += 1; + Vector3 normal = {nx, ny, nz}; + normals.push_back(normal); + // glNormal3f(nx, ny, nz); + // drawCalls += 1; + } else { + normals.push_back(Engine::Vector3::zero()); } // Check if `texcoord_index` is zero or positive. negative = no @@ -69,14 +88,27 @@ void Cube::model() { attrib.texcoords[2 * size_t(idx.texcoord_index) + 0]; tinyobj::real_t ty = attrib.texcoords[2 * size_t(idx.texcoord_index) + 1]; - glTexCoord2f(tx, ty); - drawCalls += 1; + Vector3 textureCoord = {tx, ty, 0}; + textureCoords.push_back(textureCoord); + // glTexCoord2f(tx, ty); + // drawCalls += 1; + } else { + textureCoords.push_back(Vector3::zero()); } } index_offset += fv; - glEnd(); + // glEnd(); } + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, &vertexes[0]); + glNormalPointer(GL_FLOAT, 0, &normals[0]); + glTexCoordPointer(2, GL_FLOAT, 0, &textureCoords[0]); + glDrawArrays(GL_TRIANGLES, 0, vertexes.size()); + // glDrawElements(GL_TRIANGLES, shapes[s].mesh.indices.size(), GL_UNSIGNED_INT, &shapes[s].mesh.indices[0]); + drawCalls += 1; } printf("Draw Calls: %i\n", drawCalls); drawCalls = 0; @@ -102,11 +134,10 @@ void Cube::displayStuff() { glTranslatef(0.0f, 0.0f, -5.0f); glRotatef(90, 0.0f, 1.0f, 0.5f); model(); - glKosSwapBuffers(); + SwapBuffers(); } void Cube::initScreen() { - glKosInit(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -128,7 +159,9 @@ void Cube::initScreen() { if (data) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + #ifdef _arch_dreamcast glGenerateMipmap(GL_TEXTURE_2D); + #endif } else { printf("Texture failed to load.\n"); } diff --git a/src/engine/controller/controller.hh b/src/engine/controller/controller.hh new file mode 100644 index 0000000..7a5bbda --- /dev/null +++ b/src/engine/controller/controller.hh @@ -0,0 +1,24 @@ +#ifndef CONTROLLER_HH +#define CONTROLLER_HH +class Controller { + public: + enum Button { + A = (1 << 0), + B = (1 << 1), + X = (1 << 2), + Y = (1 << 3), + DPAD_UP = (1 << 4), + DPAD_DOWN = (1 << 5), + DPAD_LEFT = (1 << 6), + DPAD_RIGHT = (1 << 7) + }; + virtual bool InitializeController() { return false; }; + virtual void PollController(){}; + virtual bool IsButtonPressed(Button button) { return 0; }; + virtual float GetLeftJoystickXAxis() { return 0.0; }; + virtual float GetLeftJoystickYAxis() { return 0.0; }; + + protected: + virtual int GetButtonMask(Button button) { return 0; } +}; +#endif diff --git a/src/engine/controller/dreamcastController.cc b/src/engine/controller/dreamcastController.cc new file mode 100644 index 0000000..c8393b1 --- /dev/null +++ b/src/engine/controller/dreamcastController.cc @@ -0,0 +1,54 @@ +#include "dreamcastController.hh" +#include "controller.hh" + +DreamcastController::DreamcastController() { +} + +bool DreamcastController::InitializeController() { + controller = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); + if (this->controller) { + controller_state = (cont_state_t*)maple_dev_status(controller); + return true; + } else { + controller = nullptr; + return false; + } +} + +void DreamcastController::PollController() { + controller_state = (cont_state_t*)maple_dev_status(controller); +} + +bool DreamcastController::IsButtonPressed(Button button) { + return controller_state->buttons & GetButtonMask(button); +} + +float DreamcastController::GetLeftJoystickXAxis() { + return (controller_state->joyx / 127.0f); +} + +float DreamcastController::GetLeftJoystickYAxis() { + return (controller_state->joyy / 127.0f); +} + +int DreamcastController::GetButtonMask(Button button) { + switch (button) { + case Button::A: + return CONT_A; + case Button::B: + return CONT_B; + case Button::X: + return CONT_X; + case Button::Y: + return CONT_Y; + case Button::DPAD_UP: + return CONT_DPAD_UP; + case Button::DPAD_DOWN: + return CONT_DPAD_DOWN; + case Button::DPAD_LEFT: + return CONT_DPAD_LEFT; + case Button::DPAD_RIGHT: + return CONT_DPAD_RIGHT; + } + return 0; +} diff --git a/src/engine/controller/dreamcastController.hh b/src/engine/controller/dreamcastController.hh new file mode 100644 index 0000000..e8c47a0 --- /dev/null +++ b/src/engine/controller/dreamcastController.hh @@ -0,0 +1,18 @@ +#ifndef DREAMCAST_CONTROLLER_HH +#define DREAMCAST_CONTROLLER_HH +#include + +#include "controller.hh" +class DreamcastController : public Controller { + public: + DreamcastController(); + bool InitializeController() override; + void PollController() override; + bool IsButtonPressed(Button button) override; + float GetLeftJoystickXAxis() override; + float GetLeftJoystickYAxis() override; + int GetButtonMask(Button button) override; + maple_device_t* controller = nullptr; + cont_state_t* controller_state = nullptr; +}; +#endif diff --git a/src/engine/controller/linuxController.cc b/src/engine/controller/linuxController.cc new file mode 100644 index 0000000..bffd309 --- /dev/null +++ b/src/engine/controller/linuxController.cc @@ -0,0 +1,48 @@ +#include "linuxController.hh" + +#include + +bool LinuxController::InitializeController() { + if (glfwJoystickIsGamepad(GLFW_JOYSTICK_1)) { + glfwGetGamepadState(GLFW_JOYSTICK_1, &controllerState); + return true; + } + return false; +} + +void LinuxController::PollController() { + glfwGetGamepadState(GLFW_JOYSTICK_1, &controllerState); +} + +bool LinuxController::IsButtonPressed(Button button) { + return controllerState.buttons[GetButtonMask(button)]; +} + +float LinuxController::GetLeftJoystickXAxis() { + return controllerState.axes[GLFW_GAMEPAD_AXIS_LEFT_X]; +} + +float LinuxController::GetLeftJoystickYAxis() { + return controllerState.axes[GLFW_GAMEPAD_AXIS_LEFT_Y]; +} + +int LinuxController::GetButtonMask(Button button) { + switch (button) { + case Button::A: + return GLFW_GAMEPAD_BUTTON_A; + case Button::B: + return GLFW_GAMEPAD_BUTTON_B; + case Button::X: + return GLFW_GAMEPAD_BUTTON_X; + case Button::Y: + return GLFW_GAMEPAD_BUTTON_Y; + case Button::DPAD_UP: + return GLFW_GAMEPAD_BUTTON_DPAD_UP; + case Button::DPAD_DOWN: + return GLFW_GAMEPAD_BUTTON_DPAD_DOWN; + case Button::DPAD_LEFT: + return GLFW_GAMEPAD_BUTTON_DPAD_LEFT; + case Button::DPAD_RIGHT: + return GLFW_GAMEPAD_BUTTON_DPAD_RIGHT; + } +} diff --git a/src/engine/controller/linuxController.hh b/src/engine/controller/linuxController.hh new file mode 100644 index 0000000..49f55d9 --- /dev/null +++ b/src/engine/controller/linuxController.hh @@ -0,0 +1,17 @@ +#ifndef LINUX_CONTROLLER_HH +#define LINUX_CONTROLLER_HH +#include "controller.hh" +#include + +class LinuxController : public Controller { + public: + bool InitializeController() override; + void PollController() override; + bool IsButtonPressed(Button button) override; + float GetLeftJoystickXAxis() override; + float GetLeftJoystickYAxis() override; + int GetButtonMask(Button button) override; + GLFWgamepadstate controllerState; +}; + +#endif diff --git a/src/engine/controller/meson.build b/src/engine/controller/meson.build new file mode 100644 index 0000000..ba0762d --- /dev/null +++ b/src/engine/controller/meson.build @@ -0,0 +1,12 @@ +sources = [] +incdirs = include_directories('.') + +if host_machine.system() == 'dreamcast' + sources += 'dreamcastController.cc' +endif + +if host_machine.system() == 'linux' + sources += 'linuxController.cc' +endif + +controller = static_library('controller', sources) diff --git a/src/engine/dreamcastEngine.cc b/src/engine/dreamcastEngine.cc new file mode 100644 index 0000000..194e18a --- /dev/null +++ b/src/engine/dreamcastEngine.cc @@ -0,0 +1,24 @@ +#ifdef _arch_dreamcast +#include "dreamcastEngine.hh" +#include +#include +#include "controller/dreamcastController.hh" + +void DreamcastEngine::initializeEngine() { + glKosInit(); + // printSystemInformation(); +} + +void DreamcastEngine::initializeController() { + DreamcastController* dreamCont = new DreamcastController; + if (dreamCont->InitializeController()) { + controller = dreamCont; + } else { + throw std::runtime_error("Can't initialize the controller."); + } +} + +void DreamcastEngine::SwapBuffers() { + glKosSwapBuffers(); +} +#endif diff --git a/src/engine/dreamcastEngine.hh b/src/engine/dreamcastEngine.hh new file mode 100644 index 0000000..9a1830e --- /dev/null +++ b/src/engine/dreamcastEngine.hh @@ -0,0 +1,10 @@ +#ifndef DREAMCAST_ENGINE_HH +#define DREAMCAST_ENGINE_HH +#include "nativeEngine.hh" + +class DreamcastEngine : public NativeEngine { + void initializeController() override; + void initializeEngine() override; + void SwapBuffers() override; +}; +#endif diff --git a/engine.cc b/src/engine/engine.cc similarity index 71% rename from engine.cc rename to src/engine/engine.cc index 1eab9c3..46379ff 100644 --- a/engine.cc +++ b/src/engine/engine.cc @@ -2,12 +2,34 @@ #include "engine.hh" +#ifdef _arch_dreamcast #include -#include +#include "dreamcastEngine.hh" +#else +#include "linuxEngine.hh" +#endif #include #include +void Engine::initializeEngine() { + #ifdef _arch_dreamcast + engine = new DreamcastEngine; + #else + engine = new LinuxEngine; + #endif + engine->initializeEngine(); + initScreen(); + controller = engine->controller; +} + +void Engine::initializeController() { + engine->initializeController(); +} +void Engine::SwapBuffers() { + engine->SwapBuffers(); +} + void Engine::initScreen() { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glViewport(0, 0, 640, 480); @@ -25,12 +47,6 @@ void Engine::printSystemInformation() { printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS)); } -void Engine::initializeEngine() { - glKosInit(); - initScreen(); - printSystemInformation(); -} - template void Engine::deltaTimeLoop(T&& callback, struct timeval& beginningOfFrame, struct timeval& endOfFrame) { @@ -52,16 +68,15 @@ void Engine::initializeGameLoop() { } } -void Engine::pressButton(cont_state_t* controller_state, int button, - std::function callback) { - if (controller_state->buttons & button) { +void Engine::pressButton(Controller::Button button, std::function callback) { + if (controller->IsButtonPressed(button)) { if (!(buttonsPressed & button)) { buttonsPressed |= button; callback(); } } else if ((buttonsPressed & button) && - ~(controller_state->buttons & button)) { + !controller->IsButtonPressed(button)) { buttonsPressed &= ~button; } } @@ -71,3 +86,5 @@ void Engine::glVertex3fNormalized(float x, float y, float z) { glVertex3f(x * xSize, y * ySize, z); } + +Engine::Vector3 Engine::Vector3::zero() { return {0, 0, 0}; } diff --git a/engine.hh b/src/engine/engine.hh similarity index 65% rename from engine.hh rename to src/engine/engine.hh index 9533bba..55dc8b8 100644 --- a/engine.hh +++ b/src/engine/engine.hh @@ -1,11 +1,13 @@ #ifndef ENGINE_HH #define ENGINE_HH -#include #include #include +#include "controller/controller.hh" +#include "nativeEngine.hh" + class Engine { protected: static constexpr float microSecond = 0.000001f; @@ -20,17 +22,26 @@ class Engine { virtual void initScreen(); void printSystemInformation(); virtual void gameLoop(){}; - void pressButton(cont_state_t* controller_state, int button, - std::function callback); + void pressButton(Controller::Button button, std::function callback); void glVertex3fNormalized(float x, float y, float z); + void SwapBuffers(); + Controller* controller = nullptr; private: template void deltaTimeLoop(T&& callback, struct timeval& beginningOfFrame, struct timeval& endOfFrame); + NativeEngine* engine = nullptr; public: + void initializeController(); void initializeEngine(); void initializeGameLoop(); + struct Vector3 { + static Vector3 zero(); + float x; + float y; + float z; + }; }; #endif diff --git a/src/engine/linuxEngine.cc b/src/engine/linuxEngine.cc new file mode 100644 index 0000000..0c7d231 --- /dev/null +++ b/src/engine/linuxEngine.cc @@ -0,0 +1,44 @@ +#ifdef __linux__ + +#include "linuxEngine.hh" + +#include +#include + +#include "linuxController.hh" + +void LinuxEngine::initializeEngine() { + glfwInit(); + // Set OpenGL version to 1.2. + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + + // Create a GLFW window. + window = glfwCreateWindow(640, 480, "DC Engine", nullptr, nullptr); + + // Fail if the window has failed to create. + if (window == nullptr) { + const char* description; + glfwGetError(&description); + std::cout << "Failed to create GLFW window.\n" + << description << std::endl; + } + + glfwMakeContextCurrent(window); + // printSystemInformation(); +} + +void LinuxEngine::initializeController() { + LinuxController* linuxCont = new LinuxController; + if (linuxCont->InitializeController()) { + controller = linuxCont; + } else { + throw std::runtime_error("No controller detected"); + } +} + +void LinuxEngine::SwapBuffers() { + glfwSwapBuffers(window); + glfwPollEvents(); +} +#endif diff --git a/src/engine/linuxEngine.hh b/src/engine/linuxEngine.hh new file mode 100644 index 0000000..ab1e734 --- /dev/null +++ b/src/engine/linuxEngine.hh @@ -0,0 +1,13 @@ +#ifndef LINUX_ENGINE_HH +#define LINUX_ENGINE_HH +#include "nativeEngine.hh" +#include +#include + +class LinuxEngine : public NativeEngine { + void initializeController() override; + void initializeEngine() override; + void SwapBuffers() override; + GLFWwindow* window = nullptr; +}; +#endif diff --git a/src/engine/meson.build b/src/engine/meson.build new file mode 100644 index 0000000..41d29a6 --- /dev/null +++ b/src/engine/meson.build @@ -0,0 +1,14 @@ +engine_deps = [ + GL, + math, +] + +if host_machine.system() == 'linux' + engine_deps += dependency('glfw3') + engine_deps += dependency('epoxy') +endif + +subdir('controller') + +engine = static_library('engine', ['dreamcastEngine.cc', 'linuxEngine.cc', 'engine.cc'], dependencies: engine_deps, include_directories: incdirs) +engine_dep = declare_dependency(link_with: [engine, controller], include_directories: incdirs) diff --git a/src/engine/nativeEngine.cc b/src/engine/nativeEngine.cc new file mode 100644 index 0000000..e69de29 diff --git a/src/engine/nativeEngine.hh b/src/engine/nativeEngine.hh new file mode 100644 index 0000000..e252618 --- /dev/null +++ b/src/engine/nativeEngine.hh @@ -0,0 +1,11 @@ +#ifndef NATIVE_ENGINE_HH +#define NATIVE_ENGINE_HH +#include "controller/controller.hh" +class NativeEngine { + public: + virtual void initializeController(){}; + virtual void initializeEngine(){}; + virtual void SwapBuffers(){}; + Controller* controller = nullptr; +}; +#endif diff --git a/gl.cc b/src/gl.cc similarity index 57% rename from gl.cc rename to src/gl.cc index 8d480c4..a640c4f 100644 --- a/gl.cc +++ b/src/gl.cc @@ -1,10 +1,14 @@ +#ifdef _arch_dreamcast #include #include - +#include +#else +#include +#endif #include #include -#include "engine.hh" +#include "engine/engine.hh" class Glcc : public Engine { void process_input(); @@ -39,43 +43,31 @@ void Glcc::displayStuff() { glPopMatrix(); // clang-format on + + #ifdef _arch_dreamcast if (thirtyfps) { vid_waitvbl(); vid_waitvbl(); } + #endif - glKosSwapBuffers(); + SwapBuffers(); } void Glcc::process_input() { - maple_device_t* controller; - cont_state_t* controller_state; + pressButton(Controller::Button::DPAD_LEFT, [&]() { speed -= 1.0f; }); + pressButton(Controller::Button::DPAD_RIGHT, [&]() { speed += 1.0f; }); + pressButton(Controller::Button::A, [&]() { thirtyfps = !thirtyfps; }); - controller = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); + speed = std::clamp(speed, 1.0f, 10.0f); - if (controller) { - controller_state = (cont_state_t*)maple_dev_status(controller); - - if (!controller_state) { - printf( - "An error has occured while trying to read the " - "controller.\n"); - } - - pressButton(controller_state, CONT_DPAD_LEFT, [&]() { speed -= 1.0f; }); - pressButton(controller_state, CONT_DPAD_RIGHT, - [&]() { speed += 1.0f; }); - pressButton(controller_state, CONT_A, - [&]() { thirtyfps = !thirtyfps; }); - - speed = std::clamp(speed, 1.0f, 10.0f); - - angle += (controller_state->joyx / 127.0f) * deltaTime * speed; - } + angle += controller->GetLeftJoystickXAxis() * deltaTime * speed; + printf("%f\n", speed); } int main() { Glcc* engine = new Glcc; engine->initializeEngine(); + engine->initializeController(); engine->initializeGameLoop(); } diff --git a/hello.cc b/src/hello.cc similarity index 84% rename from hello.cc rename to src/hello.cc index 5ef55ab..dfb3b44 100644 --- a/hello.cc +++ b/src/hello.cc @@ -1,13 +1,16 @@ +#ifdef _arch_dreamcast #include -#include -#include "engine.hh" +#else +#include +#endif +#include "engine/engine.hh" class Hello : public Engine { void triangle(); void gameLoop() override { triangle(); - glKosSwapBuffers(); + SwapBuffers(); } }; diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..176598a --- /dev/null +++ b/src/meson.build @@ -0,0 +1,54 @@ +cc = meson.get_compiler('c') + +kosinc = include_directories('/opt/toolchains/dc/kos/include') +koskernelinc = include_directories('/opt/toolchains/dc/kos/kernel/arch/dreamcast/include') +kosaddonsinc = include_directories('/opt/toolchains/dc/kos/addons/include') +kosportsinc = include_directories('/opt/toolchains/dc/kos-ports/include') + +GL = cc.find_library('GL', required: true) +math = cc.find_library('m', required: true) +# pcx = cc.find_library('pcx', required: true) +# kosutils = cc.find_library('kosutils', required: true) + +tinyobjloader = subproject('tinyobjloader') +tinyobjloader_dep = tinyobjloader.get_variable('tinyobjloader_dep') + +deps = [ + GL, + math, + tinyobjloader_dep +] + +incdirs = [] + +if host_machine.system() == 'dreamcast' + stb_image = cc.find_library('stb_image', required: true) + deps += stb_image + incdirs += [ + kosinc, + koskernelinc, + kosaddonsinc, + kosportsinc + ] +endif + +if host_machine.system() == 'linux' + deps += dependency('glfw3') + deps += dependency('glu') +endif + +subdir('engine') + +deps += [engine_dep] + +cube_sources = [ + 'cube.cc' +] + +if host_machine.system() == 'dreamcast' + cube_sources += romdsk_o +endif + +executable('hello.elf', ['hello.cc'], dependencies: deps, include_directories: incdirs) +executable('gl.elf', ['gl.cc'], dependencies: deps, include_directories: incdirs) +executable('cube.elf', cube_sources, dependencies: deps, include_directories: incdirs)