Preserve stage-1 stability fixes alongside v5 lighting, IPC v2, weapons and studio updates. Fix barrel AOE pointer corruption and extend modal gameplay gating. Verify 137 editor checks, 191 ASM checks, lighting bake and preview parity. Document stage-2 scope without implementing it.
342 lines
9.6 KiB
PHP
342 lines
9.6 KiB
PHP
; ==============================================================================
|
|
; EBLAN ENGINE - Gameplay Events, Scripting Hooks, HUD Toasts & Dialog Modals
|
|
; ==============================================================================
|
|
|
|
.code
|
|
|
|
DrawPixel PROTO :DWORD, :DWORD, :DWORD
|
|
DrawRect PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
|
|
DrawRectOutline PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
|
|
DrawString8x8 PROTO :DWORD, :DWORD, :DWORD, :DWORD
|
|
DrawNumber8x8 PROTO :DWORD, :DWORD, :DWORD, :DWORD
|
|
PlaySoundA PROTO :DWORD, :DWORD, :DWORD
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; ShowGameToast: Displays a floating toast notification banner on screen
|
|
; ------------------------------------------------------------------------------
|
|
ShowGameToast PROC uses esi edi ecx eax, pszText:DWORD, duration:DWORD, textColor:DWORD
|
|
mov esi, pszText
|
|
test esi, esi
|
|
jz toast_skip_copy
|
|
|
|
mov edi, OFFSET gameToastText
|
|
mov ecx, 63
|
|
toast_copy_loop:
|
|
lodsb
|
|
stosb
|
|
test al, al
|
|
jz toast_copy_done
|
|
dec ecx
|
|
jnz toast_copy_loop
|
|
xor al, al
|
|
stosb
|
|
toast_copy_done:
|
|
|
|
toast_skip_copy:
|
|
mov eax, duration
|
|
mov gameToastTimer, eax
|
|
mov eax, textColor
|
|
mov gameToastColor, eax
|
|
ret
|
|
ShowGameToast ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; RenderGameToast: Draws active toast notification at top center of screen
|
|
; ------------------------------------------------------------------------------
|
|
RenderGameToast PROC uses ebx ecx edx esi edi
|
|
cmp gameToastTimer, 0
|
|
jle rt_done
|
|
dec gameToastTimer
|
|
|
|
; 1. Calculate text character length
|
|
mov esi, OFFSET gameToastText
|
|
xor ecx, ecx
|
|
count_len:
|
|
mov al, [esi+ecx]
|
|
test al, al
|
|
jz count_done
|
|
inc ecx
|
|
cmp ecx, 63
|
|
jb count_len
|
|
count_done:
|
|
test ecx, ecx
|
|
jz rt_done
|
|
|
|
; Width in pixels = length * 8
|
|
mov eax, ecx
|
|
shl eax, 3
|
|
mov edx, eax
|
|
|
|
; Center X = (SCREEN_W - width) / 2
|
|
mov ebx, SCREEN_W
|
|
sub ebx, edx
|
|
sar ebx, 1
|
|
|
|
; Box coordinates: X = ebx - 6, Y = 16, W = edx + 12, H = 14
|
|
mov eax, ebx
|
|
sub eax, 6
|
|
mov esi, edx
|
|
add esi, 12
|
|
|
|
invoke DrawRect, eax, 16, esi, 14, 00101010h
|
|
invoke DrawRectOutline, eax, 16, esi, 14, gameToastColor
|
|
invoke DrawString8x8, ebx, 19, OFFSET gameToastText, gameToastColor
|
|
|
|
rt_done:
|
|
ret
|
|
RenderGameToast ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; ShowGameDialog: Opens an interactive retro dialogue modal with speaker and text
|
|
; ------------------------------------------------------------------------------
|
|
ShowGameDialog PROC uses esi edi ecx eax, pszSpeaker:DWORD, pszText:DWORD
|
|
mov esi, pszSpeaker
|
|
mov edi, OFFSET gameDialogSpeaker
|
|
mov ecx, 31
|
|
test esi, esi
|
|
jz no_speaker
|
|
copy_spk:
|
|
lodsb
|
|
stosb
|
|
test al, al
|
|
jz spk_done
|
|
dec ecx
|
|
jnz copy_spk
|
|
xor al, al
|
|
stosb
|
|
spk_done:
|
|
jmp setup_dlg_text
|
|
no_speaker:
|
|
mov BYTE PTR [edi], 0
|
|
|
|
setup_dlg_text:
|
|
mov esi, pszText
|
|
mov edi, OFFSET gameDialogText
|
|
mov ecx, 127
|
|
test esi, esi
|
|
jz no_text
|
|
copy_txt:
|
|
lodsb
|
|
stosb
|
|
test al, al
|
|
jz txt_done
|
|
dec ecx
|
|
jnz copy_txt
|
|
xor al, al
|
|
stosb
|
|
txt_done:
|
|
jmp activate_dlg
|
|
no_text:
|
|
mov BYTE PTR [edi], 0
|
|
|
|
activate_dlg:
|
|
mov gameDialogActive, 1
|
|
ret
|
|
ShowGameDialog ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; CloseGameDialog: Closes active dialogue box
|
|
; ------------------------------------------------------------------------------
|
|
CloseGameDialog PROC
|
|
mov gameDialogActive, 0
|
|
ret
|
|
CloseGameDialog ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; RenderGameDialog: Draws active dialogue box at bottom of screen
|
|
; ------------------------------------------------------------------------------
|
|
RenderGameDialog PROC uses ebx ecx edx esi edi
|
|
cmp gameDialogActive, 0
|
|
je rd_done
|
|
|
|
; Dialog Box background: X = 16, Y = 170, W = 288, H = 42
|
|
invoke DrawRect, 16, 170, 288, 42, 00121212h
|
|
invoke DrawRectOutline, 16, 170, 288, 42, COLOR_CYAN
|
|
|
|
; Speaker name (if not empty)
|
|
cmp BYTE PTR [gameDialogSpeaker], 0
|
|
je draw_dlg_body
|
|
invoke DrawString8x8, 24, 174, OFFSET gameDialogSpeaker, COLOR_YELLOW
|
|
|
|
draw_dlg_body:
|
|
; Text
|
|
invoke DrawString8x8, 24, 186, OFFSET gameDialogText, COLOR_WHITE
|
|
|
|
; Close hint in bottom-right
|
|
invoke DrawString8x8, 140, 200, OFFSET szDialogCloseHint, COLOR_GRAY
|
|
|
|
; Check if player pressed Action key or Attack to dismiss
|
|
cmp keyAction, 0
|
|
jne do_dismiss
|
|
cmp keyAttack, 0
|
|
jne do_dismiss
|
|
jmp rd_done
|
|
|
|
do_dismiss:
|
|
mov keyAction, 0
|
|
mov keyAttack, 0
|
|
mov gameDialogActive, 0
|
|
|
|
rd_done:
|
|
ret
|
|
RenderGameDialog ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; PlayGameSFX: Asynchronously plays a sound effect via WinMM PlaySoundA
|
|
; ------------------------------------------------------------------------------
|
|
PlayGameSFX PROC uses eax, pszRelativePath:DWORD
|
|
cmp isCutsceneActive, 0
|
|
jne sfx_done
|
|
mov eax, pszRelativePath
|
|
test eax, eax
|
|
jz sfx_done
|
|
cmp BYTE PTR [eax], 0
|
|
jz sfx_done
|
|
invoke PlaySoundA, eax, 0, 9 ; SND_FILENAME (1) | SND_ASYNC (8) = 9
|
|
sfx_done:
|
|
ret
|
|
PlayGameSFX ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; Game_OnTick: Hook called every 60 Hz frame during active gameplay
|
|
; ------------------------------------------------------------------------------
|
|
Game_OnTick PROC uses eax ebx ecx edx
|
|
; Extensible hook for custom game logic (quests, timers, zones)
|
|
ret
|
|
Game_OnTick ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; Game_OnPlayerInteract: Hook called when player presses [E] in range of an entity
|
|
; Returns: EAX = 1 if handled by custom script, 0 if default engine behavior
|
|
; ------------------------------------------------------------------------------
|
|
Game_OnPlayerInteract PROC uses ebx ecx edx esi edi, entityIdx:DWORD, entityTypeVal:DWORD
|
|
; Extensible hook for custom interactions
|
|
xor eax, eax
|
|
ret
|
|
Game_OnPlayerInteract ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; Game_OnEntityKilled: Hook called when enemy guard or barrel is destroyed
|
|
; ------------------------------------------------------------------------------
|
|
Game_OnEntityKilled PROC uses eax ebx ecx edx, entityIdx:DWORD, entityTypeVal:DWORD
|
|
; Extensible hook for boss fights, doors opening on kill, score multipliers
|
|
ret
|
|
Game_OnEntityKilled ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; Game_OnCustomHUD: Hook called during HUD rendering
|
|
; ------------------------------------------------------------------------------
|
|
Game_OnCustomHUD PROC uses eax ebx ecx edx
|
|
; Extensible hook for custom UI bars, quest markers, mini-dialogues
|
|
ret
|
|
Game_OnCustomHUD ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; RenderGameHUDOverlays: Renders active toast banner, dialogue modal, and custom HUD
|
|
; ------------------------------------------------------------------------------
|
|
RenderGameHUDOverlays PROC
|
|
call RenderGameToast
|
|
call RenderGameDialog
|
|
call Game_OnCustomHUD
|
|
ret
|
|
RenderGameHUDOverlays ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; CheckCmdFlag: Case-insensitive substring search (EAX = 1 if found, 0 if not)
|
|
; ------------------------------------------------------------------------------
|
|
CheckCmdFlag PROC uses esi edi ecx, pszCmd:DWORD, pszFlag:DWORD
|
|
mov esi, pszCmd
|
|
test esi, esi
|
|
jz flag_not_found
|
|
check_next_char:
|
|
cmp byte ptr [esi], 0
|
|
je flag_not_found
|
|
mov edi, pszFlag
|
|
mov ecx, esi
|
|
compare_loop:
|
|
mov al, byte ptr [edi]
|
|
test al, al
|
|
jz flag_found
|
|
mov ah, byte ptr [ecx]
|
|
cmp al, 'A'
|
|
jl @F
|
|
cmp al, 'Z'
|
|
jg @F
|
|
add al, 32
|
|
@@:
|
|
cmp ah, 'A'
|
|
jl @F
|
|
cmp ah, 'Z'
|
|
jg @F
|
|
add ah, 32
|
|
@@:
|
|
cmp al, ah
|
|
jne mismatch
|
|
inc edi
|
|
inc ecx
|
|
jmp compare_loop
|
|
mismatch:
|
|
inc esi
|
|
jmp check_next_char
|
|
flag_found:
|
|
mov eax, 1
|
|
ret
|
|
flag_not_found:
|
|
xor eax, eax
|
|
ret
|
|
CheckCmdFlag ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; LoadProjectSettings: Reads project.eblanproj if present in working directory
|
|
; ------------------------------------------------------------------------------
|
|
LoadProjectSettings PROC uses ebx ecx edx esi edi
|
|
LOCAL hFile:DWORD, bytesRead:DWORD
|
|
LOCAL projBuf[1024]:BYTE
|
|
|
|
invoke CreateFileA, OFFSET szProjectFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0
|
|
cmp eax, INVALID_HANDLE_VALUE
|
|
je proj_done
|
|
mov hFile, eax
|
|
|
|
lea edx, projBuf
|
|
invoke ReadFile, hFile, edx, 1023, ADDR bytesRead, 0
|
|
invoke CloseHandle, hFile
|
|
|
|
cmp bytesRead, 0
|
|
jle proj_done
|
|
|
|
mov eax, bytesRead
|
|
mov byte ptr [projBuf + eax], 0
|
|
|
|
lea edx, projBuf
|
|
invoke CheckCmdFlag, edx, OFFSET szProjGameMode0
|
|
test eax, eax
|
|
jnz set_adv_mode
|
|
|
|
lea edx, projBuf
|
|
invoke CheckCmdFlag, edx, OFFSET szProjShowWeapons0
|
|
test eax, eax
|
|
jnz set_adv_mode
|
|
|
|
lea edx, projBuf
|
|
invoke CheckCmdFlag, edx, OFFSET szProjGameMode1
|
|
test eax, eax
|
|
jnz set_act_mode
|
|
jmp proj_done
|
|
|
|
set_adv_mode:
|
|
mov gameMode, GAME_MODE_ADVENTURE
|
|
mov enableWeapons, 0
|
|
mov playerWeapon, WEAPON_NONE
|
|
mov showCrosshair, 0
|
|
jmp proj_done
|
|
|
|
set_act_mode:
|
|
mov gameMode, GAME_MODE_ACTION
|
|
mov enableWeapons, 1
|
|
mov playerWeapon, WEAPON_PISTOL
|
|
mov showCrosshair, 1
|
|
|
|
proj_done:
|
|
ret
|
|
LoadProjectSettings ENDP
|