Renamed everything ultra related to "ultramodern"
This commit is contained in:
parent
8188aee2c1
commit
244d37e3c8
|
@ -74,16 +74,16 @@ add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/RecompiledPatches/patches.c
|
||||||
add_executable(MMRecomp)
|
add_executable(MMRecomp)
|
||||||
|
|
||||||
set (SOURCES
|
set (SOURCES
|
||||||
${CMAKE_SOURCE_DIR}/portultra/audio.cpp
|
${CMAKE_SOURCE_DIR}/ultramodern/audio.cpp
|
||||||
${CMAKE_SOURCE_DIR}/portultra/events.cpp
|
${CMAKE_SOURCE_DIR}/ultramodern/events.cpp
|
||||||
${CMAKE_SOURCE_DIR}/portultra/mesgqueue.cpp
|
${CMAKE_SOURCE_DIR}/ultramodern/mesgqueue.cpp
|
||||||
${CMAKE_SOURCE_DIR}/portultra/misc_ultra.cpp
|
${CMAKE_SOURCE_DIR}/ultramodern/misc_ultra.cpp
|
||||||
${CMAKE_SOURCE_DIR}/portultra/port_main.c
|
${CMAKE_SOURCE_DIR}/ultramodern/port_main.c
|
||||||
${CMAKE_SOURCE_DIR}/portultra/scheduler.cpp
|
${CMAKE_SOURCE_DIR}/ultramodern/scheduler.cpp
|
||||||
${CMAKE_SOURCE_DIR}/portultra/task_win32.cpp
|
${CMAKE_SOURCE_DIR}/ultramodern/task_win32.cpp
|
||||||
${CMAKE_SOURCE_DIR}/portultra/threads.cpp
|
${CMAKE_SOURCE_DIR}/ultramodern/threads.cpp
|
||||||
${CMAKE_SOURCE_DIR}/portultra/timer.cpp
|
${CMAKE_SOURCE_DIR}/ultramodern/timer.cpp
|
||||||
${CMAKE_SOURCE_DIR}/portultra/ultrainit.cpp
|
${CMAKE_SOURCE_DIR}/ultramodern/ultrainit.cpp
|
||||||
|
|
||||||
${CMAKE_SOURCE_DIR}/src/ai.cpp
|
${CMAKE_SOURCE_DIR}/src/ai.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/cont.cpp
|
${CMAKE_SOURCE_DIR}/src/cont.cpp
|
||||||
|
@ -95,8 +95,8 @@ set (SOURCES
|
||||||
${CMAKE_SOURCE_DIR}/src/overlays.cpp
|
${CMAKE_SOURCE_DIR}/src/overlays.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/pak.cpp
|
${CMAKE_SOURCE_DIR}/src/pak.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/pi.cpp
|
${CMAKE_SOURCE_DIR}/src/pi.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/portultra_stubs.cpp
|
${CMAKE_SOURCE_DIR}/src/ultra_stubs.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/portultra_translation.cpp
|
${CMAKE_SOURCE_DIR}/src/ultra_translation.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/print.cpp
|
${CMAKE_SOURCE_DIR}/src/print.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/recomp.cpp
|
${CMAKE_SOURCE_DIR}/src/recomp.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/rt64_layer.cpp
|
${CMAKE_SOURCE_DIR}/src/rt64_layer.cpp
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __RT64_LAYER_H__
|
#ifndef __RT64_LAYER_H__
|
||||||
#define __RT64_LAYER_H__
|
#define __RT64_LAYER_H__
|
||||||
|
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// void* hWnd;
|
// void* hWnd;
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
#include "ultra64.h"
|
|
||||||
#include "multilibultra.hpp"
|
|
||||||
|
|
||||||
void Multilibultra::preinit(uint8_t* rdram, uint8_t* rom, Multilibultra::WindowHandle window_handle) {
|
|
||||||
Multilibultra::set_main_thread();
|
|
||||||
Multilibultra::init_events(rdram, rom, window_handle);
|
|
||||||
Multilibultra::init_timers(rdram);
|
|
||||||
Multilibultra::init_audio();
|
|
||||||
Multilibultra::save_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void osInitialize() {
|
|
||||||
Multilibultra::init_scheduler();
|
|
||||||
}
|
|
10
src/ai.cpp
10
src/ai.cpp
|
@ -1,8 +1,8 @@
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../portultra/ultra64.h"
|
#include "../ultramodern/ultra64.h"
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
|
|
||||||
#define VI_NTSC_CLOCK 48681812
|
#define VI_NTSC_CLOCK 48681812
|
||||||
|
|
||||||
|
@ -12,16 +12,16 @@ extern "C" void osAiSetFrequency_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
//uint32_t dacRate = (uint32_t)(((float)VI_NTSC_CLOCK / freq) + 0.5f);
|
//uint32_t dacRate = (uint32_t)(((float)VI_NTSC_CLOCK / freq) + 0.5f);
|
||||||
//freq = VI_NTSC_CLOCK / dacRate;
|
//freq = VI_NTSC_CLOCK / dacRate;
|
||||||
ctx->r2 = freq;
|
ctx->r2 = freq;
|
||||||
Multilibultra::set_audio_frequency(freq);
|
ultramodern::set_audio_frequency(freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osAiSetNextBuffer_recomp(uint8_t* rdram, recomp_context* ctx) {
|
extern "C" void osAiSetNextBuffer_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
Multilibultra::queue_audio_buffer(rdram, ctx->r4, ctx->r5);
|
ultramodern::queue_audio_buffer(rdram, ctx->r4, ctx->r5);
|
||||||
ctx->r2 = 0;
|
ctx->r2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osAiGetLength_recomp(uint8_t* rdram, recomp_context* ctx) {
|
extern "C" void osAiGetLength_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
ctx->r2 = Multilibultra::get_remaining_audio_bytes();
|
ctx->r2 = ultramodern::get_remaining_audio_bytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osAiGetStatus_recomp(uint8_t* rdram, recomp_context* ctx) {
|
extern "C" void osAiGetStatus_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
|
10
src/cont.cpp
10
src/cont.cpp
|
@ -1,9 +1,9 @@
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
#include "recomp_helpers.h"
|
#include "recomp_helpers.h"
|
||||||
|
|
||||||
static Multilibultra::input_callbacks_t input_callbacks;
|
static ultramodern::input_callbacks_t input_callbacks;
|
||||||
|
|
||||||
void set_input_callbacks(const Multilibultra::input_callbacks_t& callbacks) {
|
void set_input_callbacks(const ultramodern::input_callbacks_t& callbacks) {
|
||||||
input_callbacks = callbacks;
|
input_callbacks = callbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ extern "C" void osContInit_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osContStartReadData_recomp(uint8_t* rdram, recomp_context* ctx) {
|
extern "C" void osContStartReadData_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
Multilibultra::send_si_message();
|
ultramodern::send_si_message();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osContGetReadData_recomp(uint8_t* rdram, recomp_context* ctx) {
|
extern "C" void osContGetReadData_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
@ -63,7 +63,7 @@ extern "C" void osContGetReadData_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osContStartQuery_recomp(uint8_t * rdram, recomp_context * ctx) {
|
extern "C" void osContStartQuery_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||||
Multilibultra::send_si_message();
|
ultramodern::send_si_message();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osContGetQuery_recomp(uint8_t * rdram, recomp_context * ctx) {
|
extern "C" void osContGetQuery_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
#include "../portultra/ultra64.h"
|
#include "../ultramodern/ultra64.h"
|
||||||
|
|
||||||
void save_write(uint8_t* rdram, gpr rdram_address, uint32_t offset, uint32_t count);
|
void save_write(uint8_t* rdram, gpr rdram_address, uint32_t offset, uint32_t count);
|
||||||
void save_read(uint8_t* rdram, gpr rdram_address, uint32_t offset, uint32_t count);
|
void save_read(uint8_t* rdram, gpr rdram_address, uint32_t offset, uint32_t count);
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "../portultra/ultra64.h"
|
#include "../ultramodern/ultra64.h"
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
|
|
||||||
|
// TODO move this out into ultramodern code
|
||||||
|
|
||||||
constexpr uint32_t flash_size = 1024 * 1024 / 8; // 1Mbit
|
constexpr uint32_t flash_size = 1024 * 1024 / 8; // 1Mbit
|
||||||
constexpr uint32_t page_size = 128;
|
constexpr uint32_t page_size = 128;
|
||||||
constexpr uint32_t pages_per_sector = 128;
|
constexpr uint32_t pages_per_sector = 128;
|
||||||
|
@ -19,7 +21,7 @@ void save_clear(uint32_t start, uint32_t size, char value);
|
||||||
std::array<char, page_size> write_buffer;
|
std::array<char, page_size> write_buffer;
|
||||||
|
|
||||||
extern "C" void osFlashInit_recomp(uint8_t * rdram, recomp_context * ctx) {
|
extern "C" void osFlashInit_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||||
ctx->r2 = Multilibultra::flash_handle;
|
ctx->r2 = ultramodern::flash_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osFlashReadStatus_recomp(uint8_t * rdram, recomp_context * ctx) {
|
extern "C" void osFlashReadStatus_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||||
|
@ -42,13 +44,13 @@ extern "C" void osFlashClearStatus_recomp(uint8_t * rdram, recomp_context * ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osFlashAllErase_recomp(uint8_t * rdram, recomp_context * ctx) {
|
extern "C" void osFlashAllErase_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||||
save_clear(0, Multilibultra::save_size, 0xFF);
|
save_clear(0, ultramodern::save_size, 0xFF);
|
||||||
|
|
||||||
ctx->r2 = 0;
|
ctx->r2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osFlashAllEraseThrough_recomp(uint8_t * rdram, recomp_context * ctx) {
|
extern "C" void osFlashAllEraseThrough_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||||
save_clear(0, Multilibultra::save_size, 0xFF);
|
save_clear(0, ultramodern::save_size, 0xFF);
|
||||||
|
|
||||||
ctx->r2 = 0;
|
ctx->r2 = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include "../../portultra/ultra64.h"
|
#include "../../ultramodern/ultra64.h"
|
||||||
#include "../../portultra/multilibultra.hpp"
|
#include "../../ultramodern/ultramodern.hpp"
|
||||||
#define SDL_MAIN_HANDLED
|
#define SDL_MAIN_HANDLED
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" void init();
|
extern "C" void init();
|
||||||
/*extern "C"*/ void start(Multilibultra::WindowHandle window_handle, const Multilibultra::audio_callbacks_t* audio_callbacks, const Multilibultra::input_callbacks_t* input_callbacks);
|
/*extern "C"*/ void start(ultramodern::WindowHandle window_handle, const ultramodern::audio_callbacks_t* audio_callbacks, const ultramodern::input_callbacks_t* input_callbacks);
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
void exit_error(const char* str, Ts ...args) {
|
void exit_error(const char* str, Ts ...args) {
|
||||||
|
@ -138,7 +138,7 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_EventType::SDL_QUIT:
|
case SDL_EventType::SDL_QUIT:
|
||||||
Multilibultra::quit();
|
ultramodern::quit();
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
queue_event(*event);
|
queue_event(*event);
|
||||||
|
@ -147,7 +147,7 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Multilibultra::gfx_callbacks_t::gfx_data_t create_gfx() {
|
ultramodern::gfx_callbacks_t::gfx_data_t create_gfx() {
|
||||||
SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "system");
|
SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "system");
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) > 0) {
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) > 0) {
|
||||||
exit_error("Failed to initialize SDL2: %s\n", SDL_GetError());
|
exit_error("Failed to initialize SDL2: %s\n", SDL_GetError());
|
||||||
|
@ -158,7 +158,7 @@ Multilibultra::gfx_callbacks_t::gfx_data_t create_gfx() {
|
||||||
|
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
|
|
||||||
Multilibultra::WindowHandle create_window(Multilibultra::gfx_callbacks_t::gfx_data_t) {
|
ultramodern::WindowHandle create_window(ultramodern::gfx_callbacks_t::gfx_data_t) {
|
||||||
window = SDL_CreateWindow("Recomp", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_RESIZABLE );
|
window = SDL_CreateWindow("Recomp", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_RESIZABLE );
|
||||||
|
|
||||||
if (window == nullptr) {
|
if (window == nullptr) {
|
||||||
|
@ -170,11 +170,11 @@ Multilibultra::WindowHandle create_window(Multilibultra::gfx_callbacks_t::gfx_da
|
||||||
SDL_GetWindowWMInfo(window, &wmInfo);
|
SDL_GetWindowWMInfo(window, &wmInfo);
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
return Multilibultra::WindowHandle{ wmInfo.info.win.window, GetCurrentThreadId() };
|
return ultramodern::WindowHandle{ wmInfo.info.win.window, GetCurrentThreadId() };
|
||||||
#elif defined(__ANDROID__)
|
#elif defined(__ANDROID__)
|
||||||
static_assert(false && "Unimplemented");
|
static_assert(false && "Unimplemented");
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
return Multilibultra::WindowHandle{ wmInfo.info.x11.display, wmInfo.info.x11.window };
|
return ultramodern::WindowHandle{ wmInfo.info.x11.display, wmInfo.info.x11.window };
|
||||||
#else
|
#else
|
||||||
static_assert(false && "Unimplemented");
|
static_assert(false && "Unimplemented");
|
||||||
#endif
|
#endif
|
||||||
|
@ -344,23 +344,23 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
Multilibultra::gfx_callbacks_t gfx_callbacks{
|
ultramodern::gfx_callbacks_t gfx_callbacks{
|
||||||
.create_gfx = create_gfx,
|
.create_gfx = create_gfx,
|
||||||
.create_window = create_window,
|
.create_window = create_window,
|
||||||
.update_gfx = update_gfx,
|
.update_gfx = update_gfx,
|
||||||
};
|
};
|
||||||
|
|
||||||
Multilibultra::audio_callbacks_t audio_callbacks{
|
ultramodern::audio_callbacks_t audio_callbacks{
|
||||||
.queue_samples = queue_samples,
|
.queue_samples = queue_samples,
|
||||||
.get_frames_remaining = get_frames_remaining,
|
.get_frames_remaining = get_frames_remaining,
|
||||||
.set_frequency = set_frequency,
|
.set_frequency = set_frequency,
|
||||||
};
|
};
|
||||||
|
|
||||||
Multilibultra::input_callbacks_t input_callbacks{
|
ultramodern::input_callbacks_t input_callbacks{
|
||||||
.get_input = get_input,
|
.get_input = get_input,
|
||||||
};
|
};
|
||||||
|
|
||||||
Multilibultra::start({}, audio_callbacks, input_callbacks, gfx_callbacks);
|
ultramodern::start({}, audio_callbacks, input_callbacks, gfx_callbacks);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
#include "../portultra/ultra64.h"
|
#include "../ultramodern/ultra64.h"
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
|
|
||||||
extern "C" void osPfsInitPak_recomp(uint8_t * rdram, recomp_context* ctx) {
|
extern "C" void osPfsInitPak_recomp(uint8_t * rdram, recomp_context* ctx) {
|
||||||
ctx->r2 = 1; // PFS_ERR_NOPACK
|
ctx->r2 = 1; // PFS_ERR_NOPACK
|
||||||
|
|
10
src/pi.cpp
10
src/pi.cpp
|
@ -3,8 +3,8 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
#include "../portultra/ultra64.h"
|
#include "../ultramodern/ultra64.h"
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
|
|
||||||
// Flashram occupies the same physical address as sram, but that issue is avoided because libultra exposes
|
// Flashram occupies the same physical address as sram, but that issue is avoided because libultra exposes
|
||||||
// a high-level interface for flashram. Because that high-level interface is reimplemented, low level accesses
|
// a high-level interface for flashram. Because that high-level interface is reimplemented, low level accesses
|
||||||
|
@ -24,12 +24,12 @@ extern std::unique_ptr<uint8_t[]> rom;
|
||||||
extern size_t rom_size;
|
extern size_t rom_size;
|
||||||
|
|
||||||
extern "C" void osCartRomInit_recomp(uint8_t* rdram, recomp_context* ctx) {
|
extern "C" void osCartRomInit_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
OSPiHandle* handle = TO_PTR(OSPiHandle, Multilibultra::cart_handle);
|
OSPiHandle* handle = TO_PTR(OSPiHandle, ultramodern::cart_handle);
|
||||||
handle->type = 0; // cart
|
handle->type = 0; // cart
|
||||||
handle->baseAddress = phys_to_k1(rom_base);
|
handle->baseAddress = phys_to_k1(rom_base);
|
||||||
handle->domain = 0;
|
handle->domain = 0;
|
||||||
|
|
||||||
ctx->r2 = (gpr)Multilibultra::cart_handle;
|
ctx->r2 = (gpr)ultramodern::cart_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osCreatePiManager_recomp(uint8_t* rdram, recomp_context* ctx) {
|
extern "C" void osCreatePiManager_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
@ -89,7 +89,7 @@ void save_clear(uint32_t start, uint32_t size, char value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::save_init() {
|
void ultramodern::save_init() {
|
||||||
std::ifstream save_file{ save_filename, std::ios_base::binary };
|
std::ifstream save_file{ save_filename, std::ios_base::binary };
|
||||||
|
|
||||||
if (save_file.good()) {
|
if (save_file.good()) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "../portultra/ultra64.h"
|
#include "../ultramodern/ultra64.h"
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
#include "euc-jp.h"
|
#include "euc-jp.h"
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define EXPORT __declspec(dllexport)
|
#define EXPORT __declspec(dllexport)
|
||||||
|
@ -210,28 +210,28 @@ EXPORT extern "C" void init() {
|
||||||
|
|
||||||
std::atomic_int game_started = -1;
|
std::atomic_int game_started = -1;
|
||||||
|
|
||||||
void Multilibultra::start_game(int game) {
|
void ultramodern::start_game(int game) {
|
||||||
game_started.store(game);
|
game_started.store(game);
|
||||||
game_started.notify_all();
|
game_started.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Multilibultra::is_game_started() {
|
bool ultramodern::is_game_started() {
|
||||||
return game_started.load() != -1;
|
return game_started.load() != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_audio_callbacks(const Multilibultra::audio_callbacks_t& callbacks);
|
void set_audio_callbacks(const ultramodern::audio_callbacks_t& callbacks);
|
||||||
void set_input_callbacks(const Multilibultra::input_callbacks_t& callback);
|
void set_input_callbacks(const ultramodern::input_callbacks_t& callback);
|
||||||
|
|
||||||
std::atomic_bool exited = false;
|
std::atomic_bool exited = false;
|
||||||
|
|
||||||
void Multilibultra::quit() {
|
void ultramodern::quit() {
|
||||||
exited.store(true);
|
exited.store(true);
|
||||||
int desired = -1;
|
int desired = -1;
|
||||||
game_started.compare_exchange_strong(desired, -2);
|
game_started.compare_exchange_strong(desired, -2);
|
||||||
game_started.notify_all();
|
game_started.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::start(WindowHandle window_handle, const audio_callbacks_t& audio_callbacks, const input_callbacks_t& input_callbacks, const gfx_callbacks_t& gfx_callbacks_) {
|
void ultramodern::start(WindowHandle window_handle, const audio_callbacks_t& audio_callbacks, const input_callbacks_t& input_callbacks, const gfx_callbacks_t& gfx_callbacks_) {
|
||||||
set_audio_callbacks(audio_callbacks);
|
set_audio_callbacks(audio_callbacks);
|
||||||
set_input_callbacks(input_callbacks);
|
set_input_callbacks(input_callbacks);
|
||||||
|
|
||||||
|
@ -252,12 +252,12 @@ void Multilibultra::start(WindowHandle window_handle, const audio_callbacks_t& a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::thread game_thread{[](Multilibultra::WindowHandle window_handle) {
|
std::thread game_thread{[](ultramodern::WindowHandle window_handle) {
|
||||||
debug_printf("[Recomp] Starting\n");
|
debug_printf("[Recomp] Starting\n");
|
||||||
|
|
||||||
Multilibultra::set_native_thread_name("Game Start Thread");
|
ultramodern::set_native_thread_name("Game Start Thread");
|
||||||
|
|
||||||
Multilibultra::preinit(rdram_buffer.get(), rom.get(), window_handle);
|
ultramodern::preinit(rdram_buffer.get(), rom.get(), window_handle);
|
||||||
|
|
||||||
game_started.wait(-1);
|
game_started.wait(-1);
|
||||||
|
|
||||||
|
@ -280,5 +280,5 @@ void Multilibultra::start(WindowHandle window_handle, const audio_callbacks_t& a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
game_thread.join();
|
game_thread.join();
|
||||||
Multilibultra::join_event_threads();
|
ultramodern::join_event_threads();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
// #include <Windows.h>
|
// #include <Windows.h>
|
||||||
|
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
#include "rt64_layer.h"
|
#include "rt64_layer.h"
|
||||||
#include "rt64_render_hooks.h"
|
#include "rt64_render_hooks.h"
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ void dummy_check_interrupts() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RT64Init(uint8_t* rom, uint8_t* rdram, Multilibultra::WindowHandle window_handle) {
|
void RT64Init(uint8_t* rom, uint8_t* rdram, ultramodern::WindowHandle window_handle) {
|
||||||
set_rt64_hooks();
|
set_rt64_hooks();
|
||||||
// Dynamic loading
|
// Dynamic loading
|
||||||
//auto RT64 = LoadLibrary("RT64.dll");
|
//auto RT64 = LoadLibrary("RT64.dll");
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
|
|
||||||
extern "C" void osSpTaskLoad_recomp(uint8_t* rdram, recomp_context* ctx) {
|
extern "C" void osSpTaskLoad_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
@ -33,7 +33,7 @@ extern "C" void osSpTaskStartGo_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
dump_file.write(ram_unswapped.get(), ram_size);
|
dump_file.write(ram_unswapped.get(), ram_size);
|
||||||
dump_frame = false;
|
dump_frame = false;
|
||||||
}
|
}
|
||||||
Multilibultra::submit_rsp_task(rdram, ctx->r4);
|
ultramodern::submit_rsp_task(rdram, ctx->r4);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osSpTaskYield_recomp(uint8_t* rdram, recomp_context* ctx) {
|
extern "C" void osSpTaskYield_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#include "recomp_ui.h"
|
#include "recomp_ui.h"
|
||||||
#include "../../portultra/multilibultra.hpp"
|
#include "../../ultramodern/ultramodern.hpp"
|
||||||
|
|
||||||
#include "nfd.h"
|
#include "nfd.h"
|
||||||
#include "RmlUi/Core.h"
|
#include "RmlUi/Core.h"
|
||||||
|
@ -39,7 +41,7 @@ std::unique_ptr<Rml::EventListenerInstancer> make_event_listener_instancer() {
|
||||||
|
|
||||||
ret->register_event("start_game",
|
ret->register_event("start_game",
|
||||||
[](Rml::Event& event) {
|
[](Rml::Event& event) {
|
||||||
Multilibultra::start_game(0);
|
ultramodern::start_game(0);
|
||||||
set_current_menu(Menu::None);
|
set_current_menu(Menu::None);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "../portultra/ultra64.h"
|
#include "../ultramodern/ultra64.h"
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
|
|
||||||
// None of these functions need to be reimplemented, so stub them out
|
// None of these functions need to be reimplemented, so stub them out
|
|
@ -1,6 +1,6 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "../portultra/ultra64.h"
|
#include "../ultramodern/ultra64.h"
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
|
|
||||||
extern "C" void osInitialize_recomp(uint8_t * rdram, recomp_context * ctx) {
|
extern "C" void osInitialize_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||||
|
@ -133,7 +133,7 @@ extern "C" void __osSetFpcCsr_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||||
// if (buf->magic == SETJMP_MAGIC) {
|
// if (buf->magic == SETJMP_MAGIC) {
|
||||||
// // If so, longjmp to it
|
// // If so, longjmp to it
|
||||||
// // Setjmp/longjmp does not work across threads, so verify that this buffer was made by this thread
|
// // Setjmp/longjmp does not work across threads, so verify that this buffer was made by this thread
|
||||||
// assert(buf->owner == Multilibultra::this_thread());
|
// assert(buf->owner == ultramodern::this_thread());
|
||||||
// longjmp(buf->storage->buffer, ctx->r5);
|
// longjmp(buf->storage->buffer, ctx->r5);
|
||||||
// } else {
|
// } else {
|
||||||
// // Otherwise, check if it was one built manually by the game with $ra pointing to a function
|
// // Otherwise, check if it was one built manually by the game with $ra pointing to a function
|
||||||
|
@ -159,5 +159,5 @@ extern "C" void __osSetFpcCsr_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//extern "C" int32_t osGetThreadEx(void) {
|
//extern "C" int32_t osGetThreadEx(void) {
|
||||||
// return Multilibultra::this_thread();
|
// return ultramodern::this_thread();
|
||||||
//}
|
//}
|
|
@ -1,4 +1,4 @@
|
||||||
#include "../portultra/multilibultra.hpp"
|
#include "../ultramodern/ultramodern.hpp"
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
|
|
||||||
extern "C" void osViSetYScale_recomp(uint8_t* rdram, recomp_context * ctx) {
|
extern "C" void osViSetYScale_recomp(uint8_t* rdram, recomp_context * ctx) {
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
#include "ultra64.h"
|
#include "ultra64.h"
|
||||||
#include "multilibultra.hpp"
|
#include "ultramodern.hpp"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
static uint32_t sample_rate = 48000;
|
static uint32_t sample_rate = 48000;
|
||||||
|
|
||||||
static Multilibultra::audio_callbacks_t audio_callbacks;
|
static ultramodern::audio_callbacks_t audio_callbacks;
|
||||||
|
|
||||||
void set_audio_callbacks(const Multilibultra::audio_callbacks_t& callbacks) {
|
void set_audio_callbacks(const ultramodern::audio_callbacks_t& callbacks) {
|
||||||
audio_callbacks = callbacks;
|
audio_callbacks = callbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::init_audio() {
|
void ultramodern::init_audio() {
|
||||||
// Pick an initial dummy sample rate; this will be set by the game later to the true sample rate.
|
// Pick an initial dummy sample rate; this will be set by the game later to the true sample rate.
|
||||||
set_audio_frequency(48000);
|
set_audio_frequency(48000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::set_audio_frequency(uint32_t freq) {
|
void ultramodern::set_audio_frequency(uint32_t freq) {
|
||||||
if (audio_callbacks.set_frequency) {
|
if (audio_callbacks.set_frequency) {
|
||||||
audio_callbacks.set_frequency(freq);
|
audio_callbacks.set_frequency(freq);
|
||||||
}
|
}
|
||||||
sample_rate = freq;
|
sample_rate = freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::queue_audio_buffer(RDRAM_ARG PTR(int16_t) audio_data_, uint32_t byte_count) {
|
void ultramodern::queue_audio_buffer(RDRAM_ARG PTR(int16_t) audio_data_, uint32_t byte_count) {
|
||||||
// Buffer for holding the output of swapping the audio channels. This is reused across
|
// Buffer for holding the output of swapping the audio channels. This is reused across
|
||||||
// calls to reduce runtime allocations.
|
// calls to reduce runtime allocations.
|
||||||
static std::vector<int16_t> swap_buffer;
|
static std::vector<int16_t> swap_buffer;
|
||||||
|
@ -59,7 +59,7 @@ float buffer_offset_frames = 0.5f;
|
||||||
// If there's ever any audio popping, check here first. Some games are very sensitive to
|
// If there's ever any audio popping, check here first. Some games are very sensitive to
|
||||||
// the remaining sample count and reporting a number that's too high here can lead to issues.
|
// the remaining sample count and reporting a number that's too high here can lead to issues.
|
||||||
// Reporting a number that's too low can lead to audio lag in some games.
|
// Reporting a number that's too low can lead to audio lag in some games.
|
||||||
uint32_t Multilibultra::get_remaining_audio_bytes() {
|
uint32_t ultramodern::get_remaining_audio_bytes() {
|
||||||
// Get the number of remaining buffered audio bytes.
|
// Get the number of remaining buffered audio bytes.
|
||||||
uint32_t buffered_byte_count;
|
uint32_t buffered_byte_count;
|
||||||
if (audio_callbacks.get_frames_remaining != nullptr) {
|
if (audio_callbacks.get_frames_remaining != nullptr) {
|
|
@ -12,7 +12,7 @@
|
||||||
#include "blockingconcurrentqueue.h"
|
#include "blockingconcurrentqueue.h"
|
||||||
|
|
||||||
#include "ultra64.h"
|
#include "ultra64.h"
|
||||||
#include "multilibultra.hpp"
|
#include "ultramodern.hpp"
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
#include "recomp_ui.h"
|
#include "recomp_ui.h"
|
||||||
#include "rsp.h"
|
#include "rsp.h"
|
||||||
|
@ -99,17 +99,17 @@ extern std::atomic_bool exited;
|
||||||
void set_dummy_vi();
|
void set_dummy_vi();
|
||||||
|
|
||||||
void vi_thread_func() {
|
void vi_thread_func() {
|
||||||
Multilibultra::set_native_thread_name("VI Thread");
|
ultramodern::set_native_thread_name("VI Thread");
|
||||||
// This thread should be prioritized over every other thread in the application, as it's what allows
|
// This thread should be prioritized over every other thread in the application, as it's what allows
|
||||||
// the game to generate new audio and gfx lists.
|
// the game to generate new audio and gfx lists.
|
||||||
Multilibultra::set_native_thread_priority(Multilibultra::ThreadPriority::Critical);
|
ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::Critical);
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
int remaining_retraces = events_context.vi.retrace_count;
|
int remaining_retraces = events_context.vi.retrace_count;
|
||||||
|
|
||||||
while (!exited) {
|
while (!exited) {
|
||||||
// Determine the next VI time (more accurate than adding 16ms each VI interrupt)
|
// Determine the next VI time (more accurate than adding 16ms each VI interrupt)
|
||||||
auto next = Multilibultra::get_start() + (total_vis * 1000000us) / (60 * Multilibultra::get_speed_multiplier());
|
auto next = ultramodern::get_start() + (total_vis * 1000000us) / (60 * ultramodern::get_speed_multiplier());
|
||||||
//if (next > std::chrono::system_clock::now()) {
|
//if (next > std::chrono::system_clock::now()) {
|
||||||
// printf("Sleeping for %" PRIu64 " us to get from %" PRIu64 " us to %" PRIu64 " us \n",
|
// printf("Sleeping for %" PRIu64 " us to get from %" PRIu64 " us to %" PRIu64 " us \n",
|
||||||
// (next - std::chrono::system_clock::now()) / 1us,
|
// (next - std::chrono::system_clock::now()) / 1us,
|
||||||
|
@ -120,7 +120,7 @@ void vi_thread_func() {
|
||||||
//}
|
//}
|
||||||
std::this_thread::sleep_until(next);
|
std::this_thread::sleep_until(next);
|
||||||
// Calculate how many VIs have passed
|
// Calculate how many VIs have passed
|
||||||
uint64_t new_total_vis = (Multilibultra::time_since_start() * (60 * Multilibultra::get_speed_multiplier()) / 1000ms) + 1;
|
uint64_t new_total_vis = (ultramodern::time_since_start() * (60 * ultramodern::get_speed_multiplier()) / 1000ms) + 1;
|
||||||
if (new_total_vis > total_vis + 1) {
|
if (new_total_vis > total_vis + 1) {
|
||||||
//printf("Skipped % " PRId64 " frames in VI interupt thread!\n", new_total_vis - total_vis - 1);
|
//printf("Skipped % " PRId64 " frames in VI interupt thread!\n", new_total_vis - total_vis - 1);
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ void vi_thread_func() {
|
||||||
if (remaining_retraces == 0) {
|
if (remaining_retraces == 0) {
|
||||||
remaining_retraces = events_context.vi.retrace_count;
|
remaining_retraces = events_context.vi.retrace_count;
|
||||||
|
|
||||||
if (Multilibultra::is_game_started()) {
|
if (ultramodern::is_game_started()) {
|
||||||
if (events_context.vi.mq != NULLPTR) {
|
if (events_context.vi.mq != NULLPTR) {
|
||||||
if (osSendMesg(PASS_RDRAM events_context.vi.mq, events_context.vi.msg, OS_MESG_NOBLOCK) == -1) {
|
if (osSendMesg(PASS_RDRAM events_context.vi.mq, events_context.vi.msg, OS_MESG_NOBLOCK) == -1) {
|
||||||
//printf("Game skipped a VI frame!\n");
|
//printf("Game skipped a VI frame!\n");
|
||||||
|
@ -174,7 +174,7 @@ void dp_complete() {
|
||||||
osSendMesg(PASS_RDRAM events_context.dp.mq, events_context.dp.msg, OS_MESG_NOBLOCK);
|
osSendMesg(PASS_RDRAM events_context.dp.mq, events_context.dp.msg, OS_MESG_NOBLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RT64Init(uint8_t* rom, uint8_t* rdram, Multilibultra::WindowHandle window_handle);
|
void RT64Init(uint8_t* rom, uint8_t* rdram, ultramodern::WindowHandle window_handle);
|
||||||
void RT64SendDL(uint8_t* rdram, const OSTask* task);
|
void RT64SendDL(uint8_t* rdram, const OSTask* task);
|
||||||
void RT64UpdateScreen(uint32_t vi_origin);
|
void RT64UpdateScreen(uint32_t vi_origin);
|
||||||
void RT64ChangeWindow();
|
void RT64ChangeWindow();
|
||||||
|
@ -220,8 +220,8 @@ void run_rsp_microcode(uint8_t* rdram, const OSTask* task, RspUcodeFunc* ucode_f
|
||||||
|
|
||||||
|
|
||||||
void task_thread_func(uint8_t* rdram, uint8_t* rom, std::atomic_flag* thread_ready) {
|
void task_thread_func(uint8_t* rdram, uint8_t* rom, std::atomic_flag* thread_ready) {
|
||||||
Multilibultra::set_native_thread_name("SP Task Thread");
|
ultramodern::set_native_thread_name("SP Task Thread");
|
||||||
Multilibultra::set_native_thread_priority(Multilibultra::ThreadPriority::Normal);
|
ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::Normal);
|
||||||
|
|
||||||
// Notify the caller thread that this thread is ready.
|
// Notify the caller thread that this thread is ready.
|
||||||
thread_ready->test_and_set();
|
thread_ready->test_and_set();
|
||||||
|
@ -257,11 +257,11 @@ void task_thread_func(uint8_t* rdram, uint8_t* rom, std::atomic_flag* thread_rea
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx_thread_func(uint8_t* rdram, uint8_t* rom, std::atomic_flag* thread_ready, Multilibultra::WindowHandle window_handle) {
|
void gfx_thread_func(uint8_t* rdram, uint8_t* rom, std::atomic_flag* thread_ready, ultramodern::WindowHandle window_handle) {
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
Multilibultra::set_native_thread_name("Gfx Thread");
|
ultramodern::set_native_thread_name("Gfx Thread");
|
||||||
Multilibultra::set_native_thread_priority(Multilibultra::ThreadPriority::Normal);
|
ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::Normal);
|
||||||
|
|
||||||
RT64Init(rom, rdram, window_handle);
|
RT64Init(rom, rdram, window_handle);
|
||||||
|
|
||||||
|
@ -445,7 +445,7 @@ extern "C" PTR(void) osViGetCurrentFramebuffer() {
|
||||||
return events_context.vi.current_buffer;
|
return events_context.vi.current_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::submit_rsp_task(RDRAM_ARG PTR(OSTask) task_) {
|
void ultramodern::submit_rsp_task(RDRAM_ARG PTR(OSTask) task_) {
|
||||||
OSTask* task = TO_PTR(OSTask, task_);
|
OSTask* task = TO_PTR(OSTask, task_);
|
||||||
|
|
||||||
// Send gfx tasks to the graphics action queue
|
// Send gfx tasks to the graphics action queue
|
||||||
|
@ -459,12 +459,12 @@ void Multilibultra::submit_rsp_task(RDRAM_ARG PTR(OSTask) task_) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::send_si_message() {
|
void ultramodern::send_si_message() {
|
||||||
uint8_t* rdram = events_context.rdram;
|
uint8_t* rdram = events_context.rdram;
|
||||||
osSendMesg(PASS_RDRAM events_context.si.mq, events_context.si.msg, OS_MESG_NOBLOCK);
|
osSendMesg(PASS_RDRAM events_context.si.mq, events_context.si.msg, OS_MESG_NOBLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::init_events(uint8_t* rdram, uint8_t* rom, Multilibultra::WindowHandle window_handle) {
|
void ultramodern::init_events(uint8_t* rdram, uint8_t* rom, ultramodern::WindowHandle window_handle) {
|
||||||
std::atomic_flag gfx_thread_ready;
|
std::atomic_flag gfx_thread_ready;
|
||||||
std::atomic_flag task_thread_ready;
|
std::atomic_flag task_thread_ready;
|
||||||
events_context.rdram = rdram;
|
events_context.rdram = rdram;
|
||||||
|
@ -479,7 +479,7 @@ void Multilibultra::init_events(uint8_t* rdram, uint8_t* rom, Multilibultra::Win
|
||||||
events_context.vi.thread = std::thread{ vi_thread_func };
|
events_context.vi.thread = std::thread{ vi_thread_func };
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::join_event_threads() {
|
void ultramodern::join_event_threads() {
|
||||||
events_context.sp.gfx_thread.join();
|
events_context.sp.gfx_thread.join();
|
||||||
events_context.vi.thread.join();
|
events_context.vi.thread.join();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
#include "ultra64.h"
|
#include "ultra64.h"
|
||||||
#include "multilibultra.hpp"
|
#include "ultramodern.hpp"
|
||||||
#include "recomp.h"
|
#include "recomp.h"
|
||||||
|
|
||||||
extern "C" void osCreateMesgQueue(RDRAM_ARG PTR(OSMesgQueue) mq_, PTR(OSMesg) msg, s32 count) {
|
extern "C" void osCreateMesgQueue(RDRAM_ARG PTR(OSMesgQueue) mq_, PTR(OSMesg) msg, s32 count) {
|
||||||
|
@ -51,26 +51,26 @@ extern "C" s32 osSendMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, s32 flags)
|
||||||
OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_);
|
OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_);
|
||||||
|
|
||||||
// Prevent accidentally blocking anything that isn't a game thread
|
// Prevent accidentally blocking anything that isn't a game thread
|
||||||
if (!Multilibultra::is_game_thread()) {
|
if (!ultramodern::is_game_thread()) {
|
||||||
flags = OS_MESG_NOBLOCK;
|
flags = OS_MESG_NOBLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Multilibultra::disable_preemption();
|
ultramodern::disable_preemption();
|
||||||
|
|
||||||
if (flags == OS_MESG_NOBLOCK) {
|
if (flags == OS_MESG_NOBLOCK) {
|
||||||
// If non-blocking, fail if the queue is full
|
// If non-blocking, fail if the queue is full
|
||||||
if (MQ_IS_FULL(mq)) {
|
if (MQ_IS_FULL(mq)) {
|
||||||
Multilibultra::enable_preemption();
|
ultramodern::enable_preemption();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, yield this thread until the queue has room
|
// Otherwise, yield this thread until the queue has room
|
||||||
while (MQ_IS_FULL(mq)) {
|
while (MQ_IS_FULL(mq)) {
|
||||||
debug_printf("[Message Queue] Thread %d is blocked on send\n", TO_PTR(OSThread, Multilibultra::this_thread())->id);
|
debug_printf("[Message Queue] Thread %d is blocked on send\n", TO_PTR(OSThread, ultramodern::this_thread())->id);
|
||||||
thread_queue_insert(PASS_RDRAM &mq->blocked_on_send, Multilibultra::this_thread());
|
thread_queue_insert(PASS_RDRAM &mq->blocked_on_send, ultramodern::this_thread());
|
||||||
Multilibultra::enable_preemption();
|
ultramodern::enable_preemption();
|
||||||
Multilibultra::pause_self(PASS_RDRAM1);
|
ultramodern::pause_self(PASS_RDRAM1);
|
||||||
Multilibultra::disable_preemption();
|
ultramodern::disable_preemption();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,18 +84,18 @@ extern "C" s32 osSendMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, s32 flags)
|
||||||
to_run = thread_queue_pop(PASS_RDRAM &mq->blocked_on_recv);
|
to_run = thread_queue_pop(PASS_RDRAM &mq->blocked_on_recv);
|
||||||
}
|
}
|
||||||
|
|
||||||
Multilibultra::enable_preemption();
|
ultramodern::enable_preemption();
|
||||||
if (to_run) {
|
if (to_run) {
|
||||||
debug_printf("[Message Queue] Thread %d is unblocked\n", to_run->id);
|
debug_printf("[Message Queue] Thread %d is unblocked\n", to_run->id);
|
||||||
if (Multilibultra::is_game_thread()) {
|
if (ultramodern::is_game_thread()) {
|
||||||
OSThread* self = TO_PTR(OSThread, Multilibultra::this_thread());
|
OSThread* self = TO_PTR(OSThread, ultramodern::this_thread());
|
||||||
if (to_run->priority > self->priority) {
|
if (to_run->priority > self->priority) {
|
||||||
Multilibultra::swap_to_thread(PASS_RDRAM to_run);
|
ultramodern::swap_to_thread(PASS_RDRAM to_run);
|
||||||
} else {
|
} else {
|
||||||
Multilibultra::schedule_running_thread(to_run);
|
ultramodern::schedule_running_thread(to_run);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Multilibultra::schedule_running_thread(to_run);
|
ultramodern::schedule_running_thread(to_run);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -103,22 +103,22 @@ extern "C" s32 osSendMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, s32 flags)
|
||||||
|
|
||||||
extern "C" s32 osJamMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, s32 flags) {
|
extern "C" s32 osJamMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, s32 flags) {
|
||||||
OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_);
|
OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_);
|
||||||
Multilibultra::disable_preemption();
|
ultramodern::disable_preemption();
|
||||||
|
|
||||||
if (flags == OS_MESG_NOBLOCK) {
|
if (flags == OS_MESG_NOBLOCK) {
|
||||||
// If non-blocking, fail if the queue is full
|
// If non-blocking, fail if the queue is full
|
||||||
if (MQ_IS_FULL(mq)) {
|
if (MQ_IS_FULL(mq)) {
|
||||||
Multilibultra::enable_preemption();
|
ultramodern::enable_preemption();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, yield this thread in a loop until the queue is no longer full
|
// Otherwise, yield this thread in a loop until the queue is no longer full
|
||||||
while (MQ_IS_FULL(mq)) {
|
while (MQ_IS_FULL(mq)) {
|
||||||
debug_printf("[Message Queue] Thread %d is blocked on jam\n", TO_PTR(OSThread, Multilibultra::this_thread())->id);
|
debug_printf("[Message Queue] Thread %d is blocked on jam\n", TO_PTR(OSThread, ultramodern::this_thread())->id);
|
||||||
thread_queue_insert(PASS_RDRAM &mq->blocked_on_send, Multilibultra::this_thread());
|
thread_queue_insert(PASS_RDRAM &mq->blocked_on_send, ultramodern::this_thread());
|
||||||
Multilibultra::enable_preemption();
|
ultramodern::enable_preemption();
|
||||||
Multilibultra::pause_self(PASS_RDRAM1);
|
ultramodern::pause_self(PASS_RDRAM1);
|
||||||
Multilibultra::disable_preemption();
|
ultramodern::disable_preemption();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,14 +132,14 @@ extern "C" s32 osJamMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, s32 flags)
|
||||||
to_run = thread_queue_pop(PASS_RDRAM &mq->blocked_on_recv);
|
to_run = thread_queue_pop(PASS_RDRAM &mq->blocked_on_recv);
|
||||||
}
|
}
|
||||||
|
|
||||||
Multilibultra::enable_preemption();
|
ultramodern::enable_preemption();
|
||||||
if (to_run) {
|
if (to_run) {
|
||||||
debug_printf("[Message Queue] Thread %d is unblocked\n", to_run->id);
|
debug_printf("[Message Queue] Thread %d is unblocked\n", to_run->id);
|
||||||
OSThread *self = TO_PTR(OSThread, Multilibultra::this_thread());
|
OSThread *self = TO_PTR(OSThread, ultramodern::this_thread());
|
||||||
if (to_run->priority > self->priority) {
|
if (to_run->priority > self->priority) {
|
||||||
Multilibultra::swap_to_thread(PASS_RDRAM to_run);
|
ultramodern::swap_to_thread(PASS_RDRAM to_run);
|
||||||
} else {
|
} else {
|
||||||
Multilibultra::schedule_running_thread(to_run);
|
ultramodern::schedule_running_thread(to_run);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -148,22 +148,22 @@ extern "C" s32 osJamMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, s32 flags)
|
||||||
extern "C" s32 osRecvMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, PTR(OSMesg) msg_, s32 flags) {
|
extern "C" s32 osRecvMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, PTR(OSMesg) msg_, s32 flags) {
|
||||||
OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_);
|
OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_);
|
||||||
OSMesg *msg = TO_PTR(OSMesg, msg_);
|
OSMesg *msg = TO_PTR(OSMesg, msg_);
|
||||||
Multilibultra::disable_preemption();
|
ultramodern::disable_preemption();
|
||||||
|
|
||||||
if (flags == OS_MESG_NOBLOCK) {
|
if (flags == OS_MESG_NOBLOCK) {
|
||||||
// If non-blocking, fail if the queue is empty
|
// If non-blocking, fail if the queue is empty
|
||||||
if (MQ_IS_EMPTY(mq)) {
|
if (MQ_IS_EMPTY(mq)) {
|
||||||
Multilibultra::enable_preemption();
|
ultramodern::enable_preemption();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, yield this thread in a loop until the queue is no longer full
|
// Otherwise, yield this thread in a loop until the queue is no longer full
|
||||||
while (MQ_IS_EMPTY(mq)) {
|
while (MQ_IS_EMPTY(mq)) {
|
||||||
debug_printf("[Message Queue] Thread %d is blocked on receive\n", TO_PTR(OSThread, Multilibultra::this_thread())->id);
|
debug_printf("[Message Queue] Thread %d is blocked on receive\n", TO_PTR(OSThread, ultramodern::this_thread())->id);
|
||||||
thread_queue_insert(PASS_RDRAM &mq->blocked_on_recv, Multilibultra::this_thread());
|
thread_queue_insert(PASS_RDRAM &mq->blocked_on_recv, ultramodern::this_thread());
|
||||||
Multilibultra::enable_preemption();
|
ultramodern::enable_preemption();
|
||||||
Multilibultra::pause_self(PASS_RDRAM1);
|
ultramodern::pause_self(PASS_RDRAM1);
|
||||||
Multilibultra::disable_preemption();
|
ultramodern::disable_preemption();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,14 +180,14 @@ extern "C" s32 osRecvMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, PTR(OSMesg) msg_, s32
|
||||||
to_run = thread_queue_pop(PASS_RDRAM &mq->blocked_on_send);
|
to_run = thread_queue_pop(PASS_RDRAM &mq->blocked_on_send);
|
||||||
}
|
}
|
||||||
|
|
||||||
Multilibultra::enable_preemption();
|
ultramodern::enable_preemption();
|
||||||
if (to_run) {
|
if (to_run) {
|
||||||
debug_printf("[Message Queue] Thread %d is unblocked\n", to_run->id);
|
debug_printf("[Message Queue] Thread %d is unblocked\n", to_run->id);
|
||||||
OSThread *self = TO_PTR(OSThread, Multilibultra::this_thread());
|
OSThread *self = TO_PTR(OSThread, ultramodern::this_thread());
|
||||||
if (to_run->priority > self->priority) {
|
if (to_run->priority > self->priority) {
|
||||||
Multilibultra::swap_to_thread(PASS_RDRAM to_run);
|
ultramodern::swap_to_thread(PASS_RDRAM to_run);
|
||||||
} else {
|
} else {
|
||||||
Multilibultra::schedule_running_thread(to_run);
|
ultramodern::schedule_running_thread(to_run);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
|
@ -3,7 +3,7 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "multilibultra.hpp"
|
#include "ultramodern.hpp"
|
||||||
|
|
||||||
class OSThreadComparator {
|
class OSThreadComparator {
|
||||||
public:
|
public:
|
||||||
|
@ -134,10 +134,10 @@ void swap_running_thread(thread_queue_t& running_thread_queue, OSThread*& cur_ru
|
||||||
} else {
|
} else {
|
||||||
debug_printf("[Scheduler] Switching execution to thread %d (%d)\n", new_running_thread->id, new_running_thread->priority);
|
debug_printf("[Scheduler] Switching execution to thread %d (%d)\n", new_running_thread->id, new_running_thread->priority);
|
||||||
}
|
}
|
||||||
Multilibultra::resume_thread_impl(new_running_thread);
|
ultramodern::resume_thread_impl(new_running_thread);
|
||||||
cur_running_thread = new_running_thread;
|
cur_running_thread = new_running_thread;
|
||||||
} else if (cur_running_thread && cur_running_thread->state != OSThreadState::RUNNING) {
|
} else if (cur_running_thread && cur_running_thread->state != OSThreadState::RUNNING) {
|
||||||
Multilibultra::resume_thread_impl(cur_running_thread);
|
ultramodern::resume_thread_impl(cur_running_thread);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cur_running_thread = nullptr;
|
cur_running_thread = nullptr;
|
||||||
|
@ -191,7 +191,7 @@ extern "C" void do_yield() {
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Multilibultra {
|
namespace ultramodern {
|
||||||
|
|
||||||
void init_scheduler() {
|
void init_scheduler() {
|
||||||
scheduler_context.can_preempt = true;
|
scheduler_context.can_preempt = true;
|
||||||
|
@ -208,16 +208,16 @@ void schedule_running_thread(OSThread *t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap_to_thread(RDRAM_ARG OSThread *to) {
|
void swap_to_thread(RDRAM_ARG OSThread *to) {
|
||||||
OSThread *self = TO_PTR(OSThread, Multilibultra::this_thread());
|
OSThread *self = TO_PTR(OSThread, ultramodern::this_thread());
|
||||||
debug_printf("[Scheduler] Scheduling swap from thread %d to %d\n", self->id, to->id);
|
debug_printf("[Scheduler] Scheduling swap from thread %d to %d\n", self->id, to->id);
|
||||||
{
|
{
|
||||||
std::lock_guard lock{scheduler_context.mutex};
|
std::lock_guard lock{scheduler_context.mutex};
|
||||||
scheduler_context.to_schedule.push_back(to);
|
scheduler_context.to_schedule.push_back(to);
|
||||||
Multilibultra::set_self_paused(PASS_RDRAM1);
|
ultramodern::set_self_paused(PASS_RDRAM1);
|
||||||
scheduler_context.action_count.fetch_add(1);
|
scheduler_context.action_count.fetch_add(1);
|
||||||
scheduler_context.action_count.notify_all();
|
scheduler_context.action_count.notify_all();
|
||||||
}
|
}
|
||||||
Multilibultra::wait_for_resumed(PASS_RDRAM1);
|
ultramodern::wait_for_resumed(PASS_RDRAM1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reprioritize_thread(OSThread *t, OSPri pri) {
|
void reprioritize_thread(OSThread *t, OSPri pri) {
|
||||||
|
@ -229,16 +229,16 @@ void reprioritize_thread(OSThread *t, OSPri pri) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pause_self(RDRAM_ARG1) {
|
void pause_self(RDRAM_ARG1) {
|
||||||
OSThread *self = TO_PTR(OSThread, Multilibultra::this_thread());
|
OSThread *self = TO_PTR(OSThread, ultramodern::this_thread());
|
||||||
debug_printf("[Scheduler] Thread %d pausing itself\n", self->id);
|
debug_printf("[Scheduler] Thread %d pausing itself\n", self->id);
|
||||||
{
|
{
|
||||||
std::lock_guard lock{scheduler_context.mutex};
|
std::lock_guard lock{scheduler_context.mutex};
|
||||||
Multilibultra::set_self_paused(PASS_RDRAM1);
|
ultramodern::set_self_paused(PASS_RDRAM1);
|
||||||
scheduler_context.to_stop.push_back(self);
|
scheduler_context.to_stop.push_back(self);
|
||||||
scheduler_context.action_count.fetch_add(1);
|
scheduler_context.action_count.fetch_add(1);
|
||||||
scheduler_context.action_count.notify_all();
|
scheduler_context.action_count.notify_all();
|
||||||
}
|
}
|
||||||
Multilibultra::wait_for_resumed(PASS_RDRAM1);
|
ultramodern::wait_for_resumed(PASS_RDRAM1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_thread(OSThread *t) {
|
void cleanup_thread(OSThread *t) {
|
||||||
|
@ -250,13 +250,13 @@ void cleanup_thread(OSThread *t) {
|
||||||
|
|
||||||
void disable_preemption() {
|
void disable_preemption() {
|
||||||
scheduler_context.premption_mutex.lock();
|
scheduler_context.premption_mutex.lock();
|
||||||
if (Multilibultra::is_game_thread()) {
|
if (ultramodern::is_game_thread()) {
|
||||||
scheduler_context.can_preempt = false;
|
scheduler_context.can_preempt = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_preemption() {
|
void enable_preemption() {
|
||||||
if (Multilibultra::is_game_thread()) {
|
if (ultramodern::is_game_thread()) {
|
||||||
scheduler_context.can_preempt = true;
|
scheduler_context.can_preempt = true;
|
||||||
}
|
}
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
@ -275,6 +275,6 @@ void notify_scheduler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void pause_self(uint8_t* rdram) {
|
extern "C" void pause_self(uint8_t* rdram) {
|
||||||
Multilibultra::pause_self(rdram);
|
ultramodern::pause_self(rdram);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
#include "ultra64.h"
|
#include "ultra64.h"
|
||||||
#include "multilibultra.hpp"
|
#include "ultramodern.hpp"
|
||||||
|
|
||||||
extern "C" unsigned int sleep(unsigned int seconds) {
|
extern "C" unsigned int sleep(unsigned int seconds) {
|
||||||
Sleep(seconds * 1000);
|
Sleep(seconds * 1000);
|
|
@ -4,7 +4,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "ultra64.h"
|
#include "ultra64.h"
|
||||||
#include "multilibultra.hpp"
|
#include "ultramodern.hpp"
|
||||||
|
|
||||||
// Native APIs only used to set thread names for easier debugging
|
// Native APIs only used to set thread names for easier debugging
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -18,18 +18,18 @@ thread_local bool is_main_thread = false;
|
||||||
thread_local bool is_game_thread = false;
|
thread_local bool is_game_thread = false;
|
||||||
thread_local PTR(OSThread) thread_self = NULLPTR;
|
thread_local PTR(OSThread) thread_self = NULLPTR;
|
||||||
|
|
||||||
void Multilibultra::set_main_thread() {
|
void ultramodern::set_main_thread() {
|
||||||
::is_game_thread = true;
|
::is_game_thread = true;
|
||||||
is_main_thread = true;
|
is_main_thread = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Multilibultra::is_game_thread() {
|
bool ultramodern::is_game_thread() {
|
||||||
return ::is_game_thread;
|
return ::is_game_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
Multilibultra::set_main_thread();
|
ultramodern::set_main_thread();
|
||||||
|
|
||||||
bootproc();
|
bootproc();
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ void run_thread_function(uint8_t* rdram, uint64_t addr, uint64_t sp, uint64_t ar
|
||||||
struct thread_terminated : std::exception {};
|
struct thread_terminated : std::exception {};
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
void Multilibultra::set_native_thread_name(const std::string& name) {
|
void ultramodern::set_native_thread_name(const std::string& name) {
|
||||||
std::wstring wname{name.begin(), name.end()};
|
std::wstring wname{name.begin(), name.end()};
|
||||||
|
|
||||||
HRESULT r;
|
HRESULT r;
|
||||||
|
@ -54,7 +54,7 @@ void Multilibultra::set_native_thread_name(const std::string& name) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::set_native_thread_priority(ThreadPriority pri) {
|
void ultramodern::set_native_thread_priority(ThreadPriority pri) {
|
||||||
int nPriority = THREAD_PRIORITY_NORMAL;
|
int nPriority = THREAD_PRIORITY_NORMAL;
|
||||||
|
|
||||||
// Convert ThreadPriority to Win32 priority
|
// Convert ThreadPriority to Win32 priority
|
||||||
|
@ -81,11 +81,11 @@ void Multilibultra::set_native_thread_priority(ThreadPriority pri) {
|
||||||
// SetThreadPriority(GetCurrentThread(), nPriority);
|
// SetThreadPriority(GetCurrentThread(), nPriority);
|
||||||
}
|
}
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
void Multilibultra::set_native_thread_name(const std::string& name) {
|
void ultramodern::set_native_thread_name(const std::string& name) {
|
||||||
pthread_setname_np(pthread_self(), name.c_str());
|
pthread_setname_np(pthread_self(), name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::set_native_thread_priority(ThreadPriority pri) {
|
void ultramodern::set_native_thread_priority(ThreadPriority pri) {
|
||||||
// TODO linux thread priority
|
// TODO linux thread priority
|
||||||
printf("set_native_thread_priority unimplemented\n");
|
printf("set_native_thread_priority unimplemented\n");
|
||||||
// int nPriority = THREAD_PRIORITY_NORMAL;
|
// int nPriority = THREAD_PRIORITY_NORMAL;
|
||||||
|
@ -121,8 +121,8 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry
|
||||||
is_game_thread = true;
|
is_game_thread = true;
|
||||||
|
|
||||||
// Set the thread name
|
// Set the thread name
|
||||||
Multilibultra::set_native_thread_name("Game Thread " + std::to_string(self->id));
|
ultramodern::set_native_thread_name("Game Thread " + std::to_string(self->id));
|
||||||
Multilibultra::set_native_thread_priority(Multilibultra::ThreadPriority::High);
|
ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::High);
|
||||||
|
|
||||||
// Set initialized to false to indicate that this thread can be started.
|
// Set initialized to false to indicate that this thread can be started.
|
||||||
self->context->initialized.store(true);
|
self->context->initialized.store(true);
|
||||||
|
@ -131,8 +131,8 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry
|
||||||
debug_printf("[Thread] Thread waiting to be started: %d\n", self->id);
|
debug_printf("[Thread] Thread waiting to be started: %d\n", self->id);
|
||||||
|
|
||||||
// Wait until the thread is marked as running.
|
// Wait until the thread is marked as running.
|
||||||
Multilibultra::set_self_paused(PASS_RDRAM1);
|
ultramodern::set_self_paused(PASS_RDRAM1);
|
||||||
Multilibultra::wait_for_resumed(PASS_RDRAM1);
|
ultramodern::wait_for_resumed(PASS_RDRAM1);
|
||||||
|
|
||||||
debug_printf("[Thread] Thread started: %d\n", self->id);
|
debug_printf("[Thread] Thread started: %d\n", self->id);
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispose of this thread after it completes.
|
// Dispose of this thread after it completes.
|
||||||
Multilibultra::cleanup_thread(self);
|
ultramodern::cleanup_thread(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void osStartThread(RDRAM_ARG PTR(OSThread) t_) {
|
extern "C" void osStartThread(RDRAM_ARG PTR(OSThread) t_) {
|
||||||
|
@ -157,9 +157,9 @@ extern "C" void osStartThread(RDRAM_ARG PTR(OSThread) t_) {
|
||||||
debug_printf("[os] Thread %d is ready to be started\n", t->id);
|
debug_printf("[os] Thread %d is ready to be started\n", t->id);
|
||||||
|
|
||||||
if (thread_self && (t->priority > TO_PTR(OSThread, thread_self)->priority)) {
|
if (thread_self && (t->priority > TO_PTR(OSThread, thread_self)->priority)) {
|
||||||
Multilibultra::swap_to_thread(PASS_RDRAM t);
|
ultramodern::swap_to_thread(PASS_RDRAM t);
|
||||||
} else {
|
} else {
|
||||||
Multilibultra::schedule_running_thread(t);
|
ultramodern::schedule_running_thread(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,14 +206,14 @@ extern "C" void osSetThreadPri(RDRAM_ARG PTR(OSThread) t, OSPri pri) {
|
||||||
bool pause_self = false;
|
bool pause_self = false;
|
||||||
if (pri > TO_PTR(OSThread, thread_self)->priority) {
|
if (pri > TO_PTR(OSThread, thread_self)->priority) {
|
||||||
pause_self = true;
|
pause_self = true;
|
||||||
Multilibultra::set_self_paused(PASS_RDRAM1);
|
ultramodern::set_self_paused(PASS_RDRAM1);
|
||||||
} else if (t == thread_self && pri < TO_PTR(OSThread, thread_self)->priority) {
|
} else if (t == thread_self && pri < TO_PTR(OSThread, thread_self)->priority) {
|
||||||
pause_self = true;
|
pause_self = true;
|
||||||
Multilibultra::set_self_paused(PASS_RDRAM1);
|
ultramodern::set_self_paused(PASS_RDRAM1);
|
||||||
}
|
}
|
||||||
Multilibultra::reprioritize_thread(TO_PTR(OSThread, t), pri);
|
ultramodern::reprioritize_thread(TO_PTR(OSThread, t), pri);
|
||||||
if (pause_self) {
|
if (pause_self) {
|
||||||
Multilibultra::wait_for_resumed(PASS_RDRAM1);
|
ultramodern::wait_for_resumed(PASS_RDRAM1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ extern "C" OSId osGetThreadId(RDRAM_ARG PTR(OSThread) t) {
|
||||||
|
|
||||||
// TODO yield thread, need a stable priority queue in the scheduler
|
// TODO yield thread, need a stable priority queue in the scheduler
|
||||||
|
|
||||||
void Multilibultra::set_self_paused(RDRAM_ARG1) {
|
void ultramodern::set_self_paused(RDRAM_ARG1) {
|
||||||
debug_printf("[Thread] Thread pausing itself: %d\n", TO_PTR(OSThread, thread_self)->id);
|
debug_printf("[Thread] Thread pausing itself: %d\n", TO_PTR(OSThread, thread_self)->id);
|
||||||
TO_PTR(OSThread, thread_self)->state = OSThreadState::PAUSED;
|
TO_PTR(OSThread, thread_self)->state = OSThreadState::PAUSED;
|
||||||
TO_PTR(OSThread, thread_self)->context->running.store(false);
|
TO_PTR(OSThread, thread_self)->context->running.store(false);
|
||||||
|
@ -246,19 +246,19 @@ void check_destroyed(OSThread* t) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::wait_for_resumed(RDRAM_ARG1) {
|
void ultramodern::wait_for_resumed(RDRAM_ARG1) {
|
||||||
check_destroyed(TO_PTR(OSThread, thread_self));
|
check_destroyed(TO_PTR(OSThread, thread_self));
|
||||||
TO_PTR(OSThread, thread_self)->context->running.wait(false);
|
TO_PTR(OSThread, thread_self)->context->running.wait(false);
|
||||||
check_destroyed(TO_PTR(OSThread, thread_self));
|
check_destroyed(TO_PTR(OSThread, thread_self));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::pause_thread_impl(OSThread* t) {
|
void ultramodern::pause_thread_impl(OSThread* t) {
|
||||||
t->state = OSThreadState::PREEMPTED;
|
t->state = OSThreadState::PREEMPTED;
|
||||||
t->context->running.store(false);
|
t->context->running.store(false);
|
||||||
t->context->running.notify_all();
|
t->context->running.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::resume_thread_impl(OSThread *t) {
|
void ultramodern::resume_thread_impl(OSThread *t) {
|
||||||
if (t->state == OSThreadState::PREEMPTED) {
|
if (t->state == OSThreadState::PREEMPTED) {
|
||||||
// Nothing to do here
|
// Nothing to do here
|
||||||
}
|
}
|
||||||
|
@ -267,6 +267,6 @@ void Multilibultra::resume_thread_impl(OSThread *t) {
|
||||||
t->context->running.notify_all();
|
t->context->running.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
PTR(OSThread) Multilibultra::this_thread() {
|
PTR(OSThread) ultramodern::this_thread() {
|
||||||
return thread_self;
|
return thread_self;
|
||||||
}
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
#include "blockingconcurrentqueue.h"
|
#include "blockingconcurrentqueue.h"
|
||||||
|
|
||||||
#include "ultra64.h"
|
#include "ultra64.h"
|
||||||
#include "multilibultra.hpp"
|
#include "ultramodern.hpp"
|
||||||
|
|
||||||
// Start time for the program
|
// Start time for the program
|
||||||
static std::chrono::system_clock::time_point start_time = std::chrono::system_clock::now();
|
static std::chrono::system_clock::time_point start_time = std::chrono::system_clock::now();
|
||||||
|
@ -60,8 +60,8 @@ uint64_t time_now() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_thread(RDRAM_ARG1) {
|
void timer_thread(RDRAM_ARG1) {
|
||||||
Multilibultra::set_native_thread_name("Timer Thread");
|
ultramodern::set_native_thread_name("Timer Thread");
|
||||||
Multilibultra::set_native_thread_priority(Multilibultra::ThreadPriority::VeryHigh);
|
ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::VeryHigh);
|
||||||
|
|
||||||
// Lambda comparator function to keep the set ordered
|
// Lambda comparator function to keep the set ordered
|
||||||
auto timer_sort = [PASS_RDRAM1](PTR(OSTimer) a_, PTR(OSTimer) b_) {
|
auto timer_sort = [PASS_RDRAM1](PTR(OSTimer) a_, PTR(OSTimer) b_) {
|
||||||
|
@ -134,20 +134,20 @@ void timer_thread(RDRAM_ARG1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Multilibultra::init_timers(RDRAM_ARG1) {
|
void ultramodern::init_timers(RDRAM_ARG1) {
|
||||||
timer_context.thread = std::thread{ timer_thread, PASS_RDRAM1 };
|
timer_context.thread = std::thread{ timer_thread, PASS_RDRAM1 };
|
||||||
timer_context.thread.detach();
|
timer_context.thread.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Multilibultra::get_speed_multiplier() {
|
uint32_t ultramodern::get_speed_multiplier() {
|
||||||
return speed_multiplier;
|
return speed_multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::system_clock::time_point Multilibultra::get_start() {
|
std::chrono::system_clock::time_point ultramodern::get_start() {
|
||||||
return start_time;
|
return start_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::system_clock::duration Multilibultra::time_since_start() {
|
std::chrono::system_clock::duration ultramodern::time_since_start() {
|
||||||
return std::chrono::system_clock::now() - start_time;
|
return std::chrono::system_clock::now() - start_time;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef __ULTRA64_MULTILIBULTRA_H__
|
#ifndef __ULTRA64_ultramodern_H__
|
||||||
#define __ULTRA64_MULTILIBULTRA_H__
|
#define __ULTRA64_ultramodern_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "ultra64.h"
|
||||||
|
#include "ultramodern.hpp"
|
||||||
|
|
||||||
|
void ultramodern::preinit(uint8_t* rdram, uint8_t* rom, ultramodern::WindowHandle window_handle) {
|
||||||
|
ultramodern::set_main_thread();
|
||||||
|
ultramodern::init_events(rdram, rom, window_handle);
|
||||||
|
ultramodern::init_timers(rdram);
|
||||||
|
ultramodern::init_audio();
|
||||||
|
ultramodern::save_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void osInitialize() {
|
||||||
|
ultramodern::init_scheduler();
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef __MULTILIBULTRA_HPP__
|
#ifndef __ultramodern_HPP__
|
||||||
#define __MULTILIBULTRA_HPP__
|
#define __ultramodern_HPP__
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
@ -26,7 +26,7 @@ struct UltraThreadContext {
|
||||||
std::atomic_bool initialized;
|
std::atomic_bool initialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Multilibultra {
|
namespace ultramodern {
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
// Native HWND handle to the target window.
|
// Native HWND handle to the target window.
|
||||||
|
@ -128,7 +128,7 @@ bool is_game_started();
|
||||||
void quit();
|
void quit();
|
||||||
void join_event_threads();
|
void join_event_threads();
|
||||||
|
|
||||||
} // namespace Multilibultra
|
} // namespace ultramodern
|
||||||
|
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
Loading…
Reference in New Issue