import enum import struct import re from . base import rObject from . utils import * __all__ = ["rVersion"] # # See: IIgs Technote #76 Miscellaneous Resource Formats # See: IIgs TechNote #100 VersionVille # class Region(enum.Enum): verUS = 0 verFrance = 1 verBritain = 2 verGermany = 3 verItaly = 4 verNetherlands = 5 verBelgiumLux = 6 verFrBelgiumLux = 6 # alias verSweden = 7 verSpain = 8 verDenmark = 9 verPortugal = 10 verFrCanada = 11 verNorway = 12 verIsrael = 13 verJapan = 14 verAustralia = 15 verArabia = 16 verArabic = 16 # alias verFinland = 17 verFrSwiss = 18 verGrSwiss = 19 verGreece = 20 verIceland = 21 verMalta = 22 verCyprus = 23 verTurkey = 24 verYugoslavia = 25 verYugoCroatian = 25 # alias verIndia = 33 verIndiaHindi = 33 # alias verPakistan = 34 verLithuania = 41 verPoland = 42 verHungary = 43 verEstonia = 44 verLatvia = 45 verLapland = 46 verFaeroeIsl = 47 verIran = 48 verRussia = 49 verIreland = 50 verKorea = 51 verChina = 52 verTaiwan = 53 verThailand = 54 # import enums. globals().update(Region.__members__) __all__.extend(list(Region.__members__)) def _version_to_version(vstr): # 1 - major # 1.2 - major.minor # 1.2.3 - major.minor.bug # 1.2.3 [dabfr] - major.minor.bug develop/alpha/beta/final/release # 1.2.3r4 - major.minor.bug stage release version # release implies release version of 0. major = 0 minor = 0 bug = 0 stage = 'r' release = 0 m = re.match(r"([0-9.]+)([dabfr])?(\d+)?$", vstr) if not m: raise ValueError("Bad version string: {}".format(vstr)) if m[2]: stage = m[2] if m[3]: release = int(m[3], 10) vv = m[1].split('.') if len(vv) < 1 or len(vv) > 3 or not all(vv): raise ValueError("Bad version string: {}".format(vstr)) if len(vv) >= 1: major = int(vv[0], 10) if len(vv) >= 2: minor = int(vv[1], 10) if len(vv) >= 3: bug = int(vv[2], 10) # convert to bcd format. 25 (base 10) -> 0x25 (base 16) if major > 99: raise ValueError("major version too big: {}".format(major)) if minor > 9: raise ValueError("minor version too big: {}".format(minor)) if bug > 9: raise ValueError("bug version too big: {}".format(bug)) if release > 99: raise ValueError("release version too big: {}".format(release)) major = (major % 10) + (major // 10) * 16 release = (release % 10) + (release // 10) * 16 return (major, minor, bug, stage, release) class rVersion(rObject): rName = "rVersion" rType = 0x8029 def __init__(self, version, region, short, long, **kwargs): super().__init__(**kwargs) self.version = _version_to_version(version) self.region = region self.short = str_to_bytes(short) self.long = str_to_bytes(long) def __bytes__(self): major, minor, bug, stage, release = self.version stagemap = { 'd': 0b0010_0000, 'a': 0b0100_0000, 'b': 0b0110_0000, 'f': 0b1000_0000, 'r': 0b1010_0000, } bb = struct.pack("<4BH", release, stagemap[stage], (minor << 4) + (bug), major, self.region.value ) bb += bytes( (len(self.short), ) ) bb += self.short bb += bytes( (len(self.long), ) ) bb += self.long return bb def _rez_string(self): stagemap = { 'd': 'develop', 'a': 'alpha', 'b': 'beta', 'f': 'final', 'r': 'release', } major, minor, bug, stage, release = self.version return ( "\t{{ ${:02x}, ${:02x}, ${:02x}, {}, ${:02x} }}, /* version */\n" "\t{}, /* region */\n" "\t{}, /* short name */\n" "\t{} /* more info */".format( major, minor,bug, stagemap[stage], release, self.region.name, format_string(self.short), format_string(self.long) ))