3231 lines
73 KiB
Python
3231 lines
73 KiB
Python
# -*- coding: utf-8 -*-
|
|
import sys
|
|
|
|
# Builder for casino3d.inc
|
|
code_chunks = []
|
|
|
|
def a(s):
|
|
code_chunks.append(s)
|
|
|
|
# SECTION 1: Header, APIs, Structures, Constants
|
|
a('''
|
|
; ==============================================================================
|
|
; CASINO 3D ENGINE - DOOM / RETRO RAYCASTER FOR MASM32 (CP1251)
|
|
; ALL MINI-GAMES FULLY RENDERED IN 2.5D INSIDE THE GRAPHICAL WINDOW
|
|
; ==============================================================================
|
|
|
|
includelib gdi32.lib
|
|
includelib winmm.lib
|
|
|
|
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
|
|
Sleep PROTO :DWORD
|
|
|
|
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 ?
|
|
posY dd ?
|
|
baseTexId dd ?
|
|
frameCount dd ?
|
|
curFrame dd ?
|
|
animTimer dd ?
|
|
animSpeed dd ?
|
|
interactId dd ?
|
|
promptPtr dd ?
|
|
distSq dd ?
|
|
SpriteObject ENDS
|
|
|
|
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 4
|
|
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
|
|
|
|
MODE_WALK equ 0
|
|
MODE_SLOTS equ 1
|
|
MODE_BLACKJACK equ 2
|
|
MODE_ROULETTE equ 3
|
|
MODE_SHOP equ 4
|
|
MODE_ATM equ 5
|
|
|
|
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
|
|
INVALID_FILE_HANDLE equ -1
|
|
|
|
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)
|
|
|
|
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
|
|
|
|
playerX dd (16 * FP_1 + FP_HALF)
|
|
playerY dd (16 * FP_1 + FP_HALF)
|
|
playerAngle dd 384
|
|
playerDirX dd 0
|
|
playerDirY dd -FP_1
|
|
playerPlaneX dd (FP_1 * 66 / 100)
|
|
playerPlaneY dd 0
|
|
|
|
engineMode dd 0
|
|
interactTargetId dd 0
|
|
interactPromptPtr dd 0
|
|
dancerLuckBuff dd 0
|
|
flashTimer dd 0
|
|
flashMessage db 128 dup(0)
|
|
|
|
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] Бармен: VIP Магазин и Напитки",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/Стрелки: Ходьба | E: Действие | ESC: Меню",0
|
|
|
|
NUM_SPRITES equ 13
|
|
ALIGN 4
|
|
casinoSprites SpriteObject NUM_SPRITES dup(<>)
|
|
sortedSprites dd NUM_SPRITES dup(0)
|
|
|
|
rowDistTable dd 120 dup(0)
|
|
rngSeed3D dd 12345678h
|
|
|
|
slotBet dd 50
|
|
slotReel1 dd 0
|
|
slotReel2 dd 1
|
|
slotReel3 dd 2
|
|
slotSpinState dd 0
|
|
slotSpinTimer dd 0
|
|
slotWinAmount dd 0
|
|
slotWinMsg db 64 dup(0)
|
|
|
|
bjState dd 0
|
|
bjBet dd 100
|
|
bjPlayerCards dd 10 dup(0)
|
|
bjPlayerCardCount dd 0
|
|
bjPlayerScore dd 0
|
|
bjDealerCards dd 10 dup(0)
|
|
bjDealerCardCount dd 0
|
|
bjDealerScore dd 0
|
|
bjDealerHideHole dd 1
|
|
bjOutcomeMsg db 64 dup(0)
|
|
|
|
roulState dd 0
|
|
roulBetType dd 1
|
|
roulBetAmount dd 100
|
|
roulWheelAngle dd 0
|
|
roulBallAngle dd 0
|
|
roulSpinTimer dd 0
|
|
roulWinningNum dd 0
|
|
roulPayout dd 0
|
|
roulOutcomeMsg db 64 dup(0)
|
|
|
|
shopMsg db 128 dup(0)
|
|
atmMsg db 128 dup(0)
|
|
|
|
strWin db "ПОБЕДА! +$",0
|
|
strLose db "ПРОИГРЫШ",0
|
|
strJackpot db "ДЖЕКПОТ! +$",0
|
|
strPush db "НИЧЬЯ (PUSH)",0
|
|
strDealerBust db "ДИЛЕР ПЕРЕБРАЛ! ПОБЕДА! +$",0
|
|
strPlayerBust db "ПЕРЕБОР (>21)! ПРОИГРЫШ",0
|
|
|
|
sym7 db " 777 ",0
|
|
symBar db " BAR ",0
|
|
symBell db " BELL",0
|
|
symCherry db "CHERRY",0
|
|
symClover db "CLOVER",0
|
|
symGem db " GEM ",0
|
|
symCrown db "CROWN",0
|
|
|
|
cardRankStr db "A ",0,"2 ",0,"3 ",0,"4 ",0,"5 ",0,"6 ",0,"7 ",0,"8 ",0,"9 ",0,"10",0,"J ",0,"Q ",0,"K ",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(?)
|
|
''')
|
|
|
|
# SECTION 2: Drawing primitives & Math
|
|
a('''
|
|
.code
|
|
|
|
; --- 3D Window 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
|
|
|
|
; --- Random Generator ---
|
|
RandomRange3D PROC maxVal:DWORD
|
|
mov eax, rngSeed3D
|
|
imul eax, 1103515245
|
|
add eax, 12345
|
|
mov rngSeed3D, eax
|
|
shr eax, 16
|
|
and eax, 7FFFh
|
|
xor edx, edx
|
|
div maxVal
|
|
mov eax, edx
|
|
ret
|
|
RandomRange3D ENDP
|
|
|
|
; --- Copy String ---
|
|
CopyString3D 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
|
|
CopyString3D ENDP
|
|
|
|
; --- Format Number to Decimal String ---
|
|
FormatNumber PROC num:DWORD, buf:DWORD
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
mov eax, num
|
|
mov edi, buf
|
|
test eax, eax
|
|
jns fn_pos
|
|
mov BYTE PTR [edi], '-'
|
|
inc edi
|
|
neg eax
|
|
fn_pos:
|
|
mov ebx, 10
|
|
push 0
|
|
fn_div:
|
|
xor edx, edx
|
|
div ebx
|
|
add dl, '0'
|
|
push edx
|
|
test eax, eax
|
|
jnz fn_div
|
|
fn_pop:
|
|
pop eax
|
|
test al, al
|
|
jz fn_done
|
|
mov [edi], al
|
|
inc edi
|
|
jmp fn_pop
|
|
fn_done:
|
|
mov BYTE PTR [edi], 0
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
ret
|
|
FormatNumber 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
|
|
|
|
DrawBoxBorder PROC x:DWORD, y:DWORD, w:DWORD, h:DWORD, fillColor:DWORD, borderColor:DWORD, bWidth:DWORD
|
|
invoke DrawBox, x, y, w, h, borderColor
|
|
mov eax, x
|
|
add eax, bWidth
|
|
mov edx, y
|
|
add edx, bWidth
|
|
mov ecx, w
|
|
sub ecx, bWidth
|
|
sub ecx, bWidth
|
|
mov ebx, h
|
|
sub ebx, bWidth
|
|
sub ebx, bWidth
|
|
invoke DrawBox, eax, edx, ecx, ebx, fillColor
|
|
ret
|
|
DrawBoxBorder 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
|
|
|
|
DrawString8x8 PROC x:DWORD, y:DWORD, strPtr:DWORD, color:DWORD
|
|
push ebx
|
|
push esi
|
|
mov esi, strPtr
|
|
mov ebx, x
|
|
str_loop:
|
|
movzx eax, BYTE PTR [esi]
|
|
test al, al
|
|
jz str_done
|
|
invoke DrawChar8x8, ebx, y, eax, color
|
|
add ebx, 8
|
|
inc esi
|
|
jmp str_loop
|
|
str_done:
|
|
pop esi
|
|
pop ebx
|
|
ret
|
|
DrawString8x8 ENDP
|
|
''')
|
|
|
|
# SECTION 3: 3D Raycaster Floor, Ceiling, Walls, Sprites
|
|
a('''
|
|
; --- True 3D Perspective Floor & Ceiling Rendering ---
|
|
RenderCeilingAndFloor PROC uses ebx esi edi
|
|
local floorRow:DWORD
|
|
local pDist:DWORD
|
|
local fStepX:DWORD
|
|
local fStepY:DWORD
|
|
local fX:DWORD
|
|
local fY:DWORD
|
|
local shade:DWORD
|
|
local cShade:DWORD
|
|
|
|
; Horizon line: row 120
|
|
mov edi, 121
|
|
floor_scanlines:
|
|
cmp edi, SCREEN_H
|
|
jge floor_done
|
|
mov floorRow, edi
|
|
|
|
; Distance = (HALF_H * FP_1) / (y - HALF_H)
|
|
mov eax, edi
|
|
sub eax, HALF_H
|
|
mov ecx, eax
|
|
mov eax, HALF_H * FP_1
|
|
cdq
|
|
idiv ecx
|
|
mov pDist, eax
|
|
|
|
; Distance shading (closer is brighter, far horizon is dark)
|
|
mov edx, pDist
|
|
shr edx, 12
|
|
mov eax, 255
|
|
sub eax, edx
|
|
cmp eax, 35
|
|
jge @F
|
|
mov eax, 35
|
|
@@:
|
|
mov shade, eax
|
|
mov edx, eax
|
|
sub edx, 25
|
|
cmp edx, 20
|
|
jge @F
|
|
mov edx, 20
|
|
@@:
|
|
mov cShade, edx
|
|
|
|
; Step along scanline: (2 * playerPlane) * pDist / SCREEN_W
|
|
mov eax, playerPlaneX
|
|
shl eax, 1
|
|
imul pDist
|
|
shrd eax, edx, 16
|
|
cdq
|
|
mov ecx, SCREEN_W
|
|
idiv ecx
|
|
mov fStepX, eax
|
|
|
|
mov eax, playerPlaneY
|
|
shl eax, 1
|
|
imul pDist
|
|
shrd eax, edx, 16
|
|
cdq
|
|
mov ecx, SCREEN_W
|
|
idiv ecx
|
|
mov fStepY, eax
|
|
|
|
; Starting floor coordinates at x=0:
|
|
; player + pDist * (playerDir - playerPlane)
|
|
mov eax, playerDirX
|
|
sub eax, playerPlaneX
|
|
imul pDist
|
|
shrd eax, edx, 16
|
|
add eax, playerX
|
|
mov fX, eax
|
|
|
|
mov eax, playerDirY
|
|
sub eax, playerPlaneY
|
|
imul pDist
|
|
shrd eax, edx, 16
|
|
add eax, playerY
|
|
mov fY, eax
|
|
|
|
; Fill scanline for floor (y) and ceiling (SCREEN_H - 1 - y)
|
|
xor esi, esi
|
|
col_floor_loop:
|
|
cmp esi, SCREEN_W
|
|
jge next_floor_row
|
|
|
|
; Carpet Texture (Slot 3: 3 * 4096 * 4 = 49152 bytes)
|
|
mov eax, fX
|
|
shr eax, 10
|
|
and eax, 63
|
|
mov edx, fY
|
|
shr edx, 10
|
|
and edx, 63
|
|
shl edx, 6
|
|
add edx, eax
|
|
|
|
mov eax, [texturesBuffer + 49152 + edx*4]
|
|
|
|
; Shade Floor RGB
|
|
mov ebx, shade
|
|
movzx ecx, al
|
|
imul ecx, ebx
|
|
shr ecx, 8
|
|
push ecx
|
|
|
|
movzx ecx, ah
|
|
imul ecx, ebx
|
|
shr ecx, 8
|
|
shl ecx, 8
|
|
|
|
shr eax, 16
|
|
movzx eax, al
|
|
imul eax, ebx
|
|
shr eax, 8
|
|
shl eax, 16
|
|
or eax, ecx
|
|
pop ecx
|
|
or eax, ecx
|
|
|
|
; Store to Floor pixel
|
|
mov ecx, floorRow
|
|
imul ecx, SCREEN_W
|
|
add ecx, esi
|
|
mov [screenBuffer + ecx*4], eax
|
|
|
|
; Ceiling Spotlight Texture (Slot 5: 5 * 4096 * 4 = 81920 bytes)
|
|
mov eax, [texturesBuffer + 81920 + edx*4]
|
|
mov ebx, cShade
|
|
movzx ecx, al
|
|
imul ecx, ebx
|
|
shr ecx, 8
|
|
push ecx
|
|
|
|
movzx ecx, ah
|
|
imul ecx, ebx
|
|
shr ecx, 8
|
|
shl ecx, 8
|
|
|
|
shr eax, 16
|
|
movzx eax, al
|
|
imul eax, ebx
|
|
shr eax, 8
|
|
shl eax, 16
|
|
or eax, ecx
|
|
pop ecx
|
|
or eax, ecx
|
|
|
|
; Store to Ceiling pixel: (SCREEN_H - 1 - floorRow)
|
|
mov ecx, SCREEN_H - 1
|
|
sub ecx, floorRow
|
|
imul ecx, SCREEN_W
|
|
add ecx, esi
|
|
mov [screenBuffer + ecx*4], eax
|
|
|
|
mov eax, fStepX
|
|
add fX, eax
|
|
mov eax, fStepY
|
|
add fY, eax
|
|
inc esi
|
|
jmp col_floor_loop
|
|
|
|
next_floor_row:
|
|
inc edi
|
|
jmp floor_scanlines
|
|
|
|
floor_done:
|
|
ret
|
|
RenderCeilingAndFloor ENDP
|
|
|
|
; --- DDA Raycasting Walls ---
|
|
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
|
|
|
|
mov eax, rayDirX
|
|
test eax, eax
|
|
jnz calc_delta_x
|
|
mov deltaDistX, 7FFFFFFFh
|
|
jmp calc_delta_y
|
|
calc_delta_x:
|
|
test eax, eax
|
|
jns @F
|
|
neg eax
|
|
@@:
|
|
mov ebx, eax
|
|
mov eax, FP_1
|
|
imul eax, FP_1
|
|
cdq
|
|
idiv ebx
|
|
mov deltaDistX, eax
|
|
|
|
calc_delta_y:
|
|
mov eax, rayDirY
|
|
test eax, eax
|
|
jnz calc_delta_y_ok
|
|
mov deltaDistY, 7FFFFFFFh
|
|
jmp check_step
|
|
calc_delta_y_ok:
|
|
test eax, eax
|
|
jns @F
|
|
neg eax
|
|
@@:
|
|
mov ebx, eax
|
|
mov eax, FP_1
|
|
imul eax, FP_1
|
|
cdq
|
|
idiv ebx
|
|
mov deltaDistY, eax
|
|
|
|
check_step:
|
|
cmp rayDirX, 0
|
|
jge step_x_pos
|
|
mov stepX, -1
|
|
mov eax, playerX
|
|
mov edx, mapX
|
|
shl edx, 16
|
|
sub eax, edx
|
|
imul deltaDistX
|
|
shrd eax, edx, 16
|
|
mov sideDistX, eax
|
|
jmp check_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
|
|
|
|
check_step_y:
|
|
cmp rayDirY, 0
|
|
jge step_y_pos
|
|
mov stepY, -1
|
|
mov eax, playerY
|
|
mov edx, mapY
|
|
shl edx, 16
|
|
sub eax, edx
|
|
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
|
|
|
|
; High casino ceiling: lineH = (SCREEN_H * FP_1 * 180 / 240) / perpWallDist
|
|
mov eax, SCREEN_H * 180 / 240
|
|
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:
|
|
; MASK WITH 0FFFFh to prevent texture scrambling!
|
|
mov eax, wallHit
|
|
and eax, 0FFFFh
|
|
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
|
|
@@:
|
|
|
|
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
|
|
|
|
mov edx, texId
|
|
shl edx, 12
|
|
add eax, edx
|
|
mov eax, [texturesBuffer + eax*4]
|
|
|
|
; Shade wall pixel
|
|
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 3D 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 animation frame
|
|
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
|
|
|
|
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
|
|
@@:
|
|
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
|
|
mov edx, texSlot
|
|
shl edx, 12
|
|
add eax, edx
|
|
mov eax, [texturesBuffer + eax*4]
|
|
|
|
; Chromakey magenta filter
|
|
cmp eax, CHROMA_KEY
|
|
je next_spr_y
|
|
test eax, eax
|
|
jz next_spr_y
|
|
|
|
mov ecx, eax
|
|
and ecx, 0000FF00h
|
|
cmp ecx, 00002000h
|
|
ja do_draw_sprite_pix
|
|
mov ecx, eax
|
|
and ecx, 00FF0000h
|
|
cmp ecx, 00D00000h
|
|
jb do_draw_sprite_pix
|
|
mov ecx, eax
|
|
and ecx, 000000FFh
|
|
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 ecx, edi
|
|
imul ecx, SCREEN_W
|
|
add ecx, stripe
|
|
mov [screenBuffer + ecx*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
|
|
''')
|
|
|
|
# SECTION 4: HUD & Radar
|
|
a('''
|
|
; --- HUD & Minimap Radar ---
|
|
RenderHUD PROC uses ebx esi edi
|
|
; Top Luxury Status Bar
|
|
invoke DrawBox, 0, 0, SCREEN_W, 16, 001A0A0Ah
|
|
invoke DrawBox, 0, 15, SCREEN_W, 1, 0000D7FFh
|
|
|
|
invoke DrawString8x8, 8, 4, OFFSET statusHUDFormat, 0000D7FFh
|
|
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
|
|
invoke DrawString8x8, 90, 4, OFFSET hudNumBuffer, 0000FFFFh
|
|
|
|
invoke DrawString8x8, 140, 4, OFFSET targetHUDFormat, 0000D7FFh
|
|
invoke FormatNumber, targetBank, OFFSET hudNumBuffer
|
|
invoke DrawString8x8, 205, 4, OFFSET hudNumBuffer, 0050FF50h
|
|
|
|
invoke DrawString8x8, 250, 4, OFFSET luckHUDFormat, 00FFAA00h
|
|
invoke FormatNumber, dancerLuckBuff, OFFSET hudNumBuffer
|
|
invoke DrawString8x8, 305, 4, OFFSET hudNumBuffer, 0000FFFFh
|
|
|
|
; Flash notification banner
|
|
cmp flashTimer, 0
|
|
jle check_prompt
|
|
dec flashTimer
|
|
invoke DrawBox, 10, 20, 300, 14, 00201040h
|
|
invoke DrawBoxBorder, 10, 20, 300, 14, 00201040h, 0000D7FFh, 1
|
|
invoke DrawString8x8, 14, 23, OFFSET flashMessage, 00FFFFFFh
|
|
|
|
check_prompt:
|
|
; Interaction prompt banner at bottom
|
|
mov eax, interactPromptPtr
|
|
test eax, eax
|
|
jz draw_controls_hud
|
|
invoke DrawBoxBorder, 20, 195, 280, 18, 00201010h, 0000FFFFh, 1
|
|
invoke DrawString8x8, 26, 200, interactPromptPtr, 0000FFFFh
|
|
|
|
draw_controls_hud:
|
|
invoke DrawBox, 0, 226, SCREEN_W, 14, 00101010h
|
|
invoke DrawString8x8, 6, 229, OFFSET controlsHUD, 00A0A0A0h
|
|
ret
|
|
RenderHUD ENDP
|
|
|
|
RenderMinimap PROC uses ebx esi edi
|
|
local radarX:DWORD
|
|
local radarY:DWORD
|
|
local radarSize:DWORD
|
|
|
|
mov radarX, SCREEN_W - 48
|
|
mov radarY, 20
|
|
mov radarSize, 44
|
|
|
|
invoke DrawBoxBorder, radarX, radarY, radarSize, radarSize, 00101510h, 0000D7FFh, 1
|
|
|
|
; Draw Sprites on radar
|
|
xor esi, esi
|
|
radar_spr_loop:
|
|
cmp esi, NUM_SPRITES
|
|
jge draw_player_radar
|
|
mov eax, esi
|
|
imul eax, SIZEOF SpriteObject
|
|
mov eax, [casinoSprites + eax].posX
|
|
sar eax, 16
|
|
imul eax, radarSize
|
|
shr eax, 5
|
|
add eax, radarX
|
|
mov ebx, eax
|
|
|
|
mov eax, esi
|
|
imul eax, SIZEOF SpriteObject
|
|
mov eax, [casinoSprites + eax].posY
|
|
sar eax, 16
|
|
imul eax, radarSize
|
|
shr eax, 5
|
|
add eax, radarY
|
|
|
|
invoke DrawPixel, ebx, eax, 00FFAA00h
|
|
inc esi
|
|
jmp radar_spr_loop
|
|
|
|
draw_player_radar:
|
|
mov eax, playerX
|
|
sar eax, 16
|
|
imul eax, radarSize
|
|
shr eax, 5
|
|
add eax, radarX
|
|
mov ebx, eax
|
|
|
|
mov eax, playerY
|
|
sar eax, 16
|
|
imul eax, radarSize
|
|
shr eax, 5
|
|
add eax, radarY
|
|
|
|
invoke DrawCircle, ebx, eax, 2, 000000FFh
|
|
ret
|
|
RenderMinimap ENDP
|
|
''')
|
|
|
|
# SECTION 5: In-Engine 2.5D Mini-Games
|
|
a('''
|
|
; ==============================================================================
|
|
; IN-ENGINE 2.5D MINI-GAME: SLOTS 777
|
|
; ==============================================================================
|
|
HandleSlotsInput PROC
|
|
invoke GetAsyncKeyState, 1Bh ; ESC -> Exit to walking
|
|
test ah, 80h
|
|
jz @F
|
|
mov engineMode, MODE_WALK
|
|
ret
|
|
@@:
|
|
cmp slotSpinState, 1
|
|
je slots_input_done
|
|
|
|
invoke GetAsyncKeyState, 20h ; SPACE -> Spin
|
|
test ah, 80h
|
|
jz check_bet_adjust
|
|
mov eax, bankroll
|
|
cmp eax, slotBet
|
|
jl @F
|
|
sub eax, slotBet
|
|
mov bankroll, eax
|
|
mov slotSpinState, 1
|
|
mov slotSpinTimer, 0
|
|
mov slotWinAmount, 0
|
|
invoke PlaySoundA, OFFSET soundClick, 0, 1
|
|
jmp slots_input_done
|
|
@@:
|
|
invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage
|
|
mov flashTimer, 60
|
|
|
|
check_bet_adjust:
|
|
invoke GetAsyncKeyState, 26h ; UP / W
|
|
test ah, 80h
|
|
jnz inc_bet
|
|
invoke GetAsyncKeyState, 57h
|
|
test ah, 80h
|
|
jz check_bet_down
|
|
inc_bet:
|
|
cmp slotBet, 500
|
|
jge slots_input_done
|
|
cmp slotBet, 100
|
|
jge @F
|
|
cmp slotBet, 50
|
|
jge set_100
|
|
mov slotBet, 50
|
|
jmp slots_input_done
|
|
set_100:
|
|
mov slotBet, 100
|
|
jmp slots_input_done
|
|
@@:
|
|
mov slotBet, 500
|
|
jmp slots_input_done
|
|
|
|
check_bet_down:
|
|
invoke GetAsyncKeyState, 28h ; DOWN / S
|
|
test ah, 80h
|
|
jnz dec_bet
|
|
invoke GetAsyncKeyState, 53h
|
|
test ah, 80h
|
|
jz slots_input_done
|
|
dec_bet:
|
|
cmp slotBet, 50
|
|
jle set_10
|
|
cmp slotBet, 100
|
|
jle set_50
|
|
mov slotBet, 100
|
|
jmp slots_input_done
|
|
set_50:
|
|
mov slotBet, 50
|
|
jmp slots_input_done
|
|
set_10:
|
|
mov slotBet, 10
|
|
|
|
slots_input_done:
|
|
ret
|
|
HandleSlotsInput ENDP
|
|
|
|
RenderSlotsGame PROC uses ebx esi edi
|
|
; Cabinet Background (Dark Cherry Wood & Gold)
|
|
invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00150A10h
|
|
invoke DrawBoxBorder, 10, 10, 300, 220, 00251015h, 0000D7FFh, 3
|
|
|
|
; Illuminated Top Marquee
|
|
invoke DrawBoxBorder, 25, 20, 270, 32, 000A0505h, 0000FFFFh, 2
|
|
invoke DrawString8x8, 55, 32, OFFSET sz3DWindowTitle, 0000D7FFh
|
|
|
|
; Spinning Animation Logic
|
|
cmp slotSpinState, 1
|
|
jne draw_reels
|
|
inc slotSpinTimer
|
|
|
|
cmp slotSpinTimer, 22
|
|
jge @F
|
|
invoke RandomRange3D, 7
|
|
mov slotReel1, eax
|
|
@@:
|
|
cmp slotSpinTimer, 36
|
|
jge @F
|
|
invoke RandomRange3D, 7
|
|
mov slotReel2, eax
|
|
@@:
|
|
cmp slotSpinTimer, 50
|
|
jge @F
|
|
invoke RandomRange3D, 7
|
|
mov slotReel3, eax
|
|
@@:
|
|
cmp slotSpinTimer, 50
|
|
jl draw_reels
|
|
|
|
; Spin finished! Check outcome!
|
|
mov slotSpinState, 0
|
|
mov eax, slotReel1
|
|
cmp eax, slotReel2
|
|
jne check_pairs
|
|
cmp eax, slotReel3
|
|
jne check_pairs
|
|
|
|
; 3 Matching!
|
|
cmp eax, 0 ; 777!
|
|
jne @F
|
|
mov eax, slotBet
|
|
imul eax, 25
|
|
mov slotWinAmount, eax
|
|
add bankroll, eax
|
|
invoke PlaySoundA, OFFSET soundJackpot, 0, 1
|
|
jmp draw_reels
|
|
@@:
|
|
cmp eax, 6 ; CROWN!
|
|
jne @F
|
|
mov eax, slotBet
|
|
imul eax, 50
|
|
mov slotWinAmount, eax
|
|
add bankroll, eax
|
|
invoke PlaySoundA, OFFSET soundJackpot, 0, 1
|
|
jmp draw_reels
|
|
@@:
|
|
mov eax, slotBet
|
|
imul eax, 10
|
|
mov slotWinAmount, eax
|
|
add bankroll, eax
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
jmp draw_reels
|
|
|
|
check_pairs:
|
|
mov eax, slotReel1
|
|
cmp eax, slotReel2
|
|
je pair_win
|
|
mov eax, slotReel2
|
|
cmp eax, slotReel3
|
|
je pair_win
|
|
mov eax, slotReel1
|
|
cmp eax, slotReel3
|
|
je pair_win
|
|
jmp draw_reels
|
|
pair_win:
|
|
mov eax, slotBet
|
|
imul eax, 2
|
|
mov slotWinAmount, eax
|
|
add bankroll, eax
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
|
|
draw_reels:
|
|
; Reels Window
|
|
invoke DrawBoxBorder, 30, 62, 260, 95, 000F0F12h, 0000A5FFh, 2
|
|
|
|
; Reel 1 (45..105)
|
|
invoke DrawBoxBorder, 45, 68, 65, 82, 00F0F0F5h, 00505050h, 2
|
|
mov eax, slotReel1
|
|
call DrawReelSymbolAt1
|
|
|
|
; Reel 2 (128..188)
|
|
invoke DrawBoxBorder, 128, 68, 65, 82, 00F0F0F5h, 00505050h, 2
|
|
mov eax, slotReel2
|
|
call DrawReelSymbolAt2
|
|
|
|
; Reel 3 (210..270)
|
|
invoke DrawBoxBorder, 210, 68, 65, 82, 00F0F0F5h, 00505050h, 2
|
|
mov eax, slotReel3
|
|
call DrawReelSymbolAt3
|
|
|
|
; Bottom Control Panel
|
|
invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 0000D7FFh, 1
|
|
|
|
invoke DrawString8x8, 28, 172, OFFSET statusHUDFormat, 0000D7FFh
|
|
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
|
|
invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 0000FFFFh
|
|
|
|
invoke DrawString8x8, 175, 172, OFFSET targetHUDFormat, 0000D7FFh
|
|
invoke FormatNumber, slotBet, OFFSET hudNumBuffer
|
|
invoke DrawString8x8, 240, 172, OFFSET hudNumBuffer, 0050FF50h
|
|
|
|
cmp slotWinAmount, 0
|
|
jle draw_slot_ctrls
|
|
invoke DrawString8x8, 28, 187, OFFSET strWin, 0000FFFFh
|
|
invoke FormatNumber, slotWinAmount, OFFSET hudNumBuffer
|
|
invoke DrawString8x8, 110, 187, OFFSET hudNumBuffer, 0000FFFFh
|
|
|
|
draw_slot_ctrls:
|
|
invoke DrawString8x8, 28, 204, OFFSET promptDancer, 00A0A0A0h
|
|
ret
|
|
RenderSlotsGame ENDP
|
|
|
|
DrawReelSymbolAt1 PROC
|
|
cmp eax, 0
|
|
jne @F
|
|
invoke DrawString8x8, 52, 105, OFFSET sym7, 000000FFh
|
|
ret
|
|
@@:
|
|
cmp eax, 1
|
|
jne @F
|
|
invoke DrawString8x8, 52, 105, OFFSET symBar, 00FFAA00h
|
|
ret
|
|
@@:
|
|
cmp eax, 2
|
|
jne @F
|
|
invoke DrawString8x8, 52, 105, OFFSET symBell, 0000D7FFh
|
|
ret
|
|
@@:
|
|
cmp eax, 3
|
|
jne @F
|
|
invoke DrawString8x8, 48, 105, OFFSET symCherry, 000000D0h
|
|
ret
|
|
@@:
|
|
cmp eax, 4
|
|
jne @F
|
|
invoke DrawString8x8, 48, 105, OFFSET symClover, 0000A000h
|
|
ret
|
|
@@:
|
|
cmp eax, 5
|
|
jne @F
|
|
invoke DrawString8x8, 52, 105, OFFSET symGem, 00FFFF00h
|
|
ret
|
|
@@:
|
|
invoke DrawString8x8, 52, 105, OFFSET symCrown, 0000D7FFh
|
|
ret
|
|
DrawReelSymbolAt1 ENDP
|
|
|
|
DrawReelSymbolAt2 PROC
|
|
cmp eax, 0
|
|
jne @F
|
|
invoke DrawString8x8, 135, 105, OFFSET sym7, 000000FFh
|
|
ret
|
|
@@:
|
|
cmp eax, 1
|
|
jne @F
|
|
invoke DrawString8x8, 135, 105, OFFSET symBar, 00FFAA00h
|
|
ret
|
|
@@:
|
|
cmp eax, 2
|
|
jne @F
|
|
invoke DrawString8x8, 135, 105, OFFSET symBell, 0000D7FFh
|
|
ret
|
|
@@:
|
|
cmp eax, 3
|
|
jne @F
|
|
invoke DrawString8x8, 131, 105, OFFSET symCherry, 000000D0h
|
|
ret
|
|
@@:
|
|
cmp eax, 4
|
|
jne @F
|
|
invoke DrawString8x8, 131, 105, OFFSET symClover, 0000A000h
|
|
ret
|
|
@@:
|
|
cmp eax, 5
|
|
jne @F
|
|
invoke DrawString8x8, 135, 105, OFFSET symGem, 00FFFF00h
|
|
ret
|
|
@@:
|
|
invoke DrawString8x8, 135, 105, OFFSET symCrown, 0000D7FFh
|
|
ret
|
|
DrawReelSymbolAt2 ENDP
|
|
|
|
DrawReelSymbolAt3 PROC
|
|
cmp eax, 0
|
|
jne @F
|
|
invoke DrawString8x8, 218, 105, OFFSET sym7, 000000FFh
|
|
ret
|
|
@@:
|
|
cmp eax, 1
|
|
jne @F
|
|
invoke DrawString8x8, 218, 105, OFFSET symBar, 00FFAA00h
|
|
ret
|
|
@@:
|
|
cmp eax, 2
|
|
jne @F
|
|
invoke DrawString8x8, 218, 105, OFFSET symBell, 0000D7FFh
|
|
ret
|
|
@@:
|
|
cmp eax, 3
|
|
jne @F
|
|
invoke DrawString8x8, 214, 105, OFFSET symCherry, 000000D0h
|
|
ret
|
|
@@:
|
|
cmp eax, 4
|
|
jne @F
|
|
invoke DrawString8x8, 214, 105, OFFSET symClover, 0000A000h
|
|
ret
|
|
@@:
|
|
cmp eax, 5
|
|
jne @F
|
|
invoke DrawString8x8, 218, 105, OFFSET symGem, 00FFFF00h
|
|
ret
|
|
@@:
|
|
invoke DrawString8x8, 218, 105, OFFSET symCrown, 0000D7FFh
|
|
ret
|
|
DrawReelSymbolAt3 ENDP
|
|
|
|
; ==============================================================================
|
|
; IN-ENGINE 2.5D MINI-GAME: BLACKJACK (21)
|
|
; ==============================================================================
|
|
HandleBlackjackInput PROC
|
|
invoke GetAsyncKeyState, 1Bh ; ESC -> Exit
|
|
test ah, 80h
|
|
jz @F
|
|
mov engineMode, MODE_WALK
|
|
ret
|
|
@@:
|
|
cmp bjState, 0 ; Need Deal
|
|
jne check_bj_player_turn
|
|
invoke GetAsyncKeyState, 20h ; SPACE -> Deal
|
|
test ah, 80h
|
|
jz check_bj_bet_change
|
|
mov eax, bankroll
|
|
cmp eax, bjBet
|
|
jl bj_need_cash
|
|
sub eax, bjBet
|
|
mov bankroll, eax
|
|
|
|
; Deal 2 cards to player, 2 cards to dealer
|
|
mov bjPlayerCardCount, 0
|
|
mov bjDealerCardCount, 0
|
|
mov bjDealerHideHole, 1
|
|
|
|
; Player Card 1
|
|
invoke RandomRange3D, 13
|
|
inc eax
|
|
mov ebx, bjPlayerCardCount
|
|
mov [bjPlayerCards + ebx*4], eax
|
|
inc bjPlayerCardCount
|
|
|
|
; Dealer Card 1
|
|
invoke RandomRange3D, 13
|
|
inc eax
|
|
mov ebx, bjDealerCardCount
|
|
mov [bjDealerCards + ebx*4], eax
|
|
inc bjDealerCardCount
|
|
|
|
; Player Card 2
|
|
invoke RandomRange3D, 13
|
|
inc eax
|
|
mov ebx, bjPlayerCardCount
|
|
mov [bjPlayerCards + ebx*4], eax
|
|
inc bjPlayerCardCount
|
|
|
|
; Dealer Card 2 (Hole card)
|
|
invoke RandomRange3D, 13
|
|
inc eax
|
|
mov ebx, bjDealerCardCount
|
|
mov [bjDealerCards + ebx*4], eax
|
|
inc bjDealerCardCount
|
|
|
|
invoke PlaySoundA, OFFSET soundCards, 0, 1
|
|
|
|
; Calc Player Score
|
|
call CalcPlayerBJScore
|
|
cmp bjPlayerScore, 21
|
|
jne set_bj_turn
|
|
; Instant Blackjack!
|
|
mov bjDealerHideHole, 0
|
|
mov eax, bjBet
|
|
imul eax, 5
|
|
shr eax, 1
|
|
add bankroll, eax
|
|
invoke CopyString3D, OFFSET strWin, OFFSET bjOutcomeMsg
|
|
invoke PlaySoundA, OFFSET soundJackpot, 0, 1
|
|
mov bjState, 2
|
|
ret
|
|
set_bj_turn:
|
|
mov bjState, 1
|
|
mov BYTE PTR [bjOutcomeMsg], 0
|
|
ret
|
|
|
|
bj_need_cash:
|
|
invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage
|
|
mov flashTimer, 60
|
|
ret
|
|
|
|
check_bj_player_turn:
|
|
cmp bjState, 1
|
|
jne check_bj_round_over
|
|
|
|
invoke GetAsyncKeyState, 48h ; 'H' -> Hit
|
|
test ah, 80h
|
|
jz check_bj_stand
|
|
invoke RandomRange3D, 13
|
|
inc eax
|
|
mov ebx, bjPlayerCardCount
|
|
cmp ebx, 8
|
|
jge @F
|
|
mov [bjPlayerCards + ebx*4], eax
|
|
inc bjPlayerCardCount
|
|
@@:
|
|
invoke PlaySoundA, OFFSET soundCards, 0, 1
|
|
call CalcPlayerBJScore
|
|
cmp bjPlayerScore, 21
|
|
jle bj_input_done
|
|
; Bust!
|
|
invoke CopyString3D, OFFSET strPlayerBust, OFFSET bjOutcomeMsg
|
|
mov bjDealerHideHole, 0
|
|
mov bjState, 2
|
|
ret
|
|
|
|
check_bj_stand:
|
|
invoke GetAsyncKeyState, 53h ; 'S' -> Stand
|
|
test ah, 80h
|
|
jz bj_input_done
|
|
|
|
; Dealer Turn
|
|
mov bjDealerHideHole, 0
|
|
dealer_loop:
|
|
call CalcDealerBJScore
|
|
cmp bjDealerScore, 17
|
|
jge dealer_finished
|
|
invoke RandomRange3D, 13
|
|
inc eax
|
|
mov ebx, bjDealerCardCount
|
|
cmp ebx, 8
|
|
jge dealer_finished
|
|
mov [bjDealerCards + ebx*4], eax
|
|
inc bjDealerCardCount
|
|
jmp dealer_loop
|
|
|
|
dealer_finished:
|
|
cmp bjDealerScore, 21
|
|
jle compare_scores
|
|
; Dealer Bust!
|
|
mov eax, bjBet
|
|
shl eax, 1
|
|
add bankroll, eax
|
|
invoke CopyString3D, OFFSET strDealerBust, OFFSET bjOutcomeMsg
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
mov bjState, 2
|
|
ret
|
|
|
|
compare_scores:
|
|
mov eax, bjPlayerScore
|
|
cmp eax, bjDealerScore
|
|
jle check_dealer_won
|
|
; Player Won!
|
|
mov eax, bjBet
|
|
shl eax, 1
|
|
add bankroll, eax
|
|
invoke CopyString3D, OFFSET strWin, OFFSET bjOutcomeMsg
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
mov bjState, 2
|
|
ret
|
|
check_dealer_won:
|
|
cmp eax, bjDealerScore
|
|
jl dealer_wins
|
|
; Push (Tie)
|
|
mov eax, bjBet
|
|
add bankroll, eax
|
|
invoke CopyString3D, OFFSET strPush, OFFSET bjOutcomeMsg
|
|
mov bjState, 2
|
|
ret
|
|
dealer_wins:
|
|
invoke CopyString3D, OFFSET strLose, OFFSET bjOutcomeMsg
|
|
mov bjState, 2
|
|
ret
|
|
|
|
check_bj_round_over:
|
|
invoke GetAsyncKeyState, 20h ; SPACE -> Next Hand
|
|
test ah, 80h
|
|
jz bj_input_done
|
|
mov bjState, 0
|
|
ret
|
|
|
|
check_bj_bet_change:
|
|
invoke GetAsyncKeyState, 26h ; UP
|
|
test ah, 80h
|
|
jz @F
|
|
cmp bjBet, 500
|
|
jge bj_input_done
|
|
add bjBet, 50
|
|
ret
|
|
@@:
|
|
invoke GetAsyncKeyState, 28h ; DOWN
|
|
test ah, 80h
|
|
jz bj_input_done
|
|
cmp bjBet, 50
|
|
jle bj_input_done
|
|
sub bjBet, 50
|
|
|
|
bj_input_done:
|
|
ret
|
|
HandleBlackjackInput ENDP
|
|
|
|
CalcPlayerBJScore PROC uses ebx esi
|
|
xor eax, eax
|
|
xor ebx, ebx
|
|
xor esi, esi
|
|
calc_p_loop:
|
|
cmp esi, bjPlayerCardCount
|
|
jge calc_p_done
|
|
mov edx, [bjPlayerCards + esi*4]
|
|
cmp edx, 10
|
|
jle @F
|
|
mov edx, 10
|
|
@@:
|
|
cmp edx, 1
|
|
jne add_p_val
|
|
inc ebx ; count Aces
|
|
add eax, 11
|
|
jmp next_p_card
|
|
add_p_val:
|
|
add eax, edx
|
|
next_p_card:
|
|
inc esi
|
|
jmp calc_p_loop
|
|
calc_p_done:
|
|
; Soft Ace reduction
|
|
reduce_p_ace:
|
|
cmp eax, 21
|
|
jle store_p_score
|
|
test ebx, ebx
|
|
jz store_p_score
|
|
sub eax, 10
|
|
dec ebx
|
|
jmp reduce_p_ace
|
|
store_p_score:
|
|
mov bjPlayerScore, eax
|
|
ret
|
|
CalcPlayerBJScore ENDP
|
|
|
|
CalcDealerBJScore PROC uses ebx esi
|
|
xor eax, eax
|
|
xor ebx, ebx
|
|
xor esi, esi
|
|
calc_d_loop:
|
|
cmp esi, bjDealerCardCount
|
|
jge calc_d_done
|
|
mov edx, [bjDealerCards + esi*4]
|
|
cmp edx, 10
|
|
jle @F
|
|
mov edx, 10
|
|
@@:
|
|
cmp edx, 1
|
|
jne add_d_val
|
|
inc ebx
|
|
add eax, 11
|
|
jmp next_d_card
|
|
add_d_val:
|
|
add eax, edx
|
|
next_d_card:
|
|
inc esi
|
|
jmp calc_d_loop
|
|
calc_d_done:
|
|
reduce_d_ace:
|
|
cmp eax, 21
|
|
jle store_d_score
|
|
test ebx, ebx
|
|
jz store_d_score
|
|
sub eax, 10
|
|
dec ebx
|
|
jmp reduce_d_ace
|
|
store_d_score:
|
|
mov bjDealerScore, eax
|
|
ret
|
|
CalcDealerBJScore ENDP
|
|
|
|
RenderBlackjackGame PROC uses ebx esi edi
|
|
; Emerald Felt Table Background
|
|
invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 000A3015h
|
|
invoke DrawBoxBorder, 10, 10, 300, 220, 000D4018h, 0000D7FFh, 3
|
|
|
|
; Dealer Area Top
|
|
invoke DrawString8x8, 25, 20, OFFSET promptBlackjack, 0000D7FFh
|
|
invoke DrawString8x8, 25, 35, OFFSET statusHUDFormat, 00FFFFFFh
|
|
invoke FormatNumber, bjDealerScore, OFFSET hudNumBuffer
|
|
invoke DrawString8x8, 120, 35, OFFSET hudNumBuffer, 0000FFFFh
|
|
|
|
; Dealer Cards
|
|
xor esi, esi
|
|
draw_dealer_cards:
|
|
cmp esi, bjDealerCardCount
|
|
jge draw_player_bj_area
|
|
mov eax, esi
|
|
imul eax, 45
|
|
add eax, 25
|
|
mov ebx, eax
|
|
|
|
cmp esi, 1
|
|
jne draw_dealer_face
|
|
cmp bjDealerHideHole, 1
|
|
jne draw_dealer_face
|
|
; Face Down Card
|
|
invoke DrawBoxBorder, ebx, 48, 38, 52, 002020B0h, 00FFFFFFh, 2
|
|
jmp next_dealer_card_draw
|
|
|
|
draw_dealer_face:
|
|
invoke DrawBoxBorder, ebx, 48, 38, 52, 00F0F0F5h, 00000000h, 2
|
|
mov eax, [bjDealerCards + esi*4]
|
|
dec eax
|
|
imul eax, 3
|
|
lea edx, [cardRankStr + eax]
|
|
mov eax, ebx
|
|
add eax, 8
|
|
invoke DrawString8x8, eax, 68, edx, 00000000h
|
|
|
|
next_dealer_card_draw:
|
|
inc esi
|
|
jmp draw_dealer_cards
|
|
|
|
draw_player_bj_area:
|
|
; Player Area Bottom
|
|
invoke DrawString8x8, 25, 110, OFFSET targetHUDFormat, 00FFFFFFh
|
|
invoke FormatNumber, bjPlayerScore, OFFSET hudNumBuffer
|
|
invoke DrawString8x8, 120, 110, OFFSET hudNumBuffer, 0050FF50h
|
|
|
|
; Player Cards
|
|
xor esi, esi
|
|
draw_player_cards:
|
|
cmp esi, bjPlayerCardCount
|
|
jge draw_bj_footer
|
|
mov eax, esi
|
|
imul eax, 45
|
|
add eax, 25
|
|
mov ebx, eax
|
|
|
|
invoke DrawBoxBorder, ebx, 124, 38, 52, 00F0F0F5h, 00000000h, 2
|
|
mov eax, [bjPlayerCards + esi*4]
|
|
dec eax
|
|
imul eax, 3
|
|
lea edx, [cardRankStr + eax]
|
|
mov eax, ebx
|
|
add eax, 8
|
|
invoke DrawString8x8, eax, 144, edx, 00000000h
|
|
|
|
inc esi
|
|
jmp draw_player_cards
|
|
|
|
draw_bj_footer:
|
|
; Footer Status & Controls
|
|
invoke DrawBoxBorder, 20, 182, 280, 42, 00102010h, 0000D7FFh, 1
|
|
cmp BYTE PTR [bjOutcomeMsg], 0
|
|
je draw_bj_controls
|
|
invoke DrawString8x8, 28, 188, OFFSET bjOutcomeMsg, 0000FFFFh
|
|
invoke DrawString8x8, 28, 204, OFFSET promptSlot1, 00A0A0A0h
|
|
ret
|
|
|
|
draw_bj_controls:
|
|
invoke DrawString8x8, 28, 188, OFFSET promptDancer, 00FFFFFFh
|
|
invoke DrawString8x8, 28, 204, OFFSET promptSlot2, 00A0A0A0h
|
|
ret
|
|
RenderBlackjackGame ENDP
|
|
|
|
; ==============================================================================
|
|
; IN-ENGINE 2.5D MINI-GAME: ROULETTE
|
|
; ==============================================================================
|
|
HandleRouletteInput PROC
|
|
invoke GetAsyncKeyState, 1Bh ; ESC
|
|
test ah, 80h
|
|
jz @F
|
|
mov engineMode, MODE_WALK
|
|
ret
|
|
@@:
|
|
cmp roulState, 1
|
|
je roul_input_done
|
|
|
|
invoke GetAsyncKeyState, 31h ; '1' -> RED
|
|
test ah, 80h
|
|
jz @F
|
|
mov roulBetType, 1
|
|
@@:
|
|
invoke GetAsyncKeyState, 32h ; '2' -> BLACK
|
|
test ah, 80h
|
|
jz @F
|
|
mov roulBetType, 2
|
|
@@:
|
|
invoke GetAsyncKeyState, 33h ; '3' -> ZERO (0)
|
|
test ah, 80h
|
|
jz @F
|
|
mov roulBetType, 3
|
|
@@:
|
|
invoke GetAsyncKeyState, 34h ; '4' -> EVEN
|
|
test ah, 80h
|
|
jz @F
|
|
mov roulBetType, 4
|
|
@@:
|
|
invoke GetAsyncKeyState, 35h ; '5' -> ODD
|
|
test ah, 80h
|
|
jz check_roul_spin
|
|
mov roulBetType, 5
|
|
|
|
check_roul_spin:
|
|
invoke GetAsyncKeyState, 20h ; SPACE -> Spin
|
|
test ah, 80h
|
|
jz roul_input_done
|
|
mov eax, bankroll
|
|
cmp eax, roulBetAmount
|
|
jl roul_no_cash
|
|
sub eax, roulBetAmount
|
|
mov bankroll, eax
|
|
mov roulState, 1
|
|
mov roulSpinTimer, 50
|
|
mov roulPayout, 0
|
|
invoke PlaySoundA, OFFSET soundRoulette, 0, 1
|
|
ret
|
|
|
|
roul_no_cash:
|
|
invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage
|
|
mov flashTimer, 60
|
|
|
|
roul_input_done:
|
|
ret
|
|
HandleRouletteInput ENDP
|
|
|
|
RenderRouletteGame PROC uses ebx esi edi
|
|
; Table felt background
|
|
invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00151525h
|
|
invoke DrawBoxBorder, 10, 10, 300, 220, 00201525h, 0000D7FFh, 3
|
|
|
|
; 2.5D Rotating Wheel on Left
|
|
invoke DrawCircle, 85, 110, 65, 00102550h
|
|
invoke DrawCircle, 85, 110, 60, 0000D7FFh
|
|
invoke DrawCircle, 85, 110, 52, 00101010h
|
|
invoke DrawCircle, 85, 110, 22, 0000D7FFh ; Center brass turret
|
|
|
|
; Spinning Wheel / Ball Logic
|
|
cmp roulState, 1
|
|
jne draw_roul_ball
|
|
dec roulSpinTimer
|
|
add roulWheelAngle, 8
|
|
sub roulBallAngle, 14
|
|
cmp roulSpinTimer, 0
|
|
jg draw_roul_ball
|
|
|
|
; Wheel stopped! Determine result!
|
|
mov roulState, 2
|
|
invoke RandomRange3D, 37
|
|
mov roulWinningNum, eax
|
|
|
|
; Check bet
|
|
cmp roulBetType, 1 ; RED
|
|
jne check_ro_black
|
|
call IsNumberRed
|
|
test eax, eax
|
|
jz ro_lost
|
|
mov eax, roulBetAmount
|
|
shl eax, 1
|
|
mov roulPayout, eax
|
|
add bankroll, eax
|
|
invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
jmp draw_roul_ball
|
|
|
|
check_ro_black:
|
|
cmp roulBetType, 2 ; BLACK
|
|
jne check_ro_zero
|
|
cmp roulWinningNum, 0
|
|
je ro_lost
|
|
call IsNumberRed
|
|
test eax, eax
|
|
jnz ro_lost
|
|
mov eax, roulBetAmount
|
|
shl eax, 1
|
|
mov roulPayout, eax
|
|
add bankroll, eax
|
|
invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
jmp draw_roul_ball
|
|
|
|
check_ro_zero:
|
|
cmp roulBetType, 3 ; ZERO
|
|
jne check_ro_even
|
|
cmp roulWinningNum, 0
|
|
jne ro_lost
|
|
mov eax, roulBetAmount
|
|
imul eax, 36
|
|
mov roulPayout, eax
|
|
add bankroll, eax
|
|
invoke CopyString3D, OFFSET strJackpot, OFFSET roulOutcomeMsg
|
|
invoke PlaySoundA, OFFSET soundJackpot, 0, 1
|
|
jmp draw_roul_ball
|
|
|
|
check_ro_even:
|
|
cmp roulBetType, 4 ; EVEN
|
|
jne check_ro_odd
|
|
mov eax, roulWinningNum
|
|
test eax, eax
|
|
jz ro_lost
|
|
test al, 1
|
|
jnz ro_lost
|
|
mov eax, roulBetAmount
|
|
shl eax, 1
|
|
mov roulPayout, eax
|
|
add bankroll, eax
|
|
invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
jmp draw_roul_ball
|
|
|
|
check_ro_odd:
|
|
mov eax, roulWinningNum
|
|
test eax, eax
|
|
jz ro_lost
|
|
test al, 1
|
|
jz ro_lost
|
|
mov eax, roulBetAmount
|
|
shl eax, 1
|
|
mov roulPayout, eax
|
|
add bankroll, eax
|
|
invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
jmp draw_roul_ball
|
|
|
|
ro_lost:
|
|
invoke CopyString3D, OFFSET strLose, OFFSET roulOutcomeMsg
|
|
|
|
draw_roul_ball:
|
|
; Draw White Ball on Rim
|
|
mov eax, roulBallAngle
|
|
and eax, 511
|
|
mov ebx, [tableCos + eax*4]
|
|
imul ebx, 42
|
|
sar ebx, 16
|
|
add ebx, 85
|
|
|
|
mov eax, roulBallAngle
|
|
and eax, 511
|
|
mov edx, [tableSin + eax*4]
|
|
imul edx, 42
|
|
sar edx, 16
|
|
add edx, 110
|
|
invoke DrawCircle, ebx, edx, 3, 00FFFFFFh
|
|
|
|
; Right Betting Board
|
|
invoke DrawBoxBorder, 175, 25, 125, 28, 001010C0h, 00FFFFFFh, 2 ; [1] RED
|
|
invoke DrawString8x8, 190, 35, OFFSET promptSlot1, 00FFFFFFh
|
|
|
|
invoke DrawBoxBorder, 175, 60, 125, 28, 00151515h, 00FFFFFFh, 2 ; [2] BLACK
|
|
invoke DrawString8x8, 190, 70, OFFSET promptSlot2, 00FFFFFFh
|
|
|
|
invoke DrawBoxBorder, 175, 95, 125, 28, 00106010h, 00FFFFFFh, 2 ; [3] ZERO
|
|
invoke DrawString8x8, 190, 105, OFFSET promptPoker, 00FFFFFFh
|
|
|
|
invoke DrawBoxBorder, 175, 130, 60, 26, 00302020h, 00FFFFFFh, 1 ; [4] EVEN
|
|
invoke DrawString8x8, 185, 139, OFFSET symBar, 00FFFFFFh
|
|
|
|
invoke DrawBoxBorder, 240, 130, 60, 26, 00302020h, 00FFFFFFh, 1 ; [5] ODD
|
|
invoke DrawString8x8, 250, 139, OFFSET symBell, 00FFFFFFh
|
|
|
|
; Highlight Active Bet
|
|
cmp roulBetType, 1
|
|
jne @F
|
|
invoke DrawBoxBorder, 173, 23, 129, 32, 0, 0000FFFFh, 2
|
|
@@:
|
|
cmp roulBetType, 2
|
|
jne @F
|
|
invoke DrawBoxBorder, 173, 58, 129, 32, 0, 0000FFFFh, 2
|
|
@@:
|
|
cmp roulBetType, 3
|
|
jne @F
|
|
invoke DrawBoxBorder, 173, 93, 129, 32, 0, 0000FFFFh, 2
|
|
@@:
|
|
cmp roulBetType, 4
|
|
jne @F
|
|
invoke DrawBoxBorder, 173, 128, 64, 30, 0, 0000FFFFh, 2
|
|
@@:
|
|
cmp roulBetType, 5
|
|
jne draw_ro_footer
|
|
invoke DrawBoxBorder, 238, 128, 64, 30, 0, 0000FFFFh, 2
|
|
|
|
draw_ro_footer:
|
|
invoke DrawBoxBorder, 20, 180, 280, 42, 00101015h, 0000D7FFh, 1
|
|
|
|
cmp roulState, 2
|
|
jne @F
|
|
invoke DrawString8x8, 28, 186, OFFSET targetHUDFormat, 0000D7FFh
|
|
invoke FormatNumber, roulWinningNum, OFFSET hudNumBuffer
|
|
invoke DrawString8x8, 85, 186, OFFSET hudNumBuffer, 0000FFFFh
|
|
invoke DrawString8x8, 130, 186, OFFSET roulOutcomeMsg, 0050FF50h
|
|
@@:
|
|
invoke DrawString8x8, 28, 202, OFFSET controlsHUD, 00A0A0A0h
|
|
ret
|
|
RenderRouletteGame ENDP
|
|
|
|
IsNumberRed PROC
|
|
mov eax, roulWinningNum
|
|
cmp eax, 1
|
|
je red_yes
|
|
cmp eax, 3
|
|
je red_yes
|
|
cmp eax, 5
|
|
je red_yes
|
|
cmp eax, 7
|
|
je red_yes
|
|
cmp eax, 9
|
|
je red_yes
|
|
cmp eax, 12
|
|
je red_yes
|
|
cmp eax, 14
|
|
je red_yes
|
|
cmp eax, 16
|
|
je red_yes
|
|
cmp eax, 18
|
|
je red_yes
|
|
cmp eax, 19
|
|
je red_yes
|
|
cmp eax, 21
|
|
je red_yes
|
|
cmp eax, 23
|
|
je red_yes
|
|
cmp eax, 25
|
|
je red_yes
|
|
cmp eax, 27
|
|
je red_yes
|
|
cmp eax, 30
|
|
je red_yes
|
|
cmp eax, 32
|
|
je red_yes
|
|
cmp eax, 34
|
|
je red_yes
|
|
cmp eax, 36
|
|
je red_yes
|
|
xor eax, eax
|
|
ret
|
|
red_yes:
|
|
mov eax, 1
|
|
ret
|
|
IsNumberRed ENDP
|
|
|
|
; ==============================================================================
|
|
; IN-ENGINE 2.5D MINI-GAME: BAR & SHOP
|
|
; ==============================================================================
|
|
HandleShopInput PROC
|
|
invoke GetAsyncKeyState, 1Bh ; ESC
|
|
test ah, 80h
|
|
jz @F
|
|
mov engineMode, MODE_WALK
|
|
ret
|
|
@@:
|
|
invoke GetAsyncKeyState, 31h ; '1' -> Lucky Cocktail ($150)
|
|
test ah, 80h
|
|
jz @F
|
|
cmp bankroll, 150
|
|
jl shop_no_money
|
|
sub bankroll, 150
|
|
add dancerLuckBuff, 5
|
|
invoke CopyString3D, OFFSET msgDancerTipped, OFFSET shopMsg
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
ret
|
|
@@:
|
|
invoke GetAsyncKeyState, 32h ; '2' -> Gold Card ($1000)
|
|
test ah, 80h
|
|
jz @F
|
|
cmp bankroll, 1000
|
|
jl shop_no_money
|
|
sub bankroll, 1000
|
|
invoke CopyString3D, OFFSET strWin, OFFSET shopMsg
|
|
invoke PlaySoundA, OFFSET soundJackpot, 0, 1
|
|
ret
|
|
@@:
|
|
invoke GetAsyncKeyState, 33h ; '3' -> Cigar ($250)
|
|
test ah, 80h
|
|
jz shop_done
|
|
cmp bankroll, 250
|
|
jl shop_no_money
|
|
sub bankroll, 250
|
|
add dancerLuckBuff, 2
|
|
invoke CopyString3D, OFFSET msgDancerTipped, OFFSET shopMsg
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
ret
|
|
|
|
shop_no_money:
|
|
invoke CopyString3D, OFFSET msgNeedMoney, OFFSET shopMsg
|
|
|
|
shop_done:
|
|
ret
|
|
HandleShopInput ENDP
|
|
|
|
RenderShopGame PROC
|
|
invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00150A0Ah
|
|
invoke DrawBoxBorder, 10, 10, 300, 220, 00251515h, 0000D7FFh, 3
|
|
invoke DrawString8x8, 25, 20, OFFSET promptShop, 0000D7FFh
|
|
|
|
invoke DrawBoxBorder, 20, 40, 280, 32, 001A1010h, 00FFFFFFh, 1
|
|
invoke DrawString8x8, 28, 46, OFFSET promptSlot1, 0000FFFFh
|
|
invoke DrawString8x8, 28, 58, OFFSET symBar, 00A0A0A0h
|
|
|
|
invoke DrawBoxBorder, 20, 80, 280, 32, 001A1010h, 00FFFFFFh, 1
|
|
invoke DrawString8x8, 28, 86, OFFSET promptSlot2, 0000FFFFh
|
|
invoke DrawString8x8, 28, 98, OFFSET symBell, 00A0A0A0h
|
|
|
|
invoke DrawBoxBorder, 20, 120, 280, 32, 001A1010h, 00FFFFFFh, 1
|
|
invoke DrawString8x8, 28, 126, OFFSET promptBlackjack, 0000FFFFh
|
|
invoke DrawString8x8, 28, 138, OFFSET symCherry, 00A0A0A0h
|
|
|
|
invoke DrawBoxBorder, 20, 165, 280, 55, 00100A0Ah, 0000D7FFh, 1
|
|
invoke DrawString8x8, 28, 172, OFFSET statusHUDFormat, 0000D7FFh
|
|
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
|
|
invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 0000FFFFh
|
|
|
|
cmp BYTE PTR [shopMsg], 0
|
|
je @F
|
|
invoke DrawString8x8, 28, 188, OFFSET shopMsg, 0050FF50h
|
|
@@:
|
|
invoke DrawString8x8, 28, 204, OFFSET controlsHUD, 00A0A0A0h
|
|
ret
|
|
RenderShopGame ENDP
|
|
|
|
; ==============================================================================
|
|
; IN-ENGINE 2.5D MINI-GAME: ATM TERMINAL
|
|
; ==============================================================================
|
|
HandleATMInput PROC
|
|
invoke GetAsyncKeyState, 1Bh ; ESC
|
|
test ah, 80h
|
|
jz @F
|
|
mov engineMode, MODE_WALK
|
|
ret
|
|
@@:
|
|
invoke GetAsyncKeyState, 31h ; '1' -> Loan $1000
|
|
test ah, 80h
|
|
jz @F
|
|
add bankroll, 1000
|
|
invoke CopyString3D, OFFSET strWin, OFFSET atmMsg
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
ret
|
|
@@:
|
|
invoke GetAsyncKeyState, 32h ; '2' -> Daily Bonus $250
|
|
test ah, 80h
|
|
jz atm_done
|
|
add bankroll, 250
|
|
invoke CopyString3D, OFFSET strWin, OFFSET atmMsg
|
|
invoke PlaySoundA, OFFSET soundCoin, 0, 1
|
|
|
|
atm_done:
|
|
ret
|
|
HandleATMInput ENDP
|
|
|
|
RenderATMGame PROC
|
|
; Retro Green CRT Screen
|
|
invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00051505h
|
|
invoke DrawBoxBorder, 10, 10, 300, 220, 000A250Ah, 0000FF00h, 2
|
|
|
|
invoke DrawString8x8, 25, 25, OFFSET promptATM, 0000FF00h
|
|
|
|
invoke DrawBoxBorder, 20, 50, 280, 35, 00051805h, 0000A000h, 1
|
|
invoke DrawString8x8, 28, 58, OFFSET promptSlot1, 0050FF50h
|
|
invoke DrawString8x8, 28, 70, OFFSET symBar, 0000A000h
|
|
|
|
invoke DrawBoxBorder, 20, 95, 280, 35, 00051805h, 0000A000h, 1
|
|
invoke DrawString8x8, 28, 103, OFFSET promptSlot2, 0050FF50h
|
|
invoke DrawString8x8, 28, 115, OFFSET symBell, 0000A000h
|
|
|
|
invoke DrawBoxBorder, 20, 145, 280, 75, 00051805h, 0000FF00h, 1
|
|
invoke DrawString8x8, 28, 155, OFFSET statusHUDFormat, 0000FF00h
|
|
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
|
|
invoke DrawString8x8, 110, 155, OFFSET hudNumBuffer, 00FFFFFFh
|
|
|
|
cmp BYTE PTR [atmMsg], 0
|
|
je @F
|
|
invoke DrawString8x8, 28, 175, OFFSET atmMsg, 0000FFFFh
|
|
@@:
|
|
invoke DrawString8x8, 28, 195, OFFSET controlsHUD, 0000A000h
|
|
ret
|
|
RenderATMGame ENDP
|
|
''')
|
|
|
|
# SECTION 6: Player Input, Engine Init, and Main Loop
|
|
a('''
|
|
; --- 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, 3600
|
|
mov turnSpd, 8
|
|
|
|
invoke GetAsyncKeyState, 10h ; Shift -> Run
|
|
test ah, 80h
|
|
jz @F
|
|
mov walkSpd, 6200
|
|
@@:
|
|
|
|
invoke GetAsyncKeyState, 41h ; A / Left
|
|
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 ; D / Right
|
|
test ah, 80h
|
|
jnz turn_right
|
|
invoke GetAsyncKeyState, 27h
|
|
test ah, 80h
|
|
jz check_forward
|
|
turn_right:
|
|
mov eax, playerAngle
|
|
add eax, turnSpd
|
|
and eax, 511
|
|
mov playerAngle, eax
|
|
|
|
check_forward:
|
|
invoke GetAsyncKeyState, 57h ; W / Up
|
|
test ah, 80h
|
|
jnz walk_fwd
|
|
invoke GetAsyncKeyState, 26h
|
|
test ah, 80h
|
|
jz check_backward
|
|
walk_fwd:
|
|
mov eax, playerAngle
|
|
and eax, 511
|
|
mov ebx, [tableCos + eax*4]
|
|
imul ebx, walkSpd
|
|
shrd ebx, edx, 16
|
|
mov moveDirX, ebx
|
|
|
|
mov ebx, [tableSin + eax*4]
|
|
imul ebx, walkSpd
|
|
shrd ebx, edx, 16
|
|
mov moveDirY, ebx
|
|
|
|
mov eax, playerX
|
|
add eax, moveDirX
|
|
mov newX, eax
|
|
mov eax, playerY
|
|
add eax, moveDirY
|
|
mov newY, eax
|
|
|
|
; Collision X
|
|
mov eax, newX
|
|
sar eax, 16
|
|
mov checkTileX, eax
|
|
mov eax, playerY
|
|
sar eax, 16
|
|
shl eax, 5
|
|
add eax, checkTileX
|
|
movzx eax, BYTE PTR [casinoMap + eax]
|
|
test eax, eax
|
|
jnz @F
|
|
mov eax, newX
|
|
mov playerX, eax
|
|
@@:
|
|
; Collision Y
|
|
mov eax, newY
|
|
sar eax, 16
|
|
shl eax, 5
|
|
mov ebx, playerX
|
|
sar ebx, 16
|
|
add eax, ebx
|
|
movzx eax, BYTE PTR [casinoMap + eax]
|
|
test eax, eax
|
|
jnz check_interact
|
|
mov eax, newY
|
|
mov playerY, eax
|
|
jmp check_interact
|
|
|
|
check_backward:
|
|
invoke GetAsyncKeyState, 53h ; S / Down
|
|
test ah, 80h
|
|
jnz walk_back
|
|
invoke GetAsyncKeyState, 28h
|
|
test ah, 80h
|
|
jz check_interact
|
|
walk_back:
|
|
mov eax, playerAngle
|
|
and eax, 511
|
|
mov ebx, [tableCos + eax*4]
|
|
imul ebx, walkSpd
|
|
shrd ebx, edx, 16
|
|
neg ebx
|
|
mov moveDirX, ebx
|
|
|
|
mov ebx, [tableSin + eax*4]
|
|
imul ebx, walkSpd
|
|
shrd ebx, edx, 16
|
|
neg ebx
|
|
mov moveDirY, ebx
|
|
|
|
mov eax, playerX
|
|
add eax, moveDirX
|
|
mov newX, eax
|
|
mov eax, playerY
|
|
add eax, moveDirY
|
|
mov newY, eax
|
|
|
|
mov eax, newX
|
|
sar eax, 16
|
|
mov checkTileX, eax
|
|
mov eax, playerY
|
|
sar eax, 16
|
|
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, newY
|
|
sar eax, 16
|
|
shl eax, 5
|
|
mov ebx, playerX
|
|
sar ebx, 16
|
|
add eax, ebx
|
|
movzx eax, BYTE PTR [casinoMap + eax]
|
|
test eax, eax
|
|
jnz check_interact
|
|
mov eax, newY
|
|
mov playerY, eax
|
|
|
|
check_interact:
|
|
invoke GetAsyncKeyState, 45h ; 'E'
|
|
test ah, 80h
|
|
jz input_done
|
|
call Trigger3DInteraction
|
|
invoke Sleep, 120
|
|
|
|
input_done:
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
ret
|
|
HandlePlayerInput ENDP
|
|
|
|
CheckInteractions PROC uses ebx esi edi
|
|
mov interactTargetId, 0
|
|
mov interactPromptPtr, 0
|
|
|
|
xor esi, esi
|
|
check_spr_prox:
|
|
cmp esi, NUM_SPRITES
|
|
jge prox_done
|
|
mov eax, esi
|
|
imul eax, SIZEOF SpriteObject
|
|
mov ebx, [casinoSprites + eax].distSq
|
|
cmp ebx, 45000 ; Near sprite
|
|
jg next_prox_spr
|
|
|
|
mov edx, [casinoSprites + eax].interactId
|
|
mov interactTargetId, edx
|
|
mov edx, [casinoSprites + eax].promptPtr
|
|
mov interactPromptPtr, edx
|
|
jmp prox_done
|
|
|
|
next_prox_spr:
|
|
inc esi
|
|
jmp check_spr_prox
|
|
|
|
prox_done:
|
|
ret
|
|
CheckInteractions ENDP
|
|
|
|
Trigger3DInteraction PROC
|
|
mov eax, interactTargetId
|
|
test eax, eax
|
|
jz @F
|
|
|
|
cmp eax, 8 ; DANCER
|
|
jne check_target_slots
|
|
cmp bankroll, 100
|
|
jl dancer_no_cash
|
|
sub bankroll, 100
|
|
inc dancerLuckBuff
|
|
mov cheatLuckyWin, 1
|
|
invoke CopyString3D, OFFSET msgDancerTipped, OFFSET flashMessage
|
|
mov flashTimer, 100
|
|
invoke PlaySoundA, OFFSET soundJackpot, 0, 1
|
|
ret
|
|
dancer_no_cash:
|
|
invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage
|
|
mov flashTimer, 60
|
|
ret
|
|
|
|
check_target_slots:
|
|
cmp eax, 3 ; SLOTS
|
|
jne check_target_bj
|
|
mov engineMode, MODE_SLOTS
|
|
invoke PlaySoundA, OFFSET soundClick, 0, 1
|
|
ret
|
|
|
|
check_target_bj:
|
|
cmp eax, 1 ; BLACKJACK
|
|
jne check_target_roulette
|
|
mov engineMode, MODE_BLACKJACK
|
|
mov bjState, 0
|
|
ret
|
|
|
|
check_target_roulette:
|
|
cmp eax, 4 ; ROULETTE
|
|
jne check_target_shop
|
|
mov engineMode, MODE_ROULETTE
|
|
mov roulState, 0
|
|
ret
|
|
|
|
check_target_shop:
|
|
cmp eax, 6 ; SHOP
|
|
jne check_target_atm
|
|
mov engineMode, MODE_SHOP
|
|
ret
|
|
|
|
check_target_atm:
|
|
cmp eax, 7 ; ATM
|
|
jne @F
|
|
mov engineMode, MODE_ATM
|
|
ret
|
|
@@:
|
|
ret
|
|
Trigger3DInteraction ENDP
|
|
|
|
; --- Engine Initialization ---
|
|
Init3DEngine PROC
|
|
local screenCX:DWORD
|
|
local screenCY:DWORD
|
|
local posX:DWORD
|
|
local posY:DWORD
|
|
local bytesRead:DWORD
|
|
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
|
|
invoke GetConsoleWindow
|
|
mov hCasinoConsole, eax
|
|
|
|
; Setup DIB Info
|
|
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, DIB_RGB_COLORS
|
|
|
|
; Setup Window Class
|
|
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
|
|
|
|
; Center 1280x960 Window on Desktop
|
|
invoke GetSystemMetrics, 0
|
|
mov screenCX, eax
|
|
invoke GetSystemMetrics, 1
|
|
mov screenCY, eax
|
|
|
|
mov eax, screenCX
|
|
sub eax, WINDOW_W
|
|
shr eax, 1
|
|
cmp eax, 0
|
|
jge @F
|
|
xor eax, eax
|
|
@@:
|
|
mov posX, eax
|
|
|
|
mov eax, screenCY
|
|
sub eax, WINDOW_H
|
|
shr eax, 1
|
|
cmp eax, 0
|
|
jge @F
|
|
xor eax, eax
|
|
@@:
|
|
mov posY, eax
|
|
|
|
invoke CreateWindowExA, 0, OFFSET sz3DClassName, OFFSET sz3DWindowTitle,\
|
|
WS_OVERLAPPEDWINDOW, posX, posY, WINDOW_W + 16, WINDOW_H + 39,\
|
|
0, 0, 0, 0
|
|
mov h3DWnd, eax
|
|
|
|
invoke GetDC, h3DWnd
|
|
mov h3DDC, eax
|
|
|
|
invoke ShowWindow, h3DWnd, SW_SHOW
|
|
invoke UpdateWindow, h3DWnd
|
|
invoke SetForegroundWindow, h3DWnd
|
|
|
|
; Load Textures
|
|
invoke CreateFileA, OFFSET szTexturesRelPath, 80000000h, 1, 0, 3, 80h, 0
|
|
cmp eax, INVALID_FILE_HANDLE
|
|
je init_sprites_table
|
|
mov ebx, eax
|
|
lea ecx, bytesRead
|
|
invoke ReadFile, ebx, OFFSET texturesBuffer, (48 * 64 * 64 * 4), ecx, 0
|
|
invoke CloseHandle, ebx
|
|
|
|
init_sprites_table:
|
|
; Sprite 0: VIP Dancer 1 (Stage Left)
|
|
mov casinoSprites[0*SIZEOF SpriteObject].posX, (13 * FP_1 + FP_HALF)
|
|
mov casinoSprites[0*SIZEOF SpriteObject].posY, (4 * FP_1)
|
|
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, 5
|
|
mov casinoSprites[0*SIZEOF SpriteObject].interactId, 8
|
|
mov casinoSprites[0*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer
|
|
|
|
; Sprite 1: VIP Dancer 2 (Center Stage Star)
|
|
mov casinoSprites[1*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF)
|
|
mov casinoSprites[1*SIZEOF SpriteObject].posY, (3 * 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, 5
|
|
mov casinoSprites[1*SIZEOF SpriteObject].interactId, 8
|
|
mov casinoSprites[1*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer
|
|
|
|
; Sprite 2: VIP Dancer 3 (Stage Right)
|
|
mov casinoSprites[2*SIZEOF SpriteObject].posX, (19 * FP_1 + FP_HALF)
|
|
mov casinoSprites[2*SIZEOF SpriteObject].posY, (4 * FP_1)
|
|
mov casinoSprites[2*SIZEOF SpriteObject].baseTexId, 10
|
|
mov casinoSprites[2*SIZEOF SpriteObject].frameCount, 4
|
|
mov casinoSprites[2*SIZEOF SpriteObject].curFrame, 1
|
|
mov casinoSprites[2*SIZEOF SpriteObject].animTimer, 0
|
|
mov casinoSprites[2*SIZEOF SpriteObject].animSpeed, 5
|
|
mov casinoSprites[2*SIZEOF SpriteObject].interactId, 8
|
|
mov casinoSprites[2*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer
|
|
|
|
; Sprite 3: Blackjack Table with Dealer (Front Center Left)
|
|
mov casinoSprites[3*SIZEOF SpriteObject].posX, (12 * FP_1 + FP_HALF)
|
|
mov casinoSprites[3*SIZEOF SpriteObject].posY, (10 * FP_1)
|
|
mov casinoSprites[3*SIZEOF SpriteObject].baseTexId, 30
|
|
mov casinoSprites[3*SIZEOF SpriteObject].frameCount, 1
|
|
mov casinoSprites[3*SIZEOF SpriteObject].curFrame, 0
|
|
mov casinoSprites[3*SIZEOF SpriteObject].animTimer, 0
|
|
mov casinoSprites[3*SIZEOF SpriteObject].animSpeed, 1
|
|
mov casinoSprites[3*SIZEOF SpriteObject].interactId, 1
|
|
mov casinoSprites[3*SIZEOF SpriteObject].promptPtr, OFFSET promptBlackjack
|
|
|
|
; Sprite 4: Roulette Table (Front Center)
|
|
mov casinoSprites[4*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF)
|
|
mov casinoSprites[4*SIZEOF SpriteObject].posY, (10 * FP_1)
|
|
mov casinoSprites[4*SIZEOF SpriteObject].baseTexId, 31
|
|
mov casinoSprites[4*SIZEOF SpriteObject].frameCount, 1
|
|
mov casinoSprites[4*SIZEOF SpriteObject].curFrame, 0
|
|
mov casinoSprites[4*SIZEOF SpriteObject].animTimer, 0
|
|
mov casinoSprites[4*SIZEOF SpriteObject].animSpeed, 1
|
|
mov casinoSprites[4*SIZEOF SpriteObject].interactId, 4
|
|
mov casinoSprites[4*SIZEOF SpriteObject].promptPtr, OFFSET promptRoulette
|
|
|
|
; Sprite 5: Poker Table (Front Center Right)
|
|
mov casinoSprites[5*SIZEOF SpriteObject].posX, (21 * FP_1)
|
|
mov casinoSprites[5*SIZEOF SpriteObject].posY, (10 * FP_1)
|
|
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 promptPoker
|
|
|
|
; Sprite 6: Slot Machine 1 (West Arcade)
|
|
mov casinoSprites[6*SIZEOF SpriteObject].posX, (6 * FP_1)
|
|
mov casinoSprites[6*SIZEOF SpriteObject].posY, (8 * FP_1)
|
|
mov casinoSprites[6*SIZEOF SpriteObject].baseTexId, 20
|
|
mov casinoSprites[6*SIZEOF SpriteObject].frameCount, 3
|
|
mov casinoSprites[6*SIZEOF SpriteObject].curFrame, 0
|
|
mov casinoSprites[6*SIZEOF SpriteObject].animTimer, 0
|
|
mov casinoSprites[6*SIZEOF SpriteObject].animSpeed, 8
|
|
mov casinoSprites[6*SIZEOF SpriteObject].interactId, 3
|
|
mov casinoSprites[6*SIZEOF SpriteObject].promptPtr, OFFSET promptSlot1
|
|
|
|
; Sprite 7: Slot Machine 2 (CloverPit)
|
|
mov casinoSprites[7*SIZEOF SpriteObject].posX, (6 * FP_1)
|
|
mov casinoSprites[7*SIZEOF SpriteObject].posY, (11 * FP_1)
|
|
mov casinoSprites[7*SIZEOF SpriteObject].baseTexId, 20
|
|
mov casinoSprites[7*SIZEOF SpriteObject].frameCount, 3
|
|
mov casinoSprites[7*SIZEOF SpriteObject].curFrame, 1
|
|
mov casinoSprites[7*SIZEOF SpriteObject].animTimer, 0
|
|
mov casinoSprites[7*SIZEOF SpriteObject].animSpeed, 8
|
|
mov casinoSprites[7*SIZEOF SpriteObject].interactId, 3
|
|
mov casinoSprites[7*SIZEOF SpriteObject].promptPtr, OFFSET promptSlot2
|
|
|
|
; Sprite 8: Slot Machine 3
|
|
mov casinoSprites[8*SIZEOF SpriteObject].posX, (6 * FP_1)
|
|
mov casinoSprites[8*SIZEOF SpriteObject].posY, (14 * FP_1)
|
|
mov casinoSprites[8*SIZEOF SpriteObject].baseTexId, 20
|
|
mov casinoSprites[8*SIZEOF SpriteObject].frameCount, 3
|
|
mov casinoSprites[8*SIZEOF SpriteObject].curFrame, 2
|
|
mov casinoSprites[8*SIZEOF SpriteObject].animTimer, 0
|
|
mov casinoSprites[8*SIZEOF SpriteObject].animSpeed, 8
|
|
mov casinoSprites[8*SIZEOF SpriteObject].interactId, 3
|
|
mov casinoSprites[8*SIZEOF SpriteObject].promptPtr, OFFSET promptSlot1
|
|
|
|
; Sprite 9: Bartender / Bar Counter (East Wing)
|
|
mov casinoSprites[9*SIZEOF SpriteObject].posX, (26 * FP_1)
|
|
mov casinoSprites[9*SIZEOF SpriteObject].posY, (12 * FP_1)
|
|
mov casinoSprites[9*SIZEOF SpriteObject].baseTexId, 32
|
|
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, 6
|
|
mov casinoSprites[9*SIZEOF SpriteObject].promptPtr, OFFSET promptShop
|
|
|
|
; Sprite 10: ATM Bank Terminal (East Wing)
|
|
mov casinoSprites[10*SIZEOF SpriteObject].posX, (26 * FP_1)
|
|
mov casinoSprites[10*SIZEOF SpriteObject].posY, (16 * FP_1)
|
|
mov casinoSprites[10*SIZEOF SpriteObject].baseTexId, 33
|
|
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, 7
|
|
mov casinoSprites[10*SIZEOF SpriteObject].promptPtr, OFFSET promptATM
|
|
|
|
; Sprite 11: Underground Table (South Wing)
|
|
mov casinoSprites[11*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF)
|
|
mov casinoSprites[11*SIZEOF SpriteObject].posY, (24 * FP_1)
|
|
mov casinoSprites[11*SIZEOF SpriteObject].baseTexId, 34
|
|
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, 5
|
|
mov casinoSprites[11*SIZEOF SpriteObject].promptPtr, OFFSET promptBackroom
|
|
|
|
; Sprite 12: Secret Demon Portal (South Wing)
|
|
mov casinoSprites[12*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF)
|
|
mov casinoSprites[12*SIZEOF SpriteObject].posY, (29 * FP_1)
|
|
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
|
|
|
|
; --- Main Loop of the 3D Casino Engine ---
|
|
StartCasino3D PROC uses ebx esi edi
|
|
call Init3DEngine
|
|
invoke PlaySoundA, OFFSET soundJackpot, 0, 1
|
|
|
|
engine_loop:
|
|
lea eax, [msg3D]
|
|
invoke PeekMessageA, eax, 0, 0, 0, PM_REMOVE
|
|
test eax, eax
|
|
jz dispatch_frame
|
|
cmp msg3D.message, WM_QUIT
|
|
je exit_3d_engine
|
|
lea eax, [msg3D]
|
|
invoke TranslateMessage, eax
|
|
lea eax, [msg3D]
|
|
invoke DispatchMessageA, eax
|
|
|
|
dispatch_frame:
|
|
cmp engineMode, MODE_WALK
|
|
jne check_slots_mode
|
|
|
|
; MODE_WALK: 3D Raycasting Casino
|
|
invoke GetAsyncKeyState, 1Bh ; ESC in walk mode -> Exit 3D
|
|
test ah, 80h
|
|
jnz exit_3d_engine
|
|
|
|
call HandlePlayerInput
|
|
call CheckInteractions
|
|
call RenderCeilingAndFloor
|
|
call RenderWalls
|
|
call RenderSprites
|
|
call RenderHUD
|
|
call RenderMinimap
|
|
jmp present_frame
|
|
|
|
check_slots_mode:
|
|
cmp engineMode, MODE_SLOTS
|
|
jne check_bj_mode
|
|
call HandleSlotsInput
|
|
call RenderSlotsGame
|
|
jmp present_frame
|
|
|
|
check_bj_mode:
|
|
cmp engineMode, MODE_BLACKJACK
|
|
jne check_roul_mode
|
|
call HandleBlackjackInput
|
|
call RenderBlackjackGame
|
|
jmp present_frame
|
|
|
|
check_roul_mode:
|
|
cmp engineMode, MODE_ROULETTE
|
|
jne check_shop_mode
|
|
call HandleRouletteInput
|
|
call RenderRouletteGame
|
|
jmp present_frame
|
|
|
|
check_shop_mode:
|
|
cmp engineMode, MODE_SHOP
|
|
jne check_atm_mode
|
|
call HandleShopInput
|
|
call RenderShopGame
|
|
jmp present_frame
|
|
|
|
check_atm_mode:
|
|
call HandleATMInput
|
|
call RenderATMGame
|
|
|
|
present_frame:
|
|
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
|
|
''')
|
|
|
|
# Write complete file in Windows-1251
|
|
with open('casino3d.inc', 'wb') as f:
|
|
f.write(''.join(code_chunks).encode('cp1251'))
|
|
|
|
print('casino3d.inc completely generated in CP1251!')
|