power_play/src/base/base_incbin.c
2025-08-05 13:48:49 -05:00

86 lines
2.7 KiB
C

#if CompilerIsMsvc
////////////////////////////////
//~ Windows headers
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#include <Windows.h>
////////////////////////////////
//~ Incbin
/* Find first resource with `type` and return the data in `udata`. */
BOOL CALLBACK IncbinEnumerateResourceNamesFunc(HMODULE module, LPCWSTR type, LPCWSTR wstr_entry_name, LONG_PTR udata)
{
TempArena scratch = BeginScratchNoConflict();
IncbinRcSearchParams *params = (IncbinRcSearchParams *)udata;
String entry_name_lower = LowerString(scratch.arena, StringFromWstrNoLimit(scratch.arena, (LPWSTR)wstr_entry_name));
params->found = 0;
params->data = STRING(0, 0);
if (EqString(entry_name_lower, params->name_lower))
{
HRSRC hres = FindResourceW(module, wstr_entry_name, type);
if (hres)
{
HGLOBAL hg = LoadResource(module, hres);
if (hg)
{
params->found = 1;
params->data.len = SizeofResource(module, hres);
params->data.text = LockResource(hg);
}
}
}
EndScratch(scratch);
return !params->found;
}
String StringFromIncbinRcResource(IncbinRcResource *inc)
{
IncbinStatus state = Atomic32Fetch(&inc->state);
if (state != IncbinStatus_Searched)
{
TempArena scratch = BeginScratchNoConflict();
if (state == IncbinStatus_Unsearched)
{
IncbinStatus v = Atomic32FetchTestSet(&inc->state, state, IncbinStatus_Searching);
if (v == state)
{
/* Search RC file for the resource name */
String name_lower = LowerString(scratch.arena, inc->rc_name);
IncbinRcSearchParams params = { .name_lower = name_lower };
EnumResourceNamesW(0, RT_RCDATA, &IncbinEnumerateResourceNamesFunc, (LONG_PTR)&params);
if (!params.found)
{
/* FIXME: enable this */
//Panic(StringFormat(scratch.arena,
// Lit("INCBIN include not found in RC file: \"%F\""),
// FmtString(inc->rc_name)));
(*(volatile int *)0) = 0;
}
inc->data = params.data;
state = IncbinStatus_Searched;
Atomic32FetchSet(&inc->state, state);
}
else
{
state = v;
}
}
/* Spin while another thread searches */
while (state != IncbinStatus_Searched)
{
_mm_pause();
state = Atomic32Fetch(&inc->state);
}
EndScratch(scratch);
}
return inc->data;
}
#endif /* CompilerIsMsvc */