paavohtl Claude Opus 4.6 (1M context) commited on
Commit
0212bb3
·
1 Parent(s): eecea70

feat: port DDDisplay draw_line, draw_line_clipped, draw_pixel_strip

Browse files

draw_line (slot 13) and draw_line_clipped (slot 14) apply Fixed-point
camera offset and delegate to BitGrid line-drawing routines at 0x4F7A60
and 0x4F7500 (both stdcall). draw_pixel_strip (slot 15) iterates
count+1 pixels along a Fixed-point vector using put_pixel_clipped.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

crates/openwa-core/src/address.rs CHANGED
@@ -73,7 +73,8 @@ pub mod va {
73
  pub use crate::display::base::DISPLAY_BASE_VTABLE;
74
  pub use crate::display::bitgrid::{
75
  BitGridBaseVtable, BitGridCollisionVtable, BitGridDisplayVtable, BIT_GRID_BASE_VTABLE,
76
- BIT_GRID_COLLISION_VTABLE, BIT_GRID_DISPLAY_VTABLE, BIT_GRID_INIT,
 
77
  };
78
  pub use crate::display::compat_renderer::{
79
  CompatRendererVtable, COMPAT_RENDERER_VTABLE, DDRAW8_RENDERER_VTABLE,
 
73
  pub use crate::display::base::DISPLAY_BASE_VTABLE;
74
  pub use crate::display::bitgrid::{
75
  BitGridBaseVtable, BitGridCollisionVtable, BitGridDisplayVtable, BIT_GRID_BASE_VTABLE,
76
+ BIT_GRID_COLLISION_VTABLE, BIT_GRID_DISPLAY_VTABLE, BIT_GRID_INIT, DRAW_LINE_CLIPPED,
77
+ DRAW_LINE_TWO_COLOR,
78
  };
79
  pub use crate::display::compat_renderer::{
80
  CompatRendererVtable, COMPAT_RENDERER_VTABLE, DDRAW8_RENDERER_VTABLE,
crates/openwa-core/src/display/bitgrid.rs CHANGED
@@ -44,6 +44,10 @@ crate::define_addresses! {
44
  class "BitGrid" {
45
  /// BitGrid::init (0x4F6370) — allocates buffer, sets base vtable
46
  fn BIT_GRID_INIT = 0x004F_6370;
 
 
 
 
47
  }
48
  }
49
 
 
44
  class "BitGrid" {
45
  /// BitGrid::init (0x4F6370) — allocates buffer, sets base vtable
46
  fn BIT_GRID_INIT = 0x004F_6370;
47
+ /// Clipped line draw on 8bpp BitGrid (0x4F7500)
48
+ fn DRAW_LINE_CLIPPED = 0x004F_7500;
49
+ /// Two-color line draw on 8bpp BitGrid (0x4F7A60)
50
+ fn DRAW_LINE_TWO_COLOR = 0x004F_7A60;
51
  }
52
  }
53
 
crates/openwa-core/src/display/dd_display.rs CHANGED
@@ -640,3 +640,105 @@ pub unsafe extern "thiscall" fn draw_crosshair(
640
  DisplayBitGrid::put_pixel_clipped_raw(layer, cx, cy + 1, fg);
641
  DisplayBitGrid::put_pixel_clipped_raw(layer, cx + 1, cy + 1, fg);
642
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
640
  DisplayBitGrid::put_pixel_clipped_raw(layer, cx, cy + 1, fg);
641
  DisplayBitGrid::put_pixel_clipped_raw(layer, cx + 1, cy + 1, fg);
642
  }
643
+
644
+ /// Port of DDDisplay::DrawLine (vtable slot 13, 0x56BDB0).
645
+ ///
646
+ /// Draws a two-color line. Fixed-point coordinates with camera offset
647
+ /// applied as `camera * 0x10000 + coord`. Delegates to the BitGrid
648
+ /// line-drawing routine at 0x4F7A60.
649
+ ///
650
+ /// # Safety
651
+ /// `this` must be a valid `*mut DDDisplay` (actually a `*mut DisplayGfx`).
652
+ pub unsafe extern "thiscall" fn draw_line(
653
+ this: *mut DDDisplay,
654
+ x1: Fixed,
655
+ y1: Fixed,
656
+ x2: Fixed,
657
+ y2: Fixed,
658
+ color1: u32,
659
+ color2: u32,
660
+ ) {
661
+ let gfx = this as *mut DisplayGfx;
662
+ let cam_x = Fixed::from_int((*gfx).camera_x);
663
+ let cam_y = Fixed::from_int((*gfx).camera_y);
664
+
665
+ acquire_render_lock(gfx);
666
+
667
+ let draw: unsafe extern "stdcall" fn(*mut DisplayBitGrid, i32, i32, i32, i32, u32, u32) =
668
+ core::mem::transmute(rb(va::DRAW_LINE_TWO_COLOR) as usize);
669
+ draw(
670
+ (*gfx).layer_0,
671
+ (x1 + cam_x).to_raw(),
672
+ (y1 + cam_y).to_raw(),
673
+ (x2 + cam_x).to_raw(),
674
+ (y2 + cam_y).to_raw(),
675
+ color1,
676
+ color2,
677
+ );
678
+ }
679
+
680
+ /// Port of DDDisplay::DrawLineClipped (vtable slot 14, 0x56BD50).
681
+ ///
682
+ /// Draws a single-color clipped line. Fixed-point coordinates with camera
683
+ /// offset. Delegates to the BitGrid clipped line routine at 0x4F7500.
684
+ ///
685
+ /// # Safety
686
+ /// `this` must be a valid `*mut DDDisplay` (actually a `*mut DisplayGfx`).
687
+ pub unsafe extern "thiscall" fn draw_line_clipped(
688
+ this: *mut DDDisplay,
689
+ x1: Fixed,
690
+ y1: Fixed,
691
+ x2: Fixed,
692
+ y2: Fixed,
693
+ color: u32,
694
+ ) {
695
+ let gfx = this as *mut DisplayGfx;
696
+ let cam_x = Fixed::from_int((*gfx).camera_x);
697
+ let cam_y = Fixed::from_int((*gfx).camera_y);
698
+
699
+ acquire_render_lock(gfx);
700
+
701
+ let draw: unsafe extern "stdcall" fn(*mut DisplayBitGrid, i32, i32, i32, i32, u32) =
702
+ core::mem::transmute(rb(va::DRAW_LINE_CLIPPED) as usize);
703
+ draw(
704
+ (*gfx).layer_0,
705
+ (x1 + cam_x).to_raw(),
706
+ (y1 + cam_y).to_raw(),
707
+ (x2 + cam_x).to_raw(),
708
+ (y2 + cam_y).to_raw(),
709
+ color,
710
+ );
711
+ }
712
+
713
+ /// Port of DDDisplay::DrawPixelStrip (vtable slot 15, 0x56BE10).
714
+ ///
715
+ /// Draws `count + 1` pixels starting at (x, y), stepping by (dx, dy) each
716
+ /// iteration. All coordinates are Fixed-point. Camera applied as
717
+ /// `camera * 0x10000 + coord`.
718
+ ///
719
+ /// # Safety
720
+ /// `this` must be a valid `*mut DDDisplay` (actually a `*mut DisplayGfx`).
721
+ pub unsafe extern "thiscall" fn draw_pixel_strip(
722
+ this: *mut DDDisplay,
723
+ x: Fixed,
724
+ y: Fixed,
725
+ dx: Fixed,
726
+ dy: Fixed,
727
+ count: i32,
728
+ color: u32,
729
+ ) {
730
+ let gfx = this as *mut DisplayGfx;
731
+ let mut cx = Fixed::from_int((*gfx).camera_x) + x;
732
+ let mut cy = Fixed::from_int((*gfx).camera_y) + y;
733
+
734
+ acquire_render_lock(gfx);
735
+
736
+ let layer = (*gfx).layer_0;
737
+ if count >= 0 {
738
+ for _ in 0..=count {
739
+ DisplayBitGrid::put_pixel_clipped_raw(layer, cx.to_int(), cy.to_int(), color as u8);
740
+ cx += dx;
741
+ cy += dy;
742
+ }
743
+ }
744
+ }
crates/openwa-dll/src/replacements/display.rs CHANGED
@@ -82,6 +82,9 @@ pub fn install() -> Result<(), String> {
82
  // Patch DDDisplay vtable (0x66A218): replace ported methods with Rust.
83
  vtable_replace!(DDDisplayVtable, va::DD_DISPLAY_VTABLE, {
84
  get_dimensions => dd_display::get_dimensions,
 
 
 
85
  draw_crosshair => dd_display::draw_crosshair,
86
  draw_outlined_pixel => dd_display::draw_outlined_pixel,
87
  fill_rect => dd_display::fill_rect,
@@ -89,7 +92,7 @@ pub fn install() -> Result<(), String> {
89
  set_camera_offset => dd_display::set_camera_offset,
90
  set_clip_rect => dd_display::set_clip_rect,
91
  })?;
92
- let _ = log_line("[Display] DDDisplay: patched 7 methods → Rust");
93
  }
94
 
95
  Ok(())
 
82
  // Patch DDDisplay vtable (0x66A218): replace ported methods with Rust.
83
  vtable_replace!(DDDisplayVtable, va::DD_DISPLAY_VTABLE, {
84
  get_dimensions => dd_display::get_dimensions,
85
+ draw_line => dd_display::draw_line,
86
+ draw_line_clipped => dd_display::draw_line_clipped,
87
+ draw_pixel_strip => dd_display::draw_pixel_strip,
88
  draw_crosshair => dd_display::draw_crosshair,
89
  draw_outlined_pixel => dd_display::draw_outlined_pixel,
90
  fill_rect => dd_display::fill_rect,
 
92
  set_camera_offset => dd_display::set_camera_offset,
93
  set_clip_rect => dd_display::set_clip_rect,
94
  })?;
95
+ let _ = log_line("[Display] DDDisplay: patched 10 methods → Rust");
96
  }
97
 
98
  Ok(())