├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ └── extensionTests.yml ├── .gitignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── azure-pipelines.yml ├── contributing.md ├── imgs ├── bitmapv.PNG ├── dockertag.png ├── envvariables.png ├── extraparams.png ├── genesiscodeconfigtoolchain.png ├── genesiscodeicon.png ├── genscodeicon.png ├── genscodesettings.png ├── makefile.png ├── sbarbuttons.png ├── statusbar.png └── vscodegif.gif ├── package.json ├── resources ├── Makefile.template ├── README.md.template ├── about.html ├── boot │ ├── rom_head.c.template │ └── sega.s.template ├── build.bat ├── ccppsettings.linuxgendev.template ├── ccppsettings.linuxmarsdev.template ├── ccppsettings.macossgdk.template ├── ccppsettings.windowsmarsdev.template ├── ccppsettings.windowssgdk.template ├── codecompletion.json ├── gitignore.template ├── gitkeep.template ├── headerfile.h.template ├── imageviewer.html ├── language-configuration.json ├── launch.json.linuxmarsdev.template ├── launch.json.macossgdk.template ├── launch.json.windowsmarsdev.template ├── launch.json.windowssgdk.template ├── mainc.template └── res_grammar.json ├── src ├── CoreEngine.ts ├── IAppModel.ts ├── IAppModelDarwin.ts ├── IAppModelLinux.ts ├── IAppModelWin32.ts ├── TmxParser.ts ├── appModel.ts ├── codeProvider.ts ├── constants.ts ├── extension.ts ├── imagePreviewProvider.ts └── test │ ├── runTest.ts │ └── suite │ ├── codeProvider.test.ts │ ├── ejemplo1.json │ ├── ejemplo1.tmx │ ├── extension.test.ts │ ├── index.ts │ └── tmxParser.test.ts ├── tsconfig.json ├── tslint.json └── vsc-extension-quickstart.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: zerasul 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://www.buymeacoffee.com/zerasul'] 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "04:00" 8 | open-pull-requests-limit: 10 9 | target-branch: develop 10 | ignore: 11 | - dependency-name: nyc 12 | versions: 13 | - ">= 15.0.a, < 15.1" 14 | - dependency-name: "@types/node" 15 | versions: 16 | - 14.14.25 17 | - 14.14.26 18 | - 14.14.36 19 | - 14.14.39 20 | - 14.14.41 21 | - 15.0.0 22 | - dependency-name: "@types/vscode" 23 | versions: 24 | - 1.54.0 25 | - dependency-name: typescript 26 | versions: 27 | - 4.1.4 28 | -------------------------------------------------------------------------------- /.github/workflows/extensionTests.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | - develop 6 | pull_request: 7 | branches: 8 | - master 9 | - develop 10 | jobs: 11 | build: 12 | strategy: 13 | matrix: 14 | os: [macos-latest, ubuntu-latest, windows-latest] 15 | runs-on: ${{ matrix.os }} 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4 19 | - name: Install Node.js 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: 18.x 23 | - run: npm install 24 | - run: xvfb-run -a npm test 25 | if: runner.os == 'Linux' 26 | - run: npm test 27 | if: runner.os != 'Linux' 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode-test/ 4 | *.vsix 5 | coverage/ 6 | .nyc_output/ -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "ms-vscode.vscode-typescript-tslint-plugin" 6 | ] 7 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "--extensionDevelopmentPath=${workspaceFolder}" 15 | ], 16 | "outFiles": [ 17 | "${workspaceFolder}/out/**/*.js" 18 | ], 19 | "preLaunchTask": "npm: watch" 20 | }, 21 | { 22 | "name": "Extension Tests", 23 | "type": "extensionHost", 24 | "request": "launch", 25 | "runtimeExecutable": "${execPath}", 26 | "args": [ 27 | "--extensionDevelopmentPath=${workspaceFolder}", 28 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 29 | ], 30 | "outFiles": [ 31 | "${workspaceFolder}/out/test/**/*.js" 32 | ], 33 | "preLaunchTask": "npm: watch" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off" 11 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | src/** 5 | .gitignore 6 | vsc-extension-quickstart.md 7 | **/tsconfig.json 8 | **/tslint.json 9 | **/*.map 10 | **/*.ts 11 | coverage/** 12 | .nyc_output/ 13 | .github/** 14 | azure-pipelines.yml -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | This is the change Log of Genesis Code. For more information you can see the [Documentation page](https://zerasul.github.io/genesis-code-docs/). 4 | 5 | ## 1.5.2 6 | * [Updated autocompletion and .res grammer for use with SGDK 2.11](https://github.com/zerasul/genesis-code/issues/1416). 7 | * [Now the default Docker image is the SGDK's Github Registry: ```ghcr.io/stephane-d/sgdk:latest```](https://github.com/zerasul/genesis-code/issues/1416). 8 | * [Added new "Paralel Compile" Configuration parameter (for -j usage)](https://github.com/zerasul/genesis-code/issues/1382). 9 | * [Added new "extra params" Configuration parameter](https://github.com/zerasul/genesis-code/issues/1424). 10 | * Updated Dependencies. 11 | 12 | ## 1.5.1 13 | 14 | * [On Windows Systems, the new projects will be created using Command prompt console as default (no extra configuration needed).](https://github.com/zerasul/genesis-code/pull/1180) 15 | * [Now, when a new project is created, the current GDK or GENDEV configuration will be used for C/C++ include configuration on .vscode/settings.json; if there is no configuration, the environment variable will be used.](https://github.com/zerasul/genesis-code/issues/1198). 16 | * Updated Dependencies. 17 | 18 | ## 1.5.0 19 | 20 | * [Add "Status bar Button" configuration, to add status bar buttons for the more commons commands (no more command palette)](https://github.com/zerasul/genesis-code/issues/1087). 21 | * [Added 4 Status Bar Buttons for _compile_, _compile&Run_, _compile for Debug_ and _clean_](https://github.com/zerasul/genesis-code/pull/951). 22 | * [Updating autocompletion and .res grammar for use with the new XGM2 Driver and SGDK 2.00](https://github.com/zerasul/genesis-code/issues/928). 23 | * Updating dependencies. 24 | 25 | ## 1.4.2 26 | 27 | * [Updating grammar for use SGDK 1.80 with the last documentation.](https://github.com/zerasul/genesis-code/issues/774) 28 | * [Fix Bug when create on Windows a new project the settings are not properly point to SGDK include Folders.](https://github.com/zerasul/genesis-code/issues/809) 29 | * [Fix Multiple Instances of gens.code error.](https://github.com/zerasul/genesis-code/issues/794) 30 | * Updated dependencies. 31 | 32 | ## 1.4.1 33 | 34 | * [Added Support for Dogarasu SGDK Docker Image](https://github.com/zerasul/genesis-code/issues/627). 35 | * [Fixed Bug for run in background Emulator in MacOs](https://github.com/zerasul/genesis-code/issues/52). 36 | * [Fix Gens.code Multiples Instances Error.](https://github.com/zerasul/genesis-code/issues/672). 37 | * [Updated Rescomp Context Help Information for the Last Version of SGDK (Supports 1.70)](https://github.com/zerasul/genesis-code/issues/545). 38 | * Updated Dependencies. 39 | 40 | ## 1.4.0 41 | 42 | * [Added Docker container Support](https://github.com/zerasul/genesis-code/issues/326). 43 | * [Improved Code with a total Refactoring](https://github.com/zerasul/genesis-code/issues/350). 44 | * [SGDK resource files now have regions](https://github.com/zerasul/genesis-code/pull/491) 45 | * They start with *#region* / *#pragma region* 46 | * They end with *#endregion* / *#pragma endregion* 47 | * [Fixed some syntax highlighting errors related with numbers](https://github.com/zerasul/genesis-code/pull/491) 48 | 49 | ## 1.3.3 50 | 51 | * [Added SGDK 1.65 Support](https://github.com/zerasul/genesis-code/issues/277). 52 | * [Updating use of Wine for Wine64 (Only MacOs)](https://github.com/zerasul/genesis-code/issues/243) 53 | * [Added Bitmap Viewer for Bmp,Png and JPEG images](https://github.com/zerasul/genesis-code/issues/206). 54 | * Updated Some Dependencies. 55 | 56 | ## 1.3.2 57 | 58 | * [Added SGDK 1.60 support](https://github.com/zerasul/genesis-code/issues/239). 59 | * [Added About genesis Code command](https://github.com/zerasul/genesis-code/issues/207). 60 | * [Fixed a bug when the run command is called and the path of the rom have spaces](https://github.com/zerasul/genesis-code/issues/75). 61 | * [Added comment Syntax Hihghlighting on res files](https://github.com/zerasul/genesis-code/issues/233). 62 | * Updated Some dependencies. 63 | 64 | ## 1.3.1 65 | 66 | * [Fixed a bug with some dependencies (Import TMX format ins't works)](https://github.com/zerasul/genesis-code/issues/216) 67 | * [Fixed some code smells reported by sonar.](https://github.com/zerasul/genesis-code/issues/214) 68 | 69 | ## 1.3.0 70 | 71 | * [Adding configuration for use GDK, GENDEV or MARSDEV alternate environment variables](https://github.com/zerasul/genesis-code/issues/136) 72 | * [Adding configuration for use alternative makefile](https://github.com/zerasul/genesis-code/issues/137) 73 | * [Added import TMX file command](https://github.com/zerasul/genesis-code/issues/132) 74 | * [Added import Json Tmx File command](https://github.com/zerasul/genesis-code/issues/132) 75 | * updated some outdated dependencies and improved code 76 | 77 | ## 1.2.2 78 | 79 | * [Updated for use with SGDK 1.51](https://github.com/zerasul/genesis-code/issues/128) 80 | * [Improved code and fixed some bugs](https://github.com/zerasul/genesis-code/issues/133) 81 | * Updated some outdated Dependencies 82 | 83 | ## 1.2.1 84 | 85 | * [Updated for use with SGDK 1.50](https://github.com/zerasul/genesis-code/issues/122) 86 | * [Added Debuggers Category to Package.json](https://github.com/zerasul/genesis-code/issues/121) 87 | * [Added include path settings on new project creation](https://github.com/zerasul/genesis-code/issues/123) 88 | * [Updated some outdated Dependencies] 89 | 90 | ## 1.2.0 91 | 92 | * [Added Compatibility with MarsDev Toolchain](https://github.com/zerasul/genesis-code/issues/117) 93 | * [Added debug linking configuration](https://github.com/zerasul/genesis-code/issues/66) 94 | * [Added new configuration for Toolchain selection](https://github.com/zerasul/genesis-code/issues/117) 95 | * Updated some outdated dependencies 96 | 97 | ## 1.1.1 98 | 99 | * [Fixed a typo error on main.c file](https://github.com/zerasul/genesis-code/issues/62) 100 | * [Added Autocomplete feature for SGDK Resource Files](https://github.com/zerasul/genesis-code/issues/53) 101 | * Updated some autdated dependencies. 102 | 103 | ## 1.1.0 104 | 105 | * [Added MACOs Support](https://github.com/zerasul/genesis-code/issues/16). 106 | * [Added Syntax HighLigthing for SGDK Resource Files.](https://github.com/zerasul/genesis-code/issues/17). 107 | * Updated some outdated dependencies. 108 | 109 | ## 1.0.1 110 | 111 | * [Fixed Readme.md template Bug](https://github.com/zerasul/genesis-code/issues/18). 112 | * [Fixed an error on create project that donsent track the empty directories](https://github.com/zerasul/genesis-code/issues/18). 113 | * Updated some outdated depencies. 114 | 115 | ## 1.0.0 116 | 117 | Initial release: 118 | 119 | * Added Compile command. 120 | * Added Run command. 121 | * Added Clean command. 122 | * Added Compile & Run command. 123 | * Added Create Project command. 124 | * Added Set Gens Emulator Command. 125 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Victor Suarez, Cristobal Contreras 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 | # Genesis-code Extension 2 | 3 | [![.github/workflows/extensionTests.yml](https://github.com/zerasul/genesis-code/actions/workflows/extensionTests.yml/badge.svg?branch=master)](https://github.com/zerasul/genesis-code/actions/workflows/extensionTests.yml) 4 | [![SGDK Compatible](https://img.shields.io/badge/SGDK_Compatible-2.11-912aeb)](https://github.com/Stephane-D/SGDK) 5 | [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=genesis-code-project&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=genesis-code-project) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=genesis-code-project&metric=security_rating)](https://sonarcloud.io/dashboard?id=genesis-code-project) Buy Me A Coffee donate button 6 | [![Visual Studio Marketplace Installs](https://img.shields.io/visual-studio-marketplace/i/zerasul.genesis-code)](https://marketplace.visualstudio.com/items?itemName=zerasul.genesis-code) 7 | 8 | Genesis-Code is a Visual Studio Code Extension for Sega Genesis/ Mega Drive development. This extension is created for use with the [SGDK](https://github.com/Stephane-D/SGDK)/[GENDEV](https://github.com/kubilus1/gendev) or [MARSDEV](https://github.com/andwn/marsdev) projects for create homebrew games for the Sega 16 bits console. 9 | 10 | For more information, see [Genesis Code Documentation Web Page](https://zerasul.github.io/genesis-code-docs/). 11 | 12 | If you want to know how to develop Mega Drive Games; You can see the "16 Bits Homebrew Development" Book available on Amazon: [Spanish Version](https://amzn.eu/d/1GDGkhA), [English Version](https://www.amazon.com/dp/B0CW4TH2NJ). 13 | 14 | ## Features 15 | 16 | With this extension, you can use easily a few commands for help you create awesome games. This extension adds the following commands: 17 | 18 | * Compile command: compile the program and generate the Rom file. 19 | * Run command: You can use an emulator like Gens to run and test your game. 20 | * Clean command: Clean the programs build folder (calls makefile with clean). 21 | * Compile & Run command: first compile and later run the rom.bin file in an emulator. 22 | * Create project: Select a folder and create a Hello World project ready for compile and run. 23 | * Set Gens Command: Update the configuration and adds the command path to run Gens Emulator. 24 | * Compile For debug command: Compile the project with debug options. 25 | * SGDK Resource Files Code Completion. 26 | * Added remote debugging configuration for use with GDB. 27 | * Compatible with [MarsDev](https://github.com/andwn/marsdev) Toolchain. 28 | * Import TMX file command: Uses a [TMX file format](https://doc.mapeditor.org/en/stable/reference/tmx-map-format/) for generate a C header file for your projects. 29 | * Import Json TMX file command: Uses a [Tmx Json File Format](https://doc.mapeditor.org/en/stable/reference/json-map-format/) for generate a C Header file for Your project. 30 | * Added configuration for use alternative MakeFile. 31 | * Added configuration for use alernative environment variables for GDK, GENDEV or MARSDEV. 32 | * Added Genesis Code: About for open more information about the extension. 33 | * Added BitmapViewer. 34 | * Added Status Bar Buttons for compile, compile & Run, Compile For debug and clean (Thanks to burmaraider). 35 | * Added Configuration for enable or disable status bar buttons. 36 | * Added Docker Support. 37 | 38 | ![vscodegif](imgs/vscodegif.gif) 39 | 40 | ## Requirements 41 | 42 | To use this extension you need to install SGDK(windows)/GENDEV(linux) or MARSDEV projects on your system and configure the GDK, GENDEV or MARSDEV enviroment variables, or build/use a SGDK Docker Image. 43 | 44 | ## Extension Settings 45 | 46 | You can set the [Gens Emulator](http://www.gens.me/) command to call it directly from the Genesis Code Extension (Run Command). 47 | 48 | You can set it via command , or using the settings configuration. 49 | 50 | ![Genesiscodeconfiguration](imgs/genscodesettings.png) 51 | 52 | **NOTE**: You can use another emulators like [Blastem](https://www.retrodev.com/blastem/). 53 | 54 | You can select the toolchain type for use with genesis code: 55 | 56 | * SGDK/GENDEV: the SGDK libs and GENDEV (On Linux) will be used with Genesis Code. 57 | * MARSDEV: The MARSDEV project will be used with Genesis Code. 58 | * DOCKER: Use a SGDK Docker container for compiling. 59 | 60 | ![genesiscodeconfigtoolchain](imgs/genesiscodeconfigtoolchain.png) 61 | 62 | You can set an alternative MakeFile on the configuration panel. When the compile or clean command is called the alternative Makefile will be used instead the default makefile. 63 | 64 | ![genesiscodemakefile](imgs/makefile.png) 65 | 66 | Also, you can set an alternative value for the environment variables of GDK, GENDEV or MARSDEV. 67 | 68 | ![envvariables](imgs/envvariables.png) 69 | 70 | Now, you can define a custom docker image tag for generate a new container. 71 | 72 | ![dockertag](imgs/dockertag.png) 73 | 74 | **NOTE:** If you want to use [Doragasu SGDK Docker Image](https://gitlab.com/doragasu/docker-sgdk), you can use the check in Configuration and you must add the current Docker Image Tag description (with the gitlab registry URL). 75 | 76 | ![statusbarconfig](imgs/statusbar.png) 77 | 78 | You can enable or disable status bar buttons for use some common commands. 79 | 80 | ![Status Bar Buttons](imgs/sbarbuttons.png) 81 | 82 | Also, you can enable parallel compilation adding the number of threads in the Genesis Code configuration. 83 | 84 | And now, you can add extra parameters for compilation and clean commands this will be used on docker and make calls. 85 | 86 | ![extra Parameters](imgs/extraparams.png) 87 | 88 | ## Bitmap Viewer 89 | 90 | Now you can use the Bitmap Viewer; with some information of the images. You can open as alternative viewer on VSCODE (right click and Reopen Editor... on tab). 91 | 92 | ![bitmapviewer](imgs/bitmapv.PNG) 93 | 94 | ## Known Issues 95 | 96 | * In MacOs the _compile & Run project_ command, the emulator is not running in background. We are working in this issue. 97 | * In Linux systems, you can't compile with debug options using SGDK/GENDEV toolchain. 98 | * In Linux Systems, when you create a new project there is no launch.json file for SGDK/GENDEV toolchain. 99 | * On MacOs Systems, for the SGDK/GENDEV ToolchainType you can't use custom Makefile or custom Environment variables; this is due to the use of Wine. 100 | * The C headers include settings don't work if you are using Docker containers; this is due the SGDK headers are inside the container and not available without using a volume. Follow [this instructions](https://zerasul.github.io/genesis-code-docs/install/#configure-headers-using-docker-containers) for more information. 101 | 102 | ## Release Notes 103 | 104 | ### 1.5.2 105 | 106 | * Now the default Docker image is based on SGDK's Github Registry (```ghcr.io/stephane-d/sgdk:latest```). 107 | * Updating autocompletion and .res grammar for use with SGDK 2.11. 108 | * Added new ```ParallelCompile``` configuration parameter for use -j for parallel compilation (only for SGDK on windows or MARSDEV). 109 | * Added new ```extraParameters``` configuration parameter to add extra parameters on compilation and clean commands. 110 | * Updating dependencies. 111 | 112 | ### 1.5.1 113 | 114 | * On Windows Systems, the new projects will be created using Command prompt console as default (no extra configuration needed) (Thanks to AIoriBranford). 115 | * Now, when a new project is created, the current GDK or GENDEV configuration will be used for C/C++ include configuration on .vscode/settings.json; if there is no configuration, the environment variable will be used. 116 | * Updated Dependencies. 117 | 118 | ### 1.5.0 119 | 120 | * Add "Status bar Button" configuration, to add status bar buttons for the more commons commands (no more command palette). 121 | * Added 4 Status Bar Buttons for _compile_, _compile&Run_, _compile for Debug_ and _clean_. 122 | * Updating autocompletion and .res grammar for use with the new XGM2 Driver and SGDK 2.00. 123 | * Updating dependencies. 124 | 125 | ### 1.4.2 126 | 127 | * Updating grammar for use SGDK 1.80 with the last documentation. 128 | * Fix Bug when create on Windows a new project the settings are not properly point to SGDK include Folders. 129 | * Fix Multiple Instances of gens.code error. 130 | * Updated dependencies. 131 | 132 | ### 1.4.1 133 | 134 | * Added Support for Dogarasu SGDK Docker Image. 135 | * Added Configuration Flag for Dogarasu SGDK Docker Image. 136 | * Fix Gens.code Multiples Instances Error. 137 | * Updated Rescomp Context Help Information for the Last Version of SGDK (Supports 1.70). 138 | * Updated Dependencies. 139 | 140 | ### 1.4.0 141 | 142 | * Added Docker container Support. 143 | * Improved Code with a total Refactoring. 144 | * SGDK resource files now have regions 145 | * They start with *#region* / *#pragma region* 146 | * They end with *#endregion* / *#pragma endregion* 147 | * Fixed some syntax highlighting errors related with numbers 148 | 149 | **NOTE:** Thanks to our contributors on the HacktoberFest 2021 and for the last contributors with the File resource Grammar improvements. 150 | 151 | ### 1.3.3 152 | 153 | * Added SGDK 1.65 Support. 154 | * Updating use of Wine for Wine64 (Only MacOs). 155 | * Added Bitmap Viewer for Bmp,Png and JPEG images. 156 | 157 | ### 1.3.2 158 | 159 | * Added Support for SGDK 1.60 Map resources in res files. 160 | * Changed default main.c generation for use the new functions for SGDK 1.60. 161 | * Added comment higthlingthing on res files. 162 | * Fixed a bug that the Run command dosen't works if the path have spaces characters. 163 | * Added Genesis Code: About command. This command shows information about Genesis Code extension. 164 | * Updated some dependencies. 165 | 166 | ### 1.3.1 167 | 168 | * Fixed a bug with some dependencies (Import TMX format ins't works). 169 | * Fixed some code smells reported by sonar. 170 | 171 | ### 1.3.0 172 | 173 | * Added import TMX file command; it generates a C Header File with the information of the TMX file. For more info about the TMX format, please see [Tiled Documentation](https://doc.mapeditor.org/en/stable/reference/tmx-map-format/). 174 | * Added import Json Tmx File command; it generates a C Header File with the information of the json TMX file. For more info about the json Tmx Format, please see [Tiled Documentation](https://doc.mapeditor.org/en/stable/reference/json-map-format/). 175 | * Added custom makefile configuration; now you can set an alternartive for the default makefile. 176 | * Added configuration for GDK, GENDEV or MARSDEV custom variables. 177 | * Updated some dependencies and improved code. 178 | 179 | ### 1.2.2 180 | 181 | * Updated for use with SGDK 1.51; added new features for SGDK Resource Files autocompletion (for use with the last version of rescomp tool). 182 | * Fixed some bugs and improved code. 183 | * Updated some dependencies and updating package-lock.json. 184 | 185 | ### 1.2.1 186 | 187 | * Updated for use with SGDK 1.50; added new features for SGDK Resource Files autocompletion (for use with the last version of rescomp tool). 188 | * Now when you create a new Project a settings.json file is created with the default include paths. 189 | * Added Debuggers category to Package.json. 190 | * Updated some dependencies and updating package-lock.json. 191 | 192 | ### 1.2.0 193 | 194 | * Added [Marsdev](https://github.com/andwn/marsdev) toolchain compatibility. Now you can use the marsdev toolchain with genesis code. For more information please see [Genesis code Documentation Web](https://zerasul.github.io/genesis-code-docs/). 195 | * Added configuration for debugging. Now when you create a new project a launch.json is created. For more information please see [Genesis code Documentation Web](https://zerasul.github.io/genesis-code-docs/debug/). 196 | * Now you can select your toolchain from the genesis code Settings; SGDK/GENDEV toolchain or MARSDEV toolchain. 197 | * Added Compile with Debug Options command. 198 | * Updated dependencies and improving code. 199 | 200 | ### 1.1.1 201 | 202 | * Added SGDK Resource Files Autocomplete feature. Now we have contextual help for the SGDK Resource Files, see [Genesis code Documentation web](https://zerasul.github.io/genesis-code-docs/otherfeatures/) for more information. 203 | * Fixed a typo error on the main.c autogenerated file when we create a new Project. 204 | * Updated depdendencies and improving tests. 205 | 206 | ### 1.1.0 207 | 208 | * Adding MACOs Support. Now you can use genesis code using wine. For more information please see [Genesis code Documentation](https://zerasul.github.io/genesis-code-docs/). 209 | * Added Syntax HighLingthing for SGDK Resource Files (.res). 210 | * Updated dependencies. 211 | 212 | ### 1.0.1 213 | 214 | * Fixed a bug with create new project that dosent show properly the readme.md file. 215 | * Fixed a bug with create new project that dosent include 'res' and 'inc' directories into git repository. 216 | * Updating dependencies of the extension. 217 | 218 | ### 1.0.0 219 | 220 | Initial Release: 221 | 222 | * Added Compile command. 223 | * Added Run command. 224 | * Added Clean command. 225 | * Added Compile & Run command. 226 | * Added Create Project command. 227 | * Added Set Gens Emulator Command. 228 | 229 | ----------------------------------------------------------------------------------------------------------- 230 | 231 | You can support this project using [Buy Me a Coffee](https://www.buymeacoffee.com/zerasul). 232 | 233 | **Enjoy!** 234 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | - master 3 | 4 | strategy: 5 | matrix: 6 | linux: 7 | imageName: "ubuntu-latest" 8 | mac: 9 | imageName: "macos-latest" 10 | windows: 11 | imageName: "windows-latest" 12 | 13 | pool: 14 | vmImage: $(imageName) 15 | 16 | steps: 17 | - task: NodeTool@0 18 | inputs: 19 | versionSpec: "20.x" 20 | displayName: "Install Node.js" 21 | 22 | - bash: | 23 | /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & 24 | echo ">>> Started xvfb" 25 | displayName: Start xvfb 26 | condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) 27 | 28 | - task: SonarCloudPrepare@1 29 | inputs: 30 | SonarCloud: "SonarCloud" 31 | organization: "zerasul-github" 32 | scannerMode: "CLI" 33 | configMode: "manual" 34 | cliProjectKey: "genesis-code-project" 35 | cliProjectName: "Genesis Code" 36 | cliSources: "src/" 37 | extraProperties: | 38 | # Additional properties that will be passed to the scanner, 39 | # Put one key=value per line, example: 40 | sonar.exclusions=src/test/ 41 | 42 | - task: SonarCloudAnalyze@1 43 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Pull Request Process 9 | 10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a 11 | build. 12 | 2. Update the README.md with details of changes to the interface, this includes new environment 13 | variables, exposed ports, useful file locations and container parameters. 14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this 15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 16 | 4. Please always use as base branch the 'develop' branch; we use the [gitflow branch strategy](https://nvie.com/posts/a-successful-git-branching-model/). 17 | 5. You may merge the Pull Request in once you have the sign-off of two other developers, or if you 18 | do not have permission to do that, you may request the second reviewer to merge it for you. 19 | 6. If you need to add more documentation about this project you can make a pull request to our [Documentation Web Page Repository](https://github.com/zerasul/genesis-code-docs/). 20 | 21 | ## Code of Conduct 22 | 23 | ### Our Pledge 24 | 25 | In the interest of fostering an open and welcoming environment, we as 26 | contributors and maintainers pledge to making participation in our project and 27 | our community a harassment-free experience for everyone, regardless of age, body 28 | size, disability, ethnicity, gender identity and expression, level of experience, 29 | nationality, personal appearance, race, religion, or sexual identity and 30 | orientation. 31 | 32 | ### Our Standards 33 | 34 | Examples of behavior that contributes to creating a positive environment 35 | include: 36 | 37 | * Using welcoming and inclusive language 38 | * Being respectful of differing viewpoints and experiences 39 | * Gracefully accepting constructive criticism 40 | * Focusing on what is best for the community 41 | * Showing empathy towards other community members 42 | 43 | Examples of unacceptable behavior by participants include: 44 | 45 | * The use of sexualized language or imagery and unwelcome sexual attention or 46 | advances 47 | * Trolling, insulting/derogatory comments, and personal or political attacks 48 | * Public or private harassment 49 | * Publishing others' private information, such as a physical or electronic 50 | address, without explicit permission 51 | * Other conduct which could reasonably be considered inappropriate in a 52 | professional setting. 53 | 54 | ### Our Responsibilities 55 | 56 | Project maintainers are responsible for clarifying the standards of acceptable 57 | behavior and are expected to take appropriate and fair corrective action in 58 | response to any instances of unacceptable behavior. 59 | 60 | Project maintainers have the right and responsibility to remove, edit, or 61 | reject comments, commits, code, wiki edits, issues, and other contributions 62 | that are not aligned to this Code of Conduct, or to ban temporarily or 63 | permanently any contributor for other behaviors that they deem inappropriate, 64 | threatening, offensive, or harmful. 65 | 66 | ### Scope 67 | 68 | This Code of Conduct applies both within project spaces and in public spaces 69 | when an individual is representing the project or its community. Examples of 70 | representing a project or community include using an official project e-mail 71 | address, posting via an official social media account, or acting as an appointed 72 | representative at an online or offline event. Representation of a project may be 73 | further defined and clarified by project maintainers. 74 | 75 | ### Enforcement 76 | 77 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 78 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All 79 | complaints will be reviewed and investigated and will result in a response that 80 | is deemed necessary and appropriate to the circumstances. The project team is 81 | obligated to maintain confidentiality with regard to the reporter of an incident. 82 | Further details of specific enforcement policies may be posted separately. 83 | 84 | Project maintainers who do not follow or enforce the Code of Conduct in good 85 | faith may face temporary or permanent repercussions as determined by other 86 | members of the project's leadership. 87 | 88 | ### Attribution 89 | 90 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 91 | available at [http://contributor-covenant.org/version/1/4][version] 92 | 93 | [homepage]: http://contributor-covenant.org 94 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /imgs/bitmapv.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/bitmapv.PNG -------------------------------------------------------------------------------- /imgs/dockertag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/dockertag.png -------------------------------------------------------------------------------- /imgs/envvariables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/envvariables.png -------------------------------------------------------------------------------- /imgs/extraparams.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/extraparams.png -------------------------------------------------------------------------------- /imgs/genesiscodeconfigtoolchain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/genesiscodeconfigtoolchain.png -------------------------------------------------------------------------------- /imgs/genesiscodeicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/genesiscodeicon.png -------------------------------------------------------------------------------- /imgs/genscodeicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/genscodeicon.png -------------------------------------------------------------------------------- /imgs/genscodesettings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/genscodesettings.png -------------------------------------------------------------------------------- /imgs/makefile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/makefile.png -------------------------------------------------------------------------------- /imgs/sbarbuttons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/sbarbuttons.png -------------------------------------------------------------------------------- /imgs/statusbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/statusbar.png -------------------------------------------------------------------------------- /imgs/vscodegif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerasul/genesis-code/HEAD/imgs/vscodegif.gif -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "genesis-code", 3 | "displayName": "Genesis Code", 4 | "description": "Sega genesis Development Extension", 5 | "version": "1.5.2", 6 | "icon": "imgs/genesiscodeicon.png", 7 | "publisher": "Zerasul", 8 | "license": "See LICENSE in LICENSE", 9 | "keywords": [ 10 | "genesis", 11 | "sgdk", 12 | "gendev", 13 | "sega", 14 | "mega drive", 15 | "retrodev" 16 | ], 17 | "engines": { 18 | "vscode": "^1.92.0" 19 | }, 20 | "categories": [ 21 | "Programming Languages", 22 | "Snippets", 23 | "Other", 24 | "Debuggers" 25 | ], 26 | "activationEvents": [ 27 | "*" 28 | ], 29 | "main": "./out/extension.js", 30 | "contributes": { 31 | "customEditors": [ 32 | { 33 | "viewType": "genesiscode.imageViewer", 34 | "displayName": "SGDK Image Preview", 35 | "selector": [ 36 | { 37 | "filenamePattern": "*.bmp" 38 | }, 39 | { 40 | "filenamePattern": "*.png" 41 | }, 42 | { 43 | "filenamePattern": "*.jpg" 44 | }, 45 | { 46 | "filenamePattern": "*.jpeg" 47 | } 48 | ], 49 | "priority": "option" 50 | } 51 | ], 52 | "commands": [ 53 | { 54 | "command": "extension.cleancode", 55 | "title": "Genesis Code: clean" 56 | }, 57 | { 58 | "command": "extension.createproject", 59 | "title": "Genesis Code: Create Project" 60 | }, 61 | { 62 | "command": "extension.compileproject", 63 | "title": "Genesis Code: Compile Project" 64 | }, 65 | { 66 | "command": "extension.runproject", 67 | "title": "Genesis Code: Run Project" 68 | }, 69 | { 70 | "command": "extension.setrunpath", 71 | "title": "Genesis Code: Set Gens Emulator Command Path" 72 | }, 73 | { 74 | "command": "extension.compileandrunproject", 75 | "title": "Genesis Code: Compile & Run Project" 76 | }, 77 | { 78 | "command": "extension.compile4debug", 79 | "title": "Genesis Code: Compile For Debugging" 80 | }, 81 | { 82 | "command": "extension.tmximport", 83 | "title": "Genesis Code: Import TMX File" 84 | }, 85 | { 86 | "command": "extension.tmxjsonimport", 87 | "title": "Genesis Code: Import Json TMX File" 88 | }, 89 | { 90 | "command": "extension.aboutgenscode", 91 | "title": "Genesis Code: About" 92 | } 93 | ], 94 | "languages": [ 95 | { 96 | "id": "Sgdk Resource File", 97 | "extensions": [".res"], 98 | "configuration": "./resources/language-configuration.json" 99 | } 100 | ], 101 | "grammars": [ 102 | { 103 | "language": "Sgdk Resource File", 104 | "scopeName": "source.res", 105 | "path": "./resources/res_grammar.json" 106 | } 107 | ], 108 | "configuration": [ 109 | { 110 | "title": "Genesis Code", 111 | "properties": { 112 | "gens.path": { 113 | "title": "Gens Emulator Command path", 114 | "type": "string", 115 | "default": "gens", 116 | "description": "Set the Gens Emulator command path" 117 | }, 118 | "toolchainType": { 119 | "title": "ToolChain Type", 120 | "type": "string", 121 | "enum": [ 122 | "sgdk/gendev", 123 | "marsdev", 124 | "docker" 125 | ], 126 | "enumDescriptions": [ 127 | "Uses SGDK Library or GENDEV on Linux", 128 | "Uses MarsDev Toolchain", 129 | "Used Docker for build with SGDK docker" 130 | ], 131 | "default": "sgdk/gendev", 132 | "description": "Defines the ToolChain to Use SGDK/Gendev type or use MarsDev Toolchain" 133 | }, 134 | "dockerTag":{ 135 | "title": "Tag value for Docker", 136 | "type": "string", 137 | "default": "", 138 | "description": "Defines tag value will use in a Docker build leaves empty for default no use tag" 139 | }, 140 | "doragasuImage":{ 141 | "title": "Doragasu Image", 142 | "type":"boolean", 143 | "default":false, 144 | "description": "Uses a Doragasu Gitlab Image" 145 | }, 146 | "custom-makefile": { 147 | "title": "Custom MakeFile", 148 | "type": "string", 149 | "default": "", 150 | "description": "Set the Custom Makefile for use. leaves empty for default SGDK, GENDEV or MARSDEV Makefile" 151 | }, 152 | "MARSDEV": { 153 | "title": "MARSDEV environment variable", 154 | "type": "string", 155 | "default": "", 156 | "description": "Set the $MARSDEV environment variable. leave empty for use system default" 157 | }, 158 | "GENDEV": { 159 | "title": "GENDEV environment variable", 160 | "type": "string", 161 | "default": "", 162 | "description": "Set the $GENDEV environment variable. leave empty for use system default" 163 | }, 164 | "GDK": { 165 | "title": "GDK environment variable", 166 | "type": "string", 167 | "default": "", 168 | "description": "Set the $GDK environment variable. leave empty for use system default" 169 | }, 170 | "addStatusBarButtons":{ 171 | "title": "Add Status Bar Buttons", 172 | "type": "boolean", 173 | "default":false, 174 | "description": "Adds Status bar Auxiliar Buttons" 175 | }, 176 | "extraParameters":{ 177 | "title": "Extra Parameters", 178 | "type": "string", 179 | "default": "", 180 | "description": "Set Extra Parameters for makefile" 181 | }, 182 | "parallelCompile":{ 183 | "title": "Parallel Compile", 184 | "type": "integer", 185 | "default":1, 186 | "description": "Enable Parallel Compilation on makefile (-J)" 187 | } 188 | } 189 | } 190 | ] 191 | }, 192 | "scripts": { 193 | "vscode:prepublish": "npm run compile", 194 | "compile": "tsc -p ./", 195 | "watch": "tsc -watch -p ./", 196 | "pretest": "npm run compile", 197 | "test": "node ./out/test/runTest.js", 198 | "coverage": "nyc --reporter=lcov --reporter=text node ./out/test/runTest.js" 199 | }, 200 | "devDependencies": { 201 | "@types/glob": "^8.0.0", 202 | "@types/mocha": "^10.0.10", 203 | "@types/vscode": "^1.92.0", 204 | "glob": "^8.0.3", 205 | "mocha": "^11.1.0", 206 | "nyc": "^17.1.0", 207 | "tslint": "^6.1.3", 208 | "typescript": "^5.8.3", 209 | "@vscode/test-electron": "^2.4.1", 210 | "yarn": "^1.22.22", 211 | "@swc/core": "^1.11.8", 212 | "@swc/wasm": "^1.11.18" 213 | }, 214 | "dependencies": { 215 | "@zerasul/image-read-helper": "^0.0.1", 216 | "fast-xml-parser": "^5.2.0", 217 | "@types/node": "^22.8.4" 218 | }, 219 | "bugs": { 220 | "url": "https://github.com/zerasul/genesis-code/issues" 221 | }, 222 | "repository": { 223 | "url": "https://github.com/zerasul/genesis-code" 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /resources/Makefile.template: -------------------------------------------------------------------------------- 1 | # Sample Makefile for Marsdev (Non-SGDK version) 2 | 3 | # Default paths, can be overridden by setting MARSDEV before calling make 4 | MARSDEV ?= ${HOME}/mars 5 | MARSBIN = $(MARSDEV)/m68k-elf/bin 6 | TOOLSBIN = $(MARSDEV)/bin 7 | 8 | # GCC and Binutils 9 | CC = $(MARSBIN)/m68k-elf-gcc 10 | CXX = $(MARSBIN)/m68k-elf-g++ 11 | AS = $(MARSBIN)/m68k-elf-as 12 | LD = $(MARSBIN)/m68k-elf-ld 13 | NM = $(MARSBIN)/m68k-elf-nm 14 | OBJC = $(MARSBIN)/m68k-elf-objcopy 15 | 16 | # Some files needed are in a versioned directory 17 | GCC_VER := $(shell $(CC) -dumpversion) 18 | 19 | # Need the LTO plugin so NM can dump our symbol table 20 | PLUGIN = $(MARSDEV)/m68k-elf/libexec/gcc/m68k-elf/$(GCC_VER) 21 | LTO_SO = liblto_plugin.so 22 | ifeq ($(OS),Windows_NT) 23 | LTO_SO = liblto_plugin-0.dll 24 | endif 25 | 26 | # Includes: Local + GCC + Newlib 27 | INCS = -Isrc -Ires -Iinc 28 | INCS += -I$(MARSDEV)/m68k-elf/lib/gcc/m68k-elf/$(GCC_VER)/include 29 | INCS += -I$(MARSDEV)/m68k-elf/m68k-elf/include 30 | 31 | # Libraries: GCC + Newlib 32 | # If you plan on using Newlib, uncomment the line with -lnosys 33 | LIBS = -L$(MARSDEV)/m68k-elf/lib/gcc/m68k-elf/$(GCC_VER) -lgcc 34 | #LIBS += -L$(MARSDEV)/m68k-elf/m68k-elf/lib -lnosys 35 | 36 | # Any C or C++ standard should be fine here as long as GCC support it 37 | CCFLAGS = -m68000 -Wall -Wextra -std=c99 -ffreestanding -fcommon 38 | CXXFLAGS = -m68000 -Wall -Wextra -std=c++17 -ffreestanding 39 | 40 | # Extra options set by debug or release target 41 | OPTIONS = 42 | ASFLAGS = -m68000 --register-prefix-optional 43 | LDFLAGS = -T $(MARSDEV)/ldscripts/md.ld -nostdlib 44 | 45 | CS = $(wildcard src/*.c) 46 | CPPS = $(wildcard src/*.cpp) 47 | SS = $(wildcard src/*.s) 48 | OBJS = $(CS:.c=.o) 49 | OBJS += $(CPPS:.cpp=.o) 50 | OBJS += $(SS:.s=.o) 51 | 52 | ASMO = $(RESS:.res=.o) 53 | ASMO += $(Z80S:.s80=.o) 54 | ASMO += $(CS:%.c=asmout/%.s) 55 | 56 | .SECONDARY: out.elf 57 | 58 | .PHONY: all release asm debug 59 | 60 | all: release 61 | 62 | release: OPTIONS = -O3 -fno-web -fno-gcse -fno-unit-at-a-time -fomit-frame-pointer 63 | release: OPTIONS += -fshort-enums -flto -fuse-linker-plugin 64 | release: out.bin symbol.txt 65 | 66 | asm: OPTIONS = -O3 -fno-web -fno-gcse -fno-unit-at-a-time -fomit-frame-pointer 67 | asm: OPTIONS += -fshort-enums 68 | asm: asm-dir $(ASMO) 69 | 70 | # Gens-KMod, BlastEm and UMDK support GDB tracing, enabled by this target 71 | debug: OPTIONS = -g -Og -DDEBUG -DKDEBUG 72 | debug: out.bin symbol.txt 73 | 74 | # This generates a symbol table that is very helpful in debugging crashes, 75 | # even with an optimized release build! 76 | # Cross reference symbol.txt with the addresses displayed in the crash handler 77 | symbol.txt: out.bin 78 | $(NM) --plugin=$(PLUGIN)/$(LTO_SO) -n out.elf > symbol.txt 79 | 80 | boot.o: 81 | $(AS) $(ASFLAGS) boot.s -o $@ 82 | 83 | %.bin: %.elf 84 | @echo "Stripping ELF header..." 85 | @$(OBJC) -O binary $< temp.bin 86 | @dd if=temp.bin of=$@ bs=8192 conv=sync 87 | @rm -f temp.bin 88 | 89 | %.elf: boot.o $(OBJS) 90 | $(CC) -o $@ $(LDFLAGS) boot.o $(OBJS) $(LIBS) 91 | 92 | %.o: %.c 93 | @echo "CC $<" 94 | @$(CC) $(CCFLAGS) $(OPTIONS) $(INCS) -c $< -o $@ 95 | 96 | %.o: %.cpp 97 | @echo "CXX $<" 98 | @$(CXX) $(CXXFLAGS) $(OPTIONS) $(INCS) -c $< -o $@ 99 | 100 | %.o: %.s 101 | @echo "AS $<" 102 | @$(AS) $(ASFLAGS) $< -o $@ 103 | 104 | # For asm target 105 | asm-dir: 106 | mkdir -p asmout/src 107 | 108 | asmout/%.s: %.c 109 | $(CC) $(CCFLAGS) $(OPTIONS) $(INCS) -S $< -o $@ 110 | 111 | .PHONY: clean 112 | 113 | clean: 114 | rm -f $(OBJS) out.bin out.elf symbol.txt boot.o 115 | rm -rf asmout -------------------------------------------------------------------------------- /resources/README.md.template: -------------------------------------------------------------------------------- 1 | # My Awesome Game 2 | 3 | This is My Awesome 16 Bit Cartridge game for mega Drive -------------------------------------------------------------------------------- /resources/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | About Genesis Code 7 | 8 | 9 | 10 |

Genesis Code

11 |

Visual Studio Code extension for Sega Genesis/Mega Drive Development

12 |

© 2025. Version: 1.5.2

13 |

Genesis Code its a Visual Studio Code Extension for Sega Genesis/Mega Drive Development. With this extension you can use easily SGDK for create 16 bits homebrew games for Sega Genesis /Mega Drive.

14 |

Developed By Zerasul & his authors.

15 |

Genesis Code its Open Source and licensed with the MIT License; you can see here the license.

16 |

More Information about Genesis Code:

17 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /resources/boot/rom_head.c.template: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | 3 | __attribute__((externally_visible)) 4 | const struct 5 | { 6 | char console[16]; /* Console Name (16) */ 7 | char copyright[16]; /* Copyright Information (16) */ 8 | char title_local[48]; /* Domestic Name (48) */ 9 | char title_int[48]; /* Overseas Name (48) */ 10 | char serial[14]; /* Serial Number (2, 12) */ 11 | u16 checksum; /* Checksum (2) */ 12 | char IOSupport[16]; /* I/O Support (16) */ 13 | u32 rom_start; /* ROM Start Address (4) */ 14 | u32 rom_end; /* ROM End Address (4) */ 15 | u32 ram_start; /* Start of Backup RAM (4) */ 16 | u32 ram_end; /* End of Backup RAM (4) */ 17 | char sram_sig[2]; /* "RA" for save ram (2) */ 18 | u16 sram_type; /* 0xF820 for save ram on odd bytes (2) */ 19 | u32 sram_start; /* SRAM start address - normally 0x200001 (4) */ 20 | u32 sram_end; /* SRAM end address - start + 2*sram_size (4) */ 21 | char modem_support[12]; /* Modem Support (24) */ 22 | char notes[40]; /* Memo (40) */ 23 | char region[16]; /* Country Support (16) */ 24 | } rom_header = { 25 | "SEGA MEGA DRIVE ", 26 | "(C)FLEMTEAM 2013", 27 | "SAMPLE PROGRAM ", 28 | "SAMPLE PROGRAM ", 29 | "GM 00000000-00", 30 | 0x0000, 31 | "JD ", 32 | 0x00000000, 33 | 0x00100000, 34 | 0x00FF0000, 35 | 0x00FFFFFF, 36 | " ", 37 | 0x0000, 38 | 0x00200000, 39 | 0x002001FF, 40 | " ", 41 | "DEMONSTRATION PROGRAM ", 42 | "JUE " 43 | }; 44 | -------------------------------------------------------------------------------- /resources/boot/sega.s.template: -------------------------------------------------------------------------------- 1 | .section .text.keepboot 2 | 3 | *------------------------------------------------------- 4 | * 5 | * Sega startup code for the GNU Assembler 6 | * Translated from: 7 | * Sega startup code for the Sozobon C compiler 8 | * Written by Paul W. Lee 9 | * Modified by Charles Coty 10 | * Modified by Stephane Dallongeville 11 | * 12 | *------------------------------------------------------- 13 | 14 | .globl _hard_reset 15 | 16 | .org 0x00000000 17 | 18 | _Start_Of_Rom: 19 | _Vecteurs_68K: 20 | dc.l 0x00000000 /* Stack address */ 21 | dc.l _Entry_Point /* Program start address */ 22 | dc.l _Bus_Error 23 | dc.l _Address_Error 24 | dc.l _Illegal_Instruction 25 | dc.l _Zero_Divide 26 | dc.l _Chk_Instruction 27 | dc.l _Trapv_Instruction 28 | dc.l _Privilege_Violation 29 | dc.l _Trace 30 | dc.l _Line_1010_Emulation 31 | dc.l _Line_1111_Emulation 32 | dc.l _Error_Exception, _Error_Exception, _Error_Exception, _Error_Exception 33 | dc.l _Error_Exception, _Error_Exception, _Error_Exception, _Error_Exception 34 | dc.l _Error_Exception, _Error_Exception, _Error_Exception, _Error_Exception 35 | dc.l _Error_Exception, _INT, _EXTINT, _INT 36 | dc.l _HINT 37 | dc.l _INT 38 | dc.l _VINT 39 | dc.l _INT 40 | dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT 41 | dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT 42 | dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT 43 | dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT 44 | 45 | _Rom_Header: 46 | /* .incbin "boot/rom_head.bin", 0x10, 0x100 */ 47 | .incbin "boot/rom_head.bin" 48 | 49 | _Entry_Point: 50 | move #0x2700,%sr 51 | tst.l 0xa10008 52 | bne.s SkipJoyDetect 53 | tst.w 0xa1000c 54 | SkipJoyDetect: 55 | bne.s SkipSetup 56 | 57 | lea Table,%a5 58 | movem.w (%a5)+,%d5-%d7 59 | movem.l (%a5)+,%a0-%a4 60 | * Check Version Number 61 | move.b -0x10ff(%a1),%d0 62 | andi.b #0x0f,%d0 63 | beq.s WrongVersion 64 | * Sega Security Code (SEGA) 65 | move.l #0x53454741,0x2f00(%a1) 66 | WrongVersion: 67 | move.w (%a4),%d0 68 | moveq #0x00,%d0 69 | movea.l %d0,%a6 70 | move %a6,%usp 71 | move.w %d7,(%a1) 72 | move.w %d7,(%a2) 73 | jmp _hard_reset 74 | 75 | Table: 76 | dc.w 0x8000,0x3fff,0x0100 77 | dc.l 0xA00000,0xA11100,0xA11200,0xC00000,0xC00004 78 | 79 | SkipSetup: 80 | jmp _reset_entry 81 | 82 | _hard_reset: 83 | * clear Genesis RAM 84 | lea 0xff0000,%a0 85 | moveq #0,%d0 86 | move.w #0x3FFF,%d1 87 | 88 | ClearRam: 89 | move.l %d0,(%a0)+ 90 | dbra %d1,ClearRam 91 | 92 | * copy initialized variables from ROM to Work RAM 93 | lea _stext,%a0 94 | lea 0xFF0000,%a1 95 | move.l #_sdata,%d0 96 | 97 | * fix for last byte to initialize 98 | addq.l #1,%d0 99 | lsr.l #1,%d0 100 | beq NoCopy 101 | 102 | subq.w #1,%d0 103 | CopyVar: 104 | move.w (%a0)+,(%a1)+ 105 | dbra %d0,CopyVar 106 | 107 | NoCopy: 108 | 109 | * Jump to initialisation process... 110 | 111 | jmp _start_entry 112 | 113 | 114 | *------------------------------------------------ 115 | * 116 | * interrupt functions 117 | * 118 | *------------------------------------------------ 119 | 120 | registersDump: 121 | move.l %d0,registerState+0 122 | move.l %d1,registerState+4 123 | move.l %d2,registerState+8 124 | move.l %d3,registerState+12 125 | move.l %d4,registerState+16 126 | move.l %d5,registerState+20 127 | move.l %d6,registerState+24 128 | move.l %d7,registerState+28 129 | move.l %a0,registerState+32 130 | move.l %a1,registerState+36 131 | move.l %a2,registerState+40 132 | move.l %a3,registerState+44 133 | move.l %a4,registerState+48 134 | move.l %a5,registerState+52 135 | move.l %a6,registerState+56 136 | move.l %a7,registerState+60 137 | rts 138 | 139 | busAddressErrorDump: 140 | move.w 4(%sp),ext1State 141 | move.l 6(%sp),addrState 142 | move.w 10(%sp),ext2State 143 | move.w 12(%sp),srState 144 | move.l 14(%sp),pcState 145 | jmp registersDump 146 | 147 | exception4WDump: 148 | move.w 4(%sp),srState 149 | move.l 6(%sp),pcState 150 | move.w 10(%sp),ext1State 151 | jmp registersDump 152 | 153 | exceptionDump: 154 | move.w 4(%sp),srState 155 | move.l 6(%sp),pcState 156 | jmp registersDump 157 | 158 | 159 | _Bus_Error: 160 | jsr busAddressErrorDump 161 | movem.l %d0-%d1/%a0-%a1,-(%sp) 162 | move.l busErrorCB, %a0 163 | jsr (%a0) 164 | movem.l (%sp)+,%d0-%d1/%a0-%a1 165 | rte 166 | 167 | _Address_Error: 168 | jsr busAddressErrorDump 169 | movem.l %d0-%d1/%a0-%a1,-(%sp) 170 | move.l addressErrorCB, %a0 171 | jsr (%a0) 172 | movem.l (%sp)+,%d0-%d1/%a0-%a1 173 | rte 174 | 175 | _Illegal_Instruction: 176 | jsr exception4WDump 177 | movem.l %d0-%d1/%a0-%a1,-(%sp) 178 | move.l illegalInstCB, %a0 179 | jsr (%a0) 180 | movem.l (%sp)+,%d0-%d1/%a0-%a1 181 | rte 182 | 183 | _Zero_Divide: 184 | jsr exceptionDump 185 | movem.l %d0-%d1/%a0-%a1,-(%sp) 186 | move.l zeroDivideCB, %a0 187 | jsr (%a0) 188 | movem.l (%sp)+,%d0-%d1/%a0-%a1 189 | rte 190 | 191 | _Chk_Instruction: 192 | jsr exception4WDump 193 | movem.l %d0-%d1/%a0-%a1,-(%sp) 194 | move.l chkInstCB, %a0 195 | jsr (%a0) 196 | movem.l (%sp)+,%d0-%d1/%a0-%a1 197 | rte 198 | 199 | _Trapv_Instruction: 200 | jsr exception4WDump 201 | movem.l %d0-%d1/%a0-%a1,-(%sp) 202 | move.l trapvInstCB, %a0 203 | jsr (%a0) 204 | movem.l (%sp)+,%d0-%d1/%a0-%a1 205 | rte 206 | 207 | _Privilege_Violation: 208 | jsr exceptionDump 209 | movem.l %d0-%d1/%a0-%a1,-(%sp) 210 | move.l privilegeViolationCB, %a0 211 | jsr (%a0) 212 | movem.l (%sp)+,%d0-%d1/%a0-%a1 213 | rte 214 | 215 | _Trace: 216 | jsr exceptionDump 217 | movem.l %d0-%d1/%a0-%a1,-(%sp) 218 | move.l traceCB, %a0 219 | jsr (%a0) 220 | movem.l (%sp)+,%d0-%d1/%a0-%a1 221 | rte 222 | 223 | _Line_1010_Emulation: 224 | _Line_1111_Emulation: 225 | jsr exceptionDump 226 | movem.l %d0-%d1/%a0-%a1,-(%sp) 227 | move.l line1x1xCB, %a0 228 | jsr (%a0) 229 | movem.l (%sp)+,%d0-%d1/%a0-%a1 230 | rte 231 | 232 | _Error_Exception: 233 | jsr exceptionDump 234 | movem.l %d0-%d1/%a0-%a1,-(%sp) 235 | move.l errorExceptionCB, %a0 236 | jsr (%a0) 237 | movem.l (%sp)+,%d0-%d1/%a0-%a1 238 | rte 239 | 240 | _INT: 241 | movem.l %d0-%d1/%a0-%a1,-(%sp) 242 | move.l intCB, %a0 243 | jsr (%a0) 244 | movem.l (%sp)+,%d0-%d1/%a0-%a1 245 | rte 246 | 247 | _EXTINT: 248 | movem.l %d0-%d1/%a0-%a1,-(%sp) 249 | move.l internalExtIntCB, %a0 250 | jsr (%a0) 251 | movem.l (%sp)+,%d0-%d1/%a0-%a1 252 | rte 253 | 254 | _HINT: 255 | movem.l %d0-%d1/%a0-%a1,-(%sp) 256 | move.l internalHIntCB, %a0 257 | jsr (%a0) 258 | movem.l (%sp)+,%d0-%d1/%a0-%a1 259 | rte 260 | 261 | _VINT: 262 | movem.l %d0-%d1/%a0-%a1,-(%sp) 263 | move.l internalVIntCB, %a0 264 | jsr (%a0) 265 | movem.l (%sp)+,%d0-%d1/%a0-%a1 266 | rte 267 | 268 | *------------------------------------------------ 269 | * 270 | * Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg 271 | * 272 | * Permission is granted to anyone to use this software for any purpose 273 | * on any computer system, and to redistribute it freely, with the 274 | * following restrictions: 275 | * 1) No charge may be made other than reasonable charges for reproduction. 276 | * 2) Modified versions must be clearly marked as such. 277 | * 3) The authors are not responsible for any harmful consequences 278 | * of using this software, even if they result from defects in it. 279 | * 280 | *------------------------------------------------ 281 | 282 | ldiv: 283 | move.l 4(%a7),%d0 284 | bpl ld1 285 | neg.l %d0 286 | ld1: 287 | move.l 8(%a7),%d1 288 | bpl ld2 289 | neg.l %d1 290 | eor.b #0x80,4(%a7) 291 | ld2: 292 | bsr i_ldiv /* d0 = d0/d1 */ 293 | tst.b 4(%a7) 294 | bpl ld3 295 | neg.l %d0 296 | ld3: 297 | rts 298 | 299 | lmul: 300 | move.l 4(%a7),%d0 301 | bpl lm1 302 | neg.l %d0 303 | lm1: 304 | move.l 8(%a7),%d1 305 | bpl lm2 306 | neg.l %d1 307 | eor.b #0x80,4(%a7) 308 | lm2: 309 | bsr i_lmul /* d0 = d0*d1 */ 310 | tst.b 4(%a7) 311 | bpl lm3 312 | neg.l %d0 313 | lm3: 314 | rts 315 | 316 | lrem: 317 | move.l 4(%a7),%d0 318 | bpl lr1 319 | neg.l %d0 320 | lr1: 321 | move.l 8(%a7),%d1 322 | bpl lr2 323 | neg.l %d1 324 | lr2: 325 | bsr i_ldiv /* d1 = d0%d1 */ 326 | move.l %d1,%d0 327 | tst.b 4(%a7) 328 | bpl lr3 329 | neg.l %d0 330 | lr3: 331 | rts 332 | 333 | ldivu: 334 | move.l 4(%a7),%d0 335 | move.l 8(%a7),%d1 336 | bsr i_ldiv 337 | rts 338 | 339 | lmulu: 340 | move.l 4(%a7),%d0 341 | move.l 8(%a7),%d1 342 | bsr i_lmul 343 | rts 344 | 345 | lremu: 346 | move.l 4(%a7),%d0 347 | move.l 8(%a7),%d1 348 | bsr i_ldiv 349 | move.l %d1,%d0 350 | rts 351 | * 352 | * A in d0, B in d1, return A*B in d0 353 | * 354 | i_lmul: 355 | move.l %d3,%a2 /* save d3 */ 356 | move.w %d1,%d2 357 | mulu %d0,%d2 /* d2 = Al * Bl */ 358 | 359 | move.l %d1,%d3 360 | swap %d3 361 | mulu %d0,%d3 /* d3 = Al * Bh */ 362 | 363 | swap %d0 364 | mulu %d1,%d0 /* d0 = Ah * Bl */ 365 | 366 | add.l %d3,%d0 /* d0 = (Ah*Bl + Al*Bh) */ 367 | swap %d0 368 | clr.w %d0 /* d0 = (Ah*Bl + Al*Bh) << 16 */ 369 | 370 | add.l %d2,%d0 /* d0 = A*B */ 371 | move.l %a2,%d3 /* restore d3 */ 372 | rts 373 | * 374 | *A in d0, B in d1, return A/B in d0, A%B in d1 375 | * 376 | i_ldiv: 377 | tst.l %d1 378 | bne nz1 379 | 380 | * divide by zero 381 | * divu #0,%d0 /* cause trap */ 382 | move.l #0x80000000,%d0 383 | move.l %d0,%d1 384 | rts 385 | nz1: 386 | move.l %d3,%a2 /* save d3 */ 387 | cmp.l %d1,%d0 388 | bhi norm 389 | beq is1 390 | * AB and B is not 0 402 | norm: 403 | cmp.l #1,%d1 404 | bne not1 405 | * B==1, so ret A, rem 0 406 | clr.l %d1 407 | move.l %a2,%d3 /* restore d3 */ 408 | rts 409 | * check for A short (implies B short also) 410 | not1: 411 | cmp.l #0xffff,%d0 412 | bhi slow 413 | * A short and B short -- use 'divu' 414 | divu %d1,%d0 /* d0 = REM:ANS */ 415 | swap %d0 /* d0 = ANS:REM */ 416 | clr.l %d1 417 | move.w %d0,%d1 /* d1 = REM */ 418 | clr.w %d0 419 | swap %d0 420 | move.l %a2,%d3 /* restore d3 */ 421 | rts 422 | * check for B short 423 | slow: 424 | cmp.l #0xffff,%d1 425 | bhi slower 426 | * A long and B short -- use special stuff from gnu 427 | move.l %d0,%d2 428 | clr.w %d2 429 | swap %d2 430 | divu %d1,%d2 /* d2 = REM:ANS of Ahi/B */ 431 | clr.l %d3 432 | move.w %d2,%d3 /* d3 = Ahi/B */ 433 | swap %d3 434 | 435 | move.w %d0,%d2 /* d2 = REM << 16 + Alo */ 436 | divu %d1,%d2 /* d2 = REM:ANS of stuff/B */ 437 | 438 | move.l %d2,%d1 439 | clr.w %d1 440 | swap %d1 /* d1 = REM */ 441 | 442 | clr.l %d0 443 | move.w %d2,%d0 444 | add.l %d3,%d0 /* d0 = ANS */ 445 | move.l %a2,%d3 /* restore d3 */ 446 | rts 447 | * A>B, B > 1 448 | slower: 449 | move.l #1,%d2 450 | clr.l %d3 451 | moreadj: 452 | cmp.l %d0,%d1 453 | bhs adj 454 | add.l %d2,%d2 455 | add.l %d1,%d1 456 | bpl moreadj 457 | * we shifted B until its >A or sign bit set 458 | * we shifted #1 (d2) along with it 459 | adj: 460 | cmp.l %d0,%d1 461 | bhi ltuns 462 | or.l %d2,%d3 463 | sub.l %d1,%d0 464 | ltuns: 465 | lsr.l #1,%d1 466 | lsr.l #1,%d2 467 | bne adj 468 | * d3=answer, d0=rem 469 | move.l %d0,%d1 470 | move.l %d3,%d0 471 | move.l %a2,%d3 /* restore d3 */ 472 | rts 473 | -------------------------------------------------------------------------------- /resources/build.bat: -------------------------------------------------------------------------------- 1 | %GDK_WIN%\bin\make -f %GDK_WIN%\makefile.gen %1 -------------------------------------------------------------------------------- /resources/ccppsettings.linuxgendev.template: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.default.includePath": ["{{env:GENDEV}}/sgdk/inc", 3 | "{{env:GENDEV}}/sgdk/res", 4 | "res", 5 | "inc" 6 | ] 7 | } -------------------------------------------------------------------------------- /resources/ccppsettings.linuxmarsdev.template: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.default.includePath": ["{{env:MARSDEV}}/sgdk/SGDK/inc", 3 | "{{env:MARSDEV}}/sgdk/SGDK/res", 4 | "res", 5 | "inc" 6 | ] 7 | } -------------------------------------------------------------------------------- /resources/ccppsettings.macossgdk.template: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.default.includePath": ["${env:GENDEV}/SGDK/inc", 3 | "${env:GENDEV}/SGDK/res", 4 | "res", 5 | "inc" 6 | ] 7 | } -------------------------------------------------------------------------------- /resources/ccppsettings.windowsmarsdev.template: -------------------------------------------------------------------------------- 1 | { 2 | "terminal.integrated.defaultProfile.windows": "Command Prompt", 3 | "C_Cpp.default.includePath": ["{{env:MARSDEV}}\\sgdk\\SGDK\\inc", 4 | "{{env:MARSDEV}}\\sgdk\\SGDK\\res", 5 | "res", 6 | "inc" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /resources/ccppsettings.windowssgdk.template: -------------------------------------------------------------------------------- 1 | { 2 | "terminal.integrated.defaultProfile.windows": "Command Prompt", 3 | "C_Cpp.default.includePath": ["{{env:GDK}}\\inc", 4 | "{{env:GDK}}\\res", 5 | "res", 6 | "inc" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /resources/codecompletion.json: -------------------------------------------------------------------------------- 1 | { 2 | "items": [ 3 | { 4 | "label": "BITMAP", 5 | "kind": "KEYWORD", 6 | "text": "BITMAP ", 7 | "doc": "Bitmapped image type resource, used for the Bitmap SGDK engine" 8 | }, 9 | { 10 | "label": "PALETTE", 11 | "kind": "KEYWORD", 12 | "text": "PALETTE ", 13 | "doc": "Palette type resource, used as color input for Bitmap, Image or Sprite resource." 14 | }, 15 | { 16 | "label": "TILESET", 17 | "kind": "KEYWORD", 18 | "text": "TILESET ", 19 | "doc": "Tileset type resource can be an image or a TSX file; contains tiles data which are used by Image or Sprite resource." 20 | }, 21 | { 22 | "label": "TILEMAP", 23 | "kind": "KEYWORD", 24 | "text": "TILEMAP ", 25 | "doc": "Tilemap type resource, contains raw tilemap data. It can be used to draw an image or complete (but small) plane background." 26 | }, 27 | { 28 | "label": "MAP", 29 | "kind": "KEYWORD", 30 | "text": "MAP ", 31 | "doc": "map type resource, internally contains Palette, Tileset and encoded map optimized to draw large background/plane." 32 | }, 33 | { 34 | "label": "IMAGE", 35 | "kind": "KEYWORD", 36 | "text": "IMAGE ", 37 | "doc": "image type resource, internally contains Palette, Tileset and Tilemap data and can be used to draw a complete background (small)" 38 | }, 39 | { 40 | "label": "SPRITE", 41 | "kind": "KEYWORD", 42 | "text": "SPRITE ", 43 | "doc": "Sprite type resource, used to handle sprites with the SGDK Sprite engine." 44 | }, 45 | { 46 | "label": "XGM", 47 | "kind": "KEYWORD", 48 | "text": "XGM ", 49 | "doc": "XGM music type resource (.vgm or .xgm file), used to play music." 50 | }, 51 | { 52 | "label": "XGM2", 53 | "kind": "KEYWORD", 54 | "text": "XGM2 ", 55 | "doc": "XGM2 music type resource (.vgm or .xgm file), for use to play music with the new XGM2 Driver." 56 | }, 57 | { 58 | "label": "WAV", 59 | "kind": "KEYWORD", 60 | "text": "WAV ", 61 | "doc": "WAV sound type resource (.wav file), used to play sample sound data." 62 | }, 63 | { 64 | "label": "BIN", 65 | "kind": "KEYWORD", 66 | "text": "BIN ", 67 | "doc": "Any binary data file which do not need any specific conversion or processing." 68 | }, 69 | { 70 | "label": "BEST", 71 | "kind": "PROPERTY", 72 | "text": "BEST ", 73 | "doc": "Uses Best Compresion" 74 | }, 75 | { 76 | "label": "AUTO", 77 | "kind": "PROPERTY", 78 | "text": "AUTO ", 79 | "doc": "Uses Auto Compresion. BEST by default if possible" 80 | }, 81 | { 82 | "label": "NONE", 83 | "kind": "PROPERTY", 84 | "text": "NONE ", 85 | "doc": "Don't use compression" 86 | }, 87 | { 88 | "label": "APLIB", 89 | "kind": "PROPERTY", 90 | "text": "APLIB ", 91 | "doc": "Use APLIB Compression (good compression ratio but slow)" 92 | }, 93 | { 94 | "label": "FAST", 95 | "kind": "PROPERTY", 96 | "text": "FAST ", 97 | "doc": "Use FAST Compression (average compression ratio but fast)" 98 | }, 99 | { 100 | "label": "LZ4W", 101 | "kind": "PROPERTY", 102 | "text": "LZ4W ", 103 | "doc": "Use LZ4W Compression (average compression ratio but fast)" 104 | }, 105 | { 106 | "label": "AUTO", 107 | "kind": "TEXT", 108 | "text": "AUTO ", 109 | "doc": "Auto Timming" 110 | }, 111 | { 112 | "label": "NTSC", 113 | "kind": "TEXT", 114 | "text": "NTSC ", 115 | "doc": "NTSC Timming" 116 | }, 117 | { 118 | "label": "PAL", 119 | "kind": "TEXT", 120 | "text": "PAL ", 121 | "doc": "PAL Timming" 122 | }, 123 | { 124 | "label": "ALL", 125 | "kind": "TEXT", 126 | "text": "ALL ", 127 | "doc": "Map Optimization ALL: find duplicate and flipped tile" 128 | }, 129 | { 130 | "label": "DUPLICATE", 131 | "kind": "TEXT", 132 | "text": "DUPLICATE ", 133 | "doc": "Map Optimization DUPLICATE: find duplicate only" 134 | }, 135 | { 136 | "label": "CIRCLE", 137 | "kind": "VARIABLE", 138 | "text": "CIRCLE ", 139 | "doc": "Circle collision" 140 | }, 141 | { 142 | "label": "BOX", 143 | "kind": "VARIABLE", 144 | "text": "BOX ", 145 | "doc": "Box collision" 146 | }, 147 | { 148 | "label": "NONE", 149 | "kind": "VARIABLE", 150 | "text": "NONE ", 151 | "doc": "No collision (default)" 152 | }, 153 | { 154 | "label": "BALANCED", 155 | "kind": "VARIABLE", 156 | "text": "BALANCED ", 157 | "doc": "Balanced Sprite Optimization: balance between used tiles and hardware sprites (default)." 158 | }, 159 | { 160 | "label": "TILE", 161 | "kind": "VARIABLE", 162 | "text": "TILE ", 163 | "doc": "reduce the number of tiles at the expense of more hardware sprite" 164 | }, 165 | { 166 | "label": "SPRITE", 167 | "kind": "VARIABLE", 168 | "text": "SPRITE ", 169 | "doc": "reduce the number of hardware sprite (using bigger sprite) at the expense of more used tiles" 170 | }, 171 | { 172 | "label": "PCM", 173 | "kind": "STRUCT", 174 | "text": "PCM ", 175 | "doc": "Single channel 8 bits signed sample driver." 176 | }, 177 | { 178 | "label": "2ADPCM", 179 | "kind": "STRUCT", 180 | "text": "2ADPCM ", 181 | "doc": "2 channels 4 bits ADPCM sample driver." 182 | }, 183 | { 184 | "label": "4PCM", 185 | "kind": "STRUCT", 186 | "text": "4PCM ", 187 | "doc": "4 channels 8 bits signed sample driver with volume support." 188 | }, 189 | { 190 | "label": "XGM", 191 | "kind": "STRUCT", 192 | "text": "XGM ", 193 | "doc": "XGM music with 4 channels 8 bits samples driver." 194 | }, 195 | { 196 | "label": "XGM2", 197 | "kind": "STRUCT", 198 | "text": "XGM2 ", 199 | "doc": "XGM2 new music Driver." 200 | }, 201 | { 202 | "label": "ALIGN", 203 | "kind": "KEYWORD", 204 | "text": "ALIGN ", 205 | "doc": "Align *binary* data for the *whole* resource file so you can have only ALIGN directive per resource (.res) file.\nALIGN function is useful when using bank switch for ROM larger than 4MB, it allows to avoid having a block of data crossing 2 data banks." 206 | }, 207 | { 208 | "label": "UNGROUP", 209 | "kind": "KEYWORD", 210 | "text": "UNGROUP ", 211 | "doc": "Using UNGROUP function allow to disable that feature, that might be useful to help in bank data separation when using the bank switch mechanism." 212 | }, 213 | { 214 | "label": "NONE", 215 | "kind": "STRUCT", 216 | "text": "NONE ", 217 | "doc": "no optimization (cover the whole sprite frame)" 218 | }, 219 | { 220 | "label": "ALIGN", 221 | "kind": "FUNCTION", 222 | "text": "ALIGN ", 223 | "doc": "align *binary* data for the whole resource file using" 224 | }, 225 | { 226 | "label": "UNGROUP", 227 | "kind": "FUNCTION", 228 | "text": "UNGROUP ", 229 | "doc": "by default rescomp will group data export by type, using UNGROUP allow to disable that feature." 230 | }, 231 | { 232 | "label": "ROW", 233 | "kind": "VARIABLE", 234 | "text": "ROW ", 235 | "doc": "Row ordering" 236 | }, 237 | { 238 | "label": "COLUMN", 239 | "kind": "VARIABLE", 240 | "text": "COLUMN ", 241 | "doc": "Column ordering" 242 | }, 243 | { 244 | "label": "TRUE", 245 | "kind": "VARIABLE", 246 | "text": "TRUE ", 247 | "doc": "True value" 248 | }, 249 | { 250 | "label": "FALSE", 251 | "kind": "VARIABLE", 252 | "text": "FALSE ", 253 | "doc": "False value" 254 | } 255 | 256 | ] 257 | } -------------------------------------------------------------------------------- /resources/gitignore.template: -------------------------------------------------------------------------------- 1 | out/ 2 | src/boot/ -------------------------------------------------------------------------------- /resources/gitkeep.template: -------------------------------------------------------------------------------- 1 | # delete this file after add content to the directory -------------------------------------------------------------------------------- /resources/headerfile.h.template: -------------------------------------------------------------------------------- 1 | //This file is generated from a TMX file using Genesis Code extension For vscode 2 | //for more info please see Genesis Code Web Page: https://zerasul.github.io/genesis-code-docs 3 | // Date: {{date}} 4 | // File: {{file}} 5 | 6 | #include 7 | 8 | #ifndef _TILEMAPSTRUCT 9 | 10 | #define _TILEMAPSTRUCT 0 11 | 12 | 13 | 14 | struct Layer 15 | { 16 | u16 id; 17 | char *name; 18 | u16 *data; 19 | u16 numData; 20 | }; 21 | 22 | struct Object 23 | { 24 | u16 id; 25 | u16 x; 26 | u16 y; 27 | u16 width; 28 | u16 height; 29 | }; 30 | 31 | struct ObjectGroup 32 | { 33 | u16 id; 34 | char * name; 35 | u8 numObjects; 36 | Object *objects; 37 | }; 38 | 39 | 40 | 41 | struct MapStruct 42 | { 43 | u16 width; 44 | u16 height; 45 | u16 tilewidth; 46 | u16 tilehegiht; 47 | u8 numLayers; 48 | Layer* layers; 49 | u8 numObjects; 50 | ObjectGroup* objectgroups; 51 | }{{file}}Map; 52 | 53 | #endif 54 | 55 | #ifndef _{{fileMap}} 56 | 57 | #define _{{fileMap}} 0 58 | 59 | void Init{{file}}MapInstance(MapStruct *mapstruct) 60 | { 61 | 62 | mapstruct->width={{width}}; 63 | mapstruct->height={{height}}; 64 | mapstruct->tilewidth={{tilewidth}}; 65 | mapstruct->tilehegiht={{tileheight}}; 66 | mapstruct->numLayers={{numLayers}}; 67 | 68 | Layer layers[{{numLayers}}]; 69 | 70 | //Layers 71 | {{LayerInfo}} 72 | 73 | mapstruct->layers=layers; 74 | 75 | //Objects 76 | 77 | mapstruct->numObjects={{numobjectgroups}}; 78 | 79 | {{ObjectInfo}} 80 | 81 | 82 | 83 | } 84 | #endif -------------------------------------------------------------------------------- /resources/imageviewer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 33 | 34 | 35 | 36 |

{{filename}}

37 |
38 |
39 | image 40 |
41 |
42 |
43 |

Image Details

44 |
    45 |
  • Width: {{width}} Pixels
  • 46 |
  • Height: {{height}} Pixels
  • 47 |
  • Tiles Width: {{tilesw}} Tiles
  • 48 |
  • Tiles Height: {{tilesh}} Tiles
  • 49 |
50 |

Image Palette

51 | Loading Palette... 52 |
53 |
54 |
55 | -------------------------------------------------------------------------------- /resources/language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | // symbol used for single line comment. Remove this entry if your language does not support line comments 4 | "lineComment": "#", 5 | }, 6 | // symbols that are auto closed when typing 7 | "autoClosingPairs": [ 8 | ["\"", "\""] 9 | ], 10 | "folding": { 11 | "markers": { 12 | "start": "(^\\s*#?region\\b)|(^\\s*#?pragma region\\b)", 13 | "end": "(^\\s*#?endregion\\b)|(^\\s*#?pragma endregion\\b)" 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /resources/launch.json.linuxmarsdev.template: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | { 9 | "name": "Debug with gdb remote", 10 | "request": "launch", 11 | "type": "cppdbg", 12 | "program": "${workspaceRoot}/out.elf", 13 | "sourceFileMap": { 14 | "d:\\apps\\sgdk\\src\\": "${env:HOME}/mars/sgdk/SGDK/src", 15 | }, 16 | "args": [], 17 | "stopAtEntry": true, 18 | "cwd": "${workspaceFolder}", 19 | "environment": [], 20 | "externalConsole": false, 21 | "MIMode": "gdb", 22 | "launchCompleteCommand": "exec-continue", 23 | "miDebuggerPath": "${env:HOME}/mars/m68k-elf/bin/m68k-elf-gdb", 24 | "miDebuggerArgs": "-ex \"target remote | blastem ${workspaceRoot}/out.bin -D \"", //change blastem with your emulator. 25 | "setupCommands": [ 26 | { 27 | "text": "set directories '${workspaceFolder};$cwd;$cdir'" 28 | } 29 | ] 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /resources/launch.json.macossgdk.template: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | { 9 | "name": "Debug with gdb remote", 10 | "request": "launch", 11 | "type": "cppdbg", 12 | "program": "${workspaceRoot}\\out\\rom.out", 13 | "miDebuggerServerAddress": "localhost:6868",//GensKMod debug port. Change it for use another ports 14 | "sourceFileMap": { 15 | "d:\\apps\\sgdk\\src\\": "${env:GDK}\\src\\", 16 | }, 17 | "args": [], 18 | "stopAtEntry": true, 19 | "cwd": "${workspaceFolder}", 20 | "environment": [], 21 | "externalConsole": false, 22 | "MIMode": "gdb", 23 | "launchCompleteCommand": "exec-continue", 24 | "miDebuggerPath": "WINEPREFIX=$GENDEV/wine wine cmd /C ${env:GDK}\\bin\\gdb.exe", 25 | "setupCommands": [ 26 | { 27 | "text": "set directories '${workspaceFolder};$cwd;$cdir'" 28 | } 29 | ] 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /resources/launch.json.windowsmarsdev.template: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | { 9 | "name": "Debug with gdb remote", 10 | "request": "launch", 11 | "type": "cppdbg", 12 | "program": "${workspaceRoot}\\out.bin", 13 | "sourceFileMap": { 14 | "d:\\apps\\sgdk\\src\\": "${env:MARSDEV}\\sgdk\\SGDK\\src\\", 15 | }, 16 | "args": [], 17 | "stopAtEntry": true, 18 | "cwd": "${workspaceFolder}", 19 | "environment": [], 20 | "externalConsole": false, 21 | "MIMode": "gdb", 22 | "launchCompleteCommand": "exec-continue", 23 | "miDebuggerPath": "${env:MARSDEV}\\m68k-elf\\bin\\m68k-elf-gdb.exe", 24 | "setupCommands": [ 25 | { 26 | "text": "set directories '${workspaceFolder};$cwd;$cdir'" 27 | } 28 | ] 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /resources/launch.json.windowssgdk.template: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | { 9 | "name": "Debug with gdb remote", 10 | "request": "launch", 11 | "type": "cppdbg", 12 | "program": "${workspaceRoot}\\out\\rom.out", 13 | "miDebuggerServerAddress": "localhost:6868",//GensKMod debug port. Change it for use another ports 14 | "sourceFileMap": { 15 | "d:\\apps\\sgdk\\src\\": "${env:GDK}\\src\\", 16 | }, 17 | "args": [], 18 | "stopAtEntry": true, 19 | "cwd": "${workspaceFolder}", 20 | "environment": [], 21 | "externalConsole": false, 22 | "MIMode": "gdb", 23 | "launchCompleteCommand": "exec-continue", 24 | "miDebuggerPath": "${env:GDK}\\bin\\gdb.exe", 25 | "setupCommands": [ 26 | { 27 | "text": "set directories '${workspaceFolder};$cwd;$cdir'" 28 | } 29 | ] 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /resources/mainc.template: -------------------------------------------------------------------------------- 1 | /** 2 | * Hello World Example 3 | * Created With Genesis-Code extension for Visual Studio Code 4 | * Use "Genesis Code: Compile" command to compile this program. 5 | **/ 6 | #include 7 | 8 | int main() 9 | { 10 | VDP_drawText("Hello Sega!!", 10,13); 11 | while(1) 12 | { 13 | //For versions prior to SGDK 1.60 use VDP_waitVSync instead. 14 | SYS_doVBlankProcess(); 15 | } 16 | return (0); 17 | } 18 | -------------------------------------------------------------------------------- /resources/res_grammar.json: -------------------------------------------------------------------------------- 1 | { 2 | "scopeName": "source.res", 3 | "patterns": [ 4 | { 5 | "include": "#resource" 6 | } 7 | ], 8 | "repository": { 9 | "resource": { 10 | "patterns": [ 11 | { 12 | "include": "#resourceType" 13 | }, 14 | { 15 | "include": "#resourceName" 16 | }, 17 | { 18 | "include": "#fileName" 19 | }, 20 | { 21 | "include": "#width" 22 | }, 23 | { 24 | "include": "#height" 25 | }, 26 | { 27 | "include": "#compression" 28 | }, 29 | { 30 | "include": "#regions" 31 | }, 32 | { 33 | "include": "#comment" 34 | }, 35 | { 36 | "include": "#timing" 37 | }, 38 | { 39 | "include": "#mapopt" 40 | }, 41 | { 42 | "include": "#mapbase" 43 | }, 44 | { 45 | "include": "#timesprt" 46 | }, 47 | { 48 | "include": "#collision" 49 | }, 50 | { 51 | "include": "#optsprt" 52 | }, 53 | { 54 | "include": "#opt_level" 55 | }, 56 | { 57 | "include": "#optionsxgm" 58 | }, 59 | { 60 | "include": "#drivername" 61 | }, 62 | { 63 | "include": "#outrate" 64 | }, 65 | { 66 | "include": "#align" 67 | }, 68 | { 69 | "include": "#tileset_id" 70 | }, 71 | { 72 | "include": "#ordering" 73 | }, 74 | { 75 | "include": "#export" 76 | } 77 | ] 78 | }, 79 | "resourceType": { 80 | "match": "BITMAP|PALETTE|TILESET|TILEMAP|MAP|IMAGE|SPRITE|XGM|XGM2|WAV|BIN|ALIGN|UNGROUP|NEAR", 81 | "name": "keyword.resourceType" 82 | }, 83 | "resourceName": { 84 | "match": "\\.", 85 | "name": "variable.parameter.resource.name" 86 | }, 87 | "tileset_id": { 88 | "match": "\\.", 89 | "name": "variable.parameter.resource.name" 90 | }, 91 | "fileName": { 92 | "begin": "\"", 93 | "end": "\"", 94 | "name": "string.quoted.doble.filename" 95 | }, 96 | "width": { 97 | "patterns": [ 98 | { 99 | "include": "#number" 100 | } 101 | ] 102 | }, 103 | "number": { 104 | "match": "([0-9]+\\\n)|(\\ +[0-9]+\\ )|(\t+[0-9]+\\ )|(\\ +[0-9]+\t)|(\t+[0-9]+\t)", 105 | "name": "constant.numeric.number" 106 | }, 107 | "height": { 108 | "patterns": [ 109 | { 110 | "include": "#number" 111 | } 112 | ] 113 | }, 114 | "compression": { 115 | "match": "BEST|AUTO|NONE|APLIB|FAST|LZ4W", 116 | "name": "keyword.control.compresion" 117 | }, 118 | "comment": { 119 | "begin": "\\#", 120 | "end": "\\\n", 121 | "name": "comment.line.number-sign" 122 | }, 123 | "regions": { 124 | "begin": "(\\#region)|(\\#endregion)|(\\#pragma region)|(\\#pragma endregion)", 125 | "end": "\\\n", 126 | "name": "markup.italic" 127 | }, 128 | "timing": { 129 | "match": "AUTO|NTSC|PAL", 130 | "name": "keyword.control.timing" 131 | }, 132 | "mapopt": { 133 | "match": "NONE|ALL|DUPLICATE", 134 | "name": "keyword.operator.mapopt" 135 | }, 136 | "mapbase": { 137 | "patterns": [ 138 | { 139 | "include": "#number" 140 | } 141 | ] 142 | }, 143 | "timesprt": { 144 | "patterns": [ 145 | { 146 | "include": "#number" 147 | } 148 | ] 149 | }, 150 | "collision": { 151 | "match": "CIRCLE|BOX", 152 | "name": "support.function.collision" 153 | }, 154 | "optsprt": { 155 | "match": "BALANCED|TILE|SPRITE|NONE", 156 | "name": "support.class.optsprt" 157 | }, 158 | "drivername": { 159 | "match": "PCM|2ADPCM|4PCM|XGM|XGM2", 160 | "name": "keyword.control.drivername" 161 | }, 162 | "outrate": { 163 | "patterns": [ 164 | { 165 | "include": "#number" 166 | } 167 | ] 168 | }, 169 | "opt_level": { 170 | "patterns": [ 171 | { 172 | "include": "#number" 173 | } 174 | ] 175 | }, 176 | "letters": { 177 | "match": "\\.", 178 | "name": "variable.parameter.letters" 179 | }, 180 | "optionsxgm": { 181 | "patterns": [ 182 | { 183 | "include": "#letters" 184 | } 185 | ] 186 | }, 187 | "ordering":{ 188 | "match": "ROW|COLUMN", 189 | "name": "keyword.control.ordering" 190 | }, 191 | "export":{ 192 | "match": "0|1|TRUE|FALSE", 193 | "name": "support.function.collision" 194 | } 195 | 196 | } 197 | } -------------------------------------------------------------------------------- /src/CoreEngine.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import { LINUX, MACOS, WIN32 } from './constants'; 3 | import { AppModelDarwin } from './IAppModelDarwin'; 4 | import { AppModelLinux } from './IAppModelLinux'; 5 | import { AppModelWin32 } from './IAppModelWin32'; 6 | 7 | 8 | export class CoreEngine { 9 | 10 | private internalCoreWin32: AppModelWin32; 11 | private internalCoreLinux: AppModelLinux; 12 | private internalCoreMacOs: AppModelDarwin; 13 | private platform: string; 14 | //Status Bar Buttons 15 | private static compileButton:vscode.StatusBarItem|undefined; 16 | private static compileAndRunButton:vscode.StatusBarItem|undefined; 17 | private static compileDebugButton:vscode.StatusBarItem|undefined; 18 | private static cleanButton:vscode.StatusBarItem|undefined; 19 | 20 | 21 | 22 | 23 | 24 | public constructor(extensionPath: string) { 25 | vscode.workspace.onDidChangeConfiguration((e) => { 26 | if (e.affectsConfiguration("addStatusBarButtons")) { 27 | //add status bar button to compile 28 | let statusButtonsAdded:boolean = vscode.workspace.getConfiguration().get("addStatusBarButtons",false); 29 | if(statusButtonsAdded){ 30 | this.addStatusBarButtons(); 31 | }else{ 32 | 33 | CoreEngine.compileButton?.dispose(); 34 | CoreEngine.compileAndRunButton?.dispose(); 35 | CoreEngine.compileDebugButton?.dispose(); 36 | CoreEngine.cleanButton?.dispose(); 37 | } 38 | } 39 | }); 40 | let statusButtonsAdded:boolean = vscode.workspace.getConfiguration().get("addStatusBarButtons",false); 41 | this.internalCoreWin32 = new AppModelWin32(extensionPath); 42 | this.internalCoreLinux = new AppModelLinux(extensionPath); 43 | this.internalCoreMacOs = new AppModelDarwin(extensionPath); 44 | this.platform = process.platform.toString(); 45 | if(statusButtonsAdded) this.addStatusBarButtons(); 46 | vscode.commands.registerCommand('genesis.compile', () => { this.compile(); }); 47 | vscode.commands.registerCommand('genesis.compileAndRun', () => { this.compileAndRun(); }); 48 | vscode.commands.registerCommand('genesis.compileDebug', () => { this.compile4Debug(); }); 49 | vscode.commands.registerCommand('genesis.clean', () => { this.clean(); }); 50 | 51 | } 52 | 53 | private addStatusBarButtons(){ 54 | //Compile status Bar Button 55 | CoreEngine.compileButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1); 56 | CoreEngine.compileButton.text = "$(gear) Build"; 57 | CoreEngine.compileButton.tooltip = "Compile Genesis Project"; 58 | CoreEngine.compileButton.command = "genesis.compile"; 59 | CoreEngine.compileButton.show(); 60 | 61 | //add status bar button to compile and run 62 | CoreEngine.compileAndRunButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 2); 63 | CoreEngine.compileAndRunButton.text = "$(play) Play"; 64 | CoreEngine.compileAndRunButton.tooltip = "Compile and Run Genesis Project"; 65 | CoreEngine.compileAndRunButton.color = "statusBarItem.warningBackground"; 66 | CoreEngine.compileAndRunButton.command = "genesis.compileAndRun"; 67 | CoreEngine.compileAndRunButton.show(); 68 | 69 | //add status bar to compile for debug 70 | CoreEngine.compileDebugButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 3); 71 | CoreEngine.compileDebugButton.text = "$(bug) Debug"; 72 | CoreEngine.compileDebugButton.tooltip = "Compile Genesis Project for Debugging"; 73 | CoreEngine.compileDebugButton.color = "statusBarItem.warningBackground"; 74 | CoreEngine.compileDebugButton.command = "genesis.compileDebug"; 75 | CoreEngine.compileDebugButton.show(); 76 | 77 | //add status bar button to clean project 78 | CoreEngine.cleanButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1); 79 | CoreEngine.cleanButton.text = "$(trashcan) Clean"; 80 | CoreEngine.cleanButton.tooltip = "Clean Genesis Project"; 81 | CoreEngine.cleanButton.command = "genesis.clean"; 82 | CoreEngine.cleanButton.show(); 83 | } 84 | public compile(): boolean { 85 | switch (this.platform) { 86 | case WIN32: 87 | return this.internalCoreWin32.compileProject(true); 88 | case LINUX: 89 | return this.internalCoreLinux.compileProject(true); 90 | case MACOS: 91 | return this.internalCoreMacOs.compileProject(true); 92 | default: 93 | this.showUndefinedSOError(); 94 | return false; 95 | 96 | } 97 | } 98 | 99 | private showUndefinedSOError() { 100 | vscode.window.showErrorMessage("Unsupported Operating System"); 101 | } 102 | public clean(): boolean { 103 | switch (this.platform) { 104 | case WIN32: 105 | return this.internalCoreWin32.cleanProject(); 106 | case LINUX: 107 | return this.internalCoreLinux.cleanProject(); 108 | case MACOS: 109 | return this.internalCoreMacOs.cleanProject(); 110 | default: 111 | this.showUndefinedSOError(); 112 | return false; 113 | } 114 | } 115 | 116 | public create(rootPath: vscode.Uri): vscode.Uri | undefined { 117 | switch (this.platform) { 118 | case WIN32: 119 | return this.internalCoreWin32.createProject(rootPath); 120 | case LINUX: 121 | return this.internalCoreLinux.createProject(rootPath); 122 | case MACOS: 123 | return this.internalCoreMacOs.createProject(rootPath); 124 | default: 125 | this.showUndefinedSOError(); 126 | return undefined; 127 | } 128 | } 129 | 130 | public compileAndRun(): boolean { 131 | switch (this.platform) { 132 | case WIN32: 133 | return this.internalCoreWin32.compileAndRunProject(); 134 | case LINUX: 135 | return this.internalCoreLinux.compileAndRunProject(); 136 | case MACOS: 137 | return this.internalCoreMacOs.compileAndRunProject(); 138 | default: 139 | this.showUndefinedSOError(); 140 | return false; 141 | } 142 | } 143 | 144 | public run(): boolean { 145 | switch (this.platform) { 146 | case WIN32: 147 | return this.internalCoreWin32.runProject(true); 148 | case LINUX: 149 | return this.internalCoreLinux.runProject(true); 150 | case MACOS: 151 | return this.internalCoreMacOs.runProject(true); 152 | default: 153 | this.showUndefinedSOError(); 154 | return false; 155 | } 156 | } 157 | 158 | public compile4Debug(): boolean { 159 | switch (this.platform) { 160 | case WIN32: 161 | return this.internalCoreWin32.compileForDebugging(); 162 | case LINUX: 163 | return this.internalCoreLinux.compileForDebugging(); 164 | case MACOS: 165 | return this.internalCoreMacOs.compileForDebugging(); 166 | default: 167 | this.showUndefinedSOError(); 168 | return false; 169 | } 170 | } 171 | 172 | public tmxImport(tmxFilePath: vscode.Uri) { 173 | this.internalCoreWin32.importTmxFile(tmxFilePath); 174 | } 175 | 176 | public tmxJsonImport(tmxJsonFilePath: vscode.Uri) { 177 | this.internalCoreWin32.importJsonTmxFile(tmxJsonFilePath); 178 | } 179 | 180 | public setRunPath(uri: string) { 181 | this.internalCoreWin32.setRunPath(uri); 182 | } 183 | 184 | public deactivate() { 185 | switch (this.platform) { 186 | case WIN32: 187 | this.internalCoreWin32.deactivate(); 188 | break; 189 | case LINUX: 190 | this.internalCoreLinux.deactivate(); 191 | break; 192 | case MACOS: 193 | this.internalCoreMacOs.deactivate(); 194 | break; 195 | default: 196 | this.showUndefinedSOError(); 197 | } 198 | } 199 | 200 | } -------------------------------------------------------------------------------- /src/IAppModel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * (C) 2020. This code is under MIT license. 3 | * You can get a copy of the license with this software. 4 | * For more information please see https://opensource.org/licenses/MIT 5 | */ 6 | import * as vscode from 'vscode'; 7 | import * as Path from 'path'; 8 | import { TmxJsonFileParser, TmxXMLParser } from './TmxParser'; 9 | 10 | 11 | /** 12 | * AppModel: abstract classs with all the minimum methods needed for genesis code extension. 13 | */ 14 | export abstract class AppModel{ 15 | 16 | 17 | 18 | /** 19 | * Terminal Object 20 | */ 21 | protected terminal: vscode.Terminal|null; 22 | /** 23 | * extension Path 24 | */ 25 | protected extensionPath: string; 26 | 27 | /** 28 | * class consctructor 29 | * @param extensionPath Extension Path 30 | */ 31 | constructor(extensionPath: string){ 32 | this.terminal=null; 33 | this.extensionPath=extensionPath; 34 | } 35 | 36 | protected getTerminal():vscode.Terminal{ 37 | if(this.terminal==null){ 38 | let terminals = vscode.window.terminals.filter(terminal => terminal.name === 'gens.code'); 39 | this.terminal= terminals.length>0?terminals[0]:vscode.window.createTerminal('gens.code'); 40 | } 41 | this.terminal.show(true); 42 | return this.terminal; 43 | } 44 | 45 | /** Clean the current Project (Depends from selected Toolchain configuration) */ 46 | public abstract cleanProject(): boolean; 47 | 48 | /** 49 | * Create a new Project 50 | * @param rootPath Project Location 51 | */ 52 | public abstract createProject(rootPath: vscode.Uri):vscode.Uri; 53 | 54 | /** 55 | * Compile the current project 56 | * @param newLine run the compile project with a new Line. 57 | */ 58 | public abstract compileProject(newLine:boolean, withArg:string):boolean; 59 | 60 | /** 61 | * Compile the project and run the rom in an emulator 62 | */ 63 | public abstract compileAndRunProject():boolean; 64 | 65 | /** 66 | * Set the Emulator Run Path 67 | * @param uri Emularor Run Path 68 | * @returns True if the command was succesful 69 | */ 70 | public setRunPath(uri: string):boolean{ 71 | vscode.workspace.getConfiguration().update("gens.path", uri, vscode.ConfigurationTarget.Global).then( 72 | r => { 73 | vscode.window.showInformationMessage("Updated gens command path Configuration"); 74 | }); 75 | return true; 76 | } 77 | 78 | /** 79 | * Run the current rom in an emulator 80 | * @param newLine Run the command in a new Line 81 | */ 82 | public abstract runProject(newLine:boolean):boolean; 83 | 84 | /** 85 | * Compile the project with debug flag 86 | */ 87 | public abstract compileForDebugging():boolean; 88 | 89 | /** 90 | * Import a new TMX file and generate a new .h file 91 | * @param tmxFilePath Tmx File path 92 | */ 93 | public importTmxFile(tmxFilePath: vscode.Uri) { 94 | let parser = new TmxXMLParser(); 95 | let tmx = parser.parseFile(tmxFilePath.fsPath); 96 | let currentdir = (vscode.workspace.workspaceFolders !== undefined) ? vscode.workspace.workspaceFolders[0].uri : undefined; 97 | if (currentdir !== undefined) { 98 | tmx.writeCHeaderFile(Path.join(currentdir.fsPath, "res"), Path.join(this.extensionPath, "resources", "headerfile.h.template")); 99 | } 100 | } 101 | 102 | /** 103 | * Import a new JSON TMX file and generate a new .h file 104 | * @param tmxJsonFilePath 105 | */ 106 | public importJsonTmxFile(tmxJsonFilePath: vscode.Uri) { 107 | let parser = new TmxJsonFileParser(); 108 | let tmx = parser.parseFile(tmxJsonFilePath.fsPath); 109 | let currentdir = (vscode.workspace.workspaceFolders !== undefined) ? vscode.workspace.workspaceFolders[0].uri : undefined; 110 | if (currentdir !== undefined) { 111 | tmx.writeCHeaderFile(Path.join(currentdir.fsPath, "res"), Path.join(this.extensionPath, "resources", "headerfile.h.template")); 112 | } 113 | } 114 | 115 | /** 116 | * Deactivate the extension 117 | */ 118 | public deactivate() { 119 | this.terminal?.dispose(); 120 | 121 | } 122 | 123 | 124 | 125 | } 126 | 127 | 128 | -------------------------------------------------------------------------------- /src/IAppModelDarwin.ts: -------------------------------------------------------------------------------- 1 | import path = require("path"); 2 | import * as vscode from "vscode"; 3 | import { DOCKER, DOCKERTAG, GENS_PATH, MAKEFILE, MARSDEV, MARSDEV_ENV, SGDK_GENDEV, TOOLCHAINTYPE, DORAGASU_IMAGE } from "./constants"; 4 | import { AppModel } from "./IAppModel"; 5 | import * as constants from "./constants"; 6 | import * as Path from "path"; 7 | import * as fs from "fs"; 8 | 9 | 10 | 11 | export class AppModelDarwin extends AppModel{ 12 | 13 | 14 | public cleanProject(): boolean { 15 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 16 | let makefile = vscode.workspace.getConfiguration().get(MAKEFILE); 17 | switch(toolchainType){ 18 | case SGDK_GENDEV: 19 | return this.cleanSGDKGenDev(); 20 | case MARSDEV: 21 | return this.cleanMarsDev(makefile); 22 | case DOCKER: 23 | return this.cleanDocker(); 24 | } 25 | return false; 26 | 27 | } 28 | private cleanSGDKGenDev(): boolean { 29 | let currentdir = (vscode.workspace.workspaceFolders !== undefined) ? vscode.workspace.workspaceFolders[0].uri : undefined; 30 | this.copybuildmacos(currentdir); 31 | this.getTerminal().sendText("WINEPREFIX=$GENDEV/wine wine64 cmd /C %cd%\\\\build.bat clean && ",false); 32 | this.getTerminal().sendText("echo 'This is a deprecated Feature. Change to Docker or Marsdev'"); 33 | return true; 34 | } 35 | private cleanMarsDev(makefile: unknown): boolean { 36 | this.setmarsdevenv(); 37 | let make = (makefile!=='')?`-f ${makefile}`: ' '; 38 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 39 | 40 | this.getTerminal().sendText(`make ${make} ${extraParams} clean`); 41 | return true; 42 | } 43 | private cleanDocker(): boolean { 44 | let tag = vscode.workspace.getConfiguration().get(DOCKERTAG); 45 | let dockerTag = tag !== "" ? tag : constants.SGDK_DEFAULT_DOCKER_IMAGE; 46 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 47 | let volumeInfo = this.buildVolumeInfo(); 48 | this.getTerminal().sendText(`docker run --rm -v ${volumeInfo} -u $(id -u):$(id -g) ${dockerTag} ${extraParams} clean`); 49 | return true; 50 | } 51 | 52 | 53 | private setmarsdevenv() { 54 | let marsdev = vscode.workspace.getConfiguration().get(MARSDEV_ENV); 55 | this.getTerminal().sendText("export MARSDEV=" + marsdev, true); 56 | } 57 | 58 | /** 59 | * copy the current build.bat program for run it with wine. 60 | * @param rootPath current main path 61 | */ 62 | private copybuildmacos(rootPath: vscode.Uri | undefined) { 63 | if (rootPath !== undefined) { 64 | if (!fs.existsSync(Path.join(rootPath.fsPath, "build.bat"))) { 65 | let buildbatpath = Path.join(this.extensionPath, "resources", "build.bat"); 66 | let buildcurrentpath = Path.join(rootPath.fsPath, "build.bat"); 67 | fs.copyFileSync(buildbatpath, buildcurrentpath); 68 | } 69 | } 70 | } 71 | 72 | public createProject(rootPath: vscode.Uri): vscode.Uri { 73 | let sourcepath = Path.join(rootPath.fsPath, "src"); 74 | if (!fs.existsSync(sourcepath)) { 75 | fs.mkdirSync(sourcepath); 76 | } 77 | let includePath = Path.join(rootPath.fsPath, "inc"); 78 | if (!fs.existsSync(includePath)) { 79 | fs.mkdirSync(includePath); 80 | // Added gitkeep files to show it on git repo 81 | let gitinckeep = Path.join(this.extensionPath, "resources", "gitkeep.template"); 82 | let gitinckeeppath = Path.join(rootPath.fsPath, "inc", ".gitkeep"); 83 | fs.copyFileSync(gitinckeep, gitinckeeppath); 84 | } 85 | let resourcePath = Path.join(rootPath.fsPath, "res"); 86 | if (!fs.existsSync(resourcePath)) { 87 | fs.mkdirSync(resourcePath); 88 | // Added gitkeep files to show it on git repo 89 | let gitreskeep = Path.join(this.extensionPath, "resources", "gitkeep.template"); 90 | let gitreskeeppath = Path.join(rootPath.fsPath, "res", ".gitkeep"); 91 | fs.copyFileSync(gitreskeep, gitreskeeppath); 92 | } 93 | //Add README.md File 94 | let readmetemppath = Path.join(this.extensionPath, "resources", "README.md.template"); 95 | let readmemdpath = Path.join(rootPath.fsPath, "README.MD"); 96 | fs.copyFileSync(readmetemppath, readmemdpath); 97 | //add .gitignorefile 98 | let ignoretemppath = Path.join(this.extensionPath, "resources", "gitignore.template"); 99 | let ignorepath = Path.join(rootPath.fsPath, ".gitignore"); 100 | fs.copyFileSync(ignoretemppath, ignorepath); 101 | //add main.c hello world Example 102 | let mainctemppath = Path.join(this.extensionPath, "resources", "mainc.template"); 103 | let maincpath = Path.join(rootPath.fsPath, "src", "main.c"); 104 | fs.copyFileSync(mainctemppath, maincpath); 105 | //add launch.json file with debuging configuration. 106 | let vscodedirpath = Path.join(rootPath.fsPath, ".vscode"); 107 | if (!fs.existsSync(vscodedirpath)) { 108 | fs.mkdirSync(vscodedirpath); 109 | this.createlaunchjsonFile(vscodedirpath,this.extensionPath); 110 | this.createsettingsjsonFile(vscodedirpath,this.extensionPath); 111 | } 112 | let makefiletemppath = Path.join(this.extensionPath, "resources", "Makefile.template"); 113 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 114 | if (toolchainType === MARSDEV) { 115 | fs.copyFileSync(makefiletemppath, Path.join(rootPath.fsPath, "Makefile")); 116 | //add boot directory 117 | fs.mkdirSync(Path.join(rootPath.fsPath, "boot")); 118 | fs.copyFileSync(Path.join(this.extensionPath, "resources", "boot", "sega.s.template"), Path.join(rootPath.fsPath, "boot", "sega.s")); 119 | fs.copyFileSync(Path.join(this.extensionPath, "resources", "boot", "rom_head.c.template"), Path.join(rootPath.fsPath, "boot", "rom_head.c")); 120 | } 121 | 122 | //add git repository to the project 123 | this.getTerminal().sendText("cd \"" + rootPath.fsPath + "\" && git init"); 124 | return rootPath; 125 | } 126 | private createsettingsjsonFile(vscodepath: string, extensionPath: string) { 127 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 128 | if (toolchainType === MARSDEV) { 129 | let sourcefile = Path.join(extensionPath, "resources", "ccppsettings.linuxmarsdev.template"); 130 | let fileContent:string = fs.readFileSync(sourcefile).toLocaleString(); 131 | let configGendev:string= vscode.workspace.getConfiguration().get(MARSDEV_ENV,"${env:MARSDEV}"); 132 | fileContent= fileContent.replace(/{{env:MARSDEV}}/g,configGendev); 133 | fs.writeFileSync(Path.join(vscodepath, "settings.json"),fileContent); 134 | } else if (toolchainType === SGDK_GENDEV || toolchainType===DOCKER) { 135 | let sourcefile = Path.join(extensionPath, "resources", "ccppsettings.macossgdk.template"); 136 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "settings.json")); 137 | } 138 | } 139 | private createlaunchjsonFile(vscodepath: string, extensionPath: string) { 140 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 141 | if (toolchainType === MARSDEV) { 142 | let sourcefile = Path.join(extensionPath, "resources", "launch.json.linuxmarsdev.template"); 143 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "launch.json")); 144 | } else if (toolchainType === SGDK_GENDEV || toolchainType===DOCKER) { 145 | let sourcefile = Path.join(extensionPath, "resources", "launch.json.macossgdk.template"); 146 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "launch.json")); 147 | } 148 | } 149 | public compileProject(newLine: boolean=true, withArg: string='release'): boolean { 150 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 151 | switch(toolchainType){ 152 | case SGDK_GENDEV: 153 | return this.compileProjectSGDK(newLine,withArg); 154 | case MARSDEV: 155 | return this.compileProjectMarsDev(newLine,withArg); 156 | case DOCKER: 157 | return this.compileProjectDocker(newLine,withArg); 158 | } 159 | 160 | return false; 161 | 162 | } 163 | private compileProjectSGDK(newLine: boolean, withArg: string): boolean { 164 | let currentdir = (vscode.workspace.workspaceFolders !== undefined) ? vscode.workspace.workspaceFolders[0].uri : undefined; 165 | this.copybuildmacos(currentdir); 166 | this.getTerminal().sendText(`WINEPREFIX=$GENDEV/wine wine64 cmd /C %cd%\\\\build.bat release ${withArg}`, false); 167 | this.getTerminal().sendText(" && echo 'This is a deprecated Feature. Change to Docker or Marsdev'", newLine); 168 | return true; 169 | } 170 | private compileProjectMarsDev(newLine: boolean, withArg: string): boolean { 171 | this.setmarsdevenv(); 172 | let makefile = vscode.workspace.getConfiguration().get(MAKEFILE); 173 | let mkfile = (makefile !== "") ? `-f ${makefile}` : " "; 174 | let parallelCompile = vscode.workspace.getConfiguration().get(constants.PARALEL_COMPILE,constants.PARALLEL_COMPILE_DEFAULT); 175 | 176 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 177 | this.getTerminal().sendText(`make ${mkfile} -j${parallelCompile} ${extraParams} clean ${withArg}`, newLine); 178 | return true; 179 | } 180 | private compileProjectDocker(newLine: boolean, withArg: string): boolean { 181 | let tag = vscode.workspace.getConfiguration().get(DOCKERTAG); 182 | let dockerTag = tag !== "" ? tag : constants.SGDK_DEFAULT_DOCKER_IMAGE; 183 | let volumeInfo = this.buildVolumeInfo(); 184 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 185 | this.getTerminal().sendText(`docker run --rm -v ${volumeInfo} -u $(id -u):$(id -g) ${dockerTag} ${extraParams} ${withArg}` , newLine); 186 | return true; 187 | } 188 | public compileAndRunProject(): boolean { 189 | this.compileProject(false, 'release'); 190 | this.getTerminal().sendText(" && "); 191 | return this.runProject(true); 192 | } 193 | public runProject(newLine: boolean): boolean { 194 | let genspath = vscode.workspace.getConfiguration().get(GENS_PATH); 195 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 196 | let romPath = (toolchainType=== MARSDEV)? "$PWD/rom.bin":"$PWD/out/rom.bin"; 197 | let command = `${genspath} "${romPath}"`; 198 | this.getTerminal().sendText(`${command} &`,newLine); 199 | return true; 200 | } 201 | public compileForDebugging(): boolean { 202 | return this.compileProject(true,'debug'); 203 | } 204 | 205 | private buildVolumeInfo():string{ 206 | let dogaratsu:boolean = vscode.workspace.getConfiguration().get(DORAGASU_IMAGE,false); 207 | let volumeInfo ="/src"; 208 | if(dogaratsu){ 209 | volumeInfo="/m68k -t"; 210 | } 211 | return `"$PWD":${volumeInfo}`; 212 | } 213 | 214 | } -------------------------------------------------------------------------------- /src/IAppModelLinux.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { DEFAULT_GENDEV_SGDK_MAKEFILE, DOCKER, DOCKERTAG, GENDEV_ENV, GENS_PATH, MAKEFILE, MARSDEV, MARSDEV_ENV, SGDK_GENDEV, TOOLCHAINTYPE, DORAGASU_IMAGE } from "./constants"; 3 | import { AppModel } from "./IAppModel"; 4 | import * as constants from "./constants"; 5 | import * as Path from 'path'; 6 | import * as fs from 'fs'; 7 | 8 | 9 | export class AppModelLinux extends AppModel{ 10 | 11 | 12 | public cleanProject(): boolean { 13 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 14 | let makefile = vscode.workspace.getConfiguration().get(MAKEFILE); 15 | switch(toolchainType){ 16 | case SGDK_GENDEV: 17 | return this.cleanProjectSgdk(makefile); 18 | case MARSDEV: 19 | return this.cleanProjectMarsDev(makefile); 20 | case DOCKER: 21 | return this.cleanProjectDocker(); 22 | default: 23 | return false; 24 | } 25 | 26 | 27 | } 28 | cleanProjectDocker(): boolean { 29 | let tag = vscode.workspace.getConfiguration().get(DOCKERTAG); 30 | let dockerTag = tag !== "" ? tag : constants.SGDK_DEFAULT_DOCKER_IMAGE; 31 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 32 | let volumeInfo = this.buildVolumeInfo(); 33 | this.getTerminal().sendText(`docker run --rm -v ${volumeInfo} -u $(id -u):$(id -g) ${dockerTag} ${extraParams} clean`); 34 | return true; 35 | } 36 | cleanProjectMarsDev(makefile:unknown): boolean { 37 | this.setmardevenv(); 38 | let mkfile = (makefile !== "") ? "-f " + makefile : " "; 39 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 40 | this.getTerminal().sendText(`make ${mkfile} ${extraParams} clean`); 41 | return true; } 42 | 43 | setmardevenv() { 44 | let marsdev = vscode.workspace.getConfiguration().get(MARSDEV_ENV); 45 | 46 | this.getTerminal().sendText(`export MARSDEV=${marsdev}`,true); 47 | } 48 | public createProject(rootPath: vscode.Uri): vscode.Uri { 49 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 50 | let sourcepath = Path.join(rootPath.fsPath, "src"); 51 | if (!fs.existsSync(sourcepath)) { 52 | fs.mkdirSync(sourcepath); 53 | } 54 | let includePath = Path.join(rootPath.fsPath, "inc"); 55 | if (!fs.existsSync(includePath)) { 56 | fs.mkdirSync(includePath); 57 | // Added gitkeep files to show it on git repo 58 | let gitinckeep = Path.join(this.extensionPath, "resources", "gitkeep.template"); 59 | let gitinckeeppath = Path.join(rootPath.fsPath, "inc", ".gitkeep"); 60 | fs.copyFileSync(gitinckeep, gitinckeeppath); 61 | } 62 | let resourcePath = Path.join(rootPath.fsPath, "res"); 63 | if (!fs.existsSync(resourcePath)) { 64 | fs.mkdirSync(resourcePath); 65 | // Added gitkeep files to show it on git repo 66 | let gitreskeep = Path.join(this.extensionPath, "resources", "gitkeep.template"); 67 | let gitreskeeppath = Path.join(rootPath.fsPath, "res", ".gitkeep"); 68 | fs.copyFileSync(gitreskeep, gitreskeeppath); 69 | } 70 | //Add README.md File 71 | let readmetemppath = Path.join(this.extensionPath, "resources", "README.md.template"); 72 | let readmemdpath = Path.join(rootPath.fsPath, "README.MD"); 73 | fs.copyFileSync(readmetemppath, readmemdpath); 74 | //add .gitignorefile 75 | let ignoretemppath = Path.join(this.extensionPath, "resources", "gitignore.template"); 76 | let ignorepath = Path.join(rootPath.fsPath, ".gitignore"); 77 | fs.copyFileSync(ignoretemppath, ignorepath); 78 | //add main.c hello world Example 79 | let mainctemppath = Path.join(this.extensionPath, "resources", "mainc.template"); 80 | let maincpath = Path.join(rootPath.fsPath, "src", "main.c"); 81 | fs.copyFileSync(mainctemppath, maincpath); 82 | //add launch.json file with debuging configuration. 83 | let vscodedirpath = Path.join(rootPath.fsPath, ".vscode"); 84 | if (!fs.existsSync(vscodedirpath)) { 85 | fs.mkdirSync(vscodedirpath); 86 | if (toolchainType === MARSDEV) { 87 | let sourcefile = Path.join(this.extensionPath, "resources", "launch.json.linuxmarsdev.template"); 88 | fs.copyFileSync(sourcefile, Path.join(vscodedirpath, "launch.json")); 89 | let settingssourcefile = Path.join(this.extensionPath, "resources", "ccppsettings.linuxmarsdev.template"); 90 | let fileContent:string = fs.readFileSync(settingssourcefile).toLocaleString(); 91 | let configGendev:string= vscode.workspace.getConfiguration().get(MARSDEV_ENV,"${env:MARSDEV}"); 92 | fileContent= fileContent.replace(/{{env:MARSDEV}}/g,configGendev); 93 | fs.writeFileSync(Path.join(vscodedirpath, "settings.json"),fileContent); 94 | } else if (toolchainType === SGDK_GENDEV || toolchainType===DOCKER) { 95 | let sourcefile = Path.join(this.extensionPath, "resources", "ccppsettings.linuxgendev.template"); 96 | let fileContent:string = fs.readFileSync(sourcefile).toLocaleString(); 97 | let configGendev:string= vscode.workspace.getConfiguration().get(GENDEV_ENV,"${env:GENDEV}"); 98 | fileContent= fileContent.replace(/{{env:GENDEV}}/g,configGendev); 99 | fs.writeFileSync(Path.join(vscodedirpath, "settings.json"),fileContent); 100 | } 101 | } 102 | let makefiletemppath = Path.join(this.extensionPath, "resources", "Makefile.template"); 103 | if (toolchainType === MARSDEV) { 104 | fs.copyFileSync(makefiletemppath, Path.join(rootPath.fsPath, "Makefile")); 105 | //add boot directory 106 | fs.mkdirSync(Path.join(rootPath.fsPath, "boot")); 107 | fs.copyFileSync(Path.join(this.extensionPath, "resources", "boot", "sega.s.template"), Path.join(rootPath.fsPath, "boot", "sega.s")); 108 | fs.copyFileSync(Path.join(this.extensionPath, "resources", "boot", "rom_head.c.template"), Path.join(rootPath.fsPath, "boot", "rom_head.c")); 109 | } 110 | 111 | //add git repository to the project 112 | this.getTerminal().sendText("cd \"" + rootPath.fsPath + "\" && git init"); 113 | return rootPath; 114 | } 115 | 116 | public compileProject(newLine: boolean=true, withArg: string="release"): boolean { 117 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 118 | let makefile:string = vscode.workspace.getConfiguration().get(MAKEFILE,DEFAULT_GENDEV_SGDK_MAKEFILE); 119 | switch(toolchainType){ 120 | case SGDK_GENDEV: 121 | return this.compilesgdk(newLine,withArg, makefile); 122 | case MARSDEV: 123 | return this.compileMarsDev(newLine,withArg,makefile); 124 | case DOCKER: 125 | return this.compileDocker(newLine, withArg); 126 | } 127 | return false; 128 | } 129 | compileDocker(newLine: boolean, withArg: string): boolean { 130 | let tag = vscode.workspace.getConfiguration().get(DOCKERTAG); 131 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 132 | 133 | let dockerTag = tag !== "" ? tag : constants.SGDK_DEFAULT_DOCKER_IMAGE; 134 | let volumeInfo = this.buildVolumeInfo(); 135 | this.getTerminal().sendText(`docker run --rm -v ${volumeInfo} -u $(id -u):$(id -g) ${dockerTag} ${extraParams} ${withArg}` , newLine); 136 | return true; 137 | } 138 | 139 | compileMarsDev(newLine: boolean=true, withArg: string, makefile:string): boolean { 140 | 141 | this.setmardevenv(); 142 | let mkfile = (makefile !== "") ? "-f " + makefile : " "; 143 | let parallelCompile = vscode.workspace.getConfiguration().get(constants.PARALEL_COMPILE,constants.PARALLEL_COMPILE_DEFAULT); 144 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 145 | this.getTerminal().sendText(`make ${mkfile} -j${parallelCompile} ${extraParams} clean ${withArg}`, newLine); 146 | return true; 147 | } 148 | 149 | compilesgdk(newLine: boolean, withArg: string, makefile:string): boolean { 150 | let gendev = vscode.workspace.getConfiguration().get(GENDEV_ENV); 151 | let parallelCompile = vscode.workspace.getConfiguration().get(constants.PARALEL_COMPILE,constants.PARALLEL_COMPILE_DEFAULT); 152 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 153 | if (gendev !== "") { 154 | this.getTerminal().sendText(`export GENDEV=${gendev}`, true); 155 | } 156 | let cmakefile = (makefile !== "") ? makefile : DEFAULT_GENDEV_SGDK_MAKEFILE; 157 | this.getTerminal().sendText(`make -f ${cmakefile} -j${parallelCompile} ${extraParams} ${withArg}`, newLine); 158 | return true; 159 | } 160 | public compileAndRunProject(): boolean { 161 | this.compileProject(false); 162 | this.getTerminal().sendText(" && "); 163 | this.runProject(true); 164 | return true; 165 | } 166 | public runProject(newLine: boolean): boolean { 167 | let genspath = vscode.workspace.getConfiguration().get(GENS_PATH); 168 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 169 | let romPath = (toolchainType=== MARSDEV)? "$PWD/rom.bin":"$PWD/out/rom.bin"; 170 | let command = `${genspath} "${romPath}"`; 171 | this.getTerminal().sendText(`${command} &`, newLine); 172 | return true; 173 | } 174 | public compileForDebugging(): boolean { 175 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 176 | if(toolchainType=== SGDK_GENDEV){ 177 | vscode.window.showErrorMessage("Toolchain SGDK/GENDEV can't compile for Debugging in Linux. Change to Marsdev or Docker on configuration."); 178 | return false; 179 | } 180 | return this.compileProject(true,"debug"); 181 | } 182 | 183 | private cleanProjectSgdk(makefile:unknown):boolean { 184 | let gendev = vscode.workspace.getConfiguration().get(GENDEV_ENV); 185 | if (gendev !== "") { 186 | this.getTerminal().sendText(`export GENDEV=${gendev}`, true); 187 | } 188 | //linux 189 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 190 | let cmakefile = (makefile !== "") ? makefile : DEFAULT_GENDEV_SGDK_MAKEFILE; 191 | this.getTerminal().sendText(`make -f ${cmakefile} ${extraParams} clean\n`); 192 | return true; } 193 | 194 | 195 | 196 | private buildVolumeInfo():string{ 197 | let dogaratsu:boolean = vscode.workspace.getConfiguration().get(DORAGASU_IMAGE,false); 198 | let volumeInfo ="/src"; 199 | if(dogaratsu){ 200 | volumeInfo="/m68k -t"; 201 | } 202 | return `"$PWD":${volumeInfo}`; 203 | } 204 | } 205 | 206 | 207 | -------------------------------------------------------------------------------- /src/IAppModelWin32.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { AppModel} from "./IAppModel"; 3 | import * as constants from "./constants"; 4 | import * as Path from 'path'; 5 | import * as fs from 'fs'; 6 | 7 | export class AppModelWin32 extends AppModel{ 8 | 9 | public compileProject(newLine: boolean=true, withArg:string='release'): boolean { 10 | let toolchainType = vscode.workspace.getConfiguration().get(constants.TOOLCHAINTYPE); 11 | switch(toolchainType){ 12 | case constants.SGDK_GENDEV: 13 | return this.compilesgdk(newLine,withArg); 14 | case constants.MARSDEV: 15 | return this.compileMarsdev(newLine,withArg); 16 | case constants.DOCKER: 17 | return this.compileDocker(newLine,withArg); 18 | default: 19 | return false; 20 | } 21 | } 22 | private compileDocker(newLine: boolean,withArg:string): boolean { 23 | let tag = vscode.workspace.getConfiguration().get(constants.DOCKERTAG); 24 | let dockerTag = tag !== "" ? tag : constants.SGDK_DEFAULT_DOCKER_IMAGE; 25 | let volumeInfo = this.buildVolumeInfo(); 26 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 27 | this.getTerminal().sendText(`docker run --rm -v ${volumeInfo} ${dockerTag} ${extraParams} ${withArg}` , newLine); 28 | return true; 29 | } 30 | private compileMarsdev(newLine: boolean, withArg:string): boolean { 31 | this.setMarsDevEnv(); 32 | let makefile = vscode.workspace.getConfiguration().get(constants.MAKEFILE); 33 | let parallelCompile = vscode.workspace.getConfiguration().get(constants.PARALEL_COMPILE,constants.PARALLEL_COMPILE_DEFAULT); 34 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 35 | this.getTerminal().sendText(`make ${makefile} -j${parallelCompile} ${extraParams} clean ${withArg}`, newLine); 36 | return true; 37 | } 38 | private compilesgdk(newLine: boolean, withArg:string): boolean { 39 | let makefile = vscode.workspace.getConfiguration().get(constants.MAKEFILE, constants.DEFAULT_WIN_SGDK_MAKEFILE); 40 | let gdk = vscode.workspace.getConfiguration().get(constants.GDK_ENV); 41 | let parallelCompile = vscode.workspace.getConfiguration().get(constants.PARALEL_COMPILE,constants.PARALLEL_COMPILE_DEFAULT); 42 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 43 | if(gdk!==""){ 44 | this.getTerminal().sendText("set GDK=" + gdk, true); 45 | } 46 | if(makefile===""){ 47 | makefile=constants.DEFAULT_WIN_SGDK_MAKEFILE; 48 | } 49 | this.getTerminal().sendText(`%GDK%\\bin\\make -f ${makefile} -j${parallelCompile} ${extraParams} ${withArg}`, newLine); 50 | return true; 51 | } 52 | public compileAndRunProject(): boolean { 53 | this.compileProject(false); 54 | this.getTerminal().sendText(" && ",false); 55 | return this.runProject(true); 56 | } 57 | public runProject(newLine: boolean): boolean { 58 | let genspath = vscode.workspace.getConfiguration().get(constants.GENS_PATH); 59 | let toolchainType = vscode.workspace.getConfiguration().get(constants.TOOLCHAINTYPE); 60 | let romPath = (toolchainType=== constants.MARSDEV)? "%CD%/rom.bin":"%CD%/out/rom.bin"; 61 | this.getTerminal().sendText(`START /B ${genspath} ${romPath}`); 62 | return true; 63 | } 64 | public compileForDebugging(): boolean { 65 | return this.compileProject(true,'debug'); 66 | } 67 | 68 | 69 | public createProject(rootPath: vscode.Uri): vscode.Uri { 70 | let sourcepath = Path.join(rootPath.fsPath, "src"); 71 | if (!fs.existsSync(sourcepath)) { 72 | fs.mkdirSync(sourcepath); 73 | } 74 | let includePath = Path.join(rootPath.fsPath, "inc"); 75 | if (!fs.existsSync(includePath)) { 76 | fs.mkdirSync(includePath); 77 | // Added gitkeep files to show it on git repo 78 | let gitinckeep = Path.join(this.extensionPath, "resources", "gitkeep.template"); 79 | let gitinckeeppath = Path.join(rootPath.fsPath, "inc", ".gitkeep"); 80 | fs.copyFileSync(gitinckeep, gitinckeeppath); 81 | } 82 | let resourcePath = Path.join(rootPath.fsPath, "res"); 83 | if (!fs.existsSync(resourcePath)) { 84 | fs.mkdirSync(resourcePath); 85 | // Added gitkeep files to show it on git repo 86 | let gitreskeep = Path.join(this.extensionPath, "resources", "gitkeep.template"); 87 | let gitreskeeppath = Path.join(rootPath.fsPath, "res", ".gitkeep"); 88 | fs.copyFileSync(gitreskeep, gitreskeeppath); 89 | } 90 | //Add README.md File 91 | let readmetemppath = Path.join(this.extensionPath, "resources", "README.md.template"); 92 | let readmemdpath = Path.join(rootPath.fsPath, "README.MD"); 93 | fs.copyFileSync(readmetemppath, readmemdpath); 94 | //add .gitignorefile 95 | let ignoretemppath = Path.join(this.extensionPath, "resources", "gitignore.template"); 96 | let ignorepath = Path.join(rootPath.fsPath, ".gitignore"); 97 | fs.copyFileSync(ignoretemppath, ignorepath); 98 | //add main.c hello world Example 99 | let mainctemppath = Path.join(this.extensionPath, "resources", "mainc.template"); 100 | let maincpath = Path.join(rootPath.fsPath, "src", "main.c"); 101 | fs.copyFileSync(mainctemppath, maincpath); 102 | //add launch.json file with debuging configuration. 103 | let vscodedirpath = Path.join(rootPath.fsPath, ".vscode"); 104 | if(!fs.existsSync(vscodedirpath)){ 105 | fs.mkdirSync(vscodedirpath); 106 | let sourcefile = Path.join(this.extensionPath, "resources", "launch.json.windowssgdk.template"); 107 | fs.copyFileSync(sourcefile, Path.join(vscodedirpath, "launch.json")); 108 | } 109 | //add marsdev makefile 110 | let toolchainType = vscode.workspace.getConfiguration().get(constants.TOOLCHAINTYPE); 111 | let sourcefile = Path.join(this.extensionPath, "resources", "ccppsettings.windowssgdk.template"); 112 | let configgdk:string= vscode.workspace.getConfiguration().get(constants.GDK_ENV,"${env:GDK}"); 113 | //clean path 114 | configgdk=configgdk.replace(/\\/g,"\\\\"); 115 | let fileContent:string = fs.readFileSync( sourcefile).toLocaleString(); 116 | if(toolchainType===constants.MARSDEV){ 117 | this.createMakefileMarsDev(rootPath); 118 | sourcefile = Path.join(this.extensionPath, "resources", "ccppsettings.windowsmarsdev.template"); 119 | fileContent= fs.readFileSync( sourcefile).toLocaleString(); 120 | configgdk= Path.parse(vscode.workspace.getConfiguration().get(constants.MARSDEV_ENV,"${env:MARSDEV}")).dir; 121 | configgdk=configgdk.replace(/\\/g,"\\\\"); 122 | 123 | fileContent=fileContent.replace(/{{env:MARSDEV}}/g,configgdk); 124 | }else{ 125 | fileContent=fileContent.replace(/{{env:GDK}}/g,configgdk); 126 | } 127 | //add settings.json 128 | //Write file using configuration instead environment variable 129 | fs.writeFileSync( Path.join(vscodedirpath, "settings.json"),fileContent); 130 | this.getTerminal().sendText(`cd "${rootPath.fsPath}" && git init`); 131 | return rootPath; 132 | } 133 | 134 | private createMakefileMarsDev(rootPath:vscode.Uri){ 135 | let makefiletemppath = Path.join(this.extensionPath, "resources", "Makefile.template"); 136 | 137 | fs.copyFileSync(makefiletemppath, Path.join(rootPath.fsPath, "Makefile")); 138 | //add boot directory 139 | fs.mkdirSync(Path.join(rootPath.fsPath, "boot")); 140 | fs.copyFileSync(Path.join(this.extensionPath, "resources", "boot", "sega.s.template"), Path.join(rootPath.fsPath, "boot", "sega.s")); 141 | fs.copyFileSync(Path.join(this.extensionPath, "resources", "boot", "rom_head.c.template"), Path.join(rootPath.fsPath, "boot", "rom_head.c")); 142 | } 143 | 144 | public cleanProject(): boolean { 145 | let toolchainType = vscode.workspace.getConfiguration().get(constants.TOOLCHAINTYPE); 146 | var makefile; 147 | 148 | switch(toolchainType){ 149 | 150 | case constants.SGDK_GENDEV: 151 | makefile = vscode.workspace.getConfiguration().get(constants.MAKEFILE, constants.DEFAULT_WIN_SGDK_MAKEFILE); 152 | return this.cleanProjectSgdk(makefile); 153 | case constants.MARSDEV: 154 | makefile = vscode.workspace.getConfiguration().get(constants.MAKEFILE); 155 | return this.cleanProjectMarsDev(makefile); 156 | case constants.DOCKER: 157 | return this.cleanProjectDocker(); 158 | default: 159 | return false; 160 | 161 | } 162 | 163 | } 164 | private cleanProjectDocker(): boolean { 165 | let tag = vscode.workspace.getConfiguration().get(constants.DOCKERTAG); 166 | let dockerTag = tag !== "" ? tag : constants.SGDK_DEFAULT_DOCKER_IMAGE;; 167 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 168 | let volumeInfo = this.buildVolumeInfo(); 169 | this.getTerminal().sendText(`docker run --rm -v ${volumeInfo} ${dockerTag} ${extraParams} clean` , true); 170 | return true; 171 | } 172 | 173 | private setMarsDevEnv(){ 174 | let marsdev = vscode.workspace.getConfiguration().get(constants.MARSDEV_ENV); 175 | this.getTerminal().sendText(`set MARSDEV=${marsdev}`, true); 176 | } 177 | private cleanProjectMarsDev(makefile: unknown): boolean { 178 | this.setMarsDevEnv(); 179 | let mkfile = (makefile !== "") ? "-f " + makefile : " "; 180 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 181 | this.getTerminal().sendText(`make ${mkfile} ${extraParams} clean`); 182 | return true; 183 | } 184 | 185 | private cleanProjectSgdk(makefile:string):boolean{ 186 | let gdk = vscode.workspace.getConfiguration().get(constants.GDK_ENV); 187 | let extraParams = vscode.workspace.getConfiguration().get(constants.EXTRA_PARAMETERS,""); 188 | if (gdk !== "") { 189 | this.getTerminal().sendText(`set GDK=${gdk}`, true); 190 | } 191 | let cmakefile = makefile !== "" ? makefile : constants.DEFAULT_WIN_SGDK_MAKEFILE; 192 | this.getTerminal().sendText(`%GDK%\\bin\\make -f ${cmakefile} ${extraParams} clean\n`); 193 | return true; 194 | } 195 | 196 | private buildVolumeInfo():string{ 197 | let dogaratsu:boolean = vscode.workspace.getConfiguration().get(constants.DORAGASU_IMAGE,false); 198 | let volumeInfo ="/src"; 199 | if(dogaratsu){ 200 | volumeInfo="/m68k -t"; 201 | } 202 | return `"%CD%":${volumeInfo}`; 203 | } 204 | 205 | 206 | 207 | } -------------------------------------------------------------------------------- /src/TmxParser.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * (C) 2020. This code is under MIT license. 3 | * You can get a copy of the license with this software. 4 | * For more information please see https://opensource.org/licenses/MIT 5 | */ 6 | 7 | import { XMLParser } from 'fast-xml-parser'; 8 | import * as fs from "fs"; 9 | import * as path from "path"; 10 | 11 | const LAYERTEMPLATE = 12 | "Layer mylayer{{index}};\n" + 13 | "mylayer{{index}}.id = {{layerid}};\n" + 14 | 'mylayer{{index}}.name = "{{name}}";\n' + 15 | "u16 mapdata{{index}}[{{numData}}]={{data}};\n" + 16 | "mylayer{{index}}.data = mapdata{{index}};\n" + 17 | "mylayer{{index}}.numData = {{numData}};\n" + 18 | "layers[{{index}}] = mylayer{{index}};\n"; 19 | 20 | const OBJECTTEMPLATE = 21 | "ObjectGroup myobjectgroup{{index}};\n" + 22 | "myobjectgroup{{index}}.id={{objectgropupid}};\n" + 23 | 'myobjectgroup{{index}}.name="{{objectgroupname}}";\n' + 24 | "myobjectgroup{{index}}.numObjects={{nobjs}};\n" + 25 | "objectgroups[{{index}}]=myobjectgroup{{index}};\n" + 26 | "Object myobjects{{index}}[{{nobjs}}];\n"; 27 | 28 | const OBJSTEMPLATE = 29 | "Object myobject{{index}};\n" + 30 | "myobject{{index}}.id={{objid}};\n" + 31 | "myobject{{index}}.x={{objx}};\n" + 32 | "myobject{{index}}.y={{objy}};\n" + 33 | "myobject{{index}}.width={{objwidth}};\n" + 34 | "myobject{{index}}.height={{objheight}};\n"; 35 | 36 | export abstract class TiledParser { 37 | public abstract parseFile(file: string): TMX; 38 | } 39 | 40 | /** 41 | * Class tmxParser: this class reads a TMX File and parse it into a C Header File. 42 | * 43 | * @copyright 2020 44 | * 45 | * @author Victor Suarez 46 | */ 47 | export class TmxXMLParser extends TiledParser { 48 | /** 49 | * Parse a TMX file and return the TMX information 50 | * @param file tmx file path 51 | * 52 | * @returns TMX Object Information 53 | */ 54 | public parseFile(file: string): TMX { 55 | let content = fs.readFileSync(file).toLocaleString(); 56 | let json = new XMLParser({ 57 | ignoreAttributes: false}).parse(content); 58 | //GetMapName 59 | let start = file.lastIndexOf(path.sep) + 1; 60 | let filename = file.substr(start, file.lastIndexOf(".") - start); 61 | let tmx = new TMXXmlFile(); 62 | tmx.map = json; 63 | tmx.file = filename; 64 | 65 | return tmx; 66 | } 67 | } 68 | 69 | export class TmxJsonFileParser extends TmxXMLParser { 70 | parseFile(file: string) { 71 | let content = fs.readFileSync(file).toLocaleString(); 72 | let json = JSON.parse(content); 73 | //GetMapName 74 | let start = file.lastIndexOf(path.sep) + 1; 75 | let filename = file.substr(start, file.lastIndexOf(".") - start); 76 | let tmx = new TMXJsonFile(); 77 | tmx.map = json; 78 | tmx.file = filename; 79 | return tmx; 80 | } 81 | } 82 | 83 | /** 84 | * Class TMX: TMX format information 85 | * 86 | * @copyright 2020 87 | * 88 | * @author Victor Suarez 89 | */ 90 | export abstract class TMX { 91 | protected _map: any; 92 | 93 | protected _file: string = ""; 94 | 95 | abstract get map(): any; 96 | abstract set map(v: any); 97 | abstract get file(): string; 98 | abstract set file(v: string); 99 | 100 | public abstract writeCHeaderFile( 101 | directoryPath: string, 102 | templatePath: string 103 | ): void; 104 | } 105 | 106 | export class TMXXmlFile extends TMX { 107 | public get map(): any { 108 | return this._map.map; 109 | } 110 | 111 | public set map(v: any) { 112 | this._map = v; 113 | } 114 | 115 | public get file(): string { 116 | return this._file; 117 | } 118 | 119 | public set file(v: string) { 120 | this._file = v; 121 | } 122 | 123 | public writeCHeaderFile(directoryPath: string, templatePath: string) { 124 | let strfile = fs.readFileSync(templatePath).toLocaleString(); 125 | let currdate = new Date(); 126 | let formatedDate = 127 | currdate.getFullYear() + 128 | "-" + 129 | (currdate.getMonth() + 1) + 130 | "-" + 131 | currdate.getDate(); 132 | let n: number = this.getLayerLength(); 133 | strfile = strfile 134 | .replace(/{{date}}/, formatedDate) 135 | .replace(/{{file}}/g, this.file) 136 | .replace(/{{fileMap}}/g, this.file.toUpperCase()) 137 | .replace(/{{width}}/g, this.map["@_width"]) 138 | .replace(/{{height}}/g, this.map["@_height"]) 139 | .replace(/{{tilewidth}}/g, this.map["@_tilewidth"]) 140 | .replace(/{{tileheight}}/g, this.map["@_tileheight"]) 141 | .replace(/{{numLayers}}/g, n.toString()); 142 | let strlayer = ""; 143 | for (let index = 0; index < n; index++) { 144 | let layer = this.getLayer(index); 145 | 146 | const { csv, numData } = this.getLayerData(layer); 147 | let curlayer = LAYERTEMPLATE.replace(/{{file}}/g, this.file) 148 | .replace(/{{layerid}}/g, layer["@_id"]) 149 | .replace(/{{name}}"/g, layer["@_name"]) 150 | .replace(/{{data}}/g, "{" + csv + "}") 151 | .replace(/{{numData}}/g, numData.toString()) 152 | .replace(/{{index}}/g, index.toString()); 153 | strlayer += curlayer; 154 | } 155 | 156 | strfile = strfile.replace(/{{LayerInfo}}/g, strlayer); 157 | 158 | let nobjgroups = this.map?.objectgroup?.length ?? 0; 159 | 160 | strfile = strfile.replace(/{{numobjectgroups}}/g, nobjgroups.toString()); 161 | let strobjgroup = ""; 162 | if (nobjgroups > 0) { 163 | strobjgroup += 164 | "ObjectGroup objectgroups[" + nobjgroups.toString() + "];\n"; 165 | for (let index = 0; index < nobjgroups; index++) { 166 | let nobjs = 1; 167 | let objgroup = this.map.objectgroup?.[index] ?? this.map.objectgroup; 168 | let curobjgroup = OBJECTTEMPLATE; 169 | curobjgroup = curobjgroup 170 | .replace(/{{index}}/g, index.toString()) 171 | .replace(/{{objectgropupid}}/g, objgroup["@_id"]) 172 | .replace(/{{objectgroupname}}/g, objgroup["@_name"]) 173 | .replace(/{{nobjs}}/g, nobjs.toString()); 174 | 175 | for (let index1 = 0; index1 < nobjs; index1++) { 176 | let obj = objgroup.object?.[index1] ?? objgroup.object; 177 | let curobj = OBJSTEMPLATE.replace(/{{index}}/g, index.toString()) 178 | .replace(/{{objid}}/g, obj["@_id"]) 179 | .replace(/{{objx}}/g, obj["@_x"]) 180 | .replace(/{{objy}}/g, obj["@_y"]) 181 | .replace(/{{objwidth}}/g, obj["@_width"]) 182 | .replace(/{{objheight}}/g, obj["@_height"]); 183 | let arrayobj = "myobjectgroup{{index}}.objects=myobjects{{index1}};\n" 184 | .replace(/{{index}}/g, index.toString()) 185 | .replace(/{{index1}}/g, index1.toString()); 186 | curobj += arrayobj; 187 | curobjgroup += curobj; 188 | } 189 | strobjgroup += curobjgroup; 190 | } 191 | strobjgroup += "mapstruct->objectgroups=objectgroups;\n"; 192 | } 193 | strfile = strfile.replace(/{{ObjectInfo}}/g, strobjgroup); 194 | fs.writeFileSync(path.join(directoryPath, this.file + "Map.h"), strfile, { 195 | flag: "w", 196 | }); 197 | } 198 | 199 | private getLayer(index: number) { 200 | return this.map.layer?.[index] ?? this.map.layer; 201 | } 202 | private getLayerData(layer: any) { 203 | let csv = ""; 204 | let numData = 1; 205 | if (layer.data["@_encoding"] === "csv") { 206 | csv = layer.data["#text"]; 207 | numData = layer.data["#text"].split(",").length; 208 | } else { 209 | //Base 64 210 | if (layer.data["@_encoding"] === "base64") { 211 | let buff = Buffer.from(layer.data["#text"], "base64"); 212 | for (let bufferIndex = 0; bufferIndex < buff.length; bufferIndex += 4) { 213 | csv += buff.readUInt32LE(bufferIndex) + ","; 214 | } 215 | csv = csv.substring(0, csv.lastIndexOf(",") - 2); 216 | numData = csv.split(",").length; 217 | } 218 | } 219 | return { csv, numData }; 220 | } 221 | private getLayerLength(): number { 222 | return this.map.layer?.length ?? 1; 223 | } 224 | } 225 | 226 | export class TMXJsonFile extends TMX { 227 | public get map(): any { 228 | return this._map; 229 | } 230 | 231 | public set map(v: any) { 232 | this._map = v; 233 | } 234 | 235 | public get file(): string { 236 | return this._file; 237 | } 238 | 239 | public set file(v: string) { 240 | this._file = v; 241 | } 242 | 243 | public writeCHeaderFile(directoryPath: string, templatePath: string): void { 244 | let strfile = fs.readFileSync(templatePath).toLocaleString(); 245 | let currdate = new Date(); 246 | let formatedDate = 247 | currdate.getFullYear() + 248 | "-" + 249 | (currdate.getMonth() + 1) + 250 | "-" + 251 | currdate.getDate(); 252 | strfile = strfile 253 | .replace(/{{date}}/, formatedDate) 254 | .replace(/{{file}}/g, this.file) 255 | .replace(/{{fileMap}}/g, this.file.toUpperCase()) 256 | .replace(/{{width}}/g, this.map.width) 257 | .replace(/{{height}}/g, this.map.height) 258 | .replace(/{{tilewidth}}/g, this.map.tilewidth) 259 | .replace(/{{tileheight}}/g, this.map.tileheight) 260 | .replace(/{{numLayers}}/g, this.map.layers.length.toString()); 261 | let strlayer = ""; 262 | for (let index = 0; index < this.map.layers.length; index++) { 263 | let layer = this.map.layers[index]; 264 | 265 | const { csv, numData } = this.getLayerData(layer); 266 | let curlayer = LAYERTEMPLATE.replace(/{{file}}/g, this.file) 267 | .replace(/{{layerid}}/g, layer.id) 268 | .replace(/{{name}}/g, layer.name) 269 | .replace(/{{data}}/g, `{${csv ?? ""}}`) 270 | .replace(/{{numData}}/g, numData.toString()) 271 | .replace(/{{index}}/g, index.toString()); 272 | strlayer += curlayer; 273 | } 274 | 275 | strfile = strfile 276 | .replace(/{{LayerInfo}}/g, strlayer) 277 | .replace(/{{numobjectgroups}}/g, "0") 278 | .replace(/{{ObjectInfo}}/g, ""); 279 | 280 | fs.writeFileSync(path.join(directoryPath, this.file + "Map.h"), strfile, { 281 | flag: "w", 282 | }); 283 | } 284 | private getLayerData(layer: any) { 285 | let numData = 0; 286 | let csv: string | null = ""; 287 | if (layer.data === undefined){ return { csv: null, numData };} 288 | //CSV 289 | if (layer.encoding === "csv" || layer.encoding === undefined) { 290 | for (const layerData of layer.data) { 291 | csv += layerData.toString() + ","; 292 | } 293 | csv = csv.substring(0, csv.lastIndexOf(",")); 294 | numData = layer.data.length; 295 | } else if (layer.encoding === "base64") { 296 | let buff = Buffer.from(layer.data, "base64"); 297 | for (let bufferIndex = 0; bufferIndex < buff.length; bufferIndex += 4) { 298 | csv += buff.readUInt32LE(bufferIndex) + ","; 299 | } 300 | csv = csv.substring(0, csv.lastIndexOf(",") - 2); 301 | numData = csv.split(",").length; 302 | } 303 | 304 | return { csv, numData }; 305 | } 306 | } 307 | -------------------------------------------------------------------------------- /src/appModel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * (C) 2020. This code is under MIT license. 3 | * You can get a copy of the license with this software. 4 | * For more information please see https://opensource.org/licenses/MIT 5 | */ 6 | import * as vscode from 'vscode'; 7 | import * as Path from 'path'; 8 | import * as fs from 'fs'; 9 | import { TmxXMLParser, TmxJsonFileParser } from './TmxParser'; 10 | 11 | /** 12 | * Configuration key for toolchaintype 13 | */ 14 | export const TOOLCHAINTYPE = "toolchainType"; 15 | 16 | /** 17 | * Configuration key for custom makefile 18 | */ 19 | export const MAKEFILE = "custom-makefile"; 20 | 21 | /** 22 | * Configuration key for MARSDEV 23 | */ 24 | export const MARSDEV_ENV = "MARSDEV"; 25 | 26 | /** 27 | * configuration key for GENDEV 28 | */ 29 | export const GENDEV_ENV = "GENDEV"; 30 | 31 | /** 32 | * configuration key for GDK 33 | */ 34 | export const GDK_ENV = "GDK"; 35 | 36 | /** 37 | * Use of SGDK or GENDEV toolchains 38 | */ 39 | export const SGDK_GENDEV = "sgdk/gendev"; 40 | 41 | /** 42 | * Use of MARSDEV toolchain 43 | */ 44 | export const MARSDEV = "marsdev"; 45 | 46 | /** 47 | * Use of Docker toolchain 48 | */ 49 | const DOCKER = "docker"; 50 | 51 | /** 52 | * Use tag value for a docker 53 | */ 54 | const DOCKERTAG = "dockerTag"; 55 | 56 | /** 57 | * DEFAULT MAKEFILE for Windows Systems 58 | */ 59 | const DEFAULT_WIN_SGDK_MAKEFILE = "%GDK%\\makefile.gen"; 60 | 61 | /** 62 | * DEFAULT MAKEFILE for GenDev Systems 63 | */ 64 | const DEFAULT_GENDEV_SGDK_MAKEFILE = "$GENDEV/sgdk/mkfiles/makefile.gen"; 65 | 66 | 67 | 68 | /** 69 | * AppModel class; this class have all the internalFunctionality for use with SGDK tasks. 70 | */ 71 | export class AppModel { 72 | 73 | 74 | // Terminal opened for use with SGDK 75 | terminal: vscode.Terminal; 76 | statusBar: vscode.StatusBarItem | undefined; 77 | extensionPath: string; 78 | 79 | /** 80 | * class constructor 81 | * @param extensionPath extension Path 82 | */ 83 | constructor(extensionPath: string) { 84 | this.terminal = vscode.window.createTerminal('gens-code'); 85 | this.terminal.show(); 86 | this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1); 87 | this.statusBar.text = "Genesis Code Ready"; 88 | this.statusBar.show(); 89 | this.extensionPath = extensionPath; 90 | } 91 | 92 | /** 93 | * Clean the project calling the SGDK make clean command (using SGDK or GENDEV) 94 | * @returns true if success or false otherwise 95 | */ 96 | public cleanProject(): boolean { 97 | console.log(process.platform.toString()); 98 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 99 | let makefile = vscode.workspace.getConfiguration().get(MAKEFILE); 100 | 101 | if (toolchainType === SGDK_GENDEV) { 102 | if (process.platform.toString() === 'win32') { 103 | return this.cleanProject4Win32(makefile); 104 | } else if (process.platform.toString() === 'linux') { 105 | return this.cleanProject4Linux(makefile); 106 | } else if (process.platform.toString() === 'darwin') { 107 | return this.cleanProject4Mac(); 108 | } else { 109 | vscode.window.showWarningMessage("Operating System not yet supported"); 110 | return false; 111 | } 112 | } else { 113 | this.setmardevenv(process.platform.toString()); 114 | let mkfile = (makefile !== "") ? "-f " + makefile : " "; 115 | this.terminal.sendText("make " + mkfile + " clean"); 116 | return true; 117 | } 118 | 119 | } 120 | private cleanProject4Mac() { 121 | let gdk = vscode.workspace.getConfiguration().get(GDK_ENV); 122 | if (gdk !== "") { 123 | this.terminal.sendText("set GDK_WIN=" + gdk, true); 124 | } 125 | // MacOs using Wine 126 | //first check if the build.bat file is created 127 | let currentdir = (vscode.workspace.workspaceFolders !== undefined) ? vscode.workspace.workspaceFolders[0].uri : undefined; 128 | this.copybuildmacos(currentdir); 129 | this.terminal.sendText("WINEPREFIX=$GENDEV/wine wine64 cmd /C %cd%\\\\build.bat clean"); 130 | 131 | return true; 132 | } 133 | 134 | private cleanProject4Linux(makefile: unknown) { 135 | let gendev = vscode.workspace.getConfiguration().get(GENDEV_ENV); 136 | if (gendev !== "") { 137 | this.terminal.sendText("export GENDEV=" + gendev, true); 138 | } 139 | //linux 140 | let cmakefile = (makefile !== "") ? makefile : DEFAULT_GENDEV_SGDK_MAKEFILE; 141 | this.terminal.sendText("make -f " + cmakefile + " clean\n"); 142 | return true; 143 | } 144 | 145 | private cleanProject4Win32(makefile:unknown) { 146 | //Windows 147 | let gdk = vscode.workspace.getConfiguration().get(GDK_ENV); 148 | if (gdk !== "") { 149 | this.terminal.sendText("set GDK=" + gdk, true); 150 | } 151 | let cmakefile = makefile !== "" ? makefile : DEFAULT_WIN_SGDK_MAKEFILE; 152 | this.terminal.sendText("%GDK%\\bin\\make -f " + cmakefile + " clean\n"); 153 | 154 | return true; 155 | } 156 | /** 157 | * set the MARSDEV environment variable (using configuration info) 158 | * @param os operating system 159 | */ 160 | private setmardevenv(os: string) { 161 | let marsdev = vscode.workspace.getConfiguration().get(MARSDEV_ENV); 162 | if (os === "win32") { 163 | this.terminal.sendText("set MARSDEV=" + marsdev, true); 164 | } else { 165 | if (os === "linux" || os === "darwin") { 166 | this.terminal.sendText("export MARSDEV=" + marsdev, true); 167 | } 168 | } 169 | } 170 | 171 | /** 172 | * copy the current build.bat program for run it with wine. 173 | * @param rootPath current main path 174 | */ 175 | private copybuildmacos(rootPath: vscode.Uri | undefined) { 176 | if (rootPath !== undefined) { 177 | if (!fs.existsSync(Path.join(rootPath.fsPath, "build.bat"))) { 178 | let buildbatpath = Path.join(this.extensionPath, "resources", "build.bat"); 179 | let buildcurrentpath = Path.join(rootPath.fsPath, "build.bat"); 180 | fs.copyFileSync(buildbatpath, buildcurrentpath); 181 | } 182 | } 183 | } 184 | /** 185 | * Create a new Project for SGDK. Create on a specific folder, three subfolders called _src_, _inc_ and _res_. 186 | * @param projectPath Root Path for the project 187 | * @returns Initial Project folder 188 | */ 189 | public createProject(rootPath: vscode.Uri) { 190 | let sourcepath = Path.join(rootPath.fsPath, "src"); 191 | if (!fs.existsSync(sourcepath)) { 192 | fs.mkdirSync(sourcepath); 193 | } 194 | let includePath = Path.join(rootPath.fsPath, "inc"); 195 | if (!fs.existsSync(includePath)) { 196 | fs.mkdirSync(includePath); 197 | // Added gitkeep files to show it on git repo 198 | let gitinckeep = Path.join(this.extensionPath, "resources", "gitkeep.template"); 199 | let gitinckeeppath = Path.join(rootPath.fsPath, "inc", ".gitkeep"); 200 | fs.copyFileSync(gitinckeep, gitinckeeppath); 201 | } 202 | let resourcePath = Path.join(rootPath.fsPath, "res"); 203 | if (!fs.existsSync(resourcePath)) { 204 | fs.mkdirSync(resourcePath); 205 | // Added gitkeep files to show it on git repo 206 | let gitreskeep = Path.join(this.extensionPath, "resources", "gitkeep.template"); 207 | let gitreskeeppath = Path.join(rootPath.fsPath, "res", ".gitkeep"); 208 | fs.copyFileSync(gitreskeep, gitreskeeppath); 209 | } 210 | //Add README.md File 211 | let readmetemppath = Path.join(this.extensionPath, "resources", "README.md.template"); 212 | let readmemdpath = Path.join(rootPath.fsPath, "README.MD"); 213 | fs.copyFileSync(readmetemppath, readmemdpath); 214 | //add .gitignorefile 215 | let ignoretemppath = Path.join(this.extensionPath, "resources", "gitignore.template"); 216 | let ignorepath = Path.join(rootPath.fsPath, ".gitignore"); 217 | fs.copyFileSync(ignoretemppath, ignorepath); 218 | //add main.c hello world Example 219 | let mainctemppath = Path.join(this.extensionPath, "resources", "mainc.template"); 220 | let maincpath = Path.join(rootPath.fsPath, "src", "main.c"); 221 | fs.copyFileSync(mainctemppath, maincpath); 222 | //add launch.json file with debuging configuration. 223 | let vscodedirpath = Path.join(rootPath.fsPath, ".vscode"); 224 | if (!fs.existsSync(vscodedirpath)) { 225 | fs.mkdirSync(vscodedirpath); 226 | this.createlaunchjsonfile(this.extensionPath, vscodedirpath); 227 | } 228 | //add Makefile for marsdev toolchain projects 229 | let makefiletemppath = Path.join(this.extensionPath, "resources", "Makefile.template"); 230 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 231 | if (toolchainType === MARSDEV) { 232 | fs.copyFileSync(makefiletemppath, Path.join(rootPath.fsPath, "Makefile")); 233 | //add boot directory 234 | fs.mkdirSync(Path.join(rootPath.fsPath, "boot")); 235 | fs.copyFileSync(Path.join(this.extensionPath, "resources", "boot", "sega.s.template"), Path.join(rootPath.fsPath, "boot", "sega.s")); 236 | fs.copyFileSync(Path.join(this.extensionPath, "resources", "boot", "rom_head.c.template"), Path.join(rootPath.fsPath, "boot", "rom_head.c")); 237 | } 238 | //add settings.json with the include paths. 239 | this.createSettingsJsonFile(this.extensionPath, vscodedirpath); 240 | //add git repository to the project 241 | this.terminal.sendText("cd \"" + rootPath.fsPath + "\" && git init"); 242 | return rootPath; 243 | } 244 | 245 | /** 246 | * Add a launch.json file with the debug task configuration. 247 | * 248 | * NOTE: on Linux Systems with SGDK/GENDEV toolchain the file is not created. 249 | * @param extensionPath Extension Folder Path. 250 | * @param vscodepath .voscodepath folder path. 251 | */ 252 | private createlaunchjsonfile(extensionPath: string, vscodepath: string) { 253 | let platform = process.platform.toString(); 254 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 255 | if (platform === 'win32') { 256 | if (toolchainType === SGDK_GENDEV) { 257 | let sourcefile = Path.join(extensionPath, "resources", "launch.json.windowssgdk.template"); 258 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "launch.json")); 259 | } else if (toolchainType === MARSDEV) { 260 | let sourcefile = Path.join(extensionPath, "resources", "launch.json.windowsmarsdev.template"); 261 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "launch.json")); 262 | } 263 | } else if (platform === 'linux') { 264 | if (toolchainType === MARSDEV) { 265 | let sourcefile = Path.join(extensionPath, "resources", "launch.json.linuxmarsdev.template"); 266 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "launch.json")); 267 | } 268 | } else if (platform === 'darwin') { 269 | if (toolchainType === MARSDEV) { 270 | let sourcefile = Path.join(extensionPath, "resources", "launch.json.linuxmarsdev.template"); 271 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "launch.json")); 272 | } else if (toolchainType === SGDK_GENDEV) { 273 | let sourcefile = Path.join(extensionPath, "resources", "launch.json.macossgdk.template"); 274 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "launch.json")); 275 | } 276 | } 277 | } 278 | 279 | private createSettingsJsonFile(extensionPath: string, vscodepath: string) { 280 | let platform = process.platform.toString(); 281 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 282 | if (platform === 'win32') { 283 | if (toolchainType === MARSDEV) { 284 | let sourcefile = Path.join(extensionPath, "resources", "ccppsettings.windowsmarsdev.template"); 285 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "settings.json")); 286 | } else if (toolchainType === SGDK_GENDEV) { 287 | let sourcefile = Path.join(extensionPath, "resources", "ccppsettings.windowssgdk.template"); 288 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "settings.json")); 289 | } 290 | } else if (platform === 'linux') { 291 | if (toolchainType === MARSDEV) { 292 | let sourcefile = Path.join(extensionPath, "resources", "ccppsettings.linuxmarsdev.template"); 293 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "settings.json")); 294 | } else if (toolchainType === SGDK_GENDEV) { 295 | let sourcefile = Path.join(extensionPath, "resources", "ccppsettings.linuxgendev.template"); 296 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "settings.json")); 297 | } 298 | } else if (platform === 'darwin') { 299 | if (toolchainType === MARSDEV) { 300 | let sourcefile = Path.join(extensionPath, "resources", "ccppsettings.linuxmarsdev.template"); 301 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "settings.json")); 302 | } else if (toolchainType === SGDK_GENDEV) { 303 | let sourcefile = Path.join(extensionPath, "resources", "ccppsettings.macossgdk.template"); 304 | fs.copyFileSync(sourcefile, Path.join(vscodepath, "settings.json")); 305 | } 306 | } 307 | } 308 | 309 | /** 310 | * Run the compile command on windows systems 311 | * @param newline add a newline at the end of the command. 312 | */ 313 | private compileWindowsProject(newline: boolean = true): boolean { 314 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 315 | let makefile = vscode.workspace.getConfiguration().get(MAKEFILE); 316 | let gdk = vscode.workspace.getConfiguration().get(GDK_ENV); 317 | let tag = vscode.workspace.getConfiguration().get(DOCKERTAG); 318 | 319 | if (toolchainType === SGDK_GENDEV) { 320 | let cmakefile = (makefile !== "") ? makefile : DEFAULT_WIN_SGDK_MAKEFILE; 321 | if (gdk !== "") { 322 | this.terminal.sendText("set GDK=" + gdk, true); 323 | } 324 | this.terminal.sendText("%GDK%\\bin\\make -f " + cmakefile, newline); 325 | } else if (toolchainType === MARSDEV) { 326 | this.setmardevenv(process.platform.toString()); 327 | let mkfile = (makefile !== "") ? "-f " + makefile : " "; 328 | this.terminal.sendText("make " + mkfile + " clean release", newline); 329 | 330 | } else if (toolchainType === DOCKER) { 331 | let dockerTag = tag !== "" ? tag : "sgdk"; 332 | this.terminal.sendText("docker run --rm -v \"$PWD\":/src -u $(id -u):$(id -g) "+dockerTag , newline); 333 | } 334 | 335 | return true; 336 | } 337 | 338 | /** 339 | * Run the compile command on Linux systems 340 | * @param newline add a newline at the end of the command. 341 | */ 342 | private compileLinuxProject(newline: boolean = true): boolean { 343 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 344 | let makefile = vscode.workspace.getConfiguration().get(MAKEFILE); 345 | let tag = vscode.workspace.getConfiguration().get(DOCKERTAG); 346 | if (toolchainType === SGDK_GENDEV) { 347 | let gendev = vscode.workspace.getConfiguration().get(GENDEV_ENV); 348 | if (gendev !== "") { 349 | this.terminal.sendText("export GENDEV=" + gendev, true); 350 | } 351 | let cmakefile = (makefile !== "") ? makefile : DEFAULT_GENDEV_SGDK_MAKEFILE; 352 | this.terminal.sendText("make -f " + cmakefile, newline); 353 | } else if (toolchainType === MARSDEV) { 354 | this.setmardevenv(process.platform.toString()); 355 | let mkfile = (makefile !== "") ? "-f " + makefile : " "; 356 | this.terminal.sendText("make " + mkfile + " clean release", newline); 357 | 358 | } else if (toolchainType === DOCKER) { 359 | let dockerTag = tag !== "" ? tag : "sgdk"; 360 | this.terminal.sendText("docker run --rm -v \"$PWD\":/src -u $(id -u):$(id -g) "+dockerTag , newline); 361 | } 362 | 363 | return true; 364 | } 365 | 366 | /** 367 | * Compile the project on MacOs and using wine 368 | * @param newline adds a new line when sending text to the terminal 369 | */ 370 | private compileMacOsProject(newline: boolean = true): boolean { 371 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 372 | let makefile = vscode.workspace.getConfiguration().get(MAKEFILE); 373 | let tag = vscode.workspace.getConfiguration().get(DOCKERTAG); 374 | if (toolchainType === SGDK_GENDEV) { 375 | // MacOs using Wine 376 | //first check if the build.bat file is created 377 | let currentdir = (vscode.workspace.workspaceFolders !== undefined) ? vscode.workspace.workspaceFolders[0].uri : undefined; 378 | this.copybuildmacos(currentdir); 379 | this.terminal.sendText("WINEPREFIX=$GENDEV/wine wine64 cmd /C %cd%\\\\build.bat release", newline); 380 | } else if (toolchainType === MARSDEV) { 381 | this.setmardevenv(process.platform.toString()); 382 | let mkfile = (makefile !== "") ? "-f " + makefile : " "; 383 | this.terminal.sendText("make " + mkfile + " clean release", newline); 384 | } else if (toolchainType === DOCKER) { 385 | let dockerTag = tag !== "" ? tag : "sgdk"; 386 | this.terminal.sendText("docker run --rm -v \"$PWD\":/src -u $(id -u):$(id -g) "+dockerTag , newline); 387 | } 388 | 389 | return true; 390 | } 391 | 392 | /** 393 | * Compile the project. It call to make with the SGDK makefile.gen file. 394 | * @returns true if the project runs properly or false otherwise. 395 | */ 396 | public compileProject(newline: boolean = true): boolean { 397 | let platform = process.platform.toString(); 398 | if (platform === 'win32') { 399 | return this.compileWindowsProject(newline); 400 | } else if (platform === 'linux') { 401 | return this.compileLinuxProject(newline); 402 | } else if (platform === 'darwin') { 403 | return this.compileMacOsProject(newline); 404 | } else { 405 | vscode.window.showWarningMessage("Operating System not yet supported"); 406 | return false; 407 | } 408 | } 409 | 410 | /** 411 | * Compiles the project and run using the current emulator command path. 412 | * In this case, the emulator is not running in background. 413 | */ 414 | private compileAndRunMacosProject(): boolean { 415 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 416 | let makefile = vscode.workspace.getConfiguration().get(MAKEFILE); 417 | if (toolchainType === SGDK_GENDEV) { 418 | let currentdir = (vscode.workspace.workspaceFolders !== undefined) ? vscode.workspace.workspaceFolders[0].uri : undefined; 419 | this.copybuildmacos(currentdir); 420 | this.terminal.sendText("WINEPREFIX=$GENDEV/wine wine64 cmd /C %cd%\\\\build.bat release", false); 421 | } else if (toolchainType === MARSDEV) { 422 | this.setmardevenv(process.platform.toString()); 423 | let mkfile = (makefile !== "") ? "-f " + makefile : " "; 424 | this.terminal.sendText("make " + mkfile + " clean release", false); 425 | } 426 | this.terminal.sendText(" && ", false); 427 | let genspath = vscode.workspace.getConfiguration().get("gens.path"); 428 | let currentromfile = (toolchainType === SGDK_GENDEV) ? "\"$(pwd)/out/rom.bin\"" : "\"$(pwd)/out.bin\""; 429 | this.terminal.sendText(genspath + " " + currentromfile, true); 430 | return true; 431 | } 432 | 433 | /** 434 | * Compiles and run the current project. 435 | * NOTE: In darwin (MACOs) the emulator is running in foreground. 436 | */ 437 | public compileAndRunProject(): boolean { 438 | if (process.platform.toString() === 'darwin') { 439 | return this.compileAndRunMacosProject(); 440 | } 441 | Promise.resolve(this.compileProject(false)).then(res => { 442 | if (res) { 443 | this.terminal.sendText(" && ", false); 444 | this.runProject(); 445 | } else { 446 | vscode.window.showWarningMessage("An error ocurred while Compile & Run"); 447 | } 448 | }); 449 | return true; 450 | } 451 | 452 | /** 453 | * Sets the current gens emulator bash command and update the configuration 454 | * @param uri the new gens emulator command to be updated. 455 | * @returns true if the configuration has been updated. 456 | */ 457 | public setRunPath(uri: string): boolean { 458 | vscode.workspace.getConfiguration().update("gens.path", uri, vscode.ConfigurationTarget.Global).then( 459 | r => { 460 | vscode.window.showInformationMessage("Updated gens command path Configuration"); 461 | }); 462 | return true; 463 | } 464 | 465 | /** 466 | * Runs the current project using the gens command configuration and the rom.bin file path. 467 | * Before execute this method, the project must be compiled. 468 | * @returns true if the emulator runs properly 469 | */ 470 | public runProject(newline: boolean = true): boolean { 471 | 472 | let currentPath = (vscode.workspace.workspaceFolders !== undefined) ? vscode.workspace.workspaceFolders[0].uri : undefined; 473 | let toolchainType = vscode.workspace.getConfiguration().get("toolchainType"); 474 | let currentRomFile = (toolchainType === MARSDEV) ? "out.bin" : Path.join("out", "rom.bin"); 475 | let rompath = (currentPath !== undefined) ? Path.join(currentPath.fsPath, currentRomFile) : undefined; 476 | 477 | let genspath = vscode.workspace.getConfiguration().get("gens.path"); 478 | 479 | let command = genspath + " \"" + rompath+"\""; 480 | let platfm = process.platform.toString(); 481 | if (platfm === 'win32') { 482 | //Run command on background in cmd 483 | command = 'START /B ' + command; 484 | } else if (platfm === 'linux' || platfm === 'darwin') { 485 | //for linux and mac run the command with & 486 | command = command + ' &'; 487 | } else { 488 | return false; 489 | } 490 | this.terminal.sendText(command, newline); 491 | 492 | return true; 493 | } 494 | 495 | public deactivate() { 496 | this.terminal.dispose(); 497 | 498 | } 499 | /** 500 | * Compile the project with debug options creating the symbols table. 501 | */ 502 | public compileForDebugging() { 503 | let platform = process.platform.toString(); 504 | if (platform === 'win32') { 505 | this.compile4DebugWin32(); 506 | } else if (platform === 'linux') { 507 | this.compile4DebugLinux(); 508 | } else if (platform === 'darwin') { 509 | this.compile4DebugMacOs(); 510 | } else { 511 | vscode.window.showWarningMessage("Operating System not yet supported"); 512 | } 513 | } 514 | 515 | private compile4DebugWin32() { 516 | let makefile = vscode.workspace.getConfiguration().get(MAKEFILE); 517 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 518 | if (toolchainType === SGDK_GENDEV) { 519 | let gdk = vscode.workspace.getConfiguration().get(GDK_ENV); 520 | let cmakefile = (makefile !== "") ? makefile : DEFAULT_WIN_SGDK_MAKEFILE; 521 | if (gdk !== "") { 522 | this.terminal.sendText("set GDK=" + gdk, true); 523 | } 524 | this.terminal.sendText("%GDK%\\bin\\make -f " + cmakefile + " debug"); 525 | } else if (toolchainType === MARSDEV) { 526 | this.setmardevenv(process.platform.toString()); 527 | let mkfile = (makefile !== "") ? "-f " + makefile + " " : ""; 528 | this.terminal.sendText("make " + mkfile + " clean debug"); 529 | } 530 | } 531 | 532 | /** 533 | * Call the compile command with debug options on MacOs Systems. 534 | */ 535 | private compile4DebugMacOs() { 536 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 537 | let makefile = vscode.workspace.getConfiguration().get(MAKEFILE); 538 | if (toolchainType === SGDK_GENDEV) { 539 | let currentdir = (vscode.workspace.workspaceFolders !== undefined) ? vscode.workspace.workspaceFolders[0].uri : undefined; 540 | this.copybuildmacos(currentdir); 541 | this.terminal.sendText("WINEPREFIX=$GENDEV/wine wine64 cmd /C %cd%\\\\build.bat debug"); 542 | } else if (toolchainType === MARSDEV) { 543 | this.setmardevenv(process.platform.toString()); 544 | let mkfile = (makefile !== "") ? "-f " + makefile + " " : ""; 545 | this.terminal.sendText("make " + mkfile + " clean debug"); 546 | } 547 | } 548 | 549 | /** 550 | * Call the compile command with debug options on Linux Systems. 551 | * 552 | * NOTE: This command its not working on SGDK/GENDEV toolchains, only MARSDEV toolchain its compatible. 553 | */ 554 | private compile4DebugLinux() { 555 | let toolchainType = vscode.workspace.getConfiguration().get(TOOLCHAINTYPE); 556 | let makefile = vscode.workspace.getConfiguration().get(MAKEFILE); 557 | if (toolchainType === SGDK_GENDEV) { 558 | vscode.window.showWarningMessage("Toolchain SGDK/GENDEV can't compile for Debugging. Change to Marsdev on configuration."); 559 | } else if (toolchainType === MARSDEV) { 560 | this.setmardevenv(process.platform.toString()); 561 | let mkfile = (makefile !== "") ? "-f" + makefile + " " : ""; 562 | this.terminal.sendText("make " + mkfile + "clean debug"); 563 | } 564 | 565 | } 566 | 567 | public importTmxFile(tmxFilePath: vscode.Uri) { 568 | let parser = new TmxXMLParser(); 569 | let tmx = parser.parseFile(tmxFilePath.fsPath); 570 | let currentdir = (vscode.workspace.workspaceFolders !== undefined) ? vscode.workspace.workspaceFolders[0].uri : undefined; 571 | if (currentdir !== undefined) { 572 | tmx.writeCHeaderFile(Path.join(currentdir.fsPath, "res"), Path.join(this.extensionPath, "resources", "headerfile.h.template")); 573 | } 574 | } 575 | 576 | public importJsonTmxFile(tmxJsonFilePath: vscode.Uri) { 577 | let parser = new TmxJsonFileParser(); 578 | let tmx = parser.parseFile(tmxJsonFilePath.fsPath); 579 | let currentdir = (vscode.workspace.workspaceFolders !== undefined) ? vscode.workspace.workspaceFolders[0].uri : undefined; 580 | if (currentdir !== undefined) { 581 | tmx.writeCHeaderFile(Path.join(currentdir.fsPath, "res"), Path.join(this.extensionPath, "resources", "headerfile.h.template")); 582 | } 583 | } 584 | } -------------------------------------------------------------------------------- /src/codeProvider.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * (C) 2020. This code is under MIT license. 3 | * You can get a copy of the license with this software. 4 | * For more information please see https://opensource.org/licenses/MIT 5 | */ 6 | import * as vscode from 'vscode'; 7 | import * as fs from 'fs'; 8 | import * as path from 'path'; 9 | 10 | /** 11 | * Class CodeProvider: Provides Code Completion for SGDK Resource Files. 12 | */ 13 | export class CodeProvider { 14 | 15 | 16 | /** 17 | * Singletone Instance 18 | */ 19 | private static instance: CodeProvider | undefined; 20 | 21 | /** 22 | * Extension Context 23 | */ 24 | private extensionPath: string; 25 | /** 26 | * CompletionItemList 27 | */ 28 | private codeCompletionItems: vscode.CompletionList; 29 | 30 | 31 | /** 32 | * get the current code completion Items. if it not loaded previously, create a new codeProvider Instance 33 | * @param context Extension Context 34 | */ 35 | public static getCodeProviderInstance(context: vscode.ExtensionContext): vscode.ProviderResult { 36 | 37 | if (this.instance === undefined) { 38 | this.instance = new CodeProvider(context.extensionPath); 39 | } 40 | 41 | return this.instance.getCodeProviderItems(); 42 | } 43 | 44 | /** 45 | * Class constructor. Loads the current codeCompletionItems from the codecompletion.json file. 46 | * @param context Extension context 47 | */ 48 | constructor(extensionPath: string) { 49 | this.extensionPath = extensionPath; 50 | //loads the codecompletion from the jsonfile. 51 | this.codeCompletionItems = this.loadCodeProviderItems(); 52 | } 53 | 54 | /** 55 | * Load the content of the file 'codecompletion.json' (its on the extension's resource folder); and create a new CompletionList with his information. 56 | * 57 | * @returns the CodeCompletionList with the content of codecompletion.json file 58 | */ 59 | private loadCodeProviderItems(): vscode.CompletionList { 60 | 61 | let jsoncodefile = fs.readFileSync(path.join(this.extensionPath, "resources", "codecompletion.json")); 62 | 63 | let jsonobj = JSON.parse(jsoncodefile.toString()); 64 | let completionitems = new vscode.CompletionList; 65 | jsonobj.items.forEach((item: { label: string; text: string; doc: string; kind: string }) => { 66 | let comitem = new vscode.CompletionItem(item.label); 67 | comitem.insertText = item.text; 68 | comitem.kind = this.getcomItemKind(item.kind); 69 | comitem.documentation = new vscode.MarkdownString(item.doc); 70 | completionitems.items.push(comitem); 71 | }); 72 | 73 | return completionitems; 74 | } 75 | 76 | /** 77 | * Get the CompletionItemKind from the String of the json loaded. 78 | * @param strKind String with the kind of CodeCompletionItem. 79 | */ 80 | private getcomItemKind(strKind: string): vscode.CompletionItemKind { 81 | 82 | switch (strKind) { 83 | case "KEYWORD": 84 | return vscode.CompletionItemKind.Keyword; 85 | case "PROPERTY": 86 | return vscode.CompletionItemKind.Property; 87 | case "VARIABLE": 88 | return vscode.CompletionItemKind.Variable; 89 | case "STRUCT": 90 | return vscode.CompletionItemKind.Struct; 91 | case "FUNCTION": 92 | return vscode.CompletionItemKind.Function 93 | case "TEXT": 94 | default: 95 | return vscode.CompletionItemKind.Text; 96 | } 97 | } 98 | /** 99 | * get the current completionItemList 100 | */ 101 | public getCodeProviderItems(): vscode.CompletionItem[] { 102 | return this.codeCompletionItems.items; 103 | } 104 | } -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Configuration key for toolchaintype 3 | */ 4 | export const TOOLCHAINTYPE = "toolchainType"; 5 | 6 | /** 7 | * Configuration key for custom makefile 8 | */ 9 | export const MAKEFILE = "custom-makefile"; 10 | 11 | /** 12 | * Configuration key for MARSDEV 13 | */ 14 | export const MARSDEV_ENV = "MARSDEV"; 15 | 16 | /** 17 | * configuration key for GENDEV 18 | */ 19 | export const GENDEV_ENV = "GENDEV"; 20 | 21 | /** 22 | * configuration key for GDK 23 | */ 24 | export const GDK_ENV = "GDK"; 25 | 26 | /** 27 | * Use of SGDK or GENDEV toolchains 28 | */ 29 | export const SGDK_GENDEV = "sgdk/gendev"; 30 | 31 | /** 32 | * Use of MARSDEV toolchain 33 | */ 34 | export const MARSDEV = "marsdev"; 35 | 36 | /** 37 | * Use of Docker toolchain 38 | */ 39 | export const DOCKER = "docker"; 40 | 41 | /** 42 | * Use tag value for a docker 43 | */ 44 | export const DOCKERTAG = "dockerTag"; 45 | 46 | export const GENS_PATH= "gens.path"; 47 | 48 | /** 49 | * Parallel compilation configuration key 50 | */ 51 | export const PARALEL_COMPILE = "parallelCompile"; 52 | 53 | /** 54 | * Default value for parallel compilation 55 | */ 56 | export const PARALLEL_COMPILE_DEFAULT = 1; 57 | 58 | /** extra parameters for compilation */ 59 | export const EXTRA_PARAMETERS = "extraParameters"; 60 | 61 | /** 62 | * Doragasu Image 63 | */ 64 | export const DORAGASU_IMAGE = "doragasuImage"; 65 | 66 | /** 67 | * DEFAULT MAKEFILE for Windows Systems 68 | */ 69 | export const DEFAULT_WIN_SGDK_MAKEFILE = "%GDK%\\makefile.gen"; 70 | 71 | /** 72 | * DEFAULT MAKEFILE for GenDev Systems 73 | */ 74 | export const DEFAULT_GENDEV_SGDK_MAKEFILE = "$GENDEV/sgdk/mkfiles/makefile.gen"; 75 | 76 | /** 77 | * Windows Constant 78 | */ 79 | export const WIN32="win32"; 80 | 81 | /** 82 | * Linux Constant 83 | */ 84 | export const LINUX="linux"; 85 | 86 | /** 87 | * MacOs Constant 88 | */ 89 | export const MACOS="darwin"; 90 | 91 | /** 92 | * SGDK Docker Image (Using new SGDK Docker Image) 93 | */ 94 | export const SGDK_DEFAULT_DOCKER_IMAGE = "ghcr.io/stephane-d/sgdk:latest"; 95 | 96 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * (C) 2020. This code is under MIT license. 3 | * You can get a copy of the license with this software. 4 | * For more information please see https://opensource.org/licenses/MIT 5 | */ 6 | 7 | // The module 'vscode' contains the VS Code extensibility API 8 | // Import the module and reference it with the alias vscode in your code below 9 | import * as vscode from 'vscode'; 10 | import { CodeProvider } from './codeProvider'; 11 | import * as Path from 'path'; 12 | import * as fs from 'fs'; 13 | import { ImagePreviewProvider } from './imagePreviewProvider'; 14 | import { CoreEngine } from './CoreEngine'; 15 | 16 | 17 | let appModel: CoreEngine; 18 | 19 | // this method is called when your extension is activated 20 | // your extension is activated the very first time the command is executed 21 | export function activate(context: vscode.ExtensionContext) { 22 | 23 | appModel= new CoreEngine(context.extensionPath); 24 | let codeprovider = CodeProvider.getCodeProviderInstance(context); 25 | // Use the console to output diagnostic information (console.log) and errors (console.error) 26 | // This line of code will only be executed once when your extension is activated 27 | console.log('Congratulations, your extension "genesis-code" is now active!'); 28 | // adding a status bar element 29 | // Add code completion for sgdk files 30 | let codecompletion = vscode.languages.registerCompletionItemProvider('Sgdk Resource File', { 31 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, newcontext: vscode.CompletionContext) { 32 | 33 | 34 | return codeprovider; 35 | } 36 | }); 37 | // The command has been defined in the package.json file 38 | // Now provide the implementation of the command with registerCommand 39 | // The commandId parameter must match the command field in package.json 40 | let disposable = vscode.commands.registerCommand('extension.cleancode', () => { 41 | 42 | console.log("current platform is: " + process.platform); 43 | console.log(appModel.clean()); 44 | 45 | 46 | }); 47 | //Create Project Command; create a new Project for SGDK 48 | let disposablecreate = vscode.commands.registerCommand('extension.createproject', () => { 49 | //First, select the folder where the project will be created 50 | vscode.window.showOpenDialog({ 51 | canSelectFiles: false, 52 | canSelectFolders: true, 53 | canSelectMany: false 54 | }).then(r => { 55 | if (r !== undefined) { 56 | let uripath = appModel.create(r[0]); 57 | vscode.commands.executeCommand('vscode.openFolder', uripath). 58 | then((value) => 59 | {if(value) 60 | {vscode.window.showInformationMessage("Created New SGDK Project");}}); 61 | 62 | } 63 | }); 64 | }); 65 | // Compiple Command; 66 | let disposableCompile = vscode.commands.registerCommand('extension.compileproject', () => { 67 | appModel.compile(); 68 | }); 69 | //Set gens emulator path 70 | let disposablesetpath = vscode.commands.registerCommand('extension.setrunpath', () => { 71 | vscode.window.showInputBox({ 72 | placeHolder: 'Please insert Gens Emulator Command', 73 | value: vscode.workspace.getConfiguration().get("gens.path") 74 | }).then(r => { 75 | if (r !== undefined) { 76 | appModel.setRunPath(r); 77 | } 78 | }); 79 | }); 80 | //Run the current rom with the gens emulator 81 | let disposableRun = vscode.commands.registerCommand('extension.runproject', () => { 82 | appModel.run(); 83 | }); 84 | 85 | // Compiles and then run the current rom with the gens emulator 86 | let disposableCompileAndRun = vscode.commands.registerCommand('extension.compileandrunproject', () => { 87 | appModel.compileAndRun(); 88 | }); 89 | 90 | let disposableCompile4debugging = vscode.commands.registerCommand('extension.compile4debug', () => { 91 | appModel.compile4Debug(); 92 | }); 93 | 94 | let disposableimportTmx = vscode.commands.registerCommand('extension.tmximport', () => { 95 | vscode.window.showOpenDialog({ 96 | canSelectFiles: true, 97 | canSelectFolders: false, 98 | canSelectMany: false, 99 | filters: { 100 | 'TmxFiles': ['tmx'] 101 | } 102 | }).then(f => { 103 | if (f !== undefined) { 104 | appModel.tmxImport(f[0]); 105 | } 106 | }); 107 | }); 108 | 109 | let disposableImportJsonTmx = vscode.commands.registerCommand('extension.tmxjsonimport', () => { 110 | vscode.window.showOpenDialog({ 111 | canSelectFiles: true, 112 | canSelectFolders: false, 113 | canSelectMany: false, 114 | filters: { 115 | 'TmxJsonFiles': ['json'] 116 | } 117 | }).then(f => { 118 | if (f !== undefined) { 119 | appModel.tmxJsonImport(f[0]); 120 | } 121 | }); 122 | }); 123 | 124 | let disposableAbout = vscode.commands.registerCommand('extension.aboutgenscode', () =>{ 125 | const column = vscode.window.activeTextEditor? vscode.window.activeTextEditor.viewColumn:undefined; 126 | const panel = vscode.window.createWebviewPanel('about', "About Genesis Code",column ?? vscode.ViewColumn.One,{enableScripts:true}); 127 | const strabouthtmlpath = Path.join(context.extensionPath , "resources", "about.html"); 128 | panel.webview.html= fs.readFileSync(strabouthtmlpath).toLocaleString(); 129 | panel.reveal(); 130 | }); 131 | 132 | let diposablecursomEditor = vscode.window.registerCustomEditorProvider("genesiscode.imageViewer", 133 | new ImagePreviewProvider(context)); 134 | context.subscriptions.push(disposable); 135 | context.subscriptions.push(disposablecreate); 136 | context.subscriptions.push(disposableCompile); 137 | context.subscriptions.push(disposablesetpath); 138 | context.subscriptions.push(disposableRun); 139 | context.subscriptions.push(disposablesetpath); 140 | context.subscriptions.push(disposableCompileAndRun); 141 | context.subscriptions.push(codecompletion); 142 | context.subscriptions.push(disposableCompile4debugging); 143 | context.subscriptions.push(disposableimportTmx); 144 | context.subscriptions.push(disposableImportJsonTmx); 145 | context.subscriptions.push(disposableAbout); 146 | context.subscriptions.push(diposablecursomEditor); 147 | } 148 | 149 | 150 | 151 | // this method is called when your extension is deactivated 152 | export function deactivate() { 153 | appModel.deactivate(); 154 | } 155 | -------------------------------------------------------------------------------- /src/imagePreviewProvider.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * (C) 2021. This code is under MIT license. 3 | * You can get a copy of the license with this software. 4 | * For more information please see https://opensource.org/licenses/MIT 5 | */ 6 | import { readFileSync} from 'fs'; 7 | import * as Path from 'path'; 8 | import * as vscode from 'vscode'; 9 | import {ImageColor, ImageReader} from '@zerasul/image-read-helper'; 10 | 11 | 12 | export class ImagePreviewDocument extends vscode.Disposable implements vscode.CustomDocument{ 13 | 14 | constructor(uri: vscode.Uri){ 15 | super(ImagePreviewDocument._disposable); 16 | this.uri=uri; 17 | this.filename=Path.basename(this.uri.fsPath); 18 | this.imagedata=readFileSync(uri.fsPath); 19 | this.imagedatab64= ImagePreviewDocument.convertB64(this.imagedata); 20 | let imageInfo=ImageReader.read(this.imagedata); 21 | 22 | this.width=imageInfo.width; 23 | this.height=imageInfo.hegiht; 24 | this.palette=imageInfo.palette; 25 | 26 | 27 | } 28 | 29 | uri: vscode.Uri; 30 | width: number|undefined; 31 | height: number|undefined; 32 | imagedatab64:any; 33 | imagedata:Buffer; 34 | filename:string; 35 | bitmap: any; 36 | palette: any; 37 | 38 | private static _disposable(){ 39 | return; 40 | } 41 | 42 | private static convertB64(imagedata:Buffer){ 43 | return imagedata.toString('base64'); 44 | } 45 | dispose(){ 46 | super.dispose(); 47 | } 48 | 49 | } 50 | 51 | export class ImagePreviewProvider implements vscode.CustomReadonlyEditorProvider{ 52 | 53 | extensionContext:vscode.ExtensionContext; 54 | 55 | constructor(context:vscode.ExtensionContext){ 56 | this.extensionContext=context; 57 | } 58 | openCustomDocument(uri: vscode.Uri, openContext: vscode.CustomDocumentOpenContext, token: vscode.CancellationToken): ImagePreviewDocument | Thenable { 59 | 60 | return new ImagePreviewDocument(uri); 61 | } 62 | resolveCustomEditor(document: ImagePreviewDocument, webviewPanel: vscode.WebviewPanel, token: vscode.CancellationToken): void | Thenable { 63 | let imageuri="data:image/png;base64 ,"+document.imagedatab64; 64 | 65 | let width = document.width; 66 | let height = document.height; 67 | let tilesw = (document.width!==undefined)?document.width/8:0; 68 | let tilesh = (document.height!==undefined)?document.height/8:0; 69 | let filename= document.filename; 70 | let htmltemplate= readFileSync(Path.join(this.extensionContext.extensionPath , "resources","imageviewer.html")).toLocaleString(); 71 | 72 | htmltemplate=htmltemplate.replace(/{{filename}}/g, ""+filename); 73 | htmltemplate=htmltemplate.replace(/{{imageuri}}/g,imageuri); 74 | htmltemplate=htmltemplate.replace(/{{width}}/g, String(width)); 75 | htmltemplate=htmltemplate.replace(/{{height}}/g,String(height)); 76 | htmltemplate=htmltemplate.replace(/{{tilesw}}/g,String(tilesw)); 77 | htmltemplate=htmltemplate.replace(/{{tilesh}}/g,String(tilesh)); 78 | let htmlcolours=this.generateHtmlGrid(document.palette); 79 | htmltemplate=htmltemplate.replace(/Loading Palette.../g, htmlcolours); 80 | 81 | webviewPanel.webview.html=htmltemplate; 82 | } 83 | 84 | 85 | 86 | 87 | private generateHtmlGrid(palette:Array):string{ 88 | let html:string=`

${palette.length} Colours

`; 89 | html+="
"; 90 | palette.forEach(element=> { 91 | 92 | let htmlelement=`
`; 93 | html+=htmlelement; 94 | }); 95 | html+="
"; 96 | return html; 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/test/runTest.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | 3 | import { runTests } from '@vscode/test-electron'; 4 | 5 | async function main() { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 10 | 11 | // The path to test runner 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 14 | 15 | // Download VS Code, unzip it and run the integration test 16 | await runTests({ extensionDevelopmentPath, extensionTestsPath }); 17 | } catch (err) { 18 | console.error('Failed to run tests'); 19 | process.exit(1); 20 | } 21 | } 22 | 23 | main(); 24 | -------------------------------------------------------------------------------- /src/test/suite/codeProvider.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import { CodeProvider } from '../../codeProvider'; 3 | import * as Path from 'path'; 4 | import * as vscode from 'vscode'; 5 | 6 | 7 | 8 | 9 | suite('Codecompletion Test', () => { 10 | 11 | test('CodeProvider', () => { 12 | let currentpath = Path.join(__dirname, "../../../"); 13 | let fixture = new CodeProvider(currentpath); 14 | let firstElement = fixture.getCodeProviderItems()[0]; 15 | assert.equal(firstElement.label, "BITMAP"); 16 | assert.equal(firstElement.kind, vscode.CompletionItemKind.Keyword); 17 | }); 18 | }); -------------------------------------------------------------------------------- /src/test/suite/ejemplo1.json: -------------------------------------------------------------------------------- 1 | { "compressionlevel":-1, 2 | "height":28, 3 | "infinite":false, 4 | "layers":[ 5 | { 6 | "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 1, 1, 1, 1, 625, 626, 627, 628, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 1, 1, 1, 1, 665, 666, 667, 668, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 1, 1, 1, 1, 705, 706, 707, 708, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 1, 1, 1, 1, 745, 746, 747, 748, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 1, 1, 1, 1, 785, 786, 787, 788, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 11, 12, 13, 14, 15, 1, 1, 1, 1, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 1, 1, 1, 1, 825, 826, 827, 828, 1, 1, 1, 1, 1, 1, 1, 1, 46, 47, 48, 51, 52, 53, 54, 55, 1, 1, 1, 1, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 1, 1, 1, 1, 865, 866, 867, 868, 1, 1, 1, 1, 1, 1, 1, 1, 86, 87, 88, 91, 92, 93, 94, 95, 1, 1, 1, 1, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 1, 1, 1, 1, 905, 906, 907, 908, 1, 1, 1, 1, 1, 1, 1, 1, 126, 127, 128, 131, 132, 133, 134, 135, 1, 1, 1, 1, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 1, 1, 1, 1, 945, 946, 947, 948, 333, 334, 335, 336, 1, 1, 1, 652, 653, 654, 655, 656, 653, 654, 655, 656, 657, 658, 659, 660, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 649, 650, 651, 652, 653, 653, 653, 656, 373, 374, 375, 376, 41, 41, 691, 692, 693, 694, 695, 696, 693, 694, 695, 696, 697, 698, 699, 700, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 689, 690, 691, 692, 693, 693, 693, 696, 413, 414, 415, 1, 1, 730, 731, 732, 733, 734, 735, 736, 733, 734, 735, 736, 737, 738, 739, 740, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 729, 730, 731, 732, 733, 734, 735, 736, 453, 454, 455, 1, 769, 770, 771, 772, 773, 774, 775, 776, 773, 774, 775, 776, 777, 778, 779, 780, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 769, 770, 771, 772, 773, 774, 775, 776, 653, 654, 655, 656, 809, 810, 811, 812, 773, 774, 775, 776, 773, 774, 775, 776, 817, 818, 819, 820, 653, 654, 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, 809, 810, 811, 853, 854, 855, 856, 857, 693, 694, 695, 696, 811, 772, 775, 776, 813, 814, 815, 816, 813, 814, 815, 896, 897, 898, 899, 860, 693, 694, 693, 693, 693, 693, 693, 693, 693, 693, 693, 693, 850, 851, 853, 893, 894, 895, 896, 897, 733, 734, 735, 736, 851, 852, 815, 816, 853, 854, 855, 856, 853, 854, 855, 936, 937, 938, 939, 900, 733, 734, 735, 736, 733, 734, 735, 736, 733, 734, 735, 736, 890, 891, 893, 893, 894, 895, 896, 897], 7 | "height":28, 8 | "id":1, 9 | "name":"Capa de patrones 1", 10 | "opacity":1, 11 | "type":"tilelayer", 12 | "visible":true, 13 | "width":40, 14 | "x":0, 15 | "y":0 16 | }, 17 | { 18 | "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 525, 526, 527, 528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 565, 566, 567, 568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 605, 606, 607, 608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 19 | "height":28, 20 | "id":3, 21 | "name":"Capa de patrones 2", 22 | "opacity":1, 23 | "type":"tilelayer", 24 | "visible":true, 25 | "width":40, 26 | "x":0, 27 | "y":0 28 | }, 29 | { 30 | "draworder":"topdown", 31 | "id":2, 32 | "name":"Capa de Objetos 1", 33 | "objects":[ 34 | { 35 | "height":24.3333, 36 | "id":20, 37 | "name":"", 38 | "rotation":0, 39 | "type":"", 40 | "visible":true, 41 | "width":32.3333, 42 | "x":0, 43 | "y":200 44 | }, 45 | { 46 | "height":0, 47 | "id":21, 48 | "name":"", 49 | "polygon":[ 50 | { 51 | "x":0, 52 | "y":0 53 | }, 54 | { 55 | "x":30.3333, 56 | "y":-27.3333 57 | }, 58 | { 59 | "x":30.6667, 60 | "y":26.3333 61 | }, 62 | { 63 | "x":-0.333333, 64 | "y":27.3333 65 | }], 66 | "properties":[ 67 | { 68 | "name":"collidable", 69 | "type":"bool", 70 | "value":true 71 | }], 72 | "rotation":0, 73 | "type":"", 74 | "visible":true, 75 | "width":0, 76 | "x":34, 77 | "y":196.667 78 | }, 79 | { 80 | "height":56, 81 | "id":22, 82 | "name":"", 83 | "rotation":0, 84 | "type":"", 85 | "visible":true, 86 | "width":62.3333, 87 | "x":65.6667, 88 | "y":168.333 89 | }, 90 | { 91 | "height":0, 92 | "id":23, 93 | "name":"", 94 | "polygon":[ 95 | { 96 | "x":0, 97 | "y":0 98 | }, 99 | { 100 | "x":29.3333, 101 | "y":28.6667 102 | }, 103 | { 104 | "x":29, 105 | "y":51 106 | }, 107 | { 108 | "x":-1, 109 | "y":51 110 | }], 111 | "rotation":0, 112 | "type":"", 113 | "visible":true, 114 | "width":0, 115 | "x":129.667, 116 | "y":172 117 | }, 118 | { 119 | "height":22.3333, 120 | "id":24, 121 | "name":"", 122 | "rotation":0, 123 | "type":"", 124 | "visible":true, 125 | "width":94.6667, 126 | "x":160.667, 127 | "y":201.667 128 | }, 129 | { 130 | "height":0, 131 | "id":25, 132 | "name":"", 133 | "polygon":[ 134 | { 135 | "x":0, 136 | "y":0 137 | }, 138 | { 139 | "x":-33, 140 | "y":33.3333 141 | }, 142 | { 143 | "x":-33.3333, 144 | "y":55.3333 145 | }, 146 | { 147 | "x":-0.333333, 148 | "y":55.3333 149 | }], 150 | "rotation":0, 151 | "type":"", 152 | "visible":true, 153 | "width":0, 154 | "x":289.667, 155 | "y":168 156 | }, 157 | { 158 | "height":56.3333, 159 | "id":26, 160 | "name":"", 161 | "rotation":0, 162 | "type":"", 163 | "visible":true, 164 | "width":28.3333, 165 | "x":291.333, 166 | "y":167.333 167 | }], 168 | "opacity":1, 169 | "type":"objectgroup", 170 | "visible":true, 171 | "x":0, 172 | "y":0 173 | }], 174 | "nextlayerid":4, 175 | "nextobjectid":27, 176 | "orientation":"orthogonal", 177 | "renderorder":"right-down", 178 | "tiledversion":"1.3.4", 179 | "tileheight":8, 180 | "tilesets":[ 181 | { 182 | "firstgid":1, 183 | "source":"tset1.tsx" 184 | }], 185 | "tilewidth":8, 186 | "type":"map", 187 | "version":1.2, 188 | "width":40 189 | } -------------------------------------------------------------------------------- /src/test/suite/ejemplo1.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 7 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 8 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 10 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 11 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 12 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 13 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 14 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 15 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 16 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,67,68,69,70,71,72,73,74,75,76,77,78,1,1,1,1,1,1,1,1, 17 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,107,108,109,110,111,112,113,114,115,116,117,118,1,1,1,1,1,1,1,1, 18 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,147,148,149,150,151,152,153,154,155,156,157,158,1,1,1,1,625,626,627,628, 19 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,187,188,189,190,191,192,193,194,195,196,197,198,1,1,1,1,665,666,667,668, 20 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,227,228,229,230,231,232,233,234,235,236,237,238,1,1,1,1,705,706,707,708, 21 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,267,268,269,270,271,272,273,274,275,276,277,278,1,1,1,1,745,746,747,748, 22 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,307,308,309,310,311,312,313,314,315,316,317,318,1,1,1,1,785,786,787,788, 23 | 1,1,1,1,1,1,1,1,6,7,8,11,12,13,14,15,1,1,1,1,347,348,349,350,351,352,353,354,355,356,357,358,1,1,1,1,825,826,827,828, 24 | 1,1,1,1,1,1,1,1,46,47,48,51,52,53,54,55,1,1,1,1,387,388,389,390,391,392,393,394,395,396,397,398,1,1,1,1,865,866,867,868, 25 | 1,1,1,1,1,1,1,1,86,87,88,91,92,93,94,95,1,1,1,1,427,428,429,430,431,432,433,434,435,436,437,438,1,1,1,1,905,906,907,908, 26 | 1,1,1,1,1,1,1,1,126,127,128,131,132,133,134,135,1,1,1,1,467,468,469,470,471,472,473,474,475,476,477,478,1,1,1,1,945,946,947,948, 27 | 333,334,335,336,1,1,1,652,653,654,655,656,653,654,655,656,657,658,659,660,507,508,509,510,511,512,513,514,515,516,517,518,649,650,651,652,653,654,655,656, 28 | 373,374,375,376,1,690,691,692,693,694,695,696,693,694,695,696,697,698,699,700,547,548,549,550,551,552,553,554,555,556,557,558,689,690,691,692,693,694,695,696, 29 | 413,414,415,1,1,730,731,732,733,734,735,736,733,734,735,736,737,738,739,740,587,588,589,590,591,592,593,594,595,596,597,598,729,730,731,732,733,734,735,736, 30 | 453,454,455,1,769,770,771,772,773,774,775,776,773,774,775,776,777,778,779,780,627,628,629,630,631,632,633,634,635,636,637,638,769,770,771,772,773,774,775,776, 31 | 653,654,655,656,809,810,811,812,773,774,775,776,773,774,775,776,817,818,819,820,653,654,655,656,653,654,655,656,653,654,655,656,809,810,811,853,854,855,856,857, 32 | 693,694,695,696,811,772,775,776,813,814,815,816,813,814,815,896,897,898,899,860,693,694,695,696,693,694,695,696,693,694,695,696,850,851,853,893,894,895,896,897, 33 | 733,734,735,736,851,852,815,816,853,854,855,856,853,854,855,936,937,938,939,900,733,734,735,736,733,734,735,736,733,734,735,736,890,891,893,893,894,895,896,897 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/test/suite/extension.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import { before } from 'mocha'; 3 | 4 | // You can import and use all API from the 'vscode' module 5 | // as well as import your extension to test it 6 | import * as vscode from 'vscode'; 7 | 8 | suite('Extension Test Suite', () => { 9 | before(() => { 10 | vscode.window.showInformationMessage('Start all tests.'); 11 | }); 12 | 13 | test('extension', () => { 14 | assert.equal(-1, [1, 2, 3].indexOf(5)); 15 | assert.equal(-1, [1, 2, 3].indexOf(0)); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/test/suite/index.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as Mocha from 'mocha'; 3 | import * as glob from 'glob'; 4 | 5 | export function run(): Promise { 6 | // Create the mocha test 7 | const mocha = new Mocha({ 8 | ui: 'tdd', 9 | /*reporter: 'mocha-junit-reporter', 10 | reporterOptions:{ 11 | mochaFile: './file.xml' 12 | }*/ 13 | }); 14 | 15 | 16 | const testsRoot = path.resolve(__dirname, '..'); 17 | 18 | return new Promise((c, e) => { 19 | glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { 20 | if (err) { 21 | return e(err); 22 | } 23 | 24 | // Add files to the test suite 25 | files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); 26 | 27 | try { 28 | // Run the mocha test 29 | mocha.run(failures => { 30 | if (failures > 0) { 31 | e(new Error(`${failures} tests failed.`)); 32 | } else { 33 | c(); 34 | } 35 | }); 36 | } catch (ex) { 37 | e(ex); 38 | } 39 | }); 40 | }); 41 | } 42 | -------------------------------------------------------------------------------- /src/test/suite/tmxParser.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import { TmxXMLParser, TmxJsonFileParser } from '../../TmxParser'; 3 | import * as Path from 'path'; 4 | import * as fs from 'fs'; 5 | 6 | suite('TmxParser Test', () => { 7 | 8 | test('tmxParser', () => { 9 | let parser = new TmxXMLParser(); 10 | let tmx = parser.parseFile(Path.join(__dirname, '../../../src/test/suite/ejemplo1.tmx')); 11 | assert.equal(tmx.map['@_version'], "1.2"); 12 | assert.equal(tmx.map.layer['@_id'], 1); 13 | }); 14 | 15 | test('writeCHeader', () => { 16 | let parser = new TmxXMLParser(); 17 | let tmx = parser.parseFile(Path.join(__dirname, '../../../src/test/suite/ejemplo1.tmx')); 18 | tmx.writeCHeaderFile(Path.join(__dirname, '../../../src/test/suite/'), Path.join(__dirname, '../../../resources/headerfile.h.template')); 19 | let file = fs.readFileSync(Path.join(__dirname, '../../../src/test/suite/ejemplo1Map.h')); 20 | assert.ok(file.toLocaleString().indexOf('Capa de patrones 1') >= 0); 21 | fs.unlinkSync(Path.join(__dirname, '../../../src/test/suite/ejemplo1Map.h')); 22 | }); 23 | 24 | test('parseJson', () => { 25 | let parser = new TmxJsonFileParser(); 26 | let tmx = parser.parseFile(Path.join(__dirname, '../../../src/test/suite/ejemplo1.json')); 27 | assert.equal(tmx.map.version, "1.2"); 28 | assert.equal(tmx.map.layers[0].id, 1); 29 | 30 | }); 31 | 32 | test('writecheaderjson', () => { 33 | let parser = new TmxJsonFileParser(); 34 | let tmx = parser.parseFile(Path.join(__dirname, '../../../src/test/suite/ejemplo1.json')); 35 | tmx.writeCHeaderFile(Path.join(__dirname, '../../../src/test/suite/'), Path.join(__dirname, '../../../resources/headerfile.h.template')); 36 | fs.unlinkSync(Path.join(__dirname, '../../../src/test/suite/ejemplo1Map.h')); 37 | }); 38 | }); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src", 11 | "strict": true /* enable all strict type-checking options */ 12 | /* Additional Checks */ 13 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 14 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 15 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 16 | }, 17 | "exclude": [ 18 | "node_modules", 19 | ".vscode-test" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-string-throw": true, 4 | "no-unused-expression": true, 5 | "no-duplicate-variable": true, 6 | "curly": true, 7 | "class-name": true, 8 | "semicolon": [ 9 | true, 10 | "always" 11 | ], 12 | "triple-equals": true 13 | }, 14 | "defaultSeverity": "warning" 15 | } 16 | -------------------------------------------------------------------------------- /vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your VS Code Extension 2 | 3 | ## What's in the folder 4 | 5 | * This folder contains all of the files necessary for your extension. 6 | * `package.json` - this is the manifest file in which you declare your extension and command. 7 | * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command. 9 | * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 10 | * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. 11 | 12 | ## Get up and running straight away 13 | 14 | * Press `F5` to open a new window with your extension loaded. 15 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. 16 | * Set breakpoints in your code inside `src/extension.ts` to debug your extension. 17 | * Find output from your extension in the debug console. 18 | 19 | ## Make changes 20 | 21 | * You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. 22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. 23 | 24 | 25 | ## Explore the API 26 | 27 | * You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. 28 | 29 | ## Run tests 30 | 31 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. 32 | * Press `F5` to run the tests in a new window with your extension loaded. 33 | * See the output of the test result in the debug console. 34 | * Make changes to `src/test/suite/extension.test.ts` or create new test files inside the `test/suite` folder. 35 | * The provided test runner will only consider files matching the name pattern `**.test.ts`. 36 | * You can create folders inside the `test` folder to structure your tests any way you want. 37 | 38 | ## Go further 39 | 40 | * Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/testing-extension). 41 | * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace. 42 | * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration). 43 | --------------------------------------------------------------------------------