From 4140bd7034bd4bb54107603ebb40a044be1f3407 Mon Sep 17 00:00:00 2001 From: "Raimon @ quifisraimon" Date: Tue, 15 Sep 2026 09:54:04 +0200 Subject: [PATCH] - [NEW] [TIA] NUSIZ0, NUSIZ1, COLUP0, COLUP1, COLUPF, COLUPBK - [NEW] Paleta NTSC --- tia.cpp | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/tia.cpp b/tia.cpp index 23d82b7..beddaf4 100644 --- a/tia.cpp +++ b/tia.cpp @@ -2,6 +2,43 @@ namespace tia { + // Standard Stella NTSC Palette (ARGB format: 0xFFRRGGBB) + // Indexed by: (COLUx >> 1) & 0x7F + const uint32_t NTSC_PALETTE[128] = { + // Hue $0 (Grayscale / Monochromatic) + 0xFF000000, 0xFF282828, 0xFF444444, 0xFF5C5C5C, 0xFF707070, 0xFF848484, 0xFF989898, 0xFFACACAC, + // Hue $1 (Gold / Yellow-Orange) + 0xFF4C2C00, 0xFF684400, 0xFF845C00, 0xFF9C7400, 0xFFB48C00, 0xFFCCA414, 0xFFE4BC34, 0xFFFCD454, + // Hue $2 (Orange / Red-Orange) + 0xFF541800, 0xFF742C00, 0xFF904400, 0xFFA85C00, 0xFFC07400, 0xFFD88C00, 0xFFF0A420, 0xFFFFBC40, + // Hue $3 (Red-Orange) + 0xFF580C00, 0xFF781C00, 0xFF943000, 0xFFB04800, 0xFFC86000, 0xFFE07808, 0xFFF89028, 0xFFFFA848, + // Hue $4 (Magenta / Red-Violet) + 0xFF540420, 0xFF74103C, 0xFF902058, 0xFFAC3474, 0xFFC4488C, 0xFFDC5CA8, 0xFFF474C0, 0xFFFF8CD8, + // Hue $5 (Purple / Violet) + 0xFF440454, 0xFF601074, 0xFF7C2090, 0xFF9434AC, 0xFFAC48C4, 0xFFC45CDC, 0xFFDC74F4, 0xFFF48CFF, + // Hue $6 (Blue-Violet / Indigo) + 0xFF2C0874, 0xFF441494, 0xFF5C24B0, 0xFF7438CC, 0xFF8C4CE4, 0xFFA460FC, 0xFFBC78FF, 0xFFD490FF, + // Hue $7 (Blue) + 0xFF101480, 0xFF2424A0, 0xFF3C38BC, 0xFF504CD4, 0xFF6860EC, 0xFF8078FF, 0xFF9890FF, 0xFFB0A8FF, + // Hue $8 (Blue-Cyan) + 0xFF002074, 0xFF003494, 0xFF0C48B0, 0xFF2060CC, 0xFF3474E4, 0xFF4C8CFC, 0xFF64A4FF, 0xFF7CBCFF, + // Hue $9 (Cyan / Blue-Green) + 0xFF002854, 0xFF004074, 0xFF005490, 0xFF006CAC, 0xFF1880C4, 0xFF3098DC, 0xFF48B0F4, 0xFF60C8FF, + // Hue $A (Teal / Green-Cyan) + 0xFF00302C, 0xFF004844, 0xFF00605C, 0xFF007874, 0xFF00908C, 0xFF1CA8A4, 0xFF38C0BC, 0xFF54D8D4, + // Hue $B (Green) + 0xFF003408, 0xFF004C18, 0xFF00642C, 0xFF007C40, 0xFF009454, 0xFF14AC6C, 0xFF30C484, 0xFF4CDC9C, + // Hue $C (Yellow-Green) + 0xFF0C3400, 0xFF204C00, 0xFF346400, 0xFF487C00, 0xFF5C9400, 0xFF74AC10, 0xFF8CC428, 0xFFA4DC44, + // Hue $D (Olive Green) + 0xFF243000, 0xFF3C4800, 0xFF546000, 0xFF6C7800, 0xFF849000, 0xFF9CA800, 0xFFB4C018, 0xFFCCC434, + // Hue $E (Brown / Olive-Yellow) + 0xFF3C2C00, 0xFF584000, 0xFF745800, 0xFF8C6C00, 0xFFA48400, 0xFFBC9C00, 0xFFD4B420, 0xFFECC83C, + // Hue $F (Orange-Brown) + 0xFF482400, 0xFF643800, 0xFF805000, 0xFF986400, 0xFFB07C00, 0xFFC89400, 0xFFE0AC28, 0xFFF8C444 + }; + uint8_t collisions[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; float paddle_pos[4] { 0.5f, 0.5f, 0.5f, 0.5f }; @@ -10,6 +47,21 @@ namespace tia bool joy0_button_pressed = false; bool joy1_button_pressed = false; + uint8_t missile0_size = 1; + uint8_t player0_size = 1; + uint8_t player0_num_copies = 1; + uint8_t player0_copies_distance = 0; + uint32_t player0_color = 0x00000000; + + uint8_t missile1_size = 1; + uint8_t player1_size = 1; + uint8_t player1_num_copies = 1; + uint8_t player1_copies_distance = 0; + uint32_t player1_color = 0x00000000; + + uint32_t playfield_color = 0x00000000; + uint32_t background_color = 0x00000000; + uint32_t current_frame_cycles = 0; bool vsync_set = false; @@ -18,6 +70,7 @@ namespace tia bool vblank_dump = false; uint16_t color_clock = 0; + uint16_t current_scanline = 0; bool rdy_low = false; void reset() @@ -30,7 +83,10 @@ namespace tia if (!vblank_dump) current_frame_cycles++; color_clock = (color_clock + 1) % 228; - if (color_clock == 0) rdy_low = false; + if (color_clock == 0) { + rdy_low = false; + current_scanline++; + } // [TODO] Pintar pixels } @@ -92,7 +148,45 @@ namespace tia case 0x03: // RSYNC color_clock = 0; + rdy_low = false; break; + + case 0x004: // NUSIZ0 + missile0_size = 1 << ((value >> 4) & 0x03); + switch (value & 0x07) { + case 0: player0_num_copies = 1; player0_copies_distance = 0; player0_size = 1; break; + case 1: player0_num_copies = 2; player0_copies_distance = 2; player0_size = 1; break; + case 2: player0_num_copies = 2; player0_copies_distance = 4; player0_size = 1; break; + case 3: player0_num_copies = 3; player0_copies_distance = 2; player0_size = 1; break; + case 4: player0_num_copies = 2; player0_copies_distance = 8; player0_size = 1; break; + case 5: player0_num_copies = 1; player0_copies_distance = 0; player0_size = 2; break; + case 6: player0_num_copies = 3; player0_copies_distance = 4; player0_size = 1; break; + case 7: player0_num_copies = 1; player0_copies_distance = 0; player0_size = 4; break; + } + break; + + case 0x005: // NUSIZ1 + missile1_size = 1 << ((value >> 4) & 0x03); + switch (value & 0x07) { + case 0: player1_num_copies = 1; player1_copies_distance = 0; player1_size = 1; break; + case 1: player1_num_copies = 2; player1_copies_distance = 2; player1_size = 1; break; + case 2: player1_num_copies = 2; player1_copies_distance = 4; player1_size = 1; break; + case 3: player1_num_copies = 3; player1_copies_distance = 2; player1_size = 1; break; + case 4: player1_num_copies = 2; player1_copies_distance = 8; player1_size = 1; break; + case 5: player1_num_copies = 1; player1_copies_distance = 0; player1_size = 2; break; + case 6: player1_num_copies = 3; player1_copies_distance = 4; player1_size = 1; break; + case 7: player1_num_copies = 1; player1_copies_distance = 0; player1_size = 4; break; + } + break; + + case 0x06: // COLUP0 + player0_color = NTSC_PALETTE[(value >> 1) & 0x7F]; break; + case 0x07: // COLUP1 + player1_color = NTSC_PALETTE[(value >> 1) & 0x7F]; break; + case 0x08: // COLUPF + playfield_color = NTSC_PALETTE[(value >> 1) & 0x7F]; break; + case 0x09: // COLUBK + background_color = NTSC_PALETTE[(value >> 1) & 0x7F]; break; } }