alpine: Add creek objects
This commit is contained in:
@@ -250,7 +250,7 @@ item (FEAT_OBJECTS, meadow) {
|
||||
//tile_check: CB_RESULT_LOCATION_ALLOW;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
spriteset (creek_groundsprites, "gfx/rivers.png") {
|
||||
tmpl_groundsprites_anim(1, 0 * 64 + 1)
|
||||
tmpl_groundsprites_anim(1, 1 * 64 + 1)
|
||||
@@ -338,10 +338,15 @@ spriteset (creek_groundsprites, "gfx/rivers.png") {
|
||||
spritelayout creek_groundsprites_default(n, tile_height) {
|
||||
ground {
|
||||
sprite:
|
||||
(climate == CLIMATE_ARCTIC && tile_height > snowline_height - 2 ?
|
||||
(tile_height > snowline_height - 2 ?
|
||||
GROUNDSPRITE_SNOW + min(tile_height - snowline_height - 2, 0) * 19
|
||||
: (terrain_type == TILETYPE_DESERT ? GROUNDSPRITE_DESERT : GROUNDSPRITE_NORMAL))
|
||||
: GROUNDSPRITE_NORMAL)
|
||||
+ slope_to_sprite_offset(tile_slope);
|
||||
// sprite:
|
||||
// (climate == CLIMATE_ARCTIC && tile_height > snowline_height - 2 ?
|
||||
// GROUNDSPRITE_SNOW + min(tile_height - snowline_height - 2, 0) * 19
|
||||
// : (terrain_type == TILETYPE_DESERT ? GROUNDSPRITE_DESERT : GROUNDSPRITE_NORMAL))
|
||||
// + slope_to_sprite_offset(tile_slope);
|
||||
}
|
||||
childsprite {
|
||||
sprite: creek_groundsprites(
|
||||
@@ -1736,4 +1741,4 @@ item (FEAT_OBJECTS, rivers_80) {
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
/* */
|
||||
@@ -108,31 +108,7 @@ def replace_coastal_sprites(file, x, y, **kw):
|
||||
|
||||
replace_coastal_sprites('gfx/water/seashore_grid_temperate.gimp.png', 1, 1)
|
||||
|
||||
|
||||
# spriteset (meadow_groundsprites, "gfx/meadow_grid_temperate.png") { tmpl_groundsprites(1, 1) }
|
||||
|
||||
png = grf.ImageFile("gfx/meadow_grid_temperate.png")
|
||||
gen.add_sprite(grf.SpriteSet(grf.OBJECT, 19))
|
||||
tmpl_ground_sprites(lambda *args, **kw: gen.add_sprite(grf.FileSprite(png, *args, **kw)), 1, 1)
|
||||
# gen.add_sprite(grf.BasicSpriteLayout(grf.OBJECT, 255))
|
||||
gen.add_sprite(grf.AdvancedSpriteLayout(
|
||||
grf.OBJECT, 255,
|
||||
ground={
|
||||
'sprite': 0,
|
||||
'pal': 32768,
|
||||
'flags': 2,
|
||||
'add': grf.Temp(0),
|
||||
}
|
||||
))
|
||||
|
||||
gen.add_sprite(grf.Object(0,
|
||||
label=b'FLMA',
|
||||
size=0x11,
|
||||
climate=0xf,
|
||||
eol_date=0,
|
||||
flags=grf.Object.Flags.HAS_NO_FOUNDATION | grf.Object.Flags.ALLOW_UNDER_BRIDGE,
|
||||
))
|
||||
|
||||
# Tile slope to sprite offset
|
||||
gen.add_sprite(grf.VarAction2(
|
||||
feature=grf.OBJECT,
|
||||
use_related=False,
|
||||
@@ -142,96 +118,95 @@ gen.add_sprite(grf.VarAction2(
|
||||
code='tile_slope'
|
||||
))
|
||||
|
||||
# Ground sprite
|
||||
gen.add_sprite(grf.VarAction2(
|
||||
feature=grf.OBJECT,
|
||||
use_related=False,
|
||||
set_id=255,
|
||||
ranges={0: grf.Set(255)},
|
||||
default=grf.Set(255),
|
||||
code='TEMP[0] = call(0)'
|
||||
set_id=1,
|
||||
ranges={-2: 4550 , -1: 4550 - 19, 0: 4550 - 19 * 2, 1: 4550 - 19 * 3},
|
||||
default=3981,
|
||||
code='max(snowline_height - tile_height, -2)'
|
||||
))
|
||||
|
||||
gen.add_sprite(grf.Action3(grf.OBJECT, [0], [[255, 255]], 255))
|
||||
|
||||
# png = grf.ImageFile("gfx/meadow_grid_temperate.png")
|
||||
# gen.add_sprite(grf.SpriteSet(grf.OBJECT, 19))
|
||||
# tmpl_ground_sprites(lambda *args, **kw: gen.add_sprite(grf.FileSprite(png, *args, **kw)), 1, 1)
|
||||
# gen.add_sprite(grf.AdvancedSpriteLayout(
|
||||
# grf.OBJECT, 255,
|
||||
# ground={
|
||||
# 'sprite': 0,
|
||||
# 'pal': 32768,
|
||||
# 'flags': 2,
|
||||
# 'add': grf.Temp(0),
|
||||
# }
|
||||
# ))
|
||||
|
||||
# gen.add_sprite(grf.Object(0,
|
||||
# label=b'FLMA',
|
||||
# size=0x11,
|
||||
# climate=0xf,
|
||||
# eol_date=0,
|
||||
# flags=grf.Object.Flags.HAS_NO_FOUNDATION | grf.Object.Flags.ALLOW_UNDER_BRIDGE,
|
||||
# ))
|
||||
|
||||
# gen.add_sprite(grf.VarAction2(
|
||||
# feature=grf.OBJECT,
|
||||
# use_related=False,
|
||||
# set_id=255,
|
||||
# ranges={0: grf.Set(255)},
|
||||
# default=grf.Set(255),
|
||||
# code='TEMP[0] = call(0)'
|
||||
# ))
|
||||
|
||||
# gen.add_sprite(grf.Action3(grf.OBJECT, [0], [[255, 255]], 255))
|
||||
|
||||
# CREEKS
|
||||
|
||||
png = grf.ImageFile("gfx/meadow_grid_temperate.png")
|
||||
gen.add_sprite(grf.SpriteSet(grf.OBJECT, 19))
|
||||
tmpl_ground_sprites(lambda *args, **kw: gen.add_sprite(grf.FileSprite(png, *args, **kw)), 1, 1)
|
||||
# gen.add_sprite(grf.BasicSpriteLayout(grf.OBJECT, 255))
|
||||
gen.add_sprite(grf.AdvancedSpriteLayout(
|
||||
grf.OBJECT, 255,
|
||||
ground={
|
||||
'sprite': 0,
|
||||
'pal': 32768,
|
||||
'flags': 2,
|
||||
'add': grf.Temp(0),
|
||||
}
|
||||
))
|
||||
|
||||
gen.add_sprite(grf.Object(0,
|
||||
label=b'FLMA',
|
||||
size=0x11,
|
||||
climate=0xf,
|
||||
eol_date=0,
|
||||
flags=grf.Object.Flags.HAS_NO_FOUNDATION | grf.Object.Flags.ALLOW_UNDER_BRIDGE,
|
||||
))
|
||||
|
||||
gen.add_sprite(grf.VarAction2(
|
||||
feature=grf.OBJECT,
|
||||
use_related=False,
|
||||
set_id=0,
|
||||
ranges={0: 0, 1: 1, 2: 2, 4: 4, 8: 8, 9: 9, 3: 3, 6: 6, 12: 12, 5: 5, 10: 10, 11: 11, 7: 7, 14: 14, 13: 13, 27: 17, 23: 16, 30: 18, 29: 15},
|
||||
default=0,
|
||||
code='tile_slope'
|
||||
))
|
||||
|
||||
gen.add_sprite(grf.VarAction2(
|
||||
feature=grf.OBJECT,
|
||||
use_related=False,
|
||||
set_id=255,
|
||||
ranges={0: grf.Set(255)},
|
||||
default=grf.Set(255),
|
||||
code='TEMP[0] = call(0)'
|
||||
))
|
||||
|
||||
gen.add_sprite(grf.Action3(grf.OBJECT, [0], [[255, 255]], 255))
|
||||
|
||||
# creeks
|
||||
|
||||
gen.add_sprite(grf.SpriteSet(grf.OBJECT, 19 * 81))
|
||||
gen.add_sprite(grf.Action1(grf.OBJECT, 81, 19))
|
||||
png = grf.ImageFile("gfx/rivers.png")
|
||||
for i in range(81):
|
||||
tmpl_ground_sprites(lambda *args, **kw: gen.add_sprite(grf.FileSprite(png, *args, **kw)), 1, i * 64 + 1)
|
||||
|
||||
|
||||
gen.add_sprite(grf.AdvancedSpriteLayout(
|
||||
grf.OBJECT, 255,
|
||||
ground={
|
||||
'sprite': 0,
|
||||
'pal': 32768,
|
||||
'flags': 2,
|
||||
'add': grf.Temp(0),
|
||||
}
|
||||
))
|
||||
for i in range(81):
|
||||
gen.add_sprite(grf.AdvancedSpriteLayout(
|
||||
grf.OBJECT, 255,
|
||||
ground={
|
||||
'sprite': 0,
|
||||
'pal': 0,
|
||||
'flags': 2,
|
||||
'add': grf.Temp(1),
|
||||
},
|
||||
sprites=[{
|
||||
'sprite': i,
|
||||
'pal': (1 << 15),
|
||||
'flags': 2,
|
||||
'add': grf.Temp(0),
|
||||
}]
|
||||
))
|
||||
|
||||
gen.add_sprite(grf.Object(0,
|
||||
label=b'CREE',
|
||||
size=0x11,
|
||||
climate=0xf,
|
||||
eol_date=0,
|
||||
flags=grf.Object.Flags.HAS_NO_FOUNDATION | grf.Object.Flags.ALLOW_UNDER_BRIDGE,
|
||||
))
|
||||
gen.add_sprite(grf.VarAction2(
|
||||
feature=grf.OBJECT,
|
||||
use_related=False,
|
||||
set_id=255,
|
||||
ranges={0: grf.Set(255)},
|
||||
default=grf.Set(255),
|
||||
code=f'''
|
||||
TEMP[0] = call(0)
|
||||
TEMP[1] = call(1) + TEMP[0]
|
||||
'''
|
||||
))
|
||||
|
||||
gen.add_sprite(grf.VarAction2(
|
||||
feature=grf.OBJECT,
|
||||
use_related=False,
|
||||
set_id=255,
|
||||
ranges={0: grf.Set(255)},
|
||||
default=grf.Set(255),
|
||||
code='TEMP[0] = call(0)'
|
||||
))
|
||||
gen.add_sprite(creek_obj := grf.Object(i,
|
||||
label=b'CREE',
|
||||
size=(1, 1),
|
||||
climate=0xf,
|
||||
eol_date=0,
|
||||
flags=grf.Object.Flags.HAS_NO_FOUNDATION | grf.Object.Flags.ALLOW_UNDER_BRIDGE,
|
||||
))
|
||||
|
||||
gen.add_sprite(grf.Action3(grf.OBJECT, [0], [[255, 255]], 255))
|
||||
|
||||
gen.add_sprite(grf.Map(creek_obj, [[255, 255]], 255))
|
||||
|
||||
gen.write('alpine.grf')
|
||||
|
||||
@@ -388,6 +388,8 @@ class Object(Action0):
|
||||
|
||||
|
||||
def __init__(self, id, **props):
|
||||
if 'size' in props:
|
||||
props['size'] = (props['size'][1] << 4) | props['size'][0]
|
||||
super().__init__(OBJECT, id, 1, props)
|
||||
|
||||
|
||||
@@ -444,7 +446,7 @@ class AdvancedSpriteLayout(LazyBaseSprite):
|
||||
res = struct.pack('<HHH', sprite['sprite'], sprite['pal'], sprite['flags'])
|
||||
|
||||
if aux:
|
||||
delta = s.get('delta', (0, 0, 0))
|
||||
delta = sprite.get('delta', (0, 0, 0))
|
||||
is_parent = bool(sprite.get('parent'))
|
||||
if not is_parent:
|
||||
delta = (delta[0], delta[1], 0x80)
|
||||
@@ -546,7 +548,7 @@ class VarAction2(LazyBaseSprite):
|
||||
low = r[0]
|
||||
high = r[0]
|
||||
# TODO split (or validate) negative-positive ranges
|
||||
res += struct.pack('<HII', self._get_set_value(set_obj), low, high)
|
||||
res += struct.pack('<Hii', self._get_set_value(set_obj), low, high)
|
||||
res += struct.pack('<H', self._get_set_value(self.default))
|
||||
return res
|
||||
|
||||
@@ -570,6 +572,11 @@ class Action3(LazyBaseSprite):
|
||||
return res
|
||||
|
||||
|
||||
class Map(Action3):
|
||||
def __init__(self, object, maps, default):
|
||||
super().__init__(object.feature, [object.first_id], maps, default)
|
||||
|
||||
|
||||
class NewGRF:
|
||||
def __init__(self, grfid, name, description):
|
||||
self.sprites = []
|
||||
|
||||
@@ -48,6 +48,12 @@ OPERATORS = {
|
||||
DEFAULT_INDENT_STR = ' '
|
||||
|
||||
|
||||
def hex_str(s):
|
||||
if isinstance(s, (bytes, memoryview)):
|
||||
return ':'.join('{:02x}'.format(b) for b in s)
|
||||
return ':'.join('{:02x}'.format(ord(c)) for c in s)
|
||||
|
||||
|
||||
class Node:
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -119,10 +125,10 @@ class Expr(Node):
|
||||
return False, res
|
||||
|
||||
# Calculate secord arg first and store in in a temp var
|
||||
res += b_code
|
||||
res = b_code
|
||||
res += struct.pack('<BBBIB', OP_TSTO, 0x1a, 0x20, register, OP_INIT)
|
||||
res += self.a.compile(register + 1, shift, and_mask)[1]
|
||||
res += struct.pack('<BBBI', self.op, 0x7d, 0x20, 0xffffffff)
|
||||
res += struct.pack('<BBBBI', self.op, 0x7d, register, 0x20, 0xffffffff)
|
||||
return False, res
|
||||
|
||||
|
||||
@@ -141,6 +147,51 @@ class Value(Node):
|
||||
return True, struct.pack('<BBI', 0x1a, 0x20, valueadj)
|
||||
|
||||
|
||||
NML_VARACT2_GLOBALVARS = {
|
||||
'current_month' : {'var': 0x02, 'start': 0, 'size': 8},
|
||||
'current_day_of_month' : {'var': 0x02, 'start': 8, 'size': 5},
|
||||
'is_leapyear' : {'var': 0x02, 'start': 15, 'size': 1},
|
||||
'current_day_of_year' : {'var': 0x02, 'start': 16, 'size': 9},
|
||||
'traffic_side' : {'var': 0x06, 'start': 4, 'size': 1},
|
||||
'animation_counter' : {'var': 0x0A, 'start': 0, 'size': 16},
|
||||
'current_callback' : {'var': 0x0C, 'start': 0, 'size': 16},
|
||||
'extra_callback_info1' : {'var': 0x10, 'start': 0, 'size': 32},
|
||||
'game_mode' : {'var': 0x12, 'start': 0, 'size': 8},
|
||||
'extra_callback_info2' : {'var': 0x18, 'start': 0, 'size': 32},
|
||||
'display_options' : {'var': 0x1B, 'start': 0, 'size': 6},
|
||||
'last_computed_result' : {'var': 0x1C, 'start': 0, 'size': 32},
|
||||
'snowline_height' : {'var': 0x20, 'start': 0, 'size': 8},
|
||||
'difficulty_level' : {'var': 0x22, 'start': 0, 'size': 8},
|
||||
'current_date' : {'var': 0x23, 'start': 0, 'size': 32},
|
||||
'current_year' : {'var': 0x24, 'start': 0, 'size': 32},
|
||||
|
||||
# TODO object vars
|
||||
'relative_x' : {'var': 0x40, 'start': 0, 'size': 8},
|
||||
'relative_y' : {'var': 0x40, 'start': 8, 'size': 8},
|
||||
'relative_pos' : {'var': 0x40, 'start': 0, 'size': 16},
|
||||
|
||||
'terrain_type' : {'var': 0x41, 'start': 0, 'size': 3},
|
||||
'tile_slope' : {'var': 0x41, 'start': 8, 'size': 5},
|
||||
|
||||
'build_date' : {'var': 0x42, 'start': 0, 'size': 32},
|
||||
|
||||
'animation_frame' : {'var': 0x43, 'start': 0, 'size': 8},
|
||||
'company_colour' : {'var': 0x43, 'start': 0, 'size': 8},
|
||||
|
||||
'owner' : {'var': 0x44, 'start': 0, 'size': 8},
|
||||
|
||||
'town_manhattan_dist' : {'var': 0x45, 'start': 0, 'size': 16},
|
||||
'town_zone' : {'var': 0x45, 'start': 16, 'size': 8},
|
||||
|
||||
'town_euclidean_dist' : {'var': 0x46, 'start': 0, 'size': 16},
|
||||
'view' : {'var': 0x48, 'start': 0, 'size': 8},
|
||||
'random_bits' : {'var': 0x5F, 'start': 8, 'size': 8},
|
||||
|
||||
# TODO object nearby vars
|
||||
'tile_height' : {'var': 0x62, 'start': 16, 'size': 8, 'param': 0},
|
||||
}
|
||||
|
||||
|
||||
class Var(Node):
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
@@ -150,21 +201,25 @@ class Var(Node):
|
||||
return [self.name]
|
||||
|
||||
def compile(self, register, shift=0, and_mask=0xffffffff):
|
||||
var_data = VARS = {
|
||||
'tile_slope': (0x41, 8, 0x1f)
|
||||
}.get(self.name)
|
||||
var_data = NML_VARACT2_GLOBALVARS.get(self.name)
|
||||
|
||||
if var_data is None:
|
||||
raise ValueError(f'Unknown variable `{self.name}`')
|
||||
and_mask &= var_data[2] >> shift
|
||||
shift += var_data[1]
|
||||
var_mask = (1 << var_data['size']) - 1
|
||||
and_mask &= var_mask >> shift
|
||||
shift += var_data['start']
|
||||
assert shift < 0x20, shift
|
||||
assert and_mask <= 0xffffffff, and_mask
|
||||
return True, struct.pack('<BBI', var_data[0], 0x20 | shift, and_mask)
|
||||
if 'param' in var_data:
|
||||
return True, struct.pack('<BBBI', var_data['var'], var_data['param'], 0x20 | shift, and_mask)
|
||||
else:
|
||||
return True, struct.pack('<BBI', var_data['var'], 0x20 | shift, and_mask)
|
||||
|
||||
|
||||
class Temp(Node):
|
||||
def __init__(self, register):
|
||||
super().__init__()
|
||||
assert isinstance(register, int), type(register)
|
||||
self.register = register
|
||||
|
||||
def format(self, parent_priority=0):
|
||||
@@ -173,7 +228,7 @@ class Temp(Node):
|
||||
def compile(self, register, shift=0, and_mask=0xffffffff):
|
||||
assert shift < 0x20, shift
|
||||
assert and_mask <= 0xffffffff, and_mask
|
||||
return True, struct.pack('<BBI', 0x7d, 0x20 | shift, and_mask)
|
||||
return True, struct.pack('<BBBI', 0x7d, self.register, 0x20 | shift, and_mask)
|
||||
|
||||
|
||||
class Perm(Node):
|
||||
@@ -207,7 +262,7 @@ class Call(Node):
|
||||
tokens = (
|
||||
'NAME', 'NUMBER', 'NEWLINE',
|
||||
'ADD', 'SUB', 'MUL',
|
||||
'BINAND', 'BINOR', 'BINXOR',
|
||||
'BINAND', 'BINOR', 'BINXOR', 'SHR', 'SHL',
|
||||
'ASSIGN', 'COMMA',
|
||||
'LPAREN', 'RPAREN', 'LBRACKET', 'RBRACKET',
|
||||
)
|
||||
@@ -222,6 +277,8 @@ t_MUL = r'\*'
|
||||
t_BINAND = r'\&'
|
||||
t_BINOR = r'\|'
|
||||
t_BINXOR = r'\^'
|
||||
t_SHR = r'>>'
|
||||
t_SHL = r'<<'
|
||||
t_ASSIGN = r'='
|
||||
t_COMMA = r','
|
||||
t_LPAREN = r'\('
|
||||
@@ -259,12 +316,13 @@ def t_error(t):
|
||||
# Parsing rules
|
||||
|
||||
precedence = (
|
||||
('left', 'SHR', 'SHL'),
|
||||
('left', 'BINOR'),
|
||||
('left', 'BINXOR'),
|
||||
('left', 'BINAND'),
|
||||
('left', 'ADD', 'SUB'),
|
||||
('left', 'MUL'),
|
||||
# ('right', 'UMINUS'),
|
||||
('right', 'UMINUS'),
|
||||
)
|
||||
|
||||
|
||||
@@ -319,6 +377,8 @@ def p_expression_binop(t):
|
||||
| expression BINAND expression
|
||||
| expression BINOR expression
|
||||
| expression BINXOR expression
|
||||
| expression SHL expression
|
||||
| expression SHR expression
|
||||
'''
|
||||
op = {
|
||||
'+': OP_ADD,
|
||||
@@ -327,6 +387,8 @@ def p_expression_binop(t):
|
||||
'&': OP_BINAND,
|
||||
'|': OP_BINOR,
|
||||
'^': OP_BINXOR,
|
||||
'>>': OP_SHL,
|
||||
'<<': OP_SHR,
|
||||
}.get(t[2])
|
||||
|
||||
assert op is not None, t[2]
|
||||
@@ -358,6 +420,7 @@ def p_expression_assign(t):
|
||||
# 'expression : SUB expression %prec UMINUS'
|
||||
# t[0] = -t[2]
|
||||
|
||||
|
||||
def p_expression_call1(t):
|
||||
'expression : NAME LPAREN NUMBER RPAREN'
|
||||
assert t[1] == 'call', t[1]
|
||||
@@ -389,12 +452,17 @@ def p_expression_storage(t):
|
||||
assert t[1] in ('TEMP', 'PERM'), t[1]
|
||||
cls = Temp if t[1] == 'TEMP' else Perm
|
||||
register = int(t[3])
|
||||
t[0] = cls(Value(register))
|
||||
t[0] = cls(register)
|
||||
|
||||
|
||||
def p_expression_number(t):
|
||||
'expression : NUMBER'
|
||||
t[0] = Value(int(t[1]))
|
||||
'''expression : NUMBER
|
||||
| SUB NUMBER %prec UMINUS
|
||||
'''
|
||||
if len(t) == 2:
|
||||
t[0] = Value(int(t[1]))
|
||||
else:
|
||||
t[0] = Value(-int(t[2]))
|
||||
|
||||
|
||||
def p_expression_name(t):
|
||||
|
||||
@@ -6,9 +6,9 @@ _tabversion = '3.10'
|
||||
|
||||
_lr_method = 'LALR'
|
||||
|
||||
_lr_signature = 'leftBINORleftBINXORleftBINANDleftADDSUBleftMULADD ASSIGN BINAND BINOR BINXOR COMMA LBRACKET LPAREN MUL NAME NEWLINE NUMBER RBRACKET RPAREN SUBlines : line\n | expression\n | lines line\n line : expression NEWLINE\n | NEWLINE\n expression : expression ADD expression\n | expression SUB expression\n | expression MUL expression\n | expression BINAND expression\n | expression BINOR expression\n | expression BINXOR expression\n expression : NAME LBRACKET NUMBER RBRACKET ASSIGN expressionexpression : NAME LPAREN NUMBER RPARENexpression : NAME LPAREN expression COMMA expression RPARENexpression : LPAREN expression RPARENexpression : NAME LBRACKET NUMBER RBRACKETexpression : NUMBERexpression : NAME'
|
||||
_lr_signature = 'leftSHRSHLleftBINORleftBINXORleftBINANDleftADDSUBleftMULrightUMINUSADD ASSIGN BINAND BINOR BINXOR COMMA LBRACKET LPAREN MUL NAME NEWLINE NUMBER RBRACKET RPAREN SHL SHR SUBlines : line\n | expression\n | lines line\n line : expression NEWLINE\n | NEWLINE\n expression : expression ADD expression\n | expression SUB expression\n | expression MUL expression\n | expression BINAND expression\n | expression BINOR expression\n | expression BINXOR expression\n | expression SHL expression\n | expression SHR expression\n expression : NAME LBRACKET NUMBER RBRACKET ASSIGN expressionexpression : NAME LPAREN NUMBER RPARENexpression : NAME LPAREN expression COMMA expression RPARENexpression : LPAREN expression RPARENexpression : NAME LBRACKET NUMBER RBRACKETexpression : NUMBER\n | SUB NUMBER %prec UMINUS\n expression : NAME'
|
||||
|
||||
_lr_action_items = {'NEWLINE':([0,1,2,3,4,5,6,8,9,10,20,21,22,23,24,25,29,30,31,35,36,],[4,4,-1,10,-5,-18,-17,-3,10,-4,-6,-7,-8,-9,-10,-11,-15,-16,-13,-12,-14,]),'NAME':([0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,18,20,21,22,23,24,25,29,30,31,32,33,35,36,],[5,5,-1,-2,-5,-18,-17,5,-3,-4,5,5,5,5,5,5,5,-6,-7,-8,-9,-10,-11,-15,-16,-13,5,5,-12,-14,]),'LPAREN':([0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,18,20,21,22,23,24,25,29,30,31,32,33,35,36,],[7,7,-1,-2,-5,18,-17,7,-3,-4,7,7,7,7,7,7,7,-6,-7,-8,-9,-10,-11,-15,-16,-13,7,7,-12,-14,]),'NUMBER':([0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18,20,21,22,23,24,25,29,30,31,32,33,35,36,],[6,6,-1,-2,-5,-18,-17,6,-3,-4,6,6,6,6,6,6,26,27,-6,-7,-8,-9,-10,-11,-15,-16,-13,6,6,-12,-14,]),'$end':([1,2,3,4,5,6,8,10,20,21,22,23,24,25,29,30,31,35,36,],[0,-1,-2,-5,-18,-17,-3,-4,-6,-7,-8,-9,-10,-11,-15,-16,-13,-12,-14,]),'ADD':([3,5,6,9,19,20,21,22,23,24,25,27,28,29,30,31,34,35,36,],[11,-18,-17,11,11,-6,-7,-8,11,11,11,-17,11,-15,-16,-13,11,11,-14,]),'SUB':([3,5,6,9,19,20,21,22,23,24,25,27,28,29,30,31,34,35,36,],[12,-18,-17,12,12,-6,-7,-8,12,12,12,-17,12,-15,-16,-13,12,12,-14,]),'MUL':([3,5,6,9,19,20,21,22,23,24,25,27,28,29,30,31,34,35,36,],[13,-18,-17,13,13,13,13,-8,13,13,13,-17,13,-15,-16,-13,13,13,-14,]),'BINAND':([3,5,6,9,19,20,21,22,23,24,25,27,28,29,30,31,34,35,36,],[14,-18,-17,14,14,-6,-7,-8,-9,14,14,-17,14,-15,-16,-13,14,14,-14,]),'BINOR':([3,5,6,9,19,20,21,22,23,24,25,27,28,29,30,31,34,35,36,],[15,-18,-17,15,15,-6,-7,-8,-9,-10,-11,-17,15,-15,-16,-13,15,15,-14,]),'BINXOR':([3,5,6,9,19,20,21,22,23,24,25,27,28,29,30,31,34,35,36,],[16,-18,-17,16,16,-6,-7,-8,-9,16,-11,-17,16,-15,-16,-13,16,16,-14,]),'LBRACKET':([5,],[17,]),'RPAREN':([5,6,19,20,21,22,23,24,25,27,29,30,31,34,35,36,],[-18,-17,29,-6,-7,-8,-9,-10,-11,31,-15,-16,-13,36,-12,-14,]),'COMMA':([5,6,20,21,22,23,24,25,27,28,29,30,31,35,36,],[-18,-17,-6,-7,-8,-9,-10,-11,-17,32,-15,-16,-13,-12,-14,]),'RBRACKET':([26,],[30,]),'ASSIGN':([30,],[33,]),}
|
||||
_lr_action_items = {'NEWLINE':([0,1,2,3,4,6,7,9,10,11,20,24,25,26,27,28,29,30,31,35,36,37,41,42,],[4,4,-1,11,-5,-21,-19,-3,11,-4,-20,-6,-7,-8,-9,-10,-11,-12,-13,-17,-18,-15,-14,-16,]),'NAME':([0,1,2,3,4,6,7,8,9,11,12,13,14,15,16,17,18,19,20,22,24,25,26,27,28,29,30,31,35,36,37,38,39,41,42,],[6,6,-1,-2,-5,-21,-19,6,-3,-4,6,6,6,6,6,6,6,6,-20,6,-6,-7,-8,-9,-10,-11,-12,-13,-17,-18,-15,6,6,-14,-16,]),'LPAREN':([0,1,2,3,4,6,7,8,9,11,12,13,14,15,16,17,18,19,20,22,24,25,26,27,28,29,30,31,35,36,37,38,39,41,42,],[8,8,-1,-2,-5,22,-19,8,-3,-4,8,8,8,8,8,8,8,8,-20,8,-6,-7,-8,-9,-10,-11,-12,-13,-17,-18,-15,8,8,-14,-16,]),'NUMBER':([0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,29,30,31,35,36,37,38,39,41,42,],[7,7,-1,-2,-5,20,-21,-19,7,-3,-4,7,7,7,7,7,7,7,7,-20,32,33,-6,-7,-8,-9,-10,-11,-12,-13,-17,-18,-15,7,7,-14,-16,]),'SUB':([0,1,2,3,4,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,25,26,27,28,29,30,31,33,34,35,36,37,38,39,40,41,42,],[5,5,-1,13,-5,-21,-19,5,-3,13,-4,5,5,5,5,5,5,5,5,-20,5,13,-6,-7,-8,13,13,13,13,13,-19,13,-17,-18,-15,5,5,13,13,-16,]),'$end':([1,2,3,4,6,7,9,11,20,24,25,26,27,28,29,30,31,35,36,37,41,42,],[0,-1,-2,-5,-21,-19,-3,-4,-20,-6,-7,-8,-9,-10,-11,-12,-13,-17,-18,-15,-14,-16,]),'ADD':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[12,-21,-19,12,-20,12,-6,-7,-8,12,12,12,12,12,-19,12,-17,-18,-15,12,12,-16,]),'MUL':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[14,-21,-19,14,-20,14,14,14,-8,14,14,14,14,14,-19,14,-17,-18,-15,14,14,-16,]),'BINAND':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[15,-21,-19,15,-20,15,-6,-7,-8,-9,15,15,15,15,-19,15,-17,-18,-15,15,15,-16,]),'BINOR':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[16,-21,-19,16,-20,16,-6,-7,-8,-9,-10,-11,16,16,-19,16,-17,-18,-15,16,16,-16,]),'BINXOR':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[17,-21,-19,17,-20,17,-6,-7,-8,-9,17,-11,17,17,-19,17,-17,-18,-15,17,17,-16,]),'SHL':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[18,-21,-19,18,-20,18,-6,-7,-8,-9,-10,-11,-12,-13,-19,18,-17,-18,-15,18,18,-16,]),'SHR':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[19,-21,-19,19,-20,19,-6,-7,-8,-9,-10,-11,-12,-13,-19,19,-17,-18,-15,19,19,-16,]),'LBRACKET':([6,],[21,]),'RPAREN':([6,7,20,23,24,25,26,27,28,29,30,31,33,35,36,37,40,41,42,],[-21,-19,-20,35,-6,-7,-8,-9,-10,-11,-12,-13,37,-17,-18,-15,42,-14,-16,]),'COMMA':([6,7,20,24,25,26,27,28,29,30,31,33,34,35,36,37,41,42,],[-21,-19,-20,-6,-7,-8,-9,-10,-11,-12,-13,-19,38,-17,-18,-15,-14,-16,]),'RBRACKET':([32,],[36,]),'ASSIGN':([36,],[39,]),}
|
||||
|
||||
_lr_action = {}
|
||||
for _k, _v in _lr_action_items.items():
|
||||
@@ -17,7 +17,7 @@ for _k, _v in _lr_action_items.items():
|
||||
_lr_action[_x][_k] = _y
|
||||
del _lr_action_items
|
||||
|
||||
_lr_goto_items = {'lines':([0,],[1,]),'line':([0,1,],[2,8,]),'expression':([0,1,7,11,12,13,14,15,16,18,32,33,],[3,9,19,20,21,22,23,24,25,28,34,35,]),}
|
||||
_lr_goto_items = {'lines':([0,],[1,]),'line':([0,1,],[2,9,]),'expression':([0,1,8,12,13,14,15,16,17,18,19,22,38,39,],[3,10,23,24,25,26,27,28,29,30,31,34,40,41,]),}
|
||||
|
||||
_lr_goto = {}
|
||||
for _k, _v in _lr_goto_items.items():
|
||||
@@ -27,22 +27,25 @@ for _k, _v in _lr_goto_items.items():
|
||||
del _lr_goto_items
|
||||
_lr_productions = [
|
||||
("S' -> lines","S'",1,None,None,None),
|
||||
('lines -> line','lines',1,'p_lines','parser.py',272),
|
||||
('lines -> expression','lines',1,'p_lines','parser.py',273),
|
||||
('lines -> lines line','lines',2,'p_lines','parser.py',274),
|
||||
('line -> expression NEWLINE','line',2,'p_line','parser.py',288),
|
||||
('line -> NEWLINE','line',1,'p_line','parser.py',289),
|
||||
('expression -> expression ADD expression','expression',3,'p_expression_binop','parser.py',316),
|
||||
('expression -> expression SUB expression','expression',3,'p_expression_binop','parser.py',317),
|
||||
('expression -> expression MUL expression','expression',3,'p_expression_binop','parser.py',318),
|
||||
('expression -> expression BINAND expression','expression',3,'p_expression_binop','parser.py',319),
|
||||
('expression -> expression BINOR expression','expression',3,'p_expression_binop','parser.py',320),
|
||||
('expression -> expression BINXOR expression','expression',3,'p_expression_binop','parser.py',321),
|
||||
('expression -> NAME LBRACKET NUMBER RBRACKET ASSIGN expression','expression',6,'p_expression_assign','parser.py',350),
|
||||
('expression -> NAME LPAREN NUMBER RPAREN','expression',4,'p_expression_call1','parser.py',362),
|
||||
('expression -> NAME LPAREN expression COMMA expression RPAREN','expression',6,'p_expression_call2','parser.py',368),
|
||||
('expression -> LPAREN expression RPAREN','expression',3,'p_expression_group','parser.py',383),
|
||||
('expression -> NAME LBRACKET NUMBER RBRACKET','expression',4,'p_expression_storage','parser.py',388),
|
||||
('expression -> NUMBER','expression',1,'p_expression_number','parser.py',396),
|
||||
('expression -> NAME','expression',1,'p_expression_name','parser.py',401),
|
||||
('lines -> line','lines',1,'p_lines','parser.py',334),
|
||||
('lines -> expression','lines',1,'p_lines','parser.py',335),
|
||||
('lines -> lines line','lines',2,'p_lines','parser.py',336),
|
||||
('line -> expression NEWLINE','line',2,'p_line','parser.py',350),
|
||||
('line -> NEWLINE','line',1,'p_line','parser.py',351),
|
||||
('expression -> expression ADD expression','expression',3,'p_expression_binop','parser.py',378),
|
||||
('expression -> expression SUB expression','expression',3,'p_expression_binop','parser.py',379),
|
||||
('expression -> expression MUL expression','expression',3,'p_expression_binop','parser.py',380),
|
||||
('expression -> expression BINAND expression','expression',3,'p_expression_binop','parser.py',381),
|
||||
('expression -> expression BINOR expression','expression',3,'p_expression_binop','parser.py',382),
|
||||
('expression -> expression BINXOR expression','expression',3,'p_expression_binop','parser.py',383),
|
||||
('expression -> expression SHL expression','expression',3,'p_expression_binop','parser.py',384),
|
||||
('expression -> expression SHR expression','expression',3,'p_expression_binop','parser.py',385),
|
||||
('expression -> NAME LBRACKET NUMBER RBRACKET ASSIGN expression','expression',6,'p_expression_assign','parser.py',416),
|
||||
('expression -> NAME LPAREN NUMBER RPAREN','expression',4,'p_expression_call1','parser.py',429),
|
||||
('expression -> NAME LPAREN expression COMMA expression RPAREN','expression',6,'p_expression_call2','parser.py',435),
|
||||
('expression -> LPAREN expression RPAREN','expression',3,'p_expression_group','parser.py',450),
|
||||
('expression -> NAME LBRACKET NUMBER RBRACKET','expression',4,'p_expression_storage','parser.py',455),
|
||||
('expression -> NUMBER','expression',1,'p_expression_number','parser.py',463),
|
||||
('expression -> SUB NUMBER','expression',2,'p_expression_number','parser.py',464),
|
||||
('expression -> NAME','expression',1,'p_expression_name','parser.py',472),
|
||||
]
|
||||
|
||||
@@ -310,6 +310,9 @@ class DataReader:
|
||||
self.offset += size
|
||||
return res
|
||||
|
||||
def hex_str(self, n):
|
||||
return hex_str(self.data[self.offset: self.offset + n])
|
||||
|
||||
|
||||
TLF_NOTHING = 0x00
|
||||
TLF_DODRAW = 0x01 # Only draw sprite if value of register TileLayoutRegisters::dodraw is non-zero.
|
||||
@@ -343,7 +346,7 @@ TLF_PALETTE_REG_FLAGS = TLF_PALETTE
|
||||
def read_sprite_layout_registers(d, flags, is_parent):
|
||||
regs = {'flags': flags & TLF_DRAWING_FLAGS}
|
||||
if flags & TLF_DODRAW: regs['dodraw'] = d.get_byte();
|
||||
if flags & TLF_SPRITE: regs['sprite'] = d.get_byte();
|
||||
if flags & TLF_SPRITE: regs['add'] = Temp(d.get_byte());
|
||||
if flags & TLF_PALETTE: regs['palette'] = d.get_byte();
|
||||
|
||||
if is_parent:
|
||||
@@ -509,6 +512,74 @@ class Generic(Node):
|
||||
return [f'(var{self.var:02x} >>{self.shift} &{self.and_mask:x}{addstr})']
|
||||
|
||||
|
||||
signed_tile_offset = None
|
||||
industry_count = None
|
||||
|
||||
NML_VARACT2_GLOBALVARS = {
|
||||
'current_month' : {'var': 0x02, 'start': 0, 'size': 8},
|
||||
'current_day_of_month' : {'var': 0x02, 'start': 8, 'size': 5},
|
||||
'is_leapyear' : {'var': 0x02, 'start': 15, 'size': 1},
|
||||
'current_day_of_year' : {'var': 0x02, 'start': 16, 'size': 9},
|
||||
'traffic_side' : {'var': 0x06, 'start': 4, 'size': 1},
|
||||
'animation_counter' : {'var': 0x0A, 'start': 0, 'size': 16},
|
||||
'current_callback' : {'var': 0x0C, 'start': 0, 'size': 16},
|
||||
'extra_callback_info1' : {'var': 0x10, 'start': 0, 'size': 32},
|
||||
'game_mode' : {'var': 0x12, 'start': 0, 'size': 8},
|
||||
'extra_callback_info2' : {'var': 0x18, 'start': 0, 'size': 32},
|
||||
'display_options' : {'var': 0x1B, 'start': 0, 'size': 6},
|
||||
'last_computed_result' : {'var': 0x1C, 'start': 0, 'size': 32},
|
||||
'snowline_height' : {'var': 0x20, 'start': 0, 'size': 8},
|
||||
'difficulty_level' : {'var': 0x22, 'start': 0, 'size': 8},
|
||||
'current_date' : {'var': 0x23, 'start': 0, 'size': 32},
|
||||
'current_year' : {'var': 0x24, 'start': 0, 'size': 32},
|
||||
|
||||
# TODO object vars
|
||||
'relative_x' : {'var': 0x40, 'start': 0, 'size': 8},
|
||||
'relative_y' : {'var': 0x40, 'start': 8, 'size': 8},
|
||||
'relative_pos' : {'var': 0x40, 'start': 0, 'size': 16},
|
||||
|
||||
'terrain_type' : {'var': 0x41, 'start': 0, 'size': 3},
|
||||
'tile_slope' : {'var': 0x41, 'start': 8, 'size': 5},
|
||||
|
||||
'build_date' : {'var': 0x42, 'start': 0, 'size': 32},
|
||||
|
||||
'animation_frame' : {'var': 0x43, 'start': 0, 'size': 8},
|
||||
'company_colour' : {'var': 0x43, 'start': 0, 'size': 8},
|
||||
|
||||
'owner' : {'var': 0x44, 'start': 0, 'size': 8},
|
||||
|
||||
'town_manhattan_dist' : {'var': 0x45, 'start': 0, 'size': 16},
|
||||
'town_zone' : {'var': 0x45, 'start': 16, 'size': 8},
|
||||
|
||||
'town_euclidean_dist' : {'var': 0x46, 'start': 0, 'size': 16},
|
||||
'view' : {'var': 0x48, 'start': 0, 'size': 8},
|
||||
'random_bits' : {'var': 0x5F, 'start': 8, 'size': 8},
|
||||
|
||||
|
||||
'tile_height' : {'var': 0x62, 'start': 16, 'size': 8},
|
||||
|
||||
'nearby_tile_object_type' : {'var': 0x60, 'start': 0, 'size': 16, 'param_function': signed_tile_offset},
|
||||
'nearby_tile_object_view' : {'var': 0x60, 'start': 16, 'size': 4, 'param_function': signed_tile_offset},
|
||||
|
||||
'nearby_tile_random_bits' : {'var': 0x61, 'start': 0, 'size': 8, 'param_function': signed_tile_offset},
|
||||
|
||||
'nearby_tile_slope' : {'var': 0x62, 'start': 0, 'size': 5, 'param_function': signed_tile_offset},
|
||||
'nearby_tile_is_same_object' : {'var': 0x62, 'start': 8, 'size': 1, 'param_function': signed_tile_offset},
|
||||
'nearby_tile_is_water' : {'var': 0x62, 'start': 9, 'size': 1, 'param_function': signed_tile_offset},
|
||||
'nearby_tile_terrain_type' : {'var': 0x62, 'start': 10, 'size': 3, 'param_function': signed_tile_offset},
|
||||
'nearby_tile_water_class' : {'var': 0x62, 'start': 13, 'size': 2, 'param_function': signed_tile_offset},
|
||||
'nearby_tile_height' : {'var': 0x62, 'start': 16, 'size': 8, 'param_function': signed_tile_offset},
|
||||
'nearby_tile_class' : {'var': 0x62, 'start': 24, 'size': 4, 'param_function': signed_tile_offset},
|
||||
|
||||
'nearby_tile_animation_frame' : {'var': 0x63, 'start': 0, 'size': 8, 'param_function': signed_tile_offset},
|
||||
|
||||
'object_count' : {'var': 0x64, 'start': 16, 'size': 8, 'param_function': industry_count},
|
||||
'object_distance' : {'var': 0x64, 'start': 0, 'size': 16, 'param_function': industry_count},
|
||||
}
|
||||
|
||||
NML_VARACT2_GLOBALVARS_INV = { (v['var'], v['start'], (1 << v['size']) - 1): k for k, v in NML_VARACT2_GLOBALVARS.items()}
|
||||
|
||||
|
||||
def decode_action2(data):
|
||||
feature = data[0]
|
||||
set_id = data[1]
|
||||
@@ -559,10 +630,12 @@ def decode_action2(data):
|
||||
node = Temp(param)
|
||||
elif (var, shift, and_mask) == (0x7e, 0, 0xffffffff):
|
||||
node = Call(param)
|
||||
elif (var, shift, and_mask) == (0x41, 8, 0x1f):
|
||||
node = Var('tile_slope')
|
||||
else:
|
||||
node = Generic(var, shift, and_mask, 0, None, None)
|
||||
var_name = NML_VARACT2_GLOBALVARS_INV.get((var, shift, and_mask))
|
||||
if var_name is not None:
|
||||
node = Var(var_name)
|
||||
else:
|
||||
node = Generic(var, shift, and_mask, 0, None, None)
|
||||
|
||||
if first:
|
||||
root = node
|
||||
|
||||
Reference in New Issue
Block a user