| 
									
										
										
										
											2017-11-28 09:36:32 -05:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2019-12-09 19:27:56 +01:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2017-12-17 00:25:46 -05:00
										 |  |  | import subprocess | 
					
						
							| 
									
										
										
										
											2017-11-28 09:36:32 -05:00
										 |  |  | import sys | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-17 18:38:54 -05:00
										 |  |  | def int16_as_bytes(value): | 
					
						
							|  |  |  |     value = value & 0xFFFF | 
					
						
							|  |  |  |     return [value & 0xFF, (value >> 8) & 0xFF] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def int32_as_bytes(value): | 
					
						
							|  |  |  |     value = value & 0xFFFFFFFF | 
					
						
							|  |  |  |     return [value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, (value >> 24) & 0xFF] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-22 22:51:54 -04:00
										 |  |  | def pc_to_snes(value): | 
					
						
							|  |  |  |     return ((value<<1) & 0x7F0000)|(value & 0x7FFF)|0x8000 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def snes_to_pc(value): | 
					
						
							|  |  |  |     return ((value & 0x7F0000)>>1)|(value & 0x7FFF) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-14 10:42:27 +01:00
										 |  |  | def parse_player_names(names, players, teams): | 
					
						
							|  |  |  |     names = [n for n in re.split(r'[, ]', names) if n] | 
					
						
							|  |  |  |     ret = [] | 
					
						
							|  |  |  |     while names or len(ret) < teams: | 
					
						
							|  |  |  |         team = [n[:16] for n in names[:players]] | 
					
						
							|  |  |  |         while len(team) != players: | 
					
						
							|  |  |  |             team.append(f"Player {len(team) + 1}") | 
					
						
							|  |  |  |         ret.append(team) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         names = names[players:] | 
					
						
							|  |  |  |     return ret | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-28 09:36:32 -05:00
										 |  |  | def is_bundled(): | 
					
						
							|  |  |  |     return getattr(sys, 'frozen', False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def local_path(path): | 
					
						
							|  |  |  |     if local_path.cached_path is not None: | 
					
						
							|  |  |  |         return os.path.join(local_path.cached_path, path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if is_bundled(): | 
					
						
							|  |  |  |         # we are running in a bundle | 
					
						
							| 
									
										
										
										
											2017-12-17 00:25:46 -05:00
										 |  |  |         local_path.cached_path = sys._MEIPASS # pylint: disable=protected-access,no-member | 
					
						
							| 
									
										
										
										
											2017-11-28 09:36:32 -05:00
										 |  |  |     else: | 
					
						
							|  |  |  |         # we are running in a normal Python environment | 
					
						
							|  |  |  |         local_path.cached_path = os.path.dirname(os.path.abspath(__file__)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return os.path.join(local_path.cached_path, path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local_path.cached_path = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def output_path(path): | 
					
						
							|  |  |  |     if output_path.cached_path is not None: | 
					
						
							|  |  |  |         return os.path.join(output_path.cached_path, path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not is_bundled(): | 
					
						
							|  |  |  |         output_path.cached_path = '.' | 
					
						
							|  |  |  |         return os.path.join(output_path.cached_path, path) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         # has been packaged, so cannot use CWD for output. | 
					
						
							|  |  |  |         if sys.platform == 'win32': | 
					
						
							|  |  |  |             #windows | 
					
						
							|  |  |  |             import ctypes.wintypes | 
					
						
							|  |  |  |             CSIDL_PERSONAL = 5       # My Documents | 
					
						
							|  |  |  |             SHGFP_TYPE_CURRENT = 0   # Get current, not default value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH) | 
					
						
							|  |  |  |             ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_PERSONAL, None, SHGFP_TYPE_CURRENT, buf) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             documents = buf.value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         elif sys.platform == 'darwin': | 
					
						
							| 
									
										
										
										
											2017-12-17 00:25:46 -05:00
										 |  |  |             from AppKit import NSSearchPathForDirectoriesInDomains # pylint: disable=import-error | 
					
						
							| 
									
										
										
										
											2017-11-28 09:36:32 -05:00
										 |  |  |             # http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains | 
					
						
							|  |  |  |             NSDocumentDirectory = 9 | 
					
						
							|  |  |  |             NSUserDomainMask = 1 | 
					
						
							|  |  |  |             # True for expanding the tilde into a fully qualified path | 
					
						
							|  |  |  |             documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, True)[0] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             raise NotImplementedError('Not supported yet') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output_path.cached_path = os.path.join(documents, 'ALttPEntranceRandomizer') | 
					
						
							|  |  |  |         if not os.path.exists(output_path.cached_path): | 
					
						
							|  |  |  |             os.mkdir(output_path.cached_path) | 
					
						
							|  |  |  |         return os.path.join(output_path.cached_path, path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | output_path.cached_path = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def open_file(filename): | 
					
						
							|  |  |  |     if sys.platform == 'win32': | 
					
						
							|  |  |  |         os.startfile(filename) | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2017-12-17 00:25:46 -05:00
										 |  |  |         open_command = 'open' if sys.platform == 'darwin' else 'xdg-open' | 
					
						
							| 
									
										
										
										
											2017-11-28 09:36:32 -05:00
										 |  |  |         subprocess.call([open_command, filename]) | 
					
						
							| 
									
										
										
										
											2017-12-02 09:21:04 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | def close_console(): | 
					
						
							|  |  |  |     if sys.platform == 'win32': | 
					
						
							|  |  |  |         #windows | 
					
						
							|  |  |  |         import ctypes.wintypes | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             ctypes.windll.kernel32.FreeConsole() | 
					
						
							| 
									
										
										
										
											2017-12-17 00:25:46 -05:00
										 |  |  |         except Exception: | 
					
						
							| 
									
										
										
										
											2017-12-02 09:21:04 -05:00
										 |  |  |             pass | 
					
						
							| 
									
										
										
										
											2018-01-01 14:42:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | def make_new_base2current(old_rom='Zelda no Densetsu - Kamigami no Triforce (Japan).sfc', new_rom='working.sfc'): | 
					
						
							|  |  |  |     from collections import OrderedDict | 
					
						
							|  |  |  |     import json | 
					
						
							|  |  |  |     import hashlib | 
					
						
							|  |  |  |     with open(old_rom, 'rb') as stream: | 
					
						
							|  |  |  |         old_rom_data = bytearray(stream.read()) | 
					
						
							|  |  |  |     with open(new_rom, 'rb') as stream: | 
					
						
							|  |  |  |         new_rom_data = bytearray(stream.read()) | 
					
						
							|  |  |  |     # extend to 2 mb | 
					
						
							|  |  |  |     old_rom_data.extend(bytearray([0x00] * (2097152 - len(old_rom_data)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     out_data = OrderedDict() | 
					
						
							|  |  |  |     for idx, old in enumerate(old_rom_data): | 
					
						
							|  |  |  |         new = new_rom_data[idx] | 
					
						
							|  |  |  |         if old != new: | 
					
						
							|  |  |  |             out_data[idx] = [int(new)] | 
					
						
							|  |  |  |     for offset in reversed(list(out_data.keys())): | 
					
						
							|  |  |  |         if offset - 1 in out_data: | 
					
						
							|  |  |  |             out_data[offset-1].extend(out_data.pop(offset)) | 
					
						
							|  |  |  |     with open('data/base2current.json', 'wt') as outfile: | 
					
						
							|  |  |  |         json.dump([{key:value} for key, value in out_data.items()], outfile, separators=(",", ":")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     basemd5 = hashlib.md5() | 
					
						
							|  |  |  |     basemd5.update(new_rom_data) | 
					
						
							|  |  |  |     return "New Rom Hash: " + basemd5.hexdigest() |