86 lines
2.7 KiB
C
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)¶ms);
|
|
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 */
|