├── .github └── workflows │ └── devskim.yml ├── .gitignore ├── .gitmodules ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── LICENSE ├── README.md ├── SECURITY.md ├── bin └── renpy.ps1 ├── console └── debug.rpy ├── crowdin.yml ├── game ├── audio │ ├── boom.wav │ ├── car_door.wav │ ├── house_lo.wav │ └── secosmic_lo.wav ├── bytecode.rpyb ├── eileen_happy.png ├── gui.rpy ├── gui │ ├── bar │ │ ├── bottom.png │ │ ├── left.png │ │ ├── right.png │ │ └── top.png │ ├── button │ │ ├── check_foreground.png │ │ ├── check_selected_foreground.png │ │ ├── choice_hover_background.png │ │ ├── choice_idle_background.png │ │ ├── hover_background.png │ │ ├── idle_background.png │ │ ├── quick_hover_background.png │ │ ├── quick_idle_background.png │ │ ├── radio_foreground.png │ │ ├── radio_selected_foreground.png │ │ ├── slot_hover_background.png │ │ └── slot_idle_background.png │ ├── frame.png │ ├── game_menu.png │ ├── main_menu.png │ ├── namebox.png │ ├── notify.png │ ├── nvl.png │ ├── overlay │ │ ├── confirm.png │ │ ├── game_menu.png │ │ └── main_menu.png │ ├── phone │ │ ├── bar │ │ │ ├── bottom.png │ │ │ ├── left.png │ │ │ ├── right.png │ │ │ └── top.png │ │ ├── button │ │ │ ├── check_foreground.png │ │ │ ├── check_selected_foreground.png │ │ │ ├── choice_hover_background.png │ │ │ ├── choice_idle_background.png │ │ │ ├── hover_background.png │ │ │ ├── idle_background.png │ │ │ ├── radio_foreground.png │ │ │ ├── radio_selected_foreground.png │ │ │ ├── slot_hover_background.png │ │ │ └── slot_idle_background.png │ │ ├── nvl.png │ │ ├── overlay │ │ │ ├── game_menu.png │ │ │ └── main_menu.png │ │ ├── scrollbar │ │ │ ├── horizontal_hover_bar.png │ │ │ ├── horizontal_hover_thumb.png │ │ │ ├── horizontal_idle_bar.png │ │ │ ├── horizontal_idle_thumb.png │ │ │ ├── vertical_hover_bar.png │ │ │ ├── vertical_hover_thumb.png │ │ │ ├── vertical_idle_bar.png │ │ │ └── vertical_idle_thumb.png │ │ ├── slider │ │ │ ├── horizontal_hover_bar.png │ │ │ ├── horizontal_hover_thumb.png │ │ │ ├── horizontal_idle_bar.png │ │ │ ├── horizontal_idle_thumb.png │ │ │ ├── vertical_hover_bar.png │ │ │ ├── vertical_hover_thumb.png │ │ │ ├── vertical_idle_bar.png │ │ │ └── vertical_idle_thumb.png │ │ └── textbox.png │ ├── scrollbar │ │ ├── horizontal_hover_bar.png │ │ ├── horizontal_hover_thumb.png │ │ ├── horizontal_idle_bar.png │ │ ├── horizontal_idle_thumb.png │ │ ├── vertical_hover_bar.png │ │ ├── vertical_hover_thumb.png │ │ ├── vertical_idle_bar.png │ │ └── vertical_idle_thumb.png │ ├── skip.png │ ├── slider │ │ ├── horizontal_hover_bar.png │ │ ├── horizontal_hover_thumb.png │ │ ├── horizontal_idle_bar.png │ │ ├── horizontal_idle_thumb.png │ │ ├── vertical_hover_bar.png │ │ ├── vertical_hover_thumb.png │ │ ├── vertical_idle_bar.png │ │ └── vertical_idle_thumb.png │ ├── textbox.png │ └── window_icon.png ├── images │ ├── alien1.webp │ ├── alien2.webp │ ├── alien3.webp │ ├── background.webp │ ├── bomb.webp │ ├── explosion1.webp │ ├── player1.webp │ └── shot.webp ├── minigames │ ├── aliens.py │ └── aliens.rpy ├── options.rpy ├── renpy_utility_tool │ ├── core.rpy │ ├── flags.rpy │ ├── log_system.rpy │ ├── notify.rpy │ └── utility.rpy ├── renpygame │ └── renpygame_screen.rpy ├── screens.rpy ├── script.rpy └── tl │ ├── None │ └── common.rpym │ ├── french │ └── common.rpy │ ├── german │ └── common.rpy │ ├── italian │ └── common.rpy │ └── spanish │ └── common.rpy ├── pythonpackages ├── __init__.py ├── renpygame │ ├── __init__.py │ ├── display.py │ ├── draw.py │ ├── event.py │ ├── image.py │ ├── mixer.py │ ├── mixer_music.py │ ├── rect.py │ ├── renpygameCDD.py │ ├── renpygameCanvas.py │ ├── renpygameRender.py │ ├── sprite.py │ └── transform.py └── renpygame_pygame │ ├── __init__.py │ ├── display.py │ ├── draw.py │ ├── event.py │ ├── image.py │ ├── rect.py │ ├── sprite.py │ └── transform.py ├── translation_convertor_potorpy.py └── translation_convertor_rpytopo.py /.github/workflows/devskim.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | name: DevSkim 7 | 8 | on: 9 | push: 10 | branches: [ "main" ] 11 | pull_request: 12 | branches: [ "main" ] 13 | schedule: 14 | - cron: '23 14 * * 5' 15 | 16 | jobs: 17 | lint: 18 | name: DevSkim 19 | runs-on: ubuntu-20.04 20 | permissions: 21 | actions: read 22 | contents: read 23 | security-events: write 24 | steps: 25 | - name: Checkout code 26 | uses: actions/checkout@v3 27 | 28 | - name: Run DevSkim scanner 29 | uses: microsoft/DevSkim-Action@v1 30 | 31 | - name: Upload DevSkim scan results to GitHub Security tab 32 | uses: github/codeql-action/upload-sarif@v2 33 | with: 34 | sarif_file: devskim-results.sarif 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | .DS_Store 131 | errors.txt 132 | log.txt 133 | traceback.txt 134 | *.rpyc 135 | *.rpymc 136 | game/saves 137 | game/cache 138 | *.bak 139 | 140 | # Templete files 141 | .renpy-sdk 142 | Wiki 143 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "wiki"] 2 | path = wiki 3 | url = https://github.com/DRincs-Productions/Renpygame.wiki.git 4 | [submodule "pythonpackages/renpy_utility"] 5 | path = pythonpackages/renpy_utility 6 | url = https://github.com/DRincs-Productions/renpy-utility-lib 7 | branch = python-lib -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "luquedaniel.languague-renpy", 6 | "ms-python.python", 7 | "ms-vscode.powershell", 8 | "mrorz.language-gettext", 9 | "ms-python.black-formatter" 10 | ] 11 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Usare IntelliSense per informazioni sui possibili attributi. 3 | // Al passaggio del mouse vengono visualizzate le descrizioni degli attributi esistenti. 4 | // Per altre informazioni, visitare: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Ren'Py: Setup", 9 | "type": "PowerShell", 10 | "request": "launch", 11 | "script": "echo \"${input:RenPySdk}\" > .renpy-sdk", 12 | }, 13 | { 14 | "name": "Ren'Py: Run", 15 | "type": "PowerShell", 16 | "request": "launch", 17 | "script": "bin/renpy.ps1 run", 18 | "cwd": "${workspaceFolder}" 19 | }, 20 | { 21 | "name": "Ren'Py: Recompile & Run", 22 | "type": "PowerShell", 23 | "request": "launch", 24 | "script": "bin/renpy.ps1 compile; bin/renpy.ps1 run", 25 | "cwd": "${workspaceFolder}" 26 | }, 27 | { 28 | "name": "Ren'Py: Delete Persistent", 29 | "type": "PowerShell", 30 | "request": "launch", 31 | "script": "bin/renpy.ps1 rmpersistent", 32 | "cwd": "${workspaceFolder}" 33 | }, 34 | { 35 | "name": "Ren'Py: Lint", 36 | "type": "PowerShell", 37 | "request": "launch", 38 | "script": "bin/renpy.ps1 lint", 39 | "cwd": "${workspaceFolder}" 40 | }, 41 | { 42 | "name": "Ren'Py: Distribute", 43 | "type": "PowerShell", 44 | "request": "launch", 45 | "script": "bin/renpy.ps1 distribute", 46 | "cwd": "${workspaceFolder}" 47 | }, 48 | ], 49 | "inputs": [ 50 | { 51 | "id": "RenPySdk", 52 | "description": "Paste the path to your Ren'Py SDK folder", 53 | "type": "promptString", 54 | } 55 | ] 56 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // format 3 | "[renpy]": { 4 | "editor.defaultFormatter": "ms-python.python", 5 | }, 6 | "[python]": { 7 | "editor.defaultFormatter": "ms-python.black-formatter" 8 | }, 9 | "python.formatting.provider": "none", 10 | "editor.formatOnSave": true, 11 | // reorganise imports 12 | "editor.codeActionsOnSave": { 13 | "source.organizeImports": true 14 | }, 15 | // hide 16 | "files.exclude": { 17 | "**/*.rpyc": true, 18 | "**/*.rpa": true, 19 | "**/*.rpymc": true, 20 | "**/cache/": true 21 | }, 22 | // olther 23 | "extensions.ignoreRecommendations": false, 24 | "diffEditor.ignoreTrimWhitespace": false, 25 | "python.analysis.typeCheckingMode": "basic", 26 | // color 27 | "editor.tokenColorCustomizations": { 28 | "textMateRules": [ 29 | { 30 | "scope": "renpy.meta.plain", 31 | "settings": { 32 | "fontStyle": "" 33 | } 34 | }, 35 | { 36 | "scope": "renpy.meta.i", 37 | "settings": { 38 | "fontStyle": "italic" 39 | } 40 | }, 41 | { 42 | "scope": "renpy.meta.b", 43 | "settings": { 44 | "fontStyle": "bold" 45 | } 46 | }, 47 | { 48 | "scope": [ 49 | "renpy.meta.u", 50 | "renpy.meta.a" 51 | ], 52 | "settings": { 53 | "fontStyle": "underline" 54 | } 55 | }, 56 | { 57 | "scope": "renpy.meta.s", 58 | "settings": { 59 | "fontStyle": "strikethrough" 60 | } 61 | }, 62 | { 63 | "scope": "renpy.meta.i renpy.meta.b", 64 | "settings": { 65 | "fontStyle": "italic bold" 66 | } 67 | }, 68 | { 69 | "scope": "renpy.meta.i renpy.meta.u", 70 | "settings": { 71 | "fontStyle": "italic underline" 72 | } 73 | }, 74 | { 75 | "scope": "renpy.meta.i renpy.meta.s", 76 | "settings": { 77 | "fontStyle": "italic strikethrough" 78 | } 79 | }, 80 | { 81 | "scope": "renpy.meta.b renpy.meta.u", 82 | "settings": { 83 | "fontStyle": "bold underline" 84 | } 85 | }, 86 | { 87 | "scope": "renpy.meta.b renpy.meta.s", 88 | "settings": { 89 | "fontStyle": "bold strikethrough" 90 | } 91 | }, 92 | { 93 | "scope": "renpy.meta.u renpy.meta.s", 94 | "settings": { 95 | "fontStyle": "underline strikethrough" 96 | } 97 | }, 98 | { 99 | "scope": "renpy.meta.i renpy.meta.b renpy.meta.u", 100 | "settings": { 101 | "fontStyle": "italic bold underline" 102 | } 103 | }, 104 | { 105 | "scope": "renpy.meta.i renpy.meta.b renpy.meta.s", 106 | "settings": { 107 | "fontStyle": "italic bold strikethrough" 108 | } 109 | }, 110 | { 111 | "scope": "renpy.meta.i renpy.meta.u renpy.meta.s", 112 | "settings": { 113 | "fontStyle": "italic underline strikethrough" 114 | } 115 | }, 116 | { 117 | "scope": "renpy.meta.b renpy.meta.u renpy.meta.s", 118 | "settings": { 119 | "fontStyle": "bold underline strikethrough" 120 | } 121 | }, 122 | { 123 | "scope": "renpy.meta.i renpy.meta.b renpy.meta.u renpy.meta.s", 124 | "settings": { 125 | "fontStyle": "italic bold underline strikethrough" 126 | } 127 | }, 128 | { 129 | "scope": "renpy.meta.color.text", 130 | "settings": { 131 | "foreground": "#ffffff" 132 | } 133 | }, 134 | { 135 | "scope": "renpy.meta.color.#cfc", 136 | "settings": { 137 | "foreground": "#cfc" 138 | } 139 | }, 140 | { 141 | "scope": "renpy.meta.color.#fcc", 142 | "settings": { 143 | "foreground": "#fcc" 144 | } 145 | }, 146 | { 147 | "scope": "renpy.meta.color.#fff", 148 | "settings": { 149 | "foreground": "#fff" 150 | } 151 | }, 152 | { 153 | "scope": "renpy.meta.color.#570058", 154 | "settings": { 155 | "foreground": "#570058" 156 | } 157 | }, 158 | { 159 | "scope": "renpy.meta.color.#cc5dcd", 160 | "settings": { 161 | "foreground": "#cc5dcd" 162 | } 163 | }, 164 | { 165 | "scope": "renpy.meta.color.#ff0000", 166 | "settings": { 167 | "foreground": "#ff0000" 168 | } 169 | }, 170 | { 171 | "scope": "renpy.meta.color.#f00", 172 | "settings": { 173 | "foreground": "#f00" 174 | } 175 | }, 176 | { 177 | "scope": "renpy.meta.color.#00ff00", 178 | "settings": { 179 | "foreground": "#00ff00" 180 | } 181 | }, 182 | { 183 | "scope": "renpy.meta.color.#e59400", 184 | "settings": { 185 | "foreground": "#e59400" 186 | } 187 | }, 188 | { 189 | "scope": "renpy.meta.color.#ffbe00", 190 | "settings": { 191 | "foreground": "#ffbe00" 192 | } 193 | }, 194 | { 195 | "scope": "renpy.meta.color.#00ccff", 196 | "settings": { 197 | "foreground": "#00ccff" 198 | } 199 | }, 200 | { 201 | "scope": "renpy.meta.color.#f5bc02", 202 | "settings": { 203 | "foreground": "#f5bc02" 204 | } 205 | }, 206 | { 207 | "scope": "renpy.meta.color.#ffffff", 208 | "settings": { 209 | "foreground": "#ffffff" 210 | } 211 | }, 212 | { 213 | "scope": "renpy.meta.color.#ffff", 214 | "settings": { 215 | "foreground": "#ffff" 216 | } 217 | }, 218 | { 219 | "scope": "renpy.meta.color.#000000", 220 | "settings": { 221 | "foreground": "#000000" 222 | } 223 | }, 224 | { 225 | "scope": "renpy.meta.color.#00008b", 226 | "settings": { 227 | "foreground": "#00008b" 228 | } 229 | }, 230 | { 231 | "scope": "renpy.meta.color.e is", 232 | "settings": { 233 | "foreground": "e is" 234 | } 235 | }, 236 | { 237 | "scope": "renpy.meta.color.{/color", 238 | "settings": { 239 | "foreground": "{/color" 240 | } 241 | }, 242 | { 243 | "scope": "renpy.meta.color. is an ", 244 | "settings": { 245 | "foreground": " is an " 246 | } 247 | }, 248 | { 249 | "scope": "renpy.meta.color./color}", 250 | "settings": { 251 | "foreground": "/color}" 252 | } 253 | } 254 | ] 255 | } 256 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 DRincs Productions 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Renpygame 2 | 3 | **IMPORTANT**: This is a continuation of a project not mine, abandoned from 2008 [Renpygame](https://renpy.org/wiki/renpy/frameworks/Renpygame) (not working). Currently compared to 2008, it is not possible to directly use the [pygame_sdl2](https://github.com/renpy/pygame_sdl2) library, especially to "draw". 4 | 5 | 6 | 7 | Renpygame is a framework that allows pygame games to be integrated with Ren'Py. It's intended for people who are capable programmers. 8 | 9 | The idea is to create a library that uses [pygame_sdl2](https://github.com/renpy/pygame_sdl2) and overrides functions that can be handled by the [renpy](https://github.com/renpy/renpy) library. 10 | 11 | The big problem is that the mode for drawing is very different. The only way I found was to use [CDD](https://www.renpy.org/doc/html/cdd.html) and use that events to draw and update an element. 12 | 13 | Use of events to draw limits a lot -> you can't create loops to update a renpy.Displayable -> that's why you can't copy and paste a game, but modify it slightly. 14 | 15 | ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/67595890/236701292-d36a5f0f-d4e8-4e53-8671-a79fd903786b.gif) 16 | 17 | ---- 18 | 19 | ## TO DOWNLOAD THIS TEST PROJECT 20 | ```shell 21 | # Basic command to download projects from git 22 | git clone https://github.com/DRincs-Productions/Renpygame 23 | # IMPORTANT -> Will add the libraries needed to run the program 24 | cd Renpygame 25 | git submodule update --init --recursive 26 | 27 | ``` 28 | ---- 29 | 30 | ## Other minigames 31 | 32 | (Add topics `renpygame` to add it to the list) 33 | https://github.com/topics/renpygame 34 | 35 | ## Instructions 36 | 37 | **[Wiki](https://github.com/DRincs-Productions/Renpygame/wiki)** 38 | 39 | ## Why use pygame-renpygame and not renpy-CDD? 40 | 41 | pygame-renpygame's pros: 42 | 43 | - You can use pygame and renpy functions 44 | - huge number of minigames on github 45 | - popularity (pygame is also often used in universities) 46 | - typification (I am endeavouring to add the type everywhere) 47 | 48 | renpy's pros: 49 | 50 | - durability ([CDD](https://www.renpy.org/doc/html/cdd.html) is developed by the same developer as renpy) 51 | - you can create simple and effective effects on images thanks to [Transforms](https://www.renpy.org/doc/html/transforms.html) (in the future it could also be integrated into Renpygame) 52 | 53 | ## Performance 54 | 55 | ([in development](https://github.com/DRincs-Productions/Renpygame/issues/10)) 56 | 57 | (I don't made any tests for now) Renpygame use [CDD](https://www.renpy.org/doc/html/cdd.html) for draw and renpy for open a file, but I use a typification and is a external library. So, the performance is the same as renpy, excluding possible implementation errors. 58 | 59 | 60 | ## Insert Toolkit in your project 61 | 62 | I recommend the following ways to include it in your project: 63 | 64 | - [**Pull branch**](#pull-branch) (to **insert** it into your game and **update** it easily) 65 | - [**Fork**](https://docs.github.com/en/get-started/quickstart/fork-a-repo) (to improve the repo or create a Toolkit based on mine) 66 | - [Manually](https://github.com/DRincs-Productions/Renpygame/releases) (not recommended) 67 | 68 | ### Pull branch 69 | 70 | To **insert** or **update** the Toolkit in your repo with Pull branch I recommend the following procedure: 71 | 72 | (only if you want to insert the repo) Create a new empty branch, in the example I'll use **renpygame** 73 | 74 | ```shell 75 | git checkout -b renpygame 76 | git checkout renpygame 77 | git config pull.rebase false 78 | git pull https://github.com/DRincs-Productions/Renpygame.git tool-only --allow-unrelated-histories 79 | git submodule update --remote 80 | 81 | ``` 82 | 83 | At the end make a merge inside the arm of the project. 84 | 85 | ## Supported Modules 86 | 87 | A good number of functions should already work even if they have not yet been tested 88 | 89 | - [ ] renpygame.color 90 | - [x] renpygame.constants (Still to be tested, should already be working) 91 | - [x] renpygame.cursors (Still to be tested, should already be working) 92 | - [ ] renpygame.display (Incomplete) 93 | - [x] renpygame.display.Surface 94 | - [x] renpygame.draw 95 | - [x] renpygame.event (Still to be tested, should already be working) 96 | - [ ] renpygame.font 97 | - [ ] renpygame.image (Incomplete) 98 | - [ ] renpygame.joystick 99 | - [ ] renpygame.key (Incomplete) 100 | - [x] renpygame.locals (Still to be tested, should already be working) 101 | - [ ] renpygame.mixer (Incomplete) 102 | - [ ] renpygame.mixer.music (Incomplete) 103 | - [x] renpygame.mouse (Still to be tested, should already be working) 104 | - [x] renpygame.rect 105 | - [ ] renpygame.sprite (Incomplete) 106 | - [x] renpygame.time (Still to be tested, should already be working) 107 | - [ ] renpygame.transform (Incomplete) 108 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /bin/renpy.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [string] $Command = "run" 3 | ) 4 | $RenPy = Get-Content (Resolve-Path ".renpy-sdk") 5 | $RenPy = [string]::join("", ($RenPy.Split("`n"))) 6 | 7 | if ($IsWindows -or $IsLinux -or $IsMacOS) { 8 | if ($IsWindows) { 9 | Write-Output "Renpy will run on a Windows system" 10 | Write-Output "Using Ren'Py SDK: $RenPy\renpy.exe" 11 | Start-Process -FilePath "$RenPy\renpy.exe" -ArgumentList ". $Command" -Wait 12 | } 13 | if ($IsLinux) { 14 | Write-Output "Renpy will run on a Linux system" 15 | Write-Output "Using Ren'Py SDK: $RenPy/renpy.sh" 16 | Start-Process -FilePath "$RenPy/renpy.sh" -ArgumentList ". $Command" -Wait 17 | } 18 | if ($IsMacOS) { 19 | Write-Output "Renpy will run on a MacOS system" 20 | Write-Output "Using Ren'Py SDK: $RenPy/renpy.sh" 21 | Start-Process -FilePath "$RenPy/renpy.sh" -ArgumentList ". $Command" -Wait 22 | } 23 | } 24 | else { 25 | Write-Output "Renpy will run on an unknown system, may not work" 26 | Write-Output "Using Ren'Py SDK: $RenPy/renpy.sh" 27 | Start-Process -FilePath "$RenPy/renpy.sh" -ArgumentList ". $Command" -Wait 28 | } 29 | 30 | -------------------------------------------------------------------------------- /console/debug.rpy: -------------------------------------------------------------------------------- 1 | init python: 2 | from inspect import getargspec 3 | config.debug = True 4 | config.developer = True 5 | 6 | def scan_(s, *types): 7 | for k, v in globals().items(): 8 | if ( 9 | s.lower() in k.lower() 10 | # and (not exclude or not isinstance(v, exclude)) 11 | and (not types or isinstance(v, types)) 12 | ): 13 | yield k, v 14 | 15 | def l_(s, *types): 16 | results = list(scan_(s, *types)) 17 | width = max(map(lambda (k, v): len(k), results or [('', None)])) 18 | print "-", s, types, "found", len(results), "----------------" 19 | for k, v in results: 20 | print k.ljust(width), v_(v) 21 | print "Done." 22 | 23 | def v_(v): 24 | if callable(v): 25 | try: 26 | return getargspec(v) 27 | except Exception as e: 28 | return repr(v) + " -- Exception: " + repr(e) 29 | return repr(v) 30 | -------------------------------------------------------------------------------- /crowdin.yml: -------------------------------------------------------------------------------- 1 | files: 2 | - source: /game/tl/crowdin/*.po 3 | ignore: 4 | - /game/tl/crowdin/common.* 5 | translation: /game/tl/%language%/%original_file_name% 6 | -------------------------------------------------------------------------------- /game/audio/boom.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/audio/boom.wav -------------------------------------------------------------------------------- /game/audio/car_door.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/audio/car_door.wav -------------------------------------------------------------------------------- /game/audio/house_lo.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/audio/house_lo.wav -------------------------------------------------------------------------------- /game/audio/secosmic_lo.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/audio/secosmic_lo.wav -------------------------------------------------------------------------------- /game/bytecode.rpyb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/bytecode.rpyb -------------------------------------------------------------------------------- /game/eileen_happy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/eileen_happy.png -------------------------------------------------------------------------------- /game/gui.rpy: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ## Initialization 3 | ################################################################################ 4 | 5 | ## The init offset statement causes the initialization statements in this file 6 | ## to run before init statements in any other file. 7 | init offset = -2 8 | 9 | ## Calling gui.init resets the styles to sensible default values, and sets the 10 | ## width and height of the game. 11 | init python: 12 | gui.init(1920, 1080) 13 | 14 | 15 | 16 | ################################################################################ 17 | ## GUI Configuration Variables 18 | ################################################################################ 19 | 20 | 21 | ## Colors ###################################################################### 22 | ## 23 | ## The colors of text in the interface. 24 | 25 | ## An accent color used throughout the interface to label and highlight text. 26 | define gui.accent_color = '#cc6600' 27 | 28 | ## The color used for a text button when it is neither selected nor hovered. 29 | define gui.idle_color = '#888888' 30 | 31 | ## The small color is used for small text, which needs to be brighter/darker to 32 | ## achieve the same effect. 33 | define gui.idle_small_color = '#aaaaaa' 34 | 35 | ## The color that is used for buttons and bars that are hovered. 36 | define gui.hover_color = '#e0a366' 37 | 38 | ## The color used for a text button when it is selected but not focused. A 39 | ## button is selected if it is the current screen or preference value. 40 | define gui.selected_color = '#ffffff' 41 | 42 | ## The color used for a text button when it cannot be selected. 43 | define gui.insensitive_color = '#8888887f' 44 | 45 | ## Colors used for the portions of bars that are not filled in. These are not 46 | ## used directly, but are used when re-generating bar image files. 47 | define gui.muted_color = '#512800' 48 | define gui.hover_muted_color = '#7a3d00' 49 | 50 | ## The colors used for dialogue and menu choice text. 51 | define gui.text_color = '#ffffff' 52 | define gui.interface_text_color = '#ffffff' 53 | 54 | 55 | ## Fonts and Font Sizes ######################################################## 56 | 57 | ## The font used for in-game text. 58 | define gui.text_font = "DejaVuSans.ttf" 59 | 60 | ## The font used for character names. 61 | define gui.name_text_font = "DejaVuSans.ttf" 62 | 63 | ## The font used for out-of-game text. 64 | define gui.interface_text_font = "DejaVuSans.ttf" 65 | 66 | ## The size of normal dialogue text. 67 | define gui.text_size = 33 68 | 69 | ## The size of character names. 70 | define gui.name_text_size = 45 71 | 72 | ## The size of text in the game's user interface. 73 | define gui.interface_text_size = 33 74 | 75 | ## The size of labels in the game's user interface. 76 | define gui.label_text_size = 36 77 | 78 | ## The size of text on the notify screen. 79 | define gui.notify_text_size = 24 80 | 81 | ## The size of the game's title. 82 | define gui.title_text_size = 75 83 | 84 | 85 | ## Main and Game Menus ######################################################### 86 | 87 | ## The images used for the main and game menus. 88 | define gui.main_menu_background = "gui/main_menu.png" 89 | define gui.game_menu_background = "gui/game_menu.png" 90 | 91 | 92 | ## Dialogue #################################################################### 93 | ## 94 | ## These variables control how dialogue is displayed on the screen one line at a 95 | ## time. 96 | 97 | ## The height of the textbox containing dialogue. 98 | define gui.textbox_height = 278 99 | 100 | ## The placement of the textbox vertically on the screen. 0.0 is the top, 0.5 is 101 | ## center, and 1.0 is the bottom. 102 | define gui.textbox_yalign = 1.0 103 | 104 | 105 | ## The placement of the speaking character's name, relative to the textbox. 106 | ## These can be a whole number of pixels from the left or top, or 0.5 to center. 107 | define gui.name_xpos = 360 108 | define gui.name_ypos = 0 109 | 110 | ## The horizontal alignment of the character's name. This can be 0.0 for left- 111 | ## aligned, 0.5 for centered, and 1.0 for right-aligned. 112 | define gui.name_xalign = 0.0 113 | 114 | ## The width, height, and borders of the box containing the character's name, or 115 | ## None to automatically size it. 116 | define gui.namebox_width = None 117 | define gui.namebox_height = None 118 | 119 | ## The borders of the box containing the character's name, in left, top, right, 120 | ## bottom order. 121 | define gui.namebox_borders = Borders(5, 5, 5, 5) 122 | 123 | ## If True, the background of the namebox will be tiled, if False, the 124 | ## background of the namebox will be scaled. 125 | define gui.namebox_tile = False 126 | 127 | 128 | ## The placement of dialogue relative to the textbox. These can be a whole 129 | ## number of pixels relative to the left or top side of the textbox, or 0.5 to 130 | ## center. 131 | define gui.dialogue_xpos = 402 132 | define gui.dialogue_ypos = 75 133 | 134 | ## The maximum width of dialogue text, in pixels. 135 | define gui.dialogue_width = 1116 136 | 137 | ## The horizontal alignment of the dialogue text. This can be 0.0 for left- 138 | ## aligned, 0.5 for centered, and 1.0 for right-aligned. 139 | define gui.dialogue_text_xalign = 0.0 140 | 141 | 142 | ## Buttons ##################################################################### 143 | ## 144 | ## These variables, along with the image files in gui/button, control aspects of 145 | ## how buttons are displayed. 146 | 147 | ## The width and height of a button, in pixels. If None, Ren'Py computes a size. 148 | define gui.button_width = None 149 | define gui.button_height = None 150 | 151 | ## The borders on each side of the button, in left, top, right, bottom order. 152 | define gui.button_borders = Borders(6, 6, 6, 6) 153 | 154 | ## If True, the background image will be tiled. If False, the background image 155 | ## will be linearly scaled. 156 | define gui.button_tile = False 157 | 158 | ## The font used by the button. 159 | define gui.button_text_font = gui.interface_text_font 160 | 161 | ## The size of the text used by the button. 162 | define gui.button_text_size = gui.interface_text_size 163 | 164 | ## The color of button text in various states. 165 | define gui.button_text_idle_color = gui.idle_color 166 | define gui.button_text_hover_color = gui.hover_color 167 | define gui.button_text_selected_color = gui.selected_color 168 | define gui.button_text_insensitive_color = gui.insensitive_color 169 | 170 | ## The horizontal alignment of the button text. (0.0 is left, 0.5 is center, 1.0 171 | ## is right). 172 | define gui.button_text_xalign = 0.0 173 | 174 | 175 | ## These variables override settings for different kinds of buttons. Please see 176 | ## the gui documentation for the kinds of buttons available, and what each is 177 | ## used for. 178 | ## 179 | ## These customizations are used by the default interface: 180 | 181 | define gui.radio_button_borders = Borders(27, 6, 6, 6) 182 | 183 | define gui.check_button_borders = Borders(27, 6, 6, 6) 184 | 185 | define gui.confirm_button_text_xalign = 0.5 186 | 187 | define gui.page_button_borders = Borders(15, 6, 15, 6) 188 | 189 | define gui.quick_button_borders = Borders(15, 6, 15, 0) 190 | define gui.quick_button_text_size = 21 191 | define gui.quick_button_text_idle_color = gui.idle_small_color 192 | define gui.quick_button_text_selected_color = gui.accent_color 193 | 194 | ## You can also add your own customizations, by adding properly-named variables. 195 | ## For example, you can uncomment the following line to set the width of a 196 | ## navigation button. 197 | 198 | # define gui.navigation_button_width = 250 199 | 200 | 201 | ## Choice Buttons ############################################################## 202 | ## 203 | ## Choice buttons are used in the in-game menus. 204 | 205 | define gui.choice_button_width = 1185 206 | define gui.choice_button_height = None 207 | define gui.choice_button_tile = False 208 | define gui.choice_button_borders = Borders(150, 8, 150, 8) 209 | define gui.choice_button_text_font = gui.text_font 210 | define gui.choice_button_text_size = gui.text_size 211 | define gui.choice_button_text_xalign = 0.5 212 | define gui.choice_button_text_idle_color = "#cccccc" 213 | define gui.choice_button_text_hover_color = "#ffffff" 214 | define gui.choice_button_text_insensitive_color = "#444444" 215 | 216 | 217 | ## File Slot Buttons ########################################################### 218 | ## 219 | ## A file slot button is a special kind of button. It contains a thumbnail 220 | ## image, and text describing the contents of the save slot. A save slot uses 221 | ## image files in gui/button, like the other kinds of buttons. 222 | 223 | ## The save slot button. 224 | define gui.slot_button_width = 414 225 | define gui.slot_button_height = 309 226 | define gui.slot_button_borders = Borders(15, 15, 15, 15) 227 | define gui.slot_button_text_size = 21 228 | define gui.slot_button_text_xalign = 0.5 229 | define gui.slot_button_text_idle_color = gui.idle_small_color 230 | define gui.slot_button_text_selected_idle_color = gui.selected_color 231 | define gui.slot_button_text_selected_hover_color = gui.hover_color 232 | 233 | ## The width and height of thumbnails used by the save slots. 234 | define config.thumbnail_width = 384 235 | define config.thumbnail_height = 216 236 | 237 | ## The number of columns and rows in the grid of save slots. 238 | define gui.file_slot_cols = 3 239 | define gui.file_slot_rows = 2 240 | 241 | 242 | ## Positioning and Spacing ##################################################### 243 | ## 244 | ## These variables control the positioning and spacing of various user interface 245 | ## elements. 246 | 247 | ## The position of the left side of the navigation buttons, relative to the left 248 | ## side of the screen. 249 | define gui.navigation_xpos = 60 250 | 251 | ## The vertical position of the skip indicator. 252 | define gui.skip_ypos = 15 253 | 254 | ## The vertical position of the notify screen. 255 | define gui.notify_ypos = 68 256 | 257 | ## The spacing between menu choices. 258 | define gui.choice_spacing = 33 259 | 260 | ## Buttons in the navigation section of the main and game menus. 261 | define gui.navigation_spacing = 6 262 | 263 | ## Controls the amount of spacing between preferences. 264 | define gui.pref_spacing = 15 265 | 266 | ## Controls the amount of spacing between preference buttons. 267 | define gui.pref_button_spacing = 0 268 | 269 | ## The spacing between file page buttons. 270 | define gui.page_spacing = 0 271 | 272 | ## The spacing between file slots. 273 | define gui.slot_spacing = 15 274 | 275 | ## The position of the main menu text. 276 | define gui.main_menu_text_xalign = 1.0 277 | 278 | 279 | ## Frames ###################################################################### 280 | ## 281 | ## These variables control the look of frames that can contain user interface 282 | ## components when an overlay or window is not present. 283 | 284 | ## Generic frames. 285 | define gui.frame_borders = Borders(6, 6, 6, 6) 286 | 287 | ## The frame that is used as part of the confirm screen. 288 | define gui.confirm_frame_borders = Borders(60, 60, 60, 60) 289 | 290 | ## The frame that is used as part of the skip screen. 291 | define gui.skip_frame_borders = Borders(24, 8, 75, 8) 292 | 293 | ## The frame that is used as part of the notify screen. 294 | define gui.notify_frame_borders = Borders(24, 8, 60, 8) 295 | 296 | ## Should frame backgrounds be tiled? 297 | define gui.frame_tile = False 298 | 299 | 300 | ## Bars, Scrollbars, and Sliders ############################################### 301 | ## 302 | ## These control the look and size of bars, scrollbars, and sliders. 303 | ## 304 | ## The default GUI only uses sliders and vertical scrollbars. All of the other 305 | ## bars are only used in creator-written screens. 306 | 307 | ## The height of horizontal bars, scrollbars, and sliders. The width of vertical 308 | ## bars, scrollbars, and sliders. 309 | define gui.bar_size = 38 310 | define gui.scrollbar_size = 18 311 | define gui.slider_size = 38 312 | 313 | ## True if bar images should be tiled. False if they should be linearly scaled. 314 | define gui.bar_tile = False 315 | define gui.scrollbar_tile = False 316 | define gui.slider_tile = False 317 | 318 | ## Horizontal borders. 319 | define gui.bar_borders = Borders(6, 6, 6, 6) 320 | define gui.scrollbar_borders = Borders(6, 6, 6, 6) 321 | define gui.slider_borders = Borders(6, 6, 6, 6) 322 | 323 | ## Vertical borders. 324 | define gui.vbar_borders = Borders(6, 6, 6, 6) 325 | define gui.vscrollbar_borders = Borders(6, 6, 6, 6) 326 | define gui.vslider_borders = Borders(6, 6, 6, 6) 327 | 328 | ## What to do with unscrollable scrollbars in the gui. "hide" hides them, while 329 | ## None shows them. 330 | define gui.unscrollable = "hide" 331 | 332 | 333 | ## History ##################################################################### 334 | ## 335 | ## The history screen displays dialogue that the player has already dismissed. 336 | 337 | ## The number of blocks of dialogue history Ren'Py will keep. 338 | define config.history_length = 250 339 | 340 | ## The height of a history screen entry, or None to make the height variable at 341 | ## the cost of performance. 342 | define gui.history_height = 210 343 | 344 | ## The position, width, and alignment of the label giving the name of the 345 | ## speaking character. 346 | define gui.history_name_xpos = 233 347 | define gui.history_name_ypos = 0 348 | define gui.history_name_width = 233 349 | define gui.history_name_xalign = 1.0 350 | 351 | ## The position, width, and alignment of the dialogue text. 352 | define gui.history_text_xpos = 255 353 | define gui.history_text_ypos = 3 354 | define gui.history_text_width = 1110 355 | define gui.history_text_xalign = 0.0 356 | 357 | 358 | ## NVL-Mode #################################################################### 359 | ## 360 | ## The NVL-mode screen displays the dialogue spoken by NVL-mode characters. 361 | 362 | ## The borders of the background of the NVL-mode background window. 363 | define gui.nvl_borders = Borders(0, 15, 0, 30) 364 | 365 | ## The maximum number of NVL-mode entries Ren'Py will display. When more entries 366 | ## than this are to be show, the oldest entry will be removed. 367 | define gui.nvl_list_length = 6 368 | 369 | ## The height of an NVL-mode entry. Set this to None to have the entries 370 | ## dynamically adjust height. 371 | define gui.nvl_height = 173 372 | 373 | ## The spacing between NVL-mode entries when gui.nvl_height is None, and between 374 | ## NVL-mode entries and an NVL-mode menu. 375 | define gui.nvl_spacing = 15 376 | 377 | ## The position, width, and alignment of the label giving the name of the 378 | ## speaking character. 379 | define gui.nvl_name_xpos = 645 380 | define gui.nvl_name_ypos = 0 381 | define gui.nvl_name_width = 225 382 | define gui.nvl_name_xalign = 1.0 383 | 384 | ## The position, width, and alignment of the dialogue text. 385 | define gui.nvl_text_xpos = 675 386 | define gui.nvl_text_ypos = 12 387 | define gui.nvl_text_width = 885 388 | define gui.nvl_text_xalign = 0.0 389 | 390 | ## The position, width, and alignment of nvl_thought text (the text said by the 391 | ## nvl_narrator character.) 392 | define gui.nvl_thought_xpos = 360 393 | define gui.nvl_thought_ypos = 0 394 | define gui.nvl_thought_width = 1170 395 | define gui.nvl_thought_xalign = 0.0 396 | 397 | ## The position of nvl menu_buttons. 398 | define gui.nvl_button_xpos = 675 399 | define gui.nvl_button_xalign = 0.0 400 | 401 | ## Localization ################################################################ 402 | 403 | ## This controls where a line break is permitted. The default is suitable 404 | ## for most languages. A list of available values can be found at https:// 405 | ## www.renpy.org/doc/html/style_properties.html#style-property-language 406 | 407 | define gui.language = "unicode" 408 | 409 | 410 | ################################################################################ 411 | ## Mobile devices 412 | ################################################################################ 413 | 414 | init python: 415 | 416 | ## This increases the size of the quick buttons to make them easier to touch 417 | ## on tablets and phones. 418 | @gui.variant 419 | def touch(): 420 | 421 | gui.quick_button_borders = Borders(60, 21, 60, 0) 422 | 423 | ## This changes the size and spacing of various GUI elements to ensure they 424 | ## are easily visible on phones. 425 | @gui.variant 426 | def small(): 427 | 428 | ## Font sizes. 429 | gui.text_size = 45 430 | gui.name_text_size = 54 431 | gui.notify_text_size = 38 432 | gui.interface_text_size = 45 433 | gui.button_text_size = 45 434 | gui.label_text_size = 51 435 | 436 | ## Adjust the location of the textbox. 437 | gui.textbox_height = 360 438 | gui.name_xpos = 120 439 | gui.dialogue_xpos = 135 440 | gui.dialogue_width = 1650 441 | 442 | ## Change the size and spacing of various things. 443 | gui.slider_size = 54 444 | 445 | gui.choice_button_width = 1860 446 | gui.choice_button_text_size = 45 447 | 448 | gui.navigation_spacing = 30 449 | gui.pref_button_spacing = 15 450 | 451 | gui.history_height = 285 452 | gui.history_text_width = 1035 453 | 454 | gui.quick_button_text_size = 30 455 | 456 | ## File button layout. 457 | gui.file_slot_cols = 2 458 | gui.file_slot_rows = 2 459 | 460 | ## NVL-mode. 461 | gui.nvl_height = 255 462 | 463 | gui.nvl_name_width = 458 464 | gui.nvl_name_xpos = 488 465 | 466 | gui.nvl_text_width = 1373 467 | gui.nvl_text_xpos = 518 468 | gui.nvl_text_ypos = 8 469 | 470 | gui.nvl_thought_width = 1860 471 | gui.nvl_thought_xpos = 30 472 | 473 | gui.nvl_button_width = 1860 474 | gui.nvl_button_xpos = 30 475 | -------------------------------------------------------------------------------- /game/gui/bar/bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/bar/bottom.png -------------------------------------------------------------------------------- /game/gui/bar/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/bar/left.png -------------------------------------------------------------------------------- /game/gui/bar/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/bar/right.png -------------------------------------------------------------------------------- /game/gui/bar/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/bar/top.png -------------------------------------------------------------------------------- /game/gui/button/check_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/check_foreground.png -------------------------------------------------------------------------------- /game/gui/button/check_selected_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/check_selected_foreground.png -------------------------------------------------------------------------------- /game/gui/button/choice_hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/choice_hover_background.png -------------------------------------------------------------------------------- /game/gui/button/choice_idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/choice_idle_background.png -------------------------------------------------------------------------------- /game/gui/button/hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/hover_background.png -------------------------------------------------------------------------------- /game/gui/button/idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/idle_background.png -------------------------------------------------------------------------------- /game/gui/button/quick_hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/quick_hover_background.png -------------------------------------------------------------------------------- /game/gui/button/quick_idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/quick_idle_background.png -------------------------------------------------------------------------------- /game/gui/button/radio_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/radio_foreground.png -------------------------------------------------------------------------------- /game/gui/button/radio_selected_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/radio_selected_foreground.png -------------------------------------------------------------------------------- /game/gui/button/slot_hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/slot_hover_background.png -------------------------------------------------------------------------------- /game/gui/button/slot_idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/button/slot_idle_background.png -------------------------------------------------------------------------------- /game/gui/frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/frame.png -------------------------------------------------------------------------------- /game/gui/game_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/game_menu.png -------------------------------------------------------------------------------- /game/gui/main_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/main_menu.png -------------------------------------------------------------------------------- /game/gui/namebox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/namebox.png -------------------------------------------------------------------------------- /game/gui/notify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/notify.png -------------------------------------------------------------------------------- /game/gui/nvl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/nvl.png -------------------------------------------------------------------------------- /game/gui/overlay/confirm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/overlay/confirm.png -------------------------------------------------------------------------------- /game/gui/overlay/game_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/overlay/game_menu.png -------------------------------------------------------------------------------- /game/gui/overlay/main_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/overlay/main_menu.png -------------------------------------------------------------------------------- /game/gui/phone/bar/bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/bar/bottom.png -------------------------------------------------------------------------------- /game/gui/phone/bar/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/bar/left.png -------------------------------------------------------------------------------- /game/gui/phone/bar/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/bar/right.png -------------------------------------------------------------------------------- /game/gui/phone/bar/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/bar/top.png -------------------------------------------------------------------------------- /game/gui/phone/button/check_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/button/check_foreground.png -------------------------------------------------------------------------------- /game/gui/phone/button/check_selected_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/button/check_selected_foreground.png -------------------------------------------------------------------------------- /game/gui/phone/button/choice_hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/button/choice_hover_background.png -------------------------------------------------------------------------------- /game/gui/phone/button/choice_idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/button/choice_idle_background.png -------------------------------------------------------------------------------- /game/gui/phone/button/hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/button/hover_background.png -------------------------------------------------------------------------------- /game/gui/phone/button/idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/button/idle_background.png -------------------------------------------------------------------------------- /game/gui/phone/button/radio_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/button/radio_foreground.png -------------------------------------------------------------------------------- /game/gui/phone/button/radio_selected_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/button/radio_selected_foreground.png -------------------------------------------------------------------------------- /game/gui/phone/button/slot_hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/button/slot_hover_background.png -------------------------------------------------------------------------------- /game/gui/phone/button/slot_idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/button/slot_idle_background.png -------------------------------------------------------------------------------- /game/gui/phone/nvl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/nvl.png -------------------------------------------------------------------------------- /game/gui/phone/overlay/game_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/overlay/game_menu.png -------------------------------------------------------------------------------- /game/gui/phone/overlay/main_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/overlay/main_menu.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/horizontal_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/scrollbar/horizontal_hover_bar.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/horizontal_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/scrollbar/horizontal_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/horizontal_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/scrollbar/horizontal_idle_bar.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/horizontal_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/scrollbar/horizontal_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/vertical_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/scrollbar/vertical_hover_bar.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/vertical_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/scrollbar/vertical_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/vertical_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/scrollbar/vertical_idle_bar.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/vertical_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/scrollbar/vertical_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/slider/horizontal_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/slider/horizontal_hover_bar.png -------------------------------------------------------------------------------- /game/gui/phone/slider/horizontal_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/slider/horizontal_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/slider/horizontal_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/slider/horizontal_idle_bar.png -------------------------------------------------------------------------------- /game/gui/phone/slider/horizontal_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/slider/horizontal_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/slider/vertical_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/slider/vertical_hover_bar.png -------------------------------------------------------------------------------- /game/gui/phone/slider/vertical_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/slider/vertical_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/slider/vertical_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/slider/vertical_idle_bar.png -------------------------------------------------------------------------------- /game/gui/phone/slider/vertical_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/slider/vertical_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/textbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/phone/textbox.png -------------------------------------------------------------------------------- /game/gui/scrollbar/horizontal_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/scrollbar/horizontal_hover_bar.png -------------------------------------------------------------------------------- /game/gui/scrollbar/horizontal_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/scrollbar/horizontal_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/scrollbar/horizontal_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/scrollbar/horizontal_idle_bar.png -------------------------------------------------------------------------------- /game/gui/scrollbar/horizontal_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/scrollbar/horizontal_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/scrollbar/vertical_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/scrollbar/vertical_hover_bar.png -------------------------------------------------------------------------------- /game/gui/scrollbar/vertical_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/scrollbar/vertical_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/scrollbar/vertical_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/scrollbar/vertical_idle_bar.png -------------------------------------------------------------------------------- /game/gui/scrollbar/vertical_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/scrollbar/vertical_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/skip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/skip.png -------------------------------------------------------------------------------- /game/gui/slider/horizontal_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/slider/horizontal_hover_bar.png -------------------------------------------------------------------------------- /game/gui/slider/horizontal_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/slider/horizontal_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/slider/horizontal_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/slider/horizontal_idle_bar.png -------------------------------------------------------------------------------- /game/gui/slider/horizontal_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/slider/horizontal_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/slider/vertical_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/slider/vertical_hover_bar.png -------------------------------------------------------------------------------- /game/gui/slider/vertical_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/slider/vertical_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/slider/vertical_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/slider/vertical_idle_bar.png -------------------------------------------------------------------------------- /game/gui/slider/vertical_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/slider/vertical_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/textbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/textbox.png -------------------------------------------------------------------------------- /game/gui/window_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/gui/window_icon.png -------------------------------------------------------------------------------- /game/images/alien1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/images/alien1.webp -------------------------------------------------------------------------------- /game/images/alien2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/images/alien2.webp -------------------------------------------------------------------------------- /game/images/alien3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/images/alien3.webp -------------------------------------------------------------------------------- /game/images/background.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/images/background.webp -------------------------------------------------------------------------------- /game/images/bomb.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/images/bomb.webp -------------------------------------------------------------------------------- /game/images/explosion1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/images/explosion1.webp -------------------------------------------------------------------------------- /game/images/player1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/images/player1.webp -------------------------------------------------------------------------------- /game/images/shot.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/game/images/shot.webp -------------------------------------------------------------------------------- /game/minigames/aliens.py: -------------------------------------------------------------------------------- 1 | import random 2 | from typing import Optional 3 | 4 | import renpy.exports as renpy 5 | import renpy.store as store 6 | 7 | import pythonpackages.renpygame as pygame 8 | from pythonpackages.renpygame.event import EventType 9 | from pythonpackages.renpygame.rect import Rect 10 | from pythonpackages.renpygame.sprite import RenderUpdates 11 | 12 | # game constants 13 | MAX_SHOTS = 2 # most player bullets onscreen 14 | ALIEN_ODDS = 22 # chances a new alien appears 15 | BOMB_ODDS = 60 # chances a new bomb will drop 16 | ALIEN_RELOAD = 12 # frames between new aliens 17 | SCREENRECT = Rect(0, 0, 640, 480) 18 | 19 | 20 | class dummysound: 21 | def play(self): 22 | pass 23 | 24 | 25 | # each type of game object gets an init and an 26 | # update function. the update function is called 27 | # once per frame, and it is when each object should 28 | # change it's current position and state. the Player 29 | # object actually gets a "move" function instead of 30 | # update, since it is passed extra information about 31 | # the keyboard 32 | 33 | 34 | class Player(pygame.sprite.Sprite): 35 | speed = 10 36 | bounce = 24 37 | gun_offset = -11 38 | images: list[pygame.Surface] = [] 39 | 40 | def __init__(self): 41 | pygame.sprite.Sprite.__init__(self, self.containers) 42 | self.image = self.images[0] 43 | self.rect = self.image.get_rect(midbottom=SCREENRECT.midbottom) 44 | self.origtop = self.rect.top 45 | self.facing = -1 46 | 47 | def move(self, direction): 48 | if direction: 49 | self.facing = direction 50 | self.rect.move_ip(direction * self.speed, 0) 51 | self.rect = self.rect.clamp(SCREENRECT) 52 | if direction < 0: 53 | self.image = self.images[0] 54 | elif direction > 0: 55 | self.image = self.images[1] 56 | self.rect.top = self.origtop - (self.rect.left / self.bounce % 2) 57 | 58 | def gunpos(self): 59 | pos = self.facing * self.gun_offset + self.rect.centerx 60 | return pos, self.rect.top 61 | 62 | 63 | class Alien(pygame.sprite.Sprite): 64 | speed = 13 65 | animcycle = 12 66 | images: list[pygame.Surface] = [] 67 | 68 | def __init__(self): 69 | pygame.sprite.Sprite.__init__(self, self.containers) 70 | self.image = self.images[0] 71 | self.rect = self.image.get_rect() 72 | self.facing = random.choice((-1, 1)) * Alien.speed 73 | self.frame = 0 74 | if self.facing < 0: 75 | self.rect.right = SCREENRECT.right 76 | 77 | def update(self): 78 | self.rect.move_ip(self.facing, 0) 79 | if not SCREENRECT.contains(self.rect): 80 | self.facing = -self.facing 81 | self.rect.top = self.rect.bottom + 1 82 | self.rect = self.rect.clamp(SCREENRECT) 83 | self.frame = self.frame + 1 84 | # TODO: has been commented pe make it work 85 | # self.image = self.images[self.frame/self.animcycle%3] 86 | 87 | 88 | class Explosion(pygame.sprite.Sprite): 89 | defaultlife = 12 90 | animcycle = 3 91 | images: list[pygame.Surface] = [] 92 | 93 | def __init__(self, actor): 94 | pygame.sprite.Sprite.__init__(self, self.containers) 95 | self.image = self.images[0] 96 | self.rect = self.image.get_rect(center=actor.rect.center) 97 | self.life = self.defaultlife 98 | 99 | def update(self): 100 | self.life = self.life - 1 101 | # TODO: has been commented pe make it work 102 | # self.image = self.images[self.life/self.animcycle%2] 103 | if self.life <= 0: 104 | self.kill() 105 | 106 | 107 | class Shot(pygame.sprite.Sprite): 108 | speed = -11 109 | images: list[pygame.Surface] = [] 110 | 111 | def __init__(self, pos): 112 | pygame.sprite.Sprite.__init__(self, self.containers) 113 | self.image = self.images[0] 114 | self.rect = self.image.get_rect(midbottom=pos) 115 | 116 | def update(self): 117 | self.rect.move_ip(0, self.speed) 118 | if self.rect.top <= 0: 119 | self.kill() 120 | 121 | 122 | class Bomb(pygame.sprite.Sprite): 123 | speed = 9 124 | images: list[pygame.Surface] = [] 125 | 126 | def __init__(self, alien): 127 | pygame.sprite.Sprite.__init__(self, self.containers) 128 | self.image = self.images[0] 129 | self.rect = self.image.get_rect(midbottom=alien.rect.move(0, 5).midbottom) 130 | 131 | def update(self): 132 | self.rect.move_ip(0, self.speed) 133 | if self.rect.bottom >= 470: 134 | Explosion(self) 135 | self.kill() 136 | 137 | 138 | class Score(pygame.sprite.Sprite): 139 | def __init__(self): 140 | pygame.sprite.Sprite.__init__(self) 141 | 142 | # TODO: has been commented pe make it work 143 | # self.font = pygame.font.Font("DejaVuSans.ttf", 20) 144 | 145 | # TODO: has been commented pe make it work 146 | # self.font.set_italic(1) 147 | self.color = (255, 255, 255, 255) 148 | self.lastscore = -1 149 | self.update() 150 | self.rect = self.image.get_rect().move(10, 450) 151 | 152 | def update(self): 153 | if sh.score != self.lastscore: 154 | self.lastscore = sh.score 155 | msg = "Score: %d" % sh.score 156 | # TODO: has been commented pe make it work 157 | # self.image = self.font.render(msg, 0, self.color) 158 | 159 | 160 | class SharedData: 161 | def __init__(self): 162 | self.all = None 163 | self.player = None 164 | self.background = None 165 | self.lastalien = None 166 | self.aliens = None 167 | self.bombs = None 168 | self.shots = None 169 | self.alienreload = 12 170 | self.score = 0 171 | self.player_have_shot = False 172 | self.player_move = 0 # -1 left, 0 no move, 1 right 173 | self.boom_sound = pygame.mixer.Sound("audio/boom.wav") 174 | self.shoot_sound = pygame.mixer.Sound("audio/car_door.wav") 175 | 176 | @property 177 | def all(self) -> RenderUpdates: 178 | return self._all 179 | 180 | @all.setter 181 | def all(self, value: RenderUpdates): 182 | self._all = value 183 | 184 | @property 185 | def player(self) -> Player: 186 | return self._player 187 | 188 | @player.setter 189 | def player(self, value: Player): 190 | self._player = value 191 | 192 | @property 193 | def background(self) -> pygame.Surface: 194 | return self._background 195 | 196 | @background.setter 197 | def background(self, value: pygame.Surface): 198 | self._background = value 199 | 200 | @property 201 | def lastalien(self) -> int: 202 | return self._lastalien 203 | 204 | @lastalien.setter 205 | def lastalien(self, value: int): 206 | self._lastalien = value 207 | 208 | @property 209 | def aliens(self) -> RenderUpdates: 210 | return self._aliens 211 | 212 | @aliens.setter 213 | def aliens(self, value: RenderUpdates): 214 | self._aliens = value 215 | 216 | @property 217 | def bombs(self) -> RenderUpdates: 218 | return self._bombs 219 | 220 | @bombs.setter 221 | def bombs(self, value: RenderUpdates): 222 | self._bombs = value 223 | 224 | @property 225 | def shots(self) -> RenderUpdates: 226 | return self._shots 227 | 228 | @shots.setter 229 | def shots(self, value: RenderUpdates): 230 | self._shots = value 231 | 232 | 233 | sh = SharedData() 234 | # Create Some Starting Values 235 | kills = 0 236 | clock = pygame.time.Clock() 237 | 238 | 239 | def main(): 240 | # # Initialize a shared data 241 | global sh 242 | 243 | if not sh: 244 | sh = SharedData() 245 | 246 | # Initialize a game 247 | displayable_with_logic = pygame.RenpyGameByLoop( 248 | first_step=my_game_first_step, 249 | update_process=my_game_logic, 250 | event_lambda=game_event, 251 | delay=0.04, 252 | ) 253 | # show amd start the game 254 | displayable_with_logic.show() 255 | 256 | # * after show() the game will be running when the game is over 257 | 258 | # clean up the shared data 259 | score = sh.score 260 | sh = None 261 | # return to renpy 262 | return score 263 | 264 | 265 | def mainByTimer(): 266 | # # Initialize a shared data 267 | global sh 268 | 269 | if not sh: 270 | sh = SharedData() 271 | 272 | # Initialize a game 273 | displayable_with_logic = pygame.RenpyGameByTimer( 274 | first_step=my_game_first_step, 275 | update_process=my_game_logic, 276 | event_lambda=game_event, 277 | delay=0.04, 278 | ) 279 | # show amd start the game 280 | displayable_with_logic.show() 281 | 282 | # * after show() the game will be running when the game is over 283 | 284 | # clean up the shared data 285 | score = sh.score 286 | sh = None 287 | # return to renpy 288 | return score 289 | 290 | 291 | def my_game_first_step(width: int, height: int, st: float, at: float) -> pygame.Surface: 292 | # Set the display mode 293 | if store._preferences.fullscreen: 294 | winstyle = FULLSCREEN 295 | else: 296 | winstyle = 0 297 | 298 | bestdepth = pygame.display.mode_ok((0, 0), winstyle, 32) 299 | screen = pygame.display.set_mode((0, 0), winstyle, bestdepth) 300 | 301 | # Load images, assign to sprite classes 302 | # (do this before the classes are used, after screen setup) 303 | img = pygame.image.load("player1.webp") 304 | img_flip = pygame.transform.flip(img, 1, 0) 305 | img = img.convert(st, at) 306 | img_flip = img_flip.convert(st, at) 307 | Player.images = [img, img_flip] 308 | img = pygame.image.load("explosion1.webp") 309 | img_flip = pygame.transform.flip(img, 1, 0) 310 | img = img.convert(st, at) 311 | img_flip = img_flip.convert(st, at) 312 | Explosion.images = [img, img_flip] 313 | Alien.images = [ 314 | pygame.image.load("alien1.webp").convert(st, at), 315 | pygame.image.load("alien2.webp").convert(st, at), 316 | pygame.image.load("alien3.webp").convert(st, at), 317 | ] 318 | Bomb.images = [pygame.image.load("bomb.webp").convert(st, at)] 319 | Shot.images = [pygame.image.load("shot.webp").convert(st, at)] 320 | 321 | # decorate the game window 322 | pygame.display.set_icon(pygame.image.load("alien1.webp").pygame_image) 323 | pygame.display.set_caption("Pygame Aliens") 324 | pygame.mouse.set_visible(0) 325 | 326 | # create the background, tile the bgd image 327 | bgdtile = pygame.image.load("background.webp") 328 | bgdtile = bgdtile.convert(st, at) 329 | sh.background = pygame.Surface(SCREENRECT.size) 330 | for x in range(0, SCREENRECT.width, bgdtile.get_width()): 331 | sh.background.blit(bgdtile, (x, 0)) 332 | screen.blit(sh.background, (0, 0)) 333 | pygame.display.flip() 334 | 335 | # play music 336 | pygame.mixer.music.load("audio/house_lo.wav") 337 | pygame.mixer.music.play(-1) 338 | 339 | # Initialize Game Groups 340 | sh.aliens = pygame.sprite.Group() 341 | sh.shots = pygame.sprite.Group() 342 | sh.bombs = pygame.sprite.Group() 343 | sh.all = pygame.sprite.RenderUpdates() 344 | sh.lastalien = pygame.sprite.GroupSingle() 345 | 346 | # assign default groups to each sprite class 347 | Player.containers = sh.all 348 | Alien.containers = sh.aliens, sh.all, sh.lastalien 349 | Shot.containers = sh.shots, sh.all 350 | Bomb.containers = sh.bombs, sh.all 351 | Explosion.containers = sh.all 352 | Score.containers = sh.all 353 | 354 | # initialize our starting sprites 355 | sh.player = Player() 356 | Alien() # note, this 'lives' because it goes into a sprite group 357 | 358 | # TODO: has been commented pe make it work 359 | # if pygame.font: 360 | # all.add(Score()) 361 | 362 | return screen 363 | 364 | 365 | def my_game_logic( 366 | cur_screen: pygame.Surface, 367 | st: float, 368 | next_frame_time: Optional[float], 369 | current_frame_number: int, 370 | ) -> Optional[float]: 371 | if sh.player.alive(): 372 | # clear/erase the last drawn sprites 373 | sh.all.clear(cur_screen, sh.background) 374 | 375 | # update all the sprites 376 | sh.all.update() 377 | 378 | # handle player input 379 | direction = sh.player_move 380 | sh.player.move(direction) 381 | if sh.player_have_shot and len(sh.shots) < MAX_SHOTS: 382 | Shot(sh.player.gunpos()) 383 | # TODO: has been commented pe make it work 384 | sh.shoot_sound.play() 385 | 386 | # Create new alien 387 | if sh.alienreload: 388 | sh.alienreload = sh.alienreload - 1 389 | elif not int(random.random() * ALIEN_ODDS): 390 | Alien() 391 | sh.alienreload = ALIEN_RELOAD 392 | 393 | # Drop bombs 394 | if sh.lastalien and not int(random.random() * BOMB_ODDS): 395 | Bomb(sh.lastalien.sprite) 396 | 397 | # Detect collisions 398 | for alien in pygame.sprite.spritecollide(sh.player, sh.aliens, 1): 399 | sh.boom_sound.play() 400 | Explosion(alien) 401 | Explosion(sh.player) 402 | sh.score = sh.score + 1 403 | sh.player.kill() 404 | 405 | for alien in pygame.sprite.groupcollide(sh.shots, sh.aliens, 1, 1).keys(): 406 | sh.boom_sound.play() 407 | Explosion(alien) 408 | sh.score = sh.score + 1 409 | 410 | for bomb in pygame.sprite.spritecollide(sh.player, sh.bombs, 1): 411 | sh.boom_sound.play() 412 | Explosion(sh.player) 413 | Explosion(bomb) 414 | sh.player.kill() 415 | 416 | # draw the scene 417 | dirty = sh.all.draw(cur_screen) 418 | pygame.display.update(dirty) 419 | 420 | return next_frame_time 421 | else: 422 | # game end 423 | return None 424 | 425 | 426 | def game_event(ev: EventType, x: int, y: int, st: float): 427 | if ev.type == pygame.KEYDOWN and ev.key == pygame.K_SPACE: 428 | sh.player_have_shot = True 429 | elif ev.type == pygame.KEYUP and ev.key == pygame.K_SPACE: 430 | sh.player_have_shot = False 431 | elif ev.type == pygame.KEYDOWN and ev.key == pygame.K_LEFT: 432 | sh.player_move = -1 433 | elif ev.type == pygame.KEYUP and ev.key == pygame.K_LEFT: 434 | if sh.player_move == -1: 435 | sh.player_move = 0 436 | elif ev.type == pygame.KEYDOWN and ev.key == pygame.K_RIGHT: 437 | sh.player_move = 1 438 | elif ev.type == pygame.KEYUP and ev.key == pygame.K_RIGHT: 439 | if sh.player_move == 1: 440 | sh.player_move = 0 441 | return 442 | -------------------------------------------------------------------------------- /game/minigames/aliens.rpy: -------------------------------------------------------------------------------- 1 | init: 2 | # import minigame 3 | $ import game.minigames.aliens as aliens 4 | 5 | 6 | # The game starts here. 7 | label aliens_start: 8 | 9 | e "Welcome!" 10 | 11 | e "You're here to defend the moon from invaders from the M-64 galaxy." 12 | 13 | e "You can move your van back and forth with the arrow keys, and then press space to fire a missile." 14 | 15 | e "Good luck!" 16 | 17 | label aliens_retry: 18 | menu: 19 | "RenpyGameByLoop": 20 | $ score = aliens.main() 21 | "RenpyGameByTimer": 22 | $ score = aliens.mainByTimer() 23 | 24 | # # This eats up any remaining keypresses. 25 | # $ renpy.pause(.1) 26 | 27 | e "You shot down [score] aliens." 28 | 29 | if score > 10: 30 | 31 | e "Not bad!" 32 | 33 | menu: 34 | 35 | "Would you like to try again?" 36 | 37 | "Sure.": 38 | 39 | "Okay, get ready..." 40 | 41 | jump aliens_retry 42 | 43 | "No thanks.": 44 | 45 | pass 46 | 47 | e "No problem." 48 | 49 | e "This game was based off one of the examples that came with pygame." 50 | 51 | e "It shows how pygame games can be integrated with Ren'Py." 52 | 53 | e "Thank you for playing." 54 | 55 | return 56 | -------------------------------------------------------------------------------- /game/options.rpy: -------------------------------------------------------------------------------- 1 | ## This file contains options that can be changed to customize your game. 2 | ## 3 | ## Lines beginning with two '#' marks are comments, and you shouldn't uncomment 4 | ## them. Lines beginning with a single '#' mark are commented-out code, and you 5 | ## may want to uncomment them when appropriate. 6 | 7 | 8 | ## Basics ###################################################################### 9 | 10 | ## A human-readable name of the game. This is used to set the default window 11 | ## title, and shows up in the interface and error reports. 12 | ## 13 | ## The _() surrounding the string marks it as eligible for translation. 14 | 15 | define config.name = _("Renpygame") 16 | 17 | 18 | ## Determines if the title given above is shown on the main menu screen. Set 19 | ## this to False to hide the title. 20 | 21 | define gui.show_name = True 22 | 23 | 24 | ## The version of the game. 25 | 26 | define config.version = "1.2.0" 27 | 28 | 29 | ## Text that is placed on the game's about screen. Place the text between the 30 | ## triple-quotes, and leave a blank line between paragraphs. 31 | 32 | define gui.about = _p(""" 33 | """) 34 | 35 | 36 | ## A short name for the game used for executables and directories in the built 37 | ## distribution. This must be ASCII-only, and must not contain spaces, colons, 38 | ## or semicolons. 39 | 40 | define build.name = "Renpygame" 41 | 42 | 43 | ## Sounds and music ############################################################ 44 | 45 | ## These three variables control, among other things, which mixers are shown 46 | ## to the player by default. Setting one of these to False will hide the 47 | ## appropriate mixer. 48 | 49 | define config.has_sound = True 50 | define config.has_music = True 51 | define config.has_voice = True 52 | 53 | 54 | ## To allow the user to play a test sound on the sound or voice channel, 55 | ## uncomment a line below and use it to set a sample sound to play. 56 | 57 | # define config.sample_sound = "sample-sound.ogg" 58 | # define config.sample_voice = "sample-voice.ogg" 59 | 60 | 61 | ## Uncomment the following line to set an audio file that will be played while 62 | ## the player is at the main menu. This file will continue playing into the 63 | ## game, until it is stopped or another file is played. 64 | 65 | # define config.main_menu_music = "main-menu-theme.ogg" 66 | 67 | 68 | ## Transitions ################################################################# 69 | ## 70 | ## These variables set transitions that are used when certain events occur. 71 | ## Each variable should be set to a transition, or None to indicate that no 72 | ## transition should be used. 73 | 74 | ## Entering or exiting the game menu. 75 | 76 | define config.enter_transition = dissolve 77 | define config.exit_transition = dissolve 78 | 79 | 80 | ## Between screens of the game menu. 81 | 82 | define config.intra_transition = dissolve 83 | 84 | 85 | ## A transition that is used after a game has been loaded. 86 | 87 | define config.after_load_transition = None 88 | 89 | 90 | ## Used when entering the main menu after the game has ended. 91 | 92 | define config.end_game_transition = None 93 | 94 | 95 | ## A variable to set the transition used when the game starts does not exist. 96 | ## Instead, use a with statement after showing the initial scene. 97 | 98 | 99 | ## Window management ########################################################### 100 | ## 101 | ## This controls when the dialogue window is displayed. If "show", it is always 102 | ## displayed. If "hide", it is only displayed when dialogue is present. If 103 | ## "auto", the window is hidden before scene statements and shown again once 104 | ## dialogue is displayed. 105 | ## 106 | ## After the game has started, this can be changed with the "window show", 107 | ## "window hide", and "window auto" statements. 108 | 109 | define config.window = "auto" 110 | 111 | 112 | ## Transitions used to show and hide the dialogue window 113 | 114 | define config.window_show_transition = Dissolve(.2) 115 | define config.window_hide_transition = Dissolve(.2) 116 | 117 | 118 | ## Preference defaults ######################################################### 119 | 120 | ## Controls the default text speed. The default, 0, is infinite, while any other 121 | ## number is the number of characters per second to type out. 122 | 123 | default preferences.text_cps = 0 124 | 125 | 126 | ## The default auto-forward delay. Larger numbers lead to longer waits, with 0 127 | ## to 30 being the valid range. 128 | 129 | default preferences.afm_time = 15 130 | 131 | 132 | ## Save directory ############################################################## 133 | ## 134 | ## Controls the platform-specific place Ren'Py will place the save files for 135 | ## this game. The save files will be placed in: 136 | ## 137 | ## Windows: %APPDATA\RenPy\ 138 | ## 139 | ## Macintosh: $HOME/Library/RenPy/ 140 | ## 141 | ## Linux: $HOME/.renpy/ 142 | ## 143 | ## This generally should not be changed, and if it is, should always be a 144 | ## literal string, not an expression. 145 | 146 | define config.save_directory = "Renpygame-1676195697" 147 | 148 | 149 | ## Icon ######################################################################## 150 | ## 151 | ## The icon displayed on the taskbar or dock. 152 | 153 | define config.window_icon = "gui/window_icon.png" 154 | 155 | 156 | ## Build configuration ######################################################### 157 | ## 158 | ## This section controls how Ren'Py turns your project into distribution files. 159 | 160 | init python: 161 | 162 | ## The following functions take file patterns. File patterns are case- 163 | ## insensitive, and matched against the path relative to the base directory, 164 | ## with and without a leading /. If multiple patterns match, the first is 165 | ## used. 166 | ## 167 | ## In a pattern: 168 | ## 169 | ## / is the directory separator. 170 | ## 171 | ## * matches all characters, except the directory separator. 172 | ## 173 | ## ** matches all characters, including the directory separator. 174 | ## 175 | ## For example, "*.txt" matches txt files in the base directory, "game/ 176 | ## **.ogg" matches ogg files in the game directory or any of its 177 | ## subdirectories, and "**.psd" matches psd files anywhere in the project. 178 | 179 | ## Classify files as None to exclude them from the built distributions. 180 | 181 | build.classify('**~', None) 182 | build.classify('**.bak', None) 183 | build.classify('**/.**', None) 184 | build.classify('**/#**', None) 185 | build.classify('**/thumbs.db', None) 186 | 187 | ## To archive files, classify them as 'archive'. 188 | 189 | # build.classify('game/**.png', 'archive') 190 | # build.classify('game/**.jpg', 'archive') 191 | 192 | ## Files matching documentation patterns are duplicated in a mac app build, 193 | ## so they appear in both the app and the zip file. 194 | 195 | build.documentation('*.html') 196 | build.documentation('*.txt') 197 | 198 | 199 | ## A Google Play license key is required to download expansion files and perform 200 | ## in-app purchases. It can be found on the "Services & APIs" page of the Google 201 | ## Play developer console. 202 | 203 | # define build.google_play_key = "..." 204 | 205 | 206 | ## The username and project name associated with an itch.io project, separated 207 | ## by a slash. 208 | 209 | # define build.itch_project = "renpytom/test-project" 210 | -------------------------------------------------------------------------------- /game/renpy_utility_tool/core.rpy: -------------------------------------------------------------------------------- 1 | define config.log = "log.txt" 2 | 3 | label after_load: 4 | $ update_flags() 5 | return 6 | -------------------------------------------------------------------------------- /game/renpy_utility_tool/flags.rpy: -------------------------------------------------------------------------------- 1 | init python: 2 | import pythonpackages.renpy_utility.flags as myFlags 3 | 4 | # flags are Boolean values, a good use is for example in quests to know quickly if MC has the possibility to do a certain thing, after unlocking it somehow. 5 | # has the same alements as flag_keys, all set as False 6 | # I suggest to leave it empty and add the elements only if it is an initial value and set as True 7 | default flags = {} 8 | define flag_keys = [ 9 | ] 10 | 11 | init python: 12 | def update_flags(): 13 | """update flags by making it with the same elements of flag_keys. in case you have to add them set them as False""" 14 | return myFlags.update_flags(flags, flag_keys) 15 | 16 | def get_flags(flag_id: str) -> bool: 17 | """returns the value of the flag_id in flags""" 18 | return myFlags.get_flags(flag_id, flags) 19 | 20 | def set_flags(flag_id: str, value: bool): 21 | return myFlags.set_flags(flag_id, value, flags) 22 | -------------------------------------------------------------------------------- /game/renpy_utility_tool/log_system.rpy: -------------------------------------------------------------------------------- 1 | init -998 python: 2 | import pythonpackages.renpy_utility.renpy_custom_log as myLog 3 | 4 | # 'define config.log' is in core.rpy 5 | error_notify = __("There is an {color=#f00}{b}ERROR{/b}{/color}. Please send the developer the logs found in: {color=#00ccff}[config.log]{/color}") 6 | warn_notify = _("There is an {color=#f5bc02}{b}WARN{/b}{/color}. Please send the developer the logs found in: {color=#00ccff}[config.log]{/color}") 7 | info_notify = False 8 | 9 | def log_error(msg: str, filename_line = None): 10 | myLog.log_error(msg, filename_line) 11 | if error_notify: 12 | notify_prevents_loops(msg = error_notify) 13 | return 14 | 15 | def log_warn(msg: str, filename_line = None): 16 | myLog.log_warn(msg, filename_line) 17 | if not IsNullOrWhiteSpace(warn_notify): 18 | notify_prevents_loops(msg = warn_notify) 19 | return 20 | 21 | def log_info(msg: str, filename_line = None): 22 | myLog.log_info(msg, filename_line) 23 | if not IsNullOrWhiteSpace(info_notify): 24 | notify_prevents_loops(msg = info_notify) 25 | return 26 | -------------------------------------------------------------------------------- /game/renpy_utility_tool/notify.rpy: -------------------------------------------------------------------------------- 1 | init python: 2 | import renpy.store as store 3 | 4 | store.notifications = [] 5 | 6 | # Width of the images. 7 | define gui.notifyEx_width = gui.label_text_size 8 | # Height of the images. 9 | define gui.notifyEx_height = gui.label_text_size 10 | 11 | define gui.notifyEx_color = "#000000" 12 | define gui.notifyEx_text_color = "#ffffff" 13 | 14 | label enable_notifyEx: 15 | show screen notifyEx 16 | return 17 | label disable_notifyEx: 18 | hide notifyEx 19 | return 20 | 21 | init -999 python: 22 | import pythonpackages.renpy_utility.renpy_custom_notify as myNotify 23 | 24 | def notify_add(message: str = None, image: str = None): 25 | return myNotify.notify_add(message, image) 26 | 27 | def notify_prevents_loops(message: str = None, image: str = None): 28 | return myNotify.notify_prevents_loops(message, image) 29 | 30 | def notify_remove(value): 31 | return myNotify.notify_remove(value) 32 | 33 | def notify(notific): 34 | return myNotify.notify(notific) 35 | 36 | style notify_text is default: 37 | color gui.notifyEx_color 38 | yalign 0.5 39 | 40 | style notify_hbox is default: 41 | ysize gui.notifyEx_height 42 | 43 | screen notifyEx: 44 | 45 | zorder 100 46 | 47 | style_prefix "notify" 48 | 49 | vbox: 50 | for d in notifications: 51 | use notifyExInternal( d ) 52 | # aerate a little. 53 | null height 5 54 | 55 | screen notifyExInternal( n ): 56 | 57 | style_prefix "notify" 58 | 59 | frame at notify_appear: 60 | hbox: 61 | if not n.image is None: 62 | add n.image 63 | else: 64 | # Ensure that all the texts will be aligned. 65 | null width gui.notifyEx_width 66 | 67 | # aerate a little. 68 | null width 5 69 | 70 | if not n.message is None: 71 | text n.message color gui.notifyEx_text_color 72 | 73 | timer 0.05 repeat True action [ SetField( n, "delay", n.delay - 0.05 ), If( n.delay <= 0, Function( notify_remove, n ), NullAction() ) ] 74 | -------------------------------------------------------------------------------- /game/renpy_utility_tool/utility.rpy: -------------------------------------------------------------------------------- 1 | init -999 python: 2 | def isNullOrEmpty(item: str) -> bool: 3 | if not item: 4 | return True 5 | return False 6 | 7 | def IsNullOrWhiteSpace(item: str) -> bool: 8 | if not item or item.isspace(): 9 | return True 10 | return False 11 | 12 | def null_or_image(s): 13 | """It checks for the presence of an image, in case it is not there it returns a null value. Possible use: avoid mistakes in the management of clothes.""" 14 | # s = renpy.substitute(s) 15 | if renpy.has_image(s): 16 | return s 17 | elif renpy.list_files(s): 18 | return s 19 | else: 20 | return Null() 21 | config.displayable_prefix['check'] = null_or_image 22 | 23 | def compare(a= 0, b= 0) -> int: 24 | if a is None and b is None: 25 | return 0 26 | elif b is None: 27 | return 1 28 | elif a is None: 29 | return -1 30 | return a - b 31 | 32 | def isGreaterThan(a= 0, b= 0) -> bool: 33 | return compare(a, b) > 0 34 | 35 | label set_background(img): 36 | scene expression (img) as bg 37 | 38 | screen popup(message): 39 | zorder 100 40 | frame: 41 | style_group "invstyle" 42 | hbox: 43 | text message 44 | timer 1.5 action Hide("popup") 45 | -------------------------------------------------------------------------------- /game/renpygame/renpygame_screen.rpy: -------------------------------------------------------------------------------- 1 | screen renpygame_surface(surface): 2 | add surface 3 | 4 | 5 | screen renpygame_surface_lambda(surface, update_process): 6 | add surface 7 | $ update_process() -------------------------------------------------------------------------------- /game/script.rpy: -------------------------------------------------------------------------------- 1 | image side eileen = "eileen_happy.png" 2 | 3 | define e = Character("Eileen", color="#c8ffc8", image="eileen") 4 | 5 | # The game starts here. 6 | label start: 7 | menu: 8 | "Aliens": 9 | call aliens_start 10 | "Quit": 11 | return 12 | "An what do you want to play?" 13 | jump start -------------------------------------------------------------------------------- /pythonpackages/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DRincs-Productions/Renpygame/752ebf8e61da9946c75961f37602dd4dfa034c45/pythonpackages/__init__.py -------------------------------------------------------------------------------- /pythonpackages/renpygame/__init__.py: -------------------------------------------------------------------------------- 1 | import pythonpackages.renpygame.display as my_display 2 | import pythonpackages.renpygame.draw as my_draw 3 | import pythonpackages.renpygame.event as my_event 4 | import pythonpackages.renpygame.image as my_image 5 | import pythonpackages.renpygame.mixer as my_mixer 6 | import pythonpackages.renpygame.rect as my_rect 7 | import pythonpackages.renpygame.sprite as my_sprite 8 | import pythonpackages.renpygame.transform as my_transform 9 | from pythonpackages.renpygame.renpygameCDD import ( 10 | RenpyGameByEvent as my_RenpyGameByEvent, 11 | RenpyGameByTimerForDraw as my_RenpyGameByTimerOnlyDraw, 12 | ) 13 | from pythonpackages.renpygame.renpygameCDD import RenpyGameByLoop as my_RenpyGameByLoop 14 | from pythonpackages.renpygame.renpygameCDD import ( 15 | RenpyGameByTimer as my_RenpyGameByTimer, 16 | ) 17 | from pythonpackages.renpygame_pygame import * 18 | import pythonpackages.renpygame_pygame as my_pygame 19 | 20 | Surface = my_display.Surface 21 | Rect = my_rect.Rect 22 | rect = my_rect 23 | display = my_display 24 | sprite = my_sprite 25 | image = my_image 26 | transform = my_transform 27 | event = my_event 28 | mixer = my_mixer 29 | draw = my_draw 30 | 31 | RenpyGameByTimer = my_RenpyGameByTimer 32 | RenpyGameByEvent = my_RenpyGameByEvent 33 | RenpyGameByTimerForDraw = my_RenpyGameByTimerOnlyDraw 34 | RenpyGameByLoop = my_RenpyGameByLoop 35 | 36 | 37 | def init(): 38 | return 39 | 40 | 41 | # Event List 42 | QUIT = my_pygame.QUIT 43 | ACTIVEEVENT = my_pygame.ACTIVEEVENT 44 | KEYDOWN = my_pygame.KEYDOWN 45 | KEYUP = my_pygame.KEYUP 46 | MOUSEMOTION = my_pygame.MOUSEMOTION 47 | MOUSEBUTTONUP = my_pygame.MOUSEBUTTONUP 48 | MOUSEBUTTONDOWN = my_pygame.MOUSEBUTTONDOWN 49 | JOYAXISMOTION = my_pygame.JOYAXISMOTION 50 | JOYBALLMOTION = my_pygame.JOYBALLMOTION 51 | JOYHATMOTION = my_pygame.JOYHATMOTION 52 | JOYBUTTONUP = my_pygame.JOYBUTTONUP 53 | JOYBUTTONDOWN = my_pygame.JOYBUTTONDOWN 54 | VIDEORESIZE = my_pygame.VIDEORESIZE 55 | VIDEOEXPOSE = my_pygame.VIDEOEXPOSE 56 | USEREVENT = my_pygame.USEREVENT 57 | 58 | 59 | # Keyboard list 60 | K_BACKSPACE = my_pygame.K_BACKSPACE 61 | K_TAB = my_pygame.K_TAB 62 | K_CLEAR = my_pygame.K_CLEAR 63 | K_RETURN = my_pygame.K_RETURN 64 | K_PAUSE = my_pygame.K_PAUSE 65 | K_ESCAPE = my_pygame.K_ESCAPE 66 | K_SPACE = my_pygame.K_SPACE 67 | K_EXCLAIM = my_pygame.K_EXCLAIM 68 | K_QUOTEDBL = my_pygame.K_QUOTEDBL 69 | K_HASH = my_pygame.K_HASH 70 | K_DOLLAR = my_pygame.K_DOLLAR 71 | K_AMPERSAND = my_pygame.K_AMPERSAND 72 | K_QUOTE = my_pygame.K_QUOTE 73 | K_LEFTPAREN = my_pygame.K_LEFTPAREN 74 | K_RIGHTPAREN = my_pygame.K_RIGHTPAREN 75 | K_ASTERISK = my_pygame.K_ASTERISK 76 | K_PLUS = my_pygame.K_PLUS 77 | K_COMMA = my_pygame.K_COMMA 78 | K_MINUS = my_pygame.K_MINUS 79 | K_PERIOD = my_pygame.K_PERIOD 80 | K_SLASH = my_pygame.K_SLASH 81 | K_0 = my_pygame.K_0 82 | K_1 = my_pygame.K_1 83 | K_2 = my_pygame.K_2 84 | K_3 = my_pygame.K_3 85 | K_4 = my_pygame.K_4 86 | K_5 = my_pygame.K_5 87 | K_6 = my_pygame.K_6 88 | K_7 = my_pygame.K_7 89 | K_8 = my_pygame.K_8 90 | K_9 = my_pygame.K_9 91 | K_COLON = my_pygame.K_COLON 92 | K_SEMICOLON = my_pygame.K_SEMICOLON 93 | K_LESS = my_pygame.K_LESS 94 | K_EQUALS = my_pygame.K_EQUALS 95 | K_GREATER = my_pygame.K_GREATER 96 | K_QUESTION = my_pygame.K_QUESTION 97 | K_AT = my_pygame.K_AT 98 | K_LEFTBRACKET = my_pygame.K_LEFTBRACKET 99 | K_BACKSLASH = my_pygame.K_BACKSLASH 100 | K_RIGHTBRACKET = my_pygame.K_RIGHTBRACKET 101 | K_CARET = my_pygame.K_CARET 102 | K_UNDERSCORE = my_pygame.K_UNDERSCORE 103 | K_BACKQUOTE = my_pygame.K_BACKQUOTE 104 | K_a = my_pygame.K_a 105 | K_b = my_pygame.K_b 106 | K_c = my_pygame.K_c 107 | K_d = my_pygame.K_d 108 | K_e = my_pygame.K_e 109 | K_f = my_pygame.K_f 110 | K_g = my_pygame.K_g 111 | K_h = my_pygame.K_h 112 | K_i = my_pygame.K_i 113 | K_j = my_pygame.K_j 114 | K_k = my_pygame.K_k 115 | K_l = my_pygame.K_l 116 | K_m = my_pygame.K_m 117 | K_n = my_pygame.K_n 118 | K_o = my_pygame.K_o 119 | K_p = my_pygame.K_p 120 | K_q = my_pygame.K_q 121 | K_r = my_pygame.K_r 122 | K_s = my_pygame.K_s 123 | K_t = my_pygame.K_t 124 | K_u = my_pygame.K_u 125 | K_v = my_pygame.K_v 126 | K_w = my_pygame.K_w 127 | K_x = my_pygame.K_x 128 | K_y = my_pygame.K_y 129 | K_z = my_pygame.K_z 130 | K_DELETE = my_pygame.K_DELETE 131 | K_KP0 = my_pygame.K_KP0 132 | K_KP1 = my_pygame.K_KP1 133 | K_KP2 = my_pygame.K_KP2 134 | K_KP3 = my_pygame.K_KP3 135 | K_KP4 = my_pygame.K_KP4 136 | K_KP5 = my_pygame.K_KP5 137 | K_KP6 = my_pygame.K_KP6 138 | K_KP7 = my_pygame.K_KP7 139 | K_KP8 = my_pygame.K_KP8 140 | K_KP9 = my_pygame.K_KP9 141 | K_KP_PERIOD = my_pygame.K_KP_PERIOD 142 | K_KP_DIVIDE = my_pygame.K_KP_DIVIDE 143 | K_KP_MULTIPLY = my_pygame.K_KP_MULTIPLY 144 | K_KP_MINUS = my_pygame.K_KP_MINUS 145 | K_KP_PLUS = my_pygame.K_KP_PLUS 146 | K_KP_ENTER = my_pygame.K_KP_ENTER 147 | K_KP_EQUALS = my_pygame.K_KP_EQUALS 148 | K_UP = my_pygame.K_UP 149 | K_DOWN = my_pygame.K_DOWN 150 | K_RIGHT = my_pygame.K_RIGHT 151 | K_LEFT = my_pygame.K_LEFT 152 | K_INSERT = my_pygame.K_INSERT 153 | K_HOME = my_pygame.K_HOME 154 | K_END = my_pygame.K_END 155 | K_PAGEUP = my_pygame.K_PAGEUP 156 | K_PAGEDOWN = my_pygame.K_PAGEDOWN 157 | K_F1 = my_pygame.K_F1 158 | K_F2 = my_pygame.K_F2 159 | K_F3 = my_pygame.K_F3 160 | K_F4 = my_pygame.K_F4 161 | K_F5 = my_pygame.K_F5 162 | K_F6 = my_pygame.K_F6 163 | K_F7 = my_pygame.K_F7 164 | K_F8 = my_pygame.K_F8 165 | K_F9 = my_pygame.K_F9 166 | K_F10 = my_pygame.K_F10 167 | K_F11 = my_pygame.K_F11 168 | K_F12 = my_pygame.K_F12 169 | K_F13 = my_pygame.K_F13 170 | K_F14 = my_pygame.K_F14 171 | K_F15 = my_pygame.K_F15 172 | K_NUMLOCK = my_pygame.K_NUMLOCK 173 | K_CAPSLOCK = my_pygame.K_CAPSLOCK 174 | K_SCROLLOCK = my_pygame.K_SCROLLOCK 175 | K_RSHIFT = my_pygame.K_RSHIFT 176 | K_LSHIFT = my_pygame.K_LSHIFT 177 | K_RCTRL = my_pygame.K_RCTRL 178 | K_LCTRL = my_pygame.K_LCTRL 179 | K_RALT = my_pygame.K_RALT 180 | K_LALT = my_pygame.K_LALT 181 | K_RMETA = my_pygame.K_RMETA 182 | K_LMETA = my_pygame.K_LMETA 183 | K_LSUPER = my_pygame.K_LSUPER 184 | K_RSUPER = my_pygame.K_RSUPER 185 | K_MODE = my_pygame.K_MODE 186 | K_HELP = my_pygame.K_HELP 187 | K_PRINT = my_pygame.K_PRINT 188 | K_SYSREQ = my_pygame.K_SYSREQ 189 | K_BREAK = my_pygame.K_BREAK 190 | K_MENU = my_pygame.K_MENU 191 | K_POWER = my_pygame.K_POWER 192 | K_EURO = my_pygame.K_EURO 193 | K_AC_BACK = my_pygame.K_AC_BACK 194 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/display.py: -------------------------------------------------------------------------------- 1 | from typing import Any, Optional, Union 2 | 3 | import renpy.exports as renpy 4 | 5 | import pythonpackages.renpygame_pygame as pygame 6 | from pythonpackages.renpygame_pygame.display import * 7 | from pythonpackages.renpygame.rect import Rect 8 | from pythonpackages.renpygame.renpygameRender import Render 9 | 10 | 11 | class Surface(Render): 12 | """pygame: https://www.pygame.org/docs/ref/surface.html 13 | pygame_sdl2: https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/surface.pyx#L53 14 | """ 15 | 16 | def __init__( 17 | self, 18 | size: tuple[int, int] = (0, 0), 19 | flags: int = 0, 20 | depth: int = 0, 21 | masks=None, # Optional[ColorValue] 22 | ): 23 | # Render init 24 | # super().__init__(size[0], size[1]) 25 | Render.__init__(self, size[0], size[1]) 26 | 27 | # pygame.Surface init 28 | self.internal_surface = pygame.Surface(size, flags, depth, masks) 29 | 30 | def blit( 31 | self, source, pos: tuple[int, int], focus=True, main=True, index=None 32 | ) -> Rect: 33 | """pygame: https://www.pygame.org/docs/ref/surface.html#pygame.Surface.blit 34 | pygame_sdl2: https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/surface.pyx#L182 35 | """ 36 | if isinstance(source, pygame.Surface): 37 | self.internal_surface.blit(source, pos) 38 | if isinstance(pos, Rect) or isinstance(pos, pygame.Rect): 39 | pos = (pos.left, pos.top) 40 | super().blit(source, pos, focus, main, index) 41 | if isinstance(source, Surface) or isinstance(source, pygame.Surface): 42 | return source.get_rect() 43 | elif isinstance(source, Rect) or isinstance(source, pygame.Rect): 44 | return source 45 | elif isinstance(source, renpy.Render): 46 | return Rect() 47 | else: 48 | raise TypeError( 49 | f"renpygame.display.Surface.blit(): you have passed an invalid type: {type(source)} or not implemented yet" 50 | ) 51 | 52 | def convert(self, surface=None): 53 | return self.internal_surface.convert(surface) 54 | 55 | def convert_alpha(self, surface=None): 56 | return self.internal_surface.convert_alpha(surface) 57 | 58 | def copy(self): 59 | return self.internal_surface.copy() 60 | 61 | def fill(self, color, rect=None, special_flags=0): 62 | # self.internal_surface.fill(color, rect, special_flags) 63 | return super().fill(color) 64 | 65 | def scroll(self, dx: int = 0, dy: int = 0): 66 | return self.internal_surface.scroll(dx, dy) 67 | 68 | def set_colorkey(self, color, flags=0): 69 | return self.internal_surface.set_colorkey(color, flags) 70 | 71 | def get_colorkey(self): 72 | return self.internal_surface.get_colorkey() 73 | 74 | def set_alpha(self, value, flags=0): 75 | return self.internal_surface.set_alpha(value, flags) 76 | 77 | def get_alpha(self): 78 | return self.internal_surface.get_alpha() 79 | 80 | def lock(self, lock=None): 81 | return self.internal_surface.lock(lock) 82 | 83 | def unlock(self, lock=None): 84 | return self.internal_surface.unlock(lock) 85 | 86 | def mustlock(self): 87 | return self.internal_surface.mustlock() 88 | 89 | def get_locked(self): 90 | return self.internal_surface.get_locked() 91 | 92 | def get_locks(self): 93 | return self.internal_surface.get_locks() 94 | 95 | def get_at(self, pos): 96 | return self.internal_surface.get_at(pos) 97 | 98 | def set_at(self, pos, color): 99 | return self.internal_surface.set_at(pos, color) 100 | 101 | def get_at_mapped(self, pos): 102 | return self.internal_surface.get_at_mapped(pos) 103 | 104 | def map_rgb(self, color): 105 | return self.internal_surface.map_rgb(color) 106 | 107 | def unmap_rgb(self, pixel): 108 | return self.internal_surface.unmap_rgb(pixel) 109 | 110 | def set_clip(self, rect): 111 | return self.internal_surface.set_clip(rect) 112 | 113 | def get_clip(self): 114 | return self.internal_surface.get_clip() 115 | 116 | def subsurface(self, *args): 117 | self.internal_surface.subsurface(*args) 118 | return super().subsurface(*args) 119 | 120 | def get_parent(self): 121 | return self.internal_surface.get_parent() 122 | 123 | def get_abs_parent(self): 124 | return self.internal_surface.get_abs_parent() 125 | 126 | def get_offset(self): 127 | return self.internal_surface.get_offset() 128 | 129 | def get_abs_offset(self): 130 | return self.internal_surface.get_abs_offset() 131 | 132 | def get_size(self): 133 | self.internal_surface.get_size() 134 | return super().get_size() 135 | 136 | def get_width(self): 137 | self.internal_surface.get_width() 138 | return super().get_width() 139 | 140 | def get_height(self): 141 | self.internal_surface.get_height() 142 | return super().get_height() 143 | 144 | def get_rect(self, **kwargs) -> Rect: 145 | """https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/surface.pyx#L710""" 146 | rv = Rect(0, 0, self.width, self.height) 147 | 148 | for k, v in kwargs.items(): 149 | setattr(rv, k, v) 150 | 151 | # rv.renpygame_render = self.renpygame_render 152 | 153 | return rv 154 | 155 | def get_bitsize(self): 156 | return self.internal_surface.get_bitsize() 157 | 158 | def get_bytesize(self): 159 | return self.internal_surface.get_bytesize() 160 | 161 | def get_flags(self): 162 | return self.internal_surface.get_flags() 163 | 164 | def get_pitch(self): 165 | return self.internal_surface.get_pitch() 166 | 167 | def get_masks(self): 168 | return self.internal_surface.get_masks() 169 | 170 | def set_masks(self, masks): 171 | return self.internal_surface.set_masks(masks) 172 | 173 | def get_shifts(self): 174 | return self.internal_surface.get_shifts() 175 | 176 | def set_shifts(self, shifts): 177 | return self.internal_surface.set_shifts(shifts) 178 | 179 | def get_losses(self): 180 | return self.internal_surface.get_losses() 181 | 182 | def get_bounding_rect(self, min_alpha=1): 183 | return self.internal_surface.get_bounding_rect(min_alpha) 184 | 185 | def get_view(self, kind="2"): 186 | return self.internal_surface.get_view(kind) 187 | 188 | def get_buffer(self): 189 | return self.internal_surface.get_buffer() 190 | 191 | def from_data(self, data): 192 | return self.internal_surface.from_data(data) 193 | 194 | # my methods 195 | 196 | @property 197 | def internal_surface(self) -> pygame.Surface: 198 | return self._internal_surface 199 | 200 | @internal_surface.setter 201 | def internal_surface(self, value: pygame.Surface): 202 | self._internal_surface = value 203 | 204 | 205 | def set_mode( 206 | size: tuple[int, int] = (0, 0), 207 | flags: int = 0, 208 | depth: int = 0, 209 | display: int = 0, 210 | vsync: int = 0, 211 | ) -> Surface: 212 | """If it is commented out it will replace the renpy screen creating an error when returning to renpy. https://www.pygame.org/docs/ref/display.html#pygame.display.set_mode""" 213 | # * It has the job of replacing the original so nothing happens 214 | return Surface(size, flags, depth) 215 | 216 | 217 | def mode_ok( 218 | size: tuple[int, int], flags: int = 0, depth: int = 0, display: int = 0 219 | ) -> int: 220 | """https://www.pygame.org/docs/ref/display.html#pygame.display.mode_ok""" 221 | return pygame.display.mode_ok(size, flags, depth) # type: ignore 222 | 223 | 224 | def set_icon(Surface: pygame.Surface) -> None: 225 | """https://www.pygame.org/docs/ref/display.html#pygame.display.set_icon""" 226 | if not isinstance(Surface, pygame.Surface): 227 | print( 228 | "set_icon(): Warning: Surface is not a pygame_sdl2.surface.Surface, it is a", 229 | type(Surface), 230 | ) 231 | print("if you have a renpyGame Image you can use image.pygame_image") 232 | return pygame.display.set_icon(Surface) # type: ignore 233 | 234 | 235 | def flip() -> None: 236 | """https://www.pygame.org/docs/ref/display.html#pygame.display.flip""" 237 | return pygame.display.flip() # type: ignore 238 | 239 | 240 | def update(rectangle: Optional[Union[list, Any]] = None) -> None: 241 | """https://www.pygame.org/docs/ref/display.html#pygame.display.update""" 242 | return pygame.display.update(rectangle) # type: ignore 243 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/draw.py: -------------------------------------------------------------------------------- 1 | from pythonpackages.renpygame.renpygameCanvas import Canvas 2 | from pythonpackages.renpygame.renpygameRender import Render 3 | from pythonpackages.renpygame_pygame.draw import * 4 | import renpy.exports as renpy 5 | 6 | # https://www.pygame.org/docs/ref/draw.html 7 | # https://www.renpy.org/doc/html/cdd.html#renpy.Render.canvas 8 | # https://github.com/renpy/renpy/blob/master/renpy/display/render.pyx#L1610 9 | 10 | 11 | def get_canvas(surface: Render) -> Canvas: 12 | if hasattr(surface, "internal_render") and surface.internal_render: 13 | render_to_use = surface.internal_render 14 | else: 15 | render_to_use = surface 16 | if hasattr(render_to_use, "renpygame_canvas"): 17 | canvas = render_to_use.renpygame_canvas 18 | elif hasattr(surface, "renpygame_canvas"): 19 | canvas = surface.renpygame_canvas 20 | else: 21 | canvas = render_to_use.canvas() 22 | return canvas 23 | 24 | 25 | def rect( 26 | surface: Render, 27 | color, 28 | rect, 29 | width=0, 30 | border_radius=0, 31 | border_top_left_radius=-1, 32 | border_top_right_radius=-1, 33 | border_bottom_left_radius=-1, 34 | border_bottom_right_radius=-1, 35 | ): 36 | """https://www.pygame.org/docs/ref/draw.html#pygame.draw.rect""" 37 | canvas = get_canvas(surface) 38 | canvas.rect(color, rect, width) 39 | return surface 40 | 41 | 42 | def polygon(surface, color, points, width=0): 43 | """https://www.pygame.org/docs/ref/draw.html#pygame.draw.polygon""" 44 | canvas = get_canvas(surface) 45 | canvas.polygon(color, points, width) 46 | return surface 47 | 48 | 49 | def circle( 50 | surface, 51 | color, 52 | center, 53 | radius, 54 | width=0, 55 | draw_top_right=None, 56 | draw_top_left=None, 57 | draw_bottom_left=None, 58 | draw_bottom_right=None, 59 | ): 60 | """https://www.pygame.org/docs/ref/draw.html#pygame.draw.circle""" 61 | canvas = get_canvas(surface) 62 | canvas.circle(color, center, radius, width) 63 | return canvas.get_surface().get_rect() 64 | 65 | 66 | def ellipse(surface, color, rect, width=0): 67 | """https://www.pygame.org/docs/ref/draw.html#pygame.draw.ellipse""" 68 | canvas = get_canvas(surface) 69 | canvas.ellipse(color, rect, width) 70 | return surface 71 | 72 | 73 | def arc(surface, color, rect, start_angle, stop_angle, width=1): 74 | """https://www.pygame.org/docs/ref/draw.html#pygame.draw.arc""" 75 | canvas = get_canvas(surface) 76 | canvas.arc(color, rect, start_angle, stop_angle, width) 77 | return surface 78 | 79 | 80 | def line(surface, color, start_pos, end_pos, width=1): 81 | """https://www.pygame.org/docs/ref/draw.html#pygame.draw.line""" 82 | canvas = get_canvas(surface) 83 | canvas.line(color, start_pos, end_pos, width) 84 | return surface 85 | 86 | 87 | def lines(surface, color, closed, pointlist, width=1): 88 | """https://www.pygame.org/docs/ref/draw.html#pygame.draw.lines""" 89 | canvas = get_canvas(surface) 90 | canvas.lines(color, closed, pointlist, width) 91 | return surface 92 | 93 | 94 | def aaline(surface, color, startpos, endpos, blend=1): 95 | """https://www.pygame.org/docs/ref/draw.html#pygame.draw.aaline""" 96 | canvas = get_canvas(surface) 97 | canvas.aaline(color, startpos, endpos, blend) 98 | return surface 99 | 100 | 101 | def aalines(surface, color, closed, pointlist, blend=1): 102 | """https://www.pygame.org/docs/ref/draw.html#pygame.draw.aalines""" 103 | canvas = get_canvas(surface) 104 | canvas.aalines(color, closed, pointlist, blend) 105 | return surface 106 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/event.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | import pythonpackages.renpygame_pygame as pygame 4 | from pythonpackages.renpygame_pygame.event import * 5 | 6 | # https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/event.pyx 7 | 8 | 9 | class EventType(pygame.event.EventType): # type: ignore 10 | """ "pygame_sdl2: https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/event.pyx#LL58C1-L97C1 11 | pygame: https://www.pygame.org/docs/ref/event.html#pygame.event.Event""" 12 | 13 | @property 14 | def dict(self): 15 | return super().dict 16 | 17 | @property 18 | def type(self) -> int: 19 | return super().type 20 | 21 | @property 22 | def key(self) -> Optional[int]: 23 | return super().key 24 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/image.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | import renpy.exports as renpy 3 | 4 | import pythonpackages.renpygame_pygame as pygame 5 | from pythonpackages.renpygame.display import Surface 6 | from pythonpackages.renpygame_pygame.image import * 7 | 8 | 9 | # class Image(renpy.display.image.DynamicImage): 10 | class Image(renpy.display.im.Image): 11 | """renpy: https://github.com/renpy/renpy/blob/master/renpy/display/im.py#L709""" 12 | 13 | def __init__( 14 | self, 15 | filename: str, 16 | **properties, 17 | ): 18 | super().__init__(filename, **properties) 19 | self.rotate = 0 20 | 21 | def get_hash(self): 22 | return super().get_hash() 23 | 24 | def get_oversample(self): 25 | return super().get_oversample() 26 | 27 | def load(self, unscaled=False): 28 | return super().load(unscaled) 29 | 30 | def predict_files(self) -> list[str]: 31 | return super().predict_files() 32 | 33 | # my methods 34 | 35 | @property 36 | def size(self) -> tuple[int, int]: 37 | return self.pygame_image.get_size() 38 | 39 | @property 40 | def width(self) -> int: 41 | width, _ = self.size 42 | return width 43 | 44 | @property 45 | def height(self) -> int: 46 | _, height = self.size 47 | return height 48 | 49 | @property 50 | def imagename(self) -> str: 51 | images_names = self.predict_files() 52 | if len(images_names) > 0: 53 | return images_names[0] 54 | else: 55 | raise FileNotFoundError( 56 | f"renpygame.image.Image.imagename: Image not found: {self}" 57 | ) 58 | 59 | @property 60 | def file(self): 61 | path = "images/" + self.imagename 62 | return renpy.open_file(path) 63 | 64 | @property 65 | def pygame_image(self) -> pygame.Surface: 66 | image = pygame.image.load(self.file) # type: ignore 67 | image = image.convert() 68 | return image 69 | 70 | def convert(self, st: float, at: float) -> Surface: 71 | # TODO: try use renpy.load_surface 72 | surface = Surface(self.size) 73 | transform = self.transform 74 | if transform: 75 | render = renpy.render(transform, self.width, self.height, st, at) 76 | else: 77 | render = renpy.render(self, self.width, self.height, st, at) 78 | surface.blit(render, (0, 0)) 79 | # TODO: try use olther methods 80 | surface.internal_render = render 81 | return surface 82 | 83 | @property 84 | def transform(self) -> Optional[renpy.display.transform.Transform]: 85 | """https://github.com/renpy/renpy/blob/master/renpy/display/transform.py#L505""" 86 | # TODO: to improve 87 | if self.rotate and self.rotate != 0: 88 | return renpy.display.transform.Transform(self.imagename, rotate=self.rotate) 89 | return None 90 | 91 | @property 92 | def rotate(self) -> Optional[int]: 93 | return self._rotation 94 | 95 | @rotate.setter 96 | def rotate(self, value: int): 97 | self._rotation = value 98 | 99 | 100 | class Flip(renpy.display.im.Flip): 101 | """renpy: https://github.com/renpy/renpy/blob/master/renpy/display/im.py#L1064""" 102 | 103 | def __init__( 104 | self, 105 | im: Image, 106 | horizontal=False, 107 | vertical=False, 108 | **properties, 109 | ): 110 | super().__init__(im, horizontal, vertical, **properties) 111 | 112 | def get_hash(self): 113 | return super().get_hash() 114 | 115 | def load(self): 116 | return super().load() 117 | 118 | def predict_files(self) -> list[str]: 119 | return super().predict_files() 120 | 121 | # my methods 122 | 123 | @property 124 | def size(self) -> tuple[int, int]: 125 | return self.pygame_image.get_size() 126 | 127 | @property 128 | def width(self) -> int: 129 | width, _ = self.size 130 | return width 131 | 132 | @property 133 | def height(self) -> int: 134 | _, height = self.size 135 | return height 136 | 137 | @property 138 | def imagename(self) -> str: 139 | images_names = self.predict_files() 140 | if len(images_names) > 0: 141 | return images_names[0] 142 | else: 143 | raise FileNotFoundError( 144 | f"renpygame.image.Flip.imagename: Image not found: {self}" 145 | ) 146 | 147 | @property 148 | def file(self): 149 | path = "images/" + self.imagename 150 | return renpy.open_file(path) 151 | 152 | @property 153 | def pygame_image(self) -> pygame.Surface: 154 | image = pygame.image.load(self.file) # type: ignore 155 | image = image.convert() 156 | return image 157 | 158 | def convert(self, st: float, at: float) -> Surface: 159 | return Image.convert(self, st, at) 160 | 161 | 162 | class Scale(renpy.display.im.Scale): 163 | """https://github.com/renpy/renpy/blob/master/renpy/display/im.py#L947""" 164 | 165 | def __init__(self, im, width, height, bilinear=True, **properties): 166 | super().__init__(im, width, height, bilinear, **properties) 167 | 168 | def get_hash(self): 169 | return super().get_hash() 170 | 171 | def load(self): 172 | return super().load() 173 | 174 | def predict_files(self) -> list[str]: 175 | return super().predict_files() 176 | 177 | # my methods 178 | 179 | @property 180 | def size(self) -> tuple[int, int]: 181 | return self.pygame_image.get_size() 182 | 183 | @property 184 | def width(self) -> int: 185 | width, _ = self.size 186 | return width 187 | 188 | @property 189 | def height(self) -> int: 190 | _, height = self.size 191 | return height 192 | 193 | @property 194 | def imagename(self) -> str: 195 | images_names = self.predict_files() 196 | if len(images_names) > 0: 197 | return images_names[0] 198 | else: 199 | raise FileNotFoundError( 200 | f"renpygame.image.Scale.imagename: Image not found: {self}" 201 | ) 202 | 203 | @property 204 | def file(self): 205 | path = "images/" + self.imagename 206 | return renpy.open_file(path) 207 | 208 | @property 209 | def pygame_image(self) -> pygame.Surface: 210 | image = pygame.image.load(self.file) # type: ignore 211 | image = image.convert() 212 | return image 213 | 214 | def convert(self, st: float, at: float) -> Surface: 215 | return Image.convert(self, st, at) 216 | 217 | 218 | class Rotozoom(renpy.display.im.Rotozoom): 219 | """https://github.com/renpy/renpy/blob/master/renpy/display/im.py#L1113""" 220 | 221 | def __init__(self, im, angle, zoom, **properties): 222 | super().__init__(im, angle, zoom, **properties) 223 | 224 | def get_hash(self): 225 | return super().get_hash() 226 | 227 | def load(self): 228 | return super().load() 229 | 230 | def predict_files(self) -> list[str]: 231 | return super().predict_files() 232 | 233 | # my methods 234 | 235 | @property 236 | def size(self) -> tuple[int, int]: 237 | return self.pygame_image.get_size() 238 | 239 | @property 240 | def width(self) -> int: 241 | width, _ = self.size 242 | return width 243 | 244 | @property 245 | def height(self) -> int: 246 | _, height = self.size 247 | return height 248 | 249 | @property 250 | def imagename(self) -> str: 251 | images_names = self.predict_files() 252 | if len(images_names) > 0: 253 | return images_names[0] 254 | else: 255 | raise FileNotFoundError( 256 | f"renpygame.image.Rotozoom.imagename: Image not found: {self}" 257 | ) 258 | 259 | @property 260 | def file(self): 261 | path = "images/" + self.imagename 262 | return renpy.open_file(path) 263 | 264 | @property 265 | def pygame_image(self) -> pygame.Surface: 266 | image = pygame.image.load(self.file) # type: ignore 267 | image = image.convert() 268 | return image 269 | 270 | def convert(self, st: float, at: float) -> Surface: 271 | return Image.convert(self, st, at) 272 | 273 | 274 | def load(path: str) -> Image: 275 | """https://www.pygame.org/docs/ref/image.html#pygame.image.load""" 276 | return Image(path) 277 | 278 | 279 | # MatrixColor 280 | 281 | 282 | class MatrixColor(renpy.display.im.ImageBase): 283 | """https://github.com/renpy/renpy/blob/master/renpy/display/im.py#L1400""" 284 | 285 | def __init__(self, im, matrix, **properties): 286 | super().__init__(im, matrix, **properties) 287 | 288 | def get_hash(self): 289 | return super().get_hash() 290 | 291 | def load(self): 292 | return super().load() 293 | 294 | def predict_files(self) -> list[str]: 295 | return super().predict_files() 296 | 297 | # my methods 298 | 299 | @property 300 | def size(self) -> tuple[int, int]: 301 | return self.pygame_image.get_size() 302 | 303 | @property 304 | def width(self) -> int: 305 | width, _ = self.size 306 | return width 307 | 308 | @property 309 | def height(self) -> int: 310 | _, height = self.size 311 | return height 312 | 313 | @property 314 | def imagename(self) -> str: 315 | images_names = self.predict_files() 316 | if len(images_names) > 0: 317 | return images_names[0] 318 | else: 319 | raise FileNotFoundError( 320 | f"renpygame.image.MatrixColor.imagename: Image not found: {self}" 321 | ) 322 | 323 | @property 324 | def file(self): 325 | path = "images/" + self.imagename 326 | return renpy.open_file(path) 327 | 328 | @property 329 | def pygame_image(self) -> pygame.Surface: 330 | image = pygame.image.load(self.file) # type: ignore 331 | image = image.convert() 332 | return image 333 | 334 | def convert(self, st: float, at: float) -> Surface: 335 | return Image.convert(self, st, at) 336 | 337 | 338 | def Grayscale(im, desat=(0.2126, 0.7152, 0.0722), **properties): 339 | """https://github.com/renpy/renpy/blob/master/renpy/display/im.py#L1792""" 340 | return MatrixColor(im, matrix.saturation(0.0, desat), **properties) 341 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/mixer.py: -------------------------------------------------------------------------------- 1 | import renpy.exports as renpy 2 | 3 | from pythonpackages.renpygame import mixer_music 4 | 5 | music = mixer_music 6 | 7 | # https://www.renpy.org/doc/html/audio.html#functions 8 | 9 | 10 | class Sound: 11 | """pygame: https://www.pygame.org/docs/ref/mixer.html#pygame.mixer.Sound""" 12 | 13 | def __init__(self, filename: str): 14 | self.filename = filename 15 | return 16 | 17 | def play(self, loops: int = 0, maxtime: int = -1, fade_ms: int = 0): 18 | """pygame: https://www.pygame.org/docs/ref/mixer.html#pygame.mixer.Sound.play 19 | renpy: https://www.renpy.org/doc/html/audio.html#renpy.play""" 20 | renpy.play(self.filename, channel=None) 21 | return 22 | 23 | def stop(self): 24 | """pygame: https://www.pygame.org/docs/ref/mixer.html#pygame.mixer.Sound.stop""" 25 | # TODO: implement 26 | print("renpygame.mixer.Sound.stop: not implemented yet") 27 | return 28 | 29 | def pause(self): 30 | """pygame: https://www.pygame.org/docs/ref/mixer.html#pygame.mixer.Sound.pause""" 31 | # TODO: implement 32 | print("renpygame.mixer.Sound.pause: not implemented yet") 33 | return 34 | 35 | def unpause(self): 36 | """pygame: https://www.pygame.org/docs/ref/mixer.html#pygame.mixer.Sound.unpause""" 37 | # TODO: implement 38 | return 39 | 40 | def fadeout(self, time): 41 | # TODO: implement 42 | print("renpygame.mixer.Sound.fadeout: not implemented yet") 43 | return 44 | 45 | def set_volume(self, value: float): 46 | # TODO: implement 47 | print("renpygame.mixer.Sound.set_volume: not implemented yet") 48 | return 49 | 50 | def get_volume(self) -> float: 51 | # TODO: implement 52 | print("renpygame.mixer.Sound.get_volume: not implemented yet") 53 | return 0 54 | 55 | def get_num_channels(self) -> int: 56 | # TODO: implement 57 | print("renpygame.mixer.Sound.get_num_channels: not implemented yet") 58 | return 0 59 | 60 | def get_length(self) -> float: 61 | # TODO: implement 62 | print("renpygame.mixer.Sound.get_length: not implemented yet") 63 | return 0 64 | 65 | def get_raw(self) -> bytes: 66 | # TODO: implement 67 | print("renpygame.mixer.Sound.get_raw: not implemented yet") 68 | return bytes() 69 | 70 | # my methods 71 | @property 72 | def filename(self) -> str: 73 | return self._filename 74 | 75 | @filename.setter 76 | def filename(self, value: str): 77 | self._filename = value 78 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/mixer_music.py: -------------------------------------------------------------------------------- 1 | import renpy.exports as renpy 2 | 3 | # https://www.renpy.org/doc/html/audio.html#functions 4 | # https://www.pygame.org/docs/ref/music.html 5 | 6 | 7 | global current_music_filename 8 | 9 | 10 | def load(filename: str) -> None: 11 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.load""" 12 | global current_music_filename 13 | current_music_filename = filename 14 | return 15 | 16 | 17 | def unload() -> None: 18 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.unload""" 19 | global current_music_filename 20 | current_music_filename = None 21 | return 22 | 23 | 24 | def play(loops: int = 0, start: float = 0.0, fade_ms: int = 0) -> None: 25 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.play""" 26 | if current_music_filename is None: 27 | print("renpygame.mixer_music.play: no music loaded") 28 | return 29 | renpy.music.play(current_music_filename, loop=loops, fadeout=fade_ms) 30 | return 31 | 32 | 33 | def rewind() -> None: 34 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.rewind""" 35 | # TODO: implement 36 | print("renpygame.mixer_music.rewind: not implemented yet") 37 | return 38 | 39 | 40 | def stop() -> None: 41 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.stop""" 42 | renpy.music.stop() 43 | return 44 | 45 | 46 | def pause() -> None: 47 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.pause""" 48 | renpy.music.set_pause(True) 49 | return 50 | 51 | 52 | def unpause() -> None: 53 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.unpause""" 54 | renpy.music.set_pause(False) 55 | return 56 | 57 | 58 | def fadeout(time: float) -> None: 59 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.fadeout""" 60 | # TODO: implement 61 | print("renpygame.mixer_music.fadeout: not implemented yet") 62 | return 63 | 64 | 65 | def set_volume(volume: float) -> None: 66 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.set_volume""" 67 | renpy.music.set_volume(volume) 68 | return 69 | 70 | 71 | def get_volume() -> float: 72 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.get_volume""" 73 | # TODO: implement 74 | print("renpygame.mixer_music.get_volume: not implemented yet") 75 | return 0.0 76 | 77 | 78 | def get_busy() -> bool: 79 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.get_busy""" 80 | # TODO: implement 81 | print("renpygame.mixer_music.get_busy: not implemented yet") 82 | return False 83 | 84 | 85 | def set_pos(pos: float) -> None: 86 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.set_pos""" 87 | # TODO: implement 88 | print("renpygame.mixer_music.set_pos: not implemented yet") 89 | return 90 | 91 | 92 | def get_pos() -> float: 93 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.get_pos""" 94 | renpy.music.get_pos() 95 | return 0.0 96 | 97 | 98 | def queue(fileobj, namehint: str = "", loops: int = 0) -> None: 99 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.queue""" 100 | renpy.music.queue(fileobj, loop=loops) 101 | return 102 | 103 | 104 | def set_endevent() -> None: 105 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.set_endevent""" 106 | # TODO: implement 107 | print("renpygame.mixer_music.set_endevent: not implemented yet") 108 | return 109 | 110 | 111 | def get_endevent() -> type: 112 | """pygame: https://www.pygame.org/docs/ref/music.html#pygame.mixer.music.get_endevent""" 113 | # TODO: implement 114 | print("renpygame.mixer_music.get_endevent: not implemented yet") 115 | return type 116 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/rect.py: -------------------------------------------------------------------------------- 1 | import pythonpackages.renpygame_pygame as pygame 2 | from pythonpackages.renpygame_pygame.rect import * 3 | from pythonpackages.renpygame.renpygameRender import Render 4 | 5 | 6 | class Rect(Render): 7 | """pygame: https://www.pygame.org/docs/ref/rect.html 8 | pygame_sdl2: https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/rect.pyx#L28 9 | """ 10 | 11 | def __init__( 12 | self, 13 | left: int = 0, 14 | top: int = 0, 15 | width: int = 0, 16 | height: int = 0, 17 | ): 18 | # Render init 19 | Render.__init__(self, width, height) 20 | 21 | # pygame.Rect init 22 | self.internal_rect = pygame.Rect(left, top, width, height) 23 | 24 | def __reduce__(self): 25 | return self.internal_rect.__reduce__() 26 | 27 | def __repr__(self): 28 | return self.internal_rect.__repr__() 29 | 30 | def __len__(self): 31 | return self.internal_rect.__len__() 32 | 33 | def __iter__(self): 34 | return self.internal_rect.__iter__() 35 | 36 | def __richcmp__(self, a, b, op: int): 37 | return self.internal_rect.__richcmp__(a, b, op) 38 | 39 | def __getitem__(self, key): 40 | return self.internal_rect.__getitem__(key) 41 | 42 | def __setitem__(self, key, val): 43 | return self.internal_rect.__setitem__(key, val) 44 | 45 | @property 46 | def left(self) -> int: 47 | return self.internal_rect.left 48 | 49 | @left.setter 50 | def left(self, value: int): 51 | self.internal_rect.left = value 52 | 53 | @property 54 | def top(self) -> int: 55 | return self.internal_rect.top 56 | 57 | @top.setter 58 | def top(self, value: int): 59 | self.internal_rect.top = value 60 | 61 | # * they are already defined in Render 62 | # @property 63 | # def width(self) -> int: 64 | # return int(super().width) 65 | 66 | # @width.setter 67 | # def width(self, value): 68 | # super().width = value 69 | 70 | # @property 71 | # def height(self) -> int: 72 | # return int(super().height) 73 | 74 | # @height.setter 75 | # def height(self, value): 76 | # super().height = value 77 | 78 | @property 79 | def right(self): 80 | return self.internal_rect.right 81 | 82 | @right.setter 83 | def right(self, value): 84 | self.internal_rect.right = value 85 | 86 | @property 87 | def bottom(self): 88 | return self.internal_rect.bottom 89 | 90 | @bottom.setter 91 | def bottom(self, value): 92 | self.internal_rect.bottom = value 93 | 94 | @property 95 | def size(self): 96 | return self.internal_rect.size 97 | 98 | @size.setter 99 | def size(self, value): 100 | self.internal_rect.size = value 101 | 102 | @property 103 | def topleft(self): 104 | return self.internal_rect.topleft 105 | 106 | @topleft.setter 107 | def topleft(self, value): 108 | self.internal_rect.topleft = value 109 | 110 | @property 111 | def topright(self): 112 | return self.internal_rect.topright 113 | 114 | @topright.setter 115 | def topright(self, value): 116 | self.internal_rect.topright = value 117 | 118 | @property 119 | def bottomright(self): 120 | return self.internal_rect.bottomright 121 | 122 | @bottomright.setter 123 | def bottomright(self, value): 124 | self.internal_rect.bottomright = value 125 | 126 | @property 127 | def bottomleft(self): 128 | return self.internal_rect.bottomleft 129 | 130 | @bottomleft.setter 131 | def bottomleft(self, value): 132 | self.internal_rect.bottomleft = value 133 | 134 | @property 135 | def centerx(self): 136 | return self.internal_rect.centerx 137 | 138 | @centerx.setter 139 | def centerx(self, value): 140 | self.internal_rect.centerx = value 141 | 142 | @property 143 | def centery(self): 144 | return self.internal_rect.centery 145 | 146 | @centery.setter 147 | def centery(self, value): 148 | self.internal_rect.centery = value 149 | 150 | @property 151 | def center(self): 152 | return self.internal_rect.center 153 | 154 | @center.setter 155 | def center(self, value): 156 | self.internal_rect.center = value 157 | 158 | @property 159 | def midtop(self): 160 | return self.internal_rect.midtop 161 | 162 | @midtop.setter 163 | def midtop(self, value): 164 | self.internal_rect.midtop = value 165 | 166 | @property 167 | def midleft(self): 168 | return self.internal_rect.midleft 169 | 170 | @midleft.setter 171 | def midleft(self, value): 172 | self.internal_rect.midleft = value 173 | 174 | @property 175 | def midbottom(self): 176 | return self.internal_rect.midbottom 177 | 178 | @midbottom.setter 179 | def midbottom(self, value): 180 | self.internal_rect.midbottom = value 181 | 182 | @property 183 | def midright(self): 184 | return self.internal_rect.midright 185 | 186 | @midright.setter 187 | def midright(self, value): 188 | self.internal_rect.midright = value 189 | 190 | def copy(self): 191 | return self.internal_rect.copy() 192 | 193 | def move(self, *args): 194 | return self.internal_rect.move(*args) 195 | 196 | def move_ip(self, *args): 197 | return self.internal_rect.move_ip(*args) 198 | 199 | def inflate(self, *args): 200 | return self.internal_rect.inflate(*args) 201 | 202 | def inflate_ip(self, *args): 203 | return self.internal_rect.inflate_ip(*args) 204 | 205 | def clamp(self, other): 206 | return self.internal_rect.clamp(other) 207 | 208 | def clamp_ip(self, other): 209 | return self.internal_rect.clamp_ip(other) 210 | 211 | def clip(self, other, y=None, w=None, h=None): 212 | return self.internal_rect.clip(other, y, w, h) 213 | 214 | def union(self, other): 215 | return self.internal_rect.union(other) 216 | 217 | def union_ip(self, other): 218 | return self.internal_rect.union_ip(other) 219 | 220 | def unionall(self, other_seq): 221 | return self.internal_rect.unionall(other_seq) 222 | 223 | def unionall_ip(self, other_seq): 224 | return self.internal_rect.unionall_ip(other_seq) 225 | 226 | def fit(self, other): 227 | return self.internal_rect.fit(other) 228 | 229 | def normalize(self): 230 | return self.internal_rect.normalize() 231 | 232 | def contains(self, other): 233 | return self.internal_rect.contains(other) 234 | 235 | def collidepoint(self, x, y=None): 236 | return self.internal_rect.collidepoint(x, y) 237 | 238 | def colliderect(self, other): 239 | return self.internal_rect.colliderect(other) 240 | 241 | def collidelist(self, other_list): 242 | return self.internal_rect.collidelist(other_list) 243 | 244 | def collidelistall(self, other_list): 245 | return self.internal_rect.collidelistall(other_list) 246 | 247 | def collidedict(self, other_dict, rects_values=0): 248 | return self.internal_rect.collidedict(other_dict, rects_values) 249 | 250 | def collidedictall(self, other_dict, rects_values=0): 251 | return self.internal_rect.collidedictall(other_dict, rects_values) 252 | 253 | # my methods 254 | 255 | @property 256 | def internal_rect(self) -> pygame.Rect: 257 | return self._internal_rect 258 | 259 | @internal_rect.setter 260 | def internal_rect(self, value: pygame.Rect): 261 | self._internal_rect = value 262 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/renpygameCDD.py: -------------------------------------------------------------------------------- 1 | from typing import Any, Callable, Optional 2 | 3 | import renpy.exports as renpy 4 | 5 | import pythonpackages.renpygame as pygame 6 | from pythonpackages.renpygame.event import EventType 7 | from pythonpackages.renpygame.renpygameRender import Render 8 | 9 | # https://www.renpy.org/doc/html/cdd.html 10 | 11 | PYGAMEEVENT = 6828 12 | PYGAMEENDEVENT = 9873 13 | 14 | 15 | def main_render( 16 | child_render: Optional[Render], width: int, height: int 17 | ) -> renpy.Render: 18 | """is a Render that contains the child_render. 19 | # TODO: try to remove and return child_render 20 | """ 21 | render = renpy.Render(width, height) 22 | if child_render: 23 | if child_render.background_render: 24 | surf = renpy.render( 25 | child_render.background_render, 26 | child_render.width, 27 | child_render.height, 28 | 0, 29 | 0, 30 | ) 31 | render.blit(surf, (0, 0)) 32 | render.blit(child_render, (0, 0)) 33 | return render 34 | 35 | 36 | class RenpyGameByEvent(renpy.Displayable): 37 | """CDD: https://www.renpy.org/doc/html/cdd.html 38 | renpy.Displayable: https://github.com/renpy/renpy/blob/master/renpy/display/core.py#L292 39 | """ 40 | 41 | def __init__( 42 | self, 43 | render_lambda: Callable[[int, int, float, float], Render], 44 | event_lambda: Callable[ 45 | [EventType, int, int, float, Callable[[int], None]], Any 46 | ], 47 | redraw_lambda: Optional[Callable[[Render, float, float], None]] = None, 48 | **kwargs, 49 | ): 50 | # renpy.Displayable init 51 | super(RenpyGameByEvent, self).__init__(**kwargs) 52 | 53 | self.render_lambda = render_lambda 54 | self.event_lambda = event_lambda 55 | self.redraw_lambda = redraw_lambda 56 | self.child_render = None 57 | 58 | def render(self, width: int, height: int, st: float, at: float) -> renpy.Render: 59 | """https://github.com/renpy/renpy/blob/master/renpy/display/render.pyx#L170""" 60 | # if is first time rendering 61 | if self.child_render is None: 62 | self.child_render = self.render_lambda(width, height, st, at) 63 | else: 64 | if self.redraw_lambda is not None: 65 | self.redraw_lambda(self.child_render, st, at) 66 | return main_render(self.child_render, width, height) 67 | 68 | def event(self, ev: EventType, x: int, y: int, st: float): 69 | """keys: https://www.pygame.org/docs/ref/key.html#key-constants-label 70 | pygame_sdl2: https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/event.pyx 71 | """ 72 | if PYGAMEENDEVENT == ev.type: # 32768 is the event type for pause menu 73 | print("Renpy Game End") 74 | renpy.free_memory() 75 | pygame.time.set_timer(PYGAMEEVENT, 0) 76 | return 0 77 | return self.event_lambda(ev, x, y, st, self.redraw) 78 | 79 | def show(self): 80 | """wiki: https://github.com/DRincs-Productions/Renpygame/wiki/Minigame-with-a-render-loop#start-a-game-between-a-sterted-menu""" 81 | print("Renpy Game Show") 82 | renpy.call_screen("renpygame_surface", surface=self) 83 | return 84 | 85 | def redraw(self, delay: int): 86 | renpy.redraw(self, delay) 87 | 88 | @property 89 | def render_lambda(self) -> Callable[[int, int, float, float], Render]: 90 | """function that returns a child_render""" 91 | return self._render_lambda 92 | 93 | @render_lambda.setter 94 | def render_lambda(self, value: Callable[[int, int, float, float], Render]): 95 | self._render_lambda = value 96 | 97 | @property 98 | def child_render(self) -> Optional[Render]: 99 | """child_render is a Render object""" 100 | return self._child_render 101 | 102 | @child_render.setter 103 | def child_render(self, value: Optional[Render]): 104 | self._child_render = value 105 | 106 | 107 | def render_free_memory(): 108 | """ 109 | Frees memory used by the render system. 110 | """ 111 | 112 | # global screen_render 113 | # screen_render = None 114 | 115 | # renpy.display.render.mark_sweep() 116 | 117 | renpy.display.render.render_cache.clear() 118 | 119 | # This can hang onto a render. 120 | renpy.display.interface.surftree = None 121 | 122 | 123 | def kill_textures(): 124 | """ 125 | Kills all textures that have been loaded. 126 | """ 127 | 128 | if renpy.display.draw is not None: 129 | renpy.display.draw.kill_textures() 130 | 131 | renpy.display.im.cache.clear() 132 | render_free_memory() 133 | renpy.text.text.layout_cache_clear() 134 | renpy.display.video.texture.clear() 135 | 136 | 137 | def free_memory(): 138 | """https://github.com/renpy/renpy/blob/ed471a56cbe82d58d8b68faf807e4f0ff860f1a5/renpy/exports.py#LL2692C1-L2705C1""" 139 | renpy.force_full_redraw() 140 | kill_textures() 141 | renpy.display.interface.kill_surfaces() 142 | renpy.text.font.free_memory() 143 | 144 | renpy.gc.collect(2) 145 | 146 | if renpy.gc.garbage: 147 | del renpy.gc.garbage[:] 148 | return 149 | 150 | 151 | class RenpyGameByTimer(renpy.Displayable): 152 | """ """ 153 | 154 | def __init__( 155 | self, 156 | first_step: Callable[[int, int, float, float], Render], 157 | update_process: Callable[ 158 | [Render, float, Optional[float], int], Optional[float] 159 | ], 160 | event_lambda: Optional[Callable[[EventType, int, int, float], Any]] = None, 161 | delay: float = 0.05, 162 | end_game_frame: Optional[ 163 | Callable[[Render, float, float, float, int], None] 164 | ] = None, 165 | is_full_redraw: Optional[Callable[[int], bool]] = None, 166 | **kwargs, 167 | ): 168 | self.first_step = first_step 169 | self.delay = None 170 | self.last_delay = None 171 | self.start_delay = delay 172 | self.update_process = update_process 173 | self.event_lambda = event_lambda 174 | self.child_render = None 175 | self.current_frame_number = 0 176 | self.is_started = False 177 | self.is_game_end = False 178 | self.end_game_frame = end_game_frame 179 | self.is_game_end_menu = False 180 | self.is_full_redraw_lamda = is_full_redraw 181 | 182 | # renpy.Displayable init 183 | super(RenpyGameByTimer, self).__init__(**kwargs) 184 | 185 | @property 186 | def child_render(self) -> Optional[Render]: 187 | """child_render is a Render object and is a current frame of the game""" 188 | return self._child_render 189 | 190 | @child_render.setter 191 | def child_render(self, value: Optional[Render]): 192 | self._child_render = value 193 | 194 | @property 195 | def delay(self) -> Optional[float]: 196 | """wiki: https://github.com/DRincs-Productions/Renpygame/wiki/Minigame-with-a-render-loop#delay""" 197 | return self._delay 198 | 199 | @delay.setter 200 | def delay(self, value: Optional[float]): 201 | self._delay = value 202 | 203 | @property 204 | def start_delay(self) -> float: 205 | """start_delay is a time between frames""" 206 | return self._start_delay 207 | 208 | @start_delay.setter 209 | def start_delay(self, value: float): 210 | self._start_delay = value 211 | 212 | @property 213 | def update_process( 214 | self, 215 | ) -> Callable[[Render, float, Optional[float], int], Optional[float]]: 216 | """wiki: https://github.com/DRincs-Productions/Renpygame/wiki/Minigame-with-a-render-loop#first_step-and-update_process""" 217 | return self._update_process 218 | 219 | @update_process.setter 220 | def update_process( 221 | self, 222 | value: Callable[[Render, float, Optional[float], int], Optional[float]], 223 | ): 224 | self._update_process = value 225 | 226 | @property 227 | def first_step(self) -> Callable[[int, int, float, float], Render]: 228 | """wiki: https://github.com/DRincs-Productions/Renpygame/wiki/Minigame-with-a-render-loop#first_step-and-update_process""" 229 | return self._first_step 230 | 231 | @first_step.setter 232 | def first_step(self, value: Callable[[int, int, float, float], Render]): 233 | self._first_step = value 234 | 235 | @property 236 | def event_lambda(self) -> Optional[Callable[[Any, int, int, float], Any]]: 237 | """wiki: https://github.com/DRincs-Productions/Renpygame/wiki/Minigame-with-a-render-loop#event-handling""" 238 | return self._event_lambda 239 | 240 | @event_lambda.setter 241 | def event_lambda(self, value: Optional[Callable[[Any, int, int, float], Any]]): 242 | self._event_lambda = value 243 | 244 | @property 245 | def is_game_end(self) -> bool: 246 | return self._is_game_end 247 | 248 | @is_game_end.setter 249 | def is_game_end(self, value: bool): 250 | self._is_game_end = value 251 | 252 | @property 253 | def is_game_end_menu(self) -> bool: 254 | return self._is_game_end_menu 255 | 256 | @is_game_end_menu.setter 257 | def is_game_end_menu(self, value: bool): 258 | self._is_game_end_menu = value 259 | 260 | @property 261 | def end_game_frame( 262 | self, 263 | ) -> Optional[Callable[[Render, float, float, float, int], None]]: 264 | """wiki:""" 265 | return self._end_game_frame 266 | 267 | @end_game_frame.setter 268 | def end_game_frame( 269 | self, 270 | value: Optional[Callable[[Render, float, float, float, int], None]], 271 | ): 272 | self._end_game_frame = value 273 | 274 | @property 275 | def is_full_redraw_lamda( 276 | self, 277 | ) -> Optional[Callable[[int], bool]]: 278 | return self._is_full_redraw_lamda 279 | 280 | @is_full_redraw_lamda.setter 281 | def is_full_redraw_lamda( 282 | self, 283 | value: Optional[Callable[[int], bool]], 284 | ): 285 | self._is_full_redraw_lamda = value 286 | 287 | def _is_full_redraw(self, current_frame_number: int) -> bool: 288 | if self.is_full_redraw_lamda: 289 | return self.is_full_redraw_lamda(current_frame_number) 290 | return current_frame_number % 2 == 0 291 | 292 | def show(self, show_and_start: bool = True): 293 | """wiki: https://github.com/DRincs-Productions/Renpygame/wiki/Minigame-with-a-render-loop#start-a-game-between-a-sterted-menu""" 294 | print("Renpy Game Show") 295 | if show_and_start: 296 | self.start() 297 | renpy.call_screen("renpygame_surface", surface=self) 298 | return 299 | 300 | def start(self): 301 | """wiki: https://github.com/DRincs-Productions/Renpygame/wiki/Minigame-with-a-render-loop#start-a-game-between-a-sterted-menu""" 302 | if not self.is_started: 303 | print("Renpy Game Start") 304 | self.is_started = True 305 | self.delay = self.start_delay 306 | pygame.time.set_timer(PYGAMEEVENT, int(self.delay * 1000)) 307 | # self._start_redraw_timer() 308 | else: 309 | print("Renpy Game Already Started") 310 | return 311 | 312 | def reset_game(self): 313 | print("Renpy Game Reset") 314 | self.delay = self.start_delay 315 | self.child_render = None 316 | 317 | def game_end(self): 318 | print("Renpy Game End") 319 | if self.end_game_frame is not None: 320 | self.is_game_end_menu = True 321 | renpy.redraw(self, 0) 322 | else: 323 | self.quit() 324 | return 325 | 326 | def quit(self): 327 | self.is_game_end = True 328 | 329 | def _render_update(self, st: float, check_game_end: bool = True): 330 | if self.is_game_end_menu: 331 | if self.end_game_frame is not None: 332 | self.end_game_frame( 333 | self.child_render, 0, 0, self.start_delay, self.current_frame_number 334 | ) 335 | else: 336 | print("Error: end_game_frame is None") 337 | self.quit() 338 | elif check_game_end and self.delay is None: 339 | self.game_end() 340 | else: 341 | self.current_frame_number += 1 342 | # * first round and subsequent rounds 343 | self.child_render.renpygame_canvas = None # force to update the canvas 344 | self.delay = self.update_process( 345 | self.child_render, 346 | st, 347 | self.delay, 348 | self.current_frame_number, 349 | ) 350 | 351 | if self.current_frame_number % 3600 == 0: 352 | free_memory() 353 | 354 | def render(self, width: int, height: int, st: float, at: float) -> renpy.Render: 355 | if self.child_render is None: # * first round 356 | self.child_render = self.first_step(width, height, st, at) 357 | self.child_render.renpygame_canvas = None # force to update the canvas 358 | self.current_frame_number = 0 359 | else: # * first round and subsequent rounds 360 | self._render_update(st) 361 | return self.result_render(self.child_render, width, height) 362 | 363 | def result_render(self, render: renpy.Render, width: int, height: int): 364 | return main_render(render, width, height) 365 | 366 | def event(self, ev: EventType, x: int, y: int, st: float): 367 | """pygame_sdl2: https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/event.pyx 368 | config.keymap: https://www.renpy.org/doc/html/config.html#var-config.keymap 369 | add a event: https://www.renpy.org/doc/html/other.html#renpy.queue_event 370 | """ 371 | if self.is_game_end: 372 | renpy.free_memory() 373 | pygame.time.set_timer(PYGAMEEVENT, 0) 374 | return 0 375 | 376 | if hasattr(ev.dict, "key"): 377 | ev.key = None 378 | 379 | # if pygame.WINDOWEVENT == ev.type: 380 | # self._start_redraw_timer(check_game_end=False) 381 | if 32768 == ev.type: # 32768 is the event type for pause menu 382 | self.reset_game() 383 | if PYGAMEEVENT == ev.type: 384 | if self.delay is None: 385 | pygame.time.set_timer(PYGAMEEVENT, 0) 386 | elif self.last_delay is None or self.delay != self.last_delay: 387 | self.last_delay = self.delay 388 | pygame.time.set_timer(PYGAMEEVENT, int(self.delay * 1000)) 389 | if self.child_render is None: 390 | renpy.redraw(self, 0) 391 | else: 392 | if self._is_full_redraw(self.current_frame_number): 393 | renpy.redraw(self, 0) 394 | else: 395 | self._render_update(st) 396 | return 397 | if self.event_lambda is not None: 398 | return self.event_lambda(ev, x, y, st) 399 | 400 | 401 | class RenpyGameByLoop(RenpyGameByTimer): 402 | """ 403 | inspired by: https://github.com/renpy/renpy/blob/master/renpy/display/layout.py#L1503 404 | """ 405 | 406 | def __init__( 407 | self, 408 | first_step: Callable[[int, int, float, float], Render], 409 | update_process: Callable[ 410 | [Render, float, Optional[float], int], Optional[float] 411 | ], 412 | event_lambda: Optional[Callable[[EventType, int, int, float], Any]] = None, 413 | delay: float = 0.05, 414 | end_game_frame: Optional[ 415 | Callable[[Render, float, float, float, int], None] 416 | ] = None, 417 | **kwargs, 418 | ): 419 | super().__init__( 420 | first_step=first_step, 421 | update_process=update_process, 422 | event_lambda=event_lambda, 423 | delay=delay, 424 | end_game_frame=end_game_frame, 425 | **kwargs, 426 | ) 427 | 428 | def start(self): 429 | """wiki: https://github.com/DRincs-Productions/Renpygame/wiki/Minigame-with-a-render-loop#start-a-game-between-a-sterted-menu""" 430 | if not self.is_started: 431 | print("Renpy Game Start") 432 | self.is_started = True 433 | self.delay = self.start_delay 434 | renpy.redraw(self, 0) 435 | else: 436 | print("Renpy Game Already Started") 437 | return 438 | 439 | def render(self, width: int, height: int, st: float, at: float) -> renpy.Render: 440 | """this function will be started in the form of a loop. 441 | through start_redraw_timer, I trigger the event direnpy.redraw to create the loop. 442 | 443 | inspired by: https://github.com/renpy/renpy/blob/master/renpy/display/layout.py#L1534 444 | """ 445 | 446 | # * start the timer immediately at the beginning of the function. so that update_process does not affect the fps. 447 | # * I don't know if this is a good idea because if update_process time > delay, the game will be looped or the game skip a frame. 448 | if self.delay: 449 | renpy.redraw(self, self.delay) 450 | 451 | return super().render(width, height, st, at) 452 | 453 | 454 | class RenpyGameByTimerForDraw(RenpyGameByTimer): 455 | def __init__( 456 | self, 457 | update_process: Callable[ 458 | [Render, float, Optional[float], int], Optional[float] 459 | ], 460 | event_lambda: Optional[Callable[[EventType, int, int, float], Any]] = None, 461 | delay: float = 0.5, 462 | **kwargs, 463 | ): 464 | first_step = lambda width, height, st, at: self._first_step_for_draw( 465 | width, height 466 | ) 467 | 468 | # RenpyGameByTimer init 469 | super().__init__( 470 | first_step=first_step, 471 | update_process=update_process, 472 | event_lambda=event_lambda, 473 | delay=delay, 474 | **kwargs, 475 | ) 476 | 477 | def _first_step_for_draw(self, width: int, height: int): 478 | renpy_render = renpy.Render(width, height) 479 | pygame_render = Render(width, height) 480 | pygame_render.internal_render = renpy_render 481 | return pygame_render 482 | 483 | def result_render(self, render: Render, width: int, height: int): 484 | return render.internal_render 485 | 486 | def _is_full_redraw(self, current_frame_number: int) -> bool: 487 | return False 488 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/renpygameCanvas.py: -------------------------------------------------------------------------------- 1 | import renpy.exports as renpy 2 | 3 | 4 | class Canvas(renpy.display.render.Canvas): 5 | """https://github.com/renpy/renpy/blob/master/renpy/display/render.pyx#L1610""" 6 | 7 | def __init__(self, surf): 8 | # renpy.display.Canvas init 9 | super().__init__(surf) 10 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/renpygameRender.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | import renpy.exports as renpy 3 | 4 | from pythonpackages.renpygame.renpygameCanvas import Canvas 5 | 6 | 7 | class Render(renpy.Render): 8 | """https://github.com/renpy/renpy/blob/master/renpy/display/render.pyx#L586 9 | # TODO there is a problem a problem with self.width and self.height. They are a float and must be an int. 10 | """ 11 | 12 | def __init__( 13 | self, 14 | width: int, 15 | height: int, 16 | ): 17 | # renpy.Render init 18 | super().__init__(width, height) 19 | # * Render properties, will come set in super().__init__ 20 | 21 | self.internal_render = None 22 | self.background_render = None 23 | self._renpygame_canvas = None 24 | 25 | @property 26 | def mark(self): 27 | return super().mark 28 | 29 | @property 30 | def cache_killed(self): 31 | return super().cache_killed 32 | 33 | @property 34 | def killed(self): 35 | return super().killed 36 | 37 | @property 38 | def width(self) -> int: 39 | """must be int""" 40 | return int(super().width) 41 | 42 | @width.setter 43 | def width(self, value: int): 44 | """must be int. 45 | # TODO there is a problem a problem with self.width and self.height. They are a float and must be an int. 46 | """ 47 | super().width = int(value) 48 | 49 | @property 50 | def height(self) -> int: 51 | """must be int""" 52 | return int(super().height) 53 | 54 | @height.setter 55 | def height(self, value: int): 56 | """must be int. 57 | # TODO there is a problem a problem with self.width and self.height. They are a float and must be an int. 58 | """ 59 | super().height = int(value) 60 | print("height set to", value) 61 | 62 | @property 63 | def layer_name(self): 64 | return super().layer_name 65 | 66 | @property 67 | def children(self): 68 | return super().children 69 | 70 | @property 71 | def forward(self): 72 | return super().forward 73 | 74 | @property 75 | def reverse(self): 76 | return super().reverse 77 | 78 | @property 79 | def alpha(self): 80 | return super().alpha 81 | 82 | @property 83 | def over(self): 84 | return super().over 85 | 86 | @property 87 | def nearest(self): 88 | return super().nearest 89 | 90 | @property 91 | def focuses(self): 92 | return super().focuses 93 | 94 | @property 95 | def pass_focuses(self): 96 | return super().pass_focuses 97 | 98 | @property 99 | def focus_screen(self): 100 | return super().focus_screen 101 | 102 | @property 103 | def render_of(self): 104 | return super().render_of 105 | 106 | @property 107 | def xclipping(self): 108 | return super().xclipping 109 | 110 | @property 111 | def yclipping(self): 112 | return super().yclipping 113 | 114 | @property 115 | def modal(self): 116 | return super().modal 117 | 118 | @property 119 | def text_input(self): 120 | return super().text_input 121 | 122 | @property 123 | def parents(self): 124 | return super().parents 125 | 126 | @property 127 | def depends_on_list(self): 128 | return super().depends_on_list 129 | 130 | @property 131 | def operation(self): 132 | return super().operation 133 | 134 | @property 135 | def operation_complete(self): 136 | return super().operation_complete 137 | 138 | @property 139 | def operation_alpha(self): 140 | return super().operation_alpha 141 | 142 | @property 143 | def operation_parameter(self): 144 | return super().operation_parameter 145 | 146 | @property 147 | def surface(self): 148 | return super().surface 149 | 150 | @property 151 | def alpha_surface(self): 152 | return super().alpha_surface 153 | 154 | @property 155 | def half_cache(self): 156 | return super().half_cache 157 | 158 | @property 159 | def mesh(self): 160 | return super().mesh 161 | 162 | @property 163 | def shaders(self): 164 | return super().shaders 165 | 166 | @property 167 | def uniforms(self): 168 | return super().uniforms 169 | 170 | @property 171 | def properties(self): 172 | return super().properties 173 | 174 | @property 175 | def cached_texture(self): 176 | return super().cached_texture 177 | 178 | @property 179 | def cached_model(self): 180 | return super().cached_model 181 | 182 | @property 183 | def loaded(self): 184 | return super().loaded 185 | 186 | def blit( 187 | self, source, pos: tuple[int, int], focus=True, main=True, index=None 188 | ) -> int: 189 | """render.blit(): https://github.com/renpy/renpy/blob/master/renpy/display/render.pyx#L778""" 190 | if hasattr(source, "background_render") and source.background_render: 191 | surffill = renpy.render( 192 | source.background_render, source.width, source.height, 0, 0 193 | ) 194 | super().blit(surffill, pos, focus, main, index) 195 | if hasattr(source, "internal_render") and source.internal_render: 196 | source = source.internal_render 197 | return super().blit(source, pos, focus, main, index) 198 | 199 | def subpixel_blit( 200 | self, source, pos: tuple[int, int], focus=True, main=True, index=None 201 | ) -> int: 202 | return super().subpixel_blit(source, pos, focus, main, index) 203 | 204 | def absolute_blit( 205 | self, source, pos: tuple[int, int], focus=True, main=True, index=None 206 | ) -> int: 207 | return super().absolute_blit(source, pos, focus, main, index) 208 | 209 | def get_size(self) -> tuple[int, int]: 210 | return super().get_size() 211 | 212 | def render_to_texture(self, alpha=True): 213 | return super().render_to_texture(alpha) 214 | 215 | def subsurface(self, rect, focus=False): 216 | return super().subsurface(rect, focus) 217 | 218 | def depends_on(self, source, focus=False): 219 | return super().depends_on(source, focus) 220 | 221 | def kill_cache(self): 222 | return super().kill_cache() 223 | 224 | def kill(self): 225 | return super().kill() 226 | 227 | def add_focus( 228 | self, d, arg=None, x=0, y=0, w=None, h=None, mx=None, my=None, mask=None 229 | ): 230 | return super().add_focus(d, arg, x, y, w, h, mx, my, mask) 231 | 232 | def take_focuses(self, cminx, cminy, cmaxx, cmaxy, transform, screen, focuses): 233 | return super().take_focuses( 234 | cminx, cminy, cmaxx, cmaxy, transform, screen, focuses 235 | ) 236 | 237 | def focus_at_point(self, x, y, screen): 238 | return super().focus_at_point(x, y, screen) 239 | 240 | def main_displayables_at_point(self, x, y, layers, depth=None): 241 | return super().main_displayables_at_point(x, y, layers, depth) 242 | 243 | def is_pixel_opaque(self, x, y): 244 | return super().is_pixel_opaque(x, y) 245 | 246 | def fill(self, color): 247 | """https://github.com/renpy/renpy/blob/master/renpy/display/render.pyx#L1469 248 | # TODO there is a problem a problem with self.width and self.height. They are a float and must be an int. so I have overriden this method 249 | """ 250 | color = renpy.easy.color(color) 251 | # TODO use a self.background_render si not correct, because the color must blit over the current render and under the current render 252 | self.background_render = renpy.display.imagelike.Solid(color) 253 | # self.blit(surf, (0, 0), focus=False, main=False) 254 | 255 | if self.internal_render: 256 | self.internal_render.fill(color) 257 | 258 | # update the canvas 259 | if self.renpygame_canvas: 260 | self.renpygame_canvas = None 261 | _ = self.renpygame_canvas 262 | return 263 | 264 | def canvas(self) -> Canvas: 265 | """https://github.com/renpy/renpy/blob/master/renpy/display/render.pyx#L1480 266 | # TODO there is a problem a problem with self.width and self.height. They are a float and must be an int. so I have overriden this method 267 | """ 268 | surf = renpy.display.pgrender.surface((self.width, self.height), True) 269 | renpy.display.draw.mutated_surface(surf) 270 | self.blit(surf, (0, 0)) 271 | canvas = renpy.display.render.Canvas(surf) 272 | return canvas 273 | 274 | def screen_rect(self, sx: float, sy: float, transform: list[list[int]]): 275 | return super().screen_rect(sx, sy, transform) 276 | 277 | def place( 278 | self, 279 | d, 280 | x=0, 281 | y=0, 282 | width=None, 283 | height=None, 284 | st=None, 285 | at=None, 286 | render=None, 287 | main=True, 288 | ): 289 | return super().place(d, x, y, width, height, st, at, render, main) 290 | 291 | def zoom(self, xzoom, yzoom): 292 | return super().zoom(xzoom, yzoom) 293 | 294 | def add_shader(self, shader): 295 | return super().add_shader(shader) 296 | 297 | def add_uniform(self, name, value): 298 | return super().add_uniform(name, value) 299 | 300 | def add_property(self, name, value): 301 | return super().add_property(name, value) 302 | 303 | # my methods 304 | 305 | @property 306 | def internal_render(self) -> renpy.Render: 307 | """if set will be used during blit() instead of using the parent class. 308 | This is used for conversions and is useful to prevent errors. 309 | and because if you use a r = renpy.render() and then self.blit(r) it will not work -> when you blit the self(render) into main render it will not work 310 | # TODO: instead of using this variable during the conversion, one could set all the variables to the old element in the new 311 | """ 312 | return self._internal_render 313 | 314 | @internal_render.setter 315 | def internal_render(self, value: renpy.Render): 316 | self._internal_render = value 317 | 318 | @property 319 | def background_render(self) -> renpy.display.imagelike.Solid: 320 | """if set will be used as the background render when the parent render blit it. 321 | This is used for conversions and is useful to prevent errors. 322 | and because if you use a r = renpy.render() and then self.blit(r) it will not work -> when you blit the self(render) into main render it will not work 323 | # TODO: instead of using this variable during the conversion, one could set all the variables to the old element in the new 324 | """ 325 | return self._background_render 326 | 327 | @background_render.setter 328 | def background_render(self, value: renpy.display.imagelike.Solid): 329 | self._background_render = value 330 | 331 | @property 332 | def renpygame_canvas(self) -> Canvas: 333 | if self._renpygame_canvas is None: 334 | if self.internal_render is None: 335 | self._renpygame_canvas = self.canvas() 336 | else: 337 | self._renpygame_canvas = self.internal_render.canvas() 338 | return self._renpygame_canvas 339 | 340 | @renpygame_canvas.setter 341 | def renpygame_canvas(self, value: Optional[Canvas]): 342 | self._renpygame_canvas = value 343 | 344 | def get_width(self) -> int: 345 | width, _ = self.get_size() 346 | return int(width) 347 | 348 | def get_height(self) -> int: 349 | _, height = self.get_size() 350 | return int(height) 351 | 352 | def import_renpy_render(self, renpy_render: renpy.Render): 353 | self = renpy_render 354 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/sprite.py: -------------------------------------------------------------------------------- 1 | import renpy.exports as renpy 2 | 3 | import pythonpackages.renpygame_pygame as pygame 4 | from pythonpackages.renpygame.display import Surface 5 | from pythonpackages.renpygame.rect import Rect 6 | from pythonpackages.renpygame_pygame.sprite import * 7 | 8 | 9 | class Sprite(pygame.sprite.Sprite): 10 | """pygame: https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Sprite 11 | pygame_sdl2: https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/sprite.py#L106 12 | """ 13 | 14 | def __init__(self, *groups, **kwargs): 15 | # Sprite init 16 | super().__init__(*groups, **kwargs) 17 | 18 | def add(self, *groups): 19 | return super().add(*groups) 20 | 21 | def remove(self, *groups): 22 | return super().remove(*groups) 23 | 24 | def add_internal(self, group): 25 | return super().add_internal(group) 26 | 27 | def remove_internal(self, group): 28 | return super().remove_internal(group) 29 | 30 | def update(self, *args): 31 | return super().update(*args) 32 | 33 | def kill(self): 34 | return super().kill() 35 | 36 | def groups(self) -> list[AbstractGroup]: 37 | return super().groups() 38 | 39 | def alive(self) -> bool: 40 | return super().alive() 41 | 42 | 43 | class AbstractGroup(pygame.sprite.AbstractGroup): 44 | """pygame: https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/sprite.py#L284 45 | pygame_sdl2:""" 46 | 47 | def AbstractGroup(self): 48 | # Sprite init 49 | super().__init__() 50 | 51 | def sprites(self) -> list[Sprite]: 52 | return super().sprites() 53 | 54 | def add_internal(self, sprite): 55 | return super().add_internal(sprite) 56 | 57 | def remove_internal(self, sprite): 58 | return super().remove_internal(sprite) 59 | 60 | def has_internal(self, sprite) -> bool: 61 | return super().has_internal(sprite) 62 | 63 | def copy(self) -> pygame.sprite.AbstractGroup: 64 | return super().copy() 65 | 66 | def add(self, *sprites): 67 | return super().add(*sprites) 68 | 69 | def remove(self, *sprites): 70 | return super().remove(*sprites) 71 | 72 | def has(self, *sprites) -> bool: 73 | return super().has(*sprites) 74 | 75 | def update(self, *args): 76 | return super().update(*args) 77 | 78 | def draw(self, surface): 79 | return super().draw(surface) 80 | 81 | def clear(self, surface: Surface, bgd): 82 | # * Is commented for improved performance 83 | # return super().clear(surface, bgd) 84 | surface.blit(bgd, (0, 0)) 85 | return 86 | 87 | def empty(self): 88 | return super().empty() 89 | 90 | 91 | class Group(pygame.sprite.Group): 92 | """pygame: 93 | pygame_sdl2: https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/sprite.py#L531 94 | """ 95 | 96 | def __init__(self, *sprites): 97 | super().__init__(*sprites) 98 | 99 | def clear(self, surface: Surface, bgd): 100 | return AbstractGroup.clear(self, surface, bgd) 101 | 102 | 103 | class RenderUpdates(pygame.sprite.RenderUpdates): 104 | """pygame: https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.RenderUpdates 105 | pygame_sdl2: https://github.com/renpy/pygame_sdl2/blob/master/src/pygame_sdl2/sprite.py#L557 106 | """ 107 | 108 | def draw(self, surface: Surface) -> list[Rect]: 109 | return super().draw(surface) 110 | 111 | def clear(self, surface: Surface, bgd): 112 | return AbstractGroup.clear(self, surface, bgd) 113 | -------------------------------------------------------------------------------- /pythonpackages/renpygame/transform.py: -------------------------------------------------------------------------------- 1 | from typing import Union 2 | 3 | import renpy.exports as renpy 4 | 5 | from pythonpackages.renpygame_pygame.transform import * 6 | from pythonpackages.renpygame.display import Surface 7 | from pythonpackages.renpygame.image import ( 8 | Flip, 9 | Grayscale, 10 | Image, 11 | Rotozoom, 12 | Scale, 13 | ) 14 | 15 | # https://www.renpy.org/doc/html/displayables.html 16 | 17 | 18 | def print_error(surface, log_text) -> None: 19 | if isinstance(surface, Surface): 20 | print( 21 | f"{log_text}: You have passed a Surface, not an Image. probably you have to use Image.convert() first" 22 | ) 23 | else: 24 | print( 25 | f"{log_text}: You have passed an invalid type: {type(surface)} or not implemented yet" 26 | ) 27 | return 28 | 29 | 30 | def flip(surface: Image, flip_x: Union[int, bool], flip_y: Union[int, bool]) -> Image: 31 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.flip""" 32 | if isinstance(flip_x, int): 33 | flip_x = flip_x != 0 34 | if isinstance(flip_y, int): 35 | flip_y = flip_y != 0 36 | if isinstance(surface, Image): 37 | surface = Flip(surface, flip_x, flip_y) 38 | else: 39 | print_error(surface, "renpygame.transform.flip") 40 | return surface 41 | 42 | 43 | def scale(surface: Image, size: tuple[int, int], dest_surface=None) -> Image: 44 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.scale""" 45 | if isinstance(surface, Image): 46 | surface = Scale(surface, size[0], size[1]) 47 | else: 48 | print_error(surface, "renpygame.transform.scale") 49 | return surface 50 | 51 | 52 | def scale_by(surface, factor, dest_surface=None) -> Surface: 53 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.scale_by""" 54 | print("renpygame.transform.scale_by: not implemented yet") 55 | # TODO: implement 56 | return surface 57 | 58 | 59 | def rotate(surface: Image, angle: int) -> Image: 60 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.rotate""" 61 | if isinstance(surface, Image): 62 | surface.rotate = angle 63 | else: 64 | print_error(surface, "renpygame.transform.rotate") 65 | return surface 66 | 67 | 68 | def rotozoom(surface, angle, scale) -> Surface: 69 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.rotozoom""" 70 | if isinstance(surface, Image): 71 | surface = Rotozoom(surface, angle, scale) 72 | else: 73 | print_error(surface, "renpygame.transform.rotozoom") 74 | return surface 75 | 76 | 77 | def scale2x(surface, dest_surface=None) -> Surface: 78 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.scale2x""" 79 | print("renpygame.transform.scale2x: not implemented yet") 80 | # TODO: implement 81 | return surface 82 | 83 | 84 | def ssmoothscale(surface, size, dest_surface=None) -> Surface: 85 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.smoothscale""" 86 | print("renpygame.transform.smoothscale: not implemented yet") 87 | # TODO: implement 88 | return surface 89 | 90 | 91 | def smoothscale_by(surface, factor, dest_surface=None) -> Surface: 92 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.smoothscale""" 93 | print("renpygame.transform.smoothscale_by: not implemented yet") 94 | # TODO: implement 95 | return surface 96 | 97 | 98 | def chop(surface, rect) -> Surface: 99 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.chop""" 100 | print("renpygame.transform.chop: not implemented yet") 101 | # TODO: implement 102 | return surface 103 | 104 | 105 | def laplacian(surface, dest_surface=None) -> Surface: 106 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.laplacian""" 107 | print("renpygame.transform.laplacian: not implemented yet") 108 | # TODO: implement 109 | return surface 110 | 111 | 112 | def average_surfaces(surfaces, dest_surface=None, palette_colors=1) -> Surface: 113 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.average_surfaces""" 114 | print("renpygame.transform.average_surfaces: not implemented yet") 115 | # TODO: implement 116 | return surfaces 117 | 118 | 119 | def grayscale(surface, dest_surface=None) -> Image: 120 | """pygame: https://www.pygame.org/docs/ref/transform.html#pygame.transform.grayscale 121 | renpy: https://github.com/renpy/renpy/blob/master/renpy/display/im.py#L1792""" 122 | if isinstance(surface, Image): 123 | surface = Grayscale(surface) 124 | else: 125 | print_error(surface, "renpygame.transform.grayscale") 126 | return surface 127 | -------------------------------------------------------------------------------- /pythonpackages/renpygame_pygame/__init__.py: -------------------------------------------------------------------------------- 1 | # * This library is used to link renpygame to a pygame library (Now pygame_sdl2, but it can be changed to pygame) 2 | 3 | from pygame_sdl2 import * 4 | 5 | import pythonpackages.renpygame_pygame.display as pygame_display 6 | import pythonpackages.renpygame_pygame.event as pygame_event 7 | import pythonpackages.renpygame_pygame.image as pygame_image 8 | import pythonpackages.renpygame_pygame.rect as pygame_rect 9 | import pythonpackages.renpygame_pygame.sprite as pygame_sprite 10 | import pythonpackages.renpygame_pygame.transform as pygame_transform 11 | import pythonpackages.renpygame_pygame.draw as pygame_draw 12 | 13 | rect = pygame_rect 14 | display = pygame_display 15 | sprite = pygame_sprite 16 | image = pygame_image 17 | transform = pygame_transform 18 | event = pygame_event 19 | draw = pygame_draw 20 | -------------------------------------------------------------------------------- /pythonpackages/renpygame_pygame/display.py: -------------------------------------------------------------------------------- 1 | from pygame_sdl2.display import * 2 | -------------------------------------------------------------------------------- /pythonpackages/renpygame_pygame/draw.py: -------------------------------------------------------------------------------- 1 | from pygame_sdl2.draw import * 2 | -------------------------------------------------------------------------------- /pythonpackages/renpygame_pygame/event.py: -------------------------------------------------------------------------------- 1 | from pygame_sdl2.event import * 2 | -------------------------------------------------------------------------------- /pythonpackages/renpygame_pygame/image.py: -------------------------------------------------------------------------------- 1 | from pygame_sdl2.image import * 2 | -------------------------------------------------------------------------------- /pythonpackages/renpygame_pygame/rect.py: -------------------------------------------------------------------------------- 1 | from pygame_sdl2.rect import * 2 | -------------------------------------------------------------------------------- /pythonpackages/renpygame_pygame/sprite.py: -------------------------------------------------------------------------------- 1 | from pygame_sdl2.sprite import * 2 | -------------------------------------------------------------------------------- /pythonpackages/renpygame_pygame/transform.py: -------------------------------------------------------------------------------- 1 | from pygame_sdl2.transform import * 2 | -------------------------------------------------------------------------------- /translation_convertor_potorpy.py: -------------------------------------------------------------------------------- 1 | from fileinput import FileInput 2 | from glob import glob 3 | import os 4 | import shutil 5 | import re 6 | 7 | # ATTENTION: there must not be 2 equal key or value 8 | # regex: https://www.w3schools.com/python/python_regex.asp 9 | dict = { 10 | # search_text : replace_text 11 | # start 12 | r'\n"Plural-Forms(.*)': r'', 13 | r'\n"X-Crowdin-Pr(.*)': r'', 14 | r'\n"X-Crowdin-Pr(.*)': r'', 15 | r'\n"X-Crowdin-La(.*)': r'', 16 | r'\n"X-Crowdin-Fi(.*)': r'', 17 | r'\n"X-Crowdin-Fi(.*)': r'', 18 | r'\n"Project-Id-V(.*)': r'', 19 | r'\n"Content-Type(.*)': r'', 20 | r'\n"Language-Tea(.*)': r'', 21 | r'\n"Language:(.*)': r'', 22 | r'\n"PO-Revision-(.*)': r'', 23 | r'\n"Большой(.*)': r'', 24 | r'msgid ""\nmsgstr ""': r'', 25 | r'\\n"\n"': r'\\n', 26 | r'\\'+'"': r'§§§§§§§§', 27 | # Effect 28 | r' \[nointeract\]"': r'" nointeract', 29 | r' \[withfade\]"': r'" with fade', 30 | r' \[withdissolve\]"': r'" with dissolve', 31 | r' \[withslowdissolve\]"': r'" with slowdissolve', 32 | r' \[withhpunch\]"': r'" with hpunch', 33 | r' \[withflash\]"': r'" with flash', 34 | r' \[withvpunch\]"': r'" with vpunch', 35 | r' \[withDissolve20\]"': r'" with Dissolve(2.0)', 36 | r' \[withDissolve1\]"': r'" with Dissolve(1)', 37 | r' \[withDissolvey3\]"': r'" with Dissolve(.3)', 38 | r' \[multiple2\]"': r'" (multiple=2)', 39 | r'msgid "\[nvl_clear\]"': r' # nvl clear', 40 | r'msgstr "\[nvl_clear\]"': r' nvl clear', 41 | # first 42 | r'msgid "(.*?) \[special_delimiter\] (.*?)"': r' # "\1" "\2"', 43 | r'msgstr "(.*?) \[special_delimiter\] (.*?)"': r' "\1" "\2"', 44 | r':\nmsgid "(.*?)"': r':\n # "\1"', 45 | r' #(.*?)\nmsgstr "\[_(.*?)\_] (.*?)"': r' #\1\n \2 "\3"', 46 | r' # (.*?)\nmsgstr "(.*?)"': r' # \1\n "\2"', 47 | # after 48 | r' # "\[_(.*?)\_] (.*?)"': r' # \1 "\2"', 49 | # Comment 50 | r':\n # ': r':\n\n # ', 51 | r'rpy:(.*?) #-#-# translate': r'rpy:\1\ntranslate', 52 | r'strings: #\|#\|# # ': r'strings:\n\n# ', 53 | r'updated at (.*?)-(.*?)-(.*?) (.*?):(.*?) #\|#\|# # ': r'updated at \1-\2-\3 \4:\5\n\n# ', 54 | # end 55 | r'msgid "(.*?)"': r' old "\1"', 56 | r'msgstr "(.*?)"': r' new "\1"', 57 | r'\n#(.*?)\n old "': r'\n #\1\n old "', 58 | r'\n\n# TODO: Translation updated': r'# TODO: Translation updated', 59 | r'§§§§§§§§': r'\\'+'"', 60 | r'# TODO: Translation updated at (.*?)-(.*?)-(.*?) (.*?):(.*?) #\|#\|# # §translate ': r'# TODO: Translation updated at \1-\2-\3 \4:\5\n\ntranslate ', 61 | r'\n# §translate': r'\ntranslate', 62 | } 63 | 64 | 65 | # Creating a function to replace the text 66 | def replacetext(search_text, replace_text, pathFile, languege): 67 | 68 | # Read in the file 69 | with open(pathFile, "r+", encoding="utf8") as file: 70 | filedata = file.read() 71 | 72 | # c = re.compile(search_text) 73 | 74 | # Replace the target string 75 | # filedata = filedata.replace(search_text, replace_text) 76 | filedata = re.sub(search_text, replace_text, filedata) 77 | # TODO: to improve 78 | filedata = re.sub(r'"\n (.*?)_s_(.*?) "', 79 | r'"\n \1 \2 "', filedata) 80 | filedata = re.sub(r'"\n (.*?)_s_(.*?) "', 81 | r'"\n \1 \2 "', filedata) 82 | filedata = re.sub(r'"\n (.*?)_s_(.*?) "', 83 | r'"\n \1 \2 "', filedata) 84 | filedata = re.sub(r'"\n (.*?)_s_(.*?) "', 85 | r'"\n \1 \2 "', filedata) 86 | filedata = re.sub(r'"\n (.*?)_s_(.*?) "', 87 | r'"\n \1 \2 "', filedata) 88 | filedata = re.sub(r'"\n (.*?)_s_(.*?) "', 89 | r'"\n \1 \2 "', filedata) 90 | filedata = re.sub(r'"\n (.*?)_s_(.*?) "', 91 | r'"\n \1 \2 "', filedata) 92 | filedata = re.sub(r'"\n (.*?)_s_(.*?) "', 93 | r'"\n \1 \2 "', filedata) 94 | filedata = re.sub(r':\n\n # (.*?)_s_(.*?) "', 95 | r':\n\n # \1 \2 "', filedata) 96 | filedata = re.sub(r':\n\n # (.*?)_s_(.*?) "', 97 | r':\n\n # \1 \2 "', filedata) 98 | filedata = re.sub(r':\n\n # (.*?)_s_(.*?) "', 99 | r':\n\n # \1 \2 "', filedata) 100 | filedata = re.sub(r':\n\n # (.*?)_s_(.*?) "', 101 | r':\n\n # \1 \2 "', filedata) 102 | filedata = re.sub(r':\n\n # (.*?)_s_(.*?) "', 103 | r':\n\n # \1 \2 "', filedata) 104 | filedata = re.sub(r':\n\n # (.*?)_s_(.*?) "', 105 | r':\n\n # \1 \2 "', filedata) 106 | filedata = re.sub(r':\n\n # (.*?)_s_(.*?) "', 107 | r':\n\n # \1 \2 "', filedata) 108 | filedata = re.sub(r':\n\n # (.*?)_s_(.*?) "', 109 | r':\n\n # \1 \2 "', filedata) 110 | filedata = re.sub(r'crowdin', languege, filedata) 111 | 112 | # Write the file out again 113 | with open(pathFile, 'w', encoding="utf8") as file: 114 | file.write(filedata) 115 | return True 116 | 117 | 118 | def replaceDictionary(pathFile, dict={}, languege="crowdin"): 119 | newpathFile = fileRename(pathFile, extension=".rpy") 120 | print(pathFile) 121 | for search_text in dict.keys(): 122 | replacetext(pathFile=newpathFile, search_text=search_text, 123 | replace_text=dict[search_text], languege=languege) 124 | 125 | 126 | def getListFiles(extension, languege="**"): 127 | # Get the list of all files and directories 128 | path = "game/tl/" 129 | dir_list = glob(path + languege+"/*"+extension, recursive=True) 130 | if languege != "**": 131 | dir_list = dir_list + \ 132 | glob(path + languege+"/**/*"+extension, recursive=True) 133 | return dir_list 134 | 135 | 136 | def potorpy(languege): 137 | for path in getListFiles(extension=".po", languege=languege): 138 | replaceDictionary(path, dict=dict, languege=languege) 139 | 140 | 141 | def fileRename(pathFile, extension): 142 | pre, ext = os.path.splitext(pathFile) 143 | shutil.copyfile(pathFile, pre + extension) 144 | return pre + extension 145 | 146 | 147 | potorpy("crowdin") 148 | -------------------------------------------------------------------------------- /translation_convertor_rpytopo.py: -------------------------------------------------------------------------------- 1 | from fileinput import FileInput 2 | from glob import glob 3 | import os 4 | import shutil 5 | import re 6 | 7 | # ATTENTION: there must not be 2 equal key or value 8 | # regex: https://www.w3schools.com/python/python_regex.asp 9 | dict = { 10 | # search_text : replace_text 11 | # start 12 | r'\\'+'"': r'§§§§§§§§', 13 | # Effect 14 | r'" nointeract': r' [nointeract]"', 15 | r'" with fade': r' [withfade]"', 16 | r'" with dissolve': r' [withdissolve]"', 17 | r'" with slowdissolve': r' [withslowdissolve]"', 18 | r'" with hpunch': r' [withhpunch]"', 19 | r'" with flash': r' [withflash]"', 20 | r'" with vpunch': r' [withvpunch]"', 21 | r'" with Dissolve\(2.0\)': r' [withDissolve20]"', 22 | r'" with Dissolve\(1\)': r' [withDissolve1]"', 23 | r'" with Dissolve\(.3\)': r' [withDissolvey3]"', 24 | r'" \(multiple=2\)': r' [multiple2]"', 25 | r' # nvl clear': r'msgid "[nvl_clear]"', 26 | r' nvl clear': r'msgstr "[nvl_clear]"', 27 | # first 28 | r' # "(.*?)" "(.*?)"': r'msgid "\1 [special_delimiter] \2"', 29 | r' "(.*?)" "(.*?)"': r'msgstr "\1 [special_delimiter] \2"', 30 | r' #': r'#', 31 | r' old "(.*?)"': r'msgid "\1"', 32 | r' new "(.*?)"': r'msgstr "\1"', 33 | # find: # (.*?) "(.*?)" 34 | # replace:msgid "[$1] $2" 35 | r'# (.*?) "(.*?)"': r'msgid "[_\1_] \2"', 36 | # after 37 | # find: (.*?) "(.*?)" 38 | # replace:msgstr "[$1] $2" 39 | r' (.*?) "(.*?)"': r'msgstr "[_\1_] \2"', 40 | r'# "(.*?)"': r'msgid "\1"', 41 | r' "(.*?)"': r'msgstr "\1"', 42 | # Comment 43 | r':\n\nmsgid': r':\nmsgid', 44 | r'rpy:(.*?)\ntranslate': r'rpy:\1 #-#-# translate', 45 | r'strings:\n\n# ': r'strings: #|#|# # ', 46 | r'\ntranslate': r'\n# §translate', 47 | r'updated at (.*?)-(.*?)-(.*?) (.*?):(.*?)\n\n# ': r'updated at \1-\2-\3 \4:\5 #|#|# # ', 48 | # end 49 | r'§§§§§§§§': r'\\'+'"', 50 | } 51 | 52 | 53 | # Creating a function to replace the text 54 | def replacetext(search_text, replace_text, pathFile): 55 | 56 | # Read in the file 57 | with open(pathFile, "r+", encoding="utf8") as file: 58 | filedata = file.read() 59 | 60 | # c = re.compile(search_text) 61 | 62 | # Replace the target string 63 | # filedata = filedata.replace(search_text, replace_text) 64 | filedata = re.sub(search_text, replace_text, filedata) 65 | # TODO: to improve 66 | filedata = re.sub(r'\[_(.*?)\b (.*?)_\]', r'[_\1_s_\2_]', filedata) 67 | filedata = re.sub(r'\[_(.*?)\b (.*?)_\]', r'[_\1_s_\2_]', filedata) 68 | filedata = re.sub(r'\[_(.*?)\b (.*?)_\]', r'[_\1_s_\2_]', filedata) 69 | filedata = re.sub(r'\[_(.*?)\b (.*?)_\]', r'[_\1_s_\2_]', filedata) 70 | filedata = re.sub(r'\[_(.*?)\b (.*?)_\]', r'[_\1_s_\2_]', filedata) 71 | filedata = re.sub(r'\[_(.*?)\b (.*?)_\]', r'[_\1_s_\2_]', filedata) 72 | filedata = re.sub(r'\[_(.*?)\b (.*?)_\]', r'[_\1_s_\2_]', filedata) 73 | filedata = re.sub(r'\[_(.*?)\b (.*?)_\]', r'[_\1_s_\2_]', filedata) 74 | 75 | # Write the file out again 76 | with open(pathFile, 'w', encoding="utf8") as file: 77 | file.write(filedata) 78 | return True 79 | 80 | 81 | def replaceDictionary(pathFile, dict={}, reverse=False): 82 | newpathFile = fileRename(pathFile, extension=".po") 83 | print(pathFile) 84 | if(reverse): 85 | for item in reversed(list(dict.items())): 86 | replacetext(pathFile=newpathFile, 87 | search_text=item[1], replace_text=item[0]) 88 | else: 89 | for search_text in dict.keys(): 90 | replacetext(pathFile=newpathFile, search_text=search_text, 91 | replace_text=dict[search_text]) 92 | 93 | 94 | def getListFiles(extension=".po"): 95 | # Get the list of all files and directories 96 | path = "game/tl/" 97 | dir_list = glob(path + "/**/*"+extension, recursive=True) 98 | return dir_list 99 | 100 | 101 | def rpytopo(): 102 | for path in getListFiles(extension=".rpy"): 103 | replaceDictionary(path, dict=dict) 104 | 105 | 106 | def potorpy(): 107 | for path in getListFiles(): 108 | replaceDictionary(path, dict=dict, reverse=True) 109 | 110 | 111 | def fileRename(pathFile, extension=".rpy"): 112 | pre, ext = os.path.splitext(pathFile) 113 | shutil.copyfile(pathFile, pre + extension) 114 | return pre + extension 115 | 116 | 117 | rpytopo() 118 | --------------------------------------------------------------------------------