2502 lines
56 KiB
PHP
2502 lines
56 KiB
PHP
; ==============================================================================
|
||
; CASINO 3D ENGINE - DOOM / WOLFENSTEIN 3D RAYCASTER FOR MASM32 (CP1251)
|
||
; ==============================================================================
|
||
|
||
includelib gdi32.lib
|
||
includelib winmm.lib
|
||
|
||
; Windows API Prototypes
|
||
CreateWindowExA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
|
||
RegisterClassExA PROTO :DWORD
|
||
DefWindowProcA PROTO :DWORD,:DWORD,:DWORD,:DWORD
|
||
ShowWindow PROTO :DWORD,:DWORD
|
||
UpdateWindow PROTO :DWORD
|
||
GetDC PROTO :DWORD
|
||
ReleaseDC PROTO :DWORD,:DWORD
|
||
StretchDIBits PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
|
||
PeekMessageA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
|
||
TranslateMessage PROTO :DWORD
|
||
DispatchMessageA PROTO :DWORD
|
||
PostQuitMessage PROTO :DWORD
|
||
DestroyWindow PROTO :DWORD
|
||
SetWindowTextA PROTO :DWORD,:DWORD
|
||
SetForegroundWindow PROTO :DWORD
|
||
GetConsoleWindow PROTO
|
||
GetSystemMetrics PROTO :DWORD
|
||
CreateFileA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
|
||
ReadFile PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
|
||
CloseHandle PROTO :DWORD
|
||
GetAsyncKeyState PROTO :DWORD
|
||
PlaySoundA PROTO :DWORD,:DWORD,:DWORD
|
||
GetModuleFileNameA PROTO :DWORD,:DWORD,:DWORD
|
||
|
||
; Structures
|
||
C3D_POINT STRUCT
|
||
x dd ?
|
||
y dd ?
|
||
C3D_POINT ENDS
|
||
|
||
C3D_MSG STRUCT
|
||
hwnd dd ?
|
||
message dd ?
|
||
wParam dd ?
|
||
lParam dd ?
|
||
time dd ?
|
||
pt C3D_POINT <>
|
||
C3D_MSG ENDS
|
||
|
||
C3D_WNDCLASSEX STRUCT
|
||
cbSize dd ?
|
||
style dd ?
|
||
lpfnWndProc dd ?
|
||
cbClsExtra dd ?
|
||
cbWndExtra dd ?
|
||
hInstance dd ?
|
||
hIcon dd ?
|
||
hCursor dd ?
|
||
hbrBackground dd ?
|
||
lpszMenuName dd ?
|
||
lpszClassName dd ?
|
||
hIconSm dd ?
|
||
C3D_WNDCLASSEX ENDS
|
||
|
||
C3D_BITMAPINFOHEADER STRUCT
|
||
biSize dd ?
|
||
biWidth dd ?
|
||
biHeight dd ?
|
||
biPlanes dw ?
|
||
biBitCount dw ?
|
||
biCompression dd ?
|
||
biSizeImage dd ?
|
||
biXPelsPerMeter dd ?
|
||
biYPelsPerMeter dd ?
|
||
biClrUsed dd ?
|
||
biClrImportant dd ?
|
||
C3D_BITMAPINFOHEADER ENDS
|
||
|
||
C3D_BITMAPINFO STRUCT
|
||
bmiHeader C3D_BITMAPINFOHEADER <>
|
||
bmiColors dd ?
|
||
C3D_BITMAPINFO ENDS
|
||
|
||
SpriteObject STRUCT
|
||
posX dd ? ; 16.16 FP
|
||
posY dd ? ; 16.16 FP
|
||
baseTexId dd ? ; Texture slot index
|
||
frameCount dd ? ; Number of animation frames
|
||
curFrame dd ? ; Current frame (0..frameCount-1)
|
||
animTimer dd ? ; Frame tick counter
|
||
animSpeed dd ? ; Ticks per frame
|
||
interactId dd ? ; Interaction action ID
|
||
promptPtr dd ? ; Prompt string pointer
|
||
distSq dd ? ; Distance squared to player
|
||
SpriteObject ENDS
|
||
|
||
; Constants
|
||
SCREEN_W equ 320
|
||
SCREEN_H equ 240
|
||
HALF_W equ 160
|
||
HALF_H equ 120
|
||
SCREEN_SIZE equ (SCREEN_W * SCREEN_H)
|
||
WIN_SCALE equ 3
|
||
WINDOW_W equ (SCREEN_W * WIN_SCALE)
|
||
WINDOW_H equ (SCREEN_H * WIN_SCALE)
|
||
|
||
FP_1 equ 65536
|
||
FP_HALF equ 32768
|
||
CHROMA_KEY equ 00FF00FFh
|
||
|
||
WS_OVERLAPPEDWINDOW equ 00CF0000h
|
||
SW_SHOW equ 5
|
||
SW_HIDE equ 0
|
||
PM_REMOVE equ 1
|
||
WM_DESTROY equ 0002h
|
||
WM_CLOSE equ 0010h
|
||
WM_QUIT equ 0012h
|
||
CS_HREDRAW equ 2
|
||
CS_VREDRAW equ 1
|
||
DIB_RGB_COLORS equ 0
|
||
SRCCOPY equ 00CC0020h
|
||
|
||
SND_ASYNC equ 0001h
|
||
SND_FILENAME equ 00020000h
|
||
INVALID_FILE_HANDLE equ -1
|
||
|
||
; Precalculated Math, Map, and Font
|
||
include casino3d_data.inc
|
||
include font8x8.inc
|
||
|
||
.data
|
||
ALIGN 4
|
||
h3DInst dd 0
|
||
h3DWnd dd 0
|
||
h3DDC dd 0
|
||
hCasinoConsole dd 0
|
||
|
||
bmi3D C3D_BITMAPINFO <>
|
||
msg3D C3D_MSG <>
|
||
wc3D C3D_WNDCLASSEX <>
|
||
|
||
sz3DClassName db "Casino3DRetroClass",0
|
||
sz3DWindowTitle db "CASINO 3D - RETRO DOOM ENGINE [MASM32]",0
|
||
szTexturesRelPath db "assets\textures\casino3d.bin",0
|
||
szTexturesFullPath db 260 dup(0)
|
||
|
||
; Audio files
|
||
soundCoin db "assets\audio\Звук монеты брошенной в воздух и упавшей на поверхность.wav",0
|
||
soundCards db "assets\audio\playing_cards_deck_flick_through_001_20485.wav",0
|
||
soundRoulette db "assets\audio\roulette-wheel-throw-2.wav",0
|
||
soundJackpot db "assets\audio\Джэк пот.wav",0
|
||
soundClick db "assets\audio\b05e1ac8be34248.wav",0
|
||
|
||
; Player State (Spawns in central hall looking towards strip club and tables)
|
||
playerX dd (15 * FP_1 + FP_HALF)
|
||
playerY dd (14 * FP_1 + FP_HALF)
|
||
playerAngle dd 0 ; 0..511
|
||
playerDirX dd FP_1
|
||
playerDirY dd 0
|
||
playerPlaneX dd 0
|
||
playerPlaneY dd (FP_1 * 66 / 100)
|
||
|
||
radarActive dd 1
|
||
interactTargetId dd 0
|
||
interactPromptPtr dd 0
|
||
dancerLuckBuff dd 0
|
||
flashTimer dd 0
|
||
flashMessage db 128 dup(0)
|
||
|
||
; Prompts in CP1251
|
||
promptDancer db "[E] ТАНЦОВЩИЦА: КИНУТЬ $100 НА ЧАЙ (+УДАЧА)",0
|
||
promptSlot1 db "[E] КРУТИТЬ СЛОТ-МАШИНУ 777",0
|
||
promptSlot2 db "[E] ИГРАТЬ В CLOVERPIT (СЛОТЫ 5x3)",0
|
||
promptBlackjack db "[E] СЕСТЬ ЗА СТОЛ: 21 / BLACKJACK",0
|
||
promptPoker db "[E] СЕСТЬ ЗА СТОЛ: ТЕХАССКИЙ ПОКЕР",0
|
||
promptRoulette db "[E] СЕСТЬ ЗА СТОЛ: РУЛЕТКА КАЗИНО",0
|
||
promptShop db "[E] БАРМЕН: МАГАЗИН ТАЛИСМАНОВ И ЧИТОВ",0
|
||
promptATM db "[E] БАНКОМАТ: ПРОВЕРИТЬ БАЛАНС И КВОТУ",0
|
||
promptBackroom db "[E] BUCKSHOT / РУССКАЯ РУЛЕТКА",0
|
||
promptDurak db "[E] СЕСТЬ ЗА СТОЛ: ПОДКИДНОЙ ДУРАК",0
|
||
promptHell db "[E] ВОЙТИ В ПОРТАЛ: БАШНЯ АДА (FLOOR 666)",0
|
||
|
||
msgDancerTipped db "Вы кинули $100 танцовщице! Удача в играх повышена!",0
|
||
msgNeedMoney db "Недостаточно денег для чаевых!",0
|
||
statusHUDFormat db "БАНК: $",0
|
||
targetHUDFormat db " ЦЕЛЬ: $",0
|
||
luckHUDFormat db " УДАЧА: +",0
|
||
controlsHUD db "WASD/Стрелки: Ходить | M: Радар | E: Действие | ESC: Меню",0
|
||
|
||
NUM_SPRITES equ 13
|
||
ALIGN 4
|
||
casinoSprites SpriteObject NUM_SPRITES dup(<>)
|
||
sortedSprites dd NUM_SPRITES dup(0)
|
||
|
||
.data?
|
||
ALIGN 4
|
||
screenBuffer dd SCREEN_SIZE dup(?)
|
||
ALIGN 4
|
||
zBuffer dd SCREEN_W dup(?)
|
||
ALIGN 4
|
||
texturesBuffer dd (48 * 64 * 64) dup(?)
|
||
|
||
hudNumBuffer db 32 dup(?)
|
||
|
||
.code
|
||
|
||
; --- 3D Window Message Procedure ---
|
||
Casino3DWndProc PROC hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
|
||
cmp uMsg, WM_DESTROY
|
||
jne @F
|
||
invoke PostQuitMessage, 0
|
||
xor eax, eax
|
||
ret
|
||
@@:
|
||
cmp uMsg, WM_CLOSE
|
||
jne @F
|
||
invoke PostQuitMessage, 0
|
||
xor eax, eax
|
||
ret
|
||
@@:
|
||
invoke DefWindowProcA, hwnd, uMsg, wParam, lParam
|
||
ret
|
||
Casino3DWndProc ENDP
|
||
|
||
; --- Initialize 3D Engine Window & Load Textures ---
|
||
Init3DEngine PROC
|
||
local bytesRead:DWORD
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
|
||
invoke GetConsoleWindow
|
||
mov hCasinoConsole, eax
|
||
|
||
; Setup BITMAPINFO
|
||
mov bmi3D.bmiHeader.biSize, SIZEOF C3D_BITMAPINFOHEADER
|
||
mov bmi3D.bmiHeader.biWidth, SCREEN_W
|
||
mov bmi3D.bmiHeader.biHeight, -SCREEN_H
|
||
mov bmi3D.bmiHeader.biPlanes, 1
|
||
mov bmi3D.bmiHeader.biBitCount, 32
|
||
mov bmi3D.bmiHeader.biCompression, 0
|
||
mov bmi3D.bmiHeader.biSizeImage, SCREEN_SIZE * 4
|
||
mov bmi3D.bmiHeader.biXPelsPerMeter, 0
|
||
mov bmi3D.bmiHeader.biYPelsPerMeter, 0
|
||
mov bmi3D.bmiHeader.biClrUsed, 0
|
||
mov bmi3D.bmiHeader.biClrImportant, 0
|
||
|
||
cmp h3DWnd, 0
|
||
jne init_window_already_exists
|
||
|
||
mov wc3D.cbSize, SIZEOF C3D_WNDCLASSEX
|
||
mov wc3D.style, CS_HREDRAW or CS_VREDRAW
|
||
mov wc3D.lpfnWndProc, OFFSET Casino3DWndProc
|
||
mov wc3D.cbClsExtra, 0
|
||
mov wc3D.cbWndExtra, 0
|
||
mov wc3D.hInstance, 0
|
||
mov wc3D.hIcon, 0
|
||
mov wc3D.hCursor, 0
|
||
mov wc3D.hbrBackground, 0
|
||
mov wc3D.lpszMenuName, 0
|
||
mov wc3D.lpszClassName, OFFSET sz3DClassName
|
||
mov wc3D.hIconSm, 0
|
||
invoke RegisterClassExA, OFFSET wc3D
|
||
|
||
invoke GetSystemMetrics, 0
|
||
sub eax, WINDOW_W
|
||
shr eax, 1
|
||
mov ebx, eax
|
||
|
||
invoke GetSystemMetrics, 1
|
||
sub eax, WINDOW_H
|
||
shr eax, 1
|
||
mov ecx, eax
|
||
|
||
invoke CreateWindowExA, 0, OFFSET sz3DClassName, OFFSET sz3DWindowTitle,\
|
||
WS_OVERLAPPEDWINDOW, ebx, ecx, WINDOW_W + 16, WINDOW_H + 39,\
|
||
0, 0, 0, 0
|
||
mov h3DWnd, eax
|
||
|
||
invoke GetDC, h3DWnd
|
||
mov h3DDC, eax
|
||
|
||
init_window_already_exists:
|
||
invoke ShowWindow, h3DWnd, SW_SHOW
|
||
invoke UpdateWindow, h3DWnd
|
||
invoke SetForegroundWindow, h3DWnd
|
||
|
||
; Resolve full path to casino3d.bin
|
||
invoke GetModuleFileNameA, 0, OFFSET szTexturesFullPath, 260
|
||
; Find last backslash
|
||
lea esi, [szTexturesFullPath]
|
||
mov edi, esi
|
||
find_slash:
|
||
mov al, [esi]
|
||
test al, al
|
||
jz copy_rel_path
|
||
cmp al, '\'
|
||
jne @F
|
||
lea edi, [esi + 1]
|
||
@@:
|
||
inc esi
|
||
jmp find_slash
|
||
|
||
copy_rel_path:
|
||
lea esi, [szTexturesRelPath]
|
||
@@:
|
||
mov al, [esi]
|
||
mov [edi], al
|
||
test al, al
|
||
jz do_open_tex
|
||
inc esi
|
||
inc edi
|
||
jmp @B
|
||
|
||
do_open_tex:
|
||
invoke CreateFileA, OFFSET szTexturesFullPath, 80000000h, 1, 0, 3, 80h, 0
|
||
cmp eax, INVALID_FILE_HANDLE
|
||
jne read_tex_data
|
||
|
||
; Fallback to relative path
|
||
invoke CreateFileA, OFFSET szTexturesRelPath, 80000000h, 1, 0, 3, 80h, 0
|
||
cmp eax, INVALID_FILE_HANDLE
|
||
je generate_all_fallback_textures
|
||
|
||
read_tex_data:
|
||
mov ebx, eax
|
||
lea ecx, bytesRead
|
||
invoke ReadFile, ebx, OFFSET texturesBuffer, (48 * 64 * 64 * 4), ecx, 0
|
||
invoke CloseHandle, ebx
|
||
jmp init_sprites_table
|
||
|
||
generate_all_fallback_textures:
|
||
xor edi, edi
|
||
fill_fallback_loop:
|
||
cmp edi, (48 * 64 * 64)
|
||
jge init_sprites_table
|
||
mov eax, edi
|
||
and eax, 003Fh
|
||
mov ebx, edi
|
||
shr ebx, 6
|
||
and ebx, 003Fh
|
||
xor eax, ebx
|
||
and eax, 8
|
||
jz @F
|
||
mov DWORD PTR [texturesBuffer + edi*4], 00802020h
|
||
jmp next_fallback_pix
|
||
@@:
|
||
mov DWORD PTR [texturesBuffer + edi*4], 00202080h
|
||
next_fallback_pix:
|
||
inc edi
|
||
jmp fill_fallback_loop
|
||
|
||
init_sprites_table:
|
||
; Sprite 0: Dancer 1
|
||
mov casinoSprites[0*SIZEOF SpriteObject].posX, (5 * FP_1 + FP_HALF)
|
||
mov casinoSprites[0*SIZEOF SpriteObject].posY, (4 * FP_1 + FP_HALF)
|
||
mov casinoSprites[0*SIZEOF SpriteObject].baseTexId, 10
|
||
mov casinoSprites[0*SIZEOF SpriteObject].frameCount, 4
|
||
mov casinoSprites[0*SIZEOF SpriteObject].curFrame, 0
|
||
mov casinoSprites[0*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[0*SIZEOF SpriteObject].animSpeed, 6
|
||
mov casinoSprites[0*SIZEOF SpriteObject].interactId, 8
|
||
mov casinoSprites[0*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer
|
||
|
||
; Sprite 1: Dancer 2
|
||
mov casinoSprites[1*SIZEOF SpriteObject].posX, (8 * FP_1 + FP_HALF)
|
||
mov casinoSprites[1*SIZEOF SpriteObject].posY, (4 * FP_1 + FP_HALF)
|
||
mov casinoSprites[1*SIZEOF SpriteObject].baseTexId, 10
|
||
mov casinoSprites[1*SIZEOF SpriteObject].frameCount, 4
|
||
mov casinoSprites[1*SIZEOF SpriteObject].curFrame, 2
|
||
mov casinoSprites[1*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[1*SIZEOF SpriteObject].animSpeed, 6
|
||
mov casinoSprites[1*SIZEOF SpriteObject].interactId, 8
|
||
mov casinoSprites[1*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer
|
||
|
||
; Sprite 2: Slot 1
|
||
mov casinoSprites[2*SIZEOF SpriteObject].posX, (12 * FP_1 + FP_HALF)
|
||
mov casinoSprites[2*SIZEOF SpriteObject].posY, (12 * FP_1 + FP_HALF)
|
||
mov casinoSprites[2*SIZEOF SpriteObject].baseTexId, 20
|
||
mov casinoSprites[2*SIZEOF SpriteObject].frameCount, 3
|
||
mov casinoSprites[2*SIZEOF SpriteObject].curFrame, 0
|
||
mov casinoSprites[2*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[2*SIZEOF SpriteObject].animSpeed, 8
|
||
mov casinoSprites[2*SIZEOF SpriteObject].interactId, 3
|
||
mov casinoSprites[2*SIZEOF SpriteObject].promptPtr, OFFSET promptSlot1
|
||
|
||
; Sprite 3: Slot 2 (CloverPit)
|
||
mov casinoSprites[3*SIZEOF SpriteObject].posX, (15 * FP_1 + FP_HALF)
|
||
mov casinoSprites[3*SIZEOF SpriteObject].posY, (12 * FP_1 + FP_HALF)
|
||
mov casinoSprites[3*SIZEOF SpriteObject].baseTexId, 20
|
||
mov casinoSprites[3*SIZEOF SpriteObject].frameCount, 3
|
||
mov casinoSprites[3*SIZEOF SpriteObject].curFrame, 1
|
||
mov casinoSprites[3*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[3*SIZEOF SpriteObject].animSpeed, 8
|
||
mov casinoSprites[3*SIZEOF SpriteObject].interactId, 3
|
||
mov casinoSprites[3*SIZEOF SpriteObject].promptPtr, OFFSET promptSlot2
|
||
|
||
; Sprite 4: Slot 3
|
||
mov casinoSprites[4*SIZEOF SpriteObject].posX, (18 * FP_1 + FP_HALF)
|
||
mov casinoSprites[4*SIZEOF SpriteObject].posY, (12 * FP_1 + FP_HALF)
|
||
mov casinoSprites[4*SIZEOF SpriteObject].baseTexId, 20
|
||
mov casinoSprites[4*SIZEOF SpriteObject].frameCount, 3
|
||
mov casinoSprites[4*SIZEOF SpriteObject].curFrame, 2
|
||
mov casinoSprites[4*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[4*SIZEOF SpriteObject].animSpeed, 8
|
||
mov casinoSprites[4*SIZEOF SpriteObject].interactId, 3
|
||
mov casinoSprites[4*SIZEOF SpriteObject].promptPtr, OFFSET promptSlot1
|
||
|
||
; Sprite 5: Blackjack Table
|
||
mov casinoSprites[5*SIZEOF SpriteObject].posX, (10 * FP_1 + FP_HALF)
|
||
mov casinoSprites[5*SIZEOF SpriteObject].posY, (15 * FP_1 + FP_HALF)
|
||
mov casinoSprites[5*SIZEOF SpriteObject].baseTexId, 30
|
||
mov casinoSprites[5*SIZEOF SpriteObject].frameCount, 1
|
||
mov casinoSprites[5*SIZEOF SpriteObject].curFrame, 0
|
||
mov casinoSprites[5*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[5*SIZEOF SpriteObject].animSpeed, 1
|
||
mov casinoSprites[5*SIZEOF SpriteObject].interactId, 1
|
||
mov casinoSprites[5*SIZEOF SpriteObject].promptPtr, OFFSET promptBlackjack
|
||
|
||
; Sprite 6: Poker Table
|
||
mov casinoSprites[6*SIZEOF SpriteObject].posX, (18 * FP_1 + FP_HALF)
|
||
mov casinoSprites[6*SIZEOF SpriteObject].posY, (15 * FP_1 + FP_HALF)
|
||
mov casinoSprites[6*SIZEOF SpriteObject].baseTexId, 30
|
||
mov casinoSprites[6*SIZEOF SpriteObject].frameCount, 1
|
||
mov casinoSprites[6*SIZEOF SpriteObject].curFrame, 0
|
||
mov casinoSprites[6*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[6*SIZEOF SpriteObject].animSpeed, 1
|
||
mov casinoSprites[6*SIZEOF SpriteObject].interactId, 2
|
||
mov casinoSprites[6*SIZEOF SpriteObject].promptPtr, OFFSET promptPoker
|
||
|
||
; Sprite 7: Roulette Table
|
||
mov casinoSprites[7*SIZEOF SpriteObject].posX, (22 * FP_1 + FP_HALF)
|
||
mov casinoSprites[7*SIZEOF SpriteObject].posY, (14 * FP_1 + FP_HALF)
|
||
mov casinoSprites[7*SIZEOF SpriteObject].baseTexId, 31
|
||
mov casinoSprites[7*SIZEOF SpriteObject].frameCount, 1
|
||
mov casinoSprites[7*SIZEOF SpriteObject].curFrame, 0
|
||
mov casinoSprites[7*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[7*SIZEOF SpriteObject].animSpeed, 1
|
||
mov casinoSprites[7*SIZEOF SpriteObject].interactId, 4
|
||
mov casinoSprites[7*SIZEOF SpriteObject].promptPtr, OFFSET promptRoulette
|
||
|
||
; Sprite 8: Bartender / Shop
|
||
mov casinoSprites[8*SIZEOF SpriteObject].posX, (7 * FP_1 + FP_HALF)
|
||
mov casinoSprites[8*SIZEOF SpriteObject].posY, (22 * FP_1 + FP_HALF)
|
||
mov casinoSprites[8*SIZEOF SpriteObject].baseTexId, 32
|
||
mov casinoSprites[8*SIZEOF SpriteObject].frameCount, 1
|
||
mov casinoSprites[8*SIZEOF SpriteObject].curFrame, 0
|
||
mov casinoSprites[8*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[8*SIZEOF SpriteObject].animSpeed, 1
|
||
mov casinoSprites[8*SIZEOF SpriteObject].interactId, 6
|
||
mov casinoSprites[8*SIZEOF SpriteObject].promptPtr, OFFSET promptShop
|
||
|
||
; Sprite 9: Bank ATM
|
||
mov casinoSprites[9*SIZEOF SpriteObject].posX, (24 * FP_1 + FP_HALF)
|
||
mov casinoSprites[9*SIZEOF SpriteObject].posY, (13 * FP_1 + FP_HALF)
|
||
mov casinoSprites[9*SIZEOF SpriteObject].baseTexId, 33
|
||
mov casinoSprites[9*SIZEOF SpriteObject].frameCount, 1
|
||
mov casinoSprites[9*SIZEOF SpriteObject].curFrame, 0
|
||
mov casinoSprites[9*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[9*SIZEOF SpriteObject].animSpeed, 1
|
||
mov casinoSprites[9*SIZEOF SpriteObject].interactId, 7
|
||
mov casinoSprites[9*SIZEOF SpriteObject].promptPtr, OFFSET promptATM
|
||
|
||
; Sprite 10: Backroom Table
|
||
mov casinoSprites[10*SIZEOF SpriteObject].posX, (23 * FP_1 + FP_HALF)
|
||
mov casinoSprites[10*SIZEOF SpriteObject].posY, (23 * FP_1 + FP_HALF)
|
||
mov casinoSprites[10*SIZEOF SpriteObject].baseTexId, 34
|
||
mov casinoSprites[10*SIZEOF SpriteObject].frameCount, 1
|
||
mov casinoSprites[10*SIZEOF SpriteObject].curFrame, 0
|
||
mov casinoSprites[10*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[10*SIZEOF SpriteObject].animSpeed, 1
|
||
mov casinoSprites[10*SIZEOF SpriteObject].interactId, 5
|
||
mov casinoSprites[10*SIZEOF SpriteObject].promptPtr, OFFSET promptBackroom
|
||
|
||
; Sprite 11: Durak Table
|
||
mov casinoSprites[11*SIZEOF SpriteObject].posX, (26 * FP_1 + FP_HALF)
|
||
mov casinoSprites[11*SIZEOF SpriteObject].posY, (23 * FP_1 + FP_HALF)
|
||
mov casinoSprites[11*SIZEOF SpriteObject].baseTexId, 30
|
||
mov casinoSprites[11*SIZEOF SpriteObject].frameCount, 1
|
||
mov casinoSprites[11*SIZEOF SpriteObject].curFrame, 0
|
||
mov casinoSprites[11*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[11*SIZEOF SpriteObject].animSpeed, 1
|
||
mov casinoSprites[11*SIZEOF SpriteObject].interactId, 10
|
||
mov casinoSprites[11*SIZEOF SpriteObject].promptPtr, OFFSET promptDurak
|
||
|
||
; Sprite 12: Hell Portal
|
||
mov casinoSprites[12*SIZEOF SpriteObject].posX, (24 * FP_1 + FP_HALF)
|
||
mov casinoSprites[12*SIZEOF SpriteObject].posY, (3 * FP_1 + FP_HALF)
|
||
mov casinoSprites[12*SIZEOF SpriteObject].baseTexId, 4
|
||
mov casinoSprites[12*SIZEOF SpriteObject].frameCount, 1
|
||
mov casinoSprites[12*SIZEOF SpriteObject].curFrame, 0
|
||
mov casinoSprites[12*SIZEOF SpriteObject].animTimer, 0
|
||
mov casinoSprites[12*SIZEOF SpriteObject].animSpeed, 1
|
||
mov casinoSprites[12*SIZEOF SpriteObject].interactId, 9
|
||
mov casinoSprites[12*SIZEOF SpriteObject].promptPtr, OFFSET promptHell
|
||
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
Init3DEngine ENDP
|
||
|
||
; --- Fast 2D Drawing Primitives ---
|
||
DrawPixel PROC x:DWORD, y:DWORD, color:DWORD
|
||
mov eax, x
|
||
cmp eax, 0
|
||
jl @F
|
||
cmp eax, SCREEN_W
|
||
jge @F
|
||
mov ecx, y
|
||
cmp ecx, 0
|
||
jl @F
|
||
cmp ecx, SCREEN_H
|
||
jge @F
|
||
imul ecx, SCREEN_W
|
||
add ecx, eax
|
||
mov edx, color
|
||
mov [screenBuffer + ecx*4], edx
|
||
@@:
|
||
ret
|
||
DrawPixel ENDP
|
||
|
||
DrawBox PROC x:DWORD, y:DWORD, w:DWORD, h:DWORD, color:DWORD
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
mov edi, y
|
||
box_row_loop:
|
||
mov eax, y
|
||
add eax, h
|
||
cmp edi, eax
|
||
jge box_done
|
||
cmp edi, 0
|
||
jl next_box_row
|
||
cmp edi, SCREEN_H
|
||
jge box_done
|
||
|
||
mov esi, x
|
||
box_col_loop:
|
||
mov eax, x
|
||
add eax, w
|
||
cmp esi, eax
|
||
jge next_box_row
|
||
cmp esi, 0
|
||
jl next_box_col
|
||
cmp esi, SCREEN_W
|
||
jge next_box_row
|
||
|
||
mov ecx, edi
|
||
imul ecx, SCREEN_W
|
||
add ecx, esi
|
||
mov edx, color
|
||
mov [screenBuffer + ecx*4], edx
|
||
|
||
next_box_col:
|
||
inc esi
|
||
jmp box_col_loop
|
||
|
||
next_box_row:
|
||
inc edi
|
||
jmp box_row_loop
|
||
|
||
box_done:
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
DrawBox ENDP
|
||
|
||
DrawCircle PROC cxVal:DWORD, cyVal:DWORD, radius:DWORD, color:DWORD
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
mov eax, radius
|
||
neg eax
|
||
mov edi, eax
|
||
circ_y:
|
||
cmp edi, radius
|
||
jg circ_done
|
||
mov eax, radius
|
||
neg eax
|
||
mov esi, eax
|
||
circ_x:
|
||
cmp esi, radius
|
||
jg next_circ_y
|
||
|
||
mov eax, esi
|
||
imul eax, eax
|
||
mov ebx, edi
|
||
imul ebx, ebx
|
||
add eax, ebx
|
||
mov edx, radius
|
||
imul edx, edx
|
||
cmp eax, edx
|
||
jg next_circ_x
|
||
|
||
mov eax, cxVal
|
||
add eax, esi
|
||
mov ecx, cyVal
|
||
add ecx, edi
|
||
invoke DrawPixel, eax, ecx, color
|
||
|
||
next_circ_x:
|
||
inc esi
|
||
jmp circ_x
|
||
next_circ_y:
|
||
inc edi
|
||
jmp circ_y
|
||
circ_done:
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
DrawCircle ENDP
|
||
|
||
DrawChar8x8 PROC x:DWORD, y:DWORD, chVal:DWORD, color:DWORD
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
mov eax, chVal
|
||
and eax, 0FFh
|
||
shl eax, 3
|
||
lea esi, [font8x8 + eax]
|
||
|
||
xor edi, edi
|
||
char_row_loop:
|
||
cmp edi, 8
|
||
jge char_done
|
||
mov ecx, y
|
||
add ecx, edi
|
||
cmp ecx, 0
|
||
jl next_char_row
|
||
cmp ecx, SCREEN_H
|
||
jge char_done
|
||
|
||
movzx ebx, BYTE PTR [esi + edi]
|
||
xor edx, edx
|
||
char_col_loop:
|
||
cmp edx, 8
|
||
jge next_char_row
|
||
mov eax, x
|
||
add eax, edx
|
||
cmp eax, 0
|
||
jl next_char_col
|
||
cmp eax, SCREEN_W
|
||
jge next_char_row
|
||
|
||
test ebx, 80h
|
||
jz next_char_col
|
||
|
||
push ecx
|
||
imul ecx, SCREEN_W
|
||
add ecx, eax
|
||
push edx
|
||
mov edx, color
|
||
mov [screenBuffer + ecx*4], edx
|
||
pop edx
|
||
pop ecx
|
||
|
||
next_char_col:
|
||
shl ebx, 1
|
||
inc edx
|
||
jmp char_col_loop
|
||
|
||
next_char_row:
|
||
inc edi
|
||
jmp char_row_loop
|
||
|
||
char_done:
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
DrawChar8x8 ENDP
|
||
|
||
DrawText8x8 PROC x:DWORD, y:DWORD, strPtr:DWORD, color:DWORD
|
||
push esi
|
||
push edi
|
||
mov esi, strPtr
|
||
mov edi, x
|
||
text_loop:
|
||
movzx eax, BYTE PTR [esi]
|
||
test al, al
|
||
jz text_done
|
||
invoke DrawChar8x8, edi, y, eax, color
|
||
add edi, 8
|
||
inc esi
|
||
jmp text_loop
|
||
text_done:
|
||
pop edi
|
||
pop esi
|
||
ret
|
||
DrawText8x8 ENDP
|
||
|
||
; --- Render Floor & Ceiling ---
|
||
RenderCeilingAndFloor PROC uses ebx esi edi
|
||
; Ceiling (Slot 5: 5 * 4096 = 20480 DWORDs = 81920 bytes)
|
||
xor edi, edi
|
||
ceiling_y_loop:
|
||
cmp edi, HALF_H
|
||
jge floor_render
|
||
mov ecx, edi
|
||
imul ecx, SCREEN_W
|
||
|
||
mov eax, edi
|
||
and eax, 63
|
||
shl eax, 6
|
||
|
||
xor esi, esi
|
||
ceiling_x_loop:
|
||
cmp esi, SCREEN_W
|
||
jge next_ceiling_y
|
||
|
||
mov ebx, esi
|
||
and ebx, 63
|
||
add ebx, eax
|
||
mov edx, [texturesBuffer + 81920 + ebx*4]
|
||
add ecx, esi
|
||
mov [screenBuffer + ecx*4], edx
|
||
sub ecx, esi
|
||
|
||
inc esi
|
||
jmp ceiling_x_loop
|
||
|
||
next_ceiling_y:
|
||
inc edi
|
||
jmp ceiling_y_loop
|
||
|
||
floor_render:
|
||
; Carpet Floor (Slot 3: 3 * 4096 = 12288 DWORDs = 49152 bytes)
|
||
mov edi, HALF_H
|
||
floor_y_loop:
|
||
cmp edi, SCREEN_H
|
||
jge bg_done
|
||
mov ecx, edi
|
||
imul ecx, SCREEN_W
|
||
|
||
mov eax, edi
|
||
and eax, 63
|
||
shl eax, 6
|
||
|
||
mov edx, edi
|
||
sub edx, HALF_H
|
||
shl edx, 1
|
||
add edx, 40
|
||
cmp edx, 255
|
||
jbe @F
|
||
mov edx, 255
|
||
@@:
|
||
mov ebx, edx
|
||
|
||
xor esi, esi
|
||
floor_x_loop:
|
||
cmp esi, SCREEN_W
|
||
jge next_floor_y
|
||
|
||
mov edx, esi
|
||
and edx, 63
|
||
add edx, eax
|
||
mov eax, [texturesBuffer + 49152 + edx*4]
|
||
|
||
; Shade RGB
|
||
movzx edx, al
|
||
imul edx, ebx
|
||
shr edx, 8
|
||
push edx
|
||
|
||
movzx edx, ah
|
||
imul edx, ebx
|
||
shr edx, 8
|
||
shl edx, 8
|
||
|
||
shr eax, 16
|
||
movzx eax, al
|
||
imul eax, ebx
|
||
shr eax, 8
|
||
shl eax, 16
|
||
|
||
or eax, edx
|
||
pop edx
|
||
or eax, edx
|
||
|
||
add ecx, esi
|
||
mov [screenBuffer + ecx*4], eax
|
||
sub ecx, esi
|
||
|
||
mov eax, edi
|
||
and eax, 63
|
||
shl eax, 6
|
||
|
||
inc esi
|
||
jmp floor_x_loop
|
||
|
||
next_floor_y:
|
||
inc edi
|
||
jmp floor_y_loop
|
||
|
||
bg_done:
|
||
ret
|
||
RenderCeilingAndFloor ENDP
|
||
|
||
; --- DDA Raycasting Walls Rendering ---
|
||
RenderWalls PROC
|
||
local col:DWORD
|
||
local camX:DWORD
|
||
local rayDirX:DWORD
|
||
local rayDirY:DWORD
|
||
local mapX:DWORD
|
||
local mapY:DWORD
|
||
local deltaDistX:DWORD
|
||
local deltaDistY:DWORD
|
||
local stepX:DWORD
|
||
local stepY:DWORD
|
||
local sideDistX:DWORD
|
||
local sideDistY:DWORD
|
||
local side:DWORD
|
||
local perpWallDist:DWORD
|
||
local lineH:DWORD
|
||
local drawStart:DWORD
|
||
local drawEnd:DWORD
|
||
local wallHit:DWORD
|
||
local texX:DWORD
|
||
local texId:DWORD
|
||
local shade:DWORD
|
||
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
|
||
mov eax, playerAngle
|
||
and eax, 511
|
||
mov ebx, [tableCos + eax*4]
|
||
mov playerDirX, ebx
|
||
mov ebx, [tableSin + eax*4]
|
||
mov playerDirY, ebx
|
||
|
||
imul ebx, -66
|
||
cdq
|
||
mov ecx, 100
|
||
idiv ecx
|
||
mov playerPlaneX, eax
|
||
|
||
mov eax, playerDirX
|
||
imul eax, 66
|
||
cdq
|
||
idiv ecx
|
||
mov playerPlaneY, eax
|
||
|
||
mov col, 0
|
||
col_loop:
|
||
cmp col, SCREEN_W
|
||
jge walls_done
|
||
|
||
mov eax, col
|
||
shl eax, 1
|
||
sub eax, SCREEN_W
|
||
imul eax, FP_1
|
||
cdq
|
||
mov ecx, SCREEN_W
|
||
idiv ecx
|
||
mov camX, eax
|
||
|
||
mov eax, playerPlaneX
|
||
imul camX
|
||
shrd eax, edx, 16
|
||
add eax, playerDirX
|
||
mov rayDirX, eax
|
||
|
||
mov eax, playerPlaneY
|
||
imul camX
|
||
shrd eax, edx, 16
|
||
add eax, playerDirY
|
||
mov rayDirY, eax
|
||
|
||
mov eax, playerX
|
||
sar eax, 16
|
||
mov mapX, eax
|
||
mov eax, playerY
|
||
sar eax, 16
|
||
mov mapY, eax
|
||
|
||
cmp rayDirX, 0
|
||
jne @F
|
||
mov deltaDistX, 7FFFFFFFh
|
||
jmp calc_delta_y
|
||
@@:
|
||
mov eax, FP_1
|
||
imul eax, FP_1
|
||
cdq
|
||
idiv rayDirX
|
||
test eax, eax
|
||
jns @F
|
||
neg eax
|
||
@@:
|
||
mov deltaDistX, eax
|
||
|
||
calc_delta_y:
|
||
cmp rayDirY, 0
|
||
jne @F
|
||
mov deltaDistY, 7FFFFFFFh
|
||
jmp calc_step_x
|
||
@@:
|
||
mov eax, FP_1
|
||
imul eax, FP_1
|
||
cdq
|
||
idiv rayDirY
|
||
test eax, eax
|
||
jns @F
|
||
neg eax
|
||
@@:
|
||
mov deltaDistY, eax
|
||
|
||
calc_step_x:
|
||
cmp rayDirX, 0
|
||
jge step_x_pos
|
||
mov stepX, -1
|
||
mov eax, mapX
|
||
shl eax, 16
|
||
mov ecx, playerX
|
||
sub ecx, eax
|
||
mov eax, ecx
|
||
imul deltaDistX
|
||
shrd eax, edx, 16
|
||
mov sideDistX, eax
|
||
jmp calc_step_y
|
||
step_x_pos:
|
||
mov stepX, 1
|
||
mov eax, mapX
|
||
inc eax
|
||
shl eax, 16
|
||
sub eax, playerX
|
||
imul deltaDistX
|
||
shrd eax, edx, 16
|
||
mov sideDistX, eax
|
||
|
||
calc_step_y:
|
||
cmp rayDirY, 0
|
||
jge step_y_pos
|
||
mov stepY, -1
|
||
mov eax, mapY
|
||
shl eax, 16
|
||
mov ecx, playerY
|
||
sub ecx, eax
|
||
mov eax, ecx
|
||
imul deltaDistY
|
||
shrd eax, edx, 16
|
||
mov sideDistY, eax
|
||
jmp dda_start
|
||
step_y_pos:
|
||
mov stepY, 1
|
||
mov eax, mapY
|
||
inc eax
|
||
shl eax, 16
|
||
sub eax, playerY
|
||
imul deltaDistY
|
||
shrd eax, edx, 16
|
||
mov sideDistY, eax
|
||
|
||
dda_start:
|
||
xor ecx, ecx
|
||
dda_step_loop:
|
||
inc ecx
|
||
cmp ecx, 64
|
||
jge hit_wall
|
||
|
||
mov eax, sideDistX
|
||
cmp eax, sideDistY
|
||
jge step_in_y
|
||
|
||
mov eax, deltaDistX
|
||
add sideDistX, eax
|
||
mov eax, stepX
|
||
add mapX, eax
|
||
mov side, 0
|
||
jmp check_tile
|
||
|
||
step_in_y:
|
||
mov eax, deltaDistY
|
||
add sideDistY, eax
|
||
mov eax, stepY
|
||
add mapY, eax
|
||
mov side, 1
|
||
|
||
check_tile:
|
||
cmp mapX, 0
|
||
jl hit_wall
|
||
cmp mapX, MAP_WIDTH
|
||
jge hit_wall
|
||
cmp mapY, 0
|
||
jl hit_wall
|
||
cmp mapY, MAP_HEIGHT
|
||
jge hit_wall
|
||
|
||
mov eax, mapY
|
||
shl eax, 5
|
||
add eax, mapX
|
||
movzx eax, BYTE PTR [casinoMap + eax]
|
||
test eax, eax
|
||
jnz hit_wall
|
||
jmp dda_step_loop
|
||
|
||
hit_wall:
|
||
cmp side, 0
|
||
jne perp_y
|
||
mov eax, sideDistX
|
||
sub eax, deltaDistX
|
||
mov perpWallDist, eax
|
||
jmp perp_done
|
||
perp_y:
|
||
mov eax, sideDistY
|
||
sub eax, deltaDistY
|
||
mov perpWallDist, eax
|
||
perp_done:
|
||
cmp perpWallDist, 2048
|
||
jge @F
|
||
mov perpWallDist, 2048
|
||
@@:
|
||
mov eax, col
|
||
mov edx, perpWallDist
|
||
mov [zBuffer + eax*4], edx
|
||
|
||
mov eax, SCREEN_H
|
||
imul eax, FP_1
|
||
cdq
|
||
idiv perpWallDist
|
||
mov lineH, eax
|
||
|
||
mov eax, lineH
|
||
shr eax, 1
|
||
mov ecx, HALF_H
|
||
sub ecx, eax
|
||
mov drawStart, ecx
|
||
|
||
mov eax, lineH
|
||
shr eax, 1
|
||
mov ecx, HALF_H
|
||
add ecx, eax
|
||
mov drawEnd, ecx
|
||
|
||
cmp side, 0
|
||
jne hit_side_y
|
||
mov eax, perpWallDist
|
||
imul rayDirY
|
||
shrd eax, edx, 16
|
||
add eax, playerY
|
||
mov wallHit, eax
|
||
jmp calc_tex_x
|
||
hit_side_y:
|
||
mov eax, perpWallDist
|
||
imul rayDirX
|
||
shrd eax, edx, 16
|
||
add eax, playerX
|
||
mov wallHit, eax
|
||
|
||
calc_tex_x:
|
||
mov eax, wallHit
|
||
shr eax, 10
|
||
and eax, 63
|
||
mov texX, eax
|
||
|
||
cmp side, 0
|
||
jne @F
|
||
cmp rayDirX, 0
|
||
jle @F
|
||
mov eax, 63
|
||
sub eax, texX
|
||
mov texX, eax
|
||
@@:
|
||
cmp side, 1
|
||
jne select_tex
|
||
cmp rayDirY, 0
|
||
jge select_tex
|
||
mov eax, 63
|
||
sub eax, texX
|
||
mov texX, eax
|
||
|
||
select_tex:
|
||
mov eax, mapY
|
||
shl eax, 5
|
||
add eax, mapX
|
||
movzx eax, BYTE PTR [casinoMap + eax]
|
||
mov texId, eax
|
||
cmp texId, 0
|
||
jne @F
|
||
mov texId, 1
|
||
@@:
|
||
|
||
mov eax, perpWallDist
|
||
shr eax, 12
|
||
mov edx, 256
|
||
sub edx, eax
|
||
cmp edx, 35
|
||
jge @F
|
||
mov edx, 35
|
||
@@:
|
||
cmp side, 1
|
||
jne @F
|
||
imul edx, 3
|
||
shr edx, 2
|
||
@@:
|
||
mov shade, edx
|
||
|
||
cmp drawStart, 0
|
||
jge @F
|
||
mov drawStart, 0
|
||
@@:
|
||
cmp drawEnd, SCREEN_H
|
||
jl @F
|
||
mov drawEnd, SCREEN_H - 1
|
||
@@:
|
||
|
||
; Vertical texture sampling loop
|
||
mov eax, 64 * FP_1
|
||
cdq
|
||
idiv lineH
|
||
mov esi, eax ; stepY
|
||
|
||
mov eax, lineH
|
||
shr eax, 1
|
||
add eax, drawStart
|
||
sub eax, HALF_H
|
||
imul eax, esi
|
||
mov edi, eax ; texPos
|
||
|
||
mov ecx, drawStart
|
||
draw_stripe_loop:
|
||
cmp ecx, drawEnd
|
||
jg next_col
|
||
|
||
mov eax, edi
|
||
shr eax, 16
|
||
and eax, 63
|
||
shl eax, 6
|
||
add eax, texX
|
||
|
||
; CORRECTED TEXTURE SLOT DWORD INDEX: texId * 4096 (shl 12)
|
||
mov edx, texId
|
||
shl edx, 12
|
||
add eax, edx
|
||
|
||
mov eax, [texturesBuffer + eax*4]
|
||
|
||
; Apply shading
|
||
mov ebx, shade
|
||
movzx edx, al
|
||
imul edx, ebx
|
||
shr edx, 8
|
||
push edx
|
||
|
||
movzx edx, ah
|
||
imul edx, ebx
|
||
shr edx, 8
|
||
shl edx, 8
|
||
|
||
shr eax, 16
|
||
movzx eax, al
|
||
imul eax, ebx
|
||
shr eax, 8
|
||
shl eax, 16
|
||
|
||
or eax, edx
|
||
pop edx
|
||
or eax, edx
|
||
|
||
mov edx, ecx
|
||
imul edx, SCREEN_W
|
||
add edx, col
|
||
mov [screenBuffer + edx*4], eax
|
||
|
||
add edi, esi
|
||
inc ecx
|
||
jmp draw_stripe_loop
|
||
|
||
next_col:
|
||
inc col
|
||
jmp col_loop
|
||
|
||
walls_done:
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
RenderWalls ENDP
|
||
|
||
; --- Render 2.5D Billboard Sprites ---
|
||
RenderSprites PROC
|
||
local sprIdx:DWORD
|
||
local relX:DWORD
|
||
local relY:DWORD
|
||
local invDet:DWORD
|
||
local transX:DWORD
|
||
local transY:DWORD
|
||
local sprScreenX:DWORD
|
||
local sprH:DWORD
|
||
local sprW:DWORD
|
||
local drawStartY:DWORD
|
||
local drawEndY:DWORD
|
||
local drawStartX:DWORD
|
||
local drawEndX:DWORD
|
||
local stripe:DWORD
|
||
local texX:DWORD
|
||
local texY:DWORD
|
||
local shade:DWORD
|
||
local texSlot:DWORD
|
||
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
|
||
xor esi, esi
|
||
calc_dist_loop:
|
||
cmp esi, NUM_SPRITES
|
||
jge sort_sprites
|
||
mov eax, esi
|
||
imul eax, SIZEOF SpriteObject
|
||
|
||
mov edx, [casinoSprites + eax].posX
|
||
sub edx, playerX
|
||
sar edx, 8
|
||
imul edx, edx
|
||
mov ebx, edx
|
||
|
||
mov edx, [casinoSprites + eax].posY
|
||
sub edx, playerY
|
||
sar edx, 8
|
||
imul edx, edx
|
||
add ebx, edx
|
||
|
||
mov [casinoSprites + eax].distSq, ebx
|
||
mov [sortedSprites + esi*4], esi
|
||
inc esi
|
||
jmp calc_dist_loop
|
||
|
||
sort_sprites:
|
||
xor esi, esi
|
||
sort_outer:
|
||
cmp esi, NUM_SPRITES - 1
|
||
jge render_sorted_sprites
|
||
mov edi, esi
|
||
inc edi
|
||
sort_inner:
|
||
cmp edi, NUM_SPRITES
|
||
jge next_sort_outer
|
||
|
||
mov eax, [sortedSprites + esi*4]
|
||
imul eax, SIZEOF SpriteObject
|
||
mov eax, [casinoSprites + eax].distSq
|
||
|
||
mov ebx, [sortedSprites + edi*4]
|
||
imul ebx, SIZEOF SpriteObject
|
||
mov ebx, [casinoSprites + ebx].distSq
|
||
|
||
cmp eax, ebx
|
||
jge @F
|
||
mov ecx, [sortedSprites + esi*4]
|
||
mov edx, [sortedSprites + edi*4]
|
||
mov [sortedSprites + esi*4], edx
|
||
mov [sortedSprites + edi*4], ecx
|
||
@@:
|
||
inc edi
|
||
jmp sort_inner
|
||
next_sort_outer:
|
||
inc esi
|
||
jmp sort_outer
|
||
|
||
render_sorted_sprites:
|
||
xor esi, esi
|
||
draw_spr_loop:
|
||
cmp esi, NUM_SPRITES
|
||
jge sprites_rendered
|
||
|
||
mov eax, [sortedSprites + esi*4]
|
||
mov sprIdx, eax
|
||
imul eax, SIZEOF SpriteObject
|
||
|
||
; Advance sprite animation
|
||
mov edx, [casinoSprites + eax].animTimer
|
||
inc edx
|
||
cmp edx, [casinoSprites + eax].animSpeed
|
||
jl store_anim
|
||
xor edx, edx
|
||
mov ecx, [casinoSprites + eax].curFrame
|
||
inc ecx
|
||
cmp ecx, [casinoSprites + eax].frameCount
|
||
jl @F
|
||
xor ecx, ecx
|
||
@@:
|
||
mov [casinoSprites + eax].curFrame, ecx
|
||
store_anim:
|
||
mov [casinoSprites + eax].animTimer, edx
|
||
|
||
cmp [casinoSprites + eax].distSq, 16
|
||
jle next_spr
|
||
|
||
mov edx, [casinoSprites + eax].posX
|
||
sub edx, playerX
|
||
mov relX, edx
|
||
|
||
mov edx, [casinoSprites + eax].posY
|
||
sub edx, playerY
|
||
mov relY, edx
|
||
|
||
mov eax, playerPlaneX
|
||
imul playerDirY
|
||
shrd eax, edx, 16
|
||
mov ebx, eax
|
||
|
||
mov eax, playerDirX
|
||
imul playerPlaneY
|
||
shrd eax, edx, 16
|
||
sub ebx, eax
|
||
test ebx, ebx
|
||
jz next_spr
|
||
|
||
mov eax, FP_1
|
||
imul eax, FP_1
|
||
cdq
|
||
idiv ebx
|
||
mov invDet, eax
|
||
|
||
mov eax, playerDirY
|
||
imul relX
|
||
shrd eax, edx, 16
|
||
mov ebx, eax
|
||
|
||
mov eax, playerDirX
|
||
imul relY
|
||
shrd eax, edx, 16
|
||
sub ebx, eax
|
||
|
||
mov eax, ebx
|
||
imul invDet
|
||
shrd eax, edx, 16
|
||
mov transX, eax
|
||
|
||
mov eax, playerPlaneY
|
||
neg eax
|
||
imul relX
|
||
shrd eax, edx, 16
|
||
mov ebx, eax
|
||
|
||
mov eax, playerPlaneX
|
||
imul relY
|
||
shrd eax, edx, 16
|
||
add ebx, eax
|
||
|
||
mov eax, ebx
|
||
imul invDet
|
||
shrd eax, edx, 16
|
||
mov transY, eax
|
||
|
||
; Depth culling
|
||
cmp transY, 4096
|
||
jle next_spr
|
||
|
||
mov eax, transX
|
||
imul eax, HALF_W
|
||
cdq
|
||
idiv transY
|
||
add eax, HALF_W
|
||
mov sprScreenX, eax
|
||
|
||
mov eax, SCREEN_H
|
||
imul eax, FP_1
|
||
cdq
|
||
idiv transY
|
||
test eax, eax
|
||
jns @F
|
||
neg eax
|
||
@@:
|
||
; Limit maximum sprite height to screen height * 2 to prevent full-screen box blowout
|
||
cmp eax, SCREEN_H * 2
|
||
jle @F
|
||
mov eax, SCREEN_H * 2
|
||
@@:
|
||
mov sprH, eax
|
||
mov sprW, eax
|
||
|
||
mov eax, HALF_H
|
||
mov ebx, sprH
|
||
shr ebx, 1
|
||
sub eax, ebx
|
||
mov drawStartY, eax
|
||
add eax, sprH
|
||
mov drawEndY, eax
|
||
|
||
mov eax, sprScreenX
|
||
mov ebx, sprW
|
||
shr ebx, 1
|
||
sub eax, ebx
|
||
mov drawStartX, eax
|
||
add eax, sprW
|
||
mov drawEndX, eax
|
||
|
||
cmp drawStartY, 0
|
||
jge @F
|
||
mov drawStartY, 0
|
||
@@:
|
||
cmp drawEndY, SCREEN_H
|
||
jl @F
|
||
mov drawEndY, SCREEN_H - 1
|
||
@@:
|
||
|
||
mov eax, transY
|
||
shr eax, 12
|
||
mov edx, 256
|
||
sub edx, eax
|
||
cmp edx, 40
|
||
jge @F
|
||
mov edx, 40
|
||
@@:
|
||
mov shade, edx
|
||
|
||
mov eax, sprIdx
|
||
imul eax, SIZEOF SpriteObject
|
||
mov edx, [casinoSprites + eax].baseTexId
|
||
add edx, [casinoSprites + eax].curFrame
|
||
mov texSlot, edx
|
||
|
||
mov eax, drawStartX
|
||
mov stripe, eax
|
||
|
||
spr_stripe_loop:
|
||
mov eax, stripe
|
||
cmp eax, drawEndX
|
||
jge next_spr
|
||
|
||
cmp eax, 0
|
||
jl next_spr_stripe
|
||
cmp eax, SCREEN_W
|
||
jge next_spr
|
||
|
||
mov edx, transY
|
||
cmp edx, [zBuffer + eax*4]
|
||
jge next_spr_stripe
|
||
|
||
mov eax, stripe
|
||
sub eax, sprScreenX
|
||
mov ebx, sprW
|
||
shr ebx, 1
|
||
add eax, ebx
|
||
shl eax, 6
|
||
cdq
|
||
idiv sprW
|
||
cmp eax, 0
|
||
jl next_spr_stripe
|
||
cmp eax, 64
|
||
jge next_spr_stripe
|
||
mov texX, eax
|
||
|
||
mov edi, drawStartY
|
||
spr_pix_y_loop:
|
||
cmp edi, drawEndY
|
||
jg next_spr_stripe
|
||
|
||
mov eax, edi
|
||
sub eax, HALF_H
|
||
mov ebx, sprH
|
||
shr ebx, 1
|
||
add eax, ebx
|
||
shl eax, 6
|
||
cdq
|
||
idiv sprH
|
||
cmp eax, 0
|
||
jl next_spr_y
|
||
cmp eax, 64
|
||
jge next_spr_y
|
||
mov texY, eax
|
||
|
||
shl eax, 6
|
||
add eax, texX
|
||
; CORRECTED TEXTURE SLOT DWORD INDEX: texSlot * 4096 (shl 12)
|
||
mov edx, texSlot
|
||
shl edx, 12
|
||
add eax, edx
|
||
|
||
mov eax, [texturesBuffer + eax*4]
|
||
|
||
; ROBUST CHROMAKEY FILTER:
|
||
; Skip if pure magenta or black
|
||
cmp eax, CHROMA_KEY
|
||
je next_spr_y
|
||
test eax, eax
|
||
jz next_spr_y
|
||
|
||
; Skip if near-magenta: Green is low (< 0x20) and Blue & Red are both high (> 0xD0)
|
||
mov ecx, eax
|
||
and ecx, 0000FF00h ; Green
|
||
cmp ecx, 00002000h
|
||
ja do_draw_sprite_pix
|
||
mov ecx, eax
|
||
and ecx, 00FF0000h ; Red
|
||
cmp ecx, 00D00000h
|
||
jb do_draw_sprite_pix
|
||
mov ecx, eax
|
||
and ecx, 000000FFh ; Blue
|
||
cmp ecx, 000000D0h
|
||
ja next_spr_y
|
||
|
||
do_draw_sprite_pix:
|
||
mov ebx, shade
|
||
movzx edx, al
|
||
imul edx, ebx
|
||
shr edx, 8
|
||
push edx
|
||
|
||
movzx edx, ah
|
||
imul edx, ebx
|
||
shr edx, 8
|
||
shl edx, 8
|
||
|
||
shr eax, 16
|
||
movzx eax, al
|
||
imul eax, ebx
|
||
shr eax, 8
|
||
shl eax, 16
|
||
|
||
or eax, edx
|
||
pop edx
|
||
or eax, edx
|
||
|
||
mov edx, edi
|
||
imul edx, SCREEN_W
|
||
add edx, stripe
|
||
mov [screenBuffer + edx*4], eax
|
||
|
||
next_spr_y:
|
||
inc edi
|
||
jmp spr_pix_y_loop
|
||
|
||
next_spr_stripe:
|
||
inc stripe
|
||
jmp spr_stripe_loop
|
||
|
||
next_spr:
|
||
inc esi
|
||
jmp draw_spr_loop
|
||
|
||
sprites_rendered:
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
RenderSprites ENDP
|
||
|
||
; --- Radar / Minimap Overlay ---
|
||
RenderMinimap PROC uses ebx esi edi
|
||
cmp radarActive, 0
|
||
je map_done
|
||
|
||
invoke DrawBox, 248, 2, 68, 68, 00101018h
|
||
invoke DrawBox, 249, 3, 66, 66, 00403010h
|
||
|
||
xor edi, edi
|
||
map_y_row:
|
||
cmp edi, MAP_HEIGHT
|
||
jge draw_map_sprites
|
||
|
||
xor esi, esi
|
||
map_x_col:
|
||
cmp esi, MAP_WIDTH
|
||
jge next_map_row
|
||
|
||
mov eax, edi
|
||
shl eax, 5
|
||
add eax, esi
|
||
movzx eax, BYTE PTR [casinoMap + eax]
|
||
test eax, eax
|
||
jz next_map_col
|
||
|
||
mov eax, esi
|
||
shl eax, 1
|
||
add eax, 250
|
||
mov ebx, edi
|
||
shl ebx, 1
|
||
add ebx, 4
|
||
|
||
invoke DrawPixel, eax, ebx, 00908050h
|
||
inc eax
|
||
invoke DrawPixel, eax, ebx, 00908050h
|
||
dec eax
|
||
inc ebx
|
||
invoke DrawPixel, eax, ebx, 00706030h
|
||
inc eax
|
||
invoke DrawPixel, eax, ebx, 00706030h
|
||
|
||
next_map_col:
|
||
inc esi
|
||
jmp map_x_col
|
||
|
||
next_map_row:
|
||
inc edi
|
||
jmp map_y_row
|
||
|
||
draw_map_sprites:
|
||
xor esi, esi
|
||
map_spr_loop:
|
||
cmp esi, NUM_SPRITES
|
||
jge draw_map_player
|
||
|
||
mov eax, esi
|
||
imul eax, SIZEOF SpriteObject
|
||
|
||
mov edx, [casinoSprites + eax].posX
|
||
shr edx, 16
|
||
shl edx, 1
|
||
add edx, 250
|
||
|
||
mov ecx, [casinoSprites + eax].posY
|
||
shr ecx, 16
|
||
shl ecx, 1
|
||
add ecx, 4
|
||
|
||
mov ebx, [casinoSprites + eax].interactId
|
||
cmp ebx, 8
|
||
jne @F
|
||
mov ebx, 00FF40A0h ; Pink
|
||
jmp draw_spr_dot
|
||
@@:
|
||
cmp ebx, 6
|
||
jne @F
|
||
mov ebx, 0040D0FFh ; Cyan
|
||
jmp draw_spr_dot
|
||
@@:
|
||
cmp ebx, 9
|
||
jne @F
|
||
mov ebx, 00FF2020h ; Red
|
||
jmp draw_spr_dot
|
||
@@:
|
||
mov ebx, 0030FF40h ; Green
|
||
|
||
draw_spr_dot:
|
||
invoke DrawPixel, edx, ecx, ebx
|
||
inc edx
|
||
invoke DrawPixel, edx, ecx, ebx
|
||
|
||
inc esi
|
||
jmp map_spr_loop
|
||
|
||
draw_map_player:
|
||
mov edx, playerX
|
||
shr edx, 16
|
||
shl edx, 1
|
||
add edx, 250
|
||
|
||
mov ecx, playerY
|
||
shr ecx, 16
|
||
shl ecx, 1
|
||
add ecx, 4
|
||
|
||
invoke DrawPixel, edx, ecx, 00FFFF00h
|
||
inc edx
|
||
invoke DrawPixel, edx, ecx, 00FFFF00h
|
||
dec edx
|
||
inc ecx
|
||
invoke DrawPixel, edx, ecx, 00FFFF00h
|
||
inc edx
|
||
invoke DrawPixel, edx, ecx, 00FFFF00h
|
||
|
||
mov eax, playerDirX
|
||
sar eax, 13
|
||
add edx, eax
|
||
mov eax, playerDirY
|
||
sar eax, 13
|
||
add ecx, eax
|
||
invoke DrawPixel, edx, ecx, 00FFCC00h
|
||
|
||
map_done:
|
||
ret
|
||
RenderMinimap ENDP
|
||
|
||
; --- Format UInt to Decimal String in hudNumBuffer ---
|
||
FormatUIntString PROC val:DWORD
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
mov eax, val
|
||
lea edi, [hudNumBuffer + 31]
|
||
mov BYTE PTR [edi], 0
|
||
dec edi
|
||
mov ebx, 10
|
||
conv_loop:
|
||
xor edx, edx
|
||
div ebx
|
||
add dl, '0'
|
||
mov [edi], dl
|
||
dec edi
|
||
test eax, eax
|
||
jnz conv_loop
|
||
inc edi
|
||
mov eax, edi
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
FormatUIntString ENDP
|
||
|
||
; --- Render HUD Status Bar & Prompts ---
|
||
RenderHUD PROC uses ebx esi edi
|
||
invoke DrawBox, 0, 216, SCREEN_W, 24, 00141418h
|
||
invoke DrawBox, 0, 216, SCREEN_W, 1, 00D4AF37h
|
||
|
||
invoke DrawText8x8, 8, 220, OFFSET statusHUDFormat, 00D4AF37h
|
||
invoke FormatUIntString, bankroll
|
||
invoke DrawText8x8, 64, 220, eax, 0040FF40h
|
||
|
||
invoke DrawText8x8, 120, 220, OFFSET targetHUDFormat, 00D4AF37h
|
||
invoke FormatUIntString, targetBank
|
||
invoke DrawText8x8, 192, 220, eax, 0040D0FFh
|
||
|
||
invoke DrawText8x8, 240, 220, OFFSET luckHUDFormat, 00FF40A0h
|
||
invoke FormatUIntString, dancerLuckBuff
|
||
invoke DrawText8x8, 304, 220, eax, 00FF40A0h
|
||
|
||
cmp flashTimer, 0
|
||
jle check_interaction_prompt
|
||
dec flashTimer
|
||
invoke DrawBox, 10, 95, SCREEN_W - 20, 20, 00101018h
|
||
invoke DrawBox, 10, 95, SCREEN_W - 20, 1, 0030FF30h
|
||
invoke DrawBox, 10, 114, SCREEN_W - 20, 1, 0030FF30h
|
||
invoke DrawText8x8, 16, 101, OFFSET flashMessage, 0030FF30h
|
||
|
||
check_interaction_prompt:
|
||
cmp interactPromptPtr, 0
|
||
je show_controls_prompt
|
||
|
||
invoke DrawBox, 12, 188, SCREEN_W - 24, 20, 00141010h
|
||
invoke DrawBox, 12, 188, SCREEN_W - 24, 1, 00FFFF00h
|
||
invoke DrawBox, 12, 207, SCREEN_W - 24, 1, 00FFFF00h
|
||
invoke DrawText8x8, 18, 194, interactPromptPtr, 00FFFF00h
|
||
jmp hud_done
|
||
|
||
show_controls_prompt:
|
||
invoke DrawText8x8, 6, 6, OFFSET controlsHUD, 00888888h
|
||
|
||
hud_done:
|
||
ret
|
||
RenderHUD ENDP
|
||
|
||
; --- Proximity Interaction Detection ---
|
||
CheckInteractions PROC uses ebx esi edi
|
||
mov interactTargetId, 0
|
||
mov interactPromptPtr, 0
|
||
|
||
xor esi, esi
|
||
check_loop:
|
||
cmp esi, NUM_SPRITES
|
||
jge check_done
|
||
|
||
mov eax, esi
|
||
imul eax, SIZEOF SpriteObject
|
||
mov ebx, [casinoSprites + eax].distSq
|
||
|
||
cmp ebx, 262144
|
||
jge next_check
|
||
|
||
mov edx, [casinoSprites + eax].interactId
|
||
mov interactTargetId, edx
|
||
mov edx, [casinoSprites + eax].promptPtr
|
||
mov interactPromptPtr, edx
|
||
jmp check_done
|
||
|
||
next_check:
|
||
inc esi
|
||
jmp check_loop
|
||
|
||
check_done:
|
||
ret
|
||
CheckInteractions ENDP
|
||
|
||
CopyString PROC src:DWORD, dst:DWORD
|
||
push esi
|
||
push edi
|
||
mov esi, src
|
||
mov edi, dst
|
||
@@:
|
||
mov al, [esi]
|
||
mov [edi], al
|
||
test al, al
|
||
jz @F
|
||
inc esi
|
||
inc edi
|
||
jmp @B
|
||
@@:
|
||
pop edi
|
||
pop esi
|
||
ret
|
||
CopyString ENDP
|
||
|
||
; ==============================================================================
|
||
; VISUAL GAME ANIMATIONS
|
||
; ==============================================================================
|
||
|
||
AnimChipFlight PROC startX:DWORD, startY:DWORD, targetX:DWORD, targetY:DWORD, chipColor:DWORD
|
||
local frame:DWORD
|
||
local curX:DWORD
|
||
local curY:DWORD
|
||
local arcH:DWORD
|
||
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
|
||
invoke PlaySoundA, OFFSET soundCoin, 0, SND_ASYNC or SND_FILENAME
|
||
|
||
mov frame, 0
|
||
chip_frame_loop:
|
||
cmp frame, 16
|
||
jge chip_landed
|
||
|
||
mov eax, frame
|
||
imul eax, 100
|
||
shr eax, 4
|
||
mov ecx, eax
|
||
|
||
mov eax, targetX
|
||
sub eax, startX
|
||
imul eax, ecx
|
||
cdq
|
||
mov ebx, 100
|
||
idiv ebx
|
||
add eax, startX
|
||
mov curX, eax
|
||
|
||
mov eax, targetY
|
||
sub eax, startY
|
||
imul eax, ecx
|
||
cdq
|
||
idiv ebx
|
||
add eax, startY
|
||
|
||
mov ebx, 100
|
||
sub ebx, ecx
|
||
imul ebx, ecx
|
||
cdq
|
||
mov esi, 100
|
||
idiv esi
|
||
shr eax, 1
|
||
sub eax, curY
|
||
neg eax
|
||
mov curY, eax
|
||
|
||
invoke DrawCircle, curX, curY, 6, 00D4AF37h
|
||
invoke DrawCircle, curX, curY, 4, chipColor
|
||
invoke DrawPixel, curX, curY, 00FFFFFFh
|
||
|
||
invoke StretchDIBits, h3DDC, 0, 0, WINDOW_W, WINDOW_H,\
|
||
0, 0, SCREEN_W, SCREEN_H,\
|
||
OFFSET screenBuffer, OFFSET bmi3D, DIB_RGB_COLORS, SRCCOPY
|
||
|
||
invoke Sleep, 16
|
||
inc frame
|
||
jmp chip_frame_loop
|
||
|
||
chip_landed:
|
||
invoke DrawCircle, targetX, targetY, 7, 00D4AF37h
|
||
invoke DrawCircle, targetX, targetY, 5, chipColor
|
||
invoke StretchDIBits, h3DDC, 0, 0, WINDOW_W, WINDOW_H,\
|
||
0, 0, SCREEN_W, SCREEN_H,\
|
||
OFFSET screenBuffer, OFFSET bmi3D, DIB_RGB_COLORS, SRCCOPY
|
||
invoke Sleep, 40
|
||
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
AnimChipFlight ENDP
|
||
|
||
AnimReelSpin PROC sym1:DWORD, sym2:DWORD, sym3:DWORD, isJackpot:DWORD
|
||
local frame:DWORD
|
||
local rPos1:DWORD
|
||
local rPos2:DWORD
|
||
local rPos3:DWORD
|
||
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
|
||
invoke PlaySoundA, OFFSET soundClick, 0, SND_ASYNC or SND_FILENAME
|
||
|
||
mov rPos1, 0
|
||
mov rPos2, 0
|
||
mov rPos3, 0
|
||
mov frame, 0
|
||
|
||
reel_loop:
|
||
cmp frame, 80
|
||
jge spin_finished
|
||
|
||
invoke DrawBox, 50, 40, 220, 140, 00101018h
|
||
invoke DrawBox, 50, 40, 220, 2, 00D4AF37h
|
||
invoke DrawBox, 50, 178, 220, 2, 00D4AF37h
|
||
|
||
cmp frame, 35
|
||
jge @F
|
||
add rPos1, 16
|
||
@@:
|
||
cmp frame, 55
|
||
jge @F
|
||
add rPos2, 16
|
||
@@:
|
||
cmp frame, 75
|
||
jge @F
|
||
add rPos3, 16
|
||
@@:
|
||
|
||
invoke DrawBox, 70, 55, 45, 95, 00202028h
|
||
mov eax, rPos1
|
||
and eax, 31
|
||
invoke DrawBox, 75, 75, 35, 35, 00D02020h
|
||
|
||
invoke DrawBox, 135, 55, 45, 95, 00202028h
|
||
mov eax, rPos2
|
||
and eax, 31
|
||
invoke DrawBox, 140, 75, 35, 35, 0020D020h
|
||
|
||
invoke DrawBox, 200, 55, 45, 95, 00202028h
|
||
mov eax, rPos3
|
||
and eax, 31
|
||
invoke DrawBox, 205, 75, 35, 35, 002020D0h
|
||
|
||
invoke DrawBox, 50, 92, 220, 1, 00FF0000h
|
||
|
||
invoke StretchDIBits, h3DDC, 0, 0, WINDOW_W, WINDOW_H,\
|
||
0, 0, SCREEN_W, SCREEN_H,\
|
||
OFFSET screenBuffer, OFFSET bmi3D, DIB_RGB_COLORS, SRCCOPY
|
||
|
||
invoke Sleep, 16
|
||
inc frame
|
||
jmp reel_loop
|
||
|
||
spin_finished:
|
||
cmp isJackpot, 0
|
||
je spin_exit
|
||
|
||
invoke PlaySoundA, OFFSET soundJackpot, 0, SND_ASYNC or SND_FILENAME
|
||
invoke DrawBox, 60, 45, 200, 25, 00FFD700h
|
||
invoke DrawBox, 62, 47, 196, 21, 00800000h
|
||
|
||
invoke StretchDIBits, h3DDC, 0, 0, WINDOW_W, WINDOW_H,\
|
||
0, 0, SCREEN_W, SCREEN_H,\
|
||
OFFSET screenBuffer, OFFSET bmi3D, DIB_RGB_COLORS, SRCCOPY
|
||
invoke Sleep, 250
|
||
|
||
spin_exit:
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
AnimReelSpin ENDP
|
||
|
||
AnimCardDealAndFlip PROC targetX:DWORD, targetY:DWORD, rankChar:DWORD, isRed:DWORD
|
||
local frame:DWORD
|
||
local curX:DWORD
|
||
local curY:DWORD
|
||
local cardW:DWORD
|
||
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
|
||
invoke PlaySoundA, OFFSET soundCards, 0, SND_ASYNC or SND_FILENAME
|
||
|
||
mov frame, 0
|
||
slide_loop:
|
||
cmp frame, 12
|
||
jge start_flip
|
||
|
||
mov eax, targetX
|
||
sub eax, 260
|
||
imul eax, frame
|
||
cdq
|
||
mov ecx, 12
|
||
idiv ecx
|
||
add eax, 260
|
||
mov curX, eax
|
||
|
||
mov eax, targetY
|
||
sub eax, 30
|
||
imul eax, frame
|
||
cdq
|
||
idiv ecx
|
||
add eax, 30
|
||
mov curY, eax
|
||
|
||
invoke DrawBox, curX, curY, 24, 34, 00000000h
|
||
invoke DrawBox, curX, curY, 22, 32, 00103080h
|
||
invoke DrawBox, curX, curY, 22, 1, 00D4AF37h
|
||
|
||
invoke StretchDIBits, h3DDC, 0, 0, WINDOW_W, WINDOW_H,\
|
||
0, 0, SCREEN_W, SCREEN_H,\
|
||
OFFSET screenBuffer, OFFSET bmi3D, DIB_RGB_COLORS, SRCCOPY
|
||
invoke Sleep, 16
|
||
inc frame
|
||
jmp slide_loop
|
||
|
||
start_flip:
|
||
mov frame, 0
|
||
flip_loop:
|
||
cmp frame, 10
|
||
jge flip_done
|
||
|
||
cmp frame, 5
|
||
jge flip_expand
|
||
mov eax, 5
|
||
sub eax, frame
|
||
imul eax, 22
|
||
cdq
|
||
mov ecx, 5
|
||
idiv ecx
|
||
mov cardW, eax
|
||
|
||
mov eax, 22
|
||
sub eax, cardW
|
||
shr eax, 1
|
||
add eax, targetX
|
||
mov curX, eax
|
||
|
||
invoke DrawBox, curX, targetY, cardW, 32, 00103080h
|
||
jmp flip_frame_show
|
||
|
||
flip_expand:
|
||
mov eax, frame
|
||
sub eax, 5
|
||
imul eax, 22
|
||
cdq
|
||
mov ecx, 5
|
||
idiv ecx
|
||
mov cardW, eax
|
||
|
||
mov eax, 22
|
||
sub eax, cardW
|
||
shr eax, 1
|
||
add eax, targetX
|
||
mov curX, eax
|
||
|
||
invoke DrawBox, curX, targetY, cardW, 32, 00FFFFFFh
|
||
invoke DrawBox, curX, targetY, cardW, 1, 00000000h
|
||
|
||
mov edx, 00000000h
|
||
cmp isRed, 0
|
||
je @F
|
||
mov edx, 00CC0000h
|
||
@@:
|
||
invoke DrawChar8x8, curX, targetY, rankChar, edx
|
||
|
||
flip_frame_show:
|
||
invoke StretchDIBits, h3DDC, 0, 0, WINDOW_W, WINDOW_H,\
|
||
0, 0, SCREEN_W, SCREEN_H,\
|
||
OFFSET screenBuffer, OFFSET bmi3D, DIB_RGB_COLORS, SRCCOPY
|
||
invoke Sleep, 16
|
||
inc frame
|
||
jmp flip_loop
|
||
|
||
flip_done:
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
AnimCardDealAndFlip ENDP
|
||
|
||
AnimRouletteWheel PROC winningNumber:DWORD
|
||
local frame:DWORD
|
||
local wheelAng:DWORD
|
||
local ballAng:DWORD
|
||
local ballRadius:DWORD
|
||
local ballX:DWORD
|
||
local ballY:DWORD
|
||
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
|
||
invoke PlaySoundA, OFFSET soundRoulette, 0, SND_ASYNC or SND_FILENAME
|
||
|
||
mov wheelAng, 0
|
||
mov ballAng, 0
|
||
mov ballRadius, 52
|
||
mov frame, 0
|
||
|
||
roulette_anim_loop:
|
||
cmp frame, 90
|
||
jge roulette_finished
|
||
|
||
add wheelAng, 12
|
||
and wheelAng, 511
|
||
|
||
add ballAng, 28
|
||
and ballAng, 511
|
||
cmp frame, 45
|
||
jl @F
|
||
cmp ballRadius, 36
|
||
jle @F
|
||
dec ballRadius
|
||
@@:
|
||
|
||
invoke DrawCircle, 160, 105, 60, 00603010h
|
||
invoke DrawCircle, 160, 105, 56, 00D4AF37h
|
||
invoke DrawCircle, 160, 105, 52, 00181818h
|
||
|
||
mov eax, wheelAng
|
||
and eax, 511
|
||
mov ebx, [tableCos + eax*4]
|
||
sar ebx, 10
|
||
add ebx, 160
|
||
mov ecx, [tableSin + eax*4]
|
||
sar ecx, 10
|
||
add ecx, 105
|
||
invoke DrawCircle, ebx, ecx, 4, 00CC0000h
|
||
|
||
add eax, 64
|
||
and eax, 511
|
||
mov ebx, [tableCos + eax*4]
|
||
sar ebx, 10
|
||
add ebx, 160
|
||
mov ecx, [tableSin + eax*4]
|
||
sar ecx, 10
|
||
add ecx, 105
|
||
invoke DrawCircle, ebx, ecx, 4, 00108010h
|
||
|
||
invoke DrawCircle, 160, 105, 14, 00D4AF37h
|
||
invoke DrawCircle, 160, 105, 8, 00FFFF80h
|
||
|
||
mov eax, ballAng
|
||
and eax, 511
|
||
mov ebx, [tableCos + eax*4]
|
||
imul ebx, ballRadius
|
||
sar ebx, 16
|
||
add ebx, 160
|
||
mov ballX, ebx
|
||
|
||
mov ecx, [tableSin + eax*4]
|
||
imul ecx, ballRadius
|
||
sar ecx, 16
|
||
add ecx, 105
|
||
mov ballY, ecx
|
||
|
||
invoke DrawCircle, ballX, ballY, 3, 00FFFFFFh
|
||
|
||
invoke StretchDIBits, h3DDC, 0, 0, WINDOW_W, WINDOW_H,\
|
||
0, 0, SCREEN_W, SCREEN_H,\
|
||
OFFSET screenBuffer, OFFSET bmi3D, DIB_RGB_COLORS, SRCCOPY
|
||
|
||
invoke Sleep, 16
|
||
inc frame
|
||
jmp roulette_anim_loop
|
||
|
||
roulette_finished:
|
||
invoke Sleep, 200
|
||
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
AnimRouletteWheel ENDP
|
||
|
||
; --- Trigger Interaction ---
|
||
Trigger3DInteraction PROC
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
|
||
mov eax, interactTargetId
|
||
test eax, eax
|
||
jz interact_exit
|
||
|
||
cmp eax, 8
|
||
jne handle_mini_games
|
||
|
||
cmp bankroll, 100
|
||
jge tip_dancer_ok
|
||
|
||
invoke CopyString, OFFSET msgNeedMoney, OFFSET flashMessage
|
||
mov flashTimer, 80
|
||
jmp interact_exit
|
||
|
||
tip_dancer_ok:
|
||
sub bankroll, 100
|
||
inc dancerLuckBuff
|
||
mov cheatLuckyWin, 1
|
||
invoke CopyString, OFFSET msgDancerTipped, OFFSET flashMessage
|
||
mov flashTimer, 120
|
||
|
||
invoke PlayHakariSound
|
||
jmp interact_exit
|
||
|
||
handle_mini_games:
|
||
cmp eax, 3
|
||
jne check_blackjack
|
||
invoke AnimReelSpin, 7, 7, 7, 1
|
||
jmp launch_console_game
|
||
|
||
check_blackjack:
|
||
cmp eax, 1
|
||
jne check_roulette
|
||
invoke AnimChipFlight, 160, 210, 160, 140, 002040D0h
|
||
invoke AnimCardDealAndFlip, 120, 110, 'A', 1
|
||
invoke AnimCardDealAndFlip, 150, 110, 'K', 0
|
||
jmp launch_console_game
|
||
|
||
check_roulette:
|
||
cmp eax, 4
|
||
jne launch_console_game
|
||
invoke AnimChipFlight, 160, 210, 200, 160, 00D02020h
|
||
invoke AnimRouletteWheel, 17
|
||
|
||
launch_console_game:
|
||
invoke ShowWindow, h3DWnd, SW_HIDE
|
||
invoke SetForegroundWindow, hCasinoConsole
|
||
|
||
mov eax, interactTargetId
|
||
cmp eax, 1
|
||
jne @F
|
||
mov currentGameId, 1
|
||
call Game21
|
||
jmp game_finished
|
||
@@:
|
||
cmp eax, 2
|
||
jne @F
|
||
mov currentGameId, 2
|
||
call GamePoker
|
||
jmp game_finished
|
||
@@:
|
||
cmp eax, 3
|
||
jne @F
|
||
mov currentGameId, 3
|
||
call PlaySlotIntroSound
|
||
call GameSlot
|
||
jmp game_finished
|
||
@@:
|
||
cmp eax, 4
|
||
jne @F
|
||
mov currentGameId, 4
|
||
call GameRoulette
|
||
jmp game_finished
|
||
@@:
|
||
cmp eax, 5
|
||
jne @F
|
||
mov currentGameId, 13
|
||
call GameBuckshot
|
||
jmp game_finished
|
||
@@:
|
||
cmp eax, 6
|
||
jne @F
|
||
call GameShop
|
||
jmp game_finished
|
||
@@:
|
||
cmp eax, 7
|
||
jne @F
|
||
call AccountMenu
|
||
jmp game_finished
|
||
@@:
|
||
cmp eax, 9
|
||
jne @F
|
||
mov currentGameId, 666
|
||
call GameTournament
|
||
jmp game_finished
|
||
@@:
|
||
cmp eax, 10
|
||
jne game_finished
|
||
mov currentGameId, 11
|
||
call GameDurak
|
||
|
||
game_finished:
|
||
call CheckVictory
|
||
|
||
invoke ShowWindow, h3DWnd, SW_SHOW
|
||
invoke UpdateWindow, h3DWnd
|
||
invoke SetForegroundWindow, h3DWnd
|
||
|
||
interact_exit:
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
Trigger3DInteraction ENDP
|
||
|
||
; --- Player Input & Movement Physics ---
|
||
HandlePlayerInput PROC
|
||
local walkSpd:DWORD
|
||
local turnSpd:DWORD
|
||
local moveDirX:DWORD
|
||
local moveDirY:DWORD
|
||
local newX:DWORD
|
||
local newY:DWORD
|
||
local checkTileX:DWORD
|
||
local checkTileY:DWORD
|
||
|
||
push ebx
|
||
push esi
|
||
push edi
|
||
|
||
mov walkSpd, 3200
|
||
mov turnSpd, 7
|
||
|
||
invoke GetAsyncKeyState, 10h
|
||
test ah, 80h
|
||
jz @F
|
||
mov walkSpd, 5600
|
||
@@:
|
||
|
||
invoke GetAsyncKeyState, 41h
|
||
test ah, 80h
|
||
jnz turn_left
|
||
invoke GetAsyncKeyState, 25h
|
||
test ah, 80h
|
||
jz check_turn_right
|
||
turn_left:
|
||
mov eax, playerAngle
|
||
sub eax, turnSpd
|
||
add eax, 512
|
||
and eax, 511
|
||
mov playerAngle, eax
|
||
|
||
check_turn_right:
|
||
invoke GetAsyncKeyState, 44h
|
||
test ah, 80h
|
||
jnz turn_right
|
||
invoke GetAsyncKeyState, 27h
|
||
test ah, 80h
|
||
jz check_walk_forward
|
||
turn_right:
|
||
mov eax, playerAngle
|
||
add eax, turnSpd
|
||
and eax, 511
|
||
mov playerAngle, eax
|
||
|
||
check_walk_forward:
|
||
invoke GetAsyncKeyState, 57h
|
||
test ah, 80h
|
||
jnz walk_fwd
|
||
invoke GetAsyncKeyState, 26h
|
||
test ah, 80h
|
||
jz check_walk_back
|
||
walk_fwd:
|
||
mov eax, playerDirX
|
||
imul walkSpd
|
||
shrd eax, edx, 16
|
||
add eax, playerX
|
||
mov newX, eax
|
||
|
||
mov eax, playerDirY
|
||
imul walkSpd
|
||
shrd eax, edx, 16
|
||
add eax, playerY
|
||
mov newY, eax
|
||
|
||
mov eax, newX
|
||
sar eax, 16
|
||
mov checkTileX, eax
|
||
mov eax, playerY
|
||
sar eax, 16
|
||
mov checkTileY, eax
|
||
mov eax, checkTileY
|
||
shl eax, 5
|
||
add eax, checkTileX
|
||
movzx eax, BYTE PTR [casinoMap + eax]
|
||
test eax, eax
|
||
jnz @F
|
||
mov eax, newX
|
||
mov playerX, eax
|
||
@@:
|
||
mov eax, playerX
|
||
sar eax, 16
|
||
mov checkTileX, eax
|
||
mov eax, newY
|
||
sar eax, 16
|
||
mov checkTileY, eax
|
||
mov eax, checkTileY
|
||
shl eax, 5
|
||
add eax, checkTileX
|
||
movzx eax, BYTE PTR [casinoMap + eax]
|
||
test eax, eax
|
||
jnz check_walk_back
|
||
mov eax, newY
|
||
mov playerY, eax
|
||
|
||
check_walk_back:
|
||
invoke GetAsyncKeyState, 53h
|
||
test ah, 80h
|
||
jnz walk_back
|
||
invoke GetAsyncKeyState, 28h
|
||
test ah, 80h
|
||
jz check_radar_toggle
|
||
walk_back:
|
||
mov eax, playerDirX
|
||
imul walkSpd
|
||
shrd eax, edx, 16
|
||
mov ebx, playerX
|
||
sub ebx, eax
|
||
mov newX, ebx
|
||
|
||
mov eax, playerDirY
|
||
imul walkSpd
|
||
shrd eax, edx, 16
|
||
mov ebx, playerY
|
||
sub ebx, eax
|
||
mov newY, ebx
|
||
|
||
mov eax, newX
|
||
sar eax, 16
|
||
mov checkTileX, eax
|
||
mov eax, playerY
|
||
sar eax, 16
|
||
mov checkTileY, eax
|
||
mov eax, checkTileY
|
||
shl eax, 5
|
||
add eax, checkTileX
|
||
movzx eax, BYTE PTR [casinoMap + eax]
|
||
test eax, eax
|
||
jnz @F
|
||
mov eax, newX
|
||
mov playerX, eax
|
||
@@:
|
||
mov eax, playerX
|
||
sar eax, 16
|
||
mov checkTileX, eax
|
||
mov eax, newY
|
||
sar eax, 16
|
||
mov checkTileY, eax
|
||
mov eax, checkTileY
|
||
shl eax, 5
|
||
add eax, checkTileX
|
||
movzx eax, BYTE PTR [casinoMap + eax]
|
||
test eax, eax
|
||
jnz check_radar_toggle
|
||
mov eax, newY
|
||
mov playerY, eax
|
||
|
||
check_radar_toggle:
|
||
invoke GetAsyncKeyState, 4Dh
|
||
test ah, 80h
|
||
jnz toggle_radar
|
||
invoke GetAsyncKeyState, 09h
|
||
test ah, 80h
|
||
jz check_action_key
|
||
toggle_radar:
|
||
xor radarActive, 1
|
||
invoke Sleep, 120
|
||
|
||
check_action_key:
|
||
invoke GetAsyncKeyState, 45h
|
||
test ah, 80h
|
||
jnz do_action
|
||
invoke GetAsyncKeyState, 20h
|
||
test ah, 80h
|
||
jz input_done
|
||
do_action:
|
||
call Trigger3DInteraction
|
||
invoke Sleep, 150
|
||
|
||
input_done:
|
||
pop edi
|
||
pop esi
|
||
pop ebx
|
||
ret
|
||
HandlePlayerInput ENDP
|
||
|
||
; --- Main Loop of the 3D Casino Engine ---
|
||
StartCasino3D PROC uses ebx esi edi
|
||
call Init3DEngine
|
||
call PlaySlotIntroSound
|
||
|
||
engine_loop:
|
||
lea eax, [msg3D]
|
||
invoke PeekMessageA, eax, 0, 0, 0, PM_REMOVE
|
||
test eax, eax
|
||
jz @F
|
||
cmp msg3D.message, WM_QUIT
|
||
je exit_3d_engine
|
||
lea eax, [msg3D]
|
||
invoke TranslateMessage, eax
|
||
lea eax, [msg3D]
|
||
invoke DispatchMessageA, eax
|
||
@@:
|
||
|
||
invoke GetAsyncKeyState, 1Bh
|
||
test ah, 80h
|
||
jnz exit_3d_engine
|
||
|
||
call HandlePlayerInput
|
||
call CheckInteractions
|
||
|
||
call RenderCeilingAndFloor
|
||
call RenderWalls
|
||
call RenderSprites
|
||
call RenderHUD
|
||
call RenderMinimap
|
||
|
||
invoke StretchDIBits, h3DDC, 0, 0, WINDOW_W, WINDOW_H,\
|
||
0, 0, SCREEN_W, SCREEN_H,\
|
||
OFFSET screenBuffer, OFFSET bmi3D, DIB_RGB_COLORS, SRCCOPY
|
||
|
||
invoke Sleep, 16
|
||
jmp engine_loop
|
||
|
||
exit_3d_engine:
|
||
cmp h3DWnd, 0
|
||
je @F
|
||
invoke ShowWindow, h3DWnd, SW_HIDE
|
||
@@:
|
||
invoke SetForegroundWindow, hCasinoConsole
|
||
ret
|
||
StartCasino3D ENDP
|