Merge branch 'port' into port-debugger

This commit is contained in:
fgsfds committed 2024-05-18 19:02:37 +02:00
commit cf19cebc27
16 files changed
+175 -62

No files matched your search

+2 -2
View File
@@ -150,7 +150,7 @@ B_DIR := build/$(ROMID)-port
G_DIR := src/generated/$(ROMID)
ifneq (,$(findstring windows,$(TARGET_PLATFORM)))
TARGET_CFLAGS := $(shell pkg-config sdl2 --cflags-only-I)
TARGET_CFLAGS := $(shell pkg-config sdl2 --cflags-only-I) -pthread
TARGET_LDFLAGS := $(shell pkg-config sdl2 --libs) -lz -lopengl32 -ldbghelp
# on windows/mingw we need this to be built with a 32-bit compiler so it finds the correct libs
TOOLCHAIN ?= i686-w64-mingw32-
@@ -161,7 +161,7 @@ ifneq (,$(findstring windows,$(TARGET_PLATFORM)))
TARGET_LDFLAGS += -lstdc++
endif
else # assume *nix
TARGET_CFLAGS := $(shell pkg-config sdl2 --cflags-only-I)
TARGET_CFLAGS := $(shell pkg-config sdl2 --cflags-only-I) -pthread
TARGET_LDFLAGS := $(shell pkg-config sdl2 --libs) -lGL -lz -ldl
ifneq (,$(findstring arm,$(TARGET_PLATFORM))$(findstring aarch,$(TARGET_PLATFORM)))
# linux on arm or aarch64
+1 -1
View File
@@ -261,7 +261,7 @@ static inline void sync_framerate_with_timer(void) {
// We want to exit a bit early, so we can busy-wait the rest to never miss the deadline
left -= 15000UL;
if (left > 0) {
sysSleep(left);
sysFrameLimiterSleep(left);
}
do {
+1 -2
View File
@@ -6,7 +6,6 @@
s32 audioInit(void);
s32 audioGetBytesBuffered(void);
s32 audioGetSamplesBuffered(void);
void audioSetNextBuffer(const s16 *buf, u32 len);
void audioEndFrame(void);
void audioSubmitBuffer(const s16 *buf, u32 size);
#endif
+5 -1
View File
@@ -35,7 +35,11 @@ void *sysMemZeroAlloc(const u32 size);
void sysMemFree(void *ptr);
// hns is specified in 100ns units
void sysSleep(const s64 hns);
// do not use sysFrameLimiterSleep on any thread other than the main one
void sysFrameLimiterSleep(const s64 hns);
// us is specified in microseconds
void sysSleep(const s64 us);
// yield CPU if supported (e.g. during a busy loop)
void sysCpuRelax(void);
+27
View File
@@ -0,0 +1,27 @@
#ifndef _IN_THREAD_H
#define _IN_THREAD_H
#include <PR/ultratypes.h>
#include "platform.h"
// TODO: backends
#ifndef PLATFORM_USE_PTHREAD
#error "No available thread backend."
#endif
#include <pthread.h>
#define SYSMUTEX_STATIC_INIT PTHREAD_MUTEX_INITIALIZER
typedef pthread_t systhread;
typedef pthread_mutex_t sysmutex;
typedef void *(*systhreadfn)(void *);
s32 sysThreadCreate(systhread *thread, systhreadfn func, void *arg);
s32 sysThreadJoin(systhread *thread, void **result);
void sysMutexLock(sysmutex *mtx);
void sysMutexUnlock(sysmutex *mtx);
#endif // _IN_THREAD_H
+24 -16
View File
@@ -7,12 +7,13 @@
#include "system.h"
static SDL_AudioDeviceID dev;
static const s16 *nextBuf;
static u32 nextSize = 0;
static s32 bufferSize = 512;
static s32 queueLimit = 8192;
static f32 offsetFrames = 0.5f;
static u32 offsetBytes;
s32 audioInit(void)
{
if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) {
@@ -28,7 +29,8 @@ s32 audioInit(void)
want.samples = bufferSize;
want.callback = NULL;
nextBuf = NULL;
const f32 spf = (f32)want.freq / (PAL ? 50.f : 60.f);
offsetBytes = offsetFrames * spf * (f32)sizeof(int16_t);
dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
if (dev == 0) {
@@ -43,33 +45,39 @@ s32 audioInit(void)
s32 audioGetBytesBuffered(void)
{
return SDL_GetQueuedAudioSize(dev);
u32 count = SDL_GetQueuedAudioSize(dev);
// pd's audio code decides how many samples of audio to produce based on the amount of audio
// currently buffered, so we adjust the reported count to be some number of frames in the future
// to counteract lag; idea shamelessly stolen from mm recomp
if (offsetBytes) {
if (count > offsetBytes) {
count -= offsetBytes;
} else {
count = 0;
}
}
return count;
}
s32 audioGetSamplesBuffered(void)
{
return audioGetBytesBuffered() / 4;
return audioGetBytesBuffered() / (2 * sizeof(s16));
}
void audioSetNextBuffer(const s16 *buf, u32 len)
void audioSubmitBuffer(const s16 *buf, u32 size)
{
nextBuf = buf;
nextSize = len;
}
void audioEndFrame(void)
{
if (nextBuf && nextSize) {
if (buf && size) {
if (audioGetSamplesBuffered() < queueLimit) {
SDL_QueueAudio(dev, nextBuf, nextSize);
SDL_QueueAudio(dev, buf, size);
}
nextBuf = NULL;
nextSize = 0;
}
}
PD_CONSTRUCTOR static void audioConfigInit(void)
{
configRegisterInt("Audio.BufferSize", &bufferSize, 0, 1 * 1024 * 1024);
configRegisterFloat("Audio.OffsetFrames", &offsetFrames, 0.f, 5.f);
configRegisterInt("Audio.QueueLimit", &queueLimit, 0, 1 * 1024 * 1024);
}
+1 -1
View File
@@ -166,7 +166,7 @@ u32 osAiGetLength(void)
s32 osAiSetNextBuffer(void *bufPtr, u32 size)
{
audioSetNextBuffer(bufPtr, size);
audioSubmitBuffer(bufPtr, size);
return 0;
}
+1 -1
View File
@@ -502,7 +502,7 @@ void mainLoop(void)
schedEndFrame(&g_Sched);
}
if (g_TickExtraSleep) {
sysSleep(EXTRA_SLEEP_TIME);
sysFrameLimiterSleep(EXTRA_SLEEP_TIME);
}
}
-25
View File
@@ -244,18 +244,6 @@ void schedStartFrame(OSSched *sc)
videoStartFrame();
}
void schedAudioFrame(OSSched *sc)
{
s32 i;
if (!g_SndDisabled) {
for (i = 0; i < g_Vars.diffframe60; i++) {
amgrFrame();
audioEndFrame();
}
}
}
/**
* Handle a retrace (vsync) event.
*
@@ -274,18 +262,6 @@ void schedEndFrame(OSSched *sc)
{
sc->frameCount++;
#if PAL
if (!g_Resetting && (sc->frameCount & 1)) {
// osStopTimer(&g_SchedRspTimer);
// osSetTimer(&g_SchedRspTimer, 280000, 0, amgrGetFrameMesgQueue(), &g_SchedRspMsg);
}
#else
if (!g_Resetting && ((sc->frameCount & 1) || IS4MB())) {
// osStopTimer(&g_SchedRspTimer);
// osSetTimer(&g_SchedRspTimer, 280000, 0, amgrGetFrameMesgQueue(), &g_SchedRspMsg);
}
#endif
if (!g_Resetting) {
viHandleRetrace();
}
@@ -299,7 +275,6 @@ void schedEndFrame(OSSched *sc)
joy00014238();
sndHandleRetrace();
schedAudioFrame(sc);
schedRenderCrashPeriodically(sc->frameCount);
debuggerEndFrame();
+8 -3
View File
@@ -9,6 +9,7 @@
#include <strings.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <SDL.h>
#include <PR/ultratypes.h>
#include "platform.h"
@@ -32,8 +33,6 @@ __attribute__((dllexport)) u32 AmdPowerXpressRequestHighPerformance = 1;
#else
#include <unistd.h>
// figure out how to yield
#if defined(PLATFORM_X86) || defined(PLATFORM_X86_64)
// this should work even if the code is not built with SSE enabled, at least on gcc and clang,
@@ -293,7 +292,7 @@ void sysMemFree(void *ptr)
free(ptr);
}
void sysSleep(const s64 hns)
void sysFrameLimiterSleep(const s64 hns)
{
#ifdef PLATFORM_WIN32
static LARGE_INTEGER li;
@@ -306,6 +305,12 @@ void sysSleep(const s64 hns)
#endif
}
void sysSleep(const s64 us)
{
const struct timespec spec = { 0, us * 1000 };
nanosleep(&spec, NULL);
}
void sysCpuRelax(void)
{
DO_YIELD();
+27
View File
@@ -0,0 +1,27 @@
#include "thread.h"
#ifndef PLATFORM_USE_PTHREAD
#error "No available thread backend."
#endif
#include <pthread.h>
s32 sysThreadCreate(systhread *thread, systhreadfn func, void *arg)
{
return pthread_create(thread, NULL, func, arg);
}
s32 sysThreadJoin(systhread *thread, void **result)
{
return pthread_join(*thread, result);
}
void sysMutexLock(sysmutex *mtx)
{
pthread_mutex_lock(mtx);
}
void sysMutexUnlock(sysmutex *mtx)
{
pthread_mutex_unlock(mtx);
}
+2 -8
View File
@@ -9840,20 +9840,14 @@ bool aiIfMusicEventQueueIsEmpty(void)
{
f32 value = (u64)osGetCount() * 64 / 3000;
#ifdef PLATFORM_N64 // will hang forever until the audio thread wakes it up
if (g_MusicEventQueueLength) {
#else // HACK: will wait 1 frame and get on with it
static bool waited = false;
if (g_MusicEventQueueLength && !waited) {
waited = true;
#ifndef PLATFORM_N64
musicTickEvents();
#endif
g_Vars.aioffset += 4;
} else {
u8 *cmd = g_Vars.ailist + g_Vars.aioffset;
g_Vars.aioffset = chraiGoToLabel(g_Vars.ailist, g_Vars.aioffset, cmd[3]);
#ifndef PLATFORM_N64
waited = false;
#endif
}
return false;
+1 -1
View File
@@ -47,7 +47,7 @@ void frametimeCalculate(void)
#ifndef PLATFORM_N64
if (g_TickExtraSleep) {
sysSleep(EXTRA_SLEEP_TIME);
sysFrameLimiterSleep(EXTRA_SLEEP_TIME);
}
#endif
} while (g_Vars.mininc60 && diffframe60 < g_Vars.mininc60);
+5 -1
View File
@@ -17,7 +17,11 @@ OSMesgQueue *amgrGetFrameMesgQueue(void);
void amgrStopThread(void);
#ifndef PLATFORM_N64
void amgrFrame(void);
void amgrLock(void);
void amgrUnlock(void);
#else
#define amgrLock() do {} while(0)
#define amgrUnlock() do {} while(0)
#endif
#endif
+3
View File
@@ -34,6 +34,9 @@
#error "64-bit platforms are currently not supported."
#endif
// threading backend
#define PLATFORM_USE_PTHREAD 1
// detect endianness
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+67
View File
@@ -10,6 +10,13 @@
#include "lib/libc/ll.h"
#include "data.h"
#include "types.h"
#ifndef PLATFORM_N64
#include "lib/audiomgr.h"
#include "thread.h"
#include "audio.h"
#include "system.h"
#define AMGR_THREAD_SLEEP_US 2000
#endif
u32 var80091560;
u32 var80091564;
@@ -43,6 +50,14 @@ void *g_AudioSp;
u32 var8005cf90 = 0x00000000;
u8 var8005cf94 = 1;
#ifndef PLATFORM_N64
systhread g_AmgrThread;
sysmutex g_AmgrMutex = SYSMUTEX_STATIC_INIT;
u32 g_AmgrFrame;
u32 g_AmgrFrameTarget;
void *amgrThread(void *arg);
#endif
void amgrHandleDoneMsg(AudioInfo *info);
void amgrHandleFrameMsg(AudioInfo *info, AudioInfo *previnfo);
void amgrMain(void *arg);
@@ -155,6 +170,9 @@ void amgrStartThread(void)
{
osStartThread(&g_AudioManager.thread);
g_AudioIsThreadRunning = true;
#ifndef PLATFORM_N64
sysThreadCreate(&g_AmgrThread, &amgrThread, NULL);
#endif
}
OSMesgQueue *amgrGetFrameMesgQueue(void)
@@ -171,6 +189,12 @@ void amgrStopThread(void)
{
if (g_AudioIsThreadRunning) {
osStopThread(&g_AudioManager.thread);
#ifndef PLATFORM_N64
amgrLock();
g_AudioIsThreadRunning = false;
amgrUnlock();
sysThreadJoin(&g_AmgrThread, NULL);
#endif
}
}
@@ -321,11 +345,14 @@ void amgrHandleDoneMsg(AudioInfo *info)
}
#ifndef PLATFORM_N64
void amgrFrame(void)
{
static AudioInfo *previnfo = NULL;
static s32 count = 0;
amgrLock();
var80091588 = osGetTime();
AudioInfo *info = g_AudioManager.audioInfo[g_AdmaCurFrame % 3];
@@ -363,6 +390,8 @@ void amgrFrame(void)
count++;
amgrUnlock();
var80091590 = osGetTime();
var80091570 = var80091590 - var80091588;
@@ -377,4 +406,42 @@ void amgrFrame(void)
var80091568 = var80091590 - var80091588;
}
}
void amgrLock(void)
{
sysMutexLock(&g_AmgrMutex);
}
void amgrUnlock(void)
{
sysMutexUnlock(&g_AmgrMutex);
}
void *amgrThread(void *arg)
{
const f64 frametime = 1000000.0 / (PAL ? 50.0 : 60.0);
bool running = g_AudioIsThreadRunning;
f64 nexttick = sysGetMicroseconds();
f64 tick;
while (running)
{
tick = sysGetMicroseconds() + 0.01;
while (nexttick < tick) {
amgrFrame();
g_AmgrFrame++;
nexttick += frametime;
}
sysSleep(AMGR_THREAD_SLEEP_US);
amgrLock();
running = g_AudioIsThreadRunning;
amgrUnlock();
}
return NULL;
}
#endif