fix(jackbox): realign UI strictly within CRT monitor sprite and clear wall painting

This commit is contained in:
Игорь Федосеев 2026-10-25 17:07:05 +03:00
parent 6bf2a2885c
commit 7c262a15ad
11 changed files with 434 additions and 315 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 38 KiB

BIN
poker.exe

Binary file not shown.

BIN
poker.obj

Binary file not shown.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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/!')