From 030a2ae5cb528699dc48c9ff37e44ad55843994d Mon Sep 17 00:00:00 2001 From: dP Date: Mon, 20 Dec 2021 13:56:58 +0300 Subject: [PATCH] alpine: Add creek objects --- grf/alpine/alpine.nml | 13 ++- grf/alpine/alpine.py | 175 ++++++++++++++++---------------------- grf/alpine/grf.py | 11 ++- grf/alpine/parser.py | 96 ++++++++++++++++++--- grf/alpine/parsetab.py | 45 +++++----- grf/alpine/readgrftest.py | 81 +++++++++++++++++- 6 files changed, 276 insertions(+), 145 deletions(-) diff --git a/grf/alpine/alpine.nml b/grf/alpine/alpine.nml index e268ddd390..e578f9a190 100644 --- a/grf/alpine/alpine.nml +++ b/grf/alpine/alpine.nml @@ -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) { } } -*/ \ No newline at end of file +/* */ \ No newline at end of file diff --git a/grf/alpine/alpine.py b/grf/alpine/alpine.py index a8852d20fe..26a6ceee6f 100644 --- a/grf/alpine/alpine.py +++ b/grf/alpine/alpine.py @@ -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') diff --git a/grf/alpine/grf.py b/grf/alpine/grf.py index ae9639f422..e0045ce78b 100644 --- a/grf/alpine/grf.py +++ b/grf/alpine/grf.py @@ -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('> 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('>' +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): diff --git a/grf/alpine/parsetab.py b/grf/alpine/parsetab.py index 27234cb13d..f884eebcf5 100644 --- a/grf/alpine/parsetab.py +++ b/grf/alpine/parsetab.py @@ -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), ] diff --git a/grf/alpine/readgrftest.py b/grf/alpine/readgrftest.py index f59eab8053..7018212dbe 100644 --- a/grf/alpine/readgrftest.py +++ b/grf/alpine/readgrftest.py @@ -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