KAZIK/src_graphics/jackbox.inc

335 lines
8.7 KiB
PHP

; ==============================================================================
; JACKBOX / JUKEBOX IMPLEMENTATION - MASM32 / CP1251
; ==============================================================================
.code
LoadJackboxArt3D PROC
invoke LoadAnimPack3D, OFFSET jackboxWorldArt3D, OFFSET jackboxWorldPath3D
invoke ValidateCityPack3D, OFFSET jackboxWorldArt3D, 256, 512, 3
invoke LoadAnimPack3D, OFFSET jackboxScreenArt3D, OFFSET jackboxScreenPath3D
invoke ValidateCityPack3D, OFFSET jackboxScreenArt3D, 640, 480, 1
ret
LoadJackboxArt3D ENDP
FreeJackboxArt3D PROC
invoke FreeAnimPack3D, OFFSET jackboxWorldArt3D
invoke FreeAnimPack3D, OFFSET jackboxScreenArt3D
ret
FreeJackboxArt3D ENDP
ResolveJackboxSurface3D PROC material:DWORD
cmp jackboxWorldArt3D.pixels, 0
je jackbox_surface_missing
mov eax, material
cmp eax, MATERIAL_JACKBOX_FRONT
je jackbox_surface_front
cmp eax, MATERIAL_JACKBOX_SIDE
je jackbox_surface_side
cmp eax, MATERIAL_JACKBOX_BACK
jne jackbox_surface_missing
; Frame 2: rear panel (offset 256*512*4*2 = 1048576)
mov eax, jackboxWorldArt3D.pixels
add eax, 1048576
mov ecx, 256
mov edx, 512
ret
jackbox_surface_side:
; Frame 1: side profile (offset 256*512*4 = 524288)
mov eax, jackboxWorldArt3D.pixels
add eax, 524288
mov ecx, 256
mov edx, 512
ret
jackbox_surface_front:
; Frame 0: front face
mov eax, jackboxWorldArt3D.pixels
mov ecx, 256
mov edx, 512
ret
jackbox_surface_missing:
xor eax, eax
ret
ResolveJackboxSurface3D ENDP
DrawJackboxCabinet3D PROC uses ebx esi edi wx:DWORD, wy:DWORD
local x0:DWORD, x1:DWORD, y0:DWORD, y1:DWORD
; Footprint: width 0.75m, depth 0.55m, height 1.85m
mov eax, wx
sub eax, FP_1*15/40
mov x0, eax
add eax, FP_1*15/20
mov x1, eax
mov eax, wy
sub eax, FP_1*11/40
mov y0, eax
add eax, FP_1*11/20
mov y1, eax
; Rear: North face (Y = y0)
invoke DrawCityVertical3D, 1, y0, x0, x1, 0, FP_1*37/20, MATERIAL_JACKBOX_BACK
; Sides: West face (X = x0) and East face (X = x1)
invoke DrawCityVertical3D, 0, x0, y0, y1, 0, FP_1*37/20, MATERIAL_JACKBOX_SIDE
invoke DrawCityVertical3D, 0, x1, y0, y1, 0, FP_1*37/20, MATERIAL_JACKBOX_SIDE
; Front: South face (Y = y1)
invoke DrawCityVertical3D, 1, y1, x0, x1, 0, FP_1*37/20, MATERIAL_JACKBOX_FRONT
ret
DrawJackboxCabinet3D ENDP
RenderJackboxCabinet3D PROC
invoke DrawJackboxCabinet3D, JACKBOX_X, JACKBOX_Y
ret
RenderJackboxCabinet3D ENDP
JackboxCanWalk3D PROC px:DWORD, py:DWORD
mov eax, py
sub eax, JACKBOX_Y
test eax, eax
jns @F
neg eax
@@:
cmp eax, FP_1*11/20
ja jackbox_walk_clear
mov eax, px
sub eax, JACKBOX_X
test eax, eax
jns @F
neg eax
@@:
cmp eax, FP_1*15/20
jbe jackbox_walk_blocked
jackbox_walk_clear:
mov eax, 1
ret
jackbox_walk_blocked:
xor eax, eax
ret
JackboxCanWalk3D ENDP
PlayJukeboxTrack3D PROC uses ebx trackIndex:DWORD
invoke mciSendStringA, OFFSET jboxStopCmd, 0, 0, 0
invoke mciSendStringA, OFFSET jboxCloseCmd, 0, 0, 0
mov jboxIsPlaying, 0
mov ebx, trackIndex
cmp ebx, 9
jae jbox_play_done
cmp ebx, JACKBOX_TRACK_COUNT
jae jbox_play_done
mov eax, jboxOpenCommands[ebx*4]
test eax, eax
jz jbox_play_done
invoke mciSendStringA, eax, 0, 0, 0
invoke mciSendStringA, OFFSET jboxPlayCmd, 0, 0, 0
mov jboxCurrentTrack, ebx
mov jboxIsPlaying, 1
jbox_play_done:
ret
PlayJukeboxTrack3D ENDP
StopJukeboxTrack3D PROC
invoke mciSendStringA, OFFSET jboxStopCmd, 0, 0, 0
invoke mciSendStringA, OFFSET jboxCloseCmd, 0, 0, 0
mov jboxIsPlaying, 0
mov jboxCurrentTrack, -1
ret
StopJukeboxTrack3D ENDP
BeginJackbox3D PROC
mov engineMode, MODE_JACKBOX
call ClearKeys3D
mov mouseClick3D, 0
ret
BeginJackbox3D ENDP
HandleJackbox3D PROC uses ebx esi
; 1. Mouse interactions
cmp mouseClick3D, 0
je jbox_keys
; Check Exit button in top right: x in [228..312], y in [8..26]
cmp mouseY3D, 8
jb @F
cmp mouseY3D, 26
ja @F
cmp mouseX3D, 228
jae jbox_exit
@@:
; Check track row click: y in [54..186]
cmp mouseY3D, 54
jb jbox_keys
cmp mouseY3D, 186
ja jbox_keys
cmp mouseX3D, 16
jb jbox_keys
cmp mouseX3D, 304
ja jbox_keys
mov eax, mouseY3D
sub eax, 54
xor edx, edx
mov ebx, 13
div ebx
cmp eax, JACKBOX_TRACK_COUNT
jae jbox_keys
mov jboxSelectedTrack, eax
invoke PlayJukeboxTrack3D, eax
jmp jbox_handled
jbox_keys:
; Exit keys: ESC (1Bh) or 'E' (45h)
invoke Pressed3D, 1Bh
test eax, eax
jnz jbox_exit
invoke Pressed3D, 45h
test eax, eax
jnz jbox_exit
; Navigation: UP (26h) / DOWN (28h)
invoke Pressed3D, 26h
test eax, eax
jz @F
dec jboxSelectedTrack
jns jbox_handled
mov jboxSelectedTrack, JACKBOX_TRACK_COUNT - 1
jmp jbox_handled
@@:
invoke Pressed3D, 28h
test eax, eax
jz @F
inc jboxSelectedTrack
cmp jboxSelectedTrack, JACKBOX_TRACK_COUNT
jb jbox_handled
mov jboxSelectedTrack, 0
jmp jbox_handled
@@:
; Play selection: ENTER (0Dh) or SPACE (20h)
invoke Pressed3D, 0Dh
test eax, eax
jnz jbox_play_selected
invoke Pressed3D, 20h
test eax, eax
jnz jbox_play_selected
; Stop key: 'S' (53h)
invoke Pressed3D, 53h
test eax, eax
jz @F
call StopJukeboxTrack3D
jmp jbox_handled
@@:
; Random key: 'R' (52h)
invoke Pressed3D, 52h
test eax, eax
jz @F
invoke RandomRange3D, 9
mov jboxSelectedTrack, eax
invoke PlayJukeboxTrack3D, eax
jmp jbox_handled
@@:
; Direct digit keys '1'..'9', '0'
mov ebx, 31h ; '1'
jbox_digit_loop:
invoke Pressed3D, ebx
test eax, eax
jz jbox_digit_next
mov eax, ebx
sub eax, 31h
mov jboxSelectedTrack, eax
invoke PlayJukeboxTrack3D, eax
jmp jbox_handled
jbox_digit_next:
inc ebx
cmp ebx, 39h ; '9'
jbe jbox_digit_loop
; '0' key for mute/stop
invoke Pressed3D, 30h
test eax, eax
jz jbox_handled
mov jboxSelectedTrack, 9
invoke PlayJukeboxTrack3D, 9
jmp jbox_handled
jbox_play_selected:
invoke PlayJukeboxTrack3D, jboxSelectedTrack
jmp jbox_handled
jbox_exit:
mov engineMode, MODE_WALK
call ClearKeys3D
jbox_handled:
mov mouseClick3D, 0
ret
HandleJackbox3D ENDP
RenderJackbox3D PROC uses ebx esi edi
local rowY:DWORD, color:DWORD
; 1. Draw base background
invoke DrawBox, 0, 0, 320, 240, 000B1815h
; 2. Overlay screen artwork if available
cmp jackboxScreenArt3D.pixels, 0
je @F
invoke DrawAnimSprite3D, OFFSET jackboxScreenArt3D, 0, 0, 0, 640, 480
@@:
; 3. Title & Exit Button
invoke DrawString8x8, 52, 12, OFFSET jboxTitle, 00E7C479h
invoke DrawBoxBorder, 228, 8, 84, 16, 001A2522h, 00C8AD75h, 1
invoke DrawString8x8, 234, 12, OFFSET jboxClose, 00F2E6C6h
; 4. Now Playing Status Banner
cmp jboxIsPlaying, 1
jne jbox_render_stopped
cmp jboxCurrentTrack, -1
je jbox_render_stopped
cmp jboxCurrentTrack, 9
jae jbox_render_stopped
invoke DrawString8x8, 20, 34, OFFSET jboxStatusPlaying, 008CD8AFh
mov eax, jboxCurrentTrack
mov edx, jboxTrackNames[eax*4]
invoke DrawString8x8, 140, 34, edx, 00F0E6C3h
jmp jbox_render_divider
jbox_render_stopped:
invoke DrawString8x8, 20, 34, OFFSET jboxStatusStopped, 0090B19Fh
jbox_render_divider:
invoke DrawBox, 20, 47, 280, 1, 00495B4Ah
; 5. Track Selection List (10 rows, step Y = 13)
mov rowY, 55
xor esi, esi
jbox_render_row:
mov color, 0090B19Fh ; Default muted
cmp esi, jboxSelectedTrack
jne @F
mov color, 00F2E6C6h ; Bright cream for selection
invoke DrawString8x8, 14, rowY, OFFSET jboxCursor, 00E7C479h
@@:
mov edx, jboxTrackNames[esi*4]
invoke DrawString8x8, 28, rowY, edx, color
; Mark playing track
cmp esi, jboxCurrentTrack
jne jbox_row_next
cmp jboxIsPlaying, 1
jne jbox_row_next
invoke DrawString8x8, 252, rowY, OFFSET jboxPlayingTag, 008CD8AFh
jbox_row_next:
add rowY, 13
inc esi
cmp esi, JACKBOX_TRACK_COUNT
jb jbox_render_row
; 6. Footer Controls Help
invoke DrawBox, 20, 192, 280, 1, 00314538h
invoke DrawString8x8, 20, 200, OFFSET jboxHelp1, 00C1A982h
invoke DrawString8x8, 20, 214, OFFSET jboxHelp2, 0090B19Fh
ret
RenderJackbox3D ENDP