Source code for tuxemon.prepare

# SPDX-License-Identifier: GPL-3.0
# Copyright (c) 2014-2023 William Edwards <shadowapex@gmail.com>, Benjamin Bean <superman2k5@gmail.com>
"""This module initializes the display and creates dictionaries of resources.
It contains all the static and dynamic variables used throughout the game such
as display resolution, scale, etc.
"""
from __future__ import annotations

import logging
import os.path
import re
from typing import TYPE_CHECKING, List

from tuxemon import config
from tuxemon.constants import paths

if TYPE_CHECKING:
    import pygame as pg

    SCREEN: pg.surface.Surface
    SCREEN_RECT: pg.rect.Rect
    JOYSTICKS: List[pg.joystick.Joystick]

logger = logging.getLogger(__name__)

# TODO: refact this out when other platforms supported (such as headless)
PLATFORM = "pygame"

# list of regular expressions to blacklist devices
joystick_blacklist = [
    re.compile(r"Microsoft.*Transceiver.*"),
    re.compile(r".*Synaptics.*", re.I),
    re.compile(r"Wacom*.", re.I),
]

# Create game dir if missing
if not os.path.isdir(paths.USER_STORAGE_DIR):
    os.makedirs(paths.USER_STORAGE_DIR)

# Create game data dir if missing
if not os.path.isdir(paths.USER_GAME_DATA_DIR):
    os.makedirs(paths.USER_GAME_DATA_DIR)

# Create game savegame dir if missing
if not os.path.isdir(paths.USER_GAME_SAVE_DIR):
    os.makedirs(paths.USER_GAME_SAVE_DIR)

# Generate default config
config.generate_default_config()

# Read "tuxemon.cfg" config from disk, update and write back
CONFIG = config.TuxemonConfig(paths.USER_CONFIG_PATH)

# Starting map
STARTING_MAP = "debug.tmx"

with open(paths.USER_CONFIG_PATH, "w") as fp:
    CONFIG.cfg.write(fp)

# Set up the screen size and caption
SCREEN_SIZE = CONFIG.resolution

# Set the native tile size so we know how much to scale our maps
# 1 tile = 16 pixels
TILE_SIZE = (16, 16)

# Set the status icon size so we know how much to scale our menu icons
ICON_SIZE = [7, 7]

# Set the healthbar _color
HP_COLOR = (112, 248, 168)

# Set the XP bar _color
XP_COLOR = (248, 245, 71)

# Native resolution is similar to the old gameboy resolution. This is
# used for scaling.
NATIVE_RESOLUTION = [240, 160]

# Set the character limit for setting a player name.
PLAYER_NAME_LIMIT = 15

# Fonts
FONT_BASIC = "PressStart2P.ttf"
FONT_CHINESE = "SourceHanSerifCN-Bold.otf"
FONT_JAPANESE = "SourceHanSerifJP-Bold.otf"

# If scaling is enabled, scale the tiles based on the resolution
if CONFIG.large_gui:
    SCALE = 2
    TILE_SIZE = (TILE_SIZE[0] * SCALE, TILE_SIZE[1] * SCALE)
elif CONFIG.scaling:
    SCALE = int(SCREEN_SIZE[0] / NATIVE_RESOLUTION[0])
    TILE_SIZE = (TILE_SIZE[0] * SCALE, TILE_SIZE[1] * SCALE)
else:
    SCALE = 1

# Reference user save dir
SAVE_PATH = os.path.join(paths.USER_GAME_SAVE_DIR, "slot")
SAVE_METHOD = "JSON"
# SAVE_METHOD = "CBOR"

DEV_TOOLS = CONFIG.dev_tools


[docs]def pygame_init() -> None: """Eventually refactor out of prepare.""" global JOYSTICKS global FONTS global MUSIC global SFX global GFX global SCREEN global SCREEN_RECT import pygame as pg # Configure databases and locale from tuxemon.locale import T T.collect_languages(CONFIG.recompile_translations) from tuxemon.db import db db.load() logger.debug("pygame init") pg.init() pg.display.set_caption(CONFIG.window_caption) from tuxemon import platform if platform.android: fullscreen = pg.FULLSCREEN else: fullscreen = pg.FULLSCREEN if CONFIG.fullscreen else 0 flags = pg.HWSURFACE | pg.DOUBLEBUF | fullscreen SCREEN = pg.display.set_mode(SCREEN_SIZE, flags) SCREEN_RECT = SCREEN.get_rect() # Disable the mouse cursor visibility pg.mouse.set_visible(not CONFIG.hide_mouse) # Set up any gamepads that we detect # The following event types will be generated by the joysticks: # JOYAXISMOTION JOYBALLMOTION JOYBUTTONDOWN JOYBUTTONUP JOYHATMOTION JOYSTICKS = list() pg.joystick.init() devices = [pg.joystick.Joystick(x) for x in range(pg.joystick.get_count())] # Initialize the individual joysticks themselves. for joystick in devices: name = joystick.get_name() print(f'Found joystick: "{name}"') blacklisted = any(i.match(name) for i in joystick_blacklist) if blacklisted: print(f'Ignoring joystick: "{name}"') else: print(f'Configuring joystick: "{name}"') joystick.init() JOYSTICKS.append(joystick)
# Initialize the game framework
[docs]def init() -> None: from tuxemon import platform platform.init() if PLATFORM == "pygame": pygame_init()
# Fetches a resource file # note: this has the potential of being a bottle neck doing to all the checking of paths # eventually, this should be configured at game launch, or in a config file instead # of looking all over creation for the required files.
[docs]def fetch(*args: str) -> str: relative_path = os.path.join(*args) for mod_name in CONFIG.mods: # when assets are in folder with the source path = os.path.join(paths.mods_folder, mod_name, relative_path) logger.debug("searching asset: %s", path) if os.path.exists(path): return path # when assets are in a system path (like for os packages and android) for root_path in paths.system_installed_folders: path = os.path.join(root_path, "mods", mod_name, relative_path) logger.debug("searching asset: %s", path) if os.path.exists(path): return path # mods folder is in same folder as the launch script path = os.path.join(paths.BASEDIR, "mods", mod_name, relative_path) logger.debug("searching asset: %s", path) if os.path.exists(path): return path raise OSError(f"cannot load file {relative_path}")