aa294071f9a24fc8094880fbc718c7aa37b4a235
5
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> |
||
|
|
8dc6605a07 |
Cockpit: buttons under the glass, -fit, and player display layout
Button banks The exploded diagnostic view was still display-only - it predates the button work - so it now builds the same banks as the cockpit, with the pod arrangement laid out from the panes measured sizes rather than a hardcoded 640/480 grid (the banks make each window bigger than its glass, and the bottom row hung off the work area otherwise). The map side columns were spread height/6 from the top, but the maps own legend grid is not sixths: measured off the bitmap it starts 13 rows down with six 102-tall cells on a 105 pitch. Every button sat high of its label, worst at the bottom. Each buttons top and bottom now come off that grid separately and are subtracted - scaling a height directly would let rounding drift them back out of step on a resized cockpit. Depth 100 to 240: against the 480 glass the two banks meet in the middle bar the strips, so practically the whole display is a press target. This mattered most in the cockpit, where the panes are small enough that the halfway clamp governs - at 100 the MFDs had a 110px dead band straight through the middle of the glass. -fit (also spelled -windowed-fullscreen) Borderless over the whole monitor, with the render size chosen to match. The cockpit presents the 3D into a viewscreen that fills its canvas, so the right -res is that canvas at the scale the cockpit will settle on; computing it with identical arithmetic makes the stretch a copy. On the 3440x1440 panel that is 133% and -res 2553 1436, against 125% for the windowed path that pays for the taskbar. The pick runs after the whole command line, so an explicit -res wins from either side of -fit. Capped at 3840x2160. Cockpit mode only - mode 0 has to stay playable on real pod hardware and mode 2 is a dev view - so those get the resolution and keep their windows. Display layout, in environ.ini L4MFDSCALE sizes all five MFDs, L4MFDSCALE_UL and friends override any one of them, L4RADARSCALE the radar, and L4RADARPOS puts the radar bottom centre, in either bottom corner, or halfway up either side. Scaling is applied in canvas units before the canvas is fitted to the window, so a number means the same thing on every monitor. Sizing each display separately let the clamps become exact rather than one conservative rule for all five: what limits a display is its actual neighbour. Which neighbour that is depends on the radar, so the clamps follow it - on the bottom edge it clears the one MFD above its column, but centred on a side it has one above AND below and grows from the middle both ways, so it must clear the taller twice over. Clamping shrinks uniformly; these are photographs of real instruments and a one-axis clamp would squash them. Verified on the ultrawide: all five radar positions, per-display and group scaling with the clamps biting, -fit with and without an explicit -res, and the button geometry measured back off the screen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
c66cb00a7e |
Network races: the local console marshals remote pods over the wire
The lobby-owner-as-console architecture, in-engine. RPL4CONSOLE gains RPL4LocalConsole_InstallNetworkRace: the owner pod switches to network mode and meshes like any pod (egg fed locally via FeedLocalEgg, which now opens the ConsoleOnly state gate), while the console tick also marshals REMOTE pods over NetTransport speaking the exact arcade protocol - egg chunks with 5s-retry-until-ACK, 1Hz state polling, RunMission once every pod stages at WaitingForLaunch, StopMission at expiry (remotes first, local pod holds until their EndMission scores land), score intake labeled with [pilots]-order names on the results screen. The front end builds the multi-pilot egg: RP412HOSTPODS lists member console channels (lobby stand-in; the Steam lobby feeds the same path), RP412HOSTPORT/RP412HOSTADDR set the owner side. Winsock Connect now redials with a fresh socket per attempt (a refused TCP socket is dead; the old loop reused it) bounded at 120s - needed whenever a peer boots after the caller, which is the normal Steam lobby launch order. Verified on loopback: member pod in -net, owner hosting from its menu; mesh completed both sides, 30s race, remote score collected over the wire (host 3), local stop after the drain, results screen shows both pilots by name in one process that returns to the menu. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
58eb25a792 |
In-game front end: race setup menu builds the mission egg locally
Starting without -egg, -net, or -mr now boots a race-setup screen (RP_L4/RPL4FE.cpp) instead of aborting: track / vehicle / color / badge / time-of-day / weather / race length plus pilot name, populated from TeslaConsole''s RPConfig.xml catalog (Death Race scenario). LAUNCH builds the egg exactly as the console did - the RPMission.ToEggString port, including the pilot name pre-rendered to 1bpp plasma bitmaps (128x32 + 64x16) via GDI with the console''s auto-shrink font logic and the verbatim ordinal graphics - writes frontend.egg, and injects it into the standard egg-load path (new L4Application:: SetEggNotationFileName). The menu is a GDI child of the main window (pod green-on-black, double buffered, mouse driven, EDIT control for the name) running a modal loop before engine init; closing the window exits cleanly. Found and fixed along the way: the empty egg CString holds a NULL representation (operator! is the safe emptiness test), and the modal loop needed a queue nudge for launch clicks delivered via SendMessage. Verified end to end: boot -> menu -> LAUNCH -> generated egg (7.5KB) -> racing in the 1080p cockpit with score and mission clock running. start-windowed.bat now boots into the front end. 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> |