def get_dummy_tileset(self) -> [Dma, Image.Image]: with open(os.path.join(data_dir(), 'fixed_floor', 'dummy.dma'), 'rb') as f: dma = FileType.DMA.deserialize(f.read()) return (dma, Image.open(os.path.join(data_dir(), 'fixed_floor', 'dummy.png')))
def _load_support_images(self): # Load the support us images try: # Discord image = Gtk.Image() image.show() image.set_from_file(os.path.join(data_dir(), "discord.png")) self.builder.get_object('suppot_us_discord_container').add(image) # Github image = Gtk.Image() image.show() image.set_from_file(os.path.join(data_dir(), "github.png")) self.builder.get_object('suppot_us_github_container').add(image) # Kofi image = Gtk.Image() image.show() image.set_from_file(os.path.join(data_dir(), "kofi.png")) self.builder.get_object('suppot_us_kofi_parakoopa_container').add(image) # Kofi 2 image = Gtk.Image() image.show() image.set_from_file(os.path.join(data_dir(), "kofi.png")) self.builder.get_object('suppot_us_kofi_psy_container').add(image) except BaseException: # We are not crashing over some images... pass
def __init__(self, zmappa: ZMappaT): self._tiles = [] base = zmappa.to_pil_tiles_minimized(ZMappaTVariation.OPAQUE).convert('RGBA') for y in range(0, 4): for x in range(0, ZMAPPAT_NB_TILES_PER_LINE // 2): self._tiles.append(pil_to_cairo_surface(base.crop( (x * ZMAPPAT_DIM, y * ZMAPPAT_DIM, (x + 1) * ZMAPPAT_DIM, (y + 1) * ZMAPPAT_DIM) ))) self._secondary = pil_to_cairo_surface(Image.open(os.path.join(data_dir(), 'minimap_secondary.png'))) self._buried = pil_to_cairo_surface(Image.open(os.path.join(data_dir(), 'minimap_buried.png')))
def on_btn_add_clicked(self, *args): from skytemple.module.map_bg.module import MAP_BG_PATH response, name = self._show_generic_input(_('Map Background Name'), _('Create Background')) if response != Gtk.ResponseType.OK: return name = name.lower() name_bg_list = name.upper() if len(name) < 1 or len(name) > 8: md = SkyTempleMessageDialog( SkyTempleMainController.window(), Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, _("The length of the map background name must be between 1-8 characters." )) md.run() md.destroy() return bpl_name = f'{name}.bpl' bpc_name = f'{name}.bpc' bma_name = f'{name}.bma' if self.module.project.file_exists(MAP_BG_PATH + bpl_name) or \ self.module.project.file_exists(MAP_BG_PATH + bpc_name) or \ self.module.project.file_exists(MAP_BG_PATH + bma_name): md = SkyTempleMessageDialog( SkyTempleMainController.window(), Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, _("A map background with this name already exists.")) md.run() md.destroy() return with open(os.path.join(data_dir(), 'empty.bpl'), 'rb') as f: empty_bpl = FileType.BPL.deserialize(f.read()) with open(os.path.join(data_dir(), 'empty.bma'), 'rb') as f: empty_bma = FileType.BMA.deserialize(f.read()) with open(os.path.join(data_dir(), 'empty.bpc'), 'rb') as f: empty_bpc = FileType.BPC.deserialize(f.read()) # Write to ROM self.module.project.create_new_file(MAP_BG_PATH + bpl_name, empty_bpl, FileType.BPL) self.module.project.create_new_file(MAP_BG_PATH + bma_name, empty_bma, FileType.BMA) self.module.project.create_new_file(MAP_BG_PATH + bpc_name, empty_bpc, FileType.BPC) self.module.add_map(name_bg_list) md = SkyTempleMessageDialog(SkyTempleMainController.window(), Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, _("Map background added successfully"), is_success=True) md.run() md.destroy()
def _load_support_images(self): # Load the Discord badge try: raise Exception("Disabled for now.") url = 'https://raster.shields.io/discord/710190644152369162?label=Discord' req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'}) # Some weird issue on Windows with PyInstaller...: ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE input_stream = Gio.MemoryInputStream.new_from_data( urllib.request.urlopen(req, context=ctx, timeout=1).read(), None) pixbuf = Pixbuf.new_from_stream(input_stream, None) image = Gtk.Image() image.show() image.set_from_pixbuf(pixbuf) self.builder.get_object('discord_icon_container').add(image) except BaseException: # We are not crashing over a Discord badge... logger.error("Failed loading the Discord badge.", exc_info=sys.exc_info()) # Load the support us images try: # Discord image = Gtk.Image() image.show() image.set_from_file(os.path.join(data_dir(), "discord.png")) self.builder.get_object('suppot_us_discord_container').add(image) # Github image = Gtk.Image() image.show() image.set_from_file(os.path.join(data_dir(), "github.png")) self.builder.get_object('suppot_us_github_container').add(image) # Kofi image = Gtk.Image() image.show() image.set_from_file(os.path.join(data_dir(), "kofi.png")) self.builder.get_object('suppot_us_kofi_parakoopa_container').add( image) # Kofi 2 image = Gtk.Image() image.show() image.set_from_file(os.path.join(data_dir(), "kofi.png")) self.builder.get_object('suppot_us_kofi_psy_container').add(image) except BaseException: # We are not crashing over some images... pass
def __init__(self, project: 'RomProject'): self._project = project self._loader_surface_dims: Optional[Tuple[int, int]] = None self._loader_surface: Optional[cairo.ImageSurface] = None self._loaded__monsters: Dict[ActorSpriteKey, SpriteAndOffsetAndDims] = {} self._loaded__monsters_outlines: Dict[ActorSpriteKey, SpriteAndOffsetAndDims] = {} self._loaded__actor_placeholders: Dict[ActorSpriteKey, SpriteAndOffsetAndDims] = {} self._loaded__objects: Dict[str, SpriteAndOffsetAndDims] = {} self._loaded__traps: Dict[int, SpriteAndOffsetAndDims] = {} self._loaded__items: Dict[int, SpriteAndOffsetAndDims] = {} self._requests__monsters: List[ActorSpriteKey] = [] self._requests__monsters_outlines: List[ActorSpriteKey] = [] self._requests__actor_placeholders: List[ActorSpriteKey] = [] self._requests__objects: List[str] = [] self._requests__traps: List[int] = [] self._requests__items: List[int] = [] self._monster_md: ModelContext[Md] = self._project.open_file_in_rom( MONSTER_MD, FileType.MD, threadsafe=True) self._monster_bin: ModelContext[ BinPack] = self._project.open_file_in_rom(MONSTER_BIN, FileType.BIN_PACK, threadsafe=True) self._dungeon_bin: Optional[ModelContext[DungeonBinPack]] = None self._stripes = Image.open(os.path.join(data_dir(), 'stripes.png')) self._loaded_standins: Optional[Dict[int, int]] = None
def __init__(self, project: 'RomProject'): self._project = project self._loader_surface_dims = None self._loader_surface = None self._loaded__monsters: Dict[ActorSpriteKey, SpriteAndOffsetAndDims] = {} self._loaded__monsters_outlines: Dict[ActorSpriteKey, SpriteAndOffsetAndDims] = {} self._loaded__actor_placeholders: Dict[ActorSpriteKey, SpriteAndOffsetAndDims] = {} self._loaded__objects: Dict[str, SpriteAndOffsetAndDims] = {} self._requests__monsters: List[ActorSpriteKey] = [] self._requests__monsters_outlines: List[ActorSpriteKey] = [] self._requests__actor_placeholders: List[ActorSpriteKey] = [] self._requests__objects: List[str] = [] self._monster_md: Md = self._project.open_file_in_rom(MONSTER_MD, FileType.MD, threadsafe=True) self._monster_bin: BinPack = self._project.open_file_in_rom( MONSTER_BIN, FileType.BIN_PACK, threadsafe=True) self._stripes = Image.open(os.path.join(data_dir(), 'stripes.png')) self._loaded_standins = None
def is_available(self): if not ENABLE_GFXCRUNCH: return False path = os.path.join(data_dir(), GFXCRUNCH_BIN) if not os.path.exists(path): return False if not sys.platform.startswith('win'): if which(WINE_BIN) is None: return False return True
def process(self): # BPC: start_offset = self.bpc.layers[0].chunk_tilemap_len with open(os.path.join(data_dir(), 'created_with.png'), 'rb') as f: palettes = self._import_to_bpc(0, Image.open(f)) # BMA: for x in range(0, 11): for y in range(0, 8): index = y * 11 + x % 11 + start_offset if index == 0: index = 1 self.bma.place_chunk(0, x + 11, y, index) # BPL: self.bpl.palettes[6:14] = palettes[0:8]
def on_btn_add_clicked(self, *args): from skytemple.module.sprite.module import GROUND_DIR, WAN_FILE_EXT response, name = self._show_generic_input(_('Sprite Name'), _('Create Object Sprite')) if response != Gtk.ResponseType.OK: return name = name.lower() if len(name) < 1 or len(name) > 10: md = SkyTempleMessageDialog( SkyTempleMainController.window(), Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, _("The length of the sprite name must be between 1-10 characters." )) md.run() md.destroy() return obj_name = f'{GROUND_DIR}/{name}.{WAN_FILE_EXT}' if self.module.project.file_exists(obj_name): md = SkyTempleMessageDialog( SkyTempleMainController.window(), Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, _("A sprite with this name already exists.")) md.run() md.destroy() return with open(os.path.join(data_dir(), 'empty.wan'), 'rb') as f: empty_wan = f.read() # Write to ROM self.module.project.create_file_manually(obj_name, empty_wan) self.module.add_wan(f'{name}.{WAN_FILE_EXT}') md = SkyTempleMessageDialog(SkyTempleMainController.window(), Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, _("Object sprite added successfully"), is_success=True) md.run() md.destroy()
def __init__(self, parent: Gtk.Window, dialog_flags: Gtk.DialogFlags, message_type: Gtk.MessageType, buttons_type: Gtk.ButtonsType, *args, **kwargs): img = IMGS[message_type] if IS_SUCCESS in kwargs: if kwargs[IS_SUCCESS]: img = IMG_HAPPY del kwargs[IS_SUCCESS] self.img: Gtk.Image = Gtk.Image.new_from_file( os.path.join(data_dir(), img)) super().__init__(parent, dialog_flags, message_type, buttons_type, *args, **kwargs) box: Gtk.Box = self.get_message_area() parent: Gtk.Box = box.get_parent() box.set_valign(Gtk.Align.CENTER) parent.pack_start(self.img, False, False, 0) parent.pack_start(box, False, False, 0) parent.child_set_property(self.img, 'position', 0) self.img.show()
def get_gfxcrunch_cmd(self) -> Tuple[str, List[str], bool]: """Returns the CMD for gfxcrunch and the base argument list and if shell=True""" if sys.platform.startswith('win'): return os.path.join(data_dir(), GFXCRUNCH_BIN), [], False return WINE_BIN, [os.path.join(data_dir(), GFXCRUNCH_BIN)], False
def _get_empty_scene(self) -> Ssa: with open(os.path.join(data_dir(), 'empty.ssx'), 'rb') as f: return FileType.SSA.deserialize(f.read())
def main(): # TODO: Gtk.Application: https://python-gtk-3-tutorial.readthedocs.io/en/latest/application.html path = os.path.abspath(os.path.dirname(__file__)) # Load settings settings = SkyTempleSettingsStore() if sys.platform.startswith('win'): # Load theming under Windows _load_theme(settings) # Solve issue #12 try: from skytemple_files.common.platform_utils.win import win_set_error_mode win_set_error_mode() except BaseException: # This really shouldn't fail, but it's not important enough to crash over pass if sys.platform.startswith('darwin'): # Load theming under macOS _load_theme(settings) # The search path is wrong if SkyTemple is executed as an .app bundle if getattr(sys, 'frozen', False): path = os.path.dirname(sys.executable) if sys.platform.startswith('linux') and gdk_backend() == GDK_BACKEND_BROADWAY: gtk_settings = Gtk.Settings.get_default() gtk_settings.set_property("gtk-theme-name", 'Arc-Dark') gtk_settings.set_property("gtk-application-prefer-dark-theme", True) itheme: Gtk.IconTheme = Gtk.IconTheme.get_default() itheme.append_search_path(os.path.abspath(icons())) itheme.append_search_path(os.path.abspath(os.path.join(data_dir(), "icons"))) itheme.append_search_path(os.path.abspath(os.path.join(get_debugger_data_dir(), "icons"))) itheme.rescan_if_needed() # Load Builder and Window builder = make_builder(os.path.join(path, "skytemple.glade")) main_window: Window = builder.get_object("main_window") main_window.set_role("SkyTemple") GLib.set_application_name("SkyTemple") GLib.set_prgname("skytemple") # TODO: Deprecated but the only way to set the app title on GNOME...? main_window.set_wmclass("SkyTemple", "SkyTemple") # Load CSS style_provider = Gtk.CssProvider() with open(os.path.join(path, "skytemple.css"), 'rb') as f: css = f.read() style_provider.load_from_data(css) Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(), style_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION ) # Load async task runner thread AsyncTaskRunner.instance() # Init. core events event_manager = EventManager.instance() if settings.get_integration_discord_enabled(): try: from skytemple.core.events.impl.discord import DiscordPresence discord_listener = DiscordPresence() event_manager.register_listener(discord_listener) except BaseException: pass # Load modules Modules.load() # Load main window + controller MainController(builder, main_window, settings) main_window.present() main_window.set_icon_name('skytemple') try: Gtk.main() except (KeyboardInterrupt, SystemExit): AsyncTaskRunner.end()
# but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with SkyTemple. If not, see <https://www.gnu.org/licenses/>. import logging import os import sys import locale import gettext from skytemple.core.ui_utils import data_dir, APP, gdk_backend, GDK_BACKEND_BROADWAY # Setup locale :( from skytemple.core.settings import SkyTempleSettingsStore LOCALE_DIR = os.path.abspath(os.path.join(data_dir(), 'locale')) settings = SkyTempleSettingsStore() if hasattr(locale, 'bindtextdomain'): libintl = locale elif sys.platform.startswith('win'): import ctypes import ctypes.util if os.getenv('LANG') is None: lang, enc = locale.getdefaultlocale() os.environ['LANG'] = lang ctypes.cdll.msvcrt._putenv ("LANG=" + lang) libintl_loc = os.path.join(os.path.dirname(__file__), 'libintl-8.dll') if os.path.exists(libintl_loc): libintl = ctypes.cdll.LoadLibrary(libintl_loc) else: libintl = ctypes.cdll.LoadLibrary(ctypes.util.find_library('libintl-8'))
def _update_status(self, status): self.status = status img: Gtk.Image = self.builder.get_object('duskako') img.set_from_file(os.path.join(data_dir(), IMGS[status]))