From 82e547c25673fd1089240f92519c776a779b170e Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Thu, 18 Jan 2024 14:51:18 -0600 Subject: [PATCH 1/9] fix music playback on 3DS --- src/Audio.c | 29 ++++++++++++++++++++++++++--- src/Core.h | 1 - 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/Audio.c b/src/Audio.c index 4316802da..1aeb7975e 100644 --- a/src/Audio.c +++ b/src/Audio.c @@ -754,6 +754,7 @@ struct AudioContext { ndspWaveBuf bufs[AUDIO_MAX_BUFFERS]; int count, channels, sampleRate; void* _tmpData; int _tmpSize; + cc_bool stereo; }; static int channelIDs; @@ -797,7 +798,8 @@ void Audio_Close(struct AudioContext* ctx) { } cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sampleRate) { - int fmt = channels == 1 ? NDSP_FORMAT_MONO_PCM16 : NDSP_FORMAT_STEREO_PCM16; + ctx->stereo = (channels == 2); + int fmt = ctx->stereo ? NDSP_FORMAT_STEREO_PCM16 : NDSP_FORMAT_MONO_PCM16; ndspChnSetFormat(ctx->chanID, fmt); ndspChnSetRate(ctx->chanID, sampleRate); @@ -807,16 +809,25 @@ cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sampleRate cc_result Audio_QueueData(struct AudioContext* ctx, void* data, cc_uint32 dataSize) { ndspWaveBuf* buf; + // DSP audio buffers must be aligned to a multiple of 0x80, according to the example code I could find. + if (((uintptr_t)data & 0x7F) != 0) { + Platform_Log1("Audio_QueueData: tried to queue buffer with non-aligned audio buffer 0x%08X\n", &data); + } + if ((dataSize & 0x7F) != 0) { + Platform_Log1("Audio_QueueData: unaligned audio data size 0x%X\n", &dataSize); + } + for (int i = 0; i < ctx->count; i++) { buf = &ctx->bufs[i]; //Platform_Log2("QUEUE_CHUNK: %i = %i", &ctx->chanID, &buf->status); if (buf->status == NDSP_WBUF_QUEUED || buf->status == NDSP_WBUF_PLAYING) continue; - + buf->data_pcm16 = data; - buf->nsamples = dataSize / 2; // 16 bit samples + buf->nsamples = dataSize / (sizeof(cc_int16) * (ctx->stereo ? 2 : 1)); //Platform_Log1("PLAYING ON: %i", &ctx->chanID); + DSP_FlushDataCache(buf->data_pcm16, dataSize); ndspChnWaveBufAdd(ctx->chanID, buf); return 0; } @@ -1336,10 +1347,18 @@ static cc_result Music_PlayOgg(struct Stream* source) { /* largest possible vorbis frame decodes to blocksize1 * channels samples, */ /* so can end up decoding slightly over a second of audio */ chunkSize = channels * (sampleRate + vorbis.blockSizes[1]); +#ifdef __3DS__ + chunkSize &= ~0x7F; // all data sent to the DSP needs to be aligned to a multiple of 0x80 +#endif samplesPerSecond = channels * sampleRate; cur = 0; +#ifdef __3DS__ + // linearAlloc aligns data to a multiple of 0x80 + data = linearAlloc(chunkSize * AUDIO_MAX_BUFFERS * 2); +#else data = (cc_int16*)Mem_TryAlloc(chunkSize * AUDIO_MAX_BUFFERS, 2); +#endif if (!data) { res = ERR_OUT_OF_MEMORY; goto cleanup; } /* fill up with some samples before playing */ @@ -1393,7 +1412,11 @@ static cc_result Music_PlayOgg(struct Stream* source) { } cleanup: +#ifdef __3DS__ + linearFree(data); +#else Mem_Free(data); +#endif Vorbis_Free(&vorbis); return res == ERR_END_OF_STREAM ? 0 : res; } diff --git a/src/Core.h b/src/Core.h index bc00131cc..e5d4d8e71 100644 --- a/src/Core.h +++ b/src/Core.h @@ -282,7 +282,6 @@ typedef cc_uint8 cc_bool; #undef CC_BUILD_FREETYPE #elif defined __3DS__ #define CC_BUILD_3DS - #define CC_BUILD_OPENAL #define CC_BUILD_HTTPCLIENT #define CC_BUILD_BEARSSL #define CC_BUILD_LOWMEM From 13965dbf2ae8cce8e6a096e234e1fd7cf8a24c8a Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Thu, 18 Jan 2024 16:10:02 -0600 Subject: [PATCH 2/9] get sound effects to play on 3DS --- src/Audio.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Audio.c b/src/Audio.c index 1aeb7975e..78beb13a1 100644 --- a/src/Audio.c +++ b/src/Audio.c @@ -811,10 +811,10 @@ cc_result Audio_QueueData(struct AudioContext* ctx, void* data, cc_uint32 dataSi // DSP audio buffers must be aligned to a multiple of 0x80, according to the example code I could find. if (((uintptr_t)data & 0x7F) != 0) { - Platform_Log1("Audio_QueueData: tried to queue buffer with non-aligned audio buffer 0x%08X\n", &data); + Platform_Log1("Audio_QueueData: tried to queue buffer with non-aligned audio buffer 0x%x\n", &data); } if ((dataSize & 0x7F) != 0) { - Platform_Log1("Audio_QueueData: unaligned audio data size 0x%X\n", &dataSize); + Platform_Log1("Audio_QueueData: unaligned audio data size 0x%x\n", &dataSize); } for (int i = 0; i < ctx->count; i++) @@ -1043,7 +1043,11 @@ static cc_result Sound_ReadWaveData(struct Stream* stream, struct Sound* snd) { if (bitsPerSample != 16) return WAV_ERR_SAMPLE_BITS; size -= WAV_FMT_SIZE; } else if (fourCC == WAV_FourCC('d','a','t','a')) { +#ifdef __3DS__ + snd->data = linearAlloc(size); +#else snd->data = Mem_TryAlloc(size, 1); +#endif snd->size = size; if (!snd->data) return ERR_OUT_OF_MEMORY; From a41fda79da78e221ae7b76f851c191989511f72b Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Thu, 18 Jan 2024 18:01:39 -0600 Subject: [PATCH 3/9] fix issue with 3DS music not playing after entering the game 3 times --- src/Audio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Audio.c b/src/Audio.c index 78beb13a1..5a2aec7a3 100644 --- a/src/Audio.c +++ b/src/Audio.c @@ -783,7 +783,7 @@ void Audio_Init(struct AudioContext* ctx, int buffers) { ctx->count = buffers; ctx->chanID = chanID; ctx->used = true; - + ndspChnSetInterp(ctx->chanID, NDSP_INTERP_LINEAR); } @@ -791,6 +791,7 @@ void Audio_Close(struct AudioContext* ctx) { if (ctx->used) { ndspChnWaveBufClear(ctx->chanID); ctx->channels &= ~(1 << ctx->chanID); + channelIDs &= ~(1 << ctx->chanID); } ctx->used = false; From f9550ff6a3956288dbf6e7cde0d90e025ffd3e00 Mon Sep 17 00:00:00 2001 From: camthehaxman Date: Fri, 19 Jan 2024 08:42:34 -0600 Subject: [PATCH 4/9] don't error if LightEvent_WaitTimeout times out --- src/Platform_3DS.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Platform_3DS.c b/src/Platform_3DS.c index 478564704..d5c4ab7b4 100644 --- a/src/Platform_3DS.c +++ b/src/Platform_3DS.c @@ -277,8 +277,7 @@ void Waitable_Wait(void* handle) { void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) { s64 timeout_ns = milliseconds * (1000 * 1000); // milliseconds to nanoseconds - int res = LightEvent_WaitTimeout((LightEvent*)handle, timeout_ns); - if (res) Logger_Abort2(res, "Waiting timed event"); + LightEvent_WaitTimeout((LightEvent*)handle, timeout_ns); } @@ -462,4 +461,4 @@ static cc_result GetMachineID(cc_uint32* key) { psInit(); return PS_GetDeviceId(key); } -#endif \ No newline at end of file +#endif From 0efa11390ed3f0ddac8f769972016fd477538456 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 20 Jan 2024 08:52:56 +1100 Subject: [PATCH 5/9] Redesign audio chunk allocation for music --- src/Audio.c | 77 ++++++++++++++++++++++++++++++++++------------------- src/Audio.h | 8 +++--- src/SSL.c | 2 +- 3 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/Audio.c b/src/Audio.c index a862243f2..c460c7e2e 100644 --- a/src/Audio.c +++ b/src/Audio.c @@ -50,6 +50,9 @@ static void AudioWarn(cc_result res, const char* action) { } static void AudioBase_Clear(struct AudioContext* ctx); static cc_bool AudioBase_AdjustSound(struct AudioContext* ctx, struct AudioData* data); +static void AudioBase_AllocChunks(int size, void** chunks, int numChunks); +static void AudioBase_FreeChunks(void** chunks, int numChunks); + /* achieve higher speed by playing samples at higher sample rate */ #define Audio_AdjustSampleRate(data) ((data->sampleRate * data->rate) / 100) @@ -323,12 +326,12 @@ cc_bool Audio_DescribeError(cc_result res, cc_string* dst) { return err != NULL; } -void* Audio_AllocChunk(cc_uint32 size) { - return Mem_TryAlloc(size, 1); +void Audio_AllocChunks(cc_uint32 size, void** chunks, int numChunks) { + AudioBase_AllocChunks(size, chunks, numChunks); } -void Audio_FreeChunk(void* data) { - Mem_Free(data); +void Audio_FreeChunks(void** chunks, int numChunks) { + AudioBase_FreeChunks(chunks, numChunks); } #elif defined CC_BUILD_WINMM /*########################################################################################################################* @@ -525,12 +528,12 @@ cc_bool Audio_DescribeError(cc_result res, cc_string* dst) { return true; } -void* Audio_AllocChunk(cc_uint32 size) { - return Mem_TryAlloc(size, 1); +void Audio_AllocChunks(cc_uint32 size, void** chunks, int numChunks) { + AudioBase_AllocChunks(size, chunks, numChunks); } -void Audio_FreeChunk(void* data) { - Mem_Free(data); +void Audio_FreeChunks(void** chunks, int numChunks) { + AudioBase_FreeChunks(chunks, numChunks); } #elif defined CC_BUILD_OPENSLES /*########################################################################################################################* @@ -761,12 +764,12 @@ cc_bool Audio_DescribeError(cc_result res, cc_string* dst) { return err != NULL; } -void* Audio_AllocChunk(cc_uint32 size) { - return Mem_TryAlloc(size, 1); +void Audio_AllocChunks(cc_uint32 size, void** chunks, int numChunks) { + AudioBase_AllocChunks(size, chunks, numChunks); } -void Audio_FreeChunk(void* data) { - Mem_Free(data); +void Audio_FreeChunks(void** chunks, int numChunks) { + AudioBase_FreeChunks(chunks, numChunks); } #elif defined CC_BUILD_3DS /*########################################################################################################################* @@ -947,12 +950,12 @@ cc_bool Audio_DescribeError(cc_result res, cc_string* dst) { return len > 0; } -void* Audio_AllocChunk(cc_uint32 size) { - return Mem_TryAlloc(size, 1); +void Audio_AllocChunks(cc_uint32 size, void** chunks, int numChunks) { + AudioBase_AllocChunks(size, chunks, numChunks); } -void Audio_FreeChunk(void* data) { - Mem_Free(data); +void Audio_FreeChunks(void** chunks, int numChunks) { + AudioBase_FreeChunks(chunks, numChunks); } #endif @@ -996,6 +999,20 @@ static cc_bool AudioBase_AdjustSound(struct AudioContext* ctx, struct AudioData* data->data = audio; return true; } + +static void AudioBase_AllocChunks(int size, void** chunks, int numChunks) { + cc_uint8* dst = (cc_uint8*)Mem_TryAlloc(numChunks, size); + int i; + + for (i = 0; i < numChunks; i++) + { + chunks[i] = dst ? (dst + size * i) : NULL; + } +} + +static void AudioBase_FreeChunks(void** chunks, int numChunks) { + Mem_Free(chunks[0]); +} #endif @@ -1064,7 +1081,7 @@ static cc_result Sound_ReadWaveData(struct Stream* stream, struct Sound* snd) { if (bitsPerSample != 16) return WAV_ERR_SAMPLE_BITS; size -= WAV_FMT_SIZE; } else if (fourCC == WAV_FourCC('d','a','t','a')) { - snd->data = Audio_AllocChunk(size); + Audio_AllocChunks(size, &snd->data, 1); snd->size = size; if (!snd->data) return ERR_OUT_OF_MEMORY; @@ -1129,7 +1146,7 @@ static void Soundboard_Load(struct Soundboard* board, const cc_string* boardName if (res) { Logger_SysWarn2(res, "decoding", file); - Mem_Free(snd->data); + Audio_FreeChunks(&snd->data, 1); snd->data = NULL; snd->size = 0; } else { group->count++; } @@ -1353,7 +1370,7 @@ static cc_result Music_PlayOgg(struct Stream* source) { int channels, sampleRate; int chunkSize, samplesPerSecond; - cc_int16* data = NULL; + void* chunks[AUDIO_MAX_BUFFERS] = { 0 }; int inUse, i, cur; cc_result res; @@ -1370,19 +1387,25 @@ static cc_result Music_PlayOgg(struct Stream* source) { chunkSize = channels * (sampleRate + vorbis.blockSizes[1]); samplesPerSecond = channels * sampleRate; - cur = 0; - data = (cc_int16*)Audio_AllocChunk(chunkSize * AUDIO_MAX_BUFFERS * 2); - if (!data) { res = ERR_OUT_OF_MEMORY; goto cleanup; } + Audio_AllocChunks(chunkSize * 2, chunks, AUDIO_MAX_BUFFERS); + for (i = 0; i < AUDIO_MAX_BUFFERS; i++) + { + if (chunks[i]) continue; + + res = ERR_OUT_OF_MEMORY; goto cleanup; + } + /* fill up with some samples before playing */ - for (i = 0; i < AUDIO_MAX_BUFFERS && !res; i++) { - res = Music_Buffer(&data[chunkSize * cur], samplesPerSecond, &vorbis); - cur = (cur + 1) % AUDIO_MAX_BUFFERS; + for (i = 0; i < AUDIO_MAX_BUFFERS && !res; i++) + { + res = Music_Buffer((cc_int16*)chunks[i], samplesPerSecond, &vorbis); } if (music_stopping) goto cleanup; res = Audio_Play(&music_ctx); if (res) goto cleanup; + cur = 0; while (!music_stopping) { #ifdef CC_BUILD_ANDROID @@ -1404,7 +1427,7 @@ static cc_result Music_PlayOgg(struct Stream* source) { Thread_Sleep(10); continue; } - res = Music_Buffer(&data[chunkSize * cur], samplesPerSecond, &vorbis); + res = Music_Buffer((cc_int16*)chunks[cur], samplesPerSecond, &vorbis); cur = (cur + 1) % AUDIO_MAX_BUFFERS; /* need to specially handle last bit of audio */ @@ -1425,7 +1448,7 @@ static cc_result Music_PlayOgg(struct Stream* source) { } cleanup: - Mem_Free(data); + Audio_FreeChunks(chunks, AUDIO_MAX_BUFFERS); Vorbis_Free(&vorbis); return res == ERR_END_OF_STREAM ? 0 : res; } diff --git a/src/Audio.h b/src/Audio.h index 9c2613b1a..ec5d8c3ac 100644 --- a/src/Audio.h +++ b/src/Audio.h @@ -66,8 +66,8 @@ cc_bool Audio_FastPlay(struct AudioContext* ctx, struct AudioData* data); /* Outputs more detailed information about errors with audio. */ cc_bool Audio_DescribeError(cc_result res, cc_string* dst); -/* Allocates a chunk of data to store audio samples */ -void* Audio_AllocChunk(cc_uint32 size); -/* Frees a previously allocated chunk of data */ -void Audio_FreeChunk(void* chunk); +/* Allocates a group of chunks of data to store audio samples */ +void Audio_AllocChunks(cc_uint32 size, void** chunks, int numChunks); +/* Frees a previously allocated group of chunks of data */ +void Audio_FreeChunks(void** chunks, int numChunks); #endif diff --git a/src/SSL.c b/src/SSL.c index 317a36142..1bf323e69 100644 --- a/src/SSL.c +++ b/src/SSL.c @@ -153,7 +153,7 @@ static SECURITY_STATUS SSL_Connect(struct SSLContext* ctx, const char* hostname) out_desc.cBuffers = Array_Elems(out_buffers); out_desc.pBuffers = out_buffers; - res = FP_InitializeSecurityContextA(&ctx->handle, NULL, hostname, flags, 0, 0, + res = FP_InitializeSecurityContextA(&ctx->handle, NULL, (char*)hostname, flags, 0, 0, NULL, 0, &ctx->context, &out_desc, &flags, NULL); if (res != SEC_I_CONTINUE_NEEDED) return res; res = 0; From 12c952a02a89f7587c67218bbf0cb8c2206598c2 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 20 Jan 2024 11:57:23 +1100 Subject: [PATCH 6/9] Rename WindowInfo to Window_Main --- src/Audio.c | 4 ++-- src/Camera.c | 2 +- src/Commands.c | 2 +- src/Game.c | 10 ++++----- src/Graphics_D3D11.c | 10 ++++----- src/Graphics_D3D9.c | 2 +- src/Gui.c | 8 ++++---- src/Input.c | 2 +- src/LBackend.c | 14 ++++++------- src/LScreens.c | 2 +- src/Launcher.c | 6 +++--- src/Menus.c | 18 ++++++++--------- src/Program.c | 2 +- src/Screens.c | 38 +++++++++++++++++----------------- src/Widgets.c | 8 ++++---- src/Window.h | 12 ++++++++--- src/Window_3DS.c | 19 ++++++++++------- src/Window_Android.c | 22 ++++++++++---------- src/Window_Carbon.c | 40 ++++++++++++++++++------------------ src/Window_Dreamcast.c | 10 ++++----- src/Window_GCWii.c | 12 +++++------ src/Window_N64.c | 10 ++++----- src/Window_PS2.c | 10 ++++----- src/Window_PS3.c | 12 +++++------ src/Window_PSP.c | 10 ++++----- src/Window_PSVita.c | 10 ++++----- src/Window_SDL.c | 12 +++++------ src/Window_Web.c | 34 +++++++++++++++---------------- src/Window_Win.c | 18 ++++++++--------- src/Window_X11.c | 26 ++++++++++++------------ src/Window_Xbox.c | 10 ++++----- src/Window_Xbox360.c | 10 ++++----- src/_WindowBase.h | 8 ++++---- src/interop_BeOS.cpp | 16 +++++++-------- src/interop_cocoa.m | 32 ++++++++++++++--------------- src/interop_ios.m | 46 +++++++++++++++++++++--------------------- 36 files changed, 259 insertions(+), 248 deletions(-) diff --git a/src/Audio.c b/src/Audio.c index c460c7e2e..ded4cc988 100644 --- a/src/Audio.c +++ b/src/Audio.c @@ -1411,9 +1411,9 @@ static cc_result Music_PlayOgg(struct Stream* source) { #ifdef CC_BUILD_ANDROID /* Don't play music while in the background on Android */ /* TODO: Not use such a terrible approach */ - if (!WindowInfo.Handle) { + if (!Window_Main.Handle) { Audio_Pause(&music_ctx); - while (!WindowInfo.Handle && !music_stopping) { + while (!Window_Main.Handle && !music_stopping) { Thread_Sleep(10); continue; } Audio_Play(&music_ctx); diff --git a/src/Camera.c b/src/Camera.c index a7f08aa19..e5b81b985 100644 --- a/src/Camera.c +++ b/src/Camera.c @@ -109,7 +109,7 @@ static void PerspectiveCamera_UpdateMouseRotation(double delta) { } static void PerspectiveCamera_UpdateMouse(double delta) { - if (!Gui.InputGrab && WindowInfo.Focused) Window_UpdateRawMouse(); + if (!Gui.InputGrab && Window_Main.Focused) Window_UpdateRawMouse(); PerspectiveCamera_UpdateMouseRotation(delta); cam_deltaX = 0; cam_deltaY = 0; diff --git a/src/Commands.c b/src/Commands.c index 0f041b17b..1a994cf31 100644 --- a/src/Commands.c +++ b/src/Commands.c @@ -213,7 +213,7 @@ static void ResolutionCommand_Execute(const cc_string* args, int argsCount) { int width, height; if (argsCount < 2) { Chat_Add4("&e/client: &fCurrent resolution is %i@%f2 x %i@%f2", - &WindowInfo.Width, &DisplayInfo.ScaleX, &WindowInfo.Height, &DisplayInfo.ScaleY); + &Window_Main.Width, &DisplayInfo.ScaleX, &Window_Main.Height, &DisplayInfo.ScaleY); } else if (!Convert_ParseInt(&args[0], &width) || !Convert_ParseInt(&args[1], &height)) { Chat_AddRaw("&e/client: &cWidth and height must be integers."); } else if (width <= 0 || height <= 0) { diff --git a/src/Game.c b/src/Game.c index 4344028c7..a0b497937 100644 --- a/src/Game.c +++ b/src/Game.c @@ -273,8 +273,8 @@ cc_bool Game_ValidateBitmapPow2(const cc_string* file, struct Bitmap* bmp) { } void Game_UpdateDimensions(void) { - Game.Width = max(WindowInfo.Width, 1); - Game.Height = max(WindowInfo.Height, 1); + Game.Width = max(Window_Main.Width, 1); + Game.Height = max(Window_Main.Height, 1); } static void Game_OnResize(void* obj) { @@ -298,7 +298,7 @@ static void HandleOnNewMapLoaded(void* obj) { } static void HandleInactiveChanged(void* obj) { - if (WindowInfo.Inactive) { + if (Window_Main.Inactive) { Chat_AddOf(&Gfx_LowPerfMessage, MSG_TYPE_EXTRASTATUS_2); Gfx_SetFpsLimit(false, 1000 / 1.0f); } else { @@ -601,7 +601,7 @@ static void Game_RenderFrame(double delta) { Game_Vertices = 0; Camera.Active->UpdateMouse(delta); - if (!WindowInfo.Focused && !Gui.InputGrab) Gui_ShowPauseMenu(); + if (!Window_Main.Focused && !Gui.InputGrab) Gui_ShowPauseMenu(); if (KeyBind_IsPressed(KEYBIND_ZOOM_SCROLL) && !Gui.InputGrab) { InputHandler_SetFOV(Camera.ZoomFov); @@ -618,7 +618,7 @@ static void Game_RenderFrame(double delta) { UpdateViewMatrix(); /* TODO: Not calling Gfx_EndFrame doesn't work with Direct3D9 */ - if (WindowInfo.Inactive) return; + if (Window_Main.Inactive) return; Gfx_Clear(); Gfx_LoadMatrix(MATRIX_PROJECTION, &Gfx.Projection); diff --git a/src/Graphics_D3D11.c b/src/Graphics_D3D11.c index ab3d9f85a..39858c3f2 100644 --- a/src/Graphics_D3D11.c +++ b/src/Graphics_D3D11.c @@ -74,7 +74,7 @@ static void CreateDeviceAndSwapChain(void) { desc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // RefreshRate intentionally left at 0 so display's refresh rate is used desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - desc.OutputWindow = WindowInfo.Handle; + desc.OutputWindow = Window_Main.Handle; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Windowed = TRUE; @@ -656,8 +656,8 @@ static void RS_UpdateViewport(void) { D3D11_VIEWPORT viewport; viewport.TopLeftX = 0; viewport.TopLeftY = 0; - viewport.Width = WindowInfo.Width; - viewport.Height = WindowInfo.Height; + viewport.Width = Window_Main.Width; + viewport.Height = Window_Main.Height; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; ID3D11DeviceContext_RSSetViewports(context, 1, &viewport); @@ -1074,8 +1074,8 @@ cc_result Gfx_TakeScreenshot(struct Stream* output) { ID3D11RenderTargetView_GetDesc(backbuffer, &backbuffer_desc); D3D11_TEXTURE2D_DESC desc = { 0 }; - desc.Width = WindowInfo.Width; - desc.Height = WindowInfo.Height; + desc.Width = Window_Main.Width; + desc.Height = Window_Main.Height; desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; diff --git a/src/Graphics_D3D9.c b/src/Graphics_D3D9.c index 76e372bab..9758b4972 100644 --- a/src/Graphics_D3D9.c +++ b/src/Graphics_D3D9.c @@ -137,7 +137,7 @@ static cc_bool deviceCreated; static void TryCreateDevice(void) { cc_result res; D3DCAPS9 caps; - HWND winHandle = (HWND)WindowInfo.Handle; + HWND winHandle = (HWND)Window_Main.Handle; D3DPRESENT_PARAMETERS args = { 0 }; D3D9_FillPresentArgs(&args); diff --git a/src/Gui.c b/src/Gui.c index 5feab28ee..350e9f974 100644 --- a/src/Gui.c +++ b/src/Gui.c @@ -27,8 +27,8 @@ static cc_uint8 priorities[GUI_MAX_SCREENS]; *----------------------------------------------------------Gui------------------------------------------------------------* *#########################################################################################################################*/ static CC_NOINLINE int GetWindowScale(void) { - float widthScale = WindowInfo.Width / 640.0f; - float heightScale = WindowInfo.Height / 480.0f; + float widthScale = Window_Main.Width / 640.0f; + float heightScale = Window_Main.Height / 480.0f; /* Use larger UI scaling on mobile */ /* TODO move this DPI scaling elsewhere.,. */ @@ -383,8 +383,8 @@ void Widget_SetLocation(void* widget, cc_uint8 horAnchor, cc_uint8 verAnchor, in void Widget_CalcPosition(void* widget) { struct Widget* w = (struct Widget*)widget; - w->x = Gui_CalcPos(w->horAnchor, w->xOffset, w->width , WindowInfo.Width ); - w->y = Gui_CalcPos(w->verAnchor, w->yOffset, w->height, WindowInfo.Height); + w->x = Gui_CalcPos(w->horAnchor, w->xOffset, w->width , Window_Main.Width ); + w->y = Gui_CalcPos(w->verAnchor, w->yOffset, w->height, Window_Main.Height); } void Widget_Reset(void* widget) { diff --git a/src/Input.c b/src/Input.c index dd5c7795e..cf3b9320a 100644 --- a/src/Input.c +++ b/src/Input.c @@ -1149,7 +1149,7 @@ static void OnInputUp(void* obj, int key) { if (KeyBind_Claims(KEYBIND_PICK_BLOCK, key)) MouseStateRelease(MOUSE_MIDDLE); } -static void OnFocusChanged(void* obj) { if (!WindowInfo.Focused) Input_Clear(); } +static void OnFocusChanged(void* obj) { if (!Window_Main.Focused) Input_Clear(); } static void OnInit(void) { Event_Register_(&PointerEvents.Moved, NULL, OnPointerMove); Event_Register_(&PointerEvents.Down, NULL, OnPointerDown); diff --git a/src/LBackend.c b/src/LBackend.c index 66d9dfb53..3660c3fff 100644 --- a/src/LBackend.c +++ b/src/LBackend.c @@ -120,11 +120,11 @@ static void LBackend_LayoutDimensions(struct LWidget* w) { switch (l->type) { case LLAYOUT_WIDTH: - w->width = WindowInfo.Width - w->x - Display_ScaleX(l->offset); + w->width = Window_Main.Width - w->x - Display_ScaleX(l->offset); w->width = max(1, w->width); break; case LLAYOUT_HEIGHT: - w->height = WindowInfo.Height - w->y - Display_ScaleY(l->offset); + w->height = Window_Main.Height - w->y - Display_ScaleY(l->offset); w->height = max(1, w->height); break; } @@ -135,8 +135,8 @@ static void LBackend_LayoutDimensions(struct LWidget* w) { void LBackend_LayoutWidget(struct LWidget* w) { const struct LLayout* l = w->layouts; - w->x = Gui_CalcPos(l[0].type & 0xFF, Display_ScaleX(l[0].offset), w->width, WindowInfo.Width); - w->y = Gui_CalcPos(l[1].type & 0xFF, Display_ScaleY(l[1].offset), w->height, WindowInfo.Height); + w->x = Gui_CalcPos(l[0].type & 0xFF, Display_ScaleX(l[0].offset), w->width, Window_Main.Width); + w->y = Gui_CalcPos(l[1].type & 0xFF, Display_ScaleY(l[1].offset), w->height, Window_Main.Height); /* e.g. Table widget needs adjusts width/height based on window */ if (l[1].type & LLAYOUT_EXTRA) @@ -181,8 +181,8 @@ static CC_NOINLINE void MarkAreaDirty(int x, int y, int width, int height) { void LBackend_InitFramebuffer(void) { struct Bitmap bmp; - bmp.width = max(WindowInfo.Width, 1); - bmp.height = max(WindowInfo.Height, 1); + bmp.width = max(Window_Main.Width, 1); + bmp.height = max(Window_Main.Height, 1); Window_AllocFramebuffer(&bmp); Context2D_Wrap(&framebuffer, &bmp); @@ -1088,7 +1088,7 @@ static void LTable_ScrollbarClick(struct LTable* w, int idx) { } void LBackend_TableMouseDown(struct LTable* w, int idx) { - if (Pointers[idx].x >= WindowInfo.Width - scrollbarWidth) { + if (Pointers[idx].x >= Window_Main.Width - scrollbarWidth) { LTable_ScrollbarClick(w, idx); w->_lastRow = -1; } else if (Pointers[idx].y < w->rowsBegY) { diff --git a/src/LScreens.c b/src/LScreens.c index 02d4502f8..ea611bf06 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -1292,7 +1292,7 @@ static void ServersScreen_Activated(struct LScreen* s_) { ServersScreen_ReloadServers(s); /* This is so typing on keyboard by default searchs server list */ /* But don't do that when it would cause on-screen keyboard to show */ - if (WindowInfo.SoftKeyboard) return; + if (Window_Main.SoftKeyboard) return; LScreen_SelectWidget(s_, 0, (struct LWidget*)&s->iptSearch, false); } diff --git a/src/Launcher.c b/src/Launcher.c index fa90ab531..1e2b389c8 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -270,7 +270,7 @@ void Launcher_Run(void) { for (;;) { Window_ProcessEvents(10 / 1000.0); - if (!WindowInfo.Exists || Launcher_ShouldExit) break; + if (!Window_Main.Exists || Launcher_ShouldExit) break; Launcher_Active->Tick(Launcher_Active); LBackend_Tick(); @@ -293,7 +293,7 @@ void Launcher_Run(void) { if (res) Logger_SysWarn(res, action); } - if (WindowInfo.Exists) Window_RequestClose(); + if (Window_Main.Exists) Window_RequestClose(); #endif } @@ -529,7 +529,7 @@ void Launcher_DrawTitle(struct FontDesc* font, const char* text, struct Context2 int x; /* Skip dragging logo when very small window to save space */ - if (WindowInfo.Height < 240) return; + if (Window_Main.Height < 240) return; DrawTextArgs_Make(&args, &title, font, false); x = ctx->width / 2 - Drawer2D_TextWidth(&args) / 2; diff --git a/src/Menus.c b/src/Menus.c index c5664f203..609a9bd6d 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -79,7 +79,7 @@ static void Menu_RenderBounds(void) { Then using wolfram alpha to solve the glblendfunc equation */ PackedCol topCol = PackedCol_Make(24, 24, 24, 105); PackedCol bottomCol = PackedCol_Make(51, 51, 98, 162); - Gfx_Draw2DGradient(0, 0, WindowInfo.Width, WindowInfo.Height, topCol, bottomCol); + Gfx_Draw2DGradient(0, 0, Window_Main.Width, Window_Main.Height, topCol, bottomCol); } @@ -994,13 +994,13 @@ static void EditHotkeyScreen_Update(void* screen, double delta) { static void EditHotkeyScreen_Layout(void* screen) { struct EditHotkeyScreen* s = (struct EditHotkeyScreen*)screen; s->barWidth = Display_ScaleX(500); - s->barX = Gui_CalcPos(ANCHOR_CENTRE, 0, s->barWidth, WindowInfo.Width); + s->barX = Gui_CalcPos(ANCHOR_CENTRE, 0, s->barWidth, Window_Main.Width); s->barHeight = Display_ScaleY(2); s->barY[0] = Gui_CalcPos(ANCHOR_CENTRE, Display_ScaleY(-65), - s->barHeight, WindowInfo.Height); + s->barHeight, Window_Main.Height); s->barY[1] = Gui_CalcPos(ANCHOR_CENTRE, Display_ScaleY( 45), - s->barHeight, WindowInfo.Height); + s->barHeight, Window_Main.Height); Widget_SetLocation(&s->btns[0], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -150); Widget_SetLocation(&s->btns[1], ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -100); @@ -2334,7 +2334,7 @@ static void MenuInputOverlay_Layout(void* screen) { Widget_SetLocation(&s->input, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 110); Widget_SetLocation(&s->ok, ANCHOR_CENTRE, ANCHOR_CENTRE, 240, 110); Widget_SetLocation(&s->Default, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 150); - } else if (WindowInfo.SoftKeyboard == SOFT_KEYBOARD_SHIFT) { + } else if (Window_Main.SoftKeyboard == SOFT_KEYBOARD_SHIFT) { Widget_SetLocation(&s->input, ANCHOR_CENTRE, ANCHOR_MAX, 0, 65); Widget_SetLocation(&s->ok, ANCHOR_CENTRE, ANCHOR_MAX, 120, 25); Widget_SetLocation(&s->Default, ANCHOR_CENTRE, ANCHOR_MAX, -120, 25); @@ -2458,7 +2458,7 @@ static void MenuOptionsScreen_LayoutExtHelp(struct MenuOptionsScreen* s) { Widget_SetLocation(&s->extHelp, ANCHOR_MIN, ANCHOR_CENTRE_MIN, 0, 100); /* If use centre align above, then each line in extended help gets */ /* centered aligned separately - which is not the desired behaviour. */ - s->extHelp.xOffset = WindowInfo.Width / 2 - s->extHelp.width / 2; + s->extHelp.xOffset = Window_Main.Width / 2 - s->extHelp.width / 2; Widget_Layout(&s->extHelp); } @@ -3546,12 +3546,12 @@ static void TexIdsOverlay_Layout(void* screen) { struct TexIdsOverlay* s = (struct TexIdsOverlay*)screen; int size; - size = WindowInfo.Height / ATLAS2D_TILES_PER_ROW; + size = Window_Main.Height / ATLAS2D_TILES_PER_ROW; size = (size / 8) * 8; Math_Clamp(size, 8, 40); - s->xOffset = Gui_CalcPos(ANCHOR_CENTRE, 0, size * Atlas2D.RowsCount, WindowInfo.Width); - s->yOffset = Gui_CalcPos(ANCHOR_CENTRE, 0, size * ATLAS2D_TILES_PER_ROW, WindowInfo.Height); + s->xOffset = Gui_CalcPos(ANCHOR_CENTRE, 0, size * Atlas2D.RowsCount, Window_Main.Width); + s->yOffset = Gui_CalcPos(ANCHOR_CENTRE, 0, size * ATLAS2D_TILES_PER_ROW, Window_Main.Height); s->tileSize = size; /* Can't use vertical centreing here */ diff --git a/src/Program.c b/src/Program.c index 474ebac54..fef95a37f 100644 --- a/src/Program.c +++ b/src/Program.c @@ -141,7 +141,7 @@ void android_main(void) { #elif defined CC_BUILD_CONSOLE int main(int argc, char** argv) { SetupProgram(argc, argv); - while (WindowInfo.Exists) { + while (Window_Main.Exists) { RunProgram(argc, argv); } diff --git a/src/Screens.c b/src/Screens.c index 630f8d071..6e9e8c35f 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -337,10 +337,10 @@ static void HUDScreen_BuildCrosshairsMesh(struct VertexTextured** ptr) { static struct Texture tex = { 0, Tex_Rect(0,0,0,0), Tex_UV(0.0f,0.0f, 15/256.0f,15/256.0f) }; int extent; - extent = (int)(CH_EXTENT * Gui_Scale(WindowInfo.Height / 480.0f)); + extent = (int)(CH_EXTENT * Gui_Scale(Window_Main.Height / 480.0f)); tex.ID = Gui.IconsTex; - tex.x = (WindowInfo.Width / 2) - extent; - tex.y = (WindowInfo.Height / 2) - extent; + tex.x = (Window_Main.Width / 2) - extent; + tex.y = (Window_Main.Height / 2) - extent; tex.Width = extent * 2; tex.Height = extent * 2; @@ -509,9 +509,9 @@ static void TabListOverlay_Layout(void* screen) { width += paddingX * 2; height += paddingY * 2; - y = WindowInfo.Height / 4 - height / 2; - s->x = Gui_CalcPos(ANCHOR_CENTRE, 0, width , WindowInfo.Width ); - s->y = Gui_CalcPos(ANCHOR_CENTRE, -max(0, y), height, WindowInfo.Height); + y = Window_Main.Height / 4 - height / 2; + s->x = Gui_CalcPos(ANCHOR_CENTRE, 0, width , Window_Main.Width ); + s->y = Gui_CalcPos(ANCHOR_CENTRE, -max(0, y), height, Window_Main.Height); x = s->x + paddingX; y = s->y + paddingY; @@ -887,11 +887,11 @@ static void ChatScreen_UpdateChatYOffsets(struct ChatScreen* s) { y = min(s->input.base.y, Gui_HUD->hotbar.y); y -= s->input.base.yOffset; /* add some padding */ - s->altText.yOffset = WindowInfo.Height - y; + s->altText.yOffset = Window_Main.Height - y; Widget_Layout(&s->altText); pad = s->altText.active ? 5 : 10; - s->clientStatus.yOffset = WindowInfo.Height - s->altText.y + pad; + s->clientStatus.yOffset = Window_Main.Height - s->altText.y + pad; Widget_Layout(&s->clientStatus); s->chat.yOffset = s->clientStatus.yOffset + s->clientStatus.height; Widget_Layout(&s->chat); @@ -1237,19 +1237,19 @@ static void ChatScreen_Layout(void* screen) { Widget_Layout(&s->bottomRight); Widget_SetLocation(&s->announcement, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 0); - s->announcement.yOffset = -WindowInfo.Height / 4; + s->announcement.yOffset = -Window_Main.Height / 4; Widget_Layout(&s->announcement); Widget_SetLocation(&s->bigAnnouncement, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 0); - s->bigAnnouncement.yOffset = -WindowInfo.Height / 16; + s->bigAnnouncement.yOffset = -Window_Main.Height / 16; Widget_Layout(&s->bigAnnouncement); Widget_SetLocation(&s->smallAnnouncement, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 0); - s->smallAnnouncement.yOffset = WindowInfo.Height / 20; + s->smallAnnouncement.yOffset = Window_Main.Height / 20; Widget_Layout(&s->smallAnnouncement); #ifdef CC_BUILD_TOUCH - if (WindowInfo.SoftKeyboard == SOFT_KEYBOARD_SHIFT) { + if (Window_Main.SoftKeyboard == SOFT_KEYBOARD_SHIFT) { Widget_SetLocation(&s->send, ANCHOR_MAX, ANCHOR_MAX, 10, 60); Widget_SetLocation(&s->cancel, ANCHOR_MAX, ANCHOR_MAX, 10, 10); Widget_SetLocation(&s->more, ANCHOR_MAX, ANCHOR_MAX, 10, 110); @@ -1343,7 +1343,7 @@ static void ChatScreen_KeyUp(void* screen, int key) { #endif if (Server.SupportsFullCP437 && KeyBind_Claims(KEYBIND_EXT_INPUT, key)) { - if (!WindowInfo.Focused) return; + if (!Window_Main.Focused) return; ChatScreen_ToggleAltInput(s); } } @@ -1775,7 +1775,7 @@ static void LoadingScreen_SetMessage(struct LoadingScreen* s) { } static void LoadingScreen_CalcMaxVertices(struct LoadingScreen* s) { - s->rows = Math_CeilDiv(WindowInfo.Height, LOADING_TILE_SIZE); + s->rows = Math_CeilDiv(Window_Main.Height, LOADING_TILE_SIZE); s->maxVertices = Screen_CalcDefaultMaxVertices(s) + s->rows * 4; } @@ -1787,9 +1787,9 @@ static void LoadingScreen_Layout(void* screen) { y = Display_ScaleY(34); s->progWidth = Display_ScaleX(200); - s->progX = Gui_CalcPos(ANCHOR_CENTRE, 0, s->progWidth, WindowInfo.Width); + s->progX = Gui_CalcPos(ANCHOR_CENTRE, 0, s->progWidth, Window_Main.Width); s->progHeight = Display_ScaleY(4); - s->progY = Gui_CalcPos(ANCHOR_CENTRE, y, s->progHeight, WindowInfo.Height); + s->progY = Gui_CalcPos(ANCHOR_CENTRE, y, s->progHeight, Window_Main.Height); oldRows = s->rows; LoadingScreen_CalcMaxVertices(s); @@ -1823,9 +1823,9 @@ static void LoadingScreen_BuildMesh(void* screen) { ptr = &data; loc = Block_Tex(BLOCK_DIRT, FACE_YMAX); - Tex_SetRect(tex, 0,0, WindowInfo.Width,LOADING_TILE_SIZE); + Tex_SetRect(tex, 0,0, Window_Main.Width,LOADING_TILE_SIZE); tex.uv = Atlas1D_TexRec(loc, 1, &atlasIndex); - tex.uv.U2 = (float)WindowInfo.Width / LOADING_TILE_SIZE; + tex.uv.U2 = (float)Window_Main.Width / LOADING_TILE_SIZE; for (i = 0; i < s->rows; i++) { tex.y = i * LOADING_TILE_SIZE; @@ -2099,7 +2099,7 @@ static void DisconnectScreen_Update(void* screen, double delta) { static void DisconnectScreen_Render(void* screen, double delta) { PackedCol top = PackedCol_Make(64, 32, 32, 255); PackedCol bottom = PackedCol_Make(80, 16, 16, 255); - Gfx_Draw2DGradient(0, 0, WindowInfo.Width, WindowInfo.Height, top, bottom); + Gfx_Draw2DGradient(0, 0, Window_Main.Width, Window_Main.Height, top, bottom); Screen_Render2Widgets(screen, delta); } diff --git a/src/Widgets.c b/src/Widgets.c index 5917ad675..97285407c 100644 --- a/src/Widgets.c +++ b/src/Widgets.c @@ -565,7 +565,7 @@ static void HotbarWidget_InputUp(void* widget, int key) { if (w->altHandled) { w->altHandled = false; return; } /* handled already */ /* Don't switch hotbar when alt+tabbing to another window */ - if (WindowInfo.Focused) Inventory_SwitchHotbar(); + if (Window_Main.Focused) Inventory_SwitchHotbar(); } static int HotbarWidget_PointerDown(void* widget, int id, int x, int y) { @@ -1780,7 +1780,7 @@ static void ChatInputWidget_Render(void* widget, double delta) { caretAtEnd = (w->caretY == i) && (w->caretX == INPUTWIDGET_LEN || w->caretPos == -1); width = w->lineWidths[i] + (caretAtEnd ? w->caretTex.Width : 0); /* Cover whole window width to match Minecraft behaviour */ - width = max(width, WindowInfo.Width - x * 4); + width = max(width, Window_Main.Width - x * 4); Gfx_Draw2DFlat(x, y, width + w->padding * 2, w->lineHeight, backColor); y += w->lineHeight; @@ -2035,7 +2035,7 @@ static void TextGroupWidget_Reposition(void* widget) { for (i = 0, y = w->y; i < w->lines; i++) { - textures[i].x = Gui_CalcPos(w->horAnchor, w->xOffset, textures[i].Width, WindowInfo.Width); + textures[i].x = Gui_CalcPos(w->horAnchor, w->xOffset, textures[i].Width, Window_Main.Width); textures[i].y = y; y += textures[i].Height; } @@ -2313,7 +2313,7 @@ void TextGroupWidget_Redraw(struct TextGroupWidget* w, int index) { tex.Height = w->collapsible[index] ? 0 : w->defaultHeight; } - tex.x = Gui_CalcPos(w->horAnchor, w->xOffset, tex.Width, WindowInfo.Width); + tex.x = Gui_CalcPos(w->horAnchor, w->xOffset, tex.Width, Window_Main.Width); w->textures[index] = tex; Widget_Layout(w); } diff --git a/src/Window.h b/src/Window.h index c506c1989..24499d084 100644 --- a/src/Window.h +++ b/src/Window.h @@ -68,8 +68,8 @@ static CC_INLINE int Display_ScaleX(int x) { return (int)(x * DisplayInfo.ScaleX /* Scales the given Y coordinate from 96 dpi to current display dpi. */ static CC_INLINE int Display_ScaleY(int y) { return (int)(y * DisplayInfo.ScaleY); } -/* Data for the game/launcher window. */ -CC_VAR extern struct _WinData { +/* Data for a window */ +struct _WindowData { /* Readonly platform-specific handle to the window. */ void* Handle; /* Size of the content area of the window. (i.e. area that can draw to) */ @@ -84,7 +84,13 @@ CC_VAR extern struct _WinData { /* Whether this window is backgrounded / inactivated */ /* (rendering is not performed when window is inactive) */ cc_bool Inactive; -} WindowInfo; +}; + +/* Data for the game/launcher window */ +CC_VAR extern struct _WindowData WindowInfo; /* Named WindowInfo for backwards compatibility */ +#define Window_Main WindowInfo +/* Data for alternate game window (e.g. 3DS) */ +extern struct _WindowData Window_Alt; /* Initialises state for window, input, and display. */ void Window_Init(void); diff --git a/src/Window_3DS.c b/src/Window_3DS.c index b9836bec8..3644b6782 100644 --- a/src/Window_3DS.c +++ b/src/Window_3DS.c @@ -17,7 +17,8 @@ static cc_bool launcherMode; static Result irrst_result; struct _DisplayData DisplayInfo; -struct _WinData WindowInfo; +struct _WindowData WindowInfo; +struct _WindowData Window_Alt; // Note from https://github.com/devkitPro/libctru/blob/master/libctru/include/3ds/gfx.h @@ -42,13 +43,17 @@ void Window_Init(void) { DisplayInfo.ScaleX = 0.5; DisplayInfo.ScaleY = 0.5; - WindowInfo.Width = height; // deliberately swapped - WindowInfo.Height = width; // deliberately swapped - WindowInfo.Focused = true; - WindowInfo.Exists = true; + Window_Main.Width = height; // deliberately swapped + Window_Main.Height = width; // deliberately swapped + Window_Main.Focused = true; + Window_Main.Exists = true; Input.Sources = INPUT_SOURCE_GAMEPAD; irrst_result = irrstInit(); + + gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, &width, &height); + Window_Alt.Width = height; // deliberately swapped + Window_Alt.Height = width; // deliberately swapped } void Window_Free(void) { irrstExit(); } @@ -113,7 +118,7 @@ static void ProcessTouchInput(int mods) { if (touchActive) { // rescale X from [0, bottom_FB_width) to [0, top_FB_width) - int x = touch.px * WindowInfo.Width / GSP_SCREEN_HEIGHT_BOTTOM; + int x = touch.px * Window_Main.Width / GSP_SCREEN_HEIGHT_BOTTOM; int y = touch.py; Pointer_SetPosition(0, x, y); } @@ -129,7 +134,7 @@ void Window_ProcessEvents(double delta) { /* TODO implement */ if (!aptMainLoop()) { - WindowInfo.Exists = false; + Window_Main.Exists = false; Window_RequestClose(); return; } diff --git a/src/Window_Android.c b/src/Window_Android.c index e374cc1fb..eb759293d 100644 --- a/src/Window_Android.c +++ b/src/Window_Android.c @@ -20,9 +20,9 @@ static jmethodID JAVA_processedSurfaceDestroyed, JAVA_processEvents; static jmethodID JAVA_getDpiX, JAVA_getDpiY, JAVA_setupForGame; static void RefreshWindowBounds(void) { - WindowInfo.Width = ANativeWindow_getWidth(win_handle); - WindowInfo.Height = ANativeWindow_getHeight(win_handle); - Platform_Log2("SCREEN BOUNDS: %i,%i", &WindowInfo.Width, &WindowInfo.Height); + Window_Main.Width = ANativeWindow_getWidth(win_handle); + Window_Main.Height = ANativeWindow_getHeight(win_handle); + Platform_Log2("SCREEN BOUNDS: %i,%i", &Window_Main.Width, &Window_Main.Height); Event_RaiseVoid(&WindowEvents.Resized); } @@ -149,7 +149,7 @@ static void JNICALL java_processSurfaceCreated(JNIEnv* env, jobject o, jobject s Platform_LogConst("WIN - CREATED"); win_handle = ANativeWindow_fromSurface(env, surface); winCreated = true; - WindowInfo.Handle = win_handle; + Window_Main.Handle = win_handle; RefreshWindowBounds(); /* TODO: Restore context */ Event_RaiseVoid(&WindowEvents.Created); @@ -160,7 +160,7 @@ static void JNICALL java_processSurfaceDestroyed(JNIEnv* env, jobject o) { if (win_handle) ANativeWindow_release(win_handle); win_handle = NULL; - WindowInfo.Handle = NULL; + Window_Main.Handle = NULL; /* eglSwapBuffers might return EGL_BAD_SURFACE, EGL_BAD_ALLOC, or some other error */ /* Instead the context is lost here in a consistent manner */ if (Gfx.Created) Gfx_LoseContext("surface lost"); @@ -198,20 +198,20 @@ static void JNICALL java_onPause(JNIEnv* env, jobject o) { static void JNICALL java_onDestroy(JNIEnv* env, jobject o) { Platform_LogConst("APP - ON DESTROY"); - if (WindowInfo.Exists) Window_RequestClose(); + if (Window_Main.Exists) Window_RequestClose(); /* TODO: signal to java code we're done */ /* JavaICall_Void(env, JAVA_processedDestroyed", NULL); */ } static void JNICALL java_onGotFocus(JNIEnv* env, jobject o) { Platform_LogConst("APP - GOT FOCUS"); - WindowInfo.Focused = true; + Window_Main.Focused = true; Event_RaiseVoid(&WindowEvents.FocusChanged); } static void JNICALL java_onLostFocus(JNIEnv* env, jobject o) { Platform_LogConst("APP - LOST FOCUS"); - WindowInfo.Focused = false; + Window_Main.Focused = false; Event_RaiseVoid(&WindowEvents.FocusChanged); /* TODO: Disable rendering? */ } @@ -280,7 +280,7 @@ void Window_Init(void) { JavaRegisterNatives(env, methods); CacheMethodRefs(env); - WindowInfo.SoftKeyboard = SOFT_KEYBOARD_RESIZE; + Window_Main.SoftKeyboard = SOFT_KEYBOARD_RESIZE; Input_SetTouchMode(true); Input.Sources = INPUT_SOURCE_NORMAL; @@ -312,7 +312,7 @@ static void RemakeWindowSurface(void) { } static void DoCreateWindow(void) { - WindowInfo.Exists = true; + Window_Main.Exists = true; RemakeWindowSurface(); /* always start as fullscreen */ Window_EnterFullscreen(); @@ -358,7 +358,7 @@ void Window_Show(void) { } /* Window already visible */ void Window_SetSize(int width, int height) { } void Window_RequestClose(void) { - WindowInfo.Exists = false; + Window_Main.Exists = false; Event_RaiseVoid(&WindowEvents.Closing); /* TODO: Do we need to call finish here */ /* ANativeActivity_finish(app->activity); */ diff --git a/src/Window_Carbon.c b/src/Window_Carbon.c index 3aaf82ec5..363c74a00 100644 --- a/src/Window_Carbon.c +++ b/src/Window_Carbon.c @@ -163,8 +163,8 @@ static void RefreshWindowBounds(void) { /* TODO: kWindowContentRgn ??? */ GetWindowBounds(win_handle, kWindowGlobalPortRgn, &r); - windowX = r.left; WindowInfo.Width = r.right - r.left; - windowY = r.top; WindowInfo.Height = r.bottom - r.top; + windowX = r.left; Window_Main.Width = r.right - r.left; + windowY = r.top; Window_Main.Height = r.bottom - r.top; } static OSStatus Window_ProcessKeyboardEvent(EventRef inEvent) { @@ -209,30 +209,30 @@ static OSStatus Window_ProcessWindowEvent(EventRef inEvent) { switch (GetEventKind(inEvent)) { case kEventWindowClose: - WindowInfo.Exists = false; + Window_Main.Exists = false; Event_RaiseVoid(&WindowEvents.Closing); return eventNotHandledErr; case kEventWindowClosed: - WindowInfo.Exists = false; + Window_Main.Exists = false; return 0; case kEventWindowBoundsChanged: - oldWidth = WindowInfo.Width; oldHeight = WindowInfo.Height; + oldWidth = Window_Main.Width; oldHeight = Window_Main.Height; RefreshWindowBounds(); - if (oldWidth != WindowInfo.Width || oldHeight != WindowInfo.Height) { + if (oldWidth != Window_Main.Width || oldHeight != Window_Main.Height) { Event_RaiseVoid(&WindowEvents.Resized); } return eventNotHandledErr; case kEventWindowActivated: - WindowInfo.Focused = true; + Window_Main.Focused = true; Event_RaiseVoid(&WindowEvents.FocusChanged); return eventNotHandledErr; case kEventWindowDeactivated: - WindowInfo.Focused = false; + Window_Main.Focused = false; Event_RaiseVoid(&WindowEvents.FocusChanged); return eventNotHandledErr; @@ -285,8 +285,8 @@ static OSStatus Window_ProcessMouseEvent(EventRef inEvent) { if (!win_fullscreen) { mouseX -= windowX; mouseY -= windowY; - if (mouseX < 0 || mouseX >= WindowInfo.Width) return eventNotHandledErr; - if (mouseY < 0 || mouseY >= WindowInfo.Height) return eventNotHandledErr; + if (mouseX < 0 || mouseX >= Window_Main.Width) return eventNotHandledErr; + if (mouseY < 0 || mouseY >= Window_Main.Height) return eventNotHandledErr; } kind = GetEventKind(inEvent); @@ -501,8 +501,8 @@ static void DoCreateWindow(int width, int height) { /* TODO: Use BringWindowToFront instead.. (look in the file which has RepositionWindow in it) !!!! */ HookEvents(); Window_CommonCreate(); - WindowInfo.Exists = true; - WindowInfo.Handle = win_handle; + Window_Main.Exists = true; + Window_Main.Handle = win_handle; /* CGAssociateMouseAndMouseCursorPosition implicitly grabs cursor */ conn = _CGSDefaultConnection(); @@ -549,8 +549,8 @@ void Window_SetSize(int width, int height) { void Window_RequestClose(void) { /* DisposeWindow only sends a kEventWindowClosed */ Event_RaiseVoid(&WindowEvents.Closing); - if (WindowInfo.Exists) DisposeWindow(win_handle); - WindowInfo.Exists = false; + if (Window_Main.Exists) DisposeWindow(win_handle); + Window_Main.Exists = false; } void Window_ProcessEvents(double delta) { @@ -626,8 +626,8 @@ void Window_DrawFramebuffer(Rect2D r) { /* TODO: Only update changed bit.. */ rect.origin.x = 0; rect.origin.y = 0; - rect.size.width = WindowInfo.Width; - rect.size.height = WindowInfo.Height; + rect.size.width = Window_Main.Width; + rect.size.height = Window_Main.Height; err = QDBeginCGContext(fb_port, &context); if (err) Logger_Abort2(err, "Begin draw"); @@ -700,11 +700,11 @@ cc_result Window_EnterFullscreen(void) { } win_fullscreen = true; - ctx_windowWidth = WindowInfo.Width; - ctx_windowHeight = WindowInfo.Height; + ctx_windowWidth = Window_Main.Width; + ctx_windowHeight = Window_Main.Height; - windowX = DisplayInfo.x; WindowInfo.Width = DisplayInfo.Width; - windowY = DisplayInfo.y; WindowInfo.Height = DisplayInfo.Height; + windowX = DisplayInfo.x; Window_Main.Width = DisplayInfo.Width; + windowY = DisplayInfo.y; Window_Main.Height = DisplayInfo.Height; Event_RaiseVoid(&WindowEvents.Resized); return 0; diff --git a/src/Window_Dreamcast.c b/src/Window_Dreamcast.c index a44a09164..94ba5f9db 100644 --- a/src/Window_Dreamcast.c +++ b/src/Window_Dreamcast.c @@ -14,7 +14,7 @@ static cc_bool launcherMode; struct _DisplayData DisplayInfo; -struct _WinData WindowInfo; +struct _WindowData WindowInfo; void Window_Init(void) { DisplayInfo.Width = vid_mode->width; @@ -23,10 +23,10 @@ void Window_Init(void) { DisplayInfo.ScaleX = 1; DisplayInfo.ScaleY = 1; - WindowInfo.Width = vid_mode->width; - WindowInfo.Height = vid_mode->height; - WindowInfo.Focused = true; - WindowInfo.Exists = true; + Window_Main.Width = vid_mode->width; + Window_Main.Height = vid_mode->height; + Window_Main.Focused = true; + Window_Main.Exists = true; Input.Sources = INPUT_SOURCE_GAMEPAD; DisplayInfo.ContentOffsetX = 10; diff --git a/src/Window_GCWii.c b/src/Window_GCWii.c index a155c6f4c..3aa1f671d 100644 --- a/src/Window_GCWii.c +++ b/src/Window_GCWii.c @@ -22,11 +22,11 @@ static void* xfb; static GXRModeObj* rmode; void* Window_XFB; struct _DisplayData DisplayInfo; -struct _WinData WindowInfo; +struct _WindowData WindowInfo; static void OnPowerOff(void) { - WindowInfo.Exists = false; + Window_Main.Exists = false; Window_RequestClose(); } static void InitVideo(void) { @@ -67,10 +67,10 @@ void Window_Init(void) { DisplayInfo.ScaleX = 1; DisplayInfo.ScaleY = 1; - WindowInfo.Width = rmode->fbWidth; - WindowInfo.Height = rmode->xfbHeight; - WindowInfo.Focused = true; - WindowInfo.Exists = true; + Window_Main.Width = rmode->fbWidth; + Window_Main.Height = rmode->xfbHeight; + Window_Main.Focused = true; + Window_Main.Exists = true; Input.Sources = INPUT_SOURCE_GAMEPAD; DisplayInfo.ContentOffsetX = 10; diff --git a/src/Window_N64.c b/src/Window_N64.c index 32529597e..b69a7f483 100644 --- a/src/Window_N64.c +++ b/src/Window_N64.c @@ -15,7 +15,7 @@ static cc_bool launcherMode; struct _DisplayData DisplayInfo; -struct _WinData WindowInfo; +struct _WindowData WindowInfo; void Window_Init(void) { display_init(RESOLUTION_320x240, DEPTH_32_BPP, 2, GAMMA_NONE, FILTERS_DISABLED); @@ -27,10 +27,10 @@ void Window_Init(void) { DisplayInfo.ScaleX = 0.5f; DisplayInfo.ScaleY = 0.5f; - WindowInfo.Width = DisplayInfo.Width; - WindowInfo.Height = DisplayInfo.Height; - WindowInfo.Focused = true; - WindowInfo.Exists = true; + Window_Main.Width = DisplayInfo.Width; + Window_Main.Height = DisplayInfo.Height; + Window_Main.Focused = true; + Window_Main.Exists = true; Input.Sources = INPUT_SOURCE_GAMEPAD; DisplayInfo.ContentOffsetX = 10; diff --git a/src/Window_PS2.c b/src/Window_PS2.c index f3c105ba0..fcd63f8cc 100644 --- a/src/Window_PS2.c +++ b/src/Window_PS2.c @@ -25,7 +25,7 @@ static cc_bool launcherMode; static char padBuf[256] __attribute__((aligned(64))); struct _DisplayData DisplayInfo; -struct _WinData WindowInfo; +struct _WindowData WindowInfo; void Window_Init(void) { DisplayInfo.Width = 640; @@ -34,10 +34,10 @@ void Window_Init(void) { DisplayInfo.ScaleX = 1; DisplayInfo.ScaleY = 1; - WindowInfo.Width = DisplayInfo.Width; - WindowInfo.Height = DisplayInfo.Height; - WindowInfo.Focused = true; - WindowInfo.Exists = true; + Window_Main.Width = DisplayInfo.Width; + Window_Main.Height = DisplayInfo.Height; + Window_Main.Focused = true; + Window_Main.Exists = true; Input.Sources = INPUT_SOURCE_GAMEPAD; DisplayInfo.ContentOffsetX = 10; diff --git a/src/Window_PS3.c b/src/Window_PS3.c index fa1e6d591..70483baec 100644 --- a/src/Window_PS3.c +++ b/src/Window_PS3.c @@ -24,12 +24,12 @@ static KbData kb_data; static KbConfig kb_config; struct _DisplayData DisplayInfo; -struct _WinData WindowInfo; +struct _WindowData WindowInfo; static void sysutil_callback(u64 status, u64 param, void* usrdata) { switch (status) { case SYSUTIL_EXIT_GAME: - WindowInfo.Exists = false; + Window_Main.Exists = false; Window_RequestClose(); break; } @@ -50,10 +50,10 @@ void Window_Init(void) { DisplayInfo.ScaleX = 1; DisplayInfo.ScaleY = 1; - WindowInfo.Width = resolution.width; - WindowInfo.Height = resolution.height; - WindowInfo.Focused = true; - WindowInfo.Exists = true; + Window_Main.Width = resolution.width; + Window_Main.Height = resolution.height; + Window_Main.Focused = true; + Window_Main.Exists = true; Input.Sources = INPUT_SOURCE_GAMEPAD; DisplayInfo.ContentOffsetX = 20; diff --git a/src/Window_PSP.c b/src/Window_PSP.c index ac13c390c..ff66ba611 100644 --- a/src/Window_PSP.c +++ b/src/Window_PSP.c @@ -20,7 +20,7 @@ static cc_bool launcherMode; struct _DisplayData DisplayInfo; -struct _WinData WindowInfo; +struct _WindowData WindowInfo; void Window_Init(void) { DisplayInfo.Width = SCREEN_WIDTH; @@ -29,10 +29,10 @@ void Window_Init(void) { DisplayInfo.ScaleX = 1; DisplayInfo.ScaleY = 1; - WindowInfo.Width = SCREEN_WIDTH; - WindowInfo.Height = SCREEN_HEIGHT; - WindowInfo.Focused = true; - WindowInfo.Exists = true; + Window_Main.Width = SCREEN_WIDTH; + Window_Main.Height = SCREEN_HEIGHT; + Window_Main.Focused = true; + Window_Main.Exists = true; Input.Sources = INPUT_SOURCE_GAMEPAD; sceCtrlSetSamplingCycle(0); diff --git a/src/Window_PSVita.c b/src/Window_PSVita.c index 15000321c..2c58f4b4e 100644 --- a/src/Window_PSVita.c +++ b/src/Window_PSVita.c @@ -17,7 +17,7 @@ static cc_bool launcherMode; static SceTouchPanelInfo frontPanel; struct _DisplayData DisplayInfo; -struct _WinData WindowInfo; +struct _WindowData WindowInfo; #define DISPLAY_WIDTH 960 #define DISPLAY_HEIGHT 544 @@ -37,10 +37,10 @@ void Window_Init(void) { DisplayInfo.ScaleX = 1; DisplayInfo.ScaleY = 1; - WindowInfo.Width = DISPLAY_WIDTH; - WindowInfo.Height = DISPLAY_HEIGHT; - WindowInfo.Focused = true; - WindowInfo.Exists = true; + Window_Main.Width = DISPLAY_WIDTH; + Window_Main.Height = DISPLAY_HEIGHT; + Window_Main.Focused = true; + Window_Main.Exists = true; Input.Sources = INPUT_SOURCE_GAMEPAD; sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG); diff --git a/src/Window_SDL.c b/src/Window_SDL.c index 7460ef51a..257ec0c36 100644 --- a/src/Window_SDL.c +++ b/src/Window_SDL.c @@ -12,7 +12,7 @@ static SDL_Window* win_handle; #error "Some features are missing from the SDL backend. If possible, it is recommended that you use a native windowing backend instead" static void RefreshWindowBounds(void) { - SDL_GetWindowSize(win_handle, &WindowInfo.Width, &WindowInfo.Height); + SDL_GetWindowSize(win_handle, &Window_Main.Width, &Window_Main.Height); } static void Window_SDLFail(const char* place) { @@ -49,8 +49,8 @@ static void DoCreateWindow(int width, int height, int flags) { if (!win_handle) Window_SDLFail("creating window"); RefreshWindowBounds(); - WindowInfo.Exists = true; - WindowInfo.Handle = win_handle; + Window_Main.Exists = true; + Window_Main.Handle = win_handle; /* TODO grab using SDL_SetWindowGrab? seems to be unnecessary on Linux at least */ } void Window_Create2D(int width, int height) { DoCreateWindow(width, height, 0); } @@ -217,11 +217,11 @@ static void OnWindowEvent(const SDL_Event* e) { Event_RaiseVoid(&WindowEvents.StateChanged); break; case SDL_WINDOWEVENT_FOCUS_GAINED: - WindowInfo.Focused = true; + Window_Main.Focused = true; Event_RaiseVoid(&WindowEvents.FocusChanged); break; case SDL_WINDOWEVENT_FOCUS_LOST: - WindowInfo.Focused = false; + Window_Main.Focused = false; Event_RaiseVoid(&WindowEvents.FocusChanged); break; case SDL_WINDOWEVENT_CLOSE: @@ -254,7 +254,7 @@ void Window_ProcessEvents(double delta) { OnWindowEvent(&e); break; case SDL_QUIT: - WindowInfo.Exists = false; + Window_Main.Exists = false; Event_RaiseVoid(&WindowEvents.Closing); SDL_DestroyWindow(win_handle); break; diff --git a/src/Window_Web.c b/src/Window_Web.c index 675185f6e..b7dfdf604 100644 --- a/src/Window_Web.c +++ b/src/Window_Web.c @@ -23,10 +23,10 @@ static int GetScreenHeight(void) { return RawDpiScale(interop_ScreenHeight()); } static void UpdateWindowBounds(void) { int width = interop_CanvasWidth(); int height = interop_CanvasHeight(); - if (width == WindowInfo.Width && height == WindowInfo.Height) return; + if (width == Window_Main.Width && height == Window_Main.Height) return; - WindowInfo.Width = width; - WindowInfo.Height = height; + Window_Main.Width = width; + Window_Main.Height = height; Event_RaiseVoid(&WindowEvents.Resized); } @@ -74,8 +74,8 @@ static void RescaleXY(int* x, int* y) { emscripten_get_element_css_size("#canvas", &css_width, &css_height); if (css_width && css_height) { - *x = (int)(*x * WindowInfo.Width / css_width ); - *y = (int)(*y * WindowInfo.Height / css_height); + *x = (int)(*x * Window_Main.Width / css_width ); + *y = (int)(*y * Window_Main.Height / css_height); } else { /* If css width or height is 0, something is bogus */ /* Better to avoid divsision by 0 in that case though */ @@ -105,8 +105,8 @@ static EM_BOOL OnTouchStart(int type, const EmscriptenTouchEvent* ev, void* data /* Because we return true to cancel default browser behaviour, sometimes we also */ /* end up preventing the default 'focus gained' behaviour from occurring */ /* So manually activate focus as a workaround */ - if (!WindowInfo.Focused) { - WindowInfo.Focused = true; + if (!Window_Main.Focused) { + Window_Main.Focused = true; Event_RaiseVoid(&WindowEvents.FocusChanged); } @@ -157,7 +157,7 @@ static EM_BOOL OnTouchEnd(int type, const EmscriptenTouchEvent* ev, void* data) } static EM_BOOL OnFocus(int type, const EmscriptenFocusEvent* ev, void* data) { - WindowInfo.Focused = type == EMSCRIPTEN_EVENT_FOCUS; + Window_Main.Focused = type == EMSCRIPTEN_EVENT_FOCUS; Event_RaiseVoid(&WindowEvents.FocusChanged); return true; } @@ -189,9 +189,9 @@ static const char* OnBeforeUnload(int type, const void* ev, void *data) { static EM_BOOL OnVisibilityChanged(int eventType, const EmscriptenVisibilityChangeEvent* ev, void* data) { cc_bool inactive = ev->visibilityState == EMSCRIPTEN_VISIBILITY_HIDDEN; - if (WindowInfo.Inactive == inactive) return false; + if (Window_Main.Inactive == inactive) return false; - WindowInfo.Inactive = inactive; + Window_Main.Inactive = inactive; Event_RaiseVoid(&WindowEvents.InactiveChanged); return false; } @@ -387,7 +387,7 @@ void Window_Init(void) { /* as the chat/send butons are positioned at the top of the canvas - they */ /* get pushed offscreen and can't be used at all anymore. So handle this */ /* case specially by positioning them at the bottom instead for iOS. */ - WindowInfo.SoftKeyboard = is_ios ? SOFT_KEYBOARD_SHIFT : SOFT_KEYBOARD_RESIZE; + Window_Main.SoftKeyboard = is_ios ? SOFT_KEYBOARD_SHIFT : SOFT_KEYBOARD_RESIZE; /* Let the webpage know it needs to force a mobile layout */ if (!Input_TouchMode) return; @@ -398,12 +398,12 @@ void Window_Free(void) { } extern void interop_InitContainer(void); static void DoCreateWindow(void) { - WindowInfo.Exists = true; - WindowInfo.Focused = true; + Window_Main.Exists = true; + Window_Main.Focused = true; HookEvents(); /* Let the webpage decide on initial bounds */ - WindowInfo.Width = interop_CanvasWidth(); - WindowInfo.Height = interop_CanvasHeight(); + Window_Main.Width = interop_CanvasWidth(); + Window_Main.Height = interop_CanvasHeight(); interop_InitContainer(); } void Window_Create2D(int width, int height) { DoCreateWindow(); } @@ -501,7 +501,7 @@ void Window_SetSize(int width, int height) { } void Window_RequestClose(void) { - WindowInfo.Exists = false; + Window_Main.Exists = false; Event_RaiseVoid(&WindowEvents.Closing); /* If the game is closed while in fullscreen, the last rendered frame stays */ /* shown in fullscreen, but the game can't be interacted with anymore */ @@ -516,7 +516,7 @@ void Window_RequestClose(void) { extern void interop_RequestCanvasResize(void); static void ProcessPendingResize(void) { - if (!WindowInfo.Exists) return; + if (!Window_Main.Exists) return; if (Window_GetWindowState() == WINDOW_STATE_FULLSCREEN) { SetFullscreenBounds(); diff --git a/src/Window_Win.c b/src/Window_Win.c index 499758f78..06e8797bd 100644 --- a/src/Window_Win.c +++ b/src/Window_Win.c @@ -92,8 +92,8 @@ static void RefreshWindowBounds(void) { win_totalHeight = Rect_Height(rect); GetClientRect(win_handle, &rect); - WindowInfo.Width = Rect_Width(rect); - WindowInfo.Height = Rect_Height(rect); + Window_Main.Width = Rect_Width(rect); + Window_Main.Height = Rect_Height(rect); /* GetClientRect always returns 0,0 for left,top (see MSDN) */ ClientToScreen(win_handle, &topLeft); @@ -113,7 +113,7 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara switch (message) { case WM_ACTIVATE: - WindowInfo.Focused = LOWORD(wParam) != 0; + Window_Main.Focused = LOWORD(wParam) != 0; Event_RaiseVoid(&WindowEvents.FocusChanged); break; @@ -256,12 +256,12 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara case WM_CLOSE: Event_RaiseVoid(&WindowEvents.Closing); - if (WindowInfo.Exists) DestroyWindow(win_handle); - WindowInfo.Exists = false; + if (Window_Main.Exists) DestroyWindow(win_handle); + Window_Main.Exists = false; break; case WM_DESTROY: - WindowInfo.Exists = false; + Window_Main.Exists = false; UnregisterClassW(CC_WIN_CLASSNAME, win_instance); if (win_DC) ReleaseDC(win_handle, win_DC); @@ -365,8 +365,8 @@ static void DoCreateWindow(int width, int height) { win_DC = GetDC(win_handle); if (!win_DC) Logger_Abort2(GetLastError(), "Failed to get device context"); - WindowInfo.Exists = true; - WindowInfo.Handle = win_handle; + Window_Main.Exists = true; + Window_Main.Handle = win_handle; grabCursor = Options_GetBool(OPT_GRAB_CURSOR, false); } void Window_Create2D(int width, int height) { DoCreateWindow(width, height); } @@ -529,7 +529,7 @@ void Window_ProcessEvents(double delta) { foreground = GetForegroundWindow(); if (foreground) { - WindowInfo.Focused = foreground == win_handle; + Window_Main.Focused = foreground == win_handle; } } diff --git a/src/Window_X11.c b/src/Window_X11.c index f57dea3e0..86a94c77d 100644 --- a/src/Window_X11.c +++ b/src/Window_X11.c @@ -193,9 +193,9 @@ static void RegisterAtoms(void) { } static void RefreshWindowBounds(int width, int height) { - if (width != WindowInfo.Width || height != WindowInfo.Height) { - WindowInfo.Width = width; - WindowInfo.Height = height; + if (width != Window_Main.Width || height != Window_Main.Height) { + Window_Main.Width = width; + Window_Main.Height = height; Event_RaiseVoid(&WindowEvents.Resized); } } @@ -332,8 +332,8 @@ static void DoCreateWindow(int width, int height) { XkbSetDetectableAutoRepeat(win_display, true, &supported); RefreshWindowBounds(width, height); - WindowInfo.Exists = true; - WindowInfo.Handle = (void*)win_handle; + Window_Main.Exists = true; + Window_Main.Handle = (void*)win_handle; grabCursor = Options_GetBool(OPT_GRAB_CURSOR, false); /* So right name appears in e.g. Ubuntu Unity launchbar */ @@ -345,7 +345,7 @@ static void DoCreateWindow(int width, int height) { /* Check for focus initially, in case WM doesn't send a FocusIn event */ XGetInputFocus(win_display, &focus, &focusRevert); - if (focus == win_handle) WindowInfo.Focused = true; + if (focus == win_handle) Window_Main.Focused = true; } void Window_Create2D(int width, int height) { DoCreateWindow(width, height); } void Window_Create3D(int width, int height) { DoCreateWindow(width, height); } @@ -508,7 +508,7 @@ static void HandleWMDestroy(void) { /* sync and discard all events queued */ XSync(win_display, true); XDestroyWindow(win_display, win_handle); - WindowInfo.Exists = false; + Window_Main.Exists = false; } static void HandleWMPing(XEvent* e) { @@ -524,7 +524,7 @@ void Window_ProcessEvents(double delta) { int focusRevert; int i, btn, key, status; - while (WindowInfo.Exists) { + while (Window_Main.Exists) { if (!XCheckIfEvent(win_display, &e, FilterEvent, (XPointer)win_handle)) break; if (XFilterEvent(&e, None) == True) continue; @@ -541,7 +541,7 @@ void Window_ProcessEvents(double delta) { case DestroyNotify: Platform_LogConst("Window destroyed"); - WindowInfo.Exists = false; + Window_Main.Exists = false; break; case ConfigureNotify: @@ -555,14 +555,14 @@ void Window_ProcessEvents(double delta) { case LeaveNotify: XGetInputFocus(win_display, &focus, &focusRevert); if (focus == PointerRoot) { - WindowInfo.Focused = false; Event_RaiseVoid(&WindowEvents.FocusChanged); + Window_Main.Focused = false; Event_RaiseVoid(&WindowEvents.FocusChanged); } break; case EnterNotify: XGetInputFocus(win_display, &focus, &focusRevert); if (focus == PointerRoot) { - WindowInfo.Focused = true; Event_RaiseVoid(&WindowEvents.FocusChanged); + Window_Main.Focused = true; Event_RaiseVoid(&WindowEvents.FocusChanged); } break; @@ -621,10 +621,10 @@ void Window_ProcessEvents(double delta) { /* Don't lose focus when another app grabs key or mouse */ if (e.xfocus.mode == NotifyGrab || e.xfocus.mode == NotifyUngrab) break; - WindowInfo.Focused = e.type == FocusIn; + Window_Main.Focused = e.type == FocusIn; Event_RaiseVoid(&WindowEvents.FocusChanged); /* TODO: Keep track of keyboard when focus is lost */ - if (!WindowInfo.Focused) Input_Clear(); + if (!Window_Main.Focused) Input_Clear(); break; case MappingNotify: diff --git a/src/Window_Xbox.c b/src/Window_Xbox.c index c22061ce4..234cdaf26 100644 --- a/src/Window_Xbox.c +++ b/src/Window_Xbox.c @@ -19,7 +19,7 @@ static xid_dev_t* xid_ctrl; static xid_gamepad_in gp_state; struct _DisplayData DisplayInfo; -struct _WinData WindowInfo; +struct _WindowData WindowInfo; // TODO No idea if this even works static void OnDataReceived(UTR_T* utr) { @@ -66,10 +66,10 @@ void Window_Init(void) { DisplayInfo.ScaleX = 1; DisplayInfo.ScaleY = 1; - WindowInfo.Width = mode.width; - WindowInfo.Height = mode.height; - WindowInfo.Focused = true; - WindowInfo.Exists = true; + Window_Main.Width = mode.width; + Window_Main.Height = mode.height; + Window_Main.Focused = true; + Window_Main.Exists = true; Input.Sources = INPUT_SOURCE_GAMEPAD; DisplayInfo.ContentOffsetX = 10; diff --git a/src/Window_Xbox360.c b/src/Window_Xbox360.c index 09321f0ae..5cd4c6d47 100644 --- a/src/Window_Xbox360.c +++ b/src/Window_Xbox360.c @@ -17,7 +17,7 @@ static cc_bool launcherMode; struct _DisplayData DisplayInfo; -struct _WinData WindowInfo; +struct _WindowData WindowInfo; // https://github.com/Free60Project/libxenon/blob/71a411cddfc26c9ccade08d054d87180c359797a/libxenon/drivers/console/console.c#L47 struct ati_info { @@ -37,10 +37,10 @@ void Window_Init(void) { DisplayInfo.ScaleX = 1; DisplayInfo.ScaleY = 1; - WindowInfo.Width = ai->width; - WindowInfo.Height = ai->height; - WindowInfo.Focused = true; - WindowInfo.Exists = true; + Window_Main.Width = ai->width; + Window_Main.Height = ai->height; + Window_Main.Focused = true; + Window_Main.Exists = true; Input.Sources = INPUT_SOURCE_GAMEPAD; diff --git a/src/_WindowBase.h b/src/_WindowBase.h index 0d2306c8a..f5f56c45b 100644 --- a/src/_WindowBase.h +++ b/src/_WindowBase.h @@ -5,7 +5,7 @@ #include "Platform.h" struct _DisplayData DisplayInfo; -struct _WinData WindowInfo; +struct _WindowData WindowInfo; #define Display_CentreX(width) (DisplayInfo.x + (DisplayInfo.Width - width) / 2) #define Display_CentreY(height) (DisplayInfo.y + (DisplayInfo.Height - height) / 2) @@ -27,13 +27,13 @@ static void Cursor_SetVisible(cc_bool visible) { } static void CentreMousePosition(void) { - Cursor_SetPosition(WindowInfo.Width / 2, WindowInfo.Height / 2); + Cursor_SetPosition(Window_Main.Width / 2, Window_Main.Height / 2); /* Fixes issues with large DPI displays on Windows >= 8.0. */ Cursor_GetRawPos(&cursorPrevX, &cursorPrevY); } static void RegrabMouse(void) { - if (!WindowInfo.Focused || !WindowInfo.Exists) return; + if (!Window_Main.Focused || !Window_Main.Exists) return; CentreMousePosition(); } @@ -108,7 +108,7 @@ static EGLConfig ctx_config; static EGLint ctx_numConfig; static void GLContext_InitSurface(void) { - void* window = WindowInfo.Handle; + void* window = Window_Main.Handle; if (!window) return; /* window not created or lost */ ctx_surface = eglCreateWindowSurface(ctx_display, ctx_config, window, NULL); diff --git a/src/interop_BeOS.cpp b/src/interop_BeOS.cpp index 0985096b8..0f98abbb9 100644 --- a/src/interop_BeOS.cpp +++ b/src/interop_BeOS.cpp @@ -404,12 +404,12 @@ static void DoCreateWindow(int width, int height) { BRect frame(x, y, x + width - 1, y + height - 1); win_handle = new CC_BWindow(frame); - WindowInfo.Exists = true; - WindowInfo.Handle = win_handle; + Window_Main.Exists = true; + Window_Main.Handle = win_handle; frame = win_handle->Bounds(); - WindowInfo.Width = frame.IntegerWidth() + 1; - WindowInfo.Height = frame.IntegerHeight() + 1; + Window_Main.Width = frame.IntegerWidth() + 1; + Window_Main.Height = frame.IntegerHeight() + 1; } void Window_Create2D(int width, int height) { @@ -574,19 +574,19 @@ void Window_ProcessEvents(double delta) { Event_RaiseInt(&InputEvents.Press, event.v1.i32); break; case CC_WIN_RESIZED: - WindowInfo.Width = event.v1.i32; - WindowInfo.Height = event.v2.i32; + Window_Main.Width = event.v1.i32; + Window_Main.Height = event.v2.i32; Event_RaiseVoid(&WindowEvents.Resized); break; case CC_WIN_FOCUS: - WindowInfo.Focused = event.v1.i32; + Window_Main.Focused = event.v1.i32; Event_RaiseVoid(&WindowEvents.FocusChanged); break; case CC_WIN_REDRAW: Event_RaiseVoid(&WindowEvents.RedrawNeeded); break; case CC_WIN_QUIT: - WindowInfo.Exists = false; + Window_Main.Exists = false; Event_RaiseVoid(&WindowEvents.Closing); break; } diff --git a/src/interop_cocoa.m b/src/interop_cocoa.m index 1bde3e049..419cbacac 100644 --- a/src/interop_cocoa.m +++ b/src/interop_cocoa.m @@ -90,7 +90,7 @@ static cc_bool GetMouseCoords(int* x, int* y) { *x = (int)loc.x - windowX; *y = (DisplayInfo.Height - (int)loc.y) - windowY; // TODO: this seems to be off by 1 - return *x >= 0 && *y >= 0 && *x < WindowInfo.Width && *y < WindowInfo.Height; + return *x >= 0 && *y >= 0 && *x < Window_Main.Width && *y < Window_Main.Height; } static void ProcessRawMouseMovement(NSEvent* ev) { @@ -223,8 +223,8 @@ static void RefreshWindowBounds(void) { windowY = (int)rect.origin.y; // usually 0 // TODO is it correct to use display bounds and not just 0? - WindowInfo.Width = (int)rect.size.width; - WindowInfo.Height = (int)rect.size.height; + Window_Main.Width = (int)rect.size.width; + Window_Main.Height = (int)rect.size.height; return; } @@ -241,8 +241,8 @@ static void RefreshWindowBounds(void) { windowX = (int)win.origin.x + (int)view.origin.x; windowY = DisplayInfo.Height - ((int)win.origin.y + (int)win.size.height) + viewY; - WindowInfo.Width = (int)view.size.width; - WindowInfo.Height = (int)view.size.height; + Window_Main.Width = (int)view.size.width; + Window_Main.Height = (int)view.size.height; } @interface CCWindow : NSWindow { } @@ -266,12 +266,12 @@ static void RefreshWindowBounds(void) { } - (void)windowDidBecomeKey:(NSNotification *)notification { - WindowInfo.Focused = true; + Window_Main.Focused = true; Event_RaiseVoid(&WindowEvents.FocusChanged); } - (void)windowDidResignKey:(NSNotification *)notification { - WindowInfo.Focused = false; + Window_Main.Focused = false; Event_RaiseVoid(&WindowEvents.FocusChanged); } @@ -284,7 +284,7 @@ static void RefreshWindowBounds(void) { } - (void)windowWillClose:(NSNotification *)notification { - WindowInfo.Exists = false; + Window_Main.Exists = false; Event_RaiseVoid(&WindowEvents.Closing); } @end @@ -366,8 +366,8 @@ static void DoCreateWindow(int width, int height) { [winHandle setAcceptsMouseMovedEvents:YES]; Window_CommonCreate(); - WindowInfo.Exists = true; - WindowInfo.Handle = winHandle; + Window_Main.Exists = true; + Window_Main.Handle = winHandle; // CGAssociateMouseAndMouseCursorPosition implicitly grabs cursor del = [CCWindowDelegate alloc]; @@ -427,9 +427,9 @@ void Window_SetSize(int width, int height) { // Can't use setContentSize:, because that resizes from the bottom left corner NSRect rect = [winHandle frame]; - rect.origin.y += WindowInfo.Height - height; - rect.size.width += width - WindowInfo.Width; - rect.size.height += height - WindowInfo.Height; + rect.origin.y += Window_Main.Height - height; + rect.size.width += width - Window_Main.Width; + rect.size.height += height - Window_Main.Height; [winHandle setFrame:rect display:YES]; } @@ -692,8 +692,8 @@ static void DoDrawFramebuffer(NSRect dirty) { // TODO: Only update changed bit.. rect.origin.x = 0; rect.origin.y = 0; - rect.size.width = WindowInfo.Width; - rect.size.height = WindowInfo.Height; + rect.size.width = Window_Main.Width; + rect.size.height = Window_Main.Height; // TODO: REPLACE THIS AWFUL HACK provider = CGDataProviderCreateWithData(NULL, fb_bmp.scan0, @@ -712,7 +712,7 @@ static void DoDrawFramebuffer(NSRect dirty) { void Window_DrawFramebuffer(Rect2D r) { NSRect rect; rect.origin.x = r.x; - rect.origin.y = WindowInfo.Height - r.y - r.Height; + rect.origin.y = Window_Main.Height - r.y - r.Height; rect.size.width = r.Width; rect.size.height = r.Height; diff --git a/src/interop_ios.m b/src/interop_ios.m index c2de2bf0e..c94410cb9 100644 --- a/src/interop_ios.m +++ b/src/interop_ios.m @@ -118,8 +118,8 @@ static CGRect GetViewFrame(void) { - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { // viewWillTransitionToSize:withTransitionCoordinator - iOS 8.0 - WindowInfo.Width = size.width; - WindowInfo.Height = size.height; + Window_Main.Width = size.width; + Window_Main.Height = size.height; Event_RaiseVoid(&WindowEvents.Resized); [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; @@ -239,7 +239,7 @@ static UITextField* kb_widget; // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. Platform_LogConst("INACTIVE"); - WindowInfo.Focused = false; + Window_Main.Focused = false; Event_RaiseVoid(&WindowEvents.FocusChanged); } @@ -260,7 +260,7 @@ static UITextField* kb_widget; // applicationDidBecomeActive - iOS 2.0 // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. Platform_LogConst("ACTIVE"); - WindowInfo.Focused = true; + Window_Main.Focused = true; Event_RaiseVoid(&WindowEvents.FocusChanged); } @@ -371,9 +371,9 @@ void Window_SetTitle(const cc_string* title) { } void Window_Init(void) { - //WindowInfo.SoftKeyboard = SOFT_KEYBOARD_RESIZE; + //Window_Main.SoftKeyboard = SOFT_KEYBOARD_RESIZE; // keyboard now shifts up - WindowInfo.SoftKeyboard = SOFT_KEYBOARD_SHIFT; + Window_Main.SoftKeyboard = SOFT_KEYBOARD_SHIFT; Input_SetTouchMode(true); Input.Sources = INPUT_SOURCE_NORMAL; @@ -399,9 +399,9 @@ static CGRect DoCreateWindow(void) { win_handle.rootViewController = cc_controller; win_handle.backgroundColor = CalcBackgroundColor(); - WindowInfo.Exists = true; - WindowInfo.Width = bounds.size.width; - WindowInfo.Height = bounds.size.height; + Window_Main.Exists = true; + Window_Main.Width = bounds.size.width; + Window_Main.Height = bounds.size.height; NSNotificationCenter* notifications = NSNotificationCenter.defaultCenter; [notifications addObserver:cc_controller selector:@selector(keyboardDidShow:) name:UIKeyboardWillShowNotification object:nil]; @@ -415,7 +415,7 @@ void Window_Show(void) { } void Window_RequestClose(void) { - WindowInfo.Exists = false; + Window_Main.Exists = false; Event_RaiseVoid(&WindowEvents.Closing); } @@ -670,15 +670,15 @@ static void CreateFramebuffer(void) { glGenRenderbuffers(1, &depth_renderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, depth_renderbuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, WindowInfo.Width, WindowInfo.Height); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, Window_Main.Width, Window_Main.Height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_renderbuffer); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) Logger_Abort2(status, "Failed to create renderbuffer"); - fb_width = WindowInfo.Width; - fb_height = WindowInfo.Height; + fb_width = Window_Main.Width; + fb_height = Window_Main.Height; } void GLContext_Create(void) { @@ -698,15 +698,15 @@ static void GLContext_OnLayout(void) { CAEAGLLayer* layer = (CAEAGLLayer*)view_handle.layer; // only resize buffers when absolutely have to - if (fb_width == WindowInfo.Width && fb_height == WindowInfo.Height) return; - fb_width = WindowInfo.Width; - fb_height = WindowInfo.Height; + if (fb_width == Window_Main.Width && fb_height == Window_Main.Height) return; + fb_width = Window_Main.Width; + fb_height = Window_Main.Height; glBindRenderbuffer(GL_RENDERBUFFER, color_renderbuffer); [ctx_handle renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; glBindRenderbuffer(GL_RENDERBUFFER, depth_renderbuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, WindowInfo.Width, WindowInfo.Height); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, Window_Main.Width, Window_Main.Height); } void GLContext_Free(void) { @@ -1295,8 +1295,8 @@ void LBackend_FreeFramebuffer(void) { } void LBackend_Redraw(void) { struct Context2D ctx; struct Bitmap bmp; - bmp.width = max(WindowInfo.Width, 1); - bmp.height = max(WindowInfo.Height, 1); + bmp.width = max(Window_Main.Width, 1); + bmp.height = max(Window_Main.Height, 1); bmp.scan0 = (BitmapCol*)Mem_Alloc(bmp.width * bmp.height, 4, "window pixels"); Context2D_Wrap(&ctx, &bmp); @@ -1640,10 +1640,10 @@ static void LBackend_LayoutDimensions(struct LWidget* w, CGRect* r) { switch (l->type) { case LLAYOUT_WIDTH: - r->size.width = WindowInfo.Width - (int)r->origin.x - Display_ScaleX(l->offset); + r->size.width = Window_Main.Width - (int)r->origin.x - Display_ScaleX(l->offset); break; case LLAYOUT_HEIGHT: - r->size.height = WindowInfo.Height - (int)r->origin.y - Display_ScaleY(l->offset); + r->size.height = Window_Main.Height - (int)r->origin.y - Display_ScaleY(l->offset); break; } l++; @@ -1657,8 +1657,8 @@ void LBackend_LayoutWidget(struct LWidget* w) { int width = (int)r.size.width; int height = (int)r.size.height; - r.origin.x = Gui_CalcPos(l[0].type & 0xFF, Display_ScaleX(l[0].offset), width, WindowInfo.Width); - r.origin.y = Gui_CalcPos(l[1].type & 0xFF, Display_ScaleY(l[1].offset), height, WindowInfo.Height); + r.origin.x = Gui_CalcPos(l[0].type & 0xFF, Display_ScaleX(l[0].offset), width, Window_Main.Width); + r.origin.y = Gui_CalcPos(l[1].type & 0xFF, Display_ScaleY(l[1].offset), height, Window_Main.Height); // e.g. Table widget needs adjusts width/height based on window if (l[1].type & LLAYOUT_EXTRA) From 3dd9b32f2284b6949b628abcab0696e95dd4ce7a Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 20 Jan 2024 22:23:16 +1100 Subject: [PATCH 7/9] N64: Change movement keys to c buttons, change mipmaps grahics option to filtering option --- src/Graphics_N64.c | 4 ++-- src/Menus.c | 5 +++++ src/Window_3DS.c | 4 ++-- src/Window_N64.c | 4 ++++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Graphics_N64.c b/src/Graphics_N64.c index 2c165205f..8aee1d829 100644 --- a/src/Graphics_N64.c +++ b/src/Graphics_N64.c @@ -139,8 +139,8 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_boo glGenTextures(1, &tex->textureID); glBindTexture(GL_TEXTURE_2D, tex->textureID); // NOTE: Enabling these fixes textures, but seems to break on cen64 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmaps ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mipmaps ? GL_LINEAR : GL_NEAREST); tex->surface = surface_alloc(bit16 ? FMT_RGBA16 : FMT_RGBA32, bmp->width, bmp->height); surface_t* fb = &tex->surface; diff --git a/src/Menus.c b/src/Menus.c index 609a9bd6d..f8e3dbe5b 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -2941,8 +2941,13 @@ static void GraphicsOptionsScreen_InitWidgets(struct MenuOptionsScreen* s) { GraphicsOptionsScreen_GetNames, GraphicsOptionsScreen_SetNames }, { 1, 0, "Shadows", MenuOptionsScreen_Enum, GraphicsOptionsScreen_GetShadows, GraphicsOptionsScreen_SetShadows }, +#ifdef CC_BUILD_N64 + { 1, 50, "Filtering", MenuOptionsScreen_Bool, + GraphicsOptionsScreen_GetMipmaps, GraphicsOptionsScreen_SetMipmaps } +#else { 1, 50, "Mipmaps", MenuOptionsScreen_Bool, GraphicsOptionsScreen_GetMipmaps, GraphicsOptionsScreen_SetMipmaps } +#endif }; s->numCore = 8; diff --git a/src/Window_3DS.c b/src/Window_3DS.c index 3644b6782..e4d8b8ae5 100644 --- a/src/Window_3DS.c +++ b/src/Window_3DS.c @@ -40,8 +40,8 @@ void Window_Init(void) { DisplayInfo.Width = height; // deliberately swapped DisplayInfo.Height = width; // deliberately swapped DisplayInfo.Depth = 4; // 32 bit - DisplayInfo.ScaleX = 0.5; - DisplayInfo.ScaleY = 0.5; + DisplayInfo.ScaleX = 0.5f; + DisplayInfo.ScaleY = 0.5f; Window_Main.Width = height; // deliberately swapped Window_Main.Height = width; // deliberately swapped diff --git a/src/Window_N64.c b/src/Window_N64.c index b69a7f483..05dfa329d 100644 --- a/src/Window_N64.c +++ b/src/Window_N64.c @@ -40,6 +40,10 @@ void Window_Init(void) { // change defaults to make more sense for N64 cc_uint8* binds = (cc_uint8*)KeyBind_GamepadDefaults; binds[KEYBIND_INVENTORY] = CCPAD_Z; + binds[KEYBIND_FORWARD] = CCPAD_CUP; + binds[KEYBIND_BACK] = CCPAD_CDOWN; + binds[KEYBIND_LEFT] = CCPAD_CLEFT; + binds[KEYBIND_RIGHT] = CCPAD_CRIGHT; } void Window_Free(void) { } From cc35e79766c4f05c24014acdc4c79447d0d9b5ab Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 21 Jan 2024 18:41:13 +1100 Subject: [PATCH 8/9] N64: Change controls, default to flatgrass, add more blocks in default textures Also switch to dynamically allocating memory for vorbis decoder when converting .ogg sounds to .wav --- misc/n64/default.zip | Bin 12022 -> 24104 bytes src/Resources.c | 13 +++++++++---- src/Server.c | 6 ++++++ src/Window_N64.c | 6 +++++- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/misc/n64/default.zip b/misc/n64/default.zip index ca55af9bab9611e4c3cf033a31b38f68a2678497..73447f64750388397b0c0280d7b67add2b46456b 100644 GIT binary patch literal 24104 zcmV(rK<>X#O9KQH000080QrzLSe-bH%#2+C0RCP801E&B0CZ(?a$#w1E^uyVBv=PD z+|Aeit!4F|S7((Vq7yY(iJA~ZM6V%w?{%$C^hk78l!)j=Z>t1}-ifk$iQdavzWmQO z=ggd$GxeOg&%MucW3)6>NQoGT001C;p{l420HA+e06_rx*RIz!{BHu+=Gm)f08pI} zh?Z~AT6fho;Vya}3PH+AQOeXrInk^rP zQb{qBT~(_GF{brUSFxJnfld|vLxM-bbV@pWF3Quf6=kiLCnuP-GMD|@%O=cT+lV18 z@Ud7hEe)auO8QNG6eg3sLz(>Aa}Pj(Sj-VTfV!@7vsqOD0mZL@p@>{IcN{ZZ(2>7> zD~{{Ls3<}M{~lRruoD=voeofD)k@LxQPM_Ba;hZ>)Q@~fXGr6-rsK43fAoxUAV$g} znN$wLS5uHaS0Ym%{Zp#A_RZY8ga3}})!9^fqAR0`MVqquDA82a${&P2^R7y)&gzhf zf`JDw9BEzkW7x$hg=3&p>+Gu=z_Kc#ncIRM-?9~PPn!D+wUHGMYAQTW=2U^j$v>IT zF4wJ!Tyb%_0WRK*Up5maYs5XrTQmz^*^3G5f#CH*ShyQb$Pik zujEgE)nr3aejmGEc{|Pkm=DI-*Ph1mR}dkF`GNjL%)1Fm08#kOg?Xlm+Q%66NFatDbgqb5?v>J}dm0u_wB{G6})i){);4Vao& zkWp7q{5vle$g^x;GGsTkQh3bQxB)eax~#rUqDDIz>9k8^<`sGOUE$9rnwaq`N-fJc z#H80_dH6p5BO*%HG0abs`vRBtDg;7ut>Vj!haZ3>7HS#R8xJ1u{X9+J5 z_FDK1&qQtU`krx1;thwXEi*KNoWn5Y57ZGh<}|GkVhUUfHW9^;b+-RhsmG%RSs_;B zP0!l3C>{|0d`?I~PW9Yx)cPCUfP1u3n2vs0U$YG+*n#WPmm2#lOoirS$Lq3VimU@qXE&O2@*K^J< zpIwuW5Jw+XAAYASj|ou}aO0@{=o{yoA*mdw_K|HT*;sY#A)6ik4#f`Bj=&CQhWa%7 z(~kxHI45N8qSrXrl-KdNN?od5YN7nq&+?V?72c_?Ha#@eelz~Uz0Rt_Dq@}R*X~DA zZC@UK9$KESll~!j?N{V4>w)S1+*IZwwkQ0VwEPje zFP~~Ker+?#|IuSdX!GlWvs^7Qb#Q?Hv&W~k{{Mc}{aQ>7;MPp@NzqJ2bE0|fwLnFA z#T4I?imJ?3^1BAL|7y<{l@%$eB?`6`6Y&1!f$&tkmH9SXDOp@tw*KW)g-(&@Gdtys zuY2FJ3ymuRmHiAO^50c8kYpd zwi{;sQSb_tR**GqGj3A}(p6CE*5uGEP+H67GEMoC@vTX(R@1{&&4}07p;Whc`cr*& zeVTWLckBh2xh5fOm>~y}W7JG%66suXAh*cqUzHnSnr|AvC^3G2zV94Lduk!TZob4JH zql1yTm^$6Scw;)@OYjyfOWCM#r_tCB`EA>+4+cguN~TYJWXZ}U#9GC5^diYl%T&uu zh*Og5O7&=$Vk>Dp3G+qzOV?+l1XjhLTb<%8IirDb9Xs-6;-Cxvja?%j%Z!p?&n9BOe`lwYsQCD?iChvS!NL zVNrZi{GdK$e{;UHKA7(vtqH$4PsJm+S=ZyHoA@1x&*;EElpU6NlQo|A8iN{3!z(6a zEo5mg(l%1#4=?5yUuy^oJ`S$qwjTNX;r)MJ0fYe&0V=#fye;3KeD~IEtJElKH(4{D z&@I((Y4e6d1JI-JK5V(yORt|^hh(ng3niD|4sA#6zez?*rTZPdu++CiH^jMQWj)CJ zkR`{o%FH0kNlDCt`p6)$;J#Nc` z#ou|a;@$r&Myr|r?vOdNpDWF6LNuvVzA+OVq-{$M_PF9-b3(Tq`J@mV99AFl!nWbt zciX4OoyC)y$U8i6`su9;*TO$q2@txf8h8Kz+1LM7P}D++3jpXyy-<9n<7>K~Lzr%? z=e4Ez_7L-Z`p+LuwR%Ut6p6S7Q0**TEnXKH;X}}7)U8NSlBD?X5CDuz z0Kw@*IJq9R8>QB%@t0f{`5*p0_*)^>f%&V0hJR0e`<9(-8@qqH7;w;5X=q|{U%QAg z{V50UJKtGqx8FG|NoA%b=|A8$d_VW$1!!QND~E-}hCgV=yCUtRMubODFy+GscL|uR z?3!U1OiomEcN*u$eOqn^nvwFJl(VL$NWB@~OTBXzkCFHNTaOr-K-MN((kibv4W9;X zyzHd@P(IzK(ZBB&1X{QQLEL~F0Gr+wXr=!JiN7rRtV-?Vxu_XvD{`G#s@=Q!ijWNKP-lfTo` zs1)t{4-Nexf>!{fF*Ei1 z_r|N6CbeHJ_ghX;mHnK`19v25 zZVi?B3EcY0$Kn^19XVjq4njC6k_h^cKbiKIAtWgaJ-xlXTvmbaw5`u*Pqy5Xk#d$v z9S*hvrSqBGWZbp8Bu%Q$&1_{x!GXT|gtGhL?K@33T#=d04D?KNA6GgpxEFI|6K1)# z#p`WG;8MQZw%!$`Ei-LCMiNd*{Ev74=nZ_|aH7v-Ky-WeQC~D7q2kexKZe~tiX;$3w7>@Latwp;F0{ykY{2C8^+>x^`hjVC$$Mu zap9VQ957eKk)*|F%|desxa7^rRZlOSaZS;<$p~F8R46LpSzevPDBJPK!G{*FzJ#8d zhs7>OTjlQuNtB!{3;eGlBtEsrRAPeSLK91@L^wKqweMXC{NGtkp7Wk3LXu0*{0nu< zTm3G_#)P>Qx;f??D9$RD!x!o0|~jxMa>Ueu)2x ze`sjP-O*QhU zscWu#?WKG%g`ZqX+@$$c?;JXGmVT(`mQt=OYA@#Je-*hh_zLbFEkEy^-KfMMPB)cZ zk$ETyqLn6WR6^q=t_xY`X;bcxwUXk?QgNghJFjk8l1046NB>vvH~nvbw%4T0r;yFx z_Xi3!C9+4`-8Z|(^_vAzZk~aL(=)o+lQ$kVRKd;MK14?$4U0+6_7y4NU+oku*G^{4 zf>^hjZ5TW5W>nf)#BnHEn@c*+yX_E2c0{o6tJ4=eK%t8hSvCtDU8c|eesB_7bkuA> zhyR;D{Ulvh4LU&jrI{67D+3_;-|;I6$pW`Mix~-ROWZ(aj^#v4Rs?-)i|)@_tFQ4c z<*C=$lwwC=oS}O;9up4glM0Cg_ez_iQ*3U9oI&;Xq4Tuw;K@DT@^)@;v6ArwX)4Z- zO4AH_DeNx&Q_uDELg-z4nL+(BnM(1K#c|xGiW=kJ6@d|P@YB`rz_mGdg$3=T)r;XY{+v*l5j z8kk%o9OX}fw{4J{`rnNKVzQLMUc(+VhPz8Y-&DVJ?$RpWPuq^xu>>@Em`3)V6-5;%Xmk#GxulXMd*n>NbFF-0RU z2YJEz7DDANUb|WMS!E_I(>n@l&-#~)TO{kP7kYF5ZjW{-46p}X6m;;nHMEXJY|uqm z*Nr6Ik$X=IjCZQ(O-swRw$ou{H8;h94ooxerjJP@M=IS5RUenC#HFcI6rbg{E@%QX;2zr2mYp0P zkJZP^9)8V;+aE1kqOV;7<%J;qf;gf#a*=Of!yC%_@E<9g@fY@kE!N(tl`zXqhk@hwJNl0jmKs^ZH6paaP(o1}0l_3j;R*L+ZW zRKpV#lDrr{=}#Q^6f!S%H1p@yb`$yfQGLhJ{`fp}F9|^RM+67sUO7BkuLdL7K+4_- zwj)gYYoHLQt9v^a2)()vmfV6elM=-snx82sgz*`*8KP4V{b+0#`uBN5tG0cXp>Z&_ z*?X?))V=BSDLN^wb*F)8rCjr&>+&*u=k^MJp>DZ2XwBWpsC?l3DOVWU#>8u`Ru^pR zT;cKBSWXN$y$i=8xu(nA3}^96?m_Yt#>sMm z@v&b$s?(BzSf7UX902h>+tb260{zG4PLeqKI^ZKCQQTq%FuzKLyVLYQ>3bYsUj>2H z+5|CCP4vDehj-&_U%ICMa?0$X(L;+8g{wNgAi(;OK(njgbchV27#1LLO*cg`Cy8`mL7o-R%8(#t>)DK0EGYqOCB@l1BzFhC|xjX(O7Sad1 z(dg@r&N2Z zM!&W=yYNg+Qq&3D9I`C9F*ec8Vh-HElTx$fk`i)$(_KM;b#^KJ-;)12S7M0IMsM8D zl3&I%Xsa=R8c4TOpjWQ}%V|St^WDbC(O@kPgK+>TiNB>lbHfl<(Gm9)qUx^wgh#V+ zV>P`58fb2rW_p~kWVAM+DcW=fCArSM0GnzLu8<-DAx8HOIk+`EZ5mEzF%7jKZ#iIv z33$G87A}$%J0^?o`MJpRfMQ$E^5fY&&pA8VSaw9dnpf?KXR0HreKW1 z>ZdDIB)S*}Re^w@dmBUqfjL{lWnUTT2uS0+I*4|uO93Y_$Mae?m$AAQSU*aoaW!e5 z`B$18$jJs@M%|gpuAL?;ew4c~Va4C#?9gc;_z^8YECApjgKge1>23Vz8mU`lO%;Ijv>mRU6SVf&twC_~= ztH7&P&Ff^Yo50*y#+nvD`NCKX2wuQH<>^jU2je-2Qy%)dE1!mPU;%!)T`k7-7GpVKcjX4WBW*y6;Ueyk2cSe!~E$fx1j{kI>N56z(zO8runAUC)Rzm#0WLvx3~s*3&J4NdmHoIlzWL_&zk~JJI0z1~2e5alaG~c?;(Bx66l~~hTkh)Mkwbiy_zm>HpKRG{q=OIZ!kC-d z*}*svdu8#XwM{_Q$Fty5*^Go{^6t41(A4i@K1_xOip6nU)Q03W@mwvCarTDaH3WO= z4Wl`ozqC;@{R6oNWOv?wItlXz?7GqhPbb_bJZ6)$vXRSzd>b}a^C&PH5c9R?C=PI% z!V2Zkj5Am`EmZJa+$>yUyP&|8L!d?A^I*Y*znOYmKccdeXlp*sTQbG94!YGN>u&D| z#1OZYm7X&ig`o_H#Rc$alLRoC`dPZm!v#TD6##K(V=_%~!5nSzb8`=JuS+m1m`h<| z(dP+{!x}_MnhE#nH`?C>1d;Qt7V*1VMqt#Mf-XUva6buBypinJH!?MP>a;Chz1wbC zIo2lV&AfEQ${%CYghHU};}fut>1eA=?qal4IqXn{z#5meR?{{Pq;Eyw$ux@ZZH;hX zWiy>8uv5enC$qB~b5a}W_?o_p&0ZQgF7LNF+ENFm;2cjL_R;~!{>`}^a6icv*1^Hy zEXZl-U{@5siM}=q0aR)trATm=Z?Fn4=4PPlrv&FfcmVkO_wNgE80OB0nPp&!7BPH{ z`0|C-D@47xOLSx2M!I-JZzSUPhZCv@WuoFLs$v8s41ENZ_m+XZYu;T)bTnuZS0CR% zZhQm0@p}Dlvh%`<;viM7Xp&BCR~~>Fxeh2a6mBTHZZDwRAsz*ze)O_y0N}n%*)BQV#9}vfJ8y9^GmCTr?hamDdkC!{6hdEbb?j=)7-*osb-a_isU_`zj`VAUcL|WX;d^Npgmevcb|HhJ5 zYr;<|$GMxOIlmB_!6!)Fmu=Hzt|v|H#z$9fN<%$P;;OBOzE5csyLjB+6d+qJv{Z^6 z4QU4_V1fCX;uVA!Pv~tNZLN$W`?!j#D-1Ik?H8}0Z8j}NYnF!ly?a*js6X$C3oQe! z%(cIlf{6`uP1qA*CcNY@xR$_N(_DOxq-R&1`OsHZT&uxDM!JBb`rsr>Y^IiVmA66D z1ok2%$g(EC>3KzSp6-F)JDI26b5hT8|1))|q-8nX0&ecF#-ICM)Kr$efI>5qqn4(& zdh6T0)SB;BDT^myhknm=P6R7uliM~G54HT^aMR7LiBQgBn1qDjj_03q%3!A1tDg06 zWB70>r);TdsFX=R<-4(i+i!5m?>bkad7{opg(>=fB$3YWbj#URH~ytTFKSd%L$idI z>@Qc`e0qpf@0-&!=^#Vc`hWBzD(D$Ir$H3m$xR3O0VmIcOZaNJ+Q&5*&d$t_ukS76 z`#okpI2zE9By3~OmfeyuQ@(xY$OdCHz9E)zAp3W_TSg|q)p0;&o4zvsfR%gROWkbI z$Fi8eMa^Qq$Xz4r|IfqxDf<_|lWK!qXDM&xscof@ed&n2>D=bnsgO2qyQ(+J+E?05}Dt8E#T})naD-Nq}Uvt;!j^QhbFI0B^lV&!u{8C1F4h?yKq82X#~%AsLL(JW_)#raHR_q!q)BIWhObv+WinmMH(T zMd&=^(`nfxXS1V?#_+rp5`Y~xbAkC*rT2_vGRTy=nJ$flm>ddBXFUeU_br}n-m zh*B;K0m-RIklF6psZQmgQMvMX_l=L#w^MGejk;YQ$$U%PGLzqQ>zT2PbMd!8=!8U$ z7{KAG4trv$0G?}tVsBq>&9T+{c}2UdyV!mA!O6YPjx~-I77Cf=TElvb&r9X|4K#8z zCqw1o;B|cCTE8`#5(kGg=-s-;)*_o+sE-QkQ^nw`WR>^#G0UE`r*z?J0%Uix5Sdns zq2H|ULCSD&WLGN;F^IXme816nN7lYHmC^qp9uzS2yG|kDmI6rt$iwAv5tmVCNytYQ z0}*SXod5;P$t5XnaOE@3SMRLUBgLw>m~MLt4gERwK2AD_bJjji>L}x@70ZJP^&>N{ zL^HB()jn(X-%f7nwCA0OeRk;&Jb5Yt^Jy6zTHrsey)2O_iF_Dc*sDy%?S~P%CiNnH z)*LD+va-MV z4#@QW`<5xc*HF3p$m0D0Zu-pS8-N1~PL$p6*|ZgGamD060usqP+2p>JY4N6m>F_u@ zK%tCZ*a8(S%NZSSV}|Z;cLikPMaqM|ge1cpNz^4y<_&M$T47DH;VP0A~-agdY|QNCShIWB?K(rH#{1ew;G#%!2qt!4r1LEm9?%k7LFvSIGSXI&h0Q zxI0q@ZU-aX&SW zS0dXykG~Da6as~K1S@h~k~l&{iew#BlmJVcQbEpZtc+|4G7+44i4IoxNHIEyjhaNaq*z^6d(N=Qs?K7<|hk%-$MMx*@#Tkj)1hJD6Ro!$6MJHkYY1PDKK z7BnCnzdUUizT7>%GUVX!yT-4>@5WUT#Q-%{yV6u8pDTx$uh&55#QCMm)TrOC*b%}tbd_!pE(#hNu!{+j{( zA)F4^NK@d7atgHJ4Fx|-S|u9e;G!HQtWCZ)MUTz|X7rNwKI!}hU4=%5^qV_74{u!7I?~!9L(!tY^1c4D zj-O&b=4Ol<2WuN)eTqDjYJ&AWv#&ir!s6~yJPFdH8dOoy{~!b+P{B<-Gexxj5i}PQ=mQ+N~gnM$ETkWob_ooO}5$xnJcaZb{_4`$yw%k66fEctQxJ zdjW751!Yx&4l0_wOA$Hbhr>YCju^PL+{^A@ZCGzUXDGE=+%B+_!{PTHJfAwYG>rv^(5fN!~1QFUTKRN__jW5J3FB`$<}JeQQ|q?Zd#C<0H;6{JvtV zo7ZAA_&WZRgdE)=+$yYf$t)j@bj%|=Z+>hK7WA=+KMy&4<#Hv)9eyWn{W>IvSSV=! zE2)4qVj(Q%wTiXsD^v0=<&`gsofk~Wz?TksJO#-P3H@ysO3=DZEX4_9;K+yu@EXJh z6S9=&2iWjf+0EOB)hq+$1JM&(p+iQvLUO`c=YQ2g#2~ylIM4lo>miEtVrWny8zY;L zW^9OlG*eAyNa3etN38GzVr(B>Zm_u6RJRyC*Us0AFeS0+P95^dIaT+ z&ZHW|(_JOsGH|*vn;mT`+Y+!q){k=sT(NT~B9PK%H@|W>A7WYL@#h+Fmq2tLDr9-1m1EQUm z(3*I_`sD=Pz|Qesf*=_=^Muxa0sz<2oHB%&C^TAk`*as%{qOv_x%QC@~;w*ey-;BVSqm`WE_7IFI|OBv(ND{mm8-TgTk?-KkLp}AO)xjPm-32 z;2l2?BJ88=5E8KPNpe{I6Z1JbASmv`9Z?~%a2=QermLGKCaWCC(c$NfeiR<#;sA&t zA|r3gR3td$9oD(=Sg8p&+uuHY&YAh}-bvM#ayfok|k zf|x{casd3oWd}OtGJGu|`JeOs+0zLw^wsu!YWrPu+EO4ptj|?svN9dl#k>rXVK{ag0K^vEywHvg+F&roghPgvhQ5vE7tl#91l?cpglA z979Awf)m+Ui4UBf0PaSL=0a=#5T5wp))s}>x@@?kh{YA6qM>xZ49#6NjN6{{Y_-B9P(3;lY=bI7kkjV$N5II4^d)$qvd{wlHluK0isM_)%X6Oz z0#@Y*D5pJNIJR~f%TJUvj%uW<4hjXU=Ek1=P{b9FQrRMruLug_Xw!s~K)7)X?qgqq zS?^+8f`6WKJHykM(p{1R;}DuxW8rr}Q8w${m2jnlU2^;IKjnwg9Ko}v^WNw`<)pFw zBXzW<@S@XoNc5r0wE-Ii*a8ybH!mxsouwy1SIs8vq5F`88rr?Ach#MXru`5q*GMBm zeZjaALlBL_CsL(@N_-$h1-H`r$^v~J1scmqDSpe5G=7UzMY#t%Of=rtyyS#8UHCD> z3wwzggS<&tI|RI(xTstS1bq7Irc@llRnlucSxGL=DS3}F@-U$w#1)OyZT``0ENtDd zAAQN)(0sRp({%`U)H-NtQSm-x`M5GD!L`w|-m0$oeo6JvAf9Xz(mS;}{pgxer}u~E zZ`YAzbCo>J2@6hb71eo@=-Ialp`4uQ|jb&$jXv4R6E=)v6GJLP#C?gXdH49NCFB3<} zlmKEtxDG&dgJPwd8O{ zpcEoU65lZ`q0Q39N5`iC&qp~g?SGi}kT3h6g0ADY`MB@7NnKTRrwHjg+3G0g3CNGm z3h~5U90pb8txoRicK_6}Ff)S+@%FA8>i9iQ3ATXS%+8G7cAZ+s81iPCA3@vm71)S8 zu7k(-+ANAX227gKx3}Sg`>$1g*?c+$7H=?eg(cUEi<#1ogdfoS!4#6s03`q7b6E^V zv2Rzwc{wE~RT@BOOnfxO$sFt;jxeKGetP~#8mlk;PC;nZ*-ZHg2RjGCikCAxtGSIJ}=ZWv**BBO~QW%G1(w4cR#FZj>G2S*8BAQkG9f33E&YA+T6Fr3o ze+^l_F2J`8t}S|-gv_S)=+d{op+BD13}m~&ATjoPcT3LCwu7%6(1Ss;ZpJB*8@#RL zQrveehp9WSJQ%^wW1&N5xCL-DPKKF=7vLT#!y zOoY)T$}*GA*~?Wi06kILtTQr}XHCqr2S;Ip5Ad2WBk04Zv+%p(X69KGlYgU${cr~} zoxH1|dyrwPj3W12*0Vkg#)n|Z3tiwGRG(jYB-;^jAKmgwQq*NlLieuOi1q=lh?c3; z2zfu|?a{5l(fE;RAC(?{0~p-eoIEenN>70P_o(R4W;r`}V~FIXey8$e=vB{syx_s` z8Bw>k54e2|Ptd)??NGid=z1vXaNyPQo8<3Z0!Mpi++4~X&rPij%eLP0YPQTge(;`G&&of-qP~TDf|umy-R(ua z;K0cgXXeY19B<+>C?sP)~x0B^NH0A%k>g$F_>!QpHK?x z=tc5Q12Xd?;B6BcI-u&ouTJgWycV0BANBRtr1DNqWXWN^e_$QW_3DPEZbhF=gF*tBDW)rJ`9AL-qc9;`3xS^wx z;^Z5$Jve~{1tzL<_Gb6t$GxT~x^uhxoMrMrNLXZJ+JXY{zXV47nJm^s!!g18XU*H# zI7Q)Q&8!twi&2MIKNg_({X^kwCrmS@usC3}Zd<&!RWOc|sz5uFP1Gm@QA-keQsZ8y z2|DI|9CkeZk;(>zV0MYC)*;Y6IKZVL@Oo@n{cguNQRZkHk-e?{`#Q}rrM_Obfn^mF z`DIO2@528mWf*^>vxjYFB;srl{rO{X2X6sCWC{74+muBc89b-lwD*(t*Tsd$;_M1O z+0zqr+aa5QM6F3K9XZRh2sYn=c$fajGr8*+0y5^s-Fz@A8%iiykQBr8AtIU0Y}v)+ z<#MChtb-P{t*!mwOR>+_R?BU6#VJgo8LmN_6h;o=5RZi*-%M7jxGF%^(dui&dJ3Aw z&1oWr-Uiq9RWV**toZKQ=6g1$UrmhbE3jtu&3{sCU0oa2D5jAPwkAMe+4gQq(>%KP zuQFY6%S@}E*E`Sd<%2fSN7)|6hCtWM{D`E>mbJ=V4y}_9+N*D*kM(w-0qM!_d$Q7I zvlnJ=A!h;eLhM(^7QHKbHf-iqAxe@n(YJ6)L2wD;0pmTt_amVBjbW3G>|_V`Cp?pP zB;7$2;YKcwm@rMr`Mu3MY;)VOr3Js}SAWL$*>1loF=9lmvpi$v+hJVf^SjgkxcGM- zmjPSH=ZO|GYdb@>@@IO7e;zfMRw;Xn^)8$*cOvnZQXINwsNH}Hvj&T|7qJ3O7ynfT zd=VvzoZ8ieL@K-w^t4cWWH##zSll)L=AV-W){8lDX6sMhrCp{_QJhfUxs)umZ|8mT z3y#H&yMmzU0Hc3Wcs8iKkeAlk#MO2|pyvMlM^iViO}pw3Rl@0+nV%?!uK&4Wv3xoo ze-SB8(TNFz?qxnu{?*U%|$YK!?03MDzI=dgssR*kNtab z?#xUMGTSw|`?kked`3chZKHgo(a%30q(-Pp8BLNJiiEhDDbS_TC=#>_kc*hnk{ha$ zvOe|rfskSebFmDxq(SFxc!LHpI0R98Abo=ymw;c-i#(h!S$O8$DsHhpqD^gEZJ?R8 z{gwnl<61p?<}rK~Na5GV(ZFAaP+8B4K7eUbY3>*}O+C1~>JyOuY)YQ;EZM|#cl|YI3zI*7-2VJF;nK0Twe!CG)%Xl-xxSB8J%g&BncQ0?Jj}A|!SK6k z{m3hxoY;Yh0P=p)od(tO>&ld0#q9^fcYVLb1k0xDre4<6_{Eg;sMSIBS`<|C>a(*# z-feJ-1Z_2*nO=1AWgK5P@y^ru`O3gp_wWZT0DZM^ArbG~$?s!OWV-7JkFAqa^54IY z>1R5GTYx>HNnJhU57Jqf&~`58)t6v0XHmfi9eXW6W!8=1MT=mUS(r_gVE1vy^N~&3 zeH?vLQUm^;d?$U6*s_*YX!b+0At?^|HWYV9a9c7GhgC#ccyk=#RXQ!b%5fpO=ii@b zv*i!l>cBqr;r(LIbQ~2`l8p})Z^^CPVqs$XoLd3UpkwyvN)>Pku~@4dOVS^!mu+AE@v<%#g0rKotGqR4lT$4FQ%3uz!Lx72hZ!kzrgF1xFU~)yem5#=P_zyh zwG^4iNuAS(XTMS7oXhd-;o6fp66Jr4xb=lk%Lj(LA-+_}r4KJ`5Z)57c9l?aJuyoF z(-kK!V?jZ2xH$UM7!(GLj8sQOOwq4`IkrxfLu*H0WxdP>A{5#^e;+s0?y@1@cWIutV|jg!os~i_>3sn#Odj1-Hx;=etx@q1nU! z;|;5%l&G3!$BPA2LD!dJVq&UlYOxH(iVr~95NF9_&Py?$q=jfFvk%141PCQOYgR`Y zvKXcek?8@ZJkF`_6Rfu!qIDVll%<=eo_Ay(GVcr<(Se zCp{KB?YmW1)=c{G*Qy^vCU5bO^e=f)tJsTR1XXX`Hs7p?ibxdY zHviCxkA~~N%U}jHh=<=XJ=tI!h=%uDtJu8PcrW+!ABC{(Pf)=RKZlc|@P<{R@u0v{Z!wkejG_U<;8NfHutHsA2Ht$(-N!oZ>UTw+ zL0fVqw%=0gO|ljkaz}(^C3#XzunY-r>h#zXG+$nhgyC3c_zxE4;>$~~e7}Eb8>|B8 zmy+llLZdMtNCH*yB*C}p<(}o+*7`y~S+$KxgmLB9<&NcpZ+PYp(rs*jE)N!jU%0T4 z2ZIfuA;B)mxI#V84*HJyx7vHNoD9`SkH1WY^Gu-iFM2PyBGCO(;CgQ~!LcsauT`o^ zu1RL?^Ty|dK;t#D`@^=06O^Jf<6i}xP5KTG^Fd}3oI-+?-Qx?vmh(WrzsF$$FHsa) zHiTmEwRVFv*<${|4qtz0_4w&Lrrt5C(Zx-2jM4`kA4uhob)H!DIDL|UmKj& zAZGp0AG*X%nx*#w+iN{^?ek*leO6&vyWwxfv!M37=XNs1rqc_v0{fNCFCWim7W%1# zJz1<$h`jV1h`S@`y8Af(G2+P}HOp;`#iKXm0|!8mVSrWo#K0D(>1)oSKrydZ8=*RB zYOOEL3bZRrwZLzRb_Xo~=)Ddw(|(;A^i{?b+68WvZtB>$w`Phv8nk4+{juz6o~#)D z6ERD%*ai254Hk=Wprjca99}y6{dxthhmkEidK;;gJ`oddB&Voq>AylvPC+6=+9#%{ zZOWUd#w%#pLD+R^HO(#$h73c zC>GM;p0wRV>+%>R&fuW>)3*Fj%pcyIT-CDymHUw??e_c^28BxvL9sfM8o$oE@e6M< zPdV!?igeJo;u$Xs3*BvEKh3;Vo2u;4utF-cWTp<0X#QT|7t{-zU6%>UV0hba(kY(T zuHuF@awX;;!7*pz_@h-BjL+Qt=!~4CzhYLi$bFZSN{yRoN9~D?U`g5A*I`;LY2!DB zJPuq@mOyr`jgPl|`_CK*xnC z{J&WY3vIUr8O6#&1CRB7FwrxUen`D>advic+imJdW(LJ&@DkZ8c2O$VOLB9EspQ|U z|5~2=9FebhAN124F7wEf_QSj2ySMK(2aCE2>!oT zzB8)HEm->vp@f=X!B9g{!GbiY0*Mp>3rz)&vq?LmlFS58~F^+Sw`H6_YE?OpXbD{Vs~H_oJEH%gybA%Z2ct&u115$%9v@%kW1 z8_5vFDIeUAn~ne1oC8nOw zyseC8ut_Imhsbut_Y&QK7bNZED-P?~SsY{Nfa1~|4nP5>vNPbOoF+d3S#scCQnM4G z;$Y*+o}T2u8f1Z4cYXe4M}ZJWF;-9z@c~ShCk{b>O*%ChcyqshXxky!%895npDrf* zGSf+@BEtRbCRhR~N?l!E@l1g8ds{O)-t!dPbifn$c|?*z^qzl9G(!H~t6UPgGBzM5 zZUs)PVC?9d1!iDNcTE%p^x<)8h}m5+9HS|Y>*13)xQKh>z|!bTw>ocA8&^{t8}@{$ zBozZ(Jy;b{6S4k^#LVl-PwgH}UH)|QLBLw#*fg7cHHp`Ng1k`FJe43YRp4<)A|xk4 zfYcv}7K;g@#ib3`X?)guEMk13d_FtKlYRRO;^&ax&n$+NTL^}~5OXgQ!K)+1^%rQ1&g|fzoQ0-V%m>#>Oy}$3k##O?!nUC?`F{&WRdx{_U&&MgOMWEc5NYhOj?*` zN3K7XzQb(1s^glLql|5qD zq|N!^&1K*hp17H1i=tc@LI5#h>3|Ht$)qFp(spK&vpNVPAee@451Q~{(fX$m2suK9 z=yV|5$y@hke@8()Ksl(-C^h5r57f1w(Xp3I!EZp(LHx{U%&=PqNPORVs@&NxN-$z) zPBHm3%KK>yBv%jklK<@+hfi8}G}!45DH{LuxP-Z)OfIWa(%@-0iv!$jq*l=vdyS=6 z(5cV`N+_Qpe)=wx@ZHBH#p+V^*PmVK6=b7TWSZx6*ba+mes#}r&NEzm4*@AYEi70J zV@!wEX`F0d7;xz32yLpSbgl^QvQrH}`kb&9OsG3E`dFmU8%VbAM+jiF7O_X%+lpc> zfkmSHxmr_o2npkm8;yohq!A$SFrpgXSxvwaHB@A&e%LFaXq8@h@03hi?Wwp z@UR?G$ei*PK6~!0@CK;%SY+3Go+CF$CCVi0aA*?#=r!(Y=Z7BTW3=_161M0tCpKU2 zr$NW|*J(c~+;e{7U=A#i9@g~xSQADOAlJ1m3j|;9xC}0e8Px%YsY8J`+Ab267+$F+ zAnnfR;nT5}>HMikW0m=o=}Dq`J>pmGT~vPWiE#dK1(rzeR9*=}yhty#9V5}~n{`BW zl`gjZK7LmFX#rAACB>6Fytz(A1hHuciDZi2YEp(^)9~=9jnx!qCokLA2YD72mQ^@X z{4A?fN346f6tJV(7`DaQfi3ovP3fmuF*JzVaHglYo|6Zkc9#tddSbrUQ8{}htqHj7=D^(~ybD>>e2El0x11u548Ldp&j_4=sUq6o>YmPSQ4vs3nTzzvIRSFmqEaM~-8P)}@} z)3hV2P5juJQ_%4ROSx79Mwj>>eYMT z>(N`;dE@kbm&c!-c~DCWdTPQ&Vg%BUE*R|iPJ3`rhA=?fPbP!UG40K_HfVN=heN_7 zESN2e`B46-i?B@OKoPzf5(}r5BX&GBOA6UUcTHtC?cf(`cf`lMHVpmNZl`>WQMNoc zV(As;#M`FidM9frl{`{a#_nM{F`*nsUfiT-iPnrdEIOD z!y%bu@0dVQ2bS?5NCC5UYgFPkm0ug>+l`cTqv`l4v6Krm@RS=ka zH60Pg=#*9@H8k2Z4`4;TvX>A_&qW{vdWpZs8tVLXuS>g4=N0MD?(Jz#zqL(2tpm|$7{ zpb;G@kyNATBRTc9ykkLGBBQDxG;ee2b#NdmP>{3cT5|`q`A-aqy*gt2!(nEo8z^V= z9B67~skS-uWPAYH4Vlj{HKl8>uXvZ<=_gB=Nub~90{3=QaTi`)%-WdGyPvmqU4sf5 z?b3Vz+X;p_vH<_vpmM+#2W*HuI7WqYef+N?cug9B>HlKC;;H8~1-dRiEWp;_Az0YQa z6xv>(6hU`h;D$pz{n4sO3MjqcwDHZvD9yUvrl|H{LHwiN6ncY^@j3Uoe4+m|aun1kto6h3B- z@^$6iChlyg6Ikc)%_z|jKg|WMIXAHj;4&eADT&0zQ;BksP@ljzwP26-GpAfwQnVE8 zUj9lgVmB5PB~hK2^nFEW4!$D5XGvN?tcfT~lhjUVjRF&14zao-VK%F9naTnNHl#fw zjfEy{(kG`Q5XXtd+^-(pafj|$BkL~V-=hLUfL#lxg)t2r;$Fq#RcIstd=6iSO=Y?^ z!80}MbRR|p11!i;Y2;Z3BqGpdv}!z$xkGxSq=)0v#Mwb7+HVwkPD2sIyd#Dy_4Bcd z{W346Ldp{JLv!&Bk4aBYj%p9hG`u;-Sz|rohEclR0kKo(m1@1*0i6R`XG|jA2P0%# z6k>zQD*^FDMw!(}CS_>}A}WpUX?*9Lny#n9Hao&4e(ZT-Hz-ts=@ReKj0EZynpNDL zR_MeD8VQFU5Si?$K1_i*<;Qkg?e(AqY|)?&9??1+F~$Awk5c4UK=+U=NOd&=Lpxxv z0wd_q`4j%3Fi5{i(pRj*-(B~WRyM~XZHf%cyQkz2#_5qYM@9^;T_ewfFV=a%tlk?# zP6`($`Tj*nQX0Iv`}DyX=fUcC2H!?5Bv#z!oVkf+LDnH(U_N`Zz}q3Bu*`@M`B*u$ z1|$(4Jkij2SOBQmdIfa=$6{Bf@T}h%V%Snk1Q?}*o?~o|6ks!jePsKoL_;BjGm?-hTE znyM?<*`o~QhL4v9&T%==e>d$bIbT&StbzB*%D(Q;r3Y>$`<%{gP`i+mNKSaEZ*Vil ze@T6-y2h|bPn?aYEwOi5eDxBBUcLA6R?+pC?zhcpBezZ=>8`(ioh;p}`$d)@A90Ob z%CNFq@D--jSaX7-Q6r~P(N1c4rR@2+#FH^8z+U}d)G?O{{Ax*7w$)Tw3 zj0}A|%D+gaD5Z~JVvu{J|JHa?mL}cmk<`27_`zIkrX+=Im637~VIk7@@V#Y@mSH3- z>v;tIcA5W+XAeimX4$*dSv3%J#WKH`XG@a$79M7t17%w9BV;^!9GlQJRS@D}6oYBmtY9 z5N{)58N%Q~V2xe-lLLP}k2#Y26Gu^3VR?ZzU&ysgf14RCdK9){FJ5Arl#>+`NZC=V z(pecwfNu_4e7B#fK-&lr-D%-3yd^gc7^gShk4R z-uM3lP8|7npr?q}wZEYA|LTWB@j}+PzBdA>TVP|IKLgkhU})2R^pIiOk7sJZ+Q^(- zrBYh{3(#8s6KJ*kJ1Ar=kL(QlTbJ9vEaVUKZ{_lLZ-FBnfv0~D-Uu`;ulUXvvKn6( zFh-4%R>DH*4c2%56J+B4i=zMUKx7EuizmST)@ArF3pr$p{85g&^2`x%u;Ui>Ue~s{ zK4L!9u{0R!|5J|A>6H+Bkgqo_op;~epsV})YG+;2i*|B<&33YZ-=nC`+@JPpiZaLZ zHtM#f@(?Kr{Q{}iZm7J@inaE8>p#yy`8;qlAx$Wy|JQikR;*=}?%8kW?)#rkbru|~ z-7LA>DkY*!UXt7Ue%H)?1hV$f_+XB_R z)_dq2a&=tGy&4Hyc+A)p2;=*23&~;u7yj6#ZHvg)Ue}ejkuUb7I0^xn0FgOHp`l7J zqlRK-czC0<*}V5j4a7Cv(7ZGy9xHOer-gPma|$7*#T)rQJZGf4Ht=WH)bJge8yg3{ z{<8r%!~^*HCTt&*c;or%Qe3)RBve!_zIm@=mJrRyO&j8C;Fr=0ZQ(_#mBWIcJVe@P zsJ@RoYV-(cgX!e-TV8x?BzeN)4gc@Ow~`Tj`WF+IdMuR1!G|xo8|^A+=H4jg$3oif zeQo@z$$nZg*3);}L=TdyidJdQ7BJmX=<}Uuok(M@`4tQE4z=Uj4gU9U6x}L1%%zpH z-~Xi4xw8|wmS5t^tjFpszoqkKdZd@}&;n<~L7bFF(t{B+tkc3_#rzSp*_b0Pr6Pyh z`I2#gL2bn0I z++j|!9HzlqYc#;z6HZT+8xU)V&zfT5+-)rv0KQyav4eCloHeyVZFz@)r=rMDe&mvr zo~?|~X#51nMeVpp&FQ2&q^Fp;NpI%D^_yTI+D@ut|0{#Ht&shX0}it#UJ-~~YdMG( zlZ7u!Q>k;q4y6nFG6c~Lz(;nB8lPu=$xa5Gtpb?+$o@PP>?^gcur z$ia`Yqt0>N&BZU)NH;@xpI$!P!^6w$-bsnJvb&s&}(rWLC7$K( zGzmO|9lH0}`*Sn&*yZbuqB>MhJ!B(X2gw+t@Ah&3;1z%MC6Wsj3UQDV2gAf#{)+AZ zbRymOB;qk>SCh1t2$u@8ny+rm1@?{q1`p5&5N7 zW*3~ySbMJ3Ek?PIgwK_!_Gw5gYLY0W(D3kfVsAXpm{%Xqqems*qgmmDsyHrsv!2iQ z(u@--n6s*R2}#A@W<{ik3&vrK^5lI8OTjXc^yOL}5zm4Rlf{m^F zHs>~qR4=QsIS`j~ZYIFFGn1Id1RbxwioV`$(9>IK(MsEx=2x!Xr9BhcC`bt6HQ?XBUIF1V6cQrT%xe!7TmYLI6-=FU7HyByG^q7qoCedS7f?&6O7 zBd5anC}N4kcBY+GeWYquU5Yb5~q1ARCxX({ursUXAzzcVcU*T z71Kg@4)@n6hS^H-sxR=O)+E~1atq3g_Sjf|j7Aw6M03^3)zK1-kkV|iLSCNgCzHM6 z5Ygud-{oUN6$Xnzcc&)n3U$+d@rlUPloYj9`5?#6L4PCSX6n5PXj?L_FA#xL+;`~O zj3jbr@<#UxH0DNagW!PbaCx%RN2RNvH^)Q|3*#Pdj`i^qmM_R;&SttX^3~}(PmMo$ z)H-3Jxz4LA%SVR~hv|I_S+w+i?jcDkNl z#7T|w{V9%c8y{0FuGk+ycQs42=Mi2{|DgMNxy_ys=F+U+=qRkRs3$P*+=7kIE%QjBRJQGVnrcBA(MT zhyqOCkHwCPwr>hqOm(y$GB$%(BG;dNu2~c44BzwhBCncT8K>W1zb=YAJP|vfqLu9B z?ryUWM+|HgnNZWQ=4>%Bl+DSv7ZROHKWVwt&E1u})UBa6K2nl2q7E~ zg$q0j`_M*c4&jWo#PhSe_q2lEQU8mk2+BD?o*|f7TK=g;G&c^@YOUE{o>6!wKh1R4LiNa!-jI z_Pz<>vvk{3#vDqjIaI2AXnRw7goeME3957?3MR&twZuBWrgtJhYX*kGlD8tWRumkV zWSPv)l}j~2ccmv?T{s$Q`r4$n$Et07c~GkxQL_QUT_5(#JDT!<4<96lfb~`1fJUBK zs`L?v>xoR}EMjGNUfc14>!3ibh^Rm{HAtgjC`2=`U$F1d%>Ik?{`{l7JD*%(q5&$4 z$}+KXs3nWD=*+B@PGdN&o}LG@2JZ$nvglv!MarJ6rLJ-ki|Av6c&{dL7DVz2xY4!z zR**Cbwb#Ul=F|LIb-%kSqK&&#cLLw1gw8jIcYjvO_Iu*Nn9iKN#Jj&=e7~Iq9NZB2 zC3hA3#w-3HQ*iCc$c;eh-V&wlu# zUv;2?9D?Mm2B}KS#teAy%$}&=hKp%6$j0&z#59?yULnhstSx@$mj0S)3DA$-QDkbn z(ff752D1`lIDL>_)-%jBTxRj%VRx2I?W07?z&Rdeo4-t!9RWN|1lsdj)R5sW9!CbP zGK;=q{*1cAfi}VWc_a9?BWl?C=tqMVZhnwg%}|S?RlcGuo<#c!xp9wNVHIt`alqyU zH@F+bfc$~GSJ89o*{)(p>0G^~2q)&s63JK_M;yZK0=md=&zlU*&7X~^yr_KD`9{?Q zf4S;8hw*|&(sBh z(il^`6idezM{BA+Nc2M(jqg{MVQq=CsmQ@w5xob<)tWa5$l`9C2n>X`u&!}a&W2uM zfh$4qgd2jx1ng};!X+wh-B>TVH*NwVa+(k`A@H2ZQ#m^ih|5UFL~=;+?Dc`vR#Z5y zPpDozDKk1YzfD#hvH8ndeCT*y>JTAlF@n~kf%Cfs2I4`!+uXqKbmVUF#n5f;X46kq z45|-9_2&%FYHQ^4d%#>8fWBeAoFC06nzaw0_KSb?Pbj+`*==5TizDsZRd+`>Wgr_c zef0nwpSKlXZf6PrAOHXW000317ytlqe-r5m r+5rGUmu$}%+5rGUmu$}%+5u2Y1qJ{B000310RUY9006aJ000000b95o literal 12022 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 z z&)-jO@2;+waX(R%xplvX2d01W9b-w=l(4k)w!tGdG>7&k6w;9fgm3BC2A`1^WCp>& zhd*K@GE_AEnjbP+-x}Mu`K*TH5E5O|L`Io!s3O2~&zVm- z#=;^VDBK`D98Tsw^V>+MI zY*dZm+-JLR?l-&IawJHC2&s zb@T!Gqp+c2Dw;-nW*PP5Gl^Vmf4d%P4eFZwuR+#EhxRV=Pgk24^1N^25+H@oFq7JBw2L04(;5K0}5HxToq~^0Cu-IWzs}SK!IEoWq+^UNJDP4T?so7$9F# zE^y*zRHlLA;nbSj}2d-h&!eLb_n)2tcDVu!A zgeZob!m=pVY{qNf*;^-kmCj#a?Wt^*-<#~1)ktmYvC>zP>zmeX=uxJD5z?si*`aFT zD*clc^z_tLLb$>@lFMmJugjLBM{D}qhZBuy@13!ZJvsBo#OM8Cm1q&CieDg|kxMn# zQ+_XeJ*GKZB5=ho44LUkK-XATD0)0%3(Md^K%4R|?g{_}P7d0^T(V^V*cW7q5*Q`)83W1@yyr8Zx7`X3&>M{ zHO+5-M&3HyZ2DJ3*8KG#@jAcA%{>pl*C=|s3-0;ICL1YipN&%-2=q{vEJwy?K;;9! z+W~*dl2%00*wHwjsY_hwt)?f)s^e12YIa19JIo`;9)w2T2z?t?|izFDpMr8 zV(_ia@ld!faQ`r3!KEMuYr%EV^xbzgZ=d_qx$STt8!%2JKvLy$oH|GlCl`H6V2xsH zJUQeI&ZnD<$p=gYkLr4%l(D{AR{u1N5NQ@rHx`HYWLLN6<1rDokRyS^MPMld`lZfZ zfx!--lhQJZW2@q;BJCWUhqBJ`+W|eejcihBIu4j}T`zmmE8;^!4%nPb^X}@*4o0fk zI<=T8r_Ew+esi4m`jf+C6?YWYEyCJqU|?dr-+s5@)DtiJv;VdZ{uH&1`TL95F#5%N zPdwEIG~l`C94l^k^8;(q88ZHWKl^6yfk#aSe@$HuE>eSXL0fV%7D#Mjn09(gEIu_= zAKP~#=wOU3|7Ub!nF1HeKyU!+eZDfEI(gwGJdok+q;A@a6(ZO){Z~axvI>2Aa4_Lz zKPXOtOWE4hKhhu3sK5v9NVbX%(xr4>0b+5mAx_t_bJC}_D;&-gJWv=XY@3qrzLH># zvh(=+piPpr_MQdJuQP-zXQM=4ml;=B%IGz*d-*1ukEA39?l>uJew-A83BeY&_0T_P zx8>u0$g6#FSfkwSXzDa`Zxf~MzB=>ZulwURo3+hKD-q0c$zTI&9g

IC^7YVz<*lgl#{tT9Z9OA3%?fYcCjD9*-Y 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 bS^uxr)gb4g4gmiL?lnK* diff --git a/src/Resources.c b/src/Resources.c index 3ab08fd6a..69c974d6b 100644 --- a/src/Resources.c +++ b/src/Resources.c @@ -327,9 +327,12 @@ static void SoundPatcher_Save(const char* name, struct HttpRequest* req) { cc_string path; char pathBuffer[STRING_SIZE]; struct OggState ogg; struct Stream src, dst; - struct VorbisState ctx = { 0 }; + struct VorbisState* ctx; cc_result res; + ctx = (struct VorbisState*)Mem_TryAllocCleared(1, sizeof(struct VorbisState)); + if (!ctx) { Logger_SysWarn(ERR_OUT_OF_MEMORY, "allocating memory"); return; } + Stream_ReadonlyMemory(&src, req->data, req->size); String_InitArray(path, pathBuffer); String_Format1(&path, "audio/%c.wav", name); @@ -338,12 +341,14 @@ static void SoundPatcher_Save(const char* name, struct HttpRequest* req) { if (res) { Logger_SysWarn(res, "creating .wav file"); return; } Ogg_Init(&ogg, &src); - ctx.source = &ogg; - SoundPatcher_WriteWav(&dst, &ctx); + ctx->source = &ogg; + SoundPatcher_WriteWav(&dst, ctx); res = dst.Close(&dst); if (res) Logger_SysWarn(res, "closing .wav file"); - Vorbis_Free(&ctx); + + Vorbis_Free(ctx); + Mem_Free(ctx); } diff --git a/src/Server.c b/src/Server.c index df9bd4fdd..c778a2aa1 100644 --- a/src/Server.c +++ b/src/Server.c @@ -127,13 +127,19 @@ static void SPConnection_BeginConnect(void) { Random_SeedFromCurrentTime(&rnd); World_NewMap(); + #if defined CC_BUILD_LOWMEM World_SetDimensions(64, 64, 64); #else World_SetDimensions(128, 64, 128); #endif +#ifdef CC_BUILD_N64 + Gen_Active = &FlatgrassGen; +#else Gen_Active = &NotchyGen; +#endif + Gen_Seed = Random_Next(&rnd, Int32_MaxValue); Gen_Start(); diff --git a/src/Window_N64.c b/src/Window_N64.c index 05dfa329d..41271343f 100644 --- a/src/Window_N64.c +++ b/src/Window_N64.c @@ -39,7 +39,11 @@ void Window_Init(void) { // change defaults to make more sense for N64 cc_uint8* binds = (cc_uint8*)KeyBind_GamepadDefaults; - binds[KEYBIND_INVENTORY] = CCPAD_Z; + binds[KEYBIND_INVENTORY] = CCPAD_B; + binds[KEYBIND_PLACE_BLOCK] = CCPAD_Z; + binds[KEYBIND_HOTBAR_RIGHT] = CCPAD_L; + binds[KEYBIND_DELETE_BLOCK] = CCPAD_R; + binds[KEYBIND_FORWARD] = CCPAD_CUP; binds[KEYBIND_BACK] = CCPAD_CDOWN; binds[KEYBIND_LEFT] = CCPAD_CLEFT; From eedea7446d0aae8459a16b5cda6485bd3eac6813 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Mon, 22 Jan 2024 19:55:43 +1100 Subject: [PATCH 9/9] Only load top parts of gui.png and icons.png into GPU textures --- src/EnvRenderer.c | 8 ++++---- src/Game.c | 7 ++++++- src/Game.h | 14 ++++++++------ src/Gui.c | 11 +++++++---- src/Model.c | 5 +++-- src/Particle.c | 2 +- src/Screens.c | 4 ++-- src/Widgets.c | 15 +++++++++------ 8 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/EnvRenderer.c b/src/EnvRenderer.c index eb8067925..6bd16cc33 100644 --- a/src/EnvRenderer.c +++ b/src/EnvRenderer.c @@ -783,22 +783,22 @@ static void UpdateMapEdges(void) { *---------------------------------------------------------General---------------------------------------------------------* *#########################################################################################################################*/ static void CloudsPngProcess(struct Stream* stream, const cc_string* name) { - Game_UpdateTexture(&clouds_tex, stream, name, NULL); + Game_UpdateTexture(&clouds_tex, stream, name, NULL, NULL); } static struct TextureEntry clouds_entry = { "clouds.png", CloudsPngProcess }; static void SkyboxPngProcess(struct Stream* stream, const cc_string* name) { - Game_UpdateTexture(&skybox_tex, stream, name, NULL); + Game_UpdateTexture(&skybox_tex, stream, name, NULL, NULL); } static struct TextureEntry skybox_entry = { "skybox.png", SkyboxPngProcess }; static void SnowPngProcess(struct Stream* stream, const cc_string* name) { - Game_UpdateTexture(&snow_tex, stream, name, NULL); + Game_UpdateTexture(&snow_tex, stream, name, NULL, NULL); } static struct TextureEntry snow_entry = { "snow.png", SnowPngProcess }; static void RainPngProcess(struct Stream* stream, const cc_string* name) { - Game_UpdateTexture(&rain_tex, stream, name, NULL); + Game_UpdateTexture(&rain_tex, stream, name, NULL, NULL); } static struct TextureEntry rain_entry = { "rain.png", RainPngProcess }; diff --git a/src/Game.c b/src/Game.c index a0b497937..a95b731b6 100644 --- a/src/Game.c +++ b/src/Game.c @@ -213,13 +213,18 @@ cc_bool Game_CanPick(BlockID block) { return Blocks.Collide[block] != COLLIDE_LIQUID || Game_BreakableLiquids; } -cc_bool Game_UpdateTexture(GfxResourceID* texId, struct Stream* src, const cc_string* file, cc_uint8* skinType) { +cc_bool Game_UpdateTexture(GfxResourceID* texId, struct Stream* src, const cc_string* file, + cc_uint8* skinType, int* heightDivisor) { struct Bitmap bmp; cc_bool success; cc_result res; res = Png_Decode(&bmp, src); if (res) { Logger_SysWarn2(res, "decoding", file); } + + /* E.g. gui.png, icons.png only need top half of the texture loaded */ + if (heightDivisor && bmp.height >= *heightDivisor) + bmp.height /= *heightDivisor; success = !res && Game_ValidateBitmap(file, &bmp); if (success) { diff --git a/src/Game.h b/src/Game.h index c11763ea3..db22d993a 100644 --- a/src/Game.h +++ b/src/Game.h @@ -92,18 +92,20 @@ CC_API void Game_UpdateBlock(int x, int y, int z, BlockID block); CC_API void Game_ChangeBlock(int x, int y, int z, BlockID block); cc_bool Game_CanPick(BlockID block); -cc_bool Game_UpdateTexture(GfxResourceID* texId, struct Stream* src, const cc_string* file, cc_uint8* skinType); +/* Updates Game_Width and Game_Height. */ +void Game_UpdateDimensions(void); +/* Sets the strategy/method used to limit frames per second. */ +/* See FPS_LIMIT_ for valid strategies/methods */ +void Game_SetFpsLimit(int method); + +cc_bool Game_UpdateTexture(GfxResourceID* texId, struct Stream* src, const cc_string* file, + cc_uint8* skinType, int* heightDivisor); /* Checks that the given bitmap can be loaded into a native gfx texture. */ /* (must be power of two size and be <= Gfx_MaxTexWidth/Gfx_MaxHeight) */ cc_bool Game_ValidateBitmap(const cc_string* file, struct Bitmap* bmp); /* Checks that the given bitmap is a power of two size */ /* NOTE: Game_ValidateBitmap should nearly always be used instead of this */ cc_bool Game_ValidateBitmapPow2(const cc_string* file, struct Bitmap* bmp); -/* Updates Game_Width and Game_Height. */ -void Game_UpdateDimensions(void); -/* Sets the strategy/method used to limit frames per second. */ -/* See FPS_LIMIT_ for valid strategies/methods */ -void Game_SetFpsLimit(int method); /* Runs the main game loop until the window is closed. */ void Game_Run(int width, int height, const cc_string* title); diff --git a/src/Gui.c b/src/Gui.c index 350e9f974..9844dbfcd 100644 --- a/src/Gui.c +++ b/src/Gui.c @@ -546,22 +546,25 @@ void Screen_PointerUp(void* s, int id, int x, int y) { } *------------------------------------------------------Gui component------------------------------------------------------* *#########################################################################################################################*/ static void GuiPngProcess(struct Stream* stream, const cc_string* name) { - Game_UpdateTexture(&Gui.GuiTex, stream, name, NULL); + int heightDivisor = 2; /* only top half of gui png is used */ + Game_UpdateTexture(&Gui.GuiTex, stream, name, NULL, &heightDivisor); } static struct TextureEntry gui_entry = { "gui.png", GuiPngProcess }; static void GuiClassicPngProcess(struct Stream* stream, const cc_string* name) { - Game_UpdateTexture(&Gui.GuiClassicTex, stream, name, NULL); + int heightDivisor = 2; /* only top half of gui png is used */ + Game_UpdateTexture(&Gui.GuiClassicTex, stream, name, NULL, &heightDivisor); } static struct TextureEntry guiClassic_entry = { "gui_classic.png", GuiClassicPngProcess }; static void IconsPngProcess(struct Stream* stream, const cc_string* name) { - Game_UpdateTexture(&Gui.IconsTex, stream, name, NULL); + int heightDivisor = 4; /* only top quarter of icons png is used */ + Game_UpdateTexture(&Gui.IconsTex, stream, name, NULL, &heightDivisor); } static struct TextureEntry icons_entry = { "icons.png", IconsPngProcess }; static void TouchPngProcess(struct Stream* stream, const cc_string* name) { - Game_UpdateTexture(&Gui.TouchTex, stream, name, NULL); + Game_UpdateTexture(&Gui.TouchTex, stream, name, NULL, NULL); } static struct TextureEntry touch_entry = { "touch.png", TouchPngProcess }; diff --git a/src/Model.c b/src/Model.c index fed0298ac..7b4ad8c72 100644 --- a/src/Model.c +++ b/src/Model.c @@ -512,10 +512,11 @@ void Model_RegisterTexture(struct ModelTex* tex) { static void Models_TextureChanged(void* obj, struct Stream* stream, const cc_string* name) { struct ModelTex* tex; - for (tex = textures_head; tex; tex = tex->next) { + for (tex = textures_head; tex; tex = tex->next) + { if (!String_CaselessEqualsConst(name, tex->name)) continue; - Game_UpdateTexture(&tex->texID, stream, name, &tex->skinType); + Game_UpdateTexture(&tex->texID, stream, name, &tex->skinType, NULL); return; } } diff --git a/src/Particle.c b/src/Particle.c index 45ecc2068..4c3e3b81c 100644 --- a/src/Particle.c +++ b/src/Particle.c @@ -574,7 +574,7 @@ void Particles_CustomEffect(int effectID, float x, float y, float z, float origi *---------------------------------------------------Particles component---------------------------------------------------* *#########################################################################################################################*/ static void ParticlesPngProcess(struct Stream* stream, const cc_string* name) { - Game_UpdateTexture(&particles_TexId, stream, name, NULL); + Game_UpdateTexture(&particles_TexId, stream, name, NULL, NULL); } static struct TextureEntry particles_entry = { "particles.png", ParticlesPngProcess }; diff --git a/src/Screens.c b/src/Screens.c index 6e9e8c35f..0bc607ddb 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -334,11 +334,11 @@ static void HUDScreen_Update(void* screen, double delta) { #define CH_EXTENT 16 static void HUDScreen_BuildCrosshairsMesh(struct VertexTextured** ptr) { - static struct Texture tex = { 0, Tex_Rect(0,0,0,0), Tex_UV(0.0f,0.0f, 15/256.0f,15/256.0f) }; + /* Only top quarter of icons.png is used */ + static struct Texture tex = { 0, Tex_Rect(0,0,0,0), Tex_UV(0.0f,0.0f, 15/256.0f,15/64.0f) }; int extent; extent = (int)(CH_EXTENT * Gui_Scale(Window_Main.Height / 480.0f)); - tex.ID = Gui.IconsTex; tex.x = (Window_Main.Width / 2) - extent; tex.y = (Window_Main.Height / 2) - extent; diff --git a/src/Widgets.c b/src/Widgets.c index 97285407c..64766450d 100644 --- a/src/Widgets.c +++ b/src/Widgets.c @@ -17,7 +17,6 @@ #include "Block.h" #include "Input.h" -#define Widget_UV(u1,v1, u2,v2) Tex_UV(u1/256.0f,v1/256.0f, u2/256.0f,v2/256.0f) static void Widget_NullFunc(void* widget) { } static int Widget_Pointer(void* elem, int id, int x, int y) { return false; } static void Widget_InputUp(void* elem, int key) { } @@ -98,10 +97,12 @@ void TextWidget_SetConst(struct TextWidget* w, const char* text, struct FontDesc *------------------------------------------------------ButtonWidget-------------------------------------------------------* *#########################################################################################################################*/ #define BUTTON_uWIDTH (200.0f / 256.0f) +/* Only top half of gui.png is used */ +#define Button_UV(u1,v1, u2,v2) Tex_UV(u1/256.0f,v1/128.0f, u2/256.0f,v2/128.0f) -static struct Texture btnShadowTex = { 0, Tex_Rect(0,0, 0,0), Widget_UV(0,66, 200,86) }; -static struct Texture btnSelectedTex = { 0, Tex_Rect(0,0, 0,0), Widget_UV(0,86, 200,106) }; -static struct Texture btnDisabledTex = { 0, Tex_Rect(0,0, 0,0), Widget_UV(0,46, 200,66) }; +static struct Texture btnShadowTex = { 0, Tex_Rect(0,0, 0,0), Button_UV(0,66, 200,86) }; +static struct Texture btnSelectedTex = { 0, Tex_Rect(0,0, 0,0), Button_UV(0,86, 200,106) }; +static struct Texture btnDisabledTex = { 0, Tex_Rect(0,0, 0,0), Button_UV(0,46, 200,66) }; static void ButtonWidget_Free(void* widget) { struct ButtonWidget* w = (struct ButtonWidget*)widget; @@ -507,11 +508,13 @@ static void HotbarWidget_Reposition(void* widget) { w->slotWidth = 20.0f * scaleX; Tex_SetRect(w->backTex, w->x,w->y, w->width,w->height); - Tex_SetUV(w->backTex, 0,0, 182/256.0f,22/256.0f); + /* Only top half of gui png is used */ + Tex_SetUV(w->backTex, 0,0, 182/256.0f,22/128.0f); y = w->y + (w->height - (int)(23.0f * scaleY)); Tex_SetRect(w->selTex, 0,y, (int)w->selWidth,w->height); - Tex_SetUV(w->selTex, 0,22/256.0f, 24/256.0f,44/256.0f); + /* Only top half of gui png is used */ + Tex_SetUV(w->selTex, 0,22/128.0f, 24/256.0f,44/128.0f); } static int HotbarWidget_MapKey(int key) {