fix(jackbox): realign UI strictly within CRT monitor sprite and clear wall painting
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 223 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 187 KiB After Width: | Height: | Size: 38 KiB |
BIN
poker.exe
BIN
poker.obj
|
|
@ -1,67 +1,68 @@
|
|||
; ==============================================================================
|
||||
; 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
|
||||
|
||||
; ==============================================================================
|
||||
; 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
|
||||
; Solid rectangular cabinet against East wall beside billiards:
|
||||
; Depth along X: 0.55m (x0 = 30.40m, x1 = 30.95m against wall at 31.0m)
|
||||
; Width along Y: 0.85m (y0 = 24.575m, y1 = 25.425m, centered at Y = 25.0m)
|
||||
; Width along Y: 0.85m (y0 = 23.075m, y1 = 23.925m, centered at Y = 23.5m)
|
||||
; Leaves painting 116 at Y = [25.0 .. 26.5] completely visible and unblocked!
|
||||
; Height Z: 1.85m
|
||||
mov x0, FP_1*304/10
|
||||
mov x1, FP_1*3095/100
|
||||
mov y0, 25*FP_1 - FP_1*425/1000
|
||||
mov y1, 25*FP_1 + FP_1*425/1000
|
||||
mov y0, FP_1*235/10 - FP_1*425/1000
|
||||
mov y1, FP_1*235/10 + FP_1*425/1000
|
||||
|
||||
; 1. Back Face (against East wall: X = x1)
|
||||
invoke DrawCityVertical3D, 0, x1, y0, y1, 0, FP_1*37/20, MATERIAL_JACKBOX_BACK
|
||||
|
|
@ -88,7 +89,7 @@ JackboxCanWalk3D PROC px:DWORD, py:DWORD
|
|||
cmp eax, 31*FP_1+9830
|
||||
ja jackbox_walk_clear
|
||||
mov eax, py
|
||||
sub eax, 25*FP_1
|
||||
sub eax, FP_1*235/10
|
||||
test eax, eax
|
||||
jns @F
|
||||
neg eax
|
||||
|
|
@ -102,230 +103,309 @@ jackbox_walk_clear:
|
|||
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
|
||||
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
|
||||
|
||||
; Exit via Top-Right LCD slot: x in [232..284], y in [12..26]
|
||||
cmp mouseY3D, 12
|
||||
jb @F
|
||||
cmp mouseY3D, 26
|
||||
ja @F
|
||||
cmp mouseX3D, 232
|
||||
jb @F
|
||||
cmp mouseX3D, 284
|
||||
jbe jbox_exit
|
||||
@@:
|
||||
; Exit via Bottom Red CANCEL button: x in [224..256], y in [195..225]
|
||||
cmp mouseY3D, 195
|
||||
jb @F
|
||||
cmp mouseY3D, 225
|
||||
ja @F
|
||||
cmp mouseX3D, 224
|
||||
jb @F
|
||||
cmp mouseX3D, 256
|
||||
jbe jbox_exit
|
||||
@@:
|
||||
; Bottom Green START button: x in [154..188], y in [195..225] -> Play selected
|
||||
cmp mouseY3D, 195
|
||||
jb @F
|
||||
cmp mouseY3D, 225
|
||||
ja @F
|
||||
cmp mouseX3D, 154
|
||||
jb @F
|
||||
cmp mouseX3D, 188
|
||||
jbe jbox_play_selected
|
||||
@@:
|
||||
; Bottom Orange SELECT button: x in [190..222], y in [195..225] -> Next track & play
|
||||
cmp mouseY3D, 195
|
||||
jb @F
|
||||
cmp mouseY3D, 225
|
||||
ja @F
|
||||
cmp mouseX3D, 190
|
||||
jb @F
|
||||
cmp mouseX3D, 222
|
||||
ja @F
|
||||
inc jboxSelectedTrack
|
||||
cmp jboxSelectedTrack, JACKBOX_TRACK_COUNT
|
||||
jb jbox_play_selected
|
||||
mov jboxSelectedTrack, 0
|
||||
jmp jbox_play_selected
|
||||
@@:
|
||||
; Bottom Left Arrow: x in [256..274], y in [204..224] -> Prev track
|
||||
cmp mouseY3D, 204
|
||||
jb @F
|
||||
cmp mouseY3D, 224
|
||||
ja @F
|
||||
cmp mouseX3D, 256
|
||||
jb @F
|
||||
cmp mouseX3D, 274
|
||||
ja @F
|
||||
dec jboxSelectedTrack
|
||||
jns jbox_play_selected
|
||||
mov jboxSelectedTrack, JACKBOX_TRACK_COUNT - 1
|
||||
jmp jbox_play_selected
|
||||
@@:
|
||||
; Bottom Right Arrow: x in [276..294], y in [204..224] -> Next track
|
||||
cmp mouseY3D, 204
|
||||
jb @F
|
||||
cmp mouseY3D, 224
|
||||
ja @F
|
||||
cmp mouseX3D, 276
|
||||
jb @F
|
||||
cmp mouseX3D, 294
|
||||
ja @F
|
||||
inc jboxSelectedTrack
|
||||
cmp jboxSelectedTrack, JACKBOX_TRACK_COUNT
|
||||
jb jbox_play_selected
|
||||
mov jboxSelectedTrack, 0
|
||||
jmp jbox_play_selected
|
||||
@@:
|
||||
; Check track row click inside CRT screen: x in [46..274], y in [65..165]
|
||||
cmp mouseY3D, 65
|
||||
jb jbox_keys
|
||||
cmp mouseY3D, 165
|
||||
ja jbox_keys
|
||||
cmp mouseX3D, 46
|
||||
jb jbox_keys
|
||||
cmp mouseX3D, 274
|
||||
ja jbox_keys
|
||||
mov eax, mouseY3D
|
||||
sub eax, 65
|
||||
xor edx, edx
|
||||
mov ebx, 10
|
||||
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'
|
||||
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 (640x480 physical buffer)
|
||||
cmp jackboxScreenArt3D.pixels, 0
|
||||
je @F
|
||||
invoke DrawAnimSprite3D, OFFSET jackboxScreenArt3D, 0, 0, 0, 640, 480
|
||||
@@:
|
||||
; 3. Top Digital LCD Slots
|
||||
; Left slot: status text
|
||||
cmp jboxIsPlaying, 1
|
||||
jne jbox_top_lcd_stopped
|
||||
cmp jboxCurrentTrack, -1
|
||||
je jbox_top_lcd_stopped
|
||||
cmp jboxCurrentTrack, 9
|
||||
jae jbox_top_lcd_stopped
|
||||
invoke DrawString8x8, 42, 17, OFFSET jboxLcdPlay, 0050FF90h ; Green "ÈÃÐÀÅÒ"
|
||||
jmp jbox_top_lcd_exit
|
||||
jbox_top_lcd_stopped:
|
||||
invoke DrawString8x8, 45, 17, OFFSET jboxLcdStop, 008CB8A5h ; Dim green "ÑÒÎÏ"
|
||||
jbox_top_lcd_exit:
|
||||
; Right slot: exit button text
|
||||
invoke DrawString8x8, 241, 17, OFFSET jboxLcdExit, 00F2A648h ; Amber "ÂÛÕÎÄ"
|
||||
|
||||
; 4. CRT Monitor Header: Now Playing Status
|
||||
cmp jboxIsPlaying, 1
|
||||
jne jbox_render_stopped
|
||||
cmp jboxCurrentTrack, -1
|
||||
je jbox_render_stopped
|
||||
cmp jboxCurrentTrack, 9
|
||||
jae jbox_render_stopped
|
||||
|
||||
invoke DrawString8x8, 48, 52, OFFSET jboxHdrNow, 0050FF90h ; Green "ÑÅÉ×ÀÑ:"
|
||||
mov eax, jboxCurrentTrack
|
||||
mov edx, jboxTrackNames[eax*4]
|
||||
invoke DrawString8x8, 108, 52, edx, 00F0E6C3h
|
||||
jmp jbox_render_divider
|
||||
|
||||
jbox_render_stopped:
|
||||
invoke DrawString8x8, 48, 52, OFFSET jboxHdrStop, 008CB8A5h ; Dim green "ÑÒÀÒÓÑ: ÎÑÒÀÍÎÂËÅÍ"
|
||||
|
||||
jbox_render_divider:
|
||||
invoke DrawBox, 46, 62, 228, 1, 001C3828h
|
||||
|
||||
; 5. Track Selection List (10 rows, step Y = 10, from Y = 66)
|
||||
mov rowY, 66
|
||||
xor esi, esi
|
||||
jbox_render_row:
|
||||
mov color, 008CB8A5h ; Default CRT phosphor pale cyan
|
||||
|
||||
cmp esi, jboxSelectedTrack
|
||||
jne @F
|
||||
; Selected row: highlight box, golden cursor, bright white text
|
||||
invoke DrawBox, 46, rowY, 228, 9, 00143526h
|
||||
invoke DrawString8x8, 48, rowY, OFFSET jboxCursor, 00FFD700h
|
||||
mov color, 00FFFFFFh
|
||||
@@:
|
||||
mov edx, jboxTrackNames[esi*4]
|
||||
invoke DrawString8x8, 58, rowY, edx, color
|
||||
|
||||
; Mark playing track with [>] tag
|
||||
cmp esi, jboxCurrentTrack
|
||||
jne jbox_row_next
|
||||
cmp jboxIsPlaying, 1
|
||||
jne jbox_row_next
|
||||
invoke DrawString8x8, 238, rowY, OFFSET jboxTagPlay, 0050FF90h
|
||||
|
||||
jbox_row_next:
|
||||
add rowY, 10
|
||||
inc esi
|
||||
cmp esi, JACKBOX_TRACK_COUNT
|
||||
jb jbox_render_row
|
||||
|
||||
; 6. Footer Controls Help (strictly inside CRT)
|
||||
invoke DrawBox, 46, 166, 228, 1, 001C3828h
|
||||
invoke DrawString8x8, 56, 170, OFFSET jboxFooterHelp, 0070AA90h
|
||||
|
||||
ret
|
||||
RenderJackbox3D ENDP
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ MODE_JACKBOX equ 28
|
|||
INTERACT_JACKBOX equ 48
|
||||
|
||||
JACKBOX_X equ FP_1*306/10
|
||||
JACKBOX_Y equ 25*FP_1
|
||||
JACKBOX_Y equ FP_1*235/10
|
||||
JACKBOX_TRACK_COUNT equ 10
|
||||
|
||||
MATERIAL_JACKBOX_FRONT equ 161
|
||||
MATERIAL_JACKBOX_SIDE equ 162
|
||||
MATERIAL_JACKBOX_SIDE equ 162
|
||||
MATERIAL_JACKBOX_BACK equ 163
|
||||
|
||||
LoadJackboxArt3D PROTO
|
||||
|
|
@ -30,7 +30,8 @@ jackboxScreenArt3D AnimPack3D <>
|
|||
jackboxWorldPath3D db "assets\animations\hall\jackbox-v1.bin",0
|
||||
jackboxScreenPath3D db "assets\animations\hall\jackbox-ui-v1.bin",0
|
||||
|
||||
jackboxPrompt3D db "E: ÄÆÓÊÁÎÊÑ",0
|
||||
; Prompt: "E: Âêëþ÷èòü àâòîìàò"
|
||||
jackboxPrompt3D db 69,58,32,194,234,235,254,247,232,242,252,32,224,226,242,238,236,224,242,0
|
||||
|
||||
jboxCurrentTrack dd -1
|
||||
jboxSelectedTrack dd 0
|
||||
|
|
@ -54,26 +55,31 @@ jboxOpenCommands dd OFFSET jboxOpen0, OFFSET jboxOpen1, OFFSET jboxOpen2, OFFSET
|
|||
dd OFFSET jboxOpen4, OFFSET jboxOpen5, OFFSET jboxOpen6, OFFSET jboxOpen7
|
||||
dd OFFSET jboxOpen8, 0
|
||||
|
||||
jboxName0 db "1. Keygen Church - Tenebre Rosso Sangue",0
|
||||
jboxName1 db "2. Keygen Church - Hareklavit",0
|
||||
jboxName2 db "3. Keygen Church - Ladikerfos",0
|
||||
jboxName3 db "4. Keygen Church - Tilaskarot",0
|
||||
jboxName4 db "5. Mick Gordon - BFG Division (DOOM)",0
|
||||
jboxName5 db "6. Mick Gordon - Rip & Tear (DOOM)",0
|
||||
jboxName6 db "7. Mick Gordon - The Only Thing They Fear",0
|
||||
jboxName7 db "8. Hakari Dance (Jackpot Theme)",0
|
||||
jboxName8 db "9. Team Fortress 2 - Victory Theme",0
|
||||
jboxName9 db "0. [ ÂÛÊËÞ×ÈÒÜ ÌÓÇÛÊÓ / ÒÈØÈÍÀ ]",0
|
||||
jboxName0 db "1. Keygen - Tenebre",0
|
||||
jboxName1 db "2. Keygen - Hareklavit",0
|
||||
jboxName2 db "3. Keygen - Ladikerfos",0
|
||||
jboxName3 db "4. Keygen - Tilaskarot",0
|
||||
jboxName4 db "5. Mick Gordon - BFG",0
|
||||
jboxName5 db "6. Mick Gordon - Rip",0
|
||||
jboxName6 db "7. Mick Gordon - Doom",0
|
||||
jboxName7 db "8. Hakari Dance (Ost)",0
|
||||
jboxName8 db "9. TF2 - Victory",0
|
||||
; "0. [Âûêëþ÷èòü çâóê]"
|
||||
jboxName9 db 48,46,32,91,194,251,234,235,254,247,232,242,252,32,231,226,243,234,93,0
|
||||
|
||||
jboxTrackNames dd OFFSET jboxName0, OFFSET jboxName1, OFFSET jboxName2, OFFSET jboxName3
|
||||
dd OFFSET jboxName4, OFFSET jboxName5, OFFSET jboxName6, OFFSET jboxName7
|
||||
dd OFFSET jboxName8, OFFSET jboxName9
|
||||
|
||||
jboxTitle db "ÌÓÇÛÊÀËÜÍÛÉ ÀÂÒÎÌÀÒ",0
|
||||
jboxClose db "ÂÛÕÎÄ [ESC]",0
|
||||
jboxStatusPlaying db "ÑÅÉ×ÀÑ ÈÃÐÀÅÒ:",0
|
||||
jboxStatusStopped db "ÌÓÇÛÊÀ ÂÛÊËÞ×ÅÍÀ",0
|
||||
jboxCursor db "> ",0
|
||||
jboxPlayingTag db " [ÈÃÐÀÅÒ]",0
|
||||
jboxHelp1 db "ÑÒÐÅËÊÈ / 0-9: Âûáîð ENTER: Âêëþ÷èòü",0
|
||||
jboxHelp2 db "S: Ñòîï R: Ñëó÷àéíûé ESC:  çàë",0
|
||||
; Top Digital LCD Display Slots
|
||||
jboxLcdPlay db 200,195,208,192,197,210,0 ; "ÈÃÐÀÅÒ"
|
||||
jboxLcdStop db 209,210,206,207,0 ; "ÑÒÎÏ"
|
||||
jboxLcdExit db 194,219,213,206,196,0 ; "ÂÛÕÎÄ"
|
||||
|
||||
; CRT Monitor Screen Text
|
||||
jboxHdrNow db 209,197,201,215,192,209,58,0 ; "ÑÅÉ×ÀÑ:"
|
||||
jboxHdrStop db 209,210,192,210,211,209,58,32,206,209,210,192,205,206,194,203,197,205,0 ; "ÑÒÀÒÓÑ: ÎÑÒÀÍÎÂËÅÍ"
|
||||
jboxCursor db ">",0
|
||||
jboxTagPlay db "[>]",0
|
||||
; "ENTER:Ïóñê S:Ñòîï R:Ìèêñ"
|
||||
jboxFooterHelp db 69,78,84,69,82,58,207,243,241,234,32,32,83,58,209,242,238,239,32,32,82,58,204,232,234,241,0
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ def test_code_structure():
|
|||
assert "MODE_JACKBOX equ 28" in data_inc
|
||||
assert "INTERACT_JACKBOX equ 48" in data_inc
|
||||
assert "JACKBOX_X equ FP_1*306/10" in data_inc
|
||||
assert "JACKBOX_Y equ 25*FP_1" in data_inc
|
||||
assert "JACKBOX_Y equ FP_1*235/10" in data_inc
|
||||
assert "MATERIAL_JACKBOX_BACK equ 163" in data_inc
|
||||
|
||||
# Check procs
|
||||
|
|
|
|||
|
|
@ -251,14 +251,47 @@ def render_scene(cam_x, cam_y, cam_angle, out_path):
|
|||
draw_pool_side(0, int(26.0*FP_1), int(24.0*FP_1), int(26.0*FP_1), 0, int(0.85*FP_1))
|
||||
draw_pool_side(0, int(28.0*FP_1), int(24.0*FP_1), int(26.0*FP_1), 0, int(0.85*FP_1))
|
||||
|
||||
# 2. Solid Rectangular Jukebox Cabinet (at East wall, next to billiards table!)
|
||||
# 2. Wall Art / Painting 116 on East Wall: X = 30.98m, Y in [25.0m .. 26.5m], Z in [1.0m .. 2.0m]
|
||||
def draw_painting(axis, coord, lo, hi, z0, z1, slot):
|
||||
for col in range(SCREEN_W):
|
||||
ray_dir = cityRayX[col] if axis == 0 else cityRayY[col]
|
||||
if abs(ray_dir) < 256:
|
||||
continue
|
||||
orig = playerX if axis == 0 else playerY
|
||||
num = (coord - orig)
|
||||
depth = (num << 16) // ray_dir
|
||||
if depth <= 4096 or depth >= zBuffer[col]:
|
||||
continue
|
||||
along = playerY + ((depth * cityRayY[col]) >> 16) if axis == 0 else playerX + ((depth * cityRayX[col]) >> 16)
|
||||
if along < lo or along >= hi:
|
||||
continue
|
||||
top = (HALL_STANDING_EYE - z1) * SCREEN_H // depth + HALF_H
|
||||
bottom = (HALL_STANDING_EYE - z0) * SCREEN_H // depth + HALF_H
|
||||
span = bottom - top
|
||||
if span <= 0:
|
||||
continue
|
||||
r_start = max(0, top)
|
||||
r_end = min(SCREEN_H, bottom)
|
||||
span_along = hi - lo
|
||||
tx = int((along - lo) * 128 / span_along) % 128
|
||||
shade = max(40, min(255, 255 - (depth >> 12)))
|
||||
for row in range(r_start, r_end):
|
||||
ty = int((row - top) * 128 / span) % 128
|
||||
r, g, b, a = get_tex_pixel(slot, tx, ty)
|
||||
if depth < depthBuffer[row * SCREEN_W + col]:
|
||||
depthBuffer[row * SCREEN_W + col] = depth
|
||||
screen_pixels[row * SCREEN_W + col] = ((r * shade) >> 8, (g * shade) >> 8, (b * shade) >> 8)
|
||||
|
||||
draw_painting(0, int(30.98 * FP_1), int(25.0 * FP_1), int(26.5 * FP_1), FP_1, 2 * FP_1, 116)
|
||||
|
||||
# 3. Solid Rectangular Jukebox Cabinet (at East wall, Y = 23.5m, clearing Painting 116!)
|
||||
# Depth: X in [30.40m .. 30.95m] (back against East wall at 31.0m)
|
||||
# Width: Y in [24.575m .. 25.425m] (centered at Y = 25.0m)
|
||||
# Width: Y in [23.075m .. 23.925m] (centered at Y = 23.5m)
|
||||
# Height: Z in [0 .. 1.85m]
|
||||
x0 = int(30.40 * FP_1)
|
||||
x1 = int(30.95 * FP_1)
|
||||
y0 = int(24.575 * FP_1)
|
||||
y1 = int(25.425 * FP_1)
|
||||
y0 = int(23.075 * FP_1)
|
||||
y1 = int(23.925 * FP_1)
|
||||
zHigh = int(1.85 * FP_1)
|
||||
|
||||
# Back Face (against wall: X = x1) - Frame 2
|
||||
|
|
@ -277,11 +310,11 @@ def render_scene(cam_x, cam_y, cam_angle, out_path):
|
|||
|
||||
if __name__ == '__main__':
|
||||
# 1. Front View: Standing near billiards at (26.0, 25.0) looking East (angle=0) past table at Jukebox
|
||||
render_scene(26.0, 25.0, 0, DOCS_DIR / 'jukebox_3d_front.png')
|
||||
render_scene(26.0, 24.5, 0, DOCS_DIR / 'jukebox_3d_front.png')
|
||||
# 2. Angle View: Standing at (27.5, 22.5) looking South-East (angle=480) at pool table and Jukebox
|
||||
render_scene(27.5, 22.5, 480, DOCS_DIR / 'jukebox_3d_angle.png')
|
||||
render_scene(27.5, 21.0, 128, DOCS_DIR / 'jukebox_3d_angle.png')
|
||||
# 3. Close-up View: Standing at (29.2, 25.0) looking East (angle=0) right at Jukebox
|
||||
render_scene(29.2, 25.0, 0, DOCS_DIR / 'jukebox_3d_close.png')
|
||||
render_scene(29.2, 23.5, 0, DOCS_DIR / 'jukebox_3d_close.png')
|
||||
# 4. Side View: Standing at (30.0, 27.5) looking North (angle=384) at South side of Jukebox
|
||||
render_scene(30.0, 27.5, 384, DOCS_DIR / 'jukebox_3d_side.png')
|
||||
render_scene(30.6, 25.5, 768, DOCS_DIR / 'jukebox_3d_side.png')
|
||||
print('All Jukebox 3D preview frames rendered to docs/previews_minigames/!')
|
||||
|
|
|
|||