/* TDKPIN logical-palette creation and PAL resource loading. */ #include "tdkpin_palette.h" #include "tdkpin_strings.h" enum { DGROUP_PALETTE_HANDLE = 0x444e, DGROUP_PALETTE_RGB = 0x4450, DGROUP_PAL_RESOURCE_TYPE = 0x045a, DGROUP_DAT_RESOURCE_TYPE = 0x045e, DGROUP_DISPLAY_DRIVER = 0x0462, PALETTE_COLOR_COUNT = 256, PALETTE_RGB_BYTES = 768, LOGPALETTE_VERSION_0300 = 0x0300, PALETTE_ENTRY_NOCOLLAPSE = 0x04, CREATE_DIBITMAP_INITIALIZE = 0x00000004, }; /* Code2 1008:11bd and 131e, represented with their exact signed bounds. */ static const BorlandInt32Range g_uint16_range = {0, 0xffff}; static const BorlandInt32Range g_palette_byte_range = {0, 0x02ff}; /* * 1008:0023 — create and briefly realize a 256-entry PC_NOCOLLAPSE palette in * the supplied window DC. Allocation failure is the sole guarded palette path; * all GDI results are otherwise consumed exactly as returned. */ void tdkpin_realize_nocollapse_palette(HWND16 window) { Win16FarPtr logical_palette = borland_get_mem(sizeof(LOGPALETTE256)); if (logical_palette == 0) { return; } win16_write_u16(logical_palette, 0, LOGPALETTE_VERSION_0300); win16_write_u16(logical_palette, 2, PALETTE_COLOR_COUNT); for (uint16_t index = 0; index < PALETTE_COLOR_COUNT; index++) { Win16FarPtr entry = win16_far_add_offset( logical_palette, (uint16_t)(4 + index * sizeof(PALETTEENTRY16))); win16_write_u8(entry, 0); win16_write_u8(win16_far_add_offset(entry, 1), 0); win16_write_u8(win16_far_add_offset(entry, 2), 0); win16_write_u8( win16_far_add_offset(entry, 3), PALETTE_ENTRY_NOCOLLAPSE); } HDC16 dc = GetDC16(window); HPALETTE16 palette = CreatePalette16(logical_palette); HPALETTE16 previous = SelectPalette16(dc, palette, 0); (void)RealizePalette16(dc); (void)SelectPalette16(dc, previous, 1); (void)DeleteObject16(palette); (void)ReleaseDC16(window, dc); borland_free_mem(logical_palette, sizeof(LOGPALETTE256)); } /* * 1008:11c5 — materialize a 256-entry LOGPALETTE from the packed DGROUP RGB * table, create the GDI palette, then range-check and free the temporary block. */ void tdkpin_create_palette_from_rgb_table(void) { const uint32_t allocation_bytes = sizeof(LOGPALETTE256); Win16FarPtr logical_palette = borland_get_mem((uint16_t)allocation_bytes); win16_write_u16(logical_palette, 0, LOGPALETTE_VERSION_0300); win16_write_u16(logical_palette, 2, PALETTE_COLOR_COUNT); for (uint16_t index = 0; index < PALETTE_COLOR_COUNT; index++) { Win16FarPtr source = win16_far_add_offset( win16_dgroup_pointer(DGROUP_PALETTE_RGB), (uint16_t)(index * 3)); Win16FarPtr entry = win16_far_add_offset( logical_palette, (uint16_t)(4 + index * sizeof(PALETTEENTRY16))); win16_write_u8(entry, win16_read_u8(source)); win16_write_u8( win16_far_add_offset(entry, 1), win16_read_u8(win16_far_add_offset(source, 1))); win16_write_u8( win16_far_add_offset(entry, 2), win16_read_u8(win16_far_add_offset(source, 2))); win16_write_u8(win16_far_add_offset(entry, 3), 0); } HPALETTE16 palette = CreatePalette16(logical_palette); win16_write_u16( win16_dgroup_pointer(DGROUP_PALETTE_HANDLE), 0, palette); borland_check_int32_range((int32_t)allocation_bytes, &g_uint16_range); borland_free_mem(logical_palette, (uint16_t)allocation_bytes); } /* * 1008:1326 — load a custom "pal" resource and copy exactly 768 bytes. Both * source and destination index expressions pass through the compiler-emitted * 0..767 range descriptor on every iteration. The loaded resource is unlocked * but deliberately not FreeResource'd here, matching the binary. */ void tdkpin_load_palette_resource( Win16FarPtr destination, Win16FarPtr resource_name, HINSTANCE16 instance) { HRSRC16 found = FindResource16( instance, resource_name, win16_dgroup_pointer(DGROUP_PAL_RESOURCE_TYPE)); HGLOBAL16 resource = LoadResource16(instance, found); Win16FarPtr source = LockResource16(resource); for (uint16_t index = 0; index < PALETTE_RGB_BYTES; index++) { borland_check_int32_range(index, &g_palette_byte_range); uint8_t value = win16_read_u8(win16_far_add_offset(source, index)); borland_check_int32_range(index, &g_palette_byte_range); win16_write_u8(win16_far_add_offset(destination, index), value); } (void)GlobalUnlock16(resource); } /* * 1008:13a8 — project all 256 packed RGB triplets to BITMAPINFO RGBQUADs. * The compiler's dead ((1<