/* 281-frame, mask/image-composited panel animation from TDKPIN Code1. */ #include "tdkpin_panel_animation.h" #include "tdkpin_sound.h" static Win16FarPtr caller_receiver(uint16_t caller_bp) { uint16_t offset = win16_read_stack_u16((uint16_t)(caller_bp + 6)); uint16_t selector = win16_read_stack_u16((uint16_t)(caller_bp + 8)); return win16_make_far_pointer(selector, offset); } static INT16 twice(int32_t value) { return (INT16)(uint16_t)((uint32_t)value * 2u); } static void copy_region( HDC16 destination, INT16 destination_x, INT16 destination_y, INT16 width, INT16 height, HDC16 source, INT16 source_x, INT16 source_y) { (void)BitBlt16( destination, destination_x, destination_y, width, height, source, source_x, source_y, 0x00cc0020u); } static void mask_image_pair( HDC16 panel, INT16 destination_x, INT16 destination_y, INT16 width, INT16 height, HDC16 atlas, INT16 mask_x, INT16 mask_y, INT16 image_x, INT16 image_y) { (void)BitBlt16( panel, destination_x, destination_y, width, height, atlas, mask_x, mask_y, 0x008800c6u); (void)BitBlt16( panel, destination_x, destination_y, width, height, atlas, image_x, image_y, 0x00ee0086u); } static void phase_1_to_44( int32_t frame, HDC16 panel, HDC16 atlas) { mask_image_pair( panel, 20, 0, 45, twice(frame), atlas, 45, (INT16)(twice(45 - frame) + 89), 0, (INT16)(twice(45 - frame) + 89)); } static void phase_66_to_128( int32_t frame, HDC16 panel, HDC16 atlas) { copy_region(panel, 0, 33, 91, 90, atlas, 180, 90); if (frame < 83) { mask_image_pair( panel, 0, twice(82 - frame), 91, 90, atlas, 362, 90, 271, 90); } else { INT16 height = twice(128 - frame); INT16 source_y = (INT16)(twice(frame - 82) + 90); mask_image_pair( panel, 0, 0, 91, height, atlas, 362, source_y, 271, source_y); } if (frame < 111) { INT16 height = twice(110 - frame); INT16 source_y = (INT16)(twice(frame - 66) + 90); mask_image_pair( panel, 20, 0, 45, height, atlas, 135, source_y, 90, source_y); } } static void phase_159_to_221( int32_t frame, HDC16 panel, HDC16 atlas) { copy_region(panel, 0, 33, 91, 90, atlas, 180, 90); if (frame < 204) { INT16 height = twice(frame - 159); INT16 source_y = (INT16)(twice(204 - frame) + 90); mask_image_pair( panel, 0, 0, 91, height, atlas, 362, source_y, 453, source_y); } else { mask_image_pair( panel, 0, twice(frame - 204), 91, 90, atlas, 362, 90, 453, 90); } if (frame > 176) { if (frame == 221) { mask_image_pair( panel, 20, 0, 45, 88, atlas, 135, 90, 90, 90); } else { INT16 height = twice(frame - 177); INT16 source_y = (INT16)(twice(222 - frame) + 89); mask_image_pair( panel, 20, 0, 45, height, atlas, 135, source_y, 90, source_y); } } } static void full_panel_mask_image(HDC16 panel, HDC16 atlas) { mask_image_pair( panel, 0, 33, 91, 90, atlas, 362, 90, 453, 90); } static void phase_238_to_281( int32_t frame, HDC16 panel, HDC16 atlas) { full_panel_mask_image(panel, atlas); INT16 height = twice(281 - frame); INT16 source_y = (INT16)(twice(frame - 238) + 90); mask_image_pair( panel, 20, 0, 45, height, atlas, 45, source_y, 0, source_y); } /* 1000:7440 -- render one frame of the 91x123 board-panel animation. */ void tdkpin_draw_panel_animation(uint16_t caller_bp) { Win16FarPtr receiver = caller_receiver(caller_bp); HWND16 window = win16_read_u16(win16_far_add_offset(receiver, 4)); HDC16 dc = GetDC16(window); HDC16 atlas_dc = CreateCompatibleDC16(dc); HGDIOBJ16 old_atlas = SelectObject16( atlas_dc, win16_read_u16(win16_dgroup_pointer(0x085f))); HDC16 panel_dc = CreateCompatibleDC16(dc); HBITMAP16 panel_bitmap = CreateCompatibleBitmap16(dc, 91, 123); HGDIOBJ16 old_panel = SelectObject16(panel_dc, panel_bitmap); copy_region(panel_dc, 0, 0, 91, 123, atlas_dc, 79, 0); (void)SelectObject16( atlas_dc, win16_read_u16(win16_dgroup_pointer(0x0859))); int32_t frame = (int32_t)win16_read_u32(win16_dgroup_pointer(0x0851)); int16_t phase_frame = (int16_t)frame; if (phase_frame >= 1 && phase_frame <= 44) { if (frame == 1) { tdkpin_play_sound_if_not_tilted(13); (void)SelectObject16( panel_dc, win16_read_u16(win16_dgroup_pointer(0x085b))); copy_region(panel_dc, 79, 0, 91, 90, atlas_dc, 271, 90); (void)SelectObject16(panel_dc, panel_bitmap); } phase_1_to_44(frame, panel_dc, atlas_dc); } else if (phase_frame >= 45 && phase_frame <= 57) { if (frame == 45) { (void)tdkpin_stop_sound_if_active(); } mask_image_pair( panel_dc, 20, 0, 45, 88, atlas_dc, 45, 90, 0, 90); } else if (phase_frame >= 58 && phase_frame <= 65) { if (frame == 58) { tdkpin_play_sound_if_not_tilted(12); } mask_image_pair( panel_dc, 20, 0, 45, 88, atlas_dc, 135, 90, 90, 90); } else if (phase_frame >= 66 && phase_frame <= 128) { if (frame == 66) { tdkpin_play_sound_if_not_tilted(13); } phase_66_to_128(frame, panel_dc, atlas_dc); } else if (phase_frame >= 129 && phase_frame <= 158) { if (frame == 129) { (void)tdkpin_stop_sound_if_active(); } copy_region(panel_dc, 0, 33, 91, 90, atlas_dc, 180, 90); } else if (phase_frame >= 159 && phase_frame <= 221) { if (frame == 159) { tdkpin_play_sound_if_not_tilted(13); } phase_159_to_221(frame, panel_dc, atlas_dc); } else if (phase_frame >= 222 && phase_frame <= 229) { if (frame == 222) { (void)tdkpin_stop_sound_if_active(); } full_panel_mask_image(panel_dc, atlas_dc); mask_image_pair( panel_dc, 20, 0, 45, 88, atlas_dc, 135, 90, 90, 90); } else if (phase_frame >= 230 && phase_frame <= 237) { if (frame == 230) { tdkpin_play_sound_if_not_tilted(12); } full_panel_mask_image(panel_dc, atlas_dc); mask_image_pair( panel_dc, 20, 0, 45, 88, atlas_dc, 45, 90, 0, 90); } else if (phase_frame >= 238 && phase_frame <= 281) { if (frame == 238) { tdkpin_play_sound_if_not_tilted(13); } phase_238_to_281(frame, panel_dc, atlas_dc); if (frame == 281) { (void)SelectObject16( panel_dc, win16_read_u16(win16_dgroup_pointer(0x085b))); (void)SelectObject16( atlas_dc, win16_read_u16(win16_dgroup_pointer(0x085d))); copy_region(panel_dc, 79, 0, 91, 90, atlas_dc, 79, 0); (void)SelectObject16(panel_dc, panel_bitmap); } } copy_region(dc, 79, 0, 91, 123, panel_dc, 0, 0); (void)SelectObject16(panel_dc, old_panel); (void)SelectObject16(atlas_dc, old_atlas); (void)DeleteObject16(panel_bitmap); (void)DeleteDC16(panel_dc); (void)DeleteDC16(atlas_dc); (void)ReleaseDC16(window, dc); }