Native widescreen - #8
Merged
Merged
Conversation
The prompt was placed by constants for 640x480; it is computed from the picture globals, which 0x5c88ac already halves in the low-resolution mode. JP and OEM pinned.
The game renders at 1920x1080 itself (F4 and F5 Screen: 1280x720), in place of 640x480: about 250 sites over the retail executable and a blob of new code (asm/ui.asm) in an appended section. - mode, window, viewport globals, row tables and the coverage mask resized; the projection keeps the vertical field of view and shows more at the sides; the polygon pool is raised to 8000 - the 2D layer (backdrops, menus, HUD, text) is drawn on a 640x480 canvas and composited onto the viewport at scale, so it keeps its layout; HUD polygons are rescaled at insert to the same frame - split screen is side by side or top and bottom at full height, the timer and bars pinned to the viewport top, the machine select drawn once at full size - the ending credits lose their black bands: the roll enters at the bottom and leaves through the top, the strip watermarks floored and the tile planes' row-table overruns bounded - the enemy marker's on-screen window and the hangar's draw window follow the wider view; the credits prompt and the pause and loading text scale with the picture - the F5 dialog says 720p/1080p and Ver/Hor; the choice is saved - tools: uibuild.py builds the blob, vomap/votrans/hiresport.py map the sites onto the other builds, selftest.py pins every build's output and exercises the F4 table and the port path docs/HIRES.md is the design and the record of what the game does at each site, read off the disassembly. Retail only at this commit.
Three faults, all past the byte checks. Four MMX mask spans wrote retail's interleaved mov ecx,[FB_PITCH] verbatim, so the ported rasterizer loaded its row pointer from a retail address - the movq fault on both builds. JP's FOV block is 54 bytes to retail's 82, and the replacement ran into the viewport function's pointer stores - the null surface and blank screens. The credits jne-to-jmp sites kept retail's displacement and were rebased from the retail site, landing mid-instruction in JP's 2D engine. port_sites rebuilds mask spans from the build's bytes, routes a too-short FOV block through UI_FOV in the section, takes a jcc's displacement from the build and only rebases jumps into the sections; the F4 table and the activate recreate size are ported; the strip-loader stores pair by idiom and JP's engine-B roll site is mapped by hand. tools/portaudit.py and portdump.py check placements by instruction shape. Retail output unchanged; JP and OEM pinned.
The ending driver cuts the roll at frame 0x10e2, timed for the last line to be under the top band, which the patch no longer paints. Both thresholds move 80 frames: the last line's rows are off the top at 0x112e and back at the foot from 0x1136, and the blank feed clears only columns 9..59, so their right-hand tiles would show. All three builds re-pinned.
hiresport.py splits into resolve() and main(); portaudit.py reads the maps from it and portdump.py goes. port_sites takes the section address instead of a magic bound, reads the mask spans' interleave length from the table, and returns the FOV block once. Builds carry their PE stamp. The marker window reuses the hangar's margin. Retail-only wording out of the tip, README, NOTES and the docs index; the section header and HIRES.md name the roll cut, the marker window and what port_sites redoes per build. No byte changes.
The size the game passes for the intro movie is its 16:10 window; von.avi is 4:3 with the picture letterboxed inside it (rows 30..209, 16:9), and mciavi stretches to the window. The stub asks mciavi for the frame size - WHERE_SOURCE with WHERE_MAX, since the placement runs more than once and a plain WHERE returns the rect set last time - fits the picture band and sends it as the PUT source rect, with the game's numbers and no crop as the fallback. README's widescreen caveat trimmed to what a player needs. All three builds re-pinned.
On 2D-only screens a top row of one colour fills the margins with it, so the splash and title reach the screen edges in white; anything patterned gets black. All three builds re-pinned.
The encounter grid and the noise transition are 8-px tiles on plane B (the grid a 2x4-tile pattern, the static a 40x8-tile block under random whole-tile scrolls), not generated. In the pre-3D phase the canvas is the viewport's aspect with the picture centred (D_XO); the blob then walks the engine's ring through the game's own destination and blit helpers for the columns either side, each showing what the picture shows at its column mod 80, so seams are the walker's own. Only rows with no empty tile are continued; others take the flat colour as before. The scan for painting past 4:3 and the viewport fill go. The port tool reads each engine's ring, scroll, watermarks and helpers off the build's own walker. Verified under Unicorn on all three patched builds. All three re-pinned.
0x480410 halves its coordinates whenever 0x6bc948 is set; pre hides the flag from the game's walker but post had restored it before the margins were drawn, so their tiles landed at half scale, over the picture on the right. All three re-pinned.
fit built 1/s as (2^24 / s) << 8, dropping the low byte: 0.68% short at 2.25, so the 2D layer was stretched, its last columns and rows never shown, text drifted right and down against the HUD polygons, and the encounter grid measured 48.33 px. Now 2^32 / s rounded up; the 3 px polygon shift that compensated is zero. All three re-pinned.
Nine sites, the same shape as renderer A's: pool, side array, flush list and the three caps (2000 in B's inserts, 2500 in its flush). The port tool pairs both renderers' cap and lea sites by order. All three re-pinned.
Zeroed with the exact composite reciprocal; the data words, the two adds in pre and UI_SHIFT are now removed. All three re-pinned.
Native widescreen and Gamepad now come before Internet play; the quick start no longer says widescreen starts unticked; shorter paragraphs and subheadings; every picture with a descriptive alt text.
The star field starts further left by the extra width in columns, and the moon card's commit goes through credits_moon, which scales it to the full height.
The flash is the unit quad drawn as a grid of tiles through attribute block 0x791ad0, sized a fifth over the 4:3 frame, so it stopped 80 px short of each edge at 1080p. fill, run by both insert hooks after the pass rescale, pushes the edge tiles' outer vertices to the viewport's edges in a round (D_ROUND, from the patcher's round list). D_CMOON and D_ROUND, which had been placed on D_F4WANT and D_XO, get slots of their own.
Attaches to v_on.exe under Wine by pid. Modes: who draws a pixel, the paint order at a spot, writers of an address, a break with backtrace, a hex dump, and the ones that found the lock-on line - wedge (every write to a pixel with its record, to a log), submit (records of one attribute block at the insert, with the submitter), clip (polygons of one attribute block at the clipper) and proj2d (2D quads projected at a z other than 1.0).
So it clears the roll's window at the full height.
The object drawer picks an object's solid or meshed model by the camera yaw against the object's authored direction code, meshed outside a window of 0x4800 (0x3800 on the eight-way stages). The codes are 90-degree quantised, so an object beside the machine meshed once the yaw was 11 degrees past square to it: at 4:3 that is at the picture's edge, at 16:9 while it is whole on screen. Both windows get 22.5 degrees more; an object behind the machine is 135 degrees or more off and still meshes.
The damage flash's attribute block 0x791ad0 is the game's flat red; the off-screen arrow is drawn with it too, and the last step of its slide put its tip on the frame inset, where fill threw it to the viewport edge. fill now skips polygons under 120 HUD units wide.
The flat grey band that flashed across the picture as the enemy came on from the side is the marker's leader line to the distance readout, in pieces, 600 times its size: the 2D quad submits project their z = 1.0 vertices with the aspect slot of the projection, and the clipper re-projects what it clips or subdivides with the 3D slot, focal length included. Stock does it at 640x480 too, from 362 px of line. asm/lockline.asm, applied to every build with or without Native widescreen: the 2D quad submits' and mesh walkers' prologues call it to flag the renderer, and the clippers' eleven fdivr sites per renderer divide by the aspect slot while the flag is up. Site maps for JP and OEM by byte signature. The resolution blob's layout is as it was.
The machine select and network waiting cards draw a 64x48-tile photo at plane B's low-resolution window, 512x384 of the picture, framed in black. margins recognises the three blocks by two cell values and rescales the photo over the whole canvas from a staged copy, keeping its aspect (full width, top and bottom cropped at 16:9; the full picture at 4:3). Plane A and the sprites are drawn after, so text and cursors are untouched. The blob had 21 bytes free, so the pass stubs, data block and F4 table move down 0x400 (D_BASE 0x1c00, UI_F4TAB_OFF 0x1f00). Port tables regenerated; MD5s re-pinned for all three builds.
On a viewport wider than 4:3 the centred HUD frame carried the timer and the bars towards the middle. In a round the 2D layer's band rows and the in-game HUD pass's polygons in them move outward by the frame's inset - the timer left, PLAYER/ENEMY and the bars right - so each keeps its 4:3 distance from the nearest edge; the TOTAL time moves right the same way. 1P and top/bottom split; side by side has no inset. hud_enter records the outermost pass's stub so rescale can tell the bars' pass from the marker's. Port tables regenerated; MD5s re-pinned.
ui.asm header rewritten for what the blob does now (aspect canvas, photo backdrops, HUD spread); D_RETD filed with D_RETS; the patcher- written data listed. HIRES.md: sprites claim on the photo screens dropped, the spread's pass gating stated correctly (the marker is outside the passes in a round), stale cross-reference, two long lines, the site count, and Rebuilding now covers the port tables and the pins. UI_PASS_FUNCS comments name the reticle and the demo drivers. uibuild's data-overlap bound follows the moved block. Patcher tip and README mention the HUD anchoring and the photo screens. DEVELOPING's daily loop points at the port-table step.
post compares each canvas row against the copy once (repe cmpsd) and skips every viewport row that samples an unchanged one, which is most of the HUD phase. rescale's y side keeps its temporaries in ebp instead of push/pop; extents' labels are its own; the pass gate and stub size are named. Insert comment corrected: both writers file four vertices. Port tables regenerated; MD5s re-pinned.
…rgins in the debug readout The spread now moves only the timer (and the TOTAL time); PLAYER/ENEMY and the bars keep the centred frame. Top/bottom split draws the HUD at the side-by-side scale, capped so frame rows 48..432 stay on screen (HIRES_HUD_TB_ROWS), instead of the 4:3 that fits the half-height viewport. HIRES_DEBUG_STATES also prints margins' scroll and the two photo cells, to diagnose a photo backdrop that is not rescaled. Port tables regenerated; MD5s re-pinned.
In stock the labels and bar frames span 233..523 of the 640 frame, centre 378. In a round they move by 320 - HIRES_HUD_BARS units (-58), 2D layer and polygons alike, on every layout; the timer's inset shift and the TOTAL time are unchanged. Port tables regenerated; MD5s re-pinned.
…e stock layout spread_row applied D_BARDX as viewport px, so the labels moved 58 px where the bar polygons moved 58 units (130 px at 1080p) and the two overlapped. The shift is now scaled by the 2D scale. The bar centring is gated on the inset again, so side by side, which has no room for it, is stock. Port tables regenerated; MD5s re-pinned.
The ring reads back with every tile index of a block lowered by one constant (0x2380 as 0x154e on the select): the loader rebases the block to its bank slot after the memcpy, so the two-cell signature never matched. margins now compares the differences of cells (32, 24) and (0, 47) against (0, 0), which the rebase preserves. Port tables regenerated; MD5s re-pinned.
margins now runs for side by side too, for the photo alone: each engine's canvas is 4:3, so a card's 512x384 becomes the 640x480 and fills its half's width. Top/bottom is left as is; the rows its viewport keeps are the photo's own. Port tables regenerated; MD5s re-pinned.
The last two tile columns of all three blocks are the blank tile, so the rescale took 16 px of black along with the picture and left a strip on the right (58 px at 1080p). The source is 496x384 now. Port tables regenerated; MD5s re-pinned.
The checks this branch's changes were verified with, committed as a check: the game's plane B walker plus the blob with a rebased photo block (1P, single viewport for either engine, side by side), the HUD spread's 2D and polygon positions, the pre-fill against the viewport, the no-op composite, the layouts' insets, top/bottom's row cut and side by side's band pin. Runs from check.py on a retail exe; passes with a note without nasm or unicorn. uibuild exports the three labels it calls. rescale computes the band row once for both offsets. Port tables regenerated; MD5s re-pinned.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The game at 1920x1080 (1280x720 on F4), rendered rather than scaled: every 640x480 assumption rewritten, the 2D layer through a canvas in an appended section, HUD polygons rescaled at insert, split screen as two real viewports, the ending roll without its bands. Translated onto the JP and OEM builds by generated tables.
Since the branch was opened: the two-player photo screens fill the viewport, the timer keeps to the top-left corner and the health bars are centred as a group on wide viewports, top/bottom split draws the HUD at the side-by-side size, the compositor skips untouched rows, and tools/uiemu.py runs the blob under Unicorn as a check.
Design, the game structures it rests on and the porting record are in docs/HIRES.md. 28 files, +8534 -561.