Name the sound effects, rationalize naming in the other extractors slightly
authorNick Downing <nick@ndcode.org>
Sun, 26 Jun 2022 12:33:13 +0000 (22:33 +1000)
committerNick Downing <nick@ndcode.org>
Tue, 28 Jun 2022 03:21:38 +0000 (13:21 +1000)
disasm/draw_misc_compile.py
disasm/draw_misc_extract.py
disasm/object_defs.inc
disasm/object_extract.py
disasm/shape_compile.py
disasm/shape_extract.py
disasm/star_blazer.txt
emu_65c02/emu_65c02.c

index 4667162..62ce141 100755 (executable)
@@ -63,8 +63,16 @@ with open(out_table_inc, 'w') as fout:
   fout.write(f'draw_misc_table: ; {draw_misc_table:04x}\n')
   dot = draw_misc_table
   for i in range(0x20):
+    value = data[i]['value']
+
+    # entry < 8 (decimal) must be 4 strings of 1 character each
+    # an exception is in the case of null entries which are never drawn
+    assert i >= 8 or (
+      len(value) in [0, 4] and all([len(j['string']) == 1 for j in value])
+    )
+
     addr1 = draw_misc_table + (i + 1) * 0x10
-    for span in data[i]['value']:
+    for span in value:
       x = span['x']
       y = span['y']
       string = span['string']
@@ -75,6 +83,7 @@ with open(out_table_inc, 'w') as fout:
         fout.write(f'\t.db\t{shape:s}\n')
       dot += len(string)
       assert dot <= addr1
+
     if dot < addr1:
       # don't use .ds here, as tiny holes in the .ihx file are annoying
       fout.write('\t.db\t{0:s}\n'.format(','.join(['0'] * (addr1 - dot))))
index 995197c..8375849 100755 (executable)
@@ -94,7 +94,9 @@ data = []
 for i in range(0x20):
   addr0 = draw_misc_table + i * 0x10
   addr1 = draw_misc_table + (i + 1) * 0x10
-  name = draw_misc_entries.get(i)
+  name = f'decimal_{i:d}' if i < 8 else f'entry_{i:02x}'
+  if i in draw_misc_entries:
+    name += '_' + draw_misc_entries[i]
 
   addr = addr0
   value = []
index e57cd82..91988f4 100644 (file)
@@ -388,22 +388,22 @@ UCODE_DRAW_MISC_MASK_5 = 0xa000
 UCODE_DRAW_MISC_MASK_6 = 0xc000
 
 ; sound effect
-UCODE_SOUND_EFFECT_0 = 0x0000
-UCODE_SOUND_EFFECT_1 = 0x0100
-UCODE_SOUND_EFFECT_2 = 0x0200
+UCODE_SOUND_EFFECT_0_SHIP_IMPACT = 0x0000
+UCODE_SOUND_EFFECT_1_BOMBS_EMPTY = 0x0100
+UCODE_SOUND_EFFECT_2_PLAYER_FIRE = 0x0200
 UCODE_SOUND_EFFECT_3 = 0x0300
-UCODE_SOUND_EFFECT_4 = 0x0400
-UCODE_SOUND_EFFECT_5 = 0x0500
-UCODE_SOUND_EFFECT_6 = 0x0600
+UCODE_SOUND_EFFECT_4_TREE_IMPACT = 0x0400
+UCODE_SOUND_EFFECT_5_MISSION_COMPLETE = 0x0500
+UCODE_SOUND_EFFECT_6_MISSION_START = 0x0600
 UCODE_SOUND_EFFECT_7 = 0x0700
-UCODE_SOUND_EFFECT_8 = 0x0800
-UCODE_SOUND_EFFECT_9 = 0x0900
-UCODE_SOUND_EFFECT_A = 0x0a00
-UCODE_SOUND_EFFECT_B = 0x0b00
-UCODE_SOUND_EFFECT_C = 0x0c00
-UCODE_SOUND_EFFECT_D = 0x0d00
-UCODE_SOUND_EFFECT_E = 0x0e00
-UCODE_SOUND_EFFECT_F = 0x0f00
+UCODE_SOUND_EFFECT_8_SUPPLIES_IMPACT = 0x0800
+UCODE_SOUND_EFFECT_9_HELICOPTER_IMPACT = 0x0900
+UCODE_SOUND_EFFECT_A_MISSILE_IMPACT = 0x0a00
+UCODE_SOUND_EFFECT_B_TANK_ENGINE = 0x0b00
+UCODE_SOUND_EFFECT_C_EXPLOSION = 0x0c00
+UCODE_SOUND_EFFECT_D_EXPLOSION = 0x0d00
+UCODE_SOUND_EFFECT_E_EXPLOSION = 0x0e00
+UCODE_SOUND_EFFECT_F_EXPLOSION = 0x0f00
 
 ; the following occur by themselves
 
index f9b9197..3a5f4a4 100755 (executable)
@@ -66,8 +66,8 @@ def disasm_homing(value0):
     j = int(i, 0)
     if j in defs['byte-wide sections']:
       i = defs['byte-wide sections'][j]
-    #elif j in defs['objects']:
-    #  i = defs['objects'][j]
+    elif j in defs['objects']:
+      i = defs['objects'][j]
     value.append(i)
   return value
 
@@ -237,10 +237,12 @@ for i in range(0, len(segments), 2):
   print(f'[{segments[i]:04x}, {segments[i + 1]:04x})')
 
 print('extracting')
-data = [
-  {'name': f'{i:02x}_{objects[i]}' if i in objects else None}
-  for i in range(object0, object1)
-]
+data = []
+for i in range(object0, object1):
+  name = f'object_{i:02x}'
+  if i in objects:
+    name += '_' + objects[i]
+  data.append({'name': name})
 
 for table, (addr, index0, index1, word) in object_tables.items():
   i = bisect.bisect_right(segments, addr) - 1
index c88b7b7..78b8b06 100755 (executable)
@@ -74,11 +74,11 @@ with open(out_index_inc, 'w') as fout:
     table_data = [data[i][table] for i in range(0x100)]
     if table == 'data_ptr' or table == 'size_bytes':
       for i in range(0x100):
-        name = data[i]['name']
-        if name is not None:
+        if data[i]['data'] is not None:
+          name = data[i]['name']
           size_bytes = int(data[i]['size_bytes'], 0)
           if table == 'data_ptr':
-            table_data[i] = 'shape_' + name
+            table_data[i] = name
           if size_bytes:
             width_bytes = int(data[i]['width_bytes'], 0)
             height = int(data[i]['height'], 0)
@@ -95,8 +95,7 @@ print('writing data')
 # used for merging duplicate shape data
 addrs = {}
 for i in range(0x100):
-  name = data[i]['name']
-  if name is not None:
+  if data[i]['name'] is not None:
     addr = int(data[i]['data_ptr'], 0)
     if addr not in addrs:
       addrs[addr] = []
@@ -105,21 +104,21 @@ for i in range(0x100):
 # generate output
 out = []
 for i in range(0x100):
-  name = data[i]['name']
-  if name is not None:
-    value = data[i]['data']
+  data1 = data[i]['data']
+  if data1 is not None:
+    name = data[i]['name']
     addr = int(data[i]['data_ptr'], 0)
     size_bytes = int(data[i]['size_bytes'], 0)
-    text = f'shape_{name:s}: ; {max(addr - 3 * size_bytes, 0):04x}\n'
+    text = f'{name:s}: ; {max(addr - 3 * size_bytes, 0):04x}\n'
 
     # only output data if different from next entry at same address
     same_addr = addrs[addr]
     j = same_addr.index(i) + 1
-    if j >= len(same_addr) or data[same_addr[j]]['data'] != value:
+    if j >= len(same_addr) or data[same_addr[j]]['data'] != data1:
       text += ''.join(
         [
           ''.join(['\t.db\t{0:s}\n'.format(', '.join(k)) for k in j]) + '\n'
-          for j in value
+          for j in data1
         ]
       )
 
index bd84aee..fcc2f5c 100755 (executable)
@@ -63,10 +63,7 @@ with open(addrs_txt) as fin:
         assert len(fields) == 2
         index = int(fields[0], 0)
         name = fields[1]
-        # shape < 8 is a single pixel masked by the shape number
-        # ignore these lines in addrs file unless --pixel requested
-        if index >= 8 or pixel:
-          shapes[index] = name
+        shapes[index] = name
         fields = get_line()
       continue
 
@@ -82,7 +79,12 @@ for i in range(0, len(segments), 2):
   print(f'[{segments[i]:04x}, {segments[i + 1]:04x})')
 
 print('extracting')
-data = [{'name': None} for i in range(0x100)]
+data = []
+for i in range(0x100):
+  name = f'shape_{i:02x}'
+  if i in shapes:
+    name += '_' + shapes[i]
+  data.append({'name': name})
 
 i = 0
 shape_tables1 = list(shape_tables.items())
@@ -106,51 +108,47 @@ while i < len(shape_tables1):
       data[j][table] = str(value)
     i += 1
 
-# do this here so that item ordering is nicer in the json file
 for i in range(0x100):
-  data[i]['data'] = None
-
-for index, name in shapes.items():
-  data[index]['name'] = f'{index:02x}_{name:s}'
-
   # shape < 8 is a single pixel masked by the shape number
   # transform the special data tables for pixel drawing into ordinary data
-  if index < 8:
-    data[index]['data_ptr'] = '0x0000' # make them be compiled first
-    data[index]['width_bytes'] = '2'
-    data[index]['height'] = '1'
-    data[index]['size_bytes'] = '2'
-    data[index]['width'] = '1'
+  data1 = None
+  if pixel and i < 8:
+    data[i]['data_ptr'] = '0x0000' # make them be compiled first
+    data[i]['width_bytes'] = '2'
+    data[i]['height'] = '1'
+    data[i]['size_bytes'] = '2'
+    data[i]['width'] = '1'
 
     data_table_left = pixel_tables['data_table_left']
     data_table_right = pixel_tables['data_table_right']
     mask_table_left = pixel_tables['mask_table_left']
     mask_table_right = pixel_tables['mask_table_right']
-    value = [
+    data1 = [
       [
         [
-          f'0x{intelhex[data_table_left + ((i * 2) % 7)] & intelhex[mask_table_left + index]:02x}',
-          f'0x{intelhex[data_table_right + ((i * 2) % 7)] & intelhex[mask_table_right + index]:02x}'
+          f'0x{intelhex[data_table_left + ((j * 2) % 7)] & intelhex[mask_table_left + i]:02x}',
+          f'0x{intelhex[data_table_right + ((j * 2) % 7)] & intelhex[mask_table_right + i]:02x}'
         ]
       ]
-      for i in range(7)
+      for j in range(7)
     ]
-  else: 
-    addr = int(data[index]['data_ptr'], 0)
-    height = int(data[index]['height'], 0)
-    width_bytes = int(data[index]['width_bytes'], 0)
-    size_bytes = int(data[index]['size_bytes'], 0)
-    value = [
-      [
+  else:
+    addr = int(data[i]['data_ptr'], 0)
+    if addr != 0x5d01: # strange sentinel value for never drawn shape
+      height = int(data[i]['height'], 0)
+      width_bytes = int(data[i]['width_bytes'], 0)
+      size_bytes = int(data[i]['size_bytes'], 0)
+      data1 = [
         [
-          f'0x{intelhex[addr + (i - 3) * size_bytes + j * width_bytes + k]:02x}'
-          for k in range(width_bytes)
+          [
+            f'0x{intelhex[addr + (j - 3) * size_bytes + k * width_bytes + l]:02x}'
+            for l in range(width_bytes)
+          ]
+          for k in range(height)
         ]
-        for j in range(height)
+        for j in range(7 if size_bytes else 1)
       ]
-      for i in range(7 if size_bytes else 1)
-    ]
-  data[index]['data'] = value
+  data[i]['data'] = data1
 
 print('writing json')
 with open(out_json, 'w') as fout:
index 8e3f2b3..647b8f6 100644 (file)
@@ -844,35 +844,54 @@ objects
 0x7f,draw_star_blazer_by_tony_suzuki
 
 draw_misc_entries
-0x00,decimal_0_score
-0x01,decimal_1_high_score
-0x02,decimal_2
-0x03,decimal_3_mission
-0x04,decimal_4_fuel
-0x05,decimal_5_bomb
-0x06,decimal_6_ship_left
-0x07,decimal_7_bonus
-0x08,entry_08_score
-0x09,entry_09_high_score
-0x0a,entry_0a_scoring
-0x0b,entry_0b_ground
-0x0c,entry_0c_ground
-0x0d,entry_0d_ground
-0x0e,entry_0e_ground
-0x0f,entry_0f_fuel
-0x10,entry_10_bomb
-0x11,entry_11_ship_left
-0x12,entry_12_great_performance
-0x13,entry_13_complete
-0x14,entry_14_empty_fuel
-0x15,entry_15_copyright_1981_star_craft_inc
-0x16,entry_16_bonus
-0x17,entry_17_game_over
-0x18,entry_18_bomb_the_radar
-0x19,entry_19_attack_the_tank
-0x1a,entry_1a_bomb_the_icbm
-0x1b,entry_1b_scoring
-0x1c,entry_1c_bomb_the_headquarters
-0x1d,entry_1d_star_blazer
-0x1e,entry_1e_by_tony_suzuki
-0x1f,entry_1f_thanks_a_lot_comma_raly
+0x00,score
+0x01,high_score
+0x03,mission
+0x04,fuel
+0x05,bomb
+0x06,ship_left
+0x07,bonus
+0x08,score
+0x09,high_score
+0x0a,scoring
+0x0b,ground
+0x0c,ground
+0x0d,ground
+0x0e,ground
+0x0f,fuel
+0x10,bomb
+0x11,ship_left
+0x12,great_performance
+0x13,complete
+0x14,empty_fuel
+0x15,copyright_1981_star_craft_inc
+0x16,bonus
+0x17,game_over
+0x18,bomb_the_radar
+0x19,attack_the_tank
+0x1a,bomb_the_icbm
+0x1b,scoring
+0x1c,bomb_the_headquarters
+0x1d,star_blazer
+0x1e,by_tony_suzuki
+0x1f,thanks_a_lot_comma_raly
+
+sound_effects
+0x00,ship_impact
+0x01,bombs_empty
+0x02,player_fire
+# also when supplies caught by player
+0x04,tree_impact
+0x05,mission_complete
+0x06,mission_start
+0x08,supplies_impact
+0x09,helicopter_impact
+0x0a,missile_impact
+0x0b,tank_engine
+# multiple explosion sounds are played simultaneously
+# this might be because each participant plays its own sound
+0x0c,explosion
+0x0d,explosion
+# also missile launch
+0x0e,explosion
+0x0f,explosion
index 707a1e9..a0eaa83 100644 (file)
@@ -198,7 +198,7 @@ struct trace {
   uint8_t max_bitwise;
 } trace[MEM_SIZE][N_TRACE_REGS];
 #endif
-#if 0
+#if 1
 uint8_t start_at_mission = 1;
 #endif
 uint8_t key_waiting;
@@ -798,7 +798,7 @@ uint8_t mem_read(uint16_t addr0, bool isDbg) {
     }
 #endif
 
-#if 0 // start at level
+#if 0 // start at mission
     if (addr == 0x1726) // opcode fetch
       vrEmu6502SetX(cpu, start_at_mission);
 #endif
@@ -1030,6 +1030,13 @@ void mem_write(uint16_t addr0, uint8_t val) {
     }
 #endif
 
+#if 0 // sound effects
+    if (addr >= 0xab80 && addr < 0xab90) {
+      int pc = vrEmu6502GetPC(cpu);
+      fprintf(stderr, "pc=%04x w=%04x v=%02x\r\n", pc, addr, val);
+    }
+#endif
+
 #if 0 // decimals
     if (addr >= 0xb0 && addr < 0xc0) {
       int pc = vrEmu6502GetPC(cpu);
@@ -1613,6 +1620,29 @@ int main(int argc, char **argv) {
           SDL_TextInputEvent *e = (SDL_TextInputEvent *)&event;
           int i = e->text[0];
           switch (i) {
+#if 0 // sound effects
+          case 'a':
+          case 'b':
+          case 'c':
+          case 'd':
+          case 'e':
+          case 'f':
+            i += '0' + 10 - 'a';
+            // fallthru
+         case '0':
+         case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+         case '7':
+          case '8':
+          case '9':
+            mem[0xab80 + (i & 0xf)] = 1;
+            break;
+#endif
+
 #if 0
           case '1':
           case '2':