mirror of
https://github.com/N64Recomp/N64ModernRuntime.git
synced 2025-10-30 08:02:29 +00:00
Compare commits
2 commits
0a5830d962
...
c75f35be57
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c75f35be57 | ||
|
|
d34934aa7e |
13 changed files with 309 additions and 13 deletions
|
|
@ -5,6 +5,8 @@ set(CMAKE_CXX_STANDARD 20)
|
|||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
set(LIBRECOMP_TRACY_PATH "" CACHE STRING "Include path for Tracy library, if used.")
|
||||
|
||||
# Define the library
|
||||
add_library(librecomp STATIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/ai.cpp"
|
||||
|
|
@ -52,6 +54,11 @@ target_compile_options(librecomp PRIVATE
|
|||
-Wno-unused-parameter
|
||||
)
|
||||
|
||||
if(NOT LIBRECOMP_TRACY_PATH STREQUAL "")
|
||||
target_compile_definitions(librecomp PRIVATE "TRACY_ENABLED")
|
||||
target_include_directories(librecomp PRIVATE ${ULTRAMODERN_TRACY_PATH})
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
add_compile_definitions(NOMINMAX)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <string>
|
||||
#include <ultramodern/ultra64.h>
|
||||
#include <ultramodern/ultramodern.hpp>
|
||||
#include <ultramodern/ultramodern_tracy.hpp>
|
||||
|
||||
#define VI_NTSC_CLOCK 48681812
|
||||
|
||||
|
|
@ -13,9 +14,13 @@ extern "C" void osAiSetFrequency_recomp(uint8_t* rdram, recomp_context* ctx) {
|
|||
//freq = VI_NTSC_CLOCK / dacRate;
|
||||
ctx->r2 = freq;
|
||||
ultramodern::set_audio_frequency(freq);
|
||||
|
||||
std::string tracy_message = "Set AI Freq: " + std::to_string(freq);
|
||||
TracyMessage(tracy_message.c_str(), tracy_message.size() + 1);
|
||||
}
|
||||
|
||||
extern "C" void osAiSetNextBuffer_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||
ZoneScoped;
|
||||
ultramodern::queue_audio_buffer(rdram, ctx->r4, ctx->r5);
|
||||
ctx->r2 = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "librecomp/files.hpp"
|
||||
#include <ultramodern/ultra64.h>
|
||||
#include <ultramodern/ultramodern.hpp>
|
||||
#include <ultramodern/ultramodern_tracy.hpp>
|
||||
|
||||
static std::vector<uint8_t> rom;
|
||||
|
||||
|
|
@ -310,6 +311,7 @@ void do_dma(RDRAM_ARG PTR(OSMesgQueue) mq, gpr rdram_address, uint32_t physical_
|
|||
}
|
||||
|
||||
extern "C" void osPiStartDma_recomp(RDRAM_ARG recomp_context* ctx) {
|
||||
ZoneScoped;
|
||||
uint32_t mb = ctx->r4;
|
||||
uint32_t pri = ctx->r5;
|
||||
uint32_t direction = ctx->r6;
|
||||
|
|
@ -327,6 +329,7 @@ extern "C" void osPiStartDma_recomp(RDRAM_ARG recomp_context* ctx) {
|
|||
}
|
||||
|
||||
extern "C" void osEPiStartDma_recomp(RDRAM_ARG recomp_context* ctx) {
|
||||
ZoneScoped;
|
||||
OSPiHandle* handle = TO_PTR(OSPiHandle, ctx->r4);
|
||||
OSIoMesg* mb = TO_PTR(OSIoMesg, ctx->r5);
|
||||
uint32_t direction = ctx->r6;
|
||||
|
|
@ -344,6 +347,7 @@ extern "C" void osEPiStartDma_recomp(RDRAM_ARG recomp_context* ctx) {
|
|||
}
|
||||
|
||||
extern "C" void osEPiReadIo_recomp(RDRAM_ARG recomp_context * ctx) {
|
||||
ZoneScoped;
|
||||
OSPiHandle* handle = TO_PTR(OSPiHandle, ctx->r4);
|
||||
uint32_t devAddr = handle->baseAddress | ctx->r5;
|
||||
gpr dramAddr = ctx->r6;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <ultramodern/ultramodern.hpp>
|
||||
#include <ultramodern/ultramodern_tracy.hpp>
|
||||
#include "recomp.h"
|
||||
|
||||
extern "C" void osSpTaskLoad_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||
|
|
@ -10,6 +11,7 @@ extern "C" void osSpTaskLoad_recomp(uint8_t* rdram, recomp_context* ctx) {
|
|||
bool dump_frame = false;
|
||||
|
||||
extern "C" void osSpTaskStartGo_recomp(uint8_t* rdram, recomp_context* ctx) {
|
||||
ZoneScoped;
|
||||
//printf("[sp] osSpTaskStartGo(0x%08X)\n", (uint32_t)ctx->r4);
|
||||
OSTask* task = TO_PTR(OSTask, ctx->r4);
|
||||
if (task->t.type == M_GFXTASK) {
|
||||
|
|
|
|||
|
|
@ -73,12 +73,21 @@ extern "C" void osGetCount_recomp(uint8_t * rdram, recomp_context * ctx) {
|
|||
ctx->r2 = osGetCount();
|
||||
}
|
||||
|
||||
extern "C" void osSetCount_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||
osSetCount(ctx->r4);
|
||||
}
|
||||
|
||||
extern "C" void osGetTime_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||
uint64_t total_count = osGetTime();
|
||||
ctx->r2 = (int32_t)(total_count >> 32);
|
||||
ctx->r3 = (int32_t)(total_count >> 0);
|
||||
}
|
||||
|
||||
extern "C" void osSetTime_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||
uint64_t t = ((uint64_t)(ctx->r4) << 32) | ((ctx->r5) & 0xFFFFFFFFu);
|
||||
osSetTime(t);
|
||||
}
|
||||
|
||||
extern "C" void osSetTimer_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||
uint64_t countdown = ((uint64_t)(ctx->r6) << 32) | ((ctx->r7) & 0xFFFFFFFFu);
|
||||
uint64_t interval = load_doubleword(rdram, ctx->r29, 0x10);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ set(CMAKE_CXX_STANDARD 20)
|
|||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
set(ULTRAMODERN_TRACY_PATH "" CACHE STRING "Include path for Tracy library, if used.")
|
||||
|
||||
add_library(ultramodern STATIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/audio.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/error_handling.cpp"
|
||||
|
|
@ -35,6 +37,11 @@ target_compile_options(ultramodern PRIVATE
|
|||
-Wno-unused-parameter
|
||||
)
|
||||
|
||||
if(NOT ULTRAMODERN_TRACY_PATH STREQUAL "")
|
||||
target_compile_definitions(ultramodern PRIVATE "TRACY_ENABLED")
|
||||
target_include_directories(ultramodern PRIVATE ${ULTRAMODERN_TRACY_PATH})
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
add_compile_definitions(NOMINMAX)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -290,7 +290,9 @@ void osViSetYScale(float scale);
|
|||
PTR(void) osViGetNextFramebuffer();
|
||||
PTR(void) osViGetCurrentFramebuffer();
|
||||
u32 osGetCount();
|
||||
void osSetCount(u32 count);
|
||||
OSTime osGetTime();
|
||||
void osSetTime(OSTime t);
|
||||
int osSetTimer(RDRAM_ARG PTR(OSTimer) timer, OSTime countdown, OSTime interval, PTR(OSMesgQueue) mq, OSMesg msg);
|
||||
int osStopTimer(RDRAM_ARG PTR(OSTimer) timer);
|
||||
u32 osVirtualToPhysical(PTR(void) addr);
|
||||
|
|
|
|||
218
ultramodern/include/ultramodern/ultramodern_tracy.hpp
Normal file
218
ultramodern/include/ultramodern/ultramodern_tracy.hpp
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
#ifndef __ULTRAMODERN_TRACY_H__
|
||||
#define __ULTRAMODERN_TRACY_H__
|
||||
|
||||
#ifdef TRACY_ENABLED
|
||||
# define TRACY_ENABLE
|
||||
# include <tracy/Tracy.hpp>
|
||||
# include <tracy/TracyC.h>
|
||||
|
||||
namespace tracy {
|
||||
void SetThreadName( const char* name );
|
||||
void SetThreadNameWithHint( const char* name, int32_t groupHint );
|
||||
const char* GetThreadName( uint32_t id );
|
||||
|
||||
const char* GetEnvVar( const char* name );
|
||||
}
|
||||
|
||||
#define TracySetThreadName(name) tracy::SetThreadName(name)
|
||||
#define TracySetThreadNameWithHint(name, groupHint) tracy::SetThreadNameWithHint(name, groupHint)
|
||||
|
||||
#else
|
||||
|
||||
// C++ API
|
||||
|
||||
# define TracyNoop
|
||||
|
||||
# define ZoneNamed(x,y)
|
||||
# define ZoneNamedN(x,y,z)
|
||||
# define ZoneNamedC(x,y,z)
|
||||
# define ZoneNamedNC(x,y,z,w)
|
||||
|
||||
# define ZoneTransient(x,y)
|
||||
# define ZoneTransientN(x,y,z)
|
||||
|
||||
# define ZoneScoped
|
||||
# define ZoneScopedN(x)
|
||||
# define ZoneScopedC(x)
|
||||
# define ZoneScopedNC(x,y)
|
||||
|
||||
# define ZoneText(x,y)
|
||||
# define ZoneTextV(x,y,z)
|
||||
# define ZoneTextF(x,...)
|
||||
# define ZoneTextVF(x,y,...)
|
||||
# define ZoneName(x,y)
|
||||
# define ZoneNameV(x,y,z)
|
||||
# define ZoneNameF(x,...)
|
||||
# define ZoneNameVF(x,y,...)
|
||||
# define ZoneColor(x)
|
||||
# define ZoneColorV(x,y)
|
||||
# define ZoneValue(x)
|
||||
# define ZoneValueV(x,y)
|
||||
# define ZoneIsActive false
|
||||
# define ZoneIsActiveV(x) false
|
||||
|
||||
# define FrameMark
|
||||
# define FrameMarkNamed(x)
|
||||
# define FrameMarkStart(x)
|
||||
# define FrameMarkEnd(x)
|
||||
|
||||
# define FrameImage(x,y,z,w,a)
|
||||
|
||||
# define TracyLockable( type, varname ) type varname
|
||||
# define TracyLockableN( type, varname, desc ) type varname
|
||||
# define TracySharedLockable( type, varname ) type varname
|
||||
# define TracySharedLockableN( type, varname, desc ) type varname
|
||||
# define LockableBase( type ) type
|
||||
# define SharedLockableBase( type ) type
|
||||
# define LockMark(x) (void)x
|
||||
# define LockableName(x,y,z)
|
||||
|
||||
# define TracyPlot(x,y)
|
||||
# define TracyPlotConfig(x,y,z,w,a)
|
||||
|
||||
# define TracyMessage(x,y)
|
||||
# define TracyMessageL(x)
|
||||
# define TracyMessageC(x,y,z)
|
||||
# define TracyMessageLC(x,y)
|
||||
# define TracyAppInfo(x,y)
|
||||
|
||||
# define TracyAlloc(x,y)
|
||||
# define TracyFree(x)
|
||||
# define TracySecureAlloc(x,y)
|
||||
# define TracySecureFree(x)
|
||||
|
||||
# define TracyAllocN(x,y,z)
|
||||
# define TracyFreeN(x,y)
|
||||
# define TracySecureAllocN(x,y,z)
|
||||
# define TracySecureFreeN(x,y)
|
||||
|
||||
# define ZoneNamedS(x,y,z)
|
||||
# define ZoneNamedNS(x,y,z,w)
|
||||
# define ZoneNamedCS(x,y,z,w)
|
||||
# define ZoneNamedNCS(x,y,z,w,a)
|
||||
|
||||
# define ZoneTransientS(x,y,z)
|
||||
# define ZoneTransientNS(x,y,z,w)
|
||||
|
||||
# define ZoneScopedS(x)
|
||||
# define ZoneScopedNS(x,y)
|
||||
# define ZoneScopedCS(x,y)
|
||||
# define ZoneScopedNCS(x,y,z)
|
||||
|
||||
# define TracyAllocS(x,y,z)
|
||||
# define TracyFreeS(x,y)
|
||||
# define TracySecureAllocS(x,y,z)
|
||||
# define TracySecureFreeS(x,y)
|
||||
|
||||
# define TracyAllocNS(x,y,z,w)
|
||||
# define TracyFreeNS(x,y,z)
|
||||
# define TracySecureAllocNS(x,y,z,w)
|
||||
# define TracySecureFreeNS(x,y,z)
|
||||
|
||||
# define TracyMessageS(x,y,z)
|
||||
# define TracyMessageLS(x,y)
|
||||
# define TracyMessageCS(x,y,z,w)
|
||||
# define TracyMessageLCS(x,y,z)
|
||||
|
||||
# define TracySourceCallbackRegister(x,y)
|
||||
# define TracyParameterRegister(x,y)
|
||||
# define TracyParameterSetup(x,y,z,w)
|
||||
# define TracyIsConnected false
|
||||
# define TracyIsStarted false
|
||||
# define TracySetProgramName(x)
|
||||
|
||||
# define TracyFiberEnter(x)
|
||||
# define TracyFiberEnterHint(x,y)
|
||||
# define TracyFiberLeave
|
||||
|
||||
// C API
|
||||
|
||||
typedef const void* TracyCZoneCtx;
|
||||
|
||||
typedef const void* TracyCLockCtx;
|
||||
|
||||
# define TracyCZone(c,x)
|
||||
# define TracyCZoneN(c,x,y)
|
||||
# define TracyCZoneC(c,x,y)
|
||||
# define TracyCZoneNC(c,x,y,z)
|
||||
# define TracyCZoneEnd(c)
|
||||
# define TracyCZoneText(c,x,y)
|
||||
# define TracyCZoneName(c,x,y)
|
||||
# define TracyCZoneColor(c,x)
|
||||
# define TracyCZoneValue(c,x)
|
||||
|
||||
# define TracyCAlloc(x,y)
|
||||
# define TracyCFree(x)
|
||||
# define TracyCMemoryDiscard(x)
|
||||
# define TracyCSecureAlloc(x,y)
|
||||
# define TracyCSecureFree(x)
|
||||
# define TracyCSecureMemoryDiscard(x)
|
||||
|
||||
# define TracyCAllocN(x,y,z)
|
||||
# define TracyCFreeN(x,y)
|
||||
# define TracyCSecureAllocN(x,y,z)
|
||||
# define TracyCSecureFreeN(x,y)
|
||||
|
||||
# define TracyCFrameMark
|
||||
# define TracyCFrameMarkNamed(x)
|
||||
# define TracyCFrameMarkStart(x)
|
||||
# define TracyCFrameMarkEnd(x)
|
||||
# define TracyCFrameImage(x,y,z,w,a)
|
||||
|
||||
# define TracyCPlot(x,y)
|
||||
# define TracyCPlotF(x,y)
|
||||
# define TracyCPlotI(x,y)
|
||||
# define TracyCPlotConfig(x,y,z,w,a)
|
||||
|
||||
# define TracyCMessage(x,y)
|
||||
# define TracyCMessageL(x)
|
||||
# define TracyCMessageC(x,y,z)
|
||||
# define TracyCMessageLC(x,y)
|
||||
# define TracyCAppInfo(x,y)
|
||||
|
||||
# define TracyCZoneS(x,y,z)
|
||||
# define TracyCZoneNS(x,y,z,w)
|
||||
# define TracyCZoneCS(x,y,z,w)
|
||||
# define TracyCZoneNCS(x,y,z,w,a)
|
||||
|
||||
# define TracyCAllocS(x,y,z)
|
||||
# define TracyCFreeS(x,y)
|
||||
# define TracyCMemoryDiscardS(x,y)
|
||||
# define TracyCSecureAllocS(x,y,z)
|
||||
# define TracyCSecureFreeS(x,y)
|
||||
# define TracyCSecureMemoryDiscardS(x,y)
|
||||
|
||||
# define TracyCAllocNS(x,y,z,w)
|
||||
# define TracyCFreeNS(x,y,z)
|
||||
# define TracyCSecureAllocNS(x,y,z,w)
|
||||
# define TracyCSecureFreeNS(x,y,z)
|
||||
|
||||
# define TracyCMessageS(x,y,z)
|
||||
# define TracyCMessageLS(x,y)
|
||||
# define TracyCMessageCS(x,y,z,w)
|
||||
# define TracyCMessageLCS(x,y,z)
|
||||
|
||||
# define TracyCLockCtx(l)
|
||||
# define TracyCLockAnnounce(l)
|
||||
# define TracyCLockTerminate(l)
|
||||
# define TracyCLockBeforeLock(l)
|
||||
# define TracyCLockAfterLock(l)
|
||||
# define TracyCLockAfterUnlock(l)
|
||||
# define TracyCLockAfterTryLock(l,x)
|
||||
# define TracyCLockMark(l)
|
||||
# define TracyCLockCustomName(l,x,y)
|
||||
|
||||
# define TracyCIsConnected 0
|
||||
# define TracyCIsStarted 0
|
||||
|
||||
# define TracyCFiberEnter(fiber)
|
||||
# define TracyCFiberLeave
|
||||
|
||||
// Other tracy functions
|
||||
|
||||
#define TracySetThreadName(name)
|
||||
#define TracySetThreadNameWithHint(name, groupHint)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "ultramodern/ultra64.h"
|
||||
#include "ultramodern/ultramodern.hpp"
|
||||
#include "ultramodern/ultramodern_tracy.hpp"
|
||||
|
||||
#include "ultramodern/rsp.hpp"
|
||||
#include "ultramodern/renderer_context.hpp"
|
||||
|
|
@ -28,6 +29,7 @@ struct SpTaskAction {
|
|||
};
|
||||
|
||||
struct ScreenUpdateAction {
|
||||
ultramodern::renderer::ViRegs regs;
|
||||
};
|
||||
|
||||
struct UpdateConfigAction {
|
||||
|
|
@ -55,6 +57,7 @@ static struct {
|
|||
int field;
|
||||
ViState states[2];
|
||||
ultramodern::renderer::ViRegs regs;
|
||||
ultramodern::renderer::ViRegs update_screen_regs;
|
||||
|
||||
ViState* get_next_state() {
|
||||
return &states[cur_state ^ 1];
|
||||
|
|
@ -131,7 +134,7 @@ static struct {
|
|||
} events_context{};
|
||||
|
||||
ultramodern::renderer::ViRegs* ultramodern::renderer::get_vi_regs() {
|
||||
return &events_context.vi.regs;
|
||||
return &events_context.vi.update_screen_regs;
|
||||
}
|
||||
|
||||
extern "C" void osSetEventMesg(RDRAM_ARG OSEvent event_id, PTR(OSMesgQueue) mq_, OSMesg msg) {
|
||||
|
|
@ -198,8 +201,9 @@ void vi_thread_func() {
|
|||
next = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
ultramodern::sleep_until(next);
|
||||
auto time_now = ultramodern::time_since_start();
|
||||
// Calculate how many VIs have passed
|
||||
uint64_t new_total_vis = (ultramodern::time_since_start() * (60 * ultramodern::get_speed_multiplier()) / 1000ms) + 1;
|
||||
uint64_t new_total_vis = (time_now * (60 * ultramodern::get_speed_multiplier()) / 1000ms) + 1;
|
||||
if (new_total_vis > total_vis + 1) {
|
||||
//printf("Skipped % " PRId64 " frames in VI interupt thread!\n", new_total_vis - total_vis - 1);
|
||||
}
|
||||
|
|
@ -212,12 +216,13 @@ void vi_thread_func() {
|
|||
odd = !odd;
|
||||
}
|
||||
|
||||
// Queue a screen update for the graphics thread with the current VI register state.
|
||||
// Doing this before the VI update is equivalent to updating the screen after the previous frame's scanout finished.
|
||||
events_context.action_queue.enqueue(ScreenUpdateAction{ events_context.vi.regs });
|
||||
|
||||
// Update VI registers and swap VI modes.
|
||||
events_context.vi.update_vi();
|
||||
|
||||
// Queue a screen update for the graphics thread.
|
||||
events_context.action_queue.enqueue(ScreenUpdateAction{ });
|
||||
|
||||
// If the game has started, handle sending VI and AI events.
|
||||
if (ultramodern::is_game_started()) {
|
||||
remaining_retraces--;
|
||||
|
|
@ -226,15 +231,16 @@ void vi_thread_func() {
|
|||
std::lock_guard lock{ events_context.message_mutex };
|
||||
ViState* cur_state = events_context.vi.get_cur_state();
|
||||
if (remaining_retraces == 0) {
|
||||
remaining_retraces = cur_state->retrace_count;
|
||||
|
||||
if (cur_state->mq != NULLPTR) {
|
||||
TracyMessageL("VI Event");
|
||||
if (osSendMesg(PASS_RDRAM cur_state->mq, cur_state->msg, OS_MESG_NOBLOCK) == -1) {
|
||||
//printf("Game skipped a VI frame!\n");
|
||||
}
|
||||
}
|
||||
remaining_retraces = cur_state->retrace_count;
|
||||
}
|
||||
if (events_context.ai.mq != NULLPTR) {
|
||||
TracyMessageL("AI Event");
|
||||
if (osSendMesg(PASS_RDRAM events_context.ai.mq, events_context.ai.msg, OS_MESG_NOBLOCK) == -1) {
|
||||
//printf("Game skipped a AI frame!\n");
|
||||
}
|
||||
|
|
@ -364,13 +370,16 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re
|
|||
ultramodern::measure_input_latency();
|
||||
|
||||
[[maybe_unused]] auto renderer_start = std::chrono::high_resolution_clock::now();
|
||||
{
|
||||
ZoneScopedN("Displaylist");
|
||||
renderer_context->send_dl(&task_action->task);
|
||||
}
|
||||
[[maybe_unused]] auto renderer_end = std::chrono::high_resolution_clock::now();
|
||||
dp_complete();
|
||||
// printf("Renderer ProcessDList time: %d us\n", static_cast<u32>(std::chrono::duration_cast<std::chrono::microseconds>(renderer_end - renderer_start).count()));
|
||||
}
|
||||
else if (const auto* screen_update_action = std::get_if<ScreenUpdateAction>(&action)) {
|
||||
(void)screen_update_action;
|
||||
events_context.vi.update_screen_regs = screen_update_action->regs;
|
||||
renderer_context->update_screen();
|
||||
display_refresh_rate = renderer_context->get_display_framerate();
|
||||
resolution_scale = renderer_context->get_resolution_scale();
|
||||
|
|
@ -441,6 +450,7 @@ void set_dummy_vi(bool odd) {
|
|||
}
|
||||
|
||||
extern "C" void osViSwapBuffer(RDRAM_ARG PTR(void) frameBufPtr) {
|
||||
ZoneScoped;
|
||||
std::lock_guard lock{ events_context.message_mutex };
|
||||
events_context.vi.get_next_state()->framebuffer = frameBufPtr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "ultramodern/input.hpp"
|
||||
#include "ultramodern/ultra64.h"
|
||||
#include "ultramodern/ultramodern.hpp"
|
||||
#include "ultramodern/ultramodern_tracy.hpp"
|
||||
|
||||
static ultramodern::input::callbacks_t input_callbacks {};
|
||||
|
||||
|
|
@ -104,6 +105,7 @@ extern "C" s32 osContStartQuery(RDRAM_ARG PTR(OSMesgQueue) mq) {
|
|||
}
|
||||
|
||||
extern "C" s32 osContStartReadData(RDRAM_ARG PTR(OSMesgQueue) mq) {
|
||||
ZoneScoped;
|
||||
if (input_callbacks.poll_input != nullptr) {
|
||||
input_callbacks.poll_input();
|
||||
}
|
||||
|
|
@ -128,6 +130,7 @@ extern "C" void osContGetQuery(RDRAM_ARG PTR(OSContStatus) data_) {
|
|||
}
|
||||
|
||||
extern "C" void osContGetReadData(OSContPad *data) {
|
||||
ZoneScoped;
|
||||
for (int controller = 0; controller < max_controllers; controller++) {
|
||||
uint16_t buttons = 0;
|
||||
float x = 0.0f;
|
||||
|
|
@ -168,6 +171,7 @@ s32 osMotorStart(RDRAM_ARG PTR(OSPfs) pfs) {
|
|||
}
|
||||
|
||||
s32 __osMotorAccess(RDRAM_ARG PTR(OSPfs) pfs_, s32 flag) {
|
||||
ZoneScoped;
|
||||
OSPfs *pfs = TO_PTR(OSPfs, pfs_);
|
||||
|
||||
if (input_callbacks.set_rumble != nullptr) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <cstring>
|
||||
|
||||
#include "ultramodern/rsp.hpp"
|
||||
#include "ultramodern/ultramodern_tracy.hpp"
|
||||
|
||||
static ultramodern::rsp::callbacks_t rsp_callbacks {};
|
||||
|
||||
|
|
@ -16,6 +17,7 @@ void ultramodern::rsp::init() {
|
|||
}
|
||||
|
||||
bool ultramodern::rsp::run_task(RDRAM_ARG const OSTask* task) {
|
||||
ZoneScoped;
|
||||
assert(rsp_callbacks.run_task != nullptr);
|
||||
|
||||
return rsp_callbacks.run_task(PASS_RDRAM task);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "ultramodern/ultra64.h"
|
||||
#include "ultramodern/ultramodern.hpp"
|
||||
#include "ultramodern/ultramodern_tracy.hpp"
|
||||
#include "blockingconcurrentqueue.h"
|
||||
|
||||
#include "ultramodern/threads.hpp"
|
||||
|
|
@ -146,8 +147,14 @@ void ultramodern::set_native_thread_name(const std::string& name) {
|
|||
void ultramodern::set_native_thread_priority(ThreadPriority pri) {}
|
||||
#endif
|
||||
|
||||
void wait_for_resumed(RDRAM_ARG UltraThreadContext* thread_context) {
|
||||
void wait_for_resumed(RDRAM_ARG UltraThreadContext* thread_context, bool first_start = false) {
|
||||
if (!first_start) {
|
||||
// TracyMessageL("Pause");
|
||||
}
|
||||
thread_context->running.wait();
|
||||
if (!first_start) {
|
||||
// TracyMessageL("Resume");
|
||||
}
|
||||
// If this thread's context was replaced by another thread or deleted, destroy it again from its own context.
|
||||
// This will trigger thread cleanup instead.
|
||||
if (TO_PTR(OSThread, ultramodern::this_thread())->context != thread_context) {
|
||||
|
|
@ -189,9 +196,15 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry
|
|||
is_game_thread = true;
|
||||
|
||||
// Set the thread name
|
||||
ultramodern::set_native_thread_name(ultramodern::threads::get_game_thread_name(self));
|
||||
std::string thread_name = ultramodern::threads::get_game_thread_name(self);
|
||||
|
||||
// Copy the thread name into the fixed address buffer (for profiling).
|
||||
ultramodern::set_native_thread_name(thread_name);
|
||||
ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::High);
|
||||
|
||||
// Set the thread name in tracy and the thread group to 0x1064 to indicate a game thread.
|
||||
TracySetThreadNameWithHint(thread_name.c_str(), 0x1064);
|
||||
|
||||
// Signal the initialized semaphore to indicate that this thread can be started.
|
||||
thread_context->initialized.signal();
|
||||
|
||||
|
|
@ -199,10 +212,13 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry
|
|||
|
||||
// Wait until the thread is marked as running.
|
||||
try {
|
||||
wait_for_resumed(PASS_RDRAM thread_context);
|
||||
ZoneScopedN("Wait for Start");
|
||||
wait_for_resumed(PASS_RDRAM thread_context, true);
|
||||
} catch (ultramodern::thread_terminated& terminated) {
|
||||
}
|
||||
|
||||
TracyMessageL("Start");
|
||||
|
||||
// Make sure the thread wasn't replaced or destroyed before it was started.
|
||||
if (self->context == thread_context) {
|
||||
debug_printf("[Thread] Thread started: %d\n", self->id);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
// Start time for the program
|
||||
static std::chrono::high_resolution_clock::time_point start_time = std::chrono::high_resolution_clock::now();
|
||||
// Offset of the duration since program start used to calculate the value for osGetTime.
|
||||
static int64_t ostime_offset = 0;
|
||||
// Game speed multiplier (1 means no speedup)
|
||||
constexpr uint32_t speed_multiplier = 1;
|
||||
// N64 CPU counter ticks per millisecond
|
||||
|
|
@ -162,12 +164,20 @@ extern "C" u32 osGetCount() {
|
|||
return (uint32_t)total_count;
|
||||
}
|
||||
|
||||
extern "C" void osSetCount(u32 count) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
extern "C" OSTime osGetTime() {
|
||||
uint64_t total_count = time_now();
|
||||
uint64_t total_count = time_now() - ostime_offset;
|
||||
|
||||
return total_count;
|
||||
}
|
||||
|
||||
extern "C" void osSetTime(OSTime t) {
|
||||
ostime_offset = time_now() - t;
|
||||
}
|
||||
|
||||
extern "C" int osSetTimer(RDRAM_ARG PTR(OSTimer) t_, OSTime countdown, OSTime interval, PTR(OSMesgQueue) mq, OSMesg msg) {
|
||||
OSTimer* t = TO_PTR(OSTimer, t_);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue