diff --git a/OVMF/OVMF_VARS_4M.fd b/OVMF/OVMF_VARS_4M.fd index d34bc6f..6704f07 100644 Binary files a/OVMF/OVMF_VARS_4M.fd and b/OVMF/OVMF_VARS_4M.fd differ diff --git a/build.bat b/build.bat index 0d18ae5..305face 100644 --- a/build.bat +++ b/build.bat @@ -1,9 +1,10 @@ @echo off ml64 /c /nologo /Brepro helpers.asm cl main.cpp /c /Brepro /GS- /GR- /Oi /EHs-c- /nologo /Zc:threadSafeInit- /I include || pause && exit /b +cl take_care_of_bink.cpp /c /Brepro /GS- /GR- /Oi /EHs-c- /nologo /Zc:threadSafeInit- /I include || pause && exit /b cl user32.cpp /c /Brepro /GS- /GR- /Oi /EHs-c- /nologo /Zc:threadSafeInit- /I include || pause && exit /b cl ole32.cpp /c /Brepro /GS- /GR- /Oi /EHs-c- /nologo /Zc:threadSafeInit- /I include || pause && exit /b cl kernel32.cpp /Brepro /c /GS- /GR- /Oi /EHs-c- /nologo /Zc:threadSafeInit- /I include || pause && exit /b cl winmm.cpp /c /Brepro /GS- /GR- /Oi /EHs-c- /nologo /Zc:threadSafeInit- /I include || pause && exit /b -link helpers.obj main.obj user32.obj ole32.obj kernel32.obj winmm.obj /Brepro /STACK:0x400000,0x100000 /NODEFAULTLIB /ENTRY:efi_main /NOLOGO /SUBSYSTEM:EFI_APPLICATION /OUT:BootX64.efi efilib.lib /MACHINE:X64 || pause && exit /b +link helpers.obj main.obj take_care_of_bink.obj user32.obj ole32.obj kernel32.obj winmm.obj /Brepro /STACK:0x400000,0x100000 /NODEFAULTLIB /ENTRY:efi_main /NOLOGO /SUBSYSTEM:EFI_APPLICATION /OUT:BootX64.efi efilib.lib /MACHINE:X64 || pause && exit /b copy /B /Y BootX64.efi fatroot\EFI\Boot\ diff --git a/fatroot/EFI/Boot/BootX64.efi b/fatroot/EFI/Boot/BootX64.efi index 6b23adc..23f59e2 100644 Binary files a/fatroot/EFI/Boot/BootX64.efi and b/fatroot/EFI/Boot/BootX64.efi differ diff --git a/fatroot/idk.bk2 b/fatroot/idk.bk2 new file mode 100644 index 0000000..df733d2 Binary files /dev/null and b/fatroot/idk.bk2 differ diff --git a/kernel32.cpp b/kernel32.cpp index 5b16e97..7fa38eb 100644 --- a/kernel32.cpp +++ b/kernel32.cpp @@ -224,43 +224,58 @@ DWORD WaitForSingleObject(HANDLE, DWORD) { } // --- Timing --- -static unsigned long long tsc_freq = 0; - -static void init_tsc_freq() { - int cpuInfo[4] = {0}; - __cpuid(cpuInfo, 0x15); - - if (cpuInfo[0] && cpuInfo[1]) { - // leaf 0x15 gives: eax = denom, ebx = numer, ecx = crystal Hz - unsigned eax = cpuInfo[0]; // denom - unsigned ebx = cpuInfo[1]; // numer - unsigned ecx = cpuInfo[2]; // crystal freq Hz - - if (ecx != 0) { - tsc_freq = (unsigned long long)ecx * ebx / eax; - return; - } - } - - // fallback: CPUID 0x16 (nominal core frequency MHz) - __cpuid(cpuInfo, 0x16); - if (cpuInfo[0]) { - tsc_freq = (unsigned long long)cpuInfo[0] * 1000000ULL; - } +static inline unsigned long long read_tsc() { + _mm_lfence(); + return __rdtsc(); } -BOOL QueryPerformanceCounter(LARGE_INTEGER *li) { - if (!tsc_freq) init_tsc_freq(); - unsigned long long tsc = __rdtsc(); - // convert to microseconds - li->QuadPart = (tsc * 1000000ULL) / tsc_freq; +BOOL g_QpcInitialized = FALSE; +LARGE_INTEGER g_QpcFrequency; + +static constexpr unsigned long long MS_PER_SECOND = 1000; + +static unsigned long long g_TicksPerMs = 0; + +BOOL QueryPerformanceFrequency(LARGE_INTEGER* lpFrequency) +{ + if (!lpFrequency) + return FALSE; + + if (g_QpcInitialized) + { + *lpFrequency = g_QpcFrequency; + return TRUE; + } + + // 1. Calibrate for 1 full second to get accurate Ticks Per Second + // gBS->Stall takes microseconds (1,000,000 us = 1 second) + unsigned long long tscStart = read_tsc(); + gBS->Stall(1000000); + unsigned long long tscEnd = read_tsc(); + + unsigned long long ticksPerSecond = tscEnd - tscStart; + + // 2. Set the "TicksPerMs" for our Counter to use later + g_TicksPerMs = ticksPerSecond / MS_PER_SECOND; + + // 3. Set Frequency to 1000. + // This tells the engine: "One unit in QPC equals 1/1000th of a second (1ms)" + g_QpcFrequency.QuadPart = MS_PER_SECOND; + + *lpFrequency = g_QpcFrequency; + g_QpcInitialized = TRUE; return TRUE; } -BOOL QueryPerformanceFrequency(LARGE_INTEGER *li) { - if (!tsc_freq) init_tsc_freq(); - // frequency in Hz (ticks per second) - li->QuadPart = 1000000ULL; // since we convert to µs above +BOOL QueryPerformanceCounter(LARGE_INTEGER* lpPerformanceCount) +{ + if (!lpPerformanceCount || g_TicksPerMs == 0) + return FALSE; + + // Now QPC returns the number of milliseconds that have passed. + // Because Frequency is 1000, 1000 "counts" = 1 second. Perfectly synced. + lpPerformanceCount->QuadPart = read_tsc() / g_TicksPerMs; + return TRUE; } diff --git a/main.cpp b/main.cpp index 50cd1fe..e4706a5 100644 --- a/main.cpp +++ b/main.cpp @@ -1,207 +1,13 @@ #include #include -#include #include #include -#include "bink.h" #include "print.h" - -#pragma region - -// Macro to define function pointer and global variable -#define DECL_FN(ret, name, args, ptr) typedef ret (__cdecl *name##_t) args; name##_t p##name = NULL; - -DECL_FN(void *, BinkLogoAddress, (void), ) -DECL_FN(void, BinkSetError, (char const * err), *) -DECL_FN(char *, BinkGetError, (void), ) -DECL_FN(HBINK, BinkOpen, (char const * name, U32 flags), *) -DECL_FN(HBINK, BinkOpenWithOptions, (char const * name, BINK_OPEN_OPTIONS const * boo, U32 flags), *) -DECL_FN(void, BinkGetFrameBuffersInfo, (HBINK bink, BINKFRAMEBUFFERS * fbset), *) -DECL_FN(void, BinkRegisterFrameBuffers, (HBINK bink, BINKFRAMEBUFFERS * fbset), *) -DECL_FN(S32, BinkDoFrame, (HBINK bnk), *) -DECL_FN(S32, BinkDoFramePlane, (HBINK bnk, U32 which_planes), *) -DECL_FN(void, BinkNextFrame, (HBINK bnk), *) -DECL_FN(S32, BinkWait, (HBINK bnk), *) -DECL_FN(void, BinkClose, (HBINK bnk), *) -DECL_FN(S32, BinkPause, (HBINK bnk, S32 pause), *) -DECL_FN(S32, BinkCopyToBuffer, (HBINK bnk, void* dest, S32 destpitch, U32 destheight, U32 destx, U32 desty, U32 flags), *) -DECL_FN(S32, BinkCopyToBufferRect, (HBINK bnk, void* dest, S32 destpitch, U32 destheight, U32 destx, U32 desty, U32 srcx, U32 srcy, U32 srcw, U32 srch, U32 flags), *) -DECL_FN(S32, BinkGetRects, (HBINK bnk, U32 flags), *) -DECL_FN(void, BinkGoto, (HBINK bnk, U32 frame, S32 flags), *) -DECL_FN(U32, BinkGetKeyFrame, (HBINK bnk, U32 frame, S32 flags), *) -DECL_FN(void, BinkFreeGlobals, (void), *) -DECL_FN(S32, BinkGetPlatformInfo, (S32 bink_platform_enum, void * output), *) -DECL_FN(void, BinkRegisterGPUDataBuffers, (HBINK bink, BINKGPUDATABUFFERS * gpu), *) -DECL_FN(S32, BinkGetGPUDataBuffersInfo, (HBINK bink, BINKGPUDATABUFFERS * gpu), *) -DECL_FN(S32, BinkSetVideoOnOff, (HBINK bnk, S32 onoff), *) -DECL_FN(S32, BinkSetSoundOnOff, (HBINK bnk, S32 onoff), *) -DECL_FN(void, BinkSetVolume, (HBINK bnk, U32 trackid, S32 volume), *) -DECL_FN(void, BinkSetPan, (HBINK bnk, U32 trackid, S32 pan), *) -DECL_FN(void, BinkSetSpeakerVolumes, (HBINK bnk, U32 trackid, U32 * speaker_indexes, S32 * volumes, U32 total), *) -DECL_FN(void, BinkService, (HBINK bink), *) -DECL_FN(S32, BinkShouldSkip, (HBINK bink), *) -DECL_FN(S32, BinkControlBackgroundIO, (HBINK bink, U32 control), *) -DECL_FN(void, BinkSetWillLoop, (HBINK bink, S32 onoff), *) -DECL_FN(S32, BinkStartAsyncThread, (S32 thread_num, void const * param), *) -DECL_FN(S32, BinkDoFrameAsync, (HBINK bink, U32 thread_one, U32 thread_two), *) -DECL_FN(S32, BinkDoFrameAsyncMulti, (HBINK bink, U32* threads, S32 thread_count), *) -DECL_FN(S32, BinkDoFrameAsyncWait, (HBINK bink, S32 us), *) -DECL_FN(S32, BinkRequestStopAsyncThread, (S32 thread_num), *) -DECL_FN(S32, BinkWaitStopAsyncThread, (S32 thread_num), *) -DECL_FN(HBINKTRACK, BinkOpenTrack, (HBINK bnk, U32 trackindex), *) -DECL_FN(void, BinkCloseTrack, (HBINKTRACK bnkt), *) -DECL_FN(U32, BinkGetTrackData, (HBINKTRACK bnkt, void * dest), *) -DECL_FN(U32, BinkGetTrackType, (HBINK bnk, U32 trackindex), *) -DECL_FN(U32, BinkGetTrackMaxSize, (HBINK bnk, U32 trackindex), *) -DECL_FN(U32, BinkGetTrackID, (HBINK bnk, U32 trackindex), *) -DECL_FN(void, BinkGetSummary, (HBINK bnk, BINKSUMMARY * sum), *) -DECL_FN(void, BinkGetRealtime, (HBINK bink, BINKREALTIME * run, U32 frames), *) -DECL_FN(void, BinkSetFileOffset, (U64 offset), *) -DECL_FN(void, BinkSetSoundTrack, (U32 total_tracks, U32 * tracks), *) -DECL_FN(void, BinkSetIO, (BINKIOOPEN io), *) -DECL_FN(void, BinkSetFrameRate, (U32 forcerate, U32 forceratediv), *) -DECL_FN(void, BinkSetSimulate, (U32 sim), *) -DECL_FN(void, BinkSetIOSize, (U32 iosize), *) -DECL_FN(S32, BinkSetSoundSystem, (BINKSNDSYSOPEN open, UINTa param), *) -DECL_FN(S32, BinkSetSoundSystem2, (BINKSNDSYSOPEN2 open, UINTa param1, UINTa param2), *) -DECL_FN(BINKSNDOPEN, BinkOpenDirectSound, (UINTa param), *) -DECL_FN(BINKSNDOPEN, BinkOpenWaveOut, (UINTa param), *) -DECL_FN(BINKSNDOPEN, BinkOpenXAudio2, (UINTa param), *) -DECL_FN(void, BinkSetMemory, (BINKMEMALLOC a, BINKMEMFREE f), *) - -#pragma endregion -#pragma region +#include "take_care_of_bink.h" EFI_GRAPHICS_OUTPUT_PROTOCOL* gop; -EFI_GRAPHICS_OUTPUT_BLT_PIXEL* framebuffer; EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* mode_info; -struct BlockHeader { - uint32_t magic; - size_t size; - bool free; - BlockHeader* next; -}; - -constexpr uint32_t MAGIC_ALLOCATED = 0xCAFEBABE; -constexpr uint32_t MAGIC_FREED = 0xDEADBEEF; - -static void* g_memoryPool = 0; -static size_t g_poolSize = 0; -static struct BlockHeader* g_freeList = 0; - -#define AVX_ALIGN 32 -#define ALIGN_UP(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) - -void InitAllocatorFromBuffer(void* buffer, size_t size) { - PRINT(L"Initializing custom allocator with buffer %p of size %ull\n", buffer, size); - if (!buffer || size <= sizeof(struct BlockHeader)) { - Print(L"Invalid buffer or size for allocator initialization\n"); - gBS->Stall(5 * 1000000); // 5 seconds - gRT->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL); - } - - g_memoryPool = buffer; - g_poolSize = size; - - g_freeList = (struct BlockHeader*)buffer; - g_freeList->magic = MAGIC_ALLOCATED; - g_freeList->size = size - sizeof(struct BlockHeader); - g_freeList->free = true; - g_freeList->next = 0; -} - -static bool IsPointerInPool(void* ptr) { - return ptr >= g_memoryPool && - ptr < (void*)((uint8_t*)g_memoryPool + g_poolSize); -} - -void* Malloc(size_t size) { - PRINT(L"Allocating memory of size %llu, ptr = ", size); - size = ALIGN_UP(size, AVX_ALIGN); // ensure AVX alignment - struct BlockHeader* best = 0; - struct BlockHeader* bestPrev = 0; - struct BlockHeader* prev = 0; - struct BlockHeader* current = g_freeList; - - while (current) { - if (current->free && current->size >= size) { - if (!best || current->size < best->size) { - best = current; - bestPrev = prev; - } - } - prev = current; - current = current->next; - } - - if (!best) { - PRINT(L"NULL\n"); - return 0; - } - - uintptr_t payloadAddr = (uintptr_t)(best + 1); - uintptr_t alignedAddr = ALIGN_UP(payloadAddr, AVX_ALIGN); - size_t padding = alignedAddr - payloadAddr; - - size_t totalNeeded = size + padding; - if (best->size < totalNeeded) { - PRINT(L"NULL not enough space\n"); - return 0; // not enough space - } - - size_t remaining = best->size - totalNeeded; - - if (remaining > sizeof(struct BlockHeader)) { - struct BlockHeader* newBlock = (struct BlockHeader*)((uint8_t*)(best + 1) + totalNeeded); - newBlock->magic = MAGIC_ALLOCATED; - newBlock->size = remaining - sizeof(struct BlockHeader); - newBlock->free = true; - newBlock->next = best->next; - best->next = newBlock; - } - - best->magic = MAGIC_ALLOCATED; - best->free = false; - best->size = totalNeeded; - - PRINT(L"%p\n", (void*)alignedAddr); - return (void*)alignedAddr; -} - -void Free(void* ptr) { - PRINT(L"Freeing memory at %p\n", ptr); - if (!ptr || !IsPointerInPool(ptr)) return; - - struct BlockHeader* block = (struct BlockHeader*)((uint8_t*)ptr - sizeof(struct BlockHeader)); - - while (block->magic != MAGIC_ALLOCATED && (uint8_t*)block > (uint8_t*)g_memoryPool) { - block = (struct BlockHeader*)((uint8_t*)block - 1); // backtrack if pointer was aligned forward - } - - if (!IsPointerInPool(block) || block->magic != MAGIC_ALLOCATED) { - Print(L"Invalid pointer passed to Free: %p\n", ptr); - return; - } - - block->magic = MAGIC_FREED; - block->free = true; - - // Coalesce - struct BlockHeader* current = g_freeList; - while (current) { - if (current->free) { - struct BlockHeader* next = current->next; - while (next && next->free) { - current->size += sizeof(struct BlockHeader) + next->size; - current->next = next->next; - next = next->next; - } - } - current = current->next; - } -} - EFI_STATUS InitializeGop() { EFI_STATUS Status; @@ -214,7 +20,6 @@ EFI_STATUS InitializeGop() { // 2. Get framebuffer information mode_info = gop->Mode->Info; - framebuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL*)gop->Mode->FrameBufferBase; // yeah yeah blah blah return EFI_SUCCESS; } @@ -285,291 +90,6 @@ void* LoadFile(EFI_FILE_HANDLE volume, const wchar_t* filename) { return file_buffer; } -#pragma endregion -#pragma region - -#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b -#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 -#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 -#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 -#define IMAGE_ORDINAL_FLAG64 0x8000000000000000ULL - -#pragma pack(push, 1) -typedef struct IMAGE_OPTIONAL_HEADER64 { - uint16_t Magic; - uint8_t MajorLinkerVersion; - uint8_t MinorLinkerVersion; - uint32_t SizeOfCode; - uint32_t SizeOfInitializedData; - uint32_t SizeOfUninitializedData; - uint32_t AddressOfEntryPoint; - uint32_t BaseOfCode; - uint64_t ImageBase; - uint32_t SectionAlignment; - uint32_t FileAlignment; - uint16_t MajorOperatingSystemVersion; - uint16_t MinorOperatingSystemVersion; - uint16_t MajorImageVersion; - uint16_t MinorImageVersion; - uint16_t MajorSubsystemVersion; - uint16_t MinorSubsystemVersion; - uint32_t Win32VersionValue; - uint32_t SizeOfImage; - uint32_t SizeOfHeaders; - uint32_t CheckSum; - uint16_t Subsystem; - uint16_t DllCharacteristics; - uint64_t SizeOfStackReserve; - uint64_t SizeOfStackCommit; - uint64_t SizeOfHeapReserve; - uint64_t SizeOfHeapCommit; - uint32_t LoaderFlags; - uint32_t NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; -} __attribute__((packed)) IMAGE_OPTIONAL_HEADER64; - -typedef struct IMAGE_NT_HEADERS64 { - uint32_t Signature; - struct { - uint16_t Machine; - uint16_t NumberOfSections; - uint32_t TimeDateStamp; - uint32_t PointerToSymbolTable; - uint32_t NumberOfSymbols; - uint16_t SizeOfOptionalHeader; - uint16_t Characteristics; - } FileHeader; - IMAGE_OPTIONAL_HEADER64 OptionalHeader; -} __attribute__((packed)) IMAGE_NT_HEADERS64; - -typedef struct _IMAGE_IMPORT_BY_NAME { - uint16_t Hint; - char Name[1]; -} __attribute__((packed)) IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; - -typedef struct _IMAGE_THUNK_DATA64 { - union { - uint64_t ForwarderString; - uint64_t Function; - uint64_t Ordinal; - uint64_t AddressOfData; - } u1; -} __attribute__((packed)) IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64; - -typedef struct _IMAGE_IMPORT_DESCRIPTOR { - union { - uint32_t Characteristics; - uint32_t OriginalFirstThunk; - } u1; - uint32_t TimeDateStamp; - uint32_t ForwarderChain; - uint32_t Name; - uint32_t FirstThunk; -} __attribute__((packed)) IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; - -typedef struct _IMAGE_EXPORT_DIRECTORY { - uint32_t Characteristics; - uint32_t TimeDateStamp; - uint16_t MajorVersion; - uint16_t MinorVersion; - uint32_t Name; - uint32_t Base; - uint32_t NumberOfFunctions; - uint32_t NumberOfNames; - uint32_t AddressOfFunctions; - uint32_t AddressOfNames; - uint32_t AddressOfNameOrdinals; -} __attribute__((packed)) IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; -#pragma pack(pop) - -int stricmp(const char *s1, const char *s2) { while (*s1 && ((*s1 | 0x20) == (*s2 | 0x20))) { s1++; s2++; } return *(const unsigned char*)s1 - *(const unsigned char*)s2; } - -extern void* ResolveUser32(const char* functionName); -extern void* ResolveKernel32(const char* functionName); -extern void* ResolveOle32(const char* functionName); -extern void* ResolveWinMM(const char* functionName); - -void* ResolveImport(const char* dllName, const char* functionName) { - // user32 - if (stricmp(dllName, "user32.dll") == 0) { - return ResolveUser32(functionName); - } else if (stricmp(dllName, "kernel32.dll") == 0) { - return ResolveKernel32(functionName); - } else if (stricmp(dllName, "ole32.dll") == 0) { - return ResolveOle32(functionName); - } else if (stricmp(dllName, "winmm.dll") == 0) { - return ResolveWinMM(functionName); - } - - // If the import is not a known dependency, print an error - Print(L"Unknown dll: %a\n", dllName); - return NULL; -} - -void* GetExportByName(void* imageBase, const char* functionName) { - if (!imageBase || !functionName) return NULL; - - uint8_t* base = (uint8_t*)imageBase; - IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)base; - IMAGE_NT_HEADERS64* pe = (IMAGE_NT_HEADERS64*)(base + dos->e_lfanew); - - // Get the export directory - IMAGE_DATA_DIRECTORY exportDirEntry = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; - if (exportDirEntry.Size == 0) { - return NULL; // No export directory - } - - IMAGE_EXPORT_DIRECTORY* exportDir = (IMAGE_EXPORT_DIRECTORY*)(base + exportDirEntry.VirtualAddress); - - // Get pointers to the key tables - uint32_t* names = (uint32_t*)(base + exportDir->AddressOfNames); - uint32_t* functions = (uint32_t*)(base + exportDir->AddressOfFunctions); - uint16_t* ordinals = (uint16_t*)(base + exportDir->AddressOfNameOrdinals); - - // Search for the function by name - for (uint32_t i = 0; i < exportDir->NumberOfNames; i++) { - const char* currentName = (const char*)(base + names[i]); - if (stricmp(functionName, currentName) == 0) { - // Name found, get the ordinal - uint16_t ordinal = ordinals[i]; - // Use the ordinal to find the function's RVA - uint32_t functionRva = functions[ordinal]; - // Return the absolute address - return (void*)(base + functionRva); - } - } - - return NULL; // Function not found -} - -void* LoadPeImage(void* buffer) { - uint8_t* data = (uint8_t*)buffer; - IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)data; - if (dos->e_magic != IMAGE_DOS_SIGNATURE) { - Print(L"Invalid MZ header\n"); - return NULL; - } - - IMAGE_NT_HEADERS64* pe = (IMAGE_NT_HEADERS64*)(data + dos->e_lfanew); - if (pe->Signature != IMAGE_NT_SIGNATURE) { - Print(L"Invalid PE header\n"); - return NULL; - } - - if (pe->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - Print(L"Not PE32+\n"); - return NULL; - } - - // Allocate memory for the full image - uint64_t imageSize = pe->OptionalHeader.SizeOfImage; - uint64_t imageBase = (uint64_t)Malloc(imageSize); - if (!imageBase) { - Print(L"Failed to allocate image memory\n"); - return NULL; - } - - ZeroMem((void*)imageBase, imageSize); - - // Copy headers - CopyMem((void*)imageBase, data, pe->OptionalHeader.SizeOfHeaders); - - // Copy each section - IMAGE_SECTION_HEADER* sections = (IMAGE_SECTION_HEADER*)((uint8_t*)&pe->OptionalHeader + pe->FileHeader.SizeOfOptionalHeader); - for (uint64_t i = 0; i < pe->FileHeader.NumberOfSections; i++) { - void* dest = (void*)(imageBase + sections[i].VirtualAddress); - void* src = (void*)(data + sections[i].PointerToRawData); - uint64_t size = sections[i].SizeOfRawData; - if (size > 0) { - CopyMem(dest, src, size); - } - } - - // Relocation - uint64_t imageDelta = imageBase - pe->OptionalHeader.ImageBase; - if (imageDelta != 0 && pe->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC) { - IMAGE_DATA_DIRECTORY relocDir = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; - if (relocDir.Size > 0) { - uint8_t* relocBase = (uint8_t*)(imageBase + relocDir.VirtualAddress); - uint8_t* relocEnd = relocBase + relocDir.Size; - - while (relocBase < relocEnd) { - IMAGE_BASE_RELOCATION* rel = (IMAGE_BASE_RELOCATION*)relocBase; - if (rel->SizeOfBlock < sizeof(IMAGE_BASE_RELOCATION)) { - Print(L"Relocation block too small at %p\n", rel); - return NULL; - } - uint64_t entryCount = (rel->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(uint16_t); - uint16_t* relocs = (uint16_t*)(rel + 1); - - for (uint64_t i = 0; i < entryCount; i++) { - uint16_t entry = relocs[i]; - uint16_t type = entry >> 12; - uint16_t offset = entry & 0xFFF; - - if (type == IMAGE_REL_BASED_DIR64) { - uint64_t* patchAddr = (uint64_t*)(imageBase + rel->VirtualAddress + offset); - // Check patchAddr is within image - if ((uintptr_t)patchAddr < imageBase || (uintptr_t)patchAddr >= imageBase + imageSize) { - Print(L"Relocation address out of bounds: %p\n", patchAddr); - return NULL; - } - *patchAddr += imageDelta; - } else if (type != 0) { - Print(L"Unknown relocation type %u at RVA %x\n", type, (unsigned)(rel->VirtualAddress + offset)); - return NULL; - } - } - relocBase += rel->SizeOfBlock; - } - } - } - - if (pe->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IMPORT) { - IMAGE_DATA_DIRECTORY importDirEntry = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; - if (importDirEntry.Size > 0) { - IMAGE_IMPORT_DESCRIPTOR* importDesc = (IMAGE_IMPORT_DESCRIPTOR*)(imageBase + importDirEntry.VirtualAddress); - - // Iterate over each DLL descriptor - while (importDesc->Name != 0) { - const char* dllName = (const char*)(imageBase + importDesc->Name); - IMAGE_THUNK_DATA64* thunkINT = (IMAGE_THUNK_DATA64*)(imageBase + importDesc->u1.OriginalFirstThunk); - IMAGE_THUNK_DATA64* thunkIAT = (IMAGE_THUNK_DATA64*)(imageBase + importDesc->FirstThunk); - - // Iterate over each function in the DLL - while (thunkINT->u1.AddressOfData != 0) { - void* funcPtr = NULL; - if (thunkINT->u1.Ordinal & IMAGE_ORDINAL_FLAG64) { - // Import by ordinal - your ResolveImport doesn't support this - Print(L"Import by ordinal is not supported.\n"); - return NULL; - } else { - // Import by name - IMAGE_IMPORT_BY_NAME* importByName = (IMAGE_IMPORT_BY_NAME*)(imageBase + thunkINT->u1.AddressOfData); - const char* funcName = importByName->Name; - funcPtr = ResolveImport(dllName, funcName); - - if (!funcPtr) { - Print(L"Failed to resolve import: %a -> %a\n", dllName, importByName->Name); - return NULL; - } - } - - // Write the resolved address into the IAT - thunkIAT->u1.Function = (uint64_t)funcPtr; - - thunkINT++; - thunkIAT++; - } - importDesc++; // Move to the next DLL - } - } - } - - // Return base - return (void*)imageBase; -} - bool LoadBinkDLL(EFI_FILE_HANDLE volume) { void* binkFileBuffer = LoadFile(volume, L"bink2w64.dll"); if (!binkFileBuffer) { @@ -647,7 +167,6 @@ bool LoadBinkDLL(EFI_FILE_HANDLE volume) { #undef GRAB return true; } -#pragma endregion void Blit_AVX2_NT( EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop, @@ -780,15 +299,15 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable) { return 1; } - Print(L"Bink function pointers initialized (propably)!\n"); + Print(L"Bink function pointers initialized!\n"); //pBinkSetSoundSystem(pBinkOpenWaveOut, 0); - pBinkSetMemory((BINKMEMALLOC)Malloc, (BINKMEMFREE)Free); // debug allocators + pBinkSetMemory((BINKMEMALLOC)Malloc, (BINKMEMFREE)Free); pBinkSetIO(0); // no io Print(L"BinkSet* called\n"); - void* video_file = LoadFile(volume, L"video.bk2"); + void* video_file = LoadFile(volume, L"idk.bk2"); Print(L"Video file loaded into memory\n"); @@ -811,7 +330,6 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable) { Print(L"Framebuffer allocated!\n"); - size_t skipped_frames = 0; EFI_INPUT_KEY key; bool paused = false; @@ -847,7 +365,6 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable) { // Check if we should skip the frame if (pBinkShouldSkip(bink)) { pBinkNextFrame(bink); - skipped_frames++; continue; // skip this frame } @@ -871,7 +388,7 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable) { 0, BINKSURFACE32 | BINKCOPYALL ); - if (code != 0 && code != 1) { + if (code != 0 && code != 1) { // who knows what they mean Print(L"BinkCopyToBuffer failed!\n"); pBinkClose(bink); Free(video_file); @@ -884,13 +401,10 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable) { Blit_AVX2_NT(gop, framebuffer, width, height); - Print(L"\rframe %d done ", bink->FrameNum); // oh yeah it can go down now so we have to account for that + if (bink->FrameNum % 10 == 0) + Print(L"\rframe %d done ", bink->FrameNum); } - Print(L"\nSkipped frames: %u\n", skipped_frames); - if (skipped_frames < 10) - Print(L"That's pretty damn good!\n"); - pBinkClose(bink); Free(video_file); diff --git a/take_care_of_bink.cpp b/take_care_of_bink.cpp new file mode 100644 index 0000000..d33198e --- /dev/null +++ b/take_care_of_bink.cpp @@ -0,0 +1,413 @@ +#include +#include +#include +#include "bink.h" +#include "print.h" + +struct BlockHeader { + uint32_t magic; + size_t size; + bool free; + BlockHeader* next; +}; + +constexpr uint32_t MAGIC_ALLOCATED = 0xCAFEBABE; +constexpr uint32_t MAGIC_FREED = 0xDEADBEEF; + +static void* g_memoryPool = 0; +static size_t g_poolSize = 0; +static struct BlockHeader* g_freeList = 0; + +#define AVX_ALIGN 32 +#define ALIGN_UP(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) + +void InitAllocatorFromBuffer(void* buffer, size_t size) { + PRINT(L"Initializing custom allocator with buffer %p of size %ull\n", buffer, size); + if (!buffer || size <= sizeof(struct BlockHeader)) { + Print(L"Invalid buffer or size for allocator initialization\n"); + gBS->Stall(5 * 1000000); // 5 seconds + gRT->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL); + } + + g_memoryPool = buffer; + g_poolSize = size; + + g_freeList = (struct BlockHeader*)buffer; + g_freeList->magic = MAGIC_ALLOCATED; + g_freeList->size = size - sizeof(struct BlockHeader); + g_freeList->free = true; + g_freeList->next = 0; +} + +static bool IsPointerInPool(void* ptr) { + return ptr >= g_memoryPool && + ptr < (void*)((uint8_t*)g_memoryPool + g_poolSize); +} + +void* Malloc(size_t size) { + PRINT(L"Allocating memory of size %llu, ptr = ", size); + size = ALIGN_UP(size, AVX_ALIGN); // ensure AVX alignment + struct BlockHeader* best = 0; + struct BlockHeader* bestPrev = 0; + struct BlockHeader* prev = 0; + struct BlockHeader* current = g_freeList; + + while (current) { + if (current->free && current->size >= size) { + if (!best || current->size < best->size) { + best = current; + bestPrev = prev; + } + } + prev = current; + current = current->next; + } + + if (!best) { + PRINT(L"NULL\n"); + return 0; + } + + uintptr_t payloadAddr = (uintptr_t)(best + 1); + uintptr_t alignedAddr = ALIGN_UP(payloadAddr, AVX_ALIGN); + size_t padding = alignedAddr - payloadAddr; + + size_t totalNeeded = size + padding; + if (best->size < totalNeeded) { + PRINT(L"NULL not enough space\n"); + return 0; // not enough space + } + + size_t remaining = best->size - totalNeeded; + + if (remaining > sizeof(struct BlockHeader)) { + struct BlockHeader* newBlock = (struct BlockHeader*)((uint8_t*)(best + 1) + totalNeeded); + newBlock->magic = MAGIC_ALLOCATED; + newBlock->size = remaining - sizeof(struct BlockHeader); + newBlock->free = true; + newBlock->next = best->next; + best->next = newBlock; + } + + best->magic = MAGIC_ALLOCATED; + best->free = false; + best->size = totalNeeded; + + PRINT(L"%p\n", (void*)alignedAddr); + return (void*)alignedAddr; +} + +void Free(void* ptr) { + PRINT(L"Freeing memory at %p\n", ptr); + if (!ptr || !IsPointerInPool(ptr)) return; + + struct BlockHeader* block = (struct BlockHeader*)((uint8_t*)ptr - sizeof(struct BlockHeader)); + + while (block->magic != MAGIC_ALLOCATED && (uint8_t*)block > (uint8_t*)g_memoryPool) { + block = (struct BlockHeader*)((uint8_t*)block - 1); // backtrack if pointer was aligned forward + } + + if (!IsPointerInPool(block) || block->magic != MAGIC_ALLOCATED) { + Print(L"Invalid pointer passed to Free: %p\n", ptr); + return; + } + + block->magic = MAGIC_FREED; + block->free = true; + + // Coalesce + struct BlockHeader* current = g_freeList; + while (current) { + if (current->free) { + struct BlockHeader* next = current->next; + while (next && next->free) { + current->size += sizeof(struct BlockHeader) + next->size; + current->next = next->next; + next = next->next; + } + } + current = current->next; + } +} + +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 +#define IMAGE_ORDINAL_FLAG64 0x8000000000000000ULL + +#pragma pack(push, 1) +typedef struct IMAGE_OPTIONAL_HEADER64 { + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint64_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Win32VersionValue; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint64_t SizeOfStackReserve; + uint64_t SizeOfStackCommit; + uint64_t SizeOfHeapReserve; + uint64_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} __attribute__((packed)) IMAGE_OPTIONAL_HEADER64; + +typedef struct IMAGE_NT_HEADERS64 { + uint32_t Signature; + struct { + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; + } FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; +} __attribute__((packed)) IMAGE_NT_HEADERS64; + +typedef struct _IMAGE_IMPORT_BY_NAME { + uint16_t Hint; + char Name[1]; +} __attribute__((packed)) IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA64 { + union { + uint64_t ForwarderString; + uint64_t Function; + uint64_t Ordinal; + uint64_t AddressOfData; + } u1; +} __attribute__((packed)) IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64; + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + union { + uint32_t Characteristics; + uint32_t OriginalFirstThunk; + } u1; + uint32_t TimeDateStamp; + uint32_t ForwarderChain; + uint32_t Name; + uint32_t FirstThunk; +} __attribute__((packed)) IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; + +typedef struct _IMAGE_EXPORT_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t AddressOfFunctions; + uint32_t AddressOfNames; + uint32_t AddressOfNameOrdinals; +} __attribute__((packed)) IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; +#pragma pack(pop) + +int stricmp(const char *s1, const char *s2) { while (*s1 && ((*s1 | 0x20) == (*s2 | 0x20))) { s1++; s2++; } return *(const unsigned char*)s1 - *(const unsigned char*)s2; } + +extern void* ResolveUser32(const char* functionName); +extern void* ResolveKernel32(const char* functionName); +extern void* ResolveOle32(const char* functionName); +extern void* ResolveWinMM(const char* functionName); + +void* ResolveImport(const char* dllName, const char* functionName) { + // user32 + if (stricmp(dllName, "user32.dll") == 0) { + return ResolveUser32(functionName); + } else if (stricmp(dllName, "kernel32.dll") == 0) { + return ResolveKernel32(functionName); + } else if (stricmp(dllName, "ole32.dll") == 0) { + return ResolveOle32(functionName); + } else if (stricmp(dllName, "winmm.dll") == 0) { + return ResolveWinMM(functionName); + } + + // If the import is not a known dependency, print an error + Print(L"Unknown dll: %a\n", dllName); + return NULL; +} + +void* GetExportByName(void* imageBase, const char* functionName) { + if (!imageBase || !functionName) return NULL; + + uint8_t* base = (uint8_t*)imageBase; + IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)base; + IMAGE_NT_HEADERS64* pe = (IMAGE_NT_HEADERS64*)(base + dos->e_lfanew); + + // Get the export directory + IMAGE_DATA_DIRECTORY exportDirEntry = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + if (exportDirEntry.Size == 0) { + return NULL; // No export directory + } + + IMAGE_EXPORT_DIRECTORY* exportDir = (IMAGE_EXPORT_DIRECTORY*)(base + exportDirEntry.VirtualAddress); + + // Get pointers to the key tables + uint32_t* names = (uint32_t*)(base + exportDir->AddressOfNames); + uint32_t* functions = (uint32_t*)(base + exportDir->AddressOfFunctions); + uint16_t* ordinals = (uint16_t*)(base + exportDir->AddressOfNameOrdinals); + + // Search for the function by name + for (uint32_t i = 0; i < exportDir->NumberOfNames; i++) { + const char* currentName = (const char*)(base + names[i]); + if (stricmp(functionName, currentName) == 0) { + // Name found, get the ordinal + uint16_t ordinal = ordinals[i]; + // Use the ordinal to find the function's RVA + uint32_t functionRva = functions[ordinal]; + // Return the absolute address + return (void*)(base + functionRva); + } + } + + return NULL; // Function not found +} + +void* LoadPeImage(void* buffer) { + uint8_t* data = (uint8_t*)buffer; + IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)data; + if (dos->e_magic != IMAGE_DOS_SIGNATURE) { + Print(L"Invalid MZ header\n"); + return NULL; + } + + IMAGE_NT_HEADERS64* pe = (IMAGE_NT_HEADERS64*)(data + dos->e_lfanew); + if (pe->Signature != IMAGE_NT_SIGNATURE) { + Print(L"Invalid PE header\n"); + return NULL; + } + + if (pe->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + Print(L"Not PE32+\n"); + return NULL; + } + + // Allocate memory for the full image + uint64_t imageSize = pe->OptionalHeader.SizeOfImage; + uint64_t imageBase = (uint64_t)Malloc(imageSize); + if (!imageBase) { + Print(L"Failed to allocate image memory\n"); + return NULL; + } + + ZeroMem((void*)imageBase, imageSize); + + // Copy headers + CopyMem((void*)imageBase, data, pe->OptionalHeader.SizeOfHeaders); + + // Copy each section + IMAGE_SECTION_HEADER* sections = (IMAGE_SECTION_HEADER*)((uint8_t*)&pe->OptionalHeader + pe->FileHeader.SizeOfOptionalHeader); + for (uint64_t i = 0; i < pe->FileHeader.NumberOfSections; i++) { + void* dest = (void*)(imageBase + sections[i].VirtualAddress); + void* src = (void*)(data + sections[i].PointerToRawData); + uint64_t size = sections[i].SizeOfRawData; + if (size > 0) { + CopyMem(dest, src, size); + } + } + + // Relocation + uint64_t imageDelta = imageBase - pe->OptionalHeader.ImageBase; + if (imageDelta != 0 && pe->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC) { + IMAGE_DATA_DIRECTORY relocDir = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; + if (relocDir.Size > 0) { + uint8_t* relocBase = (uint8_t*)(imageBase + relocDir.VirtualAddress); + uint8_t* relocEnd = relocBase + relocDir.Size; + + while (relocBase < relocEnd) { + IMAGE_BASE_RELOCATION* rel = (IMAGE_BASE_RELOCATION*)relocBase; + if (rel->SizeOfBlock < sizeof(IMAGE_BASE_RELOCATION)) { + Print(L"Relocation block too small at %p\n", rel); + return NULL; + } + uint64_t entryCount = (rel->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(uint16_t); + uint16_t* relocs = (uint16_t*)(rel + 1); + + for (uint64_t i = 0; i < entryCount; i++) { + uint16_t entry = relocs[i]; + uint16_t type = entry >> 12; + uint16_t offset = entry & 0xFFF; + + if (type == IMAGE_REL_BASED_DIR64) { + uint64_t* patchAddr = (uint64_t*)(imageBase + rel->VirtualAddress + offset); + // Check patchAddr is within image + if ((uintptr_t)patchAddr < imageBase || (uintptr_t)patchAddr >= imageBase + imageSize) { + Print(L"Relocation address out of bounds: %p\n", patchAddr); + return NULL; + } + *patchAddr += imageDelta; + } else if (type != 0) { + Print(L"Unknown relocation type %u at RVA %x\n", type, (unsigned)(rel->VirtualAddress + offset)); + return NULL; + } + } + relocBase += rel->SizeOfBlock; + } + } + } + + if (pe->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IMPORT) { + IMAGE_DATA_DIRECTORY importDirEntry = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + if (importDirEntry.Size > 0) { + IMAGE_IMPORT_DESCRIPTOR* importDesc = (IMAGE_IMPORT_DESCRIPTOR*)(imageBase + importDirEntry.VirtualAddress); + + // Iterate over each DLL descriptor + while (importDesc->Name != 0) { + const char* dllName = (const char*)(imageBase + importDesc->Name); + IMAGE_THUNK_DATA64* thunkINT = (IMAGE_THUNK_DATA64*)(imageBase + importDesc->u1.OriginalFirstThunk); + IMAGE_THUNK_DATA64* thunkIAT = (IMAGE_THUNK_DATA64*)(imageBase + importDesc->FirstThunk); + + // Iterate over each function in the DLL + while (thunkINT->u1.AddressOfData != 0) { + void* funcPtr = NULL; + if (thunkINT->u1.Ordinal & IMAGE_ORDINAL_FLAG64) { + // Import by ordinal - your ResolveImport doesn't support this + Print(L"Import by ordinal is not supported.\n"); + return NULL; + } else { + // Import by name + IMAGE_IMPORT_BY_NAME* importByName = (IMAGE_IMPORT_BY_NAME*)(imageBase + thunkINT->u1.AddressOfData); + const char* funcName = importByName->Name; + funcPtr = ResolveImport(dllName, funcName); + + if (!funcPtr) { + Print(L"Failed to resolve import: %a -> %a\n", dllName, importByName->Name); + return NULL; + } + } + + // Write the resolved address into the IAT + thunkIAT->u1.Function = (uint64_t)funcPtr; + + thunkINT++; + thunkIAT++; + } + importDesc++; // Move to the next DLL + } + } + } + + // Return base + return (void*)imageBase; +} diff --git a/take_care_of_bink.h b/take_care_of_bink.h new file mode 100644 index 0000000..4f44b1d --- /dev/null +++ b/take_care_of_bink.h @@ -0,0 +1,71 @@ +#pragma once +#include "bink.h" + +void InitAllocatorFromBuffer(void* buffer, size_t size); +void* Malloc(size_t size); +void Free(void* ptr); + +void* LoadPeImage(void* peBuffer); +void* GetExportByName(void* imageBase, const char* functionName); + +#define DECL_FN(ret, name, args, ptr) typedef ret (__cdecl *name##_t) args; extern name##_t p##name = NULL; + +DECL_FN(void *, BinkLogoAddress, (void), ) +DECL_FN(void, BinkSetError, (char const * err), *) +DECL_FN(char *, BinkGetError, (void), ) +DECL_FN(HBINK, BinkOpen, (char const * name, U32 flags), *) +DECL_FN(HBINK, BinkOpenWithOptions, (char const * name, BINK_OPEN_OPTIONS const * boo, U32 flags), *) +DECL_FN(void, BinkGetFrameBuffersInfo, (HBINK bink, BINKFRAMEBUFFERS * fbset), *) +DECL_FN(void, BinkRegisterFrameBuffers, (HBINK bink, BINKFRAMEBUFFERS * fbset), *) +DECL_FN(S32, BinkDoFrame, (HBINK bnk), *) +DECL_FN(S32, BinkDoFramePlane, (HBINK bnk, U32 which_planes), *) +DECL_FN(void, BinkNextFrame, (HBINK bnk), *) +DECL_FN(S32, BinkWait, (HBINK bnk), *) +DECL_FN(void, BinkClose, (HBINK bnk), *) +DECL_FN(S32, BinkPause, (HBINK bnk, S32 pause), *) +DECL_FN(S32, BinkCopyToBuffer, (HBINK bnk, void* dest, S32 destpitch, U32 destheight, U32 destx, U32 desty, U32 flags), *) +DECL_FN(S32, BinkCopyToBufferRect, (HBINK bnk, void* dest, S32 destpitch, U32 destheight, U32 destx, U32 desty, U32 srcx, U32 srcy, U32 srcw, U32 srch, U32 flags), *) +DECL_FN(S32, BinkGetRects, (HBINK bnk, U32 flags), *) +DECL_FN(void, BinkGoto, (HBINK bnk, U32 frame, S32 flags), *) +DECL_FN(U32, BinkGetKeyFrame, (HBINK bnk, U32 frame, S32 flags), *) +DECL_FN(void, BinkFreeGlobals, (void), *) +DECL_FN(S32, BinkGetPlatformInfo, (S32 bink_platform_enum, void * output), *) +DECL_FN(void, BinkRegisterGPUDataBuffers, (HBINK bink, BINKGPUDATABUFFERS * gpu), *) +DECL_FN(S32, BinkGetGPUDataBuffersInfo, (HBINK bink, BINKGPUDATABUFFERS * gpu), *) +DECL_FN(S32, BinkSetVideoOnOff, (HBINK bnk, S32 onoff), *) +DECL_FN(S32, BinkSetSoundOnOff, (HBINK bnk, S32 onoff), *) +DECL_FN(void, BinkSetVolume, (HBINK bnk, U32 trackid, S32 volume), *) +DECL_FN(void, BinkSetPan, (HBINK bnk, U32 trackid, S32 pan), *) +DECL_FN(void, BinkSetSpeakerVolumes, (HBINK bnk, U32 trackid, U32 * speaker_indexes, S32 * volumes, U32 total), *) +DECL_FN(void, BinkService, (HBINK bink), *) +DECL_FN(S32, BinkShouldSkip, (HBINK bink), *) +DECL_FN(S32, BinkControlBackgroundIO, (HBINK bink, U32 control), *) +DECL_FN(void, BinkSetWillLoop, (HBINK bink, S32 onoff), *) +DECL_FN(S32, BinkStartAsyncThread, (S32 thread_num, void const * param), *) +DECL_FN(S32, BinkDoFrameAsync, (HBINK bink, U32 thread_one, U32 thread_two), *) +DECL_FN(S32, BinkDoFrameAsyncMulti, (HBINK bink, U32* threads, S32 thread_count), *) +DECL_FN(S32, BinkDoFrameAsyncWait, (HBINK bink, S32 us), *) +DECL_FN(S32, BinkRequestStopAsyncThread, (S32 thread_num), *) +DECL_FN(S32, BinkWaitStopAsyncThread, (S32 thread_num), *) +DECL_FN(HBINKTRACK, BinkOpenTrack, (HBINK bnk, U32 trackindex), *) +DECL_FN(void, BinkCloseTrack, (HBINKTRACK bnkt), *) +DECL_FN(U32, BinkGetTrackData, (HBINKTRACK bnkt, void * dest), *) +DECL_FN(U32, BinkGetTrackType, (HBINK bnk, U32 trackindex), *) +DECL_FN(U32, BinkGetTrackMaxSize, (HBINK bnk, U32 trackindex), *) +DECL_FN(U32, BinkGetTrackID, (HBINK bnk, U32 trackindex), *) +DECL_FN(void, BinkGetSummary, (HBINK bnk, BINKSUMMARY * sum), *) +DECL_FN(void, BinkGetRealtime, (HBINK bink, BINKREALTIME * run, U32 frames), *) +DECL_FN(void, BinkSetFileOffset, (U64 offset), *) +DECL_FN(void, BinkSetSoundTrack, (U32 total_tracks, U32 * tracks), *) +DECL_FN(void, BinkSetIO, (BINKIOOPEN io), *) +DECL_FN(void, BinkSetFrameRate, (U32 forcerate, U32 forceratediv), *) +DECL_FN(void, BinkSetSimulate, (U32 sim), *) +DECL_FN(void, BinkSetIOSize, (U32 iosize), *) +DECL_FN(S32, BinkSetSoundSystem, (BINKSNDSYSOPEN open, UINTa param), *) +DECL_FN(S32, BinkSetSoundSystem2, (BINKSNDSYSOPEN2 open, UINTa param1, UINTa param2), *) +DECL_FN(BINKSNDOPEN, BinkOpenDirectSound, (UINTa param), *) +DECL_FN(BINKSNDOPEN, BinkOpenWaveOut, (UINTa param), *) +DECL_FN(BINKSNDOPEN, BinkOpenXAudio2, (UINTa param), *) +DECL_FN(void, BinkSetMemory, (BINKMEMALLOC a, BINKMEMFREE f), *) + +#undef DECL_FN \ No newline at end of file diff --git a/winmm.cpp b/winmm.cpp index f3fb102..ccd6c6f 100644 --- a/winmm.cpp +++ b/winmm.cpp @@ -9,7 +9,6 @@ typedef DWORD (*timeGetTime_t)(); timeGetTime_t ptimeGetTime = nullptr; DWORD timeGetTime() { - PRINT(L"timeGetTime called\n"); EFI_TIME t; if (EFI_SUCCESS == gRT->GetTime(&t, nullptr)) { // convert to milliseconds since midnight