Skip to content

Commit

Permalink
Change: reduce register consumption for spritelayouts (#306)
Browse files Browse the repository at this point in the history
  • Loading branch information
glx22 authored Jul 9, 2024
1 parent 4d6fe34 commit dcbfdc7
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 70 deletions.
66 changes: 40 additions & 26 deletions nml/actions/action2layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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]

Expand Down Expand Up @@ -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)
Expand All @@ -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])
Expand All @@ -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):
Expand All @@ -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()
Expand All @@ -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:
Expand Down Expand Up @@ -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 = (
Expand All @@ -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
Expand Down
Binary file modified regression/expected/026_asl.grf
Binary file not shown.
24 changes: 10 additions & 14 deletions regression/expected/026_asl.nfo
Original file line number Diff line number Diff line change
Expand Up @@ -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 //
Expand Down Expand Up @@ -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 //
Expand Down
Binary file modified regression/expected/030_house.grf
Binary file not shown.
34 changes: 17 additions & 17 deletions regression/expected/030_house.nfo
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Binary file modified regression/expected/040_station.grf
Binary file not shown.
20 changes: 9 additions & 11 deletions regression/expected/040_station.nfo
Original file line number Diff line number Diff line change
Expand Up @@ -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 FF
// a : register 80
16 * 77 02 04 FD 89
1A 20 \dx00000000
\2sto 1A 20 \dx00000081
\2r 1A 20 \dx00000000
\2sto 1A 20 \dx00000082
\2r 1A 20 \dx00000001
16 * 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

Expand Down
Binary file modified regression/expected/example_station.grf
Binary file not shown.
4 changes: 2 additions & 2 deletions regression/expected/example_station.nfo
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,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
Expand Down

0 comments on commit dcbfdc7

Please sign in to comment.