refactor: dispatch via DisplayGfx::*_raw methods in queue_dispatch
Browse filesReplaces the per-case `((*vtable).method)(display, ...)` open-coding
with the auto-generated `DisplayGfx::*_raw` methods produced by
`bind_DisplayGfxVtable!(DisplayGfx, base.vtable)`. The `_raw` methods
do the same `((*(*this).base.vtable).method)(this, args...)` dispatch
under the hood while keeping the noalias-safe raw-pointer signature.
Drops the explicit `vtable: *const DisplayGfxVtable` parameter from
all 14 per-case dispatcher functions and removes the `let vtable =
(*display).base.vtable` setup in the main loop. Net β34 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
crates/openwa-core/src/render/queue_dispatch.rs
CHANGED
|
@@ -291,28 +291,27 @@ pub unsafe fn render_drawing_queue(
|
|
| 291 |
});
|
| 292 |
|
| 293 |
let clip_ref: &ClipContext = &*clip;
|
| 294 |
-
let vtable = (*display).base.vtable;
|
| 295 |
|
| 296 |
// Walk from the highest index downward.
|
| 297 |
for i in (0..count).rev() {
|
| 298 |
let cmd = entries[i] as *const u32;
|
| 299 |
let cmd_type = *cmd;
|
| 300 |
match cmd_type {
|
| 301 |
-
0 => dispatch_case_0_fill_rect(display,
|
| 302 |
-
1 => dispatch_case_1_bitmap_global(display,
|
| 303 |
-
2 => dispatch_case_2_textbox_local(display,
|
| 304 |
-
3 => dispatch_case_3_via_callback(display,
|
| 305 |
-
4 => dispatch_case_4_sprite_global(display,
|
| 306 |
-
5 => dispatch_case_5_sprite_local(display,
|
| 307 |
-
6 => dispatch_case_6_sprite_offset(display,
|
| 308 |
-
7 => dispatch_case_7_polyline(display,
|
| 309 |
-
8 => dispatch_case_8_line_strip(display,
|
| 310 |
-
9 => dispatch_case_9_polygon(display,
|
| 311 |
-
0xA => dispatch_case_a_pixel_strip(display,
|
| 312 |
-
0xB => dispatch_case_b_crosshair(display,
|
| 313 |
-
0xC => dispatch_case_c_outlined_pixel(display,
|
| 314 |
-
0xD => dispatch_case_d_tiled_bitmap(display,
|
| 315 |
-
0xE => dispatch_case_e_tiled_terrain(display,
|
| 316 |
_ => { /* unknown command type β silently skipped, matching WA */ }
|
| 317 |
}
|
| 318 |
}
|
|
@@ -325,8 +324,11 @@ pub unsafe fn render_drawing_queue(
|
|
| 325 |
// Each case body mirrors the corresponding `case N:` arm of WA's
|
| 326 |
// `RenderDrawingQueue` (0x542350). Field offsets are the `puVar1[N]`
|
| 327 |
// indices from the decompile (each step = 4 bytes).
|
| 328 |
-
|
| 329 |
-
|
|
|
|
|
|
|
|
|
|
| 330 |
|
| 331 |
#[inline]
|
| 332 |
unsafe fn read_field(cmd: *const u32, idx: usize) -> i32 {
|
|
@@ -346,12 +348,7 @@ unsafe fn read_fixed(cmd: *const u32, idx: usize) -> Fixed {
|
|
| 346 |
// if !iVar4 break;
|
| 347 |
// // x/y MIN-corner clamps to keep pixel-perfect rect edges
|
| 348 |
// vtable[18](this, x1>>16, y1>>16, x2>>16, y2>>16, cmd[2]);
|
| 349 |
-
unsafe fn dispatch_case_0_fill_rect(
|
| 350 |
-
display: *mut DisplayGfx,
|
| 351 |
-
vtable: *const DisplayGfxVtable,
|
| 352 |
-
clip: &ClipContext,
|
| 353 |
-
cmd: *const u32,
|
| 354 |
-
) {
|
| 355 |
let mut x1 = Fixed::ZERO;
|
| 356 |
let mut y1 = Fixed::ZERO;
|
| 357 |
let mut x2 = Fixed::ZERO;
|
|
@@ -398,7 +395,7 @@ unsafe fn dispatch_case_0_fill_rect(
|
|
| 398 |
}
|
| 399 |
|
| 400 |
let color = *(cmd.add(2));
|
| 401 |
-
(
|
| 402 |
display,
|
| 403 |
x1.to_int(),
|
| 404 |
y1.to_int(),
|
|
@@ -413,11 +410,7 @@ unsafe fn dispatch_case_0_fill_rect(
|
|
| 413 |
// vtable[20](this, cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], cmd[9]);
|
| 414 |
//
|
| 415 |
// Pure passthrough β global bitmaps draw at the supplied world coords.
|
| 416 |
-
unsafe fn dispatch_case_1_bitmap_global(
|
| 417 |
-
display: *mut DisplayGfx,
|
| 418 |
-
vtable: *const DisplayGfxVtable,
|
| 419 |
-
cmd: *const u32,
|
| 420 |
-
) {
|
| 421 |
use crate::bitgrid::DisplayBitGrid;
|
| 422 |
let x = read_fixed(cmd, 2);
|
| 423 |
let y = read_fixed(cmd, 3);
|
|
@@ -427,7 +420,7 @@ unsafe fn dispatch_case_1_bitmap_global(
|
|
| 427 |
let src_w = read_field(cmd, 7);
|
| 428 |
let src_h = read_field(cmd, 8);
|
| 429 |
let flags = *(cmd.add(9));
|
| 430 |
-
(
|
| 431 |
}
|
| 432 |
|
| 433 |
// ---- case 2: DRAW_TEXTBOX_LOCAL β slot 20 (draw_scaled_sprite) -------------
|
|
@@ -437,7 +430,6 @@ unsafe fn dispatch_case_1_bitmap_global(
|
|
| 437 |
// `cmd+8` controlling whether the result clamps to the second clip pair.
|
| 438 |
unsafe fn dispatch_case_2_textbox_local(
|
| 439 |
display: *mut DisplayGfx,
|
| 440 |
-
vtable: *const DisplayGfxVtable,
|
| 441 |
clip: &ClipContext,
|
| 442 |
cmd: *const u32,
|
| 443 |
) {
|
|
@@ -497,7 +489,7 @@ unsafe fn dispatch_case_2_textbox_local(
|
|
| 497 |
let src_w = read_field(cmd, 10);
|
| 498 |
let src_h = read_field(cmd, 11);
|
| 499 |
let flags = *(cmd.add(12));
|
| 500 |
-
(
|
| 501 |
}
|
| 502 |
|
| 503 |
// ---- case 3 β slot 21 (draw_via_callback) ----------------------------------
|
|
@@ -507,7 +499,6 @@ unsafe fn dispatch_case_2_textbox_local(
|
|
| 507 |
// vtable[21](this, x, y, cmd[6], cmd[7], cmd[8]);
|
| 508 |
unsafe fn dispatch_case_3_via_callback(
|
| 509 |
display: *mut DisplayGfx,
|
| 510 |
-
vtable: *const DisplayGfxVtable,
|
| 511 |
clip: &ClipContext,
|
| 512 |
cmd: *const u32,
|
| 513 |
) {
|
|
@@ -528,22 +519,18 @@ unsafe fn dispatch_case_3_via_callback(
|
|
| 528 |
let obj = read_field(cmd, 6) as *mut u8;
|
| 529 |
let p5 = *(cmd.add(7));
|
| 530 |
let p6 = *(cmd.add(8));
|
| 531 |
-
(
|
| 532 |
}
|
| 533 |
|
| 534 |
// ---- case 4: DRAW_SPRITE_GLOBAL β slot 19 (blit_sprite) --------------------
|
| 535 |
//
|
| 536 |
// vtable[19](this, cmd[2], cmd[3], cmd[4], cmd[5]);
|
| 537 |
-
unsafe fn dispatch_case_4_sprite_global(
|
| 538 |
-
display: *mut DisplayGfx,
|
| 539 |
-
vtable: *const DisplayGfxVtable,
|
| 540 |
-
cmd: *const u32,
|
| 541 |
-
) {
|
| 542 |
let x = read_fixed(cmd, 2);
|
| 543 |
let y = read_fixed(cmd, 3);
|
| 544 |
let sprite_flags = *(cmd.add(4));
|
| 545 |
let palette = *(cmd.add(5));
|
| 546 |
-
(
|
| 547 |
}
|
| 548 |
|
| 549 |
// ---- case 5: DRAW_SPRITE_LOCAL β slot 19 (blit_sprite) ---------------------
|
|
@@ -552,7 +539,6 @@ unsafe fn dispatch_case_4_sprite_global(
|
|
| 552 |
// vtable[19](this, x, y, cmd[4], cmd[5]);
|
| 553 |
unsafe fn dispatch_case_5_sprite_local(
|
| 554 |
display: *mut DisplayGfx,
|
| 555 |
-
vtable: *const DisplayGfxVtable,
|
| 556 |
clip: &ClipContext,
|
| 557 |
cmd: *const u32,
|
| 558 |
) {
|
|
@@ -561,7 +547,7 @@ unsafe fn dispatch_case_5_sprite_local(
|
|
| 561 |
rq_translate_coordinates(clip, read_fixed(cmd, 2), read_fixed(cmd, 3), &mut x, &mut y);
|
| 562 |
let sprite_flags = *(cmd.add(4));
|
| 563 |
let palette = *(cmd.add(5));
|
| 564 |
-
(
|
| 565 |
}
|
| 566 |
|
| 567 |
// ---- case 6: DRAW_SPRITE_OFFSET β slot 19 (blit_sprite) --------------------
|
|
@@ -572,7 +558,6 @@ unsafe fn dispatch_case_5_sprite_local(
|
|
| 572 |
// screen-space offset sprites.
|
| 573 |
unsafe fn dispatch_case_6_sprite_offset(
|
| 574 |
display: *mut DisplayGfx,
|
| 575 |
-
vtable: *const DisplayGfxVtable,
|
| 576 |
clip: &ClipContext,
|
| 577 |
cmd: *const u32,
|
| 578 |
) {
|
|
@@ -636,7 +621,7 @@ unsafe fn dispatch_case_6_sprite_offset(
|
|
| 636 |
|
| 637 |
let sprite_flags = *(cmd.add(7));
|
| 638 |
let palette = *(cmd.add(8));
|
| 639 |
-
(
|
| 640 |
}
|
| 641 |
|
| 642 |
// ---- case 7 β slot 12 (draw_polyline) --------------------------------------
|
|
@@ -645,15 +630,11 @@ unsafe fn dispatch_case_6_sprite_offset(
|
|
| 645 |
//
|
| 646 |
// `cmd[2]` is the vertex count, `cmd[3]` is the color, vertex data
|
| 647 |
// follows starting at `cmd[4]`.
|
| 648 |
-
unsafe fn dispatch_case_7_polyline(
|
| 649 |
-
display: *mut DisplayGfx,
|
| 650 |
-
vtable: *const DisplayGfxVtable,
|
| 651 |
-
cmd: *const u32,
|
| 652 |
-
) {
|
| 653 |
let points = cmd.add(4) as *mut i32;
|
| 654 |
let count = read_field(cmd, 2);
|
| 655 |
let color = *(cmd.add(3));
|
| 656 |
-
(
|
| 657 |
}
|
| 658 |
|
| 659 |
// ---- case 8: DRAW_LINE_STRIP β slot 14 (draw_line_clipped) -----------------
|
|
@@ -663,7 +644,6 @@ unsafe fn dispatch_case_7_polyline(
|
|
| 663 |
// `cmd[3]` is the color shared by all segments.
|
| 664 |
unsafe fn dispatch_case_8_line_strip(
|
| 665 |
display: *mut DisplayGfx,
|
| 666 |
-
vtable: *const DisplayGfxVtable,
|
| 667 |
clip: &ClipContext,
|
| 668 |
cmd: *const u32,
|
| 669 |
) {
|
|
@@ -703,7 +683,7 @@ unsafe fn dispatch_case_8_line_strip(
|
|
| 703 |
) {
|
| 704 |
break;
|
| 705 |
}
|
| 706 |
-
(
|
| 707 |
x1 = x2;
|
| 708 |
y1 = y2;
|
| 709 |
vert = vert.add(3);
|
|
@@ -714,12 +694,7 @@ unsafe fn dispatch_case_8_line_strip(
|
|
| 714 |
//
|
| 715 |
// Same shape as case 8 but with two color params (cmd[3], cmd[4]) and the
|
| 716 |
// first vertex starts at `cmd[5..8]`. Per-segment vertex stride is 3 u32s.
|
| 717 |
-
unsafe fn dispatch_case_9_polygon(
|
| 718 |
-
display: *mut DisplayGfx,
|
| 719 |
-
vtable: *const DisplayGfxVtable,
|
| 720 |
-
clip: &ClipContext,
|
| 721 |
-
cmd: *const u32,
|
| 722 |
-
) {
|
| 723 |
let mut x1 = Fixed::ZERO;
|
| 724 |
let mut y1 = Fixed::ZERO;
|
| 725 |
let mut scale = Fixed::ZERO;
|
|
@@ -755,7 +730,7 @@ unsafe fn dispatch_case_9_polygon(
|
|
| 755 |
) {
|
| 756 |
break;
|
| 757 |
}
|
| 758 |
-
(
|
| 759 |
x1 = x2;
|
| 760 |
y1 = y2;
|
| 761 |
vert = vert.add(3);
|
|
@@ -773,7 +748,6 @@ unsafe fn dispatch_case_9_polygon(
|
|
| 773 |
// vtable[15](this, x, y, cmd[4], cmd[5], cmd[6], cmd[7]);
|
| 774 |
unsafe fn dispatch_case_a_pixel_strip(
|
| 775 |
display: *mut DisplayGfx,
|
| 776 |
-
vtable: *const DisplayGfxVtable,
|
| 777 |
clip: &ClipContext,
|
| 778 |
cmd: *const u32,
|
| 779 |
) {
|
|
@@ -788,7 +762,7 @@ unsafe fn dispatch_case_a_pixel_strip(
|
|
| 788 |
let dy = read_fixed(cmd, 5);
|
| 789 |
let count = read_field(cmd, 6);
|
| 790 |
let color = *(cmd.add(7));
|
| 791 |
-
(
|
| 792 |
}
|
| 793 |
|
| 794 |
// ---- case 0xB: DRAW_CROSSHAIR β slot 16 (draw_crosshair) -------------------
|
|
@@ -796,12 +770,7 @@ unsafe fn dispatch_case_a_pixel_strip(
|
|
| 796 |
// iVar4 = RQ_ClipCoordinates(this, cmd[4], cmd[5], cmd[6], &x, &y, ..);
|
| 797 |
// if !iVar4 break;
|
| 798 |
// vtable[16](this, x>>16, y>>16, cmd[2], cmd[3]);
|
| 799 |
-
unsafe fn dispatch_case_b_crosshair(
|
| 800 |
-
display: *mut DisplayGfx,
|
| 801 |
-
vtable: *const DisplayGfxVtable,
|
| 802 |
-
clip: &ClipContext,
|
| 803 |
-
cmd: *const u32,
|
| 804 |
-
) {
|
| 805 |
let mut x = Fixed::ZERO;
|
| 806 |
let mut y = Fixed::ZERO;
|
| 807 |
let mut scale = Fixed::ZERO;
|
|
@@ -818,7 +787,7 @@ unsafe fn dispatch_case_b_crosshair(
|
|
| 818 |
}
|
| 819 |
let color_fg = *(cmd.add(2));
|
| 820 |
let color_bg = *(cmd.add(3));
|
| 821 |
-
(
|
| 822 |
}
|
| 823 |
|
| 824 |
// ---- case 0xC β slot 17 (draw_outlined_pixel) ------------------------------
|
|
@@ -828,7 +797,6 @@ unsafe fn dispatch_case_b_crosshair(
|
|
| 828 |
// vtable[17](this, x>>16, y>>16, cmd[2], cmd[3]);
|
| 829 |
unsafe fn dispatch_case_c_outlined_pixel(
|
| 830 |
display: *mut DisplayGfx,
|
| 831 |
-
vtable: *const DisplayGfxVtable,
|
| 832 |
clip: &ClipContext,
|
| 833 |
cmd: *const u32,
|
| 834 |
) {
|
|
@@ -848,7 +816,7 @@ unsafe fn dispatch_case_c_outlined_pixel(
|
|
| 848 |
}
|
| 849 |
let color_fg = *(cmd.add(2));
|
| 850 |
let color_bg = read_field(cmd, 3);
|
| 851 |
-
(
|
| 852 |
}
|
| 853 |
|
| 854 |
// ---- case 0xD: DRAW_TILED_BITMAP β slot 11 (draw_tiled_bitmap) -------------
|
|
@@ -859,7 +827,6 @@ unsafe fn dispatch_case_c_outlined_pixel(
|
|
| 859 |
// vtable[11](this, (flag ? 0 : x>>16), y>>16, cmd[4]);
|
| 860 |
unsafe fn dispatch_case_d_tiled_bitmap(
|
| 861 |
display: *mut DisplayGfx,
|
| 862 |
-
vtable: *const DisplayGfxVtable,
|
| 863 |
clip: &ClipContext,
|
| 864 |
cmd: *const u32,
|
| 865 |
) {
|
|
@@ -881,7 +848,7 @@ unsafe fn dispatch_case_d_tiled_bitmap(
|
|
| 881 |
let flag_byte = *(cmd.add(5)) as u8;
|
| 882 |
let dest_x = if flag_byte != 0 { 0 } else { x.to_int() };
|
| 883 |
let source = read_field(cmd, 4) as *const TiledBitmapSource;
|
| 884 |
-
(
|
| 885 |
}
|
| 886 |
|
| 887 |
// ---- case 0xE β slot 22 (draw_tiled_terrain) -------------------------------
|
|
@@ -890,7 +857,6 @@ unsafe fn dispatch_case_d_tiled_bitmap(
|
|
| 890 |
// runs the two-clip path with the same flag-byte clamps.
|
| 891 |
unsafe fn dispatch_case_e_tiled_terrain(
|
| 892 |
display: *mut DisplayGfx,
|
| 893 |
-
vtable: *const DisplayGfxVtable,
|
| 894 |
clip: &ClipContext,
|
| 895 |
cmd: *const u32,
|
| 896 |
) {
|
|
@@ -945,7 +911,7 @@ unsafe fn dispatch_case_e_tiled_terrain(
|
|
| 945 |
}
|
| 946 |
let count = read_field(cmd, 7);
|
| 947 |
let flags = *(cmd.add(8));
|
| 948 |
-
(
|
| 949 |
}
|
| 950 |
|
| 951 |
// =============================================================================
|
|
|
|
| 291 |
});
|
| 292 |
|
| 293 |
let clip_ref: &ClipContext = &*clip;
|
|
|
|
| 294 |
|
| 295 |
// Walk from the highest index downward.
|
| 296 |
for i in (0..count).rev() {
|
| 297 |
let cmd = entries[i] as *const u32;
|
| 298 |
let cmd_type = *cmd;
|
| 299 |
match cmd_type {
|
| 300 |
+
0 => dispatch_case_0_fill_rect(display, clip_ref, cmd),
|
| 301 |
+
1 => dispatch_case_1_bitmap_global(display, cmd),
|
| 302 |
+
2 => dispatch_case_2_textbox_local(display, clip_ref, cmd),
|
| 303 |
+
3 => dispatch_case_3_via_callback(display, clip_ref, cmd),
|
| 304 |
+
4 => dispatch_case_4_sprite_global(display, cmd),
|
| 305 |
+
5 => dispatch_case_5_sprite_local(display, clip_ref, cmd),
|
| 306 |
+
6 => dispatch_case_6_sprite_offset(display, clip_ref, cmd),
|
| 307 |
+
7 => dispatch_case_7_polyline(display, cmd),
|
| 308 |
+
8 => dispatch_case_8_line_strip(display, clip_ref, cmd),
|
| 309 |
+
9 => dispatch_case_9_polygon(display, clip_ref, cmd),
|
| 310 |
+
0xA => dispatch_case_a_pixel_strip(display, clip_ref, cmd),
|
| 311 |
+
0xB => dispatch_case_b_crosshair(display, clip_ref, cmd),
|
| 312 |
+
0xC => dispatch_case_c_outlined_pixel(display, clip_ref, cmd),
|
| 313 |
+
0xD => dispatch_case_d_tiled_bitmap(display, clip_ref, cmd),
|
| 314 |
+
0xE => dispatch_case_e_tiled_terrain(display, clip_ref, cmd),
|
| 315 |
_ => { /* unknown command type β silently skipped, matching WA */ }
|
| 316 |
}
|
| 317 |
}
|
|
|
|
| 324 |
// Each case body mirrors the corresponding `case N:` arm of WA's
|
| 325 |
// `RenderDrawingQueue` (0x542350). Field offsets are the `puVar1[N]`
|
| 326 |
// indices from the decompile (each step = 4 bytes).
|
| 327 |
+
//
|
| 328 |
+
// Vtable dispatch goes through the auto-generated `DisplayGfx::*_raw`
|
| 329 |
+
// methods (from `bind_DisplayGfxVtable!(DisplayGfx, base.vtable)`),
|
| 330 |
+
// which take a raw `*mut DisplayGfx` to avoid creating `&mut self` β
|
| 331 |
+
// see the noalias rule in CLAUDE.md.
|
| 332 |
|
| 333 |
#[inline]
|
| 334 |
unsafe fn read_field(cmd: *const u32, idx: usize) -> i32 {
|
|
|
|
| 348 |
// if !iVar4 break;
|
| 349 |
// // x/y MIN-corner clamps to keep pixel-perfect rect edges
|
| 350 |
// vtable[18](this, x1>>16, y1>>16, x2>>16, y2>>16, cmd[2]);
|
| 351 |
+
unsafe fn dispatch_case_0_fill_rect(display: *mut DisplayGfx, clip: &ClipContext, cmd: *const u32) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
let mut x1 = Fixed::ZERO;
|
| 353 |
let mut y1 = Fixed::ZERO;
|
| 354 |
let mut x2 = Fixed::ZERO;
|
|
|
|
| 395 |
}
|
| 396 |
|
| 397 |
let color = *(cmd.add(2));
|
| 398 |
+
DisplayGfx::fill_rect_raw(
|
| 399 |
display,
|
| 400 |
x1.to_int(),
|
| 401 |
y1.to_int(),
|
|
|
|
| 410 |
// vtable[20](this, cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], cmd[9]);
|
| 411 |
//
|
| 412 |
// Pure passthrough β global bitmaps draw at the supplied world coords.
|
| 413 |
+
unsafe fn dispatch_case_1_bitmap_global(display: *mut DisplayGfx, cmd: *const u32) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 414 |
use crate::bitgrid::DisplayBitGrid;
|
| 415 |
let x = read_fixed(cmd, 2);
|
| 416 |
let y = read_fixed(cmd, 3);
|
|
|
|
| 420 |
let src_w = read_field(cmd, 7);
|
| 421 |
let src_h = read_field(cmd, 8);
|
| 422 |
let flags = *(cmd.add(9));
|
| 423 |
+
DisplayGfx::draw_scaled_sprite_raw(display, x, y, sprite, src_x, src_y, src_w, src_h, flags);
|
| 424 |
}
|
| 425 |
|
| 426 |
// ---- case 2: DRAW_TEXTBOX_LOCAL β slot 20 (draw_scaled_sprite) -------------
|
|
|
|
| 430 |
// `cmd+8` controlling whether the result clamps to the second clip pair.
|
| 431 |
unsafe fn dispatch_case_2_textbox_local(
|
| 432 |
display: *mut DisplayGfx,
|
|
|
|
| 433 |
clip: &ClipContext,
|
| 434 |
cmd: *const u32,
|
| 435 |
) {
|
|
|
|
| 489 |
let src_w = read_field(cmd, 10);
|
| 490 |
let src_h = read_field(cmd, 11);
|
| 491 |
let flags = *(cmd.add(12));
|
| 492 |
+
DisplayGfx::draw_scaled_sprite_raw(display, x1, y1, sprite, src_x, src_y, src_w, src_h, flags);
|
| 493 |
}
|
| 494 |
|
| 495 |
// ---- case 3 β slot 21 (draw_via_callback) ----------------------------------
|
|
|
|
| 499 |
// vtable[21](this, x, y, cmd[6], cmd[7], cmd[8]);
|
| 500 |
unsafe fn dispatch_case_3_via_callback(
|
| 501 |
display: *mut DisplayGfx,
|
|
|
|
| 502 |
clip: &ClipContext,
|
| 503 |
cmd: *const u32,
|
| 504 |
) {
|
|
|
|
| 519 |
let obj = read_field(cmd, 6) as *mut u8;
|
| 520 |
let p5 = *(cmd.add(7));
|
| 521 |
let p6 = *(cmd.add(8));
|
| 522 |
+
DisplayGfx::draw_via_callback_raw(display, x, y, obj, p5, p6);
|
| 523 |
}
|
| 524 |
|
| 525 |
// ---- case 4: DRAW_SPRITE_GLOBAL β slot 19 (blit_sprite) --------------------
|
| 526 |
//
|
| 527 |
// vtable[19](this, cmd[2], cmd[3], cmd[4], cmd[5]);
|
| 528 |
+
unsafe fn dispatch_case_4_sprite_global(display: *mut DisplayGfx, cmd: *const u32) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 529 |
let x = read_fixed(cmd, 2);
|
| 530 |
let y = read_fixed(cmd, 3);
|
| 531 |
let sprite_flags = *(cmd.add(4));
|
| 532 |
let palette = *(cmd.add(5));
|
| 533 |
+
DisplayGfx::blit_sprite_raw(display, x, y, sprite_flags, palette);
|
| 534 |
}
|
| 535 |
|
| 536 |
// ---- case 5: DRAW_SPRITE_LOCAL β slot 19 (blit_sprite) ---------------------
|
|
|
|
| 539 |
// vtable[19](this, x, y, cmd[4], cmd[5]);
|
| 540 |
unsafe fn dispatch_case_5_sprite_local(
|
| 541 |
display: *mut DisplayGfx,
|
|
|
|
| 542 |
clip: &ClipContext,
|
| 543 |
cmd: *const u32,
|
| 544 |
) {
|
|
|
|
| 547 |
rq_translate_coordinates(clip, read_fixed(cmd, 2), read_fixed(cmd, 3), &mut x, &mut y);
|
| 548 |
let sprite_flags = *(cmd.add(4));
|
| 549 |
let palette = *(cmd.add(5));
|
| 550 |
+
DisplayGfx::blit_sprite_raw(display, x, y, sprite_flags, palette);
|
| 551 |
}
|
| 552 |
|
| 553 |
// ---- case 6: DRAW_SPRITE_OFFSET β slot 19 (blit_sprite) --------------------
|
|
|
|
| 558 |
// screen-space offset sprites.
|
| 559 |
unsafe fn dispatch_case_6_sprite_offset(
|
| 560 |
display: *mut DisplayGfx,
|
|
|
|
| 561 |
clip: &ClipContext,
|
| 562 |
cmd: *const u32,
|
| 563 |
) {
|
|
|
|
| 621 |
|
| 622 |
let sprite_flags = *(cmd.add(7));
|
| 623 |
let palette = *(cmd.add(8));
|
| 624 |
+
DisplayGfx::blit_sprite_raw(display, x, y, sprite_flags, palette);
|
| 625 |
}
|
| 626 |
|
| 627 |
// ---- case 7 β slot 12 (draw_polyline) --------------------------------------
|
|
|
|
| 630 |
//
|
| 631 |
// `cmd[2]` is the vertex count, `cmd[3]` is the color, vertex data
|
| 632 |
// follows starting at `cmd[4]`.
|
| 633 |
+
unsafe fn dispatch_case_7_polyline(display: *mut DisplayGfx, cmd: *const u32) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 634 |
let points = cmd.add(4) as *mut i32;
|
| 635 |
let count = read_field(cmd, 2);
|
| 636 |
let color = *(cmd.add(3));
|
| 637 |
+
DisplayGfx::draw_polyline_raw(display, points, count, color);
|
| 638 |
}
|
| 639 |
|
| 640 |
// ---- case 8: DRAW_LINE_STRIP β slot 14 (draw_line_clipped) -----------------
|
|
|
|
| 644 |
// `cmd[3]` is the color shared by all segments.
|
| 645 |
unsafe fn dispatch_case_8_line_strip(
|
| 646 |
display: *mut DisplayGfx,
|
|
|
|
| 647 |
clip: &ClipContext,
|
| 648 |
cmd: *const u32,
|
| 649 |
) {
|
|
|
|
| 683 |
) {
|
| 684 |
break;
|
| 685 |
}
|
| 686 |
+
DisplayGfx::draw_line_clipped_raw(display, x1, y1, x2, y2, color);
|
| 687 |
x1 = x2;
|
| 688 |
y1 = y2;
|
| 689 |
vert = vert.add(3);
|
|
|
|
| 694 |
//
|
| 695 |
// Same shape as case 8 but with two color params (cmd[3], cmd[4]) and the
|
| 696 |
// first vertex starts at `cmd[5..8]`. Per-segment vertex stride is 3 u32s.
|
| 697 |
+
unsafe fn dispatch_case_9_polygon(display: *mut DisplayGfx, clip: &ClipContext, cmd: *const u32) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 698 |
let mut x1 = Fixed::ZERO;
|
| 699 |
let mut y1 = Fixed::ZERO;
|
| 700 |
let mut scale = Fixed::ZERO;
|
|
|
|
| 730 |
) {
|
| 731 |
break;
|
| 732 |
}
|
| 733 |
+
DisplayGfx::draw_line_raw(display, x1, y1, x2, y2, color1, color2);
|
| 734 |
x1 = x2;
|
| 735 |
y1 = y2;
|
| 736 |
vert = vert.add(3);
|
|
|
|
| 748 |
// vtable[15](this, x, y, cmd[4], cmd[5], cmd[6], cmd[7]);
|
| 749 |
unsafe fn dispatch_case_a_pixel_strip(
|
| 750 |
display: *mut DisplayGfx,
|
|
|
|
| 751 |
clip: &ClipContext,
|
| 752 |
cmd: *const u32,
|
| 753 |
) {
|
|
|
|
| 762 |
let dy = read_fixed(cmd, 5);
|
| 763 |
let count = read_field(cmd, 6);
|
| 764 |
let color = *(cmd.add(7));
|
| 765 |
+
DisplayGfx::draw_pixel_strip_raw(display, x, y, dx, dy, count, color);
|
| 766 |
}
|
| 767 |
|
| 768 |
// ---- case 0xB: DRAW_CROSSHAIR β slot 16 (draw_crosshair) -------------------
|
|
|
|
| 770 |
// iVar4 = RQ_ClipCoordinates(this, cmd[4], cmd[5], cmd[6], &x, &y, ..);
|
| 771 |
// if !iVar4 break;
|
| 772 |
// vtable[16](this, x>>16, y>>16, cmd[2], cmd[3]);
|
| 773 |
+
unsafe fn dispatch_case_b_crosshair(display: *mut DisplayGfx, clip: &ClipContext, cmd: *const u32) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 774 |
let mut x = Fixed::ZERO;
|
| 775 |
let mut y = Fixed::ZERO;
|
| 776 |
let mut scale = Fixed::ZERO;
|
|
|
|
| 787 |
}
|
| 788 |
let color_fg = *(cmd.add(2));
|
| 789 |
let color_bg = *(cmd.add(3));
|
| 790 |
+
DisplayGfx::draw_crosshair_raw(display, x.to_int(), y.to_int(), color_fg, color_bg);
|
| 791 |
}
|
| 792 |
|
| 793 |
// ---- case 0xC β slot 17 (draw_outlined_pixel) ------------------------------
|
|
|
|
| 797 |
// vtable[17](this, x>>16, y>>16, cmd[2], cmd[3]);
|
| 798 |
unsafe fn dispatch_case_c_outlined_pixel(
|
| 799 |
display: *mut DisplayGfx,
|
|
|
|
| 800 |
clip: &ClipContext,
|
| 801 |
cmd: *const u32,
|
| 802 |
) {
|
|
|
|
| 816 |
}
|
| 817 |
let color_fg = *(cmd.add(2));
|
| 818 |
let color_bg = read_field(cmd, 3);
|
| 819 |
+
DisplayGfx::draw_outlined_pixel_raw(display, x.to_int(), y.to_int(), color_fg, color_bg);
|
| 820 |
}
|
| 821 |
|
| 822 |
// ---- case 0xD: DRAW_TILED_BITMAP β slot 11 (draw_tiled_bitmap) -------------
|
|
|
|
| 827 |
// vtable[11](this, (flag ? 0 : x>>16), y>>16, cmd[4]);
|
| 828 |
unsafe fn dispatch_case_d_tiled_bitmap(
|
| 829 |
display: *mut DisplayGfx,
|
|
|
|
| 830 |
clip: &ClipContext,
|
| 831 |
cmd: *const u32,
|
| 832 |
) {
|
|
|
|
| 848 |
let flag_byte = *(cmd.add(5)) as u8;
|
| 849 |
let dest_x = if flag_byte != 0 { 0 } else { x.to_int() };
|
| 850 |
let source = read_field(cmd, 4) as *const TiledBitmapSource;
|
| 851 |
+
DisplayGfx::draw_tiled_bitmap_raw(display, dest_x, y.to_int(), source);
|
| 852 |
}
|
| 853 |
|
| 854 |
// ---- case 0xE β slot 22 (draw_tiled_terrain) -------------------------------
|
|
|
|
| 857 |
// runs the two-clip path with the same flag-byte clamps.
|
| 858 |
unsafe fn dispatch_case_e_tiled_terrain(
|
| 859 |
display: *mut DisplayGfx,
|
|
|
|
| 860 |
clip: &ClipContext,
|
| 861 |
cmd: *const u32,
|
| 862 |
) {
|
|
|
|
| 911 |
}
|
| 912 |
let count = read_field(cmd, 7);
|
| 913 |
let flags = *(cmd.add(8));
|
| 914 |
+
DisplayGfx::draw_tiled_terrain_raw(display, x, y, count, flags);
|
| 915 |
}
|
| 916 |
|
| 917 |
// =============================================================================
|