mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 21:33:40 -07:00
Graphics backend enhancements etc. (#163)
This commit is contained in:
parent
fe6dbd2a5b
commit
ceef4a9453
21 changed files with 872 additions and 588 deletions
|
@ -977,6 +977,7 @@ void LightContext_RemoveLight(GlobalContext* globalCtx, LightContext* lightCtx,
|
|||
Lights* Lights_NewAndDraw(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 ambientB, u8 numLights, u8 r, u8 g,
|
||||
u8 b, s8 x, s8 y, s8 z);
|
||||
Lights* Lights_New(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 ambientB);
|
||||
void Lights_GlowCheckPrepare(GlobalContext* globalCtx);
|
||||
void Lights_GlowCheck(GlobalContext* globalCtx);
|
||||
void Lights_DrawGlow(GlobalContext* globalCtx);
|
||||
void ZeldaArena_CheckPointer(void* ptr, size_t size, const char* name, const char* action);
|
||||
|
|
|
@ -9,6 +9,7 @@ void Graph_ProcessGfxCommands(Gfx* commands);
|
|||
void OTRLogString(const char* src);
|
||||
void OTRGfxPrint(const char* str, void* printer, void (*printImpl)(void*, char));
|
||||
void OTRSetFrameDivisor(int divisor);
|
||||
void OTRGetPixelDepthPrepare(float x, float y);
|
||||
uint16_t OTRGetPixelDepth(float x, float y);
|
||||
int32_t OTRGetLastScancode();
|
||||
void ResourceMgr_CacheDirectory(const char* resName);
|
||||
|
|
|
@ -24,9 +24,17 @@
|
|||
#include "../soh/Enhancements/debugconsole.h"
|
||||
#include "../soh/Enhancements/debugger/debugger.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "variables.h"
|
||||
|
||||
OTRGlobals* OTRGlobals::Instance;
|
||||
|
||||
static struct {
|
||||
std::condition_variable cv_to_thread, cv_from_thread;
|
||||
std::mutex mutex;
|
||||
bool initialized;
|
||||
bool processing;
|
||||
} audio;
|
||||
|
||||
OTRGlobals::OTRGlobals() {
|
||||
context = Ship::GlobalCtx2::CreateInstance("Ship of Harkinian");
|
||||
context->GetWindow()->Init();
|
||||
|
@ -39,6 +47,10 @@ extern uintptr_t clearMtx;
|
|||
extern "C" Mtx gMtxClear;
|
||||
extern "C" MtxF gMtxFClear;
|
||||
extern "C" void OTRMessage_Init();
|
||||
extern "C" void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples);
|
||||
extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
|
||||
extern "C" int AudioPlayer_Buffered(void);
|
||||
extern "C" int AudioPlayer_GetDesiredBuffered(void);
|
||||
|
||||
// C->C++ Bridge
|
||||
extern "C" void InitOTR() {
|
||||
|
@ -80,8 +92,67 @@ extern "C" void Graph_ProcessFrame(void (*run_one_game_iter)(void)) {
|
|||
|
||||
// C->C++ Bridge
|
||||
extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
||||
OTRGlobals::Instance->context->GetWindow()->SetFrameDivisor(R_UPDATE_RATE);
|
||||
|
||||
if (!audio.initialized) {
|
||||
audio.initialized = true;
|
||||
std::thread([]() {
|
||||
for (;;) {
|
||||
{
|
||||
std::unique_lock<std::mutex> Lock(audio.mutex);
|
||||
while (!audio.processing) {
|
||||
audio.cv_to_thread.wait(Lock);
|
||||
}
|
||||
}
|
||||
//AudioMgr_ThreadEntry(&gAudioMgr);
|
||||
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
|
||||
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
|
||||
#define SAMPLES_HIGH 560
|
||||
#define SAMPLES_LOW 528
|
||||
// PAL values
|
||||
//#define SAMPLES_HIGH 656
|
||||
//#define SAMPLES_LOW 624
|
||||
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
|
||||
#define NUM_AUDIO_CHANNELS 2
|
||||
int samples_left = AudioPlayer_Buffered();
|
||||
u32 num_audio_samples = samples_left < AudioPlayer_GetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
|
||||
// printf("Audio samples: %d %u\n", samples_left, num_audio_samples);
|
||||
|
||||
// 3 is the maximum authentic frame divisor.
|
||||
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
|
||||
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
|
||||
AudioMgr_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples);
|
||||
}
|
||||
//for (uint32_t i = 0; i < 2 * num_audio_samples; i++) {
|
||||
// audio_buffer[i] = Rand_Next() & 0xFF;
|
||||
//}
|
||||
// printf("Audio samples before submitting: %d\n", audio_api->buffered());
|
||||
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> Lock(audio.mutex);
|
||||
audio.processing = false;
|
||||
}
|
||||
audio.cv_from_thread.notify_one();
|
||||
}
|
||||
}).detach();
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> Lock(audio.mutex);
|
||||
audio.processing = true;
|
||||
}
|
||||
audio.cv_to_thread.notify_one();
|
||||
|
||||
OTRGlobals::Instance->context->GetWindow()->RunCommands(commands);
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> Lock(audio.mutex);
|
||||
while (audio.processing) {
|
||||
audio.cv_from_thread.wait(Lock);
|
||||
}
|
||||
}
|
||||
|
||||
// OTRTODO: FIGURE OUT END FRAME POINT
|
||||
/* if (OTRGlobals::Instance->context->GetWindow()->lastScancode != -1)
|
||||
OTRGlobals::Instance->context->GetWindow()->lastScancode = -1;*/
|
||||
|
@ -90,8 +161,8 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
|||
|
||||
float divisor_num = 0.0f;
|
||||
|
||||
extern "C" void OTRSetFrameDivisor(int divisor) {
|
||||
OTRGlobals::Instance->context->GetWindow()->SetFrameDivisor(divisor);
|
||||
extern "C" void OTRGetPixelDepthPrepare(float x, float y) {
|
||||
OTRGlobals::Instance->context->GetWindow()->GetPixelDepthPrepare(x, y);
|
||||
}
|
||||
|
||||
extern "C" uint16_t OTRGetPixelDepth(float x, float y) {
|
||||
|
|
|
@ -24,7 +24,7 @@ void Graph_ProcessFrame(void (*run_one_game_iter)(void));
|
|||
void Graph_ProcessGfxCommands(Gfx* commands);
|
||||
void OTRLogString(const char* src);
|
||||
void OTRGfxPrint(const char* str, void* printer, void (*printImpl)(void*, char));
|
||||
void OTRSetFrameDivisor(int divisor);
|
||||
void OTRGetPixelDepthPrepare(float x, float y);
|
||||
uint16_t OTRGetPixelDepth(float x, float y);
|
||||
int32_t OTRGetLastScancode();
|
||||
uint32_t ResourceMgr_GetGameVersion();
|
||||
|
|
|
@ -468,35 +468,6 @@ static void RunFrame()
|
|||
{
|
||||
uint64_t ticksA, ticksB;
|
||||
ticksA = GetPerfCounter();
|
||||
|
||||
OTRSetFrameDivisor(R_UPDATE_RATE);
|
||||
//OTRSetFrameDivisor(0);
|
||||
|
||||
|
||||
//AudioMgr_ThreadEntry(&gAudioMgr);
|
||||
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
|
||||
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
|
||||
#define SAMPLES_HIGH 560
|
||||
#define SAMPLES_LOW 528
|
||||
// PAL values
|
||||
//#define SAMPLES_HIGH 656
|
||||
//#define SAMPLES_LOW 624
|
||||
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
|
||||
#define NUM_AUDIO_CHANNELS 2
|
||||
int samples_left = AudioPlayer_Buffered();
|
||||
u32 num_audio_samples = samples_left < AudioPlayer_GetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
|
||||
// printf("Audio samples: %d %u\n", samples_left, num_audio_samples);
|
||||
|
||||
// 3 is the maximum authentic frame divisor.
|
||||
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
|
||||
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
|
||||
AudioMgr_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples);
|
||||
}
|
||||
//for (uint32_t i = 0; i < 2 * num_audio_samples; i++) {
|
||||
// audio_buffer[i] = Rand_Next() & 0xFF;
|
||||
//}
|
||||
// printf("Audio samples before submitting: %d\n", audio_api->buffered());
|
||||
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
|
||||
|
||||
|
||||
PadMgr_ThreadEntry(&gPadMgr);
|
||||
|
|
|
@ -226,6 +226,9 @@ u16 Environment_GetPixelDepth(s32 x, s32 y) {
|
|||
void Environment_GraphCallback(GraphicsContext* gfxCtx, void* param) {
|
||||
GlobalContext* globalCtx = (GlobalContext*)param;
|
||||
|
||||
OTRGetPixelDepthPrepare(D_8015FD7E, D_8015FD80);
|
||||
Lights_GlowCheckPrepare(globalCtx);
|
||||
|
||||
D_8011FB44 = Environment_GetPixelDepth(D_8015FD7E, D_8015FD80);
|
||||
Lights_GlowCheck(globalCtx);
|
||||
}
|
||||
|
|
|
@ -323,6 +323,44 @@ Lights* Lights_New(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 ambient
|
|||
return lights;
|
||||
}
|
||||
|
||||
void Lights_GlowCheckPrepare(GlobalContext* globalCtx) {
|
||||
LightNode* node;
|
||||
LightPoint* params;
|
||||
Vec3f pos;
|
||||
Vec3f multDest;
|
||||
f32 wDest;
|
||||
f32 wX;
|
||||
f32 wY;
|
||||
|
||||
node = globalCtx->lightCtx.listHead;
|
||||
|
||||
while (node != NULL) {
|
||||
params = &node->info->params.point;
|
||||
|
||||
if (node->info->type == LIGHT_POINT_GLOW) {
|
||||
f32 x, y;
|
||||
u32 shrink;
|
||||
uint32_t height;
|
||||
|
||||
pos.x = params->x;
|
||||
pos.y = params->y;
|
||||
pos.z = params->z;
|
||||
func_8002BE04(globalCtx, &pos, &multDest, &wDest);
|
||||
wX = multDest.x * wDest;
|
||||
wY = multDest.y * wDest;
|
||||
|
||||
x = wX * 160 + 160;
|
||||
y = wY * 120 + 120;
|
||||
shrink = ShrinkWindow_GetCurrentVal();
|
||||
|
||||
if ((multDest.z > 1.0f) && y >= shrink && y <= SCREEN_HEIGHT - shrink) {
|
||||
OTRGetPixelDepthPrepare(x, y);
|
||||
}
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
void Lights_GlowCheck(GlobalContext* globalCtx) {
|
||||
LightNode* node;
|
||||
LightPoint* params;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue