EBLAN_ENGINE/include/engine_gameplay.inc

343 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