Skip to content

Commit 87c41a7

Browse files
authored
Add command line color specification. (#38)
1 parent b9e1be7 commit 87c41a7

File tree

4 files changed

+63
-15
lines changed

4 files changed

+63
-15
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
4. [Clip Quirks](#clip-quirks)
2626
5. [Logic Quirks](#logic-quirks)
2727
5. [Memory Size](#memory-size)
28+
6. [Colors](#colors)
2829
5. [Customization](#customization)
2930
1. [Keys](#keys)
3031
2. [Debug Keys](#debug-keys)
@@ -304,6 +305,25 @@ but this behavior can be controlled with the `--mem_size` flag. Valid options ar
304305
`64K` or `4K` for historical purposes.
305306
306307
308+
### Colors
309+
310+
The original Chip8 language specification called for pixels to be turned on or
311+
off. It did not specify what color the pixel states had to be. The emulator
312+
lets the user specify what colors they want to use when the emulator is running.
313+
Color values are specified by using HTML hex values such as `AABBCC` without the
314+
leading `#`. There are currently 4 color values that can be set:
315+
316+
* `--color_0` specifies the background color. This defaults to `000000`.
317+
* `--color_1` specifies bitplane 1 color. This defaults to `666666`.
318+
* `--color_2` specifies bitplane 2 color. This defaults to `BBBBBB`.
319+
* `--color_3` specifies bitplane 1 and 2 overlap color. This defaults to `FFFFFF`.
320+
321+
For Chip8 and SuperChip 8 programs, only the background color `color_0` (for pixels
322+
turned off) and the bitplane 1 color `color_1` (for pixels turned on) are used.
323+
Only XO Chip programs will use `color_2` and `color_3` when the additional bitplanes
324+
are potentially used.
325+
326+
307327
## Customization
308328
309329
The file `chip8/config.py` contains several variables that can be changed to

chip8/emulator.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ def main_loop(args):
2323
"""
2424
delay_timer_event = 24
2525

26-
screen = Chip8Screen(scale_factor=args.scale)
26+
screen = Chip8Screen(
27+
scale_factor=args.scale,
28+
color_0=args.color_0,
29+
color_1=args.color_1,
30+
color_2=args.color_2,
31+
color_3=args.color_3,
32+
)
2733
screen.init_display()
2834
cpu = Chip8CPU(
2935
screen,

chip8/screen.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,6 @@
1818
# of a pixel.
1919
SCREEN_DEPTH = 8
2020

21-
# The colors of the pixels to draw. The Chip 8 supports two colors: 0 (off)
22-
# and 1 (on). The format of the colors is in RGBA format.
23-
PIXEL_COLORS = {
24-
0: Color(0, 0, 0, 255),
25-
1: Color(250, 250, 250, 255)
26-
}
27-
2821
# C L A S S E S ###############################################################
2922

3023

@@ -34,7 +27,14 @@ class Chip8Screen:
3427
with 2 colors. In this emulator, this translates to color 0 (off) and color
3528
1 (on).
3629
"""
37-
def __init__(self, scale_factor):
30+
def __init__(
31+
self,
32+
scale_factor,
33+
color_0="000000",
34+
color_1="666666",
35+
color_2="BBBBBB",
36+
color_3="FFFFFF"
37+
):
3838
"""
3939
Initializes the main screen. The scale factor is used to modify
4040
the size of the main screen, since the original resolution of the
@@ -47,6 +47,12 @@ def __init__(self, scale_factor):
4747
self.scale_factor = scale_factor
4848
self.surface = None
4949
self.mode = SCREEN_MODE_NORMAL
50+
self.pixel_colors = {
51+
0: Color(f"#{color_0}"),
52+
1: Color(f"#{color_1}"),
53+
2: Color(f"#{color_2}"),
54+
3: Color(f"#{color_3}"),
55+
}
5056

5157
def init_display(self):
5258
"""
@@ -81,7 +87,7 @@ def draw_pixel(self, x_pos, y_pos, turn_on):
8187
x_base = (x_pos * mode_scale) * self.scale_factor
8288
y_base = (y_pos * mode_scale) * self.scale_factor
8389
draw.rect(self.surface,
84-
PIXEL_COLORS[pixel_color],
90+
self.pixel_colors[pixel_color],
8591
(x_base, y_base, mode_scale * self.scale_factor, mode_scale * self.scale_factor))
8692

8793
def get_pixel(self, x_pos, y_pos):
@@ -97,7 +103,7 @@ def get_pixel(self, x_pos, y_pos):
97103
x_scale = (x_pos * mode_scale) * self.scale_factor
98104
y_scale = (y_pos * mode_scale) * self.scale_factor
99105
pixel_color = self.surface.get_at((x_scale, y_scale))
100-
return pixel_color == PIXEL_COLORS[1]
106+
return pixel_color == self.pixel_colors[1]
101107

102108
def get_width(self):
103109
"""
@@ -119,7 +125,7 @@ def clear_screen(self):
119125
"""
120126
Turns off all the pixels on the screen (writes color 0 to all pixels).
121127
"""
122-
self.surface.fill(PIXEL_COLORS[0])
128+
self.surface.fill(self.pixel_colors[0])
123129

124130
@staticmethod
125131
def update():
@@ -152,7 +158,7 @@ def scroll_down(self, num_lines):
152158
mode_scale = 1 if self.mode == SCREEN_MODE_EXTENDED else 2
153159
actual_lines = num_lines * mode_scale * self.scale_factor
154160
self.surface.scroll(0, actual_lines)
155-
self.surface.fill(PIXEL_COLORS[0], (0, 0, self.width * mode_scale * self.scale_factor, actual_lines))
161+
self.surface.fill(self.pixel_colors[0], (0, 0, self.width * mode_scale * self.scale_factor, actual_lines))
156162
self.update()
157163

158164
def scroll_left(self):
@@ -163,7 +169,7 @@ def scroll_left(self):
163169
actual_lines = 4 * mode_scale * self.scale_factor
164170
left = (self.width * mode_scale * self.scale_factor) - actual_lines
165171
self.surface.scroll(-actual_lines, 0)
166-
self.surface.fill(PIXEL_COLORS[0], (left, 0, actual_lines, self.height * mode_scale * self.scale_factor))
172+
self.surface.fill(self.pixel_colors[0], (left, 0, actual_lines, self.height * mode_scale * self.scale_factor))
167173
self.update()
168174

169175
def scroll_right(self):
@@ -173,7 +179,7 @@ def scroll_right(self):
173179
mode_scale = 1 if self.mode == SCREEN_MODE_EXTENDED else 2
174180
actual_lines = 4 * mode_scale * self.scale_factor
175181
self.surface.scroll(actual_lines, 0)
176-
self.surface.fill(PIXEL_COLORS[0], (0, 0, actual_lines, self.height * mode_scale * self.scale_factor))
182+
self.surface.fill(self.pixel_colors[0], (0, 0, actual_lines, self.height * mode_scale * self.scale_factor))
177183
self.update()
178184

179185
# E N D O F F I L E ########################################################

yac8e.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,22 @@ def parse_arguments():
6464
"--trace", help="print registers and instructions to STDOUT",
6565
action="store_true", dest="trace"
6666
)
67+
parser.add_argument(
68+
"--color_0", help="the hex color to use for the background (default=000000)",
69+
dest="color_0", default="000000"
70+
)
71+
parser.add_argument(
72+
"--color_1", help="the hex color to use for bitplane 1 (default=666666)",
73+
dest="color_1", default="666666"
74+
)
75+
parser.add_argument(
76+
"--color_2", help="the hex color to use for bitplane 2 (default=BBBBBB)",
77+
dest="color_2", default="BBBBBB"
78+
)
79+
parser.add_argument(
80+
"--color_3", help="the hex color to use for bitplane overlaps (default=FFFFFF)",
81+
dest="color_3", default="FFFFFF"
82+
)
6783
return parser.parse_args()
6884

6985

0 commit comments

Comments
 (0)