Download crates/openwa-core/src/render/display/context.rs from nmarshall/wormz-a: direct link, hf CLI and curl.
- Browser
- Download file 15.2 kB
-
https://huggingface.co/nmarshall/wormz-a/resolve/main/crates/openwa-core/src/render/display/context.rs
- Command line
-
hf download hf://nmarshall/wormz-a/crates/openwa-core/src/render/display/context.rs
-
curl -L -o context.rs https://huggingface.co/nmarshall/wormz-a/resolve/main/crates/openwa-core/src/render/display/context.rs
15.2 kB
| // RenderContext β CWormsApp rendering dispatch subobject. | |
| // Manages the software framebuffer and dispatches rendering calls to the active | |
| // renderer backend (CompatRenderer, OpenGLCPU, or DDraw). | |
| crate::define_addresses! { | |
| class "CWormsApp" { | |
| /// CWormsApp__FlipSurface β dispatches to renderer backend vtable[1] | |
| fn/Fastcall CWORMSAPP_FLIP_SURFACE = 0x005A_2700; | |
| /// ConstructFrameBuffer β allocates software framebuffer, inits renderer | |
| fn/Fastcall CONSTRUCT_FRAME_BUFFER_THISCALL = 0x005A_2430; | |
| /// CWormsApp__ReleaseFrameBuffer | |
| fn/Fastcall CWORMSAPP_RELEASE_FRAME_BUFFER = 0x005A_24A0; | |
| /// CWormsApp__FillRect β lock surface, memset rows, unlock | |
| fn/Fastcall CWORMSAPP_FILL_RECT = 0x005A_25C0; | |
| /// CWormsApp__BlitToFrameBuffer β optimized blit from surface to framebuffer | |
| fn/Fastcall CWORMSAPP_BLIT_TO_FRAME_BUFFER = 0x005A_2A40; | |
| /// CWormsApp__DrawLandscape β blit with clipping and transparency | |
| fn/Fastcall CWORMSAPP_DRAW_LANDSCAPE = 0x005A_2790; | |
| /// ClearFrameBuffer β memset(framebuffer, 0, w*h) | |
| fn CWORMSAPP_CLEAR_FRAME_BUFFER = 0x005A_23F0; | |
| } | |
| } | |
| /// Result buffer for RenderContext and CompatRenderer `__fastcall` vtable calls. | |
| /// | |
| /// These classes use `__fastcall` convention: ECX = this, EDX = result buffer pointer. | |
| /// The callee writes a result (typically an HRESULT or pointer) into `value` and | |
| /// returns `EDX` in `EAX`. Most callers allocate this on the stack and ignore the result. | |
| pub struct FastcallResult { | |
| pub value: u32, | |
| _pad: u32, | |
| } | |
| /// RenderContext vtable (0x662EC8, 25 slots). | |
| /// | |
| /// Many slots are thin thunks that forward to the renderer backend | |
| /// via `*(this+0x18)->vtable[N]`. Others manage the software framebuffer | |
| /// or perform blitting directly. | |
| /// | |
| /// ## Calling convention | |
| /// | |
| /// All methods use `__fastcall`: ECX = this, EDX = `*mut FastcallResult` (caller-allocated | |
| /// 8-byte result buffer). Remaining parameters are on the stack, callee-cleaned. | |
| /// Most callers ignore the result value. | |
| /// | |
| /// ## Slot categories | |
| /// | |
| /// - **Renderer thunks** (0, 2, 4, 5, 8, 10, 11): Forward to backend | |
| /// - **Framebuffer management** (3, 6, 7, 9, 15/17, 16/18, 20): Manage G_FRAME_BUFFER_* | |
| /// - **Blitting** (19, 23, 24): FillRect, DrawLandscape, BlitToFrameBuffer | |
| /// - **Surface management** (12, 13, 22): Renderer queries and surface allocation | |
| /// - **Stub** (14): Returns 0 | |
| pub struct RenderContextVtable { | |
| /// renderer thunk -> backend vtable[0] (init/create) (0x4E3420, RET 0x8) | |
| pub renderer_init: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| p2: u32, | |
| p3: u32, | |
| ) -> *mut FastcallResult, | |
| /// flip/present β dispatches to renderer backend vtable[1] (0x5A2700) | |
| pub flip_surface: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// renderer thunk -> backend vtable[2] (reset state) (0x4E3440) | |
| pub renderer_reset: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// get framebuffer dimensions β reads G_FRAME_BUFFER_WIDTH/HEIGHT (0x5A2660, RET 0x4) | |
| pub get_framebuffer_dims: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| out: *mut u32, | |
| ) -> *mut FastcallResult, | |
| /// renderer thunk -> backend vtable[4] (enum display modes) (0x4E3460, RET 0x8) | |
| pub renderer_enum_modes: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| p2: u32, | |
| p3: u32, | |
| ) -> *mut FastcallResult, | |
| /// renderer thunk -> backend vtable[5] (tail jump) (0x4E3480) | |
| pub renderer_slot5: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// construct framebuffer β wa_malloc(w*h), init renderer (0x5A2430, RET 0x8) | |
| pub construct_frame_buffer: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| width: i32, | |
| height: i32, | |
| ) -> *mut FastcallResult, | |
| /// release framebuffer β calls renderer teardown, frees buffer (0x5A24A0) | |
| pub release_frame_buffer: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| p2: i32, | |
| ) -> *mut FastcallResult, | |
| /// renderer thunk -> backend vtable[8] (0x5A24F0) | |
| pub renderer_slot8: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// lock framebuffer for pixel access (0x5A2530) | |
| /// | |
| /// Returns framebuffer pointer and stride for direct pixel manipulation. | |
| pub lock_framebuffer: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| p2: u32, | |
| p3: u32, | |
| p4: u32, | |
| p5: u32, | |
| ) -> *mut FastcallResult, | |
| /// renderer thunk -> backend vtable[10] (0x5A2510) | |
| pub renderer_restore_dims: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// renderer thunk -> backend vtable[11] (restore surface) (0x5A25A0) | |
| pub renderer_restore_surface: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// allocate error/result object (0x5A2720, RET 0x4) | |
| pub alloc_error_result: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| p2: u32, | |
| ) -> *mut FastcallResult, | |
| /// get renderer surface pointer (0x5A26C0) | |
| /// | |
| /// Queries `renderer->vtable[12]` with G_FRAME_BUFFER_PTR. | |
| pub get_renderer_surface: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// stub β returns 0 (CGameTask__vt18, 0x545780) | |
| pub stub_ret_zero: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// lock surface for reading (0x5A2690, RET 0x8) | |
| /// | |
| /// Writes framebuffer pointer to `*out_data` and stride to `*out_stride`. | |
| pub lock_surface_read: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| out_data: *mut u32, | |
| out_stride: *mut u32, | |
| ) -> *mut FastcallResult, | |
| /// unlock surface (0x5A2C10, RET 0x4) | |
| /// | |
| /// No-op for software framebuffer β just returns success code. | |
| pub unlock_surface_read: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| p2: u32, | |
| ) -> *mut FastcallResult, | |
| /// lock surface for writing (0x5A2690 β same fn as slot 15, RET 0x8) | |
| /// | |
| /// Writes framebuffer pointer to `*out_data` and stride to `*out_stride`. | |
| pub lock_surface_write: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| out_data: *mut *mut u8, | |
| out_stride: *mut u32, | |
| ) -> *mut FastcallResult, | |
| /// unlock surface after writing (0x5A2C10 β same fn as slot 16, RET 0x4) | |
| /// | |
| /// `data` is the framebuffer pointer previously returned from | |
| /// `lock_surface_write`. The original ignores it; we still pass it | |
| /// through for fidelity. | |
| pub unlock_surface_write: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| data: *mut u8, | |
| ) -> *mut FastcallResult, | |
| /// fill rectangle β lock, memset rows, unlock (0x5A25C0) | |
| /// | |
| /// Params: x, y, width, height, fill_value. | |
| pub fill_rect: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| x: i32, | |
| y: i32, | |
| width: i32, | |
| height: i32, | |
| fill_value: u32, | |
| ) -> *mut FastcallResult, | |
| /// clear framebuffer β memset(ptr, 0, w*h) (0x5A23F0) | |
| pub clear_frame_buffer: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// trampoline to slot 20 via vtable dispatch (0x5A2420) | |
| pub clear_frame_buffer_indirect: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// allocate surface object β wa_malloc(0x14) (0x5A2760) | |
| pub alloc_surface: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// draw landscape β blit a `Surface` to the framebuffer with optional | |
| /// color-key transparency (0x5A2790). | |
| /// | |
| /// 8 stack args (verified by RET 0x20 at 0x5a2cba): | |
| /// - `surface`: source `Surface*` (its vtable's slot 17 = lock-write, | |
| /// slot 18 = unlock are dispatched internally to read pixel data) | |
| /// - `dst_x`/`dst_y`: framebuffer destination top-left | |
| /// - `src_x`/`src_y`: rect origin within the surface to copy from | |
| /// - `width`/`height`: rect size | |
| /// - `flags`: bit 1 (`0x2`) = use color-key transparency (skip pixels | |
| /// equal to the surface's color-key); bit 0 (`0x1`) is set by the | |
| /// caller in `BlitBitmapClipped` and is reserved/ignored by the | |
| /// blit loop here. | |
| /// | |
| /// Used by `DisplayGfx::DrawTiledBitmap` (slot 11) and | |
| /// `DisplayGfx::DrawTiledTerrain` (slot 22) via the `CBitmap` blit | |
| /// helper at `FUN_00403c60`. | |
| pub draw_landscape: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| surface: *mut u8, | |
| dst_x: i32, | |
| dst_y: i32, | |
| src_x: i32, | |
| src_y: i32, | |
| width: i32, | |
| height: i32, | |
| flags: u32, | |
| ) -> *mut FastcallResult, | |
| /// blit surface to framebuffer β optimized copy with stride alignment (0x5A2A40) | |
| pub blit_to_frame_buffer: unsafe extern "fastcall" fn( | |
| this: *mut RenderContext, | |
| result: *mut FastcallResult, | |
| surface: *mut u8, | |
| y_offset: i32, | |
| ) -> *mut FastcallResult, | |
| } | |
| /// RenderContext β CWormsApp rendering dispatch subobject. | |
| /// | |
| /// Stored as a global pointer at 0x79D6D4 (g_RenderContext). | |
| /// The full object layout is part of CWormsApp; only key fields are mapped here. | |
| pub struct RenderContext { | |
| /// 0x00: Vtable pointer (0x662EC8) | |
| pub vtable: *const RenderContextVtable, | |
| /// 0x04-0x17: Unknown (part of CWormsApp layout) | |
| pub _unknown_04: [u8; 0x14], | |
| /// 0x18: Pointer to renderer backend (CompatRenderer, OpenGLCPU, or DDraw object) | |
| pub renderer_backend: *mut u8, | |
| } | |
| const _: () = assert!(core::mem::size_of::<RenderContext>() == 0x1C); | |
| // Generate calling wrappers: RenderContext::get_renderer_surface_raw(), etc. | |
| // Use the `_raw` variants to avoid LLVM noalias miscompilation. | |
| // Callers must pass a `&mut FastcallResult` buffer (allocated on the stack). | |
| bind_RenderContextVtable!(RenderContext, vtable); | |
| // --------------------------------------------------------------------------- | |
| // Surface β DDraw/D3D/OpenGL surface object created by alloc_surface (slot 22) | |
| // --------------------------------------------------------------------------- | |
| /// Vtable for `Surface` objects allocated by `RenderContext::alloc_surface` | |
| /// (slot 22). This is the rendering-backend surface interface β different | |
| /// backends (CompatRenderer / OpenGLCPU / DDraw) implement different vtables | |
| /// at the same slot positions. | |
| /// | |
| /// Slots typed here are the ones used by `DisplayGfx::DrawTiledBitmap` | |
| /// (slot 11) and `LoadSpriteByName` (which already uses raw transmutes). | |
| /// The remaining slots are unmapped β extend as needed. | |
| /// | |
| /// All slots are `__fastcall(this, *FastcallResult, ...args)`. The | |
| /// `FastcallResult.value` field receives a non-zero failure code on | |
| /// `init_surface` failure (slot 11 retries with bpp=4 if bpp=8 fails). | |
| pub struct SurfaceVtable { | |
| /// lock surface for direct pixel access (slot 3). | |
| /// | |
| /// Writes the locked surface base pointer to `*out_data` and the row | |
| /// stride (bytes between rows) to `*out_stride`. | |
| pub lock_surface: unsafe extern "fastcall" fn( | |
| this: *mut Surface, | |
| result: *mut FastcallResult, | |
| out_data: *mut *mut u8, | |
| out_stride: *mut i32, | |
| ) -> *mut FastcallResult, | |
| /// unlock surface after editing (slot 4). | |
| /// | |
| /// `addr` is the surface base pointer previously obtained from | |
| /// `lock_surface`'s `out_data`. | |
| pub unlock_surface: unsafe extern "fastcall" fn( | |
| this: *mut Surface, | |
| result: *mut FastcallResult, | |
| addr: *mut u8, | |
| ) -> *mut FastcallResult, | |
| /// init/recreate surface storage (slot 5). | |
| /// | |
| /// `(width, height, bpp)`. Returns 0 in `*result.value` on success; | |
| /// non-zero on failure. | |
| pub init_surface: unsafe extern "fastcall" fn( | |
| this: *mut Surface, | |
| result: *mut FastcallResult, | |
| width: i32, | |
| height: i32, | |
| bpp: i32, | |
| ) -> *mut FastcallResult, | |
| /// release surface backing storage (slot 6). | |
| /// | |
| /// Pure fastcall β no stack args. Writes a result code into | |
| /// `*result.value` (which most callers ignore). Called from the | |
| /// `DisplayGfx` destructor's CBitmap-vec teardown loop on every | |
| /// non-null `CBitmap.surface` before the bitmap itself is freed. | |
| pub release: unsafe extern "fastcall" fn( | |
| this: *mut Surface, | |
| result: *mut FastcallResult, | |
| ) -> *mut FastcallResult, | |
| /// set color-key (transparency) (slot 7). | |
| /// | |
| /// Used by `load_sprite_by_name` after `init_surface` to enable | |
| /// transparency on the freshly-allocated frame surface (color key | |
| /// `0`, flag `0x10`). The result code is unused by all known callers. | |
| pub set_color_key: unsafe extern "fastcall" fn( | |
| this: *mut Surface, | |
| result: *mut FastcallResult, | |
| color_key: u32, | |
| flags: u32, | |
| ) -> *mut FastcallResult, | |
| } | |
| /// Backend-specific surface object created by | |
| /// `RenderContext::alloc_surface` (slot 22). Layout beyond the vtable | |
| /// pointer is opaque (varies by backend); we only access it through the | |
| /// `SurfaceVtable` slots. | |
| pub struct Surface { | |
| /// 0x00: vtable pointer (one of several backend vtables) | |
| pub vtable: *const SurfaceVtable, | |
| } | |
| bind_SurfaceVtable!(Surface, vtable); | |