aa294071f9a24fc8094880fbc718c7aa37b4a235
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
aa294071f9 |
The render target is the size that was asked for
A crosshair off-centre on the second race, and underneath it every race after the first was a different race. Windowed, BackBufferWidth/Height were left at zero, so D3D sized the back buffer to the device window's client area at the moment the device was created. Everything downstream is built from the size we ASKED for instead - the projection matrix takes its aspect from it, the reticle is centred on it - so a window that was not exactly that size rendered at the wrong shape and got rescaled on the way to the viewscreen pane. -fit decided which window that was, and it decided differently for the first mission than for the rest. Its borderless full-monitor placement lived only in SVGA16's cockpit build, which does not run until a mission starts - just after that mission has built its device. So race one was set up against a still-bordered client and every race after it against the borderless monitor. On a 3440x1440 panel that is a 1.778 image drawn across a 2.389 target, against 1.816 the first time. That is not a cosmetic difference. The simulation advances on wall-clock deltas, so frame cost is physics: two render targets that size and scale differently are two different races from one lobby and one set of settings. A racing sim does not get to do that. So: the back buffer is the requested size windowed as well as full-screen, and -fit takes its shape at startup rather than four screens later. SVGA16 still applies the same rect when it builds the cockpit - that call is now a no-op instead of a change, which is the point. The first lobby also stops being the only one with a title bar. The reticle keeps its own share of the blame and is fixed on its own terms, so it cannot drift again if a target ever does move: - It is measured against the viewport at draw time and rebuilt when that changes, rather than baked once in the constructor from the renderer's requested size. One GetViewport a frame, no rewrite until it moves. - The arms are quads, not lines. D3D9 line rasterisation follows the diamond-exit rule and is free to differ between drivers on a segment running along a pixel boundary, which is how a crosshair loses one pair of arms and keeps the other - and full-screen, where both dimensions are usually even and both pairs sit on boundaries, how it can lose the lot. - Arm thickness follows the target rather than being one pixel whatever the resolution. One pixel is a width the presentation can throw away in a downscale, and it was a hairline at 1440 next to the pod's line at 480. The log names the viewport, the requested size and where the crosshair landed, and says TARGET DISAGREES with both aspects when the first two do not match - so the next report of this arrives with its own diagnosis. Window creation cleaned up while in there: it computed a style and then handed CreateWindowEx a literal WS_OVERLAPPEDWINDOW regardless, so the full-screen path never got the WS_POPUP it thought it was asking for. Borderless modes are now born borderless instead of being restyled a moment after. The requested size also goes through AdjustWindowRect, because -res is a render size and was being used as the OUTER rectangle with the chrome taken out of the middle - which is how -res 640 480 came to present into a 624x441 client and started all of this. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
9389ec2003 |
Winners Circle: the award platform at the end of a race
The pod hall stood the finishers on a numbered platform when the race ended. All of it shipped in this repo and none of it ever ran here: the stand geometry, the eight ranked dropzones win1-win8 in every one of the 11 maps, and the sequence that places the racers on them. The sequence lived on RPL4PlaybackApplication - the mission-review build - behind a spool file, so the app the pods actually race has never called it. RPL4Application now has its own StopMission handler that ranks the finishers, drops each onto their spot, freezes them, re-sorts the name plates into finishing order and frames a camera on the stand. It fires once: StopMission arrives twice, from the console at the buzzer and again from the player when the ending fade expires, and only the first is the end of the race. Ranking works in football as well as a race. CalcFootballRanking ranks only the RunnerPlayers group, which would have placed the runners and stopped - but nothing calls it. What runs is Player::CalcRanking, every frame, over every scoring player by score. Three pieces of the original had been stubbed out in the D3D9 port and are restored: SetViewAngle was an empty function, so the 45 degrees the sequence asks for did nothing. It now rebuilds the projection the way DPLReadINIPage does and pushes it, and sets viewRatio, which nothing had written since the DPL body was commented out. winnersCircleFogStyle was an empty case. The stand sits far off the track in open ground where the track's own fog leaves it dark; this is the blue-violet the original used, with the fog pushed back to 100/1050 and the clip plane pulled to 1100. The end-of-mission fade had to be told to stand down. It multiplies the fog colour and both fog distances toward zero every frame - correct when a race just ends, fatal to anything shown afterwards. That fade is what made the podium a black screen, and it took a while to find because every frame was being built and presented correctly the whole time. The presentation camera overrides D3DTS_VIEW between the eye renderable writing it and ExecuteImplementation reading it back for the draw calls, so no CameraShip is needed. It builds with LookAt LH, not RH: the projection is LH, and RH aims the camera the opposite way - ask to look down at the stand and you get the sky behind you. The engine's own eye renderable is right to use RH, because its forward and up come out of the entity matrix already in that convention. The mission is held open 11 seconds rather than 3. That fade timer is the only thing keeping the simulation and the renderer alive once the race is over, and it has no upper bound on the ending path. Switches, all off-by-default behaviour aside: RP412PODIUM=0 skips it, RP412PODIUMCAM=0 keeps the cockpit view, RP412PODIUMSTANDOFF/HEIGHT/AIM frame the shot, RP412MISSIONSECONDS overrides the menu game length (the shortest it offers is 3:00, a long wait when what you are testing is the buzzer), and RP412RENDERDIAG=1 reports what a frame is made of. Verified end to end on Wiseguy's Wake: the stand, its tiers, the blue 2 and 3, the red 4 through 8 and all eight name bays, held steady for the full 11 seconds and then handing off to the results screen. Known gaps: the name plates are blank, because the player1-8 textures are runtime name bitmaps that do not resolve as files in this port, and your own vehicle has no exterior model - you see the others, not yourself. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
4abbf8879f |
Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet', built on the MUNGA engine and its L4 (Win32/DirectX) platform layer: - MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend - RP / RP_L4: Red Planet game logic and Win32 application - DivLoader, Setup1: asset loader and installer project - lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies Removed stale Subversion metadata and added .gitignore/.gitattributes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |