/* Player status threshold and indicator rendering. */ #include "tdkpin_render.h" enum { DGROUP_CURRENT_PLAYER = 0x07d1, DGROUP_DISPLAYED_STATUS_LEVEL = 0x086b, DGROUP_PLAYER_SCORE_INDEX_BASE = 0x097e, DGROUP_STATUS_BITMAP_INDEX_BASE = 0x4319, DGROUP_ITEM_BITMAP_INDEX_BASE = 0x4321, }; static int32_t player_score(uint8_t player) { uint16_t offset = (uint16_t)( DGROUP_PLAYER_SCORE_INDEX_BASE + (uint16_t)player * 4); return (int32_t)win16_read_u32(win16_dgroup_pointer(offset)); } static uint16_t status_level_for_score(int32_t score) { if (score > 1300000) { return 4; } if (score > 650000) { return 3; } if (score > 140000) { return 2; } if (score > 2000) { return 1; } return 0; } static void draw_status_indicators( HDC16 destination, uint16_t active_level, bool all_inactive) { for (uint16_t index = 0; index <= 4; index++) { int16_t x = (int16_t)((4 - index) * 23 + 77); if (!all_inactive && index == active_level) { tdkpin_restore_background_region_a(11, 11, 544, x, destination); } else { tdkpin_restore_background_region_b(11, 11, 544, x, destination); } tdkpin_present_background_region(11, 11, 544, x, destination); } } /* * 1008:0b9e — update the current player's four score-threshold status levels * and five indicator cells. Player zero clears the display and restores the * sentinel 99; unrelated/invalid players leave every pixel and state unchanged. */ void tdkpin_update_status_display(uint8_t player, HDC16 destination) { uint8_t current_player = win16_read_u8( win16_dgroup_pointer(DGROUP_CURRENT_PLAYER)); uint16_t displayed = win16_read_u16( win16_dgroup_pointer(DGROUP_DISPLAYED_STATUS_LEVEL)); if ((player == current_player || displayed == 99) && player != 0 && player < 5) { uint16_t level = status_level_for_score(player_score(player)); if (level != displayed) { if (level == 0) { tdkpin_restore_background_region_a( 142, 146, 69, 380, destination); } else { uint16_t offset = (uint16_t)( DGROUP_STATUS_BITMAP_INDEX_BASE + level * 2); HBITMAP16 bitmap = win16_read_u16(win16_dgroup_pointer(offset)); tdkpin_blit_bitmap_to_background( bitmap, 142, 146, 69, 380, destination); } tdkpin_present_background_region( 142, 146, 69, 380, destination); draw_status_indicators(destination, level, false); } win16_write_u16( win16_dgroup_pointer(DGROUP_DISPLAYED_STATUS_LEVEL), 0, level); return; } if (player == 0) { tdkpin_restore_background_region_b( 142, 146, 69, 380, destination); tdkpin_present_background_region( 142, 146, 69, 380, destination); draw_status_indicators(destination, 0, true); win16_write_u16( win16_dgroup_pointer(DGROUP_DISPLAYED_STATUS_LEVEL), 0, 99); } } /* 1008:0dbd — draw one item state in the fixed 68x61 panel rectangle. */ void tdkpin_draw_item_status(int16_t item, HDC16 destination) { if (item == 0) { tdkpin_restore_background_region_b( 61, 68, 300, 123, destination); } else { uint16_t offset = (uint16_t)( DGROUP_ITEM_BITMAP_INDEX_BASE + (uint16_t)item * 2); HBITMAP16 bitmap = win16_read_u16(win16_dgroup_pointer(offset)); tdkpin_blit_bitmap_to_background( bitmap, 61, 68, 300, 123, destination); } tdkpin_present_background_region( 61, 68, 300, 123, destination); }