Workwork
This commit is contained in:
		| @@ -1,2 +1,10 @@ | ||||
| class Buffer(object): | ||||
|     pass | ||||
|     def __init__(self): | ||||
|         self.__size = 0 | ||||
|         self.__data = '' | ||||
|  | ||||
|     def setSize(self, size): | ||||
|         self.__size = size | ||||
|  | ||||
|     def getData(self): | ||||
|         return self.__data | ||||
|   | ||||
							
								
								
									
										97
									
								
								einsteingame/formatter.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								einsteingame/formatter.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| import struct | ||||
| from enum import Enum | ||||
|  | ||||
| class Formatter(object): | ||||
|     class CmdType(Enum): | ||||
|         EMPTY_CMD = 0 | ||||
|         TEXT_COMMAND = 1 | ||||
|         INT_ARG = 2 | ||||
|         STRING_ARG = 3 | ||||
|         DOUBLE_ARG = 4 | ||||
|         FLOAT_ARG = 5 | ||||
|  | ||||
|     def __init__(self, data, offset): | ||||
|         cnt = struct.unpack('i', data[offset:offset + 4])[0] | ||||
|  | ||||
|         if cnt == 0: | ||||
|             commandsCnt = argsCnt = 0 | ||||
|             commands = NULL | ||||
|             args = NULL | ||||
|  | ||||
|         offset += 4 | ||||
|         commands = [] | ||||
|         commandsCnt = 0 | ||||
|  | ||||
|         maxArg = 0 | ||||
|         argNo = None | ||||
|  | ||||
|         for i in range(0, cnt): | ||||
|             typ = data[offset] | ||||
|             offset += 1 | ||||
|             size = struct.unpack('i', data[offset:offset + 4])[0] | ||||
|             offset += 4 | ||||
|  | ||||
|             if typ == 1: | ||||
|                 commands.append({ | ||||
|                     "type": self.CmdType.TEXT_COMMAND, | ||||
|                     "data": data[offset:offset + size].decode('utf-8'), | ||||
|                 }) | ||||
|             elif typ == 2: | ||||
|                 argNo = struct.unapack('i', data[offset:offset + 4])[0] | ||||
|  | ||||
|                 if argNo > maxArg: | ||||
|                     maxArg = argNo | ||||
|  | ||||
|                 commands.append({ | ||||
|                     "type": self.CmdType.INT_ARG, | ||||
|                     "data": argNo, | ||||
|                 }) | ||||
|             elif typ == 3: | ||||
|                 argNo = struct.unapack('i', data[offset:offset + 4])[0] | ||||
|  | ||||
|                 if argNo > maxArg: | ||||
|                     maxArg = argNo | ||||
|  | ||||
|                 commands.append({ | ||||
|                     "type": self.CmdType.STRING_ARG, | ||||
|                     "data": argNo, | ||||
|                 }) | ||||
|             elif typ == 3: | ||||
|                 argNo = struct.unapack('i', data[offset:offset + 4])[0] | ||||
|  | ||||
|                 if argNo > maxArg: | ||||
|                     maxArg = argNo | ||||
|  | ||||
|                 commands.append({ | ||||
|                     "type": self.CmdType.FLOAT_ARG, | ||||
|                     "data": argNo, | ||||
|                 }) | ||||
|             elif typ == 3: | ||||
|                 argNo = struct.unapack('i', data[offset:offset + 4])[0] | ||||
|  | ||||
|                 if argNo > maxArg: | ||||
|                     maxArg = argNo | ||||
|  | ||||
|                 commands.append({ | ||||
|                     "type": self.CmdType.DOUBLE_ARG, | ||||
|                     "data": argNo, | ||||
|                 }) | ||||
|  | ||||
|             offset += size; | ||||
|  | ||||
|         argsCnt = maxArg | ||||
|  | ||||
|         if argsCnt == 0: | ||||
|             args = None | ||||
|         else: | ||||
|             args = [] | ||||
|  | ||||
|             for i in range(0, len(commands)): | ||||
|                 args.append[0] | ||||
|  | ||||
|             for i in range(0, len(commands)): | ||||
|                 c = commands[i] | ||||
|  | ||||
|                 if c.type == INT_ARG or c.type == STRING_ARG or c.type == FLOAT_ARG or c.type == DOUBLE_ARG: | ||||
|                     no = c.data | ||||
|                     args[no - 1] = c.type | ||||
| @@ -2,10 +2,21 @@ from locale import setlocale, LC_ALL, LC_NUMERIC | ||||
|  | ||||
| class Locale(object): | ||||
|     def __init__(self): | ||||
|         self.__country = None | ||||
|         self.__language = None | ||||
|  | ||||
|         self.parseLocale(setlocale(LC_ALL, "")) | ||||
|         # hack because of numbers in Lua | ||||
|         setlocale(LC_NUMERIC, "C") | ||||
|  | ||||
|     @property | ||||
|     def country(self): | ||||
|         return self.__country | ||||
|  | ||||
|     @property | ||||
|     def language(self): | ||||
|         return self.__language | ||||
|  | ||||
|     def parseLocale(self, name): | ||||
|         pos = name.find('.') | ||||
|  | ||||
| @@ -21,17 +32,16 @@ class Locale(object): | ||||
|         pos = langAndCountry.find('_') | ||||
|  | ||||
|         if pos < 0: | ||||
|             language = langAndCountry | ||||
|             country = "" | ||||
|             self.__language = langAndCountry | ||||
|             self.__country = '' | ||||
|         else: | ||||
|             language = langAndCountry[0:pos] | ||||
|             country = langAndCountry[pos + 1:] | ||||
|             self.__language = langAndCountry[0:pos] | ||||
|             self.__country = langAndCountry[pos + 1:] | ||||
|  | ||||
|         language = language.lower() | ||||
|         country = country.lower() | ||||
|         self.__language = self.__language.lower() | ||||
|         self.__country = self.__country.lower() | ||||
|         encoding = encoding.upper() | ||||
|  | ||||
|  | ||||
| def splitFileName(fileName): | ||||
|     """ | ||||
|     Returns tuple of name, extension, lang, country | ||||
| @@ -87,10 +97,10 @@ def getScore(lang, country, locale): | ||||
|  | ||||
|     score = 0 | ||||
|  | ||||
|     if locale.getCountry() == country: | ||||
|     if locale.country == country: | ||||
|         score += 2 | ||||
|  | ||||
|     if locale.getLanguage() == lang: | ||||
|     if locale.language == lang: | ||||
|         score += 4 | ||||
|  | ||||
|     return score | ||||
|   | ||||
| @@ -11,7 +11,8 @@ gi.require_version('Clutter', '1.0') | ||||
| from gi.repository import Clutter | ||||
| from gi.repository import GLib | ||||
|  | ||||
| from .resources import ResourcesCollection | ||||
| from .messages import msg | ||||
| from .resources import ResourcesCollection, resources | ||||
| from .utils import ensureDirExists | ||||
|  | ||||
| win32 = False | ||||
| @@ -19,8 +20,7 @@ apple = False | ||||
| developer = True | ||||
|  | ||||
| PREFIX = '/usr' | ||||
| # Clutter.init() | ||||
| # | ||||
|  | ||||
| # stage = Clutter.Stage() | ||||
| # stage.connect('destroy', lambda x: Clutter.main_quit()) | ||||
| # stage.title = 'Test' | ||||
| @@ -48,6 +48,21 @@ PREFIX = '/usr' | ||||
| # stage.show() | ||||
| # Clutter.main() | ||||
|  | ||||
| stage = None | ||||
| sound = None | ||||
|  | ||||
| def initScreen(): | ||||
|     Clutter.init() | ||||
|  | ||||
|     stage = Clutter.Stage() | ||||
|     stage.connect('destroy', lambda x: Clutter.main_quit()) | ||||
|     stage.set_size(800, 600) | ||||
|     stage.title = 'Einstein' | ||||
|  | ||||
| def initAudio(): | ||||
|     # sound = Sound() | ||||
|     pass | ||||
|  | ||||
| def loadResources(selfPath): | ||||
|     dirs = [] | ||||
|  | ||||
| @@ -65,7 +80,7 @@ def loadResources(selfPath): | ||||
|     dirs.append("res") | ||||
|     dirs.append(".") | ||||
|     resources = ResourcesCollection(dirs) | ||||
|     msg.load() | ||||
|     msg.load(resources) | ||||
|  | ||||
| def main(script, *args): | ||||
|     ensureDirExists(os.environ["HOME"] + "/.einstein") | ||||
| @@ -73,7 +88,5 @@ def main(script, *args): | ||||
|     loadResources(sys.argv[0]) | ||||
|     initScreen() | ||||
|     initAudio() | ||||
|     menu() | ||||
|     getStorage().flush() | ||||
|  | ||||
|     # screen.doneCursors(); | ||||
|     # menu() | ||||
|     # getStorage().flush() | ||||
|   | ||||
							
								
								
									
										66
									
								
								einsteingame/messages.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								einsteingame/messages.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| import struct | ||||
|  | ||||
| from .buffer import Buffer | ||||
| from .formatter import Formatter | ||||
|  | ||||
| class Messages(object): | ||||
|     def __init__(self): | ||||
|         self.__messages = {} | ||||
|  | ||||
|     def load(self, resources): | ||||
|         buf = Buffer() | ||||
|  | ||||
|         resources.forEachInGroup('messages', lambda res: self.loadFromResource(res, buf)) | ||||
|  | ||||
|     def loadFromResource(self, resource, buf): | ||||
|         if not resource: | ||||
|             return | ||||
|  | ||||
|         cnt = resource.getVariantsCount() | ||||
|  | ||||
|         for variant in resource.variants: | ||||
|             if variant: | ||||
|                 try: | ||||
|                     score = variant.i18nScore | ||||
|                     data = variant.getData() | ||||
|                     self.loadBundle(score, data) | ||||
|                 except Exception as e: | ||||
|                     print("Error loading text bundle {}: {}".format(resource.getName(), e)) | ||||
|  | ||||
|                     raise | ||||
|  | ||||
|     def loadBundle(self, score, data): | ||||
|         if data[0:3] != b"CMF": | ||||
|             raise Exception("Invalid format of message file!") | ||||
|  | ||||
|         version = struct.unpack('i', data[3:7])[0] | ||||
|         if version != 1: | ||||
|             raise Exception("Unknown version of message file!") | ||||
|  | ||||
|         offset = struct.unpack('i', data[len(data) - 4:])[0] | ||||
|         cnt = struct.unpack('i', data[offset:offset + 4])[0] | ||||
|         offset += 4 | ||||
|  | ||||
|         for i in range(0, cnt): | ||||
|             sz = struct.unpack('i', data[offset:offset + 4])[0] | ||||
|             offset += 4; | ||||
|  | ||||
|             if sz > 0: | ||||
|                 name = data[offset:offset + sz].decode('utf-8') | ||||
|                 msgOffset = struct.unpack('i', data[offset + sz:offset + sz + 4])[0] | ||||
|  | ||||
|                 if name in self.__messages: | ||||
|                     ss = self.__messages[name] | ||||
|                     if ss['score'] <= score: | ||||
|                         ss['score'] = score | ||||
|                         ss['message'] = Formatter(data, msgOffset) | ||||
|                 else: | ||||
|                     self.__messages[name] = { | ||||
|                         "score": score, | ||||
|                         "message": Formatter(data, msgOffset), | ||||
|                     } | ||||
|  | ||||
|             offset += sz + 4 | ||||
|  | ||||
|  | ||||
| msg = Messages() | ||||
| @@ -1,6 +1,7 @@ | ||||
| from os import listdir | ||||
| import struct | ||||
| import io | ||||
| import zlib | ||||
|  | ||||
| from .buffer import Buffer | ||||
| from .i18n import splitFileName, getScore, locale | ||||
| @@ -9,16 +10,73 @@ class ResourceError(Exception): | ||||
|     def __init__(self, code=None): | ||||
|         self.code = code | ||||
|  | ||||
| class ResVariant(object): | ||||
|     def __init__(self, resFile, i18nScore, dirEntry): | ||||
|         self.__file = resFile | ||||
|         self.__i18nScore = i18nScore | ||||
|         self.__offset = dirEntry['offset'] | ||||
|         self.__unpackedSize = dirEntry['unpackedSize'] | ||||
|         self.__packedSize = dirEntry['packedSize'] | ||||
|         self.__level = dirEntry['level'] | ||||
|         self.__refCnt = 0 | ||||
|         self.__data = None | ||||
|  | ||||
|     @property | ||||
|     def i18nScore(self): | ||||
|         return self.__i18nScore | ||||
|  | ||||
|     def getData(self): | ||||
|         buf = Buffer() | ||||
|  | ||||
|         buf.setSize(self.__unpackedSize) | ||||
|  | ||||
|         if self.__refCnt == 0: | ||||
|             self.__data = self.__file.load(self.__offset, self.__packedSize, self.__unpackedSize, self.__level) | ||||
|  | ||||
|         return self.__data | ||||
|  | ||||
| class Resource(object): | ||||
|     def __init__(self, file, i18nScore, entry, name): | ||||
|         self.__variants = [] | ||||
|         self.__name = name | ||||
|  | ||||
|         self.addVariant(file, i18nScore, entry) | ||||
|  | ||||
|     def addVariant(self, file, i18nScore, entry): | ||||
|         if len(self.__variants) == 0: | ||||
|             self.__variants.append(ResVariant(file, i18nScore, entry)) | ||||
|  | ||||
|             return | ||||
|  | ||||
|         try: | ||||
|             best_variant = [idx for idx, variant in enumerate(self.__variants) \ | ||||
|                                     if variant.i18nScore == i18nScore][0] | ||||
|  | ||||
|             self.__variants[best_variant] = ResVariant(file, i18nScore, entry) | ||||
|         except KeyError: | ||||
|             self.__variants.append(ResVariant(file, i18nScore, entry)) | ||||
|             self.__variants.sort(key=lambda variant: variant.getI18nScore()) | ||||
|  | ||||
|     def getVariantsCount(self): | ||||
|         return len(self.__variants) | ||||
|  | ||||
|     @property | ||||
|     def variants(self): | ||||
|         return self.__variants | ||||
|  | ||||
|     def getName(self): | ||||
|         return self.__name | ||||
|  | ||||
| class ResourceFile(object): | ||||
|     def __init__(self, fileName, buf=None): | ||||
|         self.__name = fileName | ||||
|  | ||||
|         if buf is not None: | ||||
|             buffer = buf | ||||
|             ownBuffer = False | ||||
|             self.__buffer = buf | ||||
|             self.__ownBuffer = False | ||||
|         else: | ||||
|             buffer = Buffer() | ||||
|             ownBuffer = True | ||||
|             self.__buffer = Buffer() | ||||
|             self.__ownBuffer = True | ||||
|  | ||||
|         try: | ||||
|             self.__stream = open(self.__name, 'rb') | ||||
| @@ -37,6 +95,27 @@ class ResourceFile(object): | ||||
|         except IOError as e: | ||||
|             raise Exception("Error loading resource file '{}': {}".format(self.__name, e.message)) | ||||
|  | ||||
|     def load(self, offset, packedSize, unpackedSize, level): | ||||
|         try: | ||||
|             if level == 0: | ||||
|                 self.__stream.seek(offset, io.SEEK_SET) | ||||
|                 self.__stream.read() | ||||
|  | ||||
|                 return self.__stream.read(unpackedSize) | ||||
|  | ||||
|             self.__stream.seek(offset, io.SEEK_SET) | ||||
|             data = self.__stream.read(packedSize) | ||||
|  | ||||
|             return self.unpack(data) | ||||
|         except Exception as e: | ||||
|             print("Eror loading resource: {}".format(e)) | ||||
|  | ||||
|             raise | ||||
|  | ||||
|     # void ResourceFile::unpack(char *in, int inSize, char *out, int outSize) | ||||
|     def unpack(self, data): | ||||
|         return zlib.decompress(data) | ||||
|  | ||||
|     def readInt(self): | ||||
|         return struct.unpack('i', self.__stream.read(4))[0] | ||||
|  | ||||
| @@ -55,7 +134,7 @@ class ResourceFile(object): | ||||
|  | ||||
|     def getDirectory(self): | ||||
|         try: | ||||
|             self.__stream.seek(-8, io.SEEK_END); | ||||
|             self.__stream.seek(-8, io.SEEK_END) | ||||
|         except IOError: | ||||
|             raise Exception("Error reading {} directory".format(self.__name)) | ||||
|  | ||||
| @@ -63,7 +142,7 @@ class ResourceFile(object): | ||||
|         count = self.readInt() | ||||
|  | ||||
|         try: | ||||
|             self.__stream.seek(start, io.SEEK_SET); | ||||
|             self.__stream.seek(start, io.SEEK_SET) | ||||
|         except IOError: | ||||
|             raise Exception("Error reading {} directory".format(self.__name)) | ||||
|  | ||||
| @@ -89,9 +168,13 @@ class ResourcesCollection: | ||||
|         self.__files = [] | ||||
|         self.__buffer = None | ||||
|         self.__resources = {} | ||||
|         self.__groups = {} | ||||
|         self.loadResourceFiles(directories) | ||||
|         self.processFiles() | ||||
|  | ||||
|     def __iter__(self): | ||||
|         return iter(self.__resources.values()) | ||||
|  | ||||
|     def loadResourceFiles(self, directories): | ||||
|         for directory in directories: | ||||
|             try: | ||||
| @@ -119,9 +202,18 @@ class ResourcesCollection: | ||||
|                         res = Resource(res_file, score, de, resName) | ||||
|                         self.__resources[resName] = res | ||||
|  | ||||
|                         if len(de.group) > 0: | ||||
|                             groups[de.group].append(res) | ||||
|                         if len(de['group']) > 0: | ||||
|                             if de['group'] not in self.__groups: | ||||
|                                 self.__groups[de['group']] = [] | ||||
|  | ||||
|                             self.__groups[de['group']].append(res) | ||||
|                     else: | ||||
|                         res.addVariant(file, score, de) | ||||
|                         res.addVariant(res_file, score, de) | ||||
|  | ||||
|             directory.clear() | ||||
|  | ||||
|     def forEachInGroup(self, group, func): | ||||
|         for resource in self.__groups[group]: | ||||
|             func(resource) | ||||
|  | ||||
| resources = None | ||||
|   | ||||
							
								
								
									
										8
									
								
								einsteingame/screen.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								einsteingame/screen.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| class Screen(object): | ||||
|     def __init__(self): | ||||
|         self.__screen = None | ||||
|         self.__mouseImage = None | ||||
|         self.__mouseSave = None | ||||
|         self.__mouseVisible = None | ||||
|         self.__regionsList = None | ||||
|         self.__maxRegionsList = 0 | ||||
		Reference in New Issue
	
	Block a user