Skip to content

Commit

Permalink
Implement runtime display (test) (#318)
Browse files Browse the repository at this point in the history
* Implement runtime display (test)

* Update runtime.cpp

* [game display] add "-nodisplay" argument

* style fixes

* Update gfx.cpp

* [deci2server] fix deadlock when killing a Deci2Server

* add libxrandr to linux github test

* correct package name to libxrandr-dev

* set g_main_thread_id in exec_runtime

* add libxinerama to linux test packages

* correct the name

* add libxcursor1 package

* Update linux-workflow.yaml

* add libxi-dev

* fix constructor for g_main_thread_id

* fix submodules + use -nodisplay during tests

* move the gfx loop to its own function and use a lambda for exit conditions

* fix include

* fix include

* fix includes (for real this time)
  • Loading branch information
ManDude authored Mar 10, 2021
1 parent 8bba3d7 commit 9430b47
Show file tree
Hide file tree
Showing 22 changed files with 27,947 additions and 18 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/linux-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
path: |
./third-party/googletest
./third-party/zydis
./third-party/glfw
./.git/modules/
- name: Checkout Submodules
Expand All @@ -69,7 +70,7 @@ jobs:
echo "##[set-output name=artifact-metadata;]${ARTIFACT_NAME}"
- name: Get Package Dependencies
run: sudo apt install build-essential cmake ccache clang gcc g++ lcov make nasm
run: sudo apt install build-essential cmake ccache clang gcc g++ lcov make nasm libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev

# # -- SETUP CCACHE - https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/
# - name: Prepare ccache timestamp
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/windows-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
path: |
./third-party/googletest
./third-party/zydis
./third-party/glfw
./.git/modules/
- name: Checkout Submodules
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "third-party/zydis"]
path = third-party/zydis
url = https://github.com/zyantific/zydis.git
[submodule "third-party/glfw"]
path = third-party/glfw
url = https://github.com/glfw/glfw
7 changes: 7 additions & 0 deletions .vs/launch.vs.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@
"name" : "Run Runtime (with kernel)",
"args" : [ "-fakeiso", "-debug" ]
},
{
"type" : "default",
"project" : "CMakeLists.txt",
"projectTarget" : "gk.exe (bin\\gk.exe)",
"name" : "Run Runtime (no kernel) (verbose)",
"args" : [ "-fakeiso", "-debug", "-nokernel", "-v" ]
},
{
"type" : "default",
"project" : "CMakeLists.txt",
Expand Down
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ add_subdirectory(common)
# build decompiler
add_subdirectory(decompiler)

# build glfw library
add_subdirectory(third-party/glfw)

# build the game code in C++
include_directories(third-party/glad/include)
include_directories(third-party/glfw/include)
add_subdirectory(game)

# build the compiler
Expand Down
10 changes: 6 additions & 4 deletions game/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ if(UNIX)
-Wshadow \
-Wsign-promo")
else()
set(CMAKE_CXX_FLAGS "/EHsc")
set(CMAKE_CXX_FLAGS "/EHsc")
endif(UNIX)

enable_language(ASM_NASM)
Expand Down Expand Up @@ -70,13 +70,15 @@ set(RUNTIME_SOURCE
overlord/soundcommon.cpp
overlord/srpc.cpp
overlord/ssound.cpp
overlord/stream.cpp)
overlord/stream.cpp
graphics/gfx.cpp
graphics/display.cpp)


# we build the runtime as a static library.
add_library(runtime ${RUNTIME_SOURCE})
add_library(runtime ${RUNTIME_SOURCE} "../third-party/glad/src/glad.c")

target_link_libraries(runtime common fmt)
target_link_libraries(runtime common fmt glfw)
if(WIN32)
target_link_libraries(runtime mman)
else()
Expand Down
54 changes: 54 additions & 0 deletions game/graphics/display.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*!
* @file display.cpp
* Display for graphics. This is the game window, distinct from the runtime console.
*/

#include "display.h"

#include "common/log/log.h"

namespace Display {

GLFWwindow* display = NULL;

void InitDisplay(int width, int height, 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);
}

void KillDisplay(GLFWwindow*& d) {
lg::debug("kill display #x{}", (uintptr_t)d);
if (!d) {
lg::warn("KillDisplay called when no display was available");
return;
}

glfwDestroyWindow(d);
d = NULL;
}

} // namespace Display
25 changes: 25 additions & 0 deletions game/graphics/display.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

/*!
* @file display.h
* Display for graphics. This is the game window, distinct from the runtime console.
*/

#ifndef RUNTIME_DISPLAY_H
#define RUNTIME_DISPLAY_H

#include "opengl.h"

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;

void InitDisplay(int width, int height, char* title, GLFWwindow*& d);
void KillDisplay(GLFWwindow*& d);

} // namespace Display

#endif // RUNTIME_DISPLAY_H
46 changes: 46 additions & 0 deletions game/graphics/gfx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*!
* @file gfx.cpp
* Graphics component for the runtime. Handles some low-level routines.
*/

#include "gfx.h"
#include "common/log/log.h"
#include "game/runtime.h"
#include "display.h"

#include "opengl.h"

namespace Gfx {

void GlfwErrorCallback(int err, const char* msg) {
lg::error("GLFW ERR {}: " + std::string(msg), err);
}

u32 Init() {
if (glfwSetErrorCallback(GlfwErrorCallback) != NULL) {
lg::warn("glfwSetErrorCallback has been re-set!");
}

if (!glfwInit()) {
lg::error("glfwInit 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);
}

return 0;
}

u32 Exit() {
lg::debug("gfx exit");
Display::KillDisplay(Display::display);
glfwTerminate();
glfwSetErrorCallback(NULL);
return 0;
}

} // namespace Gfx
47 changes: 47 additions & 0 deletions game/graphics/gfx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once

/*!
* @file gfx.h
* Graphics component for the runtime. Handles some low-level routines.
*/

#ifndef RUNTIME_GFX_H
#define RUNTIME_GFX_H

#include "common/common_types.h"
#include "display.h"
#include "game/kernel/kboot.h"

namespace Gfx {

u32 Init();
u32 Exit();

template <typename T>
void Loop(T f) {
while (f()) {
// run display-specific things
if (Display::display) {
// 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 = 1;
}
}
}
}

} // namespace Gfx

#endif // RUNTIME_GFX_H
15 changes: 15 additions & 0 deletions game/graphics/opengl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#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
2 changes: 1 addition & 1 deletion game/kernel/kmachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ void InitParms(int argc, const char* const* argv) {
DebugSegment = 0;
}

// the "debug" mode is used to set GOAL up for debugging/developemtn
// the "debug" mode is used to set GOAL up for debugging/development
if (arg == "-debug") {
Msg(6, "dkernel: debug mode\n");
MasterDebug = 1;
Expand Down
26 changes: 23 additions & 3 deletions game/runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,15 @@
#include "game/overlord/srpc.h"
#include "game/overlord/stream.h"

#include "game/graphics/opengl.h"
#include "game/graphics/gfx.h"
#include "game/graphics/display.h"

#include "common/goal_constants.h"
#include "common/cross_os_debug/xdbg.h"

u8* g_ee_main_mem = nullptr;
std::thread::id g_main_thread_id = std::thread::id();

namespace {

Expand Down Expand Up @@ -81,8 +86,6 @@ void deci2_runner(SystemThreadInterface& iface) {
}

lg::debug("[DECI2] Waiting for listener...");
// lg::debug("[DECI2] Waiting for listener..."); --> disabled temporarily, some weird race
// condition?
bool saw_listener = false;
while (!iface.get_want_exit()) {
if (server.check_for_listener()) {
Expand Down Expand Up @@ -233,6 +236,15 @@ void iop_runner(SystemThreadInterface& iface) {
u32 exec_runtime(int argc, char** argv) {
g_argc = argc;
g_argv = argv;
g_main_thread_id = std::this_thread::get_id();

bool enable_display = true;
for (int i = 1; i < argc; i++) {
if (std::string("-nodisplay") == argv[i]) {
enable_display = false;
break;
}
}

// step 1: sce library prep
iop::LIBRARY_INIT();
Expand All @@ -251,7 +263,15 @@ u32 exec_runtime(int argc, char** argv) {
ee_thread.start(ee_runner);
deci_thread.start(deci2_runner);

// step 4: wait for EE to signal a shutdown, which will cause the DECI thread to join.
// step 4: wait for EE to signal a shutdown. meanwhile, run video loop on main thread.
// TODO relegate this to its own function
// TODO also sync this up with how the game actually renders things (this is just a placeholder)
if (enable_display) {
Gfx::Init();
Gfx::Loop([&tm] { return !tm.all_threads_exiting(); });
Gfx::Exit();
}

deci_thread.join();
// DECI has been killed, shutdown!

Expand Down
3 changes: 3 additions & 0 deletions game/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
#define JAK1_RUNTIME_H

#include "common/common_types.h"
#include <thread>

extern u8* g_ee_main_mem;
u32 exec_runtime(int argc, char** argv);

extern std::thread::id g_main_thread_id;

#endif // JAK1_RUNTIME_H
6 changes: 3 additions & 3 deletions game/system/Deci2Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ Deci2Server::Deci2Server(std::function<bool()> shutdown_callback) {
}

Deci2Server::~Deci2Server() {
close_server_socket();
close_socket(new_sock);

// if accept thread is running, kill it
if (accept_thread_running) {
kill_accept_thread = true;
Expand All @@ -39,9 +42,6 @@ Deci2Server::~Deci2Server() {
}

delete[] buffer;

close_server_socket();
close_socket(new_sock);
}

/*!
Expand Down
11 changes: 11 additions & 0 deletions game/system/SystemThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ void SystemThreadManager::join() {
}
}

/*!
* Return true if all threads are exiting (manager shutdown)
*/
bool SystemThreadManager::all_threads_exiting() {
for (int i = 0; i < thread_count; i++) {
if (!threads[i].want_exit)
return false;
}
return true;
}

/*!
* bootstrap function to call a SystemThread's function
*/
Expand Down
Loading

0 comments on commit 9430b47

Please sign in to comment.