Implement lightning flash in apple_io.py
authorNick Downing <nick@ndcode.org>
Sun, 22 May 2022 12:00:25 +0000 (22:00 +1000)
committerNick Downing <nick@ndcode.org>
Sun, 22 May 2022 12:00:25 +0000 (22:00 +1000)
apple_io.py

index 42faa61..9bfa047 100644 (file)
@@ -182,6 +182,13 @@ NICK_DURH = 0x30b
 NICK_FREQL = 0x30d
 NICK_FREQH = 0x314
 
+# see lemonade_flash_patched.lst
+FLASH_INIT = 0x3600
+FLASH_INIT_PATCHED = 0x95ef
+FLASH_EXECUTE = 0x3603
+FLASH_EXECUTE_PATCHED = 0x9586
+flash_color0 = 0
+
 # command line
 BEEP_STYLE_ALSA = 0
 BEEP_STYLE_VT100 = 1
@@ -203,6 +210,7 @@ mem = {
   ZP_WNDBTM: 24,
   ZP_CH: 0,
   ZP_CV: 23, # just a likely value (depends on previous terminal activity)
+  ZP_COLOR: 0,
   ZP_LOMEM: 4,
   ZP_LOMEM + 1: 8,
   ZP_HIMEM: 0,
@@ -214,7 +222,6 @@ mem = {
   NICK_FREQL: 0,
   NICK_FREQH: 0,
 }
-gr_color = 0
 gr_mem = [[0 for j in range(40)] for i in range(40)]
 
 def init():
@@ -398,6 +405,8 @@ def poke(addr, data):
     write(f'\x1b[s\x1b[{mem[ZP_WNDTOP] + 1:d};{mem[ZP_WNDBTM]:d}r\x1b[u')
 
 def call(addr):
+  global flash_color0
+
   addr &= 0xffff
   if addr == NICK_REST or addr == NICK_TONE:
     # for lemonade_patched, see test/lemonade_tone_nick.py
@@ -426,12 +435,30 @@ def call(addr):
       2.50702246e-03 + 2.50310997e-03 / period_count
     )
     tone(cycles / duration, duration)
-  elif addr == 0x3600 or addr == 0x95ef:
+  elif addr == FLASH_INIT or addr == FLASH_INIT_PATCHED:
     # for lemonade, lighting (init)
-    pass
-  elif addr == 0x3603 or addr == 0x9586:
+    flash_color0 = mem[ZP_COLOR]
+  elif addr == FLASH_EXECUTE or addr == FLASH_EXECUTE_PATCHED:
     # for lemonade, lightning (execute)
-    pass
+    time.sleep(.02)
+    flash_color1 = mem[ZP_COLOR]
+    for i in range(20):
+      x0 = 40
+      x1 = 0
+      for j in range(40):
+        if gr_mem[i * 2][j] == flash_color0:
+          gr_mem[i * 2][j] = flash_color1
+          if j < x0:
+            x0 = j
+          x1 = j + 1
+        if gr_mem[i * 2 + 1][j] == flash_color0:
+          gr_mem[i * 2 + 1][j] = flash_color1
+          if j < x0:
+            x0 = j
+          x1 = j + 1
+      if x1 > x0:
+        gr_update(x0, i, x1, i + 1)
+    flash_color0 = flash_color1
   elif addr == ROM_CLREOP:
     clreop()
   elif addr == ROM_BELL2:
@@ -502,11 +529,10 @@ def gr_update(x0, y0, x1, y1):
   write(f'\x1b8') # restore all attributes (in case in INVERSE/FLASH mode)
 
 def color(n):
-  global gr_color
-  gr_color = n
+  mem[ZP_COLOR] = n
 
 def plot(x, y):
-  gr_mem[y][x] = gr_color
+  gr_mem[y][x] = mem[ZP_COLOR]
   y >>= 1
   gr_update(x, y, x + 1, y + 1)
 
@@ -514,7 +540,7 @@ def hlin(x0, x1, y):
   if x1 < x0:
     x0, x1 = x1, x0
   for x in range(x0, x1 + 1):
-    gr_mem[y][x] = gr_color
+    gr_mem[y][x] = mem[ZP_COLOR]
   y >>= 1
   gr_update(x0, y, x1 + 1, y + 1)
 
@@ -522,7 +548,7 @@ def vlin(y0, y1, x):
   if y1 < y0:
     y0, y1 = y1, y0
   for y in range(y0, y1 + 1):
-    gr_mem[y][x] = gr_color
+    gr_mem[y][x] = mem[ZP_COLOR]
   gr_update(x, y0 >> 1, x + 1, (y1 >> 1) + 1)
 
 def usr(n):