Trace shots against current map geometry instead of stale render depth. Preserve outline counters across volatile pixel calls and freeze gameplay on cinematic, transition and death ticks. Clamp packed HP before narrowing and match legacy archetype rules. Publish IDE saves atomically; failed saves block file switches and builds. Drain compiler output while hidden. Verify runtime/editor builds, 112 editor checks, 148 ASM checks and live preview parity. Record remaining stages in docs/STABILIZATION.md.
228 lines
7.5 KiB
PHP
228 lines
7.5 KiB
PHP
|
|
COMM screenBuffer:BYTE:FRAME_BUFFER_SIZE
|
|
COMM textureBuffer:BYTE:MAX_TEXTURES * TEX_SIZE_BYTES
|
|
COMM portalTextureBuffer:BYTE:TEX_SIZE_BYTES
|
|
COMM texturePackStaging:BYTE:MAX_TEXTURES * TEX_SIZE_BYTES
|
|
; ==============================================================================
|
|
; EBLAN ENGINE - Global State and Data Structures
|
|
; ==============================================================================
|
|
|
|
.data
|
|
; Window and GDI
|
|
szClassName db "EblanEngine3DWndClass",0
|
|
szWindowTitle db "EBLAN ENGINE 3D - Retro Raycaster [Pure x86 Assembly]",0
|
|
hEngineWnd dd 0
|
|
hEngineDC dd 0
|
|
hEngineInstance dd 0
|
|
isRunning dd 1
|
|
|
|
; High Precision Timing
|
|
; Latched by UpdatePlayer: scene/end/skip/instant-transition ticks never run AI
|
|
; or combat, even if they return control partway through the tick.
|
|
gameplayTickBlocked dd 0
|
|
targetFrameTimeMs dd 16 ; ~60 FPS (16.6 ms)
|
|
lastTickCount dd 0
|
|
fpsCounter dd 0
|
|
fpsTimer dd 0
|
|
currentFps dd 60
|
|
szFpsLabel db "FPS: ",0
|
|
|
|
; Software Framebuffer & BITMAPINFO
|
|
ALIGN 4
|
|
bmiEngine BITMAPINFOHEADER <sizeof BITMAPINFOHEADER, SCREEN_W, -SCREEN_H, 1, 32, 0, 0, 0, 0, 0, 0>
|
|
dd 0 ; palette dummy
|
|
|
|
rngSeed dd 12345678h
|
|
|
|
; Player State
|
|
; Position in RAW world units (1 cell = 64 units; e.g. 160 = cell 2.5)
|
|
playerX dd 160
|
|
playerY dd 160
|
|
playerAngle dd 0 ; 0..511 (0 = East, 128 = South, 256 = West, 384 = North)
|
|
playerMoveSpeed dd 3 ; raw units per frame (walk)
|
|
playerRunSpeed dd 6 ; raw units per frame (sprint)
|
|
playerTurnSpeed dd 4 ; angle units per frame
|
|
playerRadius dd 16 ; collision radius (raw units)
|
|
|
|
; Input State Flags
|
|
keyForward db 0
|
|
keyBackward db 0
|
|
keyStrafeLeft db 0
|
|
keyStrafeRight db 0
|
|
keyTurnLeft db 0
|
|
keyTurnRight db 0
|
|
keyAction db 0
|
|
keyRun db 0
|
|
keyShowMap db 1 ; minimap toggle
|
|
keyScreenshot db 0 ; F12 screenshot request
|
|
keyActionHeld db 0
|
|
keyMapHeld db 0
|
|
keyShotHeld db 0
|
|
keyCutscene db 0
|
|
keySkipScene db 0
|
|
keySceneHeld db 0
|
|
keySkipHeld db 0
|
|
keyAttack db 0
|
|
keyAttackHeld db 0
|
|
keyRestart db 0
|
|
keyRestartHeld db 0
|
|
|
|
; Player Combat & Gameplay Stats
|
|
playerHealth dd 100
|
|
playerMaxHealth dd 100
|
|
playerAmmo dd 50
|
|
playerMaxAmmo dd 99
|
|
playerScore dd 0
|
|
playerKeys dd 0
|
|
playerAttackCooldown dd 0
|
|
playerFlashTimer dd 0
|
|
playerHitFlash dd 0
|
|
isPlayerDead dd 0
|
|
|
|
; Map palette (overridable by map.dat header)
|
|
mapCeilingColor dd COLOR_CEILING
|
|
mapFloorColor dd COLOR_FLOOR
|
|
szMapFilePath db "assets\map.dat",0
|
|
szAssetsPrefix db "assets\",0
|
|
startupMapPath db MAX_PATH_BYTES dup(0)
|
|
portalLatchCell dd -1 ; suppress repeated entry until the player leaves the cell
|
|
mapErrorFrames dd 0
|
|
|
|
; Sector Streaming & Portals
|
|
transitionCount dd 0
|
|
pendingMapPath db 64 dup(0)
|
|
szSublevelFullPath db 80 dup(0)
|
|
pendingSpawnX dd 0
|
|
pendingSpawnY dd 0
|
|
pendingSpawnAngle dd 0
|
|
|
|
; Screen Fade Transition State Machine
|
|
fadeState dd 0 ; 0 = None, 1 = Fading Out, 2 = Black / Switching, 3 = Fading In
|
|
fadeLevel dd 0 ; 0..16 (0 = visible, 16 = black)
|
|
|
|
; Texture pack (optional; falls back to procedural textures)
|
|
szTexPackPath db "assets\textures\texturepack.bin",0
|
|
texPackLoaded dd 0
|
|
|
|
; Sprite Manager
|
|
spriteCount dd 0
|
|
|
|
; Engine HUD & Strings
|
|
strControls1 db "WASD: Move / Strafe | Shift: Run",0
|
|
strControls2 db "Arrows: Turn Camera",0
|
|
strControls3 db "E:Use C:Scene M:Map F12:Shot Esc:Exit",0
|
|
strEngineName db "EBLAN ENGINE 3D (x86 MASM)",0
|
|
strDoorHint db "[E] - Door",0
|
|
strPortalHint db "[E] - Enter Portal",0
|
|
strMapLoadError db "Cannot load destination level",0
|
|
strSkipScene db "[Tab] Skip",0
|
|
strHpLabel db "HP:",0
|
|
strAmmoLabel db "AMMO:",0
|
|
strScoreLabel db "SCORE:",0
|
|
strKeysLabel db "KEY:",0
|
|
strYouDied db "YOU DIED! PRESS [R] TO RESTART",0
|
|
cutsceneCount dd 0
|
|
cutsceneStringCount dd 0
|
|
cutsceneFlags dd 0
|
|
isCutsceneActive dd 0
|
|
cutscenePending dd 0
|
|
cutsceneTick dd 0
|
|
cutsceneIndex dd 0
|
|
cutsceneWait dd 0
|
|
cutsceneSubtitle dd -1
|
|
cutsceneSubtitleUntil dd 0
|
|
cutsceneFade dd 0
|
|
csMoveFromX dd 0
|
|
csMoveFromY dd 0
|
|
csMoveToX dd 0
|
|
csMoveToY dd 0
|
|
csMoveDuration dd 0
|
|
csMoveElapsed dd 0
|
|
csAngleFrom dd 0
|
|
csAngleDelta dd 0
|
|
csAngleDuration dd 0
|
|
csAngleElapsed dd 0
|
|
csFadeFrom dd 0
|
|
csFadeTo dd 0
|
|
csFadeDuration dd 0
|
|
csFadeElapsed dd 0
|
|
csSoundPrefix db "assets\sounds\",0
|
|
csSoundPath db 128 dup(0)
|
|
csLineBuffer db 40 dup(0)
|
|
|
|
; Screenshot (F12): writes 32-bit top-down BMP of screenBuffer
|
|
szScreenshotPath db "screenshot.bmp",0
|
|
ALIGN 4
|
|
screenshotHeader db 'B','M'
|
|
dd (54 + FRAME_BUFFER_SIZE) ; bfSize
|
|
dd 0 ; bfReserved
|
|
dd 54 ; bfOffBits
|
|
dd 40 ; BITMAPINFOHEADER.biSize
|
|
dd SCREEN_W ; biWidth
|
|
dd -SCREEN_H ; biHeight (top-down)
|
|
dw 1 ; biPlanes
|
|
dw 32 ; biBitCount
|
|
dd 0 ; biCompression = BI_RGB
|
|
dd FRAME_BUFFER_SIZE ; biSizeImage
|
|
dd 0, 0, 0, 0
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; Large buffers live in BSS (.data?) so they are NOT baked into the .exe
|
|
; ------------------------------------------------------------------------------
|
|
.data?
|
|
ALIGN 4
|
|
; (moved to COMM)
|
|
|
|
ALIGN 4
|
|
depthBuffer dd SCREEN_W dup(?)
|
|
|
|
; Glass (Transparent Wall) per-column buffers
|
|
ALIGN 4
|
|
glassDistBuffer dd SCREEN_W dup(?)
|
|
glassDrawStartBuf dd SCREEN_W dup(?)
|
|
glassDrawEndBuf dd SCREEN_W dup(?)
|
|
glassLineHeightBuf dd SCREEN_W dup(?)
|
|
glassTexXBuf dd SCREEN_W dup(?)
|
|
glassSideHitBuf dd SCREEN_W dup(?)
|
|
|
|
; Fixed-point Math Lookup Tables (512 angles, 16.16 signed fixed point)
|
|
ALIGN 4
|
|
tableSin dd ANGLE_512 dup(?)
|
|
tableCos dd ANGLE_512 dup(?)
|
|
ALIGN 4
|
|
tableRayAngleOffset dd SCREEN_W dup(?)
|
|
ALIGN 4
|
|
tableRayCos dd SCREEN_W dup(?)
|
|
|
|
; Game Map Grid (32x32 = 1024 bytes)
|
|
gameMap db MAP_SIZE dup(?)
|
|
|
|
; Texture Memory (16 slots of 128x128 32-bit BGRA = 1 MB)
|
|
ALIGN 4
|
|
; (moved to COMM)
|
|
|
|
; (moved to COMM)
|
|
|
|
; (moved to COMM)
|
|
|
|
|
|
ALIGN 4
|
|
spriteList db MAX_SPRITES * (sizeof SpriteStruct) dup(?)
|
|
spriteOrder dd MAX_SPRITES dup(?) ; sprite indices sorted far-to-near
|
|
|
|
ALIGN 4
|
|
transitionList db MAX_TRANSITIONS * (sizeof LevelTransition) dup(?)
|
|
|
|
ALIGN 4
|
|
cutsceneEvents db MAX_CUTSCENE_EVENTS * (sizeof CutsceneEvent) dup(?)
|
|
cutsceneStrings db MAX_CUTSCENE_STRINGS * CUTSCENE_STRING_BYTES dup(?)
|
|
stagedCutsceneEvents db MAX_CUTSCENE_EVENTS * (sizeof CutsceneEvent) dup(?)
|
|
stagedCutsceneStrings db MAX_CUTSCENE_STRINGS * CUTSCENE_STRING_BYTES dup(?)
|
|
|
|
ALIGN 4
|
|
entityType dd MAX_SPRITES dup(?)
|
|
entityHealth dd MAX_SPRITES dup(?)
|
|
entityState dd MAX_SPRITES dup(?)
|
|
entityTimer dd MAX_SPRITES dup(?)
|
|
entitySpeed dd MAX_SPRITES dup(?)
|
|
entityAggro dd MAX_SPRITES dup(?)
|