diff --git a/build/graphics/poker.exe b/build/graphics/poker.exe index 0a16790..f91d180 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 e70d1f2..e1e78d6 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_front.png b/docs/previews_minigames/jukebox_3d_front.png index d7fffde..29906ab 100644 Binary files a/docs/previews_minigames/jukebox_3d_front.png and b/docs/previews_minigames/jukebox_3d_front.png differ diff --git a/poker.exe b/poker.exe index 0a16790..f91d180 100644 Binary files a/poker.exe and b/poker.exe differ diff --git a/poker.obj b/poker.obj index 43940d5..46e5782 100644 Binary files a/poker.obj and b/poker.obj differ diff --git a/src_graphics/jackbox.inc b/src_graphics/jackbox.inc index acebaee..6e23c26 100644 --- a/src_graphics/jackbox.inc +++ b/src_graphics/jackbox.inc @@ -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 diff --git a/src_graphics/jackbox_data.inc b/src_graphics/jackbox_data.inc index d9ba706..3aef868 100644 --- a/src_graphics/jackbox_data.inc +++ b/src_graphics/jackbox_data.inc @@ -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 diff --git a/tools/tests/check_jackbox.py b/tools/tests/check_jackbox.py index 2568539..90eb59b 100644 --- a/tools/tests/check_jackbox.py +++ b/tools/tests/check_jackbox.py @@ -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 diff --git a/tools/tests/test_jukebox_render_all_angles.py b/tools/tests/test_jukebox_render_all_angles.py index 5f4bbb2..96fed14 100644 --- a/tools/tests/test_jukebox_render_all_angles.py +++ b/tools/tests/test_jukebox_render_all_angles.py @@ -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