diff --git a/nml/actions/action2layout.py b/nml/actions/action2layout.py index 288222f8..33ec49f6 100644 --- a/nml/actions/action2layout.py +++ b/nml/actions/action2layout.py @@ -60,9 +60,10 @@ class Action2LayoutSpriteType: class Action2LayoutSprite: - def __init__(self, feature, type, pos=None, extra_dicts=None): + def __init__(self, feature, type, layout_registers=None, pos=None, extra_dicts=None): self.feature = feature self.type = type + self.layout_registers = layout_registers self.pos = pos self.extra_dicts = extra_dicts or [] self.params = { @@ -217,7 +218,10 @@ def create_register(self, name, value): store_tmp = None load_tmp = action2var.VarAction2Var(0x7D, 0, 0xFFFFFFFF, value.register.value) else: - store_tmp = action2var.VarAction2StoreTempVar() + if self.layout_registers is None: + store_tmp = action2var.VarAction2StoreTempVar() + else: + store_tmp = self.layout_registers.add(value) load_tmp = action2var.VarAction2LoadTempVar(store_tmp) self.params[name]["register"] = (load_tmp, store_tmp, value) @@ -387,10 +391,9 @@ def _validate_hide_sprite(self, name, value): class ParsedSpriteLayout: - def __init__(self, registers=None): + def __init__(self): self.ground_sprite = None self.building_sprites = [] - self.registers = registers or [] self.advanced = False def get_size(self): @@ -441,7 +444,7 @@ def write(self, file): sprite.write_registers(file) file.newline() - def process(self, spritelayout, feature, param_map, actions, var10map=None): + def process(self, spritelayout, feature, param_map, actions, layout_registers, var10map=None): if not isinstance(param_map, list): param_map = [param_map] @@ -474,10 +477,9 @@ def process(self, spritelayout, feature, param_map, actions, var10map=None): ), type.pos, ) - sprite = Action2LayoutSprite(feature, layout_sprite_types[type.value], pos, param_map) + sprite = Action2LayoutSprite(feature, layout_sprite_types[type.value], layout_registers, pos, param_map) for name, value in param_list: sprite.set_param(name, value) - self.registers.extend(sprite.get_all_registers()) if sprite.type == Action2LayoutSpriteType.GROUND: if self.ground_sprite is not None: raise generic.ScriptError("Sprite layout can have no more than one ground sprite", spritelayout.pos) @@ -490,7 +492,7 @@ def process(self, spritelayout, feature, param_map, actions, var10map=None): # no sprites defined at all, that's not very much. raise generic.ScriptError("Sprite layout requires at least one sprite", spritelayout.pos) # set to 0 for no ground sprite - self.ground_sprite = Action2LayoutSprite(feature, Action2LayoutSpriteType.GROUND) + self.ground_sprite = Action2LayoutSprite(feature, Action2LayoutSpriteType.GROUND, layout_registers) self.ground_sprite.set_param(expression.Identifier("sprite"), expression.ConstantNumeric(0)) self.advanced = any(x.is_advanced_sprite() for x in self.building_sprites + [self.ground_sprite]) @@ -510,17 +512,23 @@ def write_action_value(self, actions, act6, offset): return offset - def parse_registers(self, varact2parser): - if self.registers: - for register_info in self.registers: - reg, expr = register_info[1], register_info[2] - if reg is None: - continue - varact2parser.parse_expr(expr) - varact2parser.var_list.append(nmlop.STO_TMP) - varact2parser.var_list.append(reg) - varact2parser.var_list.append(nmlop.VAL2) - varact2parser.var_list_size += reg.get_size() + 2 + +class LayoutRegisters: + def __init__(self): + self.registers = {} + + def add(self, value): + if value not in self.registers: + self.registers[value] = action2var.VarAction2StoreTempVar() + return self.registers[value] + + def parse(self, varact2parser): + for expr, reg in self.registers.items(): + varact2parser.parse_expr(expr) + varact2parser.var_list.append(nmlop.STO_TMP) + varact2parser.var_list.append(reg) + varact2parser.var_list.append(nmlop.VAL2) + varact2parser.var_list_size += reg.get_size() + 2 def get_layout_action2s(spritelayout, feature): @@ -541,8 +549,9 @@ def get_layout_action2s(spritelayout, feature): param_map = (param_map, lambda name, value, pos: action2var.VarAction2LoadCallParam(value, name)) spritelayout.register_map[feature] = param_registers + layout_registers = LayoutRegisters() layout = ParsedSpriteLayout() - layout.process(spritelayout, feature, param_map, actions) + layout.process(spritelayout, feature, param_map, actions, layout_registers) action6.free_parameters.save() act6 = action6.Action6() @@ -562,7 +571,7 @@ def get_layout_action2s(spritelayout, feature): actions.append(layout_action) varact2parser = action2var.Varaction2Parser(feature) - layout.parse_registers(varact2parser) + layout_registers.parse(varact2parser) # Only continue if we actually needed any new registers if varact2parser.var_list: @@ -694,6 +703,7 @@ def parse_spriteset(name, args, pos, info): param_registers = [] parsed_layouts = [] varact2parser = action2var.Varaction2Parser(feature) + layout_registers = LayoutRegisters() for layout in layouts: spritelayout = ( @@ -703,22 +713,26 @@ def parse_spriteset(name, args, pos, info): raise generic.ScriptError("Expected a SpriteLayout", layout.pos) # Allocate registers - registers = [] param_map = {} for i, param in enumerate(spritelayout.param_list): reg = action2var.VarAction2CallParam(param.value) param_registers.append(reg) param_map[param.value] = reg store_tmp = action2var.VarAction2StoreCallParam(reg) - registers.append((reg, store_tmp, layout.param_list[i])) + varact2parser.parse_expr(layout.param_list[i]) + varact2parser.var_list.append(nmlop.STO_TMP) + varact2parser.var_list.append(store_tmp) + varact2parser.var_list.append(nmlop.VAL2) + varact2parser.var_list_size += store_tmp.get_size() + 2 param_map = [(param_map, lambda name, value, pos: action2var.VarAction2LoadCallParam(value, name))] param_map.extend(default_param) - layout = ParsedSpriteLayout(registers) - layout.process(spritelayout, feature, param_map, actions, var10map) - layout.parse_registers(varact2parser) + layout = ParsedSpriteLayout() + layout.process(spritelayout, feature, param_map, actions, layout_registers, var10map) parsed_layouts.append(layout) + layout_registers.parse(varact2parser) + actions.extend(action0.get_layout_action0(feature, id, parsed_layouts)) registers_ref = None diff --git a/regression/expected/026_asl.grf b/regression/expected/026_asl.grf index f688852f..8630aa03 100644 Binary files a/regression/expected/026_asl.grf and b/regression/expected/026_asl.grf differ diff --git a/regression/expected/026_asl.nfo b/regression/expected/026_asl.nfo index 1176d8d4..28c3055c 100644 --- a/regression/expected/026_asl.nfo +++ b/regression/expected/026_asl.nfo @@ -65,19 +65,17 @@ F0 F1 F2 F3 F4 F5 00 00 00 00 00 00 00 00 00 FF // Name: layout2 - feature 0F 10 * 38 02 0F FF \b66 \dx00000000 \wx0000 \dx80000000 \wx0002 \b0 \b0 \b0 \b16 \b16 \b16 80 -\dx80018000 \wx000F \b0 \b0 \b0 \b16 \b16 \b16 81 83 82 +\dx80018000 \wx000F \b0 \b0 \b0 \b16 \b16 \b16 82 81 81 // Name: layout2@registers - feature 0F -11 * 80 02 0F FF 89 +11 * 66 02 0F FF 89 43 20 \dx000000FF \2sto 1A 20 \dx00000080 +\2r 1A 20 \dx00000001 +\2sto 1A 20 \dx00000081 \2r 62 00 29 \dx00000001 \2^ 1A 20 \dx00000001 -\2sto 1A 20 \dx00000081 -\2r 1A 20 \dx00000001 -\2sto 1A 20 \dx00000082 -\2r 1A 20 \dx00000001 -\2sto 1A 00 \dx00000083 +\2sto 1A 00 \dx00000082 \b1 \wx00FF \dx00000000 \dx00000000 \wx00FF // @@ -127,19 +125,17 @@ F0 F1 F2 F3 F4 F5 00 00 00 00 00 00 00 00 00 FF // Name: layout2 - feature 11 19 * 38 02 11 FE \b66 \dx00000000 \wx0000 \dx80000000 \wx0002 \b0 \b0 \b0 \b16 \b16 \b16 80 -\dx80018000 \wx000F \b0 \b0 \b0 \b16 \b16 \b16 81 83 82 +\dx80018000 \wx000F \b0 \b0 \b0 \b16 \b16 \b16 82 81 81 // Name: layout2@registers - feature 11 -20 * 80 02 11 FE 89 +20 * 66 02 11 FE 89 44 20 \dx000000FF \2sto 1A 20 \dx00000080 +\2r 1A 20 \dx00000001 +\2sto 1A 20 \dx00000081 \2r 60 00 29 \dx00000001 \2^ 1A 20 \dx00000001 -\2sto 1A 20 \dx00000081 -\2r 1A 20 \dx00000001 -\2sto 1A 20 \dx00000082 -\2r 1A 20 \dx00000001 -\2sto 1A 00 \dx00000083 +\2sto 1A 00 \dx00000082 \b1 \wx00FE \dx00000000 \dx00000000 \wx00FE // diff --git a/regression/expected/030_house.grf b/regression/expected/030_house.grf index d0ebec34..bac652ac 100644 Binary files a/regression/expected/030_house.grf and b/regression/expected/030_house.grf differ diff --git a/regression/expected/030_house.nfo b/regression/expected/030_house.nfo index cdc20619..511604d1 100644 --- a/regression/expected/030_house.nfo +++ b/regression/expected/030_house.nfo @@ -55,8 +55,8 @@ FF // with_smoke : register 8C 22 * 49 02 07 FF \b67 \dx00000F8D \wx0000 \dxC0000000 \wx0002 \b0 \b0 80 83 -\dx00000000 \wx0003 \b0 \b0 \b0 \b16 \b16 \b48 85 86 -\dx00000000 \wx0023 \b8 \b0 \b0 \b11 \b16 \b7 88 89 8A +\dx00000000 \wx0003 \b0 \b0 \b0 \b16 \b16 \b48 86 84 +\dx00000000 \wx0023 \b8 \b0 \b0 \b11 \b16 \b7 8A 87 88 // Name: brewery_sprite_layout@registers - feature 07 23 * 362 02 07 FF 89 @@ -74,37 +74,37 @@ FF \2* 1A 20 \dx00000002 \2+ 7D 82 20 \dxFFFFFFFF \2sto 1A 20 \dx00000083 +\2r 43 20 \dx000000FF +\2cmp 1A 20 \dx00000004 +\2& 1A 20 \dx00000001 +\2* 1A 20 \dx00000003 +\2+ 7D 8B 20 \dxFFFFFFFF // building_sprite +\2sto 1A 20 \dx00000084 \2r 40 20 \dx00000003 \2cmp 1A 20 \dx00000003 \2& 1A 20 \dx00000001 \2^ 1A 20 \dx00000001 -\2sto 1A 20 \dx00000084 +\2sto 1A 20 \dx00000085 \2r 7D 8B 20 \dxFFFFFFFF // building_sprite \2cmp 1A 20 \dxFFFFFFFF \2& 1A 20 \dx00000001 -\2| 7D 84 20 \dxFFFFFFFF +\2| 7D 85 20 \dxFFFFFFFF \2^ 1A 20 \dx00000001 -\2sto 1A 20 \dx00000085 -\2r 43 20 \dx000000FF -\2cmp 1A 20 \dx00000004 -\2& 1A 20 \dx00000001 -\2* 1A 20 \dx00000003 -\2+ 7D 8B 20 \dxFFFFFFFF // building_sprite \2sto 1A 20 \dx00000086 +\2r 46 60 \dx000000FF \dxFFFFFFFF \dx00000004 +\2+ 1A 20 \dx00000C07 +\2sto 1A 20 \dx00000087 +\2r 46 60 \dx000000FF \dx00000036 \dx00000001 +\2sto 1A 20 \dx00000088 \2r 46 20 \dx000000FF \2cmp 1A 20 \dx00000000 \2& 1A 20 \dx00000001 -\2sto 1A 20 \dx00000087 +\2sto 1A 20 \dx00000089 \2r 7D 8C 20 \dxFFFFFFFF // with_smoke \2u< 1A 20 \dx00000001 \2^ 1A 20 \dx00000001 -\2| 7D 87 20 \dxFFFFFFFF +\2| 7D 89 20 \dxFFFFFFFF \2^ 1A 20 \dx00000001 -\2sto 1A 20 \dx00000088 -\2r 46 60 \dx000000FF \dxFFFFFFFF \dx00000004 -\2+ 1A 20 \dx00000C07 -\2sto 1A 20 \dx00000089 -\2r 46 60 \dx000000FF \dx00000036 \dx00000001 \2sto 1A 00 \dx0000008A \b1 \wx00FF \dx00000000 \dx00000000 diff --git a/regression/expected/040_station.grf b/regression/expected/040_station.grf index a5d99774..e7d79dc8 100644 Binary files a/regression/expected/040_station.grf and b/regression/expected/040_station.grf differ diff --git a/regression/expected/040_station.nfo b/regression/expected/040_station.nfo index 8eb8fc98..2005c8a7 100644 --- a/regression/expected/040_station.nfo +++ b/regression/expected/040_station.nfo @@ -55,26 +55,24 @@ \dx0000842E \wx0000 \b0 \b0 \b0 \b16 \b5 \b2 \dx8000842D \wx0002 \b17 \b11 80 81 \dx00008430 \wx0000 \b0 \b11 \b0 \b16 \b5 \b2 -\dx8000842D \wx0042 \b17 \b10 80 82 01 +\dx8000842D \wx0042 \b17 \b10 80 81 01 \b68 \dx000003F3 \wx0000 \dx0000842F \wx0000 \b0 \b0 \b0 \b5 \b16 \b2 -\dx8000842D \wx0042 \b20 \b11 80 83 01 +\dx8000842D \wx0042 \b20 \b11 80 82 01 \dx0000842D \wx0000 \b11 \b0 \b0 \b5 \b16 \b2 -\dx8000842D \wx0042 \b20 \b10 80 84 03 +\dx8000842D \wx0042 \b20 \b10 80 83 03 // Name: Station Layout@registers - Id 00 // a : register 80 -15 * 77 02 04 FD 89 -1A 20 \dx00000000 -\2sto 1A 20 \dx00000081 -\2r 1A 20 \dx00000000 -\2sto 1A 20 \dx00000082 -\2r 1A 20 \dx00000001 +15 * 63 02 04 FD 89 +1A 20 \dx00000001 \2sto 1A 20 \dx00000080 +\2r 1A 20 \dx00000000 +\2sto 1A 20 \dx00000081 \2r 7D 80 20 \dxFFFFFFFF // a -\2sto 1A 20 \dx00000083 +\2sto 1A 20 \dx00000082 \2r 1A 20 \dx00000001 -\2sto 1A 00 \dx00000084 +\2sto 1A 00 \dx00000083 \b0 \wx8000 // Return computed value diff --git a/regression/expected/example_station.grf b/regression/expected/example_station.grf index 77ffb496..554b480e 100644 Binary files a/regression/expected/example_station.grf and b/regression/expected/example_station.grf differ diff --git a/regression/expected/example_station.nfo b/regression/expected/example_station.nfo index f1a9a462..55593827 100644 --- a/regression/expected/example_station.nfo +++ b/regression/expected/example_station.nfo @@ -94,13 +94,13 @@ 25 * 106 02 04 FC 89 1A 20 \dx00000000 \2sto 1A 20 \dx00000080 +\2r 1A 20 \dx00000000 +\2sto 1A 20 \dx00000081 \2r 7D 80 20 \dxFFFFFFFF // a \2+ 1A 20 \dx000007E6 \2sto 1A 20 \dx00000082 \2r 1A 20 \dx00000000 \2sto 1A 20 \dx00000083 -\2r 1A 20 \dx00000000 -\2sto 1A 20 \dx00000081 \2r 7D 81 20 \dxFFFFFFFF // a \2+ 1A 20 \dx000007E6 \2sto 1A 20 \dx00000084