feat(jackbox): use terminal wooden cabinet side panels (material 121) for Jukebox flanks

This commit is contained in:
Игорь Федосеев 2026-10-25 17:21:40 +03:00
parent 7c262a15ad
commit 4c2428c367
9 changed files with 56 additions and 8 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

BIN
poker.exe

Binary file not shown.

BIN
poker.obj

Binary file not shown.

View file

@ -66,9 +66,9 @@ DrawJackboxCabinet3D PROC uses ebx esi edi wx:DWORD, wy:DWORD
; 1. Back Face (against East wall: X = x1)
invoke DrawCityVertical3D, 0, x1, y0, y1, 0, FP_1*37/20, MATERIAL_JACKBOX_BACK
; 2. North Side (Y = y0)
; 2. North Side (Y = y0) - Authentic wooden terminal cabinet panel with brass trim
invoke DrawCityVertical3D, 1, y0, x0, x1, 0, FP_1*37/20, MATERIAL_JACKBOX_SIDE
; 3. South Side (Y = y1)
; 3. South Side (Y = y1) - Authentic wooden terminal cabinet panel with brass trim
invoke DrawCityVertical3D, 1, y1, x0, x1, 0, FP_1*37/20, MATERIAL_JACKBOX_SIDE
; 4. Front Face (facing West towards billiards: X = x0)
invoke DrawCityVertical3D, 0, x0, y0, y1, 0, FP_1*37/20, MATERIAL_JACKBOX_FRONT

View file

@ -10,7 +10,7 @@ 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 121
MATERIAL_JACKBOX_BACK equ 163
LoadJackboxArt3D PROTO

View file

@ -65,6 +65,7 @@ def test_code_structure():
assert "INTERACT_JACKBOX equ 48" in data_inc
assert "JACKBOX_X equ FP_1*306/10" in data_inc
assert "JACKBOX_Y equ FP_1*235/10" in data_inc
assert "MATERIAL_JACKBOX_SIDE equ 121" in data_inc
assert "MATERIAL_JACKBOX_BACK equ 163" in data_inc
# Check procs

View file

@ -59,6 +59,16 @@ magic, jw, jh, jframes, jlen = struct.unpack('<4s4I', jackbox_raw[:20])
assert magic == b'ANM1' and (jw, jh, jframes) == (256, 512, 3)
jpixels = jackbox_raw[20:]
# 4. Load Terminals Art pack (ANM1) for authentic wooden side panels (Frame 3)
term_raw = open(REPO_ROOT / 'assets/animations/hall/terminals-v2.bin', 'rb').read()
tmagic, tw, th, tframes, tlen = struct.unpack('<4s4I', term_raw[:20])
tpixels = term_raw[20:]
def get_terminal_pixel(frame, tx, ty):
idx = (frame * tw * th + ty * tw + tx) * 4
b, g, r, a = tpixels[idx:idx+4]
return (r, g, b, a)
def get_jackbox_pixel(frame, tx, ty):
idx = frame * (jw * jh * 4) + (ty * jw + tx) * 4
b, g, r, a = jpixels[idx:idx+4]
@ -282,6 +292,43 @@ def render_scene(cam_x, cam_y, cam_angle, out_path):
depthBuffer[row * SCREEN_W + col] = depth
screen_pixels[row * SCREEN_W + col] = ((r * shade) >> 8, (g * shade) >> 8, (b * shade) >> 8)
def draw_term_vert(axis, coord, lo, hi, zLow, zHigh, frame_idx):
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
span_along = hi - lo
srcX = int((along - lo) * tw / span_along)
if srcX < 0 or srcX >= tw:
continue
top = (HALL_STANDING_EYE - zHigh) * SCREEN_H // depth + HALF_H
bottom = (HALL_STANDING_EYE - zLow) * SCREEN_H // depth + HALF_H
span = bottom - top
if span <= 0:
continue
stepY = (th << 16) // span
r_start = max(0, top)
r_end = min(SCREEN_H, bottom)
curY = (r_start - top) * stepY
shade = max(40, min(255, 255 - (depth >> 12)))
for row in range(r_start, r_end):
srcY = (curY >> 16)
curY += stepY
if srcY < 0 or srcY >= th:
continue
r, g, b, a = get_terminal_pixel(frame_idx, srcX, srcY)
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!)
@ -296,10 +343,10 @@ def render_scene(cam_x, cam_y, cam_angle, out_path):
# Back Face (against wall: X = x1) - Frame 2
draw_vert(0, x1, y0, y1, 0, zHigh, 2)
# North Side (Y = y0) - Frame 1
draw_vert(1, y0, x0, x1, 0, zHigh, 1)
# South Side (Y = y1) - Frame 1
draw_vert(1, y1, x0, x1, 0, zHigh, 1)
# North Side (Y = y0) - Authentic terminal wooden panel (Frame 3)
draw_term_vert(1, y0, x0, x1, 0, zHigh, 3)
# South Side (Y = y1) - Authentic terminal wooden panel (Frame 3)
draw_term_vert(1, y1, x0, x1, 0, zHigh, 3)
# Front Face (facing West towards billiards table: X = x0) - Frame 0
draw_vert(0, x0, y0, y1, 0, zHigh, 0)
@ -312,7 +359,7 @@ 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, 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, 21.0, 128, DOCS_DIR / 'jukebox_3d_angle.png')
render_scene(28.8, 25.0, 960, 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, 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