Skip to content

Commit 3b030cd

Browse files
Use DEC Rainbow font and add blinking cursor
1 parent 9a93583 commit 3b030cd

File tree

4 files changed

+60
-36664
lines changed

4 files changed

+60
-36664
lines changed

BmPlus_Rainbow100_re_80.otb

30.4 KB
Binary file not shown.

LICENSE.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,17 @@ know.
3333
[1]: https://simondlevy.academic.wlu.edu/files/software/kbhit.py
3434
[2]: https://www.gnu.org/licenses/lgpl-3.0.html
3535

36-
## Terminus
36+
## Rainbow100 font
3737

3838
```
39-
ter-u20n.bdf
39+
BmPlus_Rainbow100_re_80.otb
4040
```
4141

42-
The [Terminus][3] font is copyright its creators and used under the terms of
43-
the [SIL Open Font License][4].
42+
The [Rainbow100][3] font is by VileR and used under the terms of the Creative
43+
Commons [Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)][4] license.
4444

45-
[3]: http://terminus-font.sourceforge.net/
46-
[4]: http://scripts.sil.org/OFL
45+
[3]: https://int10h.org/oldschool-pc-fonts/fontlist/font?rainbow100_re_80
46+
[4]: https://creativecommons.org/licenses/by-sa/4.0/
4747

4848
## 8080/8085 CPU Exerciser
4949

cpm.py

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@
3030

3131
import argparse
3232
import os
33+
import time
3334
from typing import Dict, List, Optional, Tuple
3435

3536
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = '1'
3637
import pygame
3738
from pygame.constants import KEYDOWN, KMOD_CTRL, KMOD_SHIFT, QUIT
38-
from pygame.font import Font
39+
from pygame.freetype import Font
3940
from pygame.rect import Rect
4041
from pygame.surface import Surface
4142

@@ -204,9 +205,13 @@ def __init__(self, disk_images: List[str] = []):
204205
self.esc_sequence: bytes = b''
205206

206207
pygame.init()
207-
pygame.display.set_caption('8080 Emulator')
208-
self.screen: Surface = pygame.display.set_mode((80 * 10 + 10, 24 * 20 + 10))
209-
self.font: Font = pygame.font.Font('ter-u20n.bdf', 20)
208+
pygame.display.set_caption('CP/M')
209+
pygame.key.set_repeat(1000, 100)
210+
211+
self.screen: Surface = pygame.display.set_mode(
212+
(80 * 10 + 2 * self.margin, 24 * 20 + 2 * self.margin))
213+
self.font: Font = Font('BmPlus_Rainbow100_re_80.otb', 24)
214+
self.blink_rate: int = 750
210215

211216

212217
def putch(self, ch: int) -> None:
@@ -253,20 +258,50 @@ def putch(self, ch: int) -> None:
253258

254259

255260
def render_buffer(self) -> List[Tuple[Surface, Rect]]:
256-
img = self.font.render('█', False, self.foreground)
257-
col = self.cursor % 80
258-
row = self.cursor // 80
259-
rect = img.get_rect()
260-
rect.topleft = (col * 10 + self.margin, row * 20 + self.margin)
261-
rect.size = img.get_size()
262-
blits = [(img, rect)]
263-
264-
for row in range(24):
265-
img = self.font.render(bytes(self.buffer[80*row:80*row+80]), False, self.foreground)
266-
rect = img.get_rect()
261+
cursor_on = (time.time_ns() // 1000000 // self.blink_rate) % 2 == 0
262+
curs_col = self.cursor % 80
263+
curs_row = self.cursor // 80
264+
265+
# Render the cursor
266+
if cursor_on:
267+
surface, rect = self.font.render(bytes([self.buffer[80*curs_row+curs_col]]),
268+
fgcolor=self.background,
269+
bgcolor=self.foreground)
270+
else:
271+
surface, rect = self.font.render(bytes([self.buffer[80*curs_row+curs_col]]),
272+
fgcolor=self.foreground,
273+
bgcolor=self.background)
274+
rect.topleft = (curs_col * 10 + self.margin, curs_row * 20 + self.margin)
275+
rect.size = surface.get_size()
276+
blits = [(surface, rect)]
277+
278+
# Render rows up to the cursor row
279+
for row in range(0, curs_row):
280+
surface, rect = self.font.render(bytes(self.buffer[80*row:80*row+80]),
281+
fgcolor=self.foreground)
282+
rect.topleft = (self.margin, row * 20 + self.margin)
283+
rect.size = surface.get_size()
284+
blits += [(surface, rect)]
285+
286+
# Render the cursor row, but not the cursor
287+
surface, rect = self.font.render(bytes(self.buffer[80*curs_row:80*curs_row+curs_col]),
288+
fgcolor=self.foreground)
289+
rect.topleft = (self.margin, curs_row * 20 + self.margin)
290+
rect.size = surface.get_size()
291+
blits += [(surface, rect)]
292+
surface, rect = self.font.render(bytes(self.buffer[80*curs_row+curs_col+1:80*curs_row+80]),
293+
fgcolor=self.foreground)
294+
rect.topleft = ((curs_col + 1) * 10 + self.margin, curs_row * 20 + self.margin)
295+
rect.size = surface.get_size()
296+
blits += [(surface, rect)]
297+
298+
# Render rows after the cursor row
299+
for row in range(curs_row+1, 24):
300+
surface, rect = self.font.render(bytes(self.buffer[80*row:80*row+80]),
301+
fgcolor=self.foreground)
267302
rect.topleft = (self.margin, row * 20 + self.margin)
268-
rect.size = img.get_size()
269-
blits += [(img, rect)]
303+
rect.size = surface.get_size()
304+
blits += [(surface, rect)]
270305
return blits
271306

272307

@@ -296,7 +331,8 @@ def run(self) -> None:
296331
if 97 <= key <= 122 and event.mod & KMOD_SHIFT: # A-Z
297332
key -= 32
298333
elif event.mod & KMOD_SHIFT: # Other
299-
key = self.shift_keymap[key]
334+
if key in self.shift_keymap.keys():
335+
key = self.shift_keymap[key]
300336
elif 97 <= key <= 122 and event.mod & KMOD_CTRL: # ^A - ^Z
301337
key -= 96
302338
vm.io.input_buffer += bytes([key])

0 commit comments

Comments
 (0)