#include "../tdkpin_gameplay_helpers.h" #include uint8_t g_player_count; uint8_t g_gameplay_transition_pending; int32_t g_ball_x_milli; int32_t g_ball_y_milli; uint8_t g_current_player; static INT16 g_item_status; static unsigned g_calls; static unsigned g_kind[32]; static INT16 g_record_y[32]; static INT16 g_record_x[32]; static HBITMAP16 g_bitmap; static INT16 g_height; static INT16 g_width; static INT16 g_y; static INT16 g_x; static HDC16 g_dc; static HWND16 g_window; static int32_t g_score; static unsigned g_create_dc_calls; static unsigned g_select_object_calls; static unsigned g_bitblt_calls; static unsigned g_delete_dc_calls; static void record( unsigned kind, INT16 height, INT16 width, INT16 y, INT16 x, HDC16 dc) { g_kind[g_calls] = kind; g_record_y[g_calls] = y; g_record_x[g_calls] = x; g_calls++; g_height = height; g_width = width; g_y = y; g_x = x; g_dc = dc; } void tdkpin_blit_bitmap_to_background( HBITMAP16 bitmap, INT16 height, INT16 width, INT16 y, INT16 x, HDC16 dc) { g_bitmap = bitmap; record(1, height, width, y, x, dc); } void tdkpin_restore_background_region_a( INT16 height, INT16 width, INT16 y, INT16 x, HDC16 dc) { record(2, height, width, y, x, dc); } void tdkpin_restore_background_region_b( INT16 height, INT16 width, INT16 y, INT16 x, HDC16 dc) { record(3, height, width, y, x, dc); } void tdkpin_present_background_region( INT16 height, INT16 width, INT16 y, INT16 x, HDC16 dc) { record(4, height, width, y, x, dc); } HDC16 GetDC16(HWND16 window) { g_window = window; return 0x3333; } INT16 ReleaseDC16(HWND16 window, HDC16 dc) { assert(window == g_window && dc == 0x3333); return 1; } void tdkpin_draw_score(HDC16 destination, int32_t value) { assert(destination == 0x3333); g_score = value; } void tdkpin_draw_item_status(INT16 item, HDC16 destination) { assert(destination == 0x3333); g_item_status = item; } HDC16 CreateCompatibleDC16(HDC16 dc) { assert(dc == 0x4444 && g_create_dc_calls < 2); return (HDC16)(0x5001 + g_create_dc_calls++); } HGDIOBJ16 SelectObject16(HDC16 dc, HGDIOBJ16 object) { switch (g_select_object_calls++) { case 0: assert(dc == 0x5001 && object == 0x6001); return 0x7001; case 1: assert(dc == 0x5002 && object == 0x6002); return 0x7002; case 2: assert(dc == 0x5002 && object == 0x7002); return 0x6002; default: assert(g_select_object_calls == 4); assert(dc == 0x5001 && object == 0x7001); return 0x6001; } } BOOL16 BitBlt16( HDC16 destination, INT16 destination_x, INT16 destination_y, INT16 width, INT16 height, HDC16 source, INT16 source_x, INT16 source_y, uint32_t raster_operation) { assert(destination == 0x5001 && destination_x == 0); assert(destination_y == 21 && width == 21 && height == 18); assert(source == 0x5002 && source_x == 314 && source_y == 426); assert(raster_operation == 0x00cc0020u); g_bitblt_calls++; return 1; } BOOL16 DeleteDC16(HDC16 dc) { assert(dc == (g_delete_dc_calls == 0 ? 0x5002 : 0x5001)); g_delete_dc_calls++; return 1; } int main(void) { static uint8_t stack[0x400]; static uint8_t object[0x0c00]; static uint8_t dgroup[0x4d3a]; win16_reset_segment_bindings(); win16_bind_segment(0x7000, stack, sizeof(stack), true); win16_bind_segment(0x7100, object, sizeof(object), true); win16_bind_segment(0x7200, dgroup, sizeof(dgroup), true); win16_set_dgroup_selector(0x7200); win16_set_stack_state(0x7000, 0); Win16FarPtr receiver = win16_make_far_pointer(0x7100, 0); win16_write_u16(win16_make_far_pointer(0x7000, 0x0106), 0, win16_far_offset(receiver)); win16_write_u16(win16_make_far_pointer(0x7000, 0x0108), 0, win16_far_selector(receiver)); win16_write_u16(receiver, 4, 0x2222); win16_write_stack_u16(0x00f4, 0x4444); win16_write_u16(win16_dgroup_pointer(0x085b), 0, 0x6001); win16_write_u16(win16_dgroup_pointer(0x0865), 0, 0x6002); g_create_dc_calls = 0; g_select_object_calls = 0; g_bitblt_calls = 0; g_delete_dc_calls = 0; g_calls = 0; tdkpin_draw_board_decoration_row(0x0100, 21); assert(g_create_dc_calls == 2 && g_select_object_calls == 4); assert(g_bitblt_calls == 1 && g_delete_dc_calls == 2); assert(win16_read_stack_u16(0x00f2) == 0x5001); assert(win16_read_stack_u16(0x00f0) == 0x5002); assert(win16_read_stack_u16(0x00ee) == 0x7001); assert(win16_read_stack_u16(0x00ec) == 0x7002); assert(g_calls == 1 && g_kind[0] == 4); assert(g_height == 18 && g_width == 21 && g_y == 21 && g_x == 0); assert(g_dc == 0x4444); g_current_player = 2; win16_write_u16(win16_dgroup_pointer(0x0823), 0, 3); g_calls = 0; tdkpin_refresh_player_progress_markers(0x0100); assert(g_calls == 12); for (unsigned marker = 0; marker < 6; marker++) { unsigned restore = marker * 2; assert(g_kind[restore] == (marker < 3 ? 2u : 3u)); assert(g_kind[restore + 1] == 4); assert(g_record_y[restore] == 342); assert(g_record_x[restore] == (INT16)(391 + marker * 8)); assert(g_record_y[restore + 1] == 342); assert(g_record_x[restore + 1] == (INT16)(391 + marker * 8)); } g_calls = 0; tdkpin_blit_bitmap_and_present(0x1111, 10, 20, 30, 40, 0x5555); assert(g_calls == 2 && g_kind[0] == 1 && g_kind[1] == 4); assert(g_bitmap == 0x1111 && g_height == 10 && g_width == 20); assert(g_y == 30 && g_x == 40 && g_dc == 0x5555); g_calls = 0; tdkpin_restore_bounds_overlay_a(0xbeef, 10, 20, 5, 7, 0x5555); assert(g_calls == 2 && g_kind[0] == 2 && g_kind[1] == 4); assert(g_height == 6 && g_width == 14 && g_y == 5 && g_x == 7); g_calls = 0; tdkpin_restore_bounds_overlay_b(0xbeef, 10, 20, 5, 7, 0x5555); assert(g_calls == 2 && g_kind[0] == 3 && g_kind[1] == 4); tdkpin_draw_score_from_caller_frame(0x0100, 0x5678, 0x89ab); assert(g_window == 0x2222 && g_score == (int32_t)0x89ab5678u); g_player_count = 9; g_gameplay_transition_pending = 0; win16_write_u8(win16_far_add_offset(receiver, 0x0bde), 0); tdkpin_set_gameplay_transition_flags(0x0100); assert(g_player_count == 0); assert(g_gameplay_transition_pending == 1); assert(win16_read_u8(win16_far_add_offset(receiver, 0x0bde)) == 1); win16_write_u32(receiver, 0x0bba, 0x00001234u); win16_write_u32(receiver, 0x0bbe, 0x000056abu); assert(tdkpin_receiver_point_in_bounds( 0x0100, 0x6000, 0x2000, 0x5000, 0x1000) == 0x5601); assert(tdkpin_receiver_point_in_bounds( 0x0100, 0x6000, 0x2000, 0x5000, 0x1300) == 0x1200); win16_write_u32(win16_dgroup_pointer(0x07db), 0, 0x00001234u); win16_write_u32(win16_dgroup_pointer(0x07df), 0, 0x000056abu); assert(tdkpin_predicted_ball_in_bounds( 0, 0x6000, 0x2000, 0x5000, 0x1000) == 0x5601); g_ball_x_milli = 0; g_ball_y_milli = 0; assert(tdkpin_predicted_ball_in_bounds( 0, 0x6000, 0x2000, 0x5000, 0x1000) == 0x5601); g_ball_x_milli = 100000; g_ball_y_milli = 200000; tdkpin_update_dynamic_ball_record(0, 0); Win16FarPtr dynamic = win16_dgroup_pointer( (uint16_t)(0x095b + 173u * 0x53u)); assert((int32_t)win16_read_u32(win16_far_add_offset(dynamic, 0x12)) == 100000); assert((int32_t)win16_read_u32(win16_far_add_offset(dynamic, 0x16)) == 200000); assert((int32_t)win16_read_u32(win16_far_add_offset(dynamic, 0x02)) == 79000); assert((int32_t)win16_read_u32(win16_far_add_offset(dynamic, 0x06)) == 179000); assert((int32_t)win16_read_u32(win16_far_add_offset(dynamic, 0x0a)) == 121000); assert((int32_t)win16_read_u32(win16_far_add_offset(dynamic, 0x0e)) == 221000); Win16FarPtr record_one = win16_dgroup_pointer( (uint16_t)(0x095b + 0x53u)); win16_write_u16(record_one, 0x4b, 7); win16_write_u16(record_one, 0x4d, 5); win16_write_u16(record_one, 0x4f, 20); win16_write_u16(record_one, 0x51, 10); g_calls = 0; tdkpin_restore_record_or_item_a(0x0100, 1); assert(g_calls == 2 && g_kind[0] == 2 && g_kind[1] == 4); assert(g_height == 6 && g_width == 14 && g_y == 5 && g_x == 7); g_calls = 0; tdkpin_restore_record_b(0x0100, 1); assert(g_kind[0] == 3 && g_kind[1] == 4); Win16FarPtr quad_two = win16_dgroup_pointer(0x4273); win16_write_u16(quad_two, 0, 7); win16_write_u16(quad_two, 2, 5); win16_write_u16(quad_two, 4, 20); win16_write_u16(quad_two, 6, 10); g_calls = 0; tdkpin_restore_record_or_item_a(0x0100, 1002); assert(g_kind[0] == 2 && g_height == 6 && g_width == 14); g_item_status = 0; tdkpin_restore_record_or_item_a(0x0100, 1006); assert(g_item_status == 1); win16_write_u16(record_one, 0x41, 0x0080); win16_write_u8(win16_far_add_offset(record_one, 0x34), 1); g_calls = 0; tdkpin_refresh_collision_record(0x0100, 1); assert(g_kind[0] == 3); win16_write_u8(win16_far_add_offset(record_one, 0x34), 0); g_calls = 0; tdkpin_refresh_collision_record(0x0100, 1); assert(g_kind[0] == 2); win16_write_u16(record_one, 0x41, 0x0100); g_calls = 0; tdkpin_refresh_collision_record(0x0100, 1); assert(g_kind[0] == 3); g_current_player = 1; win16_write_u8(win16_far_add_offset(receiver, 0x047d), 1); g_calls = 0; tdkpin_refresh_player_item(0x0100, 2); assert(g_kind[0] == 2); win16_write_u8(win16_far_add_offset(receiver, 0x047d), 0); g_calls = 0; tdkpin_refresh_player_item(0x0100, 2); assert(g_kind[0] == 3); win16_write_u32(win16_dgroup_pointer(0x07e7), 0, 0x11112222u); win16_write_u32(win16_dgroup_pointer(0x07ef), 0, 0x33334444u); win16_write_u32(win16_dgroup_pointer(0x07f7), 0, 0x55556666u); win16_write_u32(win16_dgroup_pointer(0x07ff), 0, 0x77778888u); win16_write_u32(win16_dgroup_pointer(0x0807), 0, 0x9999aaaau); for (uint16_t index = 0; index < 6; index++) { win16_write_u8( win16_dgroup_pointer((uint16_t)(0x0811 + index)), (uint8_t)(0xb0 + index)); } tdkpin_load_ball_slot(0x0100, 1); assert((uint32_t)g_ball_x_milli == 0x11112222u); assert((uint32_t)g_ball_y_milli == 0x33334444u); assert(win16_read_u32(win16_far_add_offset(receiver, 0x0baa)) == 0x55556666u); assert(win16_read_u32(win16_far_add_offset(receiver, 0x0bae)) == 0x77778888u); assert(win16_read_u32(win16_far_add_offset(receiver, 0x0bca)) == 0x9999aaaau); for (uint16_t index = 0; index < 6; index++) { assert(win16_read_u8(win16_far_add_offset( receiver, (uint16_t)(0x0bce + index))) == (uint8_t)(0xb0 + index)); } g_ball_x_milli = (int32_t)0xabcdef01u; g_ball_y_milli = (int32_t)0x12345678u; win16_write_u32(receiver, 0x0baa, 0x01020304u); win16_write_u32(receiver, 0x0bae, 0x05060708u); win16_write_u32(receiver, 0x0bca, 0x090a0b0cu); for (uint16_t index = 0; index < 6; index++) { win16_write_u8( win16_far_add_offset(receiver, (uint16_t)(0x0bce + index)), (uint8_t)(0xc0 + index)); } tdkpin_save_ball_slot(0x0100, 2); assert(win16_read_u32(win16_dgroup_pointer(0x07eb)) == 0xabcdef01u); assert(win16_read_u32(win16_dgroup_pointer(0x07f3)) == 0x12345678u); assert(win16_read_u32(win16_dgroup_pointer(0x07fb)) == 0x01020304u); assert(win16_read_u32(win16_dgroup_pointer(0x0803)) == 0x05060708u); assert(win16_read_u32(win16_dgroup_pointer(0x080b)) == 0x090a0b0cu); for (uint16_t index = 0; index < 6; index++) { assert(win16_read_u8(win16_dgroup_pointer( (uint16_t)(0x0817 + index))) == (uint8_t)(0xc0 + index)); } return 0; }