diff --git a/build/graphics/poker.exe b/build/graphics/poker.exe index 33daddb..0a16790 100644 Binary files a/build/graphics/poker.exe and b/build/graphics/poker.exe differ diff --git a/docs/previews_minigames/jukebox_3d_angle.png b/docs/previews_minigames/jukebox_3d_angle.png index 1c34bb1..e70d1f2 100644 Binary files a/docs/previews_minigames/jukebox_3d_angle.png and b/docs/previews_minigames/jukebox_3d_angle.png differ diff --git a/docs/previews_minigames/jukebox_3d_close.png b/docs/previews_minigames/jukebox_3d_close.png index ba20513..147a9b7 100644 Binary files a/docs/previews_minigames/jukebox_3d_close.png and b/docs/previews_minigames/jukebox_3d_close.png differ diff --git a/docs/previews_minigames/jukebox_3d_front.png b/docs/previews_minigames/jukebox_3d_front.png index e26fbcd..d7fffde 100644 Binary files a/docs/previews_minigames/jukebox_3d_front.png and b/docs/previews_minigames/jukebox_3d_front.png differ diff --git a/docs/previews_minigames/jukebox_3d_side.png b/docs/previews_minigames/jukebox_3d_side.png index 22682a8..4b37b7c 100644 Binary files a/docs/previews_minigames/jukebox_3d_side.png and b/docs/previews_minigames/jukebox_3d_side.png differ diff --git a/poker.exe b/poker.exe index 33daddb..0a16790 100644 Binary files a/poker.exe and b/poker.exe differ diff --git a/poker.obj b/poker.obj index 17fcbb9..43940d5 100644 Binary files a/poker.obj and b/poker.obj differ diff --git a/src_graphics/jackbox.inc b/src_graphics/jackbox.inc index 75a9926..acebaee 100644 --- a/src_graphics/jackbox.inc +++ b/src_graphics/jackbox.inc @@ -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 diff --git a/src_graphics/jackbox_data.inc b/src_graphics/jackbox_data.inc index 6eae614..d9ba706 100644 --- a/src_graphics/jackbox_data.inc +++ b/src_graphics/jackbox_data.inc @@ -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 diff --git a/tools/tests/check_jackbox.py b/tools/tests/check_jackbox.py index fe2622c..2568539 100644 --- a/tools/tests/check_jackbox.py +++ b/tools/tests/check_jackbox.py @@ -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 diff --git a/tools/tests/test_jukebox_render_all_angles.py b/tools/tests/test_jukebox_render_all_angles.py index e6364e3..5f4bbb2 100644 --- a/tools/tests/test_jukebox_render_all_angles.py +++ b/tools/tests/test_jukebox_render_all_angles.py @@ -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/!')