├── .gitignore ├── assets ├── icon.png ├── splash.png ├── sprites.act ├── sprites.png ├── sprites.tsx ├── level00.tmx ├── level01.tmx ├── level03.tmx └── level02.tmx ├── screenshot.png ├── README.md ├── metadata.yml ├── rocks-and-diamonds.hpp ├── ci └── install_sdl_vs.sh ├── assets.yml ├── splash.tmx ├── CMakeLists.txt ├── LICENSE ├── .github └── workflows │ └── build.yml └── rocks-and-diamonds.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | build.em/ 3 | build.stm32/ 4 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/32blit/rocks-and-diamonds/HEAD/assets/icon.png -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/32blit/rocks-and-diamonds/HEAD/screenshot.png -------------------------------------------------------------------------------- /assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/32blit/rocks-and-diamonds/HEAD/assets/splash.png -------------------------------------------------------------------------------- /assets/sprites.act: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/32blit/rocks-and-diamonds/HEAD/assets/sprites.act -------------------------------------------------------------------------------- /assets/sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/32blit/rocks-and-diamonds/HEAD/assets/sprites.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rocks and Diamonds - 32blit 2 | 3 | A 32blit remake of the classic rock-dodging, diamond-grabbing, boulder-dashing game we all know and love. 4 | 5 | ![Screenshot of Rocks and Diamonds in action](screenshot.png) -------------------------------------------------------------------------------- /assets/sprites.tsx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /metadata.yml: -------------------------------------------------------------------------------- 1 | title: Rocks And Diamonds 2 | description: A classic game of rock-dodging, boulder-dashing action. 3 | author: Gadgetoid 4 | splash: 5 | file: assets/splash.png 6 | icon: 7 | file: assets/icon.png 8 | url: https://github.com/32blit/rocks-and-diamonds 9 | version: v0.0.5 10 | 11 | -------------------------------------------------------------------------------- /rocks-and-diamonds.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "32blit.hpp" 4 | #include "assets.hpp" 5 | 6 | void init(); 7 | void update(uint32_t time); 8 | void render(uint32_t time); 9 | 10 | void update_camera(uint32_t time); 11 | 12 | void update_level(blit::Timer &timer); 13 | void animate_level(blit::Timer &timer); -------------------------------------------------------------------------------- /ci/install_sdl_vs.sh: -------------------------------------------------------------------------------- 1 | if [ ! -f 32blit/vs/sdl/include/SDL_image.h ]; then 2 | curl https://libsdl.org/release/SDL2-devel-2.0.10-VC.zip -o SDL2.zip 3 | curl https://www.libsdl.org/projects/SDL_image/release/SDL2_image-devel-2.0.5-VC.zip -o SDL2_image.zip 4 | 5 | unzip SDL2.zip -d 32blit/vs/sdl 6 | unzip SDL2_image.zip -d 32blit/vs/sdl 7 | 8 | # move dirs up 9 | mv 32blit/vs/sdl/SDL2-2.0.10/* 32blit/vs/sdl 10 | cp -r 32blit/vs/sdl/SDL2_image-2.0.5/* 32blit/vs/sdl 11 | fi 12 | -------------------------------------------------------------------------------- /assets/level00.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 3,3,3,3,3,3,3,3, 7 | 3,49,2,2,2,2,17,3, 8 | 3,2,2,18,18,18,18,3, 9 | 3,17,3,3,3,3,18,3, 10 | 3,33,3,2,5,3,18,3, 11 | 3,2,3,2,18,3,18,3, 12 | 3,2,2,2,18,18,18,3, 13 | 3,3,3,3,3,3,3,3 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /assets.yml: -------------------------------------------------------------------------------- 1 | # Define an output target for the asset builder 2 | # in this case we want a CSource (and implicitly also a header file) 3 | # type auto-detection will notice the ".cpp" and act accordingly 4 | assets.cpp: 5 | prefix: asset_ 6 | # Include assets/sprites.png 7 | # and place it in a variable named "sprites" 8 | # Since it ends in ".png" the builder will run "sprites_packed" to convert our source file 9 | assets/sprites.png: 10 | name: sprites 11 | palette: assets/sprites.act 12 | strict: true # Fail if a colour does not exist in the palette 13 | transparent: 255,0,255 14 | 15 | # Include assets/level.tmx 16 | # and place it in a variable named "level" 17 | # Since it ends in ".tmx" the builder will run "map_tiled" to convert our source file 18 | assets/level*.tmx: 19 | name: 20 | empty_tile: 0 21 | output_struct: true 22 | -------------------------------------------------------------------------------- /splash.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 7 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 8 | 3,2,17,17,17,17,2,2,2,18,18,18,18,2,2,3, 9 | 3,2,17,2,2,2,17,2,2,18,2,2,2,18,2,3, 10 | 3,2,17,2,2,2,17,2,2,18,2,2,2,18,2,3, 11 | 3,2,17,17,17,17,2,2,2,18,2,2,2,18,2,3, 12 | 3,2,17,2,2,2,17,2,2,18,2,2,2,18,2,3, 13 | 3,2,17,2,2,2,17,2,2,18,2,2,2,18,2,3, 14 | 3,2,17,2,2,2,17,2,2,18,2,2,2,18,2,3, 15 | 3,2,17,2,2,2,17,2,2,18,18,18,18,2,2,3, 16 | 3,49,2,2,2,2,2,2,2,2,2,2,2,2,97,3, 17 | 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Basic parameters; check that these match your project / environment 2 | cmake_minimum_required(VERSION 3.8) 3 | 4 | project(rocks-and-diamonds) 5 | set(PROJECT_SOURCE rocks-and-diamonds.cpp rocks-and-diamonds.hpp) 6 | set(PROJECT_DISTRIBS LICENSE README.md) 7 | 8 | # Build configuration; approach this with caution! 9 | if(MSVC) 10 | add_compile_options("/W4" "/wd4244" "/wd4324") 11 | else() 12 | add_compile_options("-Wall" "-Wextra" "-Wdouble-promotion") 13 | endif() 14 | find_package(32BLIT CONFIG REQUIRED PATHS ../ /opt) 15 | 16 | blit_executable (${PROJECT_NAME} ${PROJECT_SOURCE}) 17 | blit_assets_yaml (${PROJECT_NAME} assets.yml) 18 | blit_metadata (${PROJECT_NAME} metadata.yml) 19 | add_custom_target (flash DEPENDS ${PROJECT_NAME}.flash) 20 | 21 | # setup release packages 22 | install (FILES ${PROJECT_DISTRIBS} DESTINATION .) 23 | set (CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF) 24 | set (CPACK_GENERATOR "ZIP" "TGZ") 25 | include (CPack) 26 | -------------------------------------------------------------------------------- /assets/level01.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 7 | 3,3,3,18,3,3,17,3,3,18,3,3,3,2,5,3, 8 | 3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,3, 9 | 3,2,3,3,3,3,2,3,3,3,3,3,3,17,2,3, 10 | 3,2,3,2,2,2,2,2,2,2,2,2,3,18,2,3, 11 | 3,2,3,2,2,2,2,2,2,2,2,2,3,2,17,3, 12 | 3,2,3,2,2,2,18,2,2,2,2,2,3,2,18,3, 13 | 3,2,3,2,2,18,18,18,2,2,2,2,3,17,2,3, 14 | 3,2,3,3,3,3,3,3,3,3,3,2,3,18,2,3, 15 | 3,2,17,17,3,17,3,2,2,2,3,2,3,2,17,3, 16 | 3,2,18,18,3,33,3,2,2,2,3,2,3,2,18,3, 17 | 3,2,3,3,3,2,3,3,3,3,3,2,3,17,2,3, 18 | 3,2,3,17,3,2,3,17,3,17,3,2,3,18,2,3, 19 | 3,2,3,18,2,2,2,2,2,2,2,2,2,2,2,3, 20 | 3,49,3,18,2,2,2,2,2,2,2,2,2,2,2,3, 21 | 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Phil Howard 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 | -------------------------------------------------------------------------------- /assets/level03.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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 | 3,49,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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 | 3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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 | 3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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 | 3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1, 11 | 3,2,2,17,2,17,2,17,2,17,2,17,2,17,2,17,2,17,2,17,2,3,1,1,3,2,2,2,2,2,2,2,2,2,2,17,2,18,2,18,3,1,1,1,1,1, 12 | 3,2,2,2,17,2,17,2,17,2,17,2,17,2,17,2,17,2,17,18,2,3,1,1,3,2,5,2,2,2,2,2,2,2,2,2,17,2,2,2,3,1,1,1,1,1, 13 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,17,2,18,3,1,1,1,1,1, 14 | 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,2,17,2,3,1,1,1,1,1, 15 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,17,3,1,1,1,1,1, 16 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,3,1,1,1,1,1, 17 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,17,2,17,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,17,3,1,1,1,1,1, 18 | 1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,2,17,2,3,1,1,1,1,1, 19 | 1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1,1,3,17,2,2,2,2,2,2,2,2,2,2,2,17,2,18,3,1,1,1,1,1, 20 | 1,1,1,1,1,3,2,18,2,2,2,2,2,2,2,18,2,2,2,19,2,3,1,1,3,2,17,2,2,2,2,2,2,2,2,2,17,2,2,2,3,1,1,1,1,1, 21 | 1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1,1,3,2,2,17,2,2,2,2,2,2,2,2,2,18,2,18,3,1,1,1,1,1, 22 | 1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,1,1,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1, 23 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,17,2,2,3,1,1,3,2,2,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 24 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,17,2,2,3,1,1,3,2,2,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 25 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,17,2,2,3,1,1,3,2,2,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 26 | 1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,1,1,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1, 27 | 1,1,1,1,1,3,2,17,17,2,2,2,2,2,2,2,2,2,2,2,2,3,1,1,3,2,2,17,2,2,19,2,2,17,2,2,19,2,2,2,3,1,1,1,1,1, 28 | 1,1,1,1,1,3,2,2,2,17,17,2,2,2,18,2,2,2,2,18,2,3,1,1,3,2,18,2,2,18,2,2,18,2,2,18,2,2,2,2,3,1,1,1,1,1, 29 | 1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1,1,3,17,2,2,19,2,2,19,2,2,19,2,2,2,17,2,3,1,1,1,1,1, 30 | 1,1,1,1,1,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,1,1,1,1,1, 31 | 1,1,1,1,1,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,3,1,1,1,1,1,1,1, 32 | 1,1,1,1,1,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,3,1,1,1,1,1,1,1, 33 | 1,1,1,1,1,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,3,1,1,1,1,1,1,1, 34 | 1,1,1,1,3,3,2,3,3,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,1,1,1,1,1,1,1, 35 | 1,1,1,1,3,2,2,2,3,1,1,1,1,1,1,1,1,1,1,1,3,2,17,2,2,2,2,2,2,2,2,2,2,2,2,2,17,2,3,1,1,1,1,1,1,1, 36 | 1,1,1,1,3,2,2,2,3,1,1,1,1,1,1,1,1,1,1,1,3,2,18,2,3,3,3,3,17,2,17,3,3,3,3,2,2,17,3,1,1,1,1,1,1,1, 37 | 1,1,1,1,3,2,2,2,3,3,3,3,3,3,3,3,3,3,1,1,3,2,2,2,3,1,1,3,18,2,18,3,1,1,3,2,2,2,3,3,3,3,1,1,1,1, 38 | 1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,3,1,1,3,2,17,2,3,1,1,3,3,3,3,3,1,1,3,2,2,2,2,2,2,3,1,1,1,1, 39 | 1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,3,1,1,3,2,2,2,3,1,1,1,1,1,1,1,1,1,3,2,2,17,2,18,2,3,1,1,1,1, 40 | 1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,3,1,1,3,2,18,2,3,1,1,1,1,1,1,1,1,1,3,2,17,2,2,2,2,3,1,1,1,1, 41 | 1,1,1,1,3,18,2,18,3,3,3,3,3,3,2,2,2,3,1,1,3,2,17,2,3,1,1,1,1,1,1,1,1,1,3,2,2,2,3,3,3,3,1,1,1,1, 42 | 1,1,1,1,3,2,17,2,3,1,1,1,1,3,2,2,2,3,1,1,3,2,18,2,3,1,1,3,3,3,3,3,3,3,3,2,2,2,3,1,1,1,1,1,1,1, 43 | 1,1,1,1,3,18,2,18,3,1,1,1,1,3,2,2,2,3,1,1,3,2,2,2,3,1,1,3,2,2,2,2,2,2,2,2,2,17,3,1,1,1,1,1,1,1, 44 | 1,1,1,1,3,2,17,2,3,1,1,1,1,3,2,2,2,3,1,1,3,2,17,2,3,1,1,3,2,2,2,3,3,3,3,2,17,2,3,1,1,1,1,1,1,1, 45 | 1,1,1,1,3,18,2,18,3,1,1,1,1,3,2,2,2,3,1,1,3,2,2,2,3,1,1,3,2,2,2,3,1,1,3,2,2,2,3,1,1,1,1,1,1,1, 46 | 1,1,1,1,3,2,17,2,3,3,3,3,3,3,2,2,2,3,1,1,3,2,18,2,3,1,1,3,2,17,2,3,1,1,3,2,17,2,3,3,3,3,1,1,1,1, 47 | 1,1,1,1,3,18,2,18,2,2,2,2,2,2,2,2,2,3,1,1,3,2,17,2,3,1,1,3,2,33,2,3,1,1,3,17,2,2,18,18,18,3,1,1,1,1, 48 | 1,1,1,1,3,2,17,2,2,2,2,2,2,2,2,2,2,3,3,3,3,2,18,2,3,1,1,3,2,2,2,3,1,1,3,2,18,2,18,18,18,3,1,1,1,1, 49 | 1,1,1,1,3,18,2,18,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1,1,3,2,2,2,3,1,1,3,2,2,2,18,18,18,3,1,1,1,1, 50 | 1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,3,1,1,3,3,3,3,3,3,3,3,1,1,1,1, 51 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # Build Github Action, to run a test build on all targets 2 | # (Linux, Blit, MacOS, Visual Studio) when the project is checked in. 3 | # 4 | # Thanks in large part to the phenomenal examples of DaftFreak. 5 | 6 | name: Build 7 | 8 | on: 9 | push: 10 | branches: 11 | - '**' # only run on branches 12 | pull_request: 13 | release: 14 | types: [created] 15 | 16 | env: 17 | BUILD_TYPE: Release 18 | EM_VERSION: 2.0.18 # Emscripten version 19 | EM_CACHE_FOLDER: 'emsdk-cache' # Cache for Emscripten libs 20 | 21 | jobs: 22 | 23 | build: 24 | 25 | name: ${{matrix.name}} 26 | strategy: 27 | matrix: 28 | include: 29 | - os: ubuntu-20.04 30 | name: Linux 31 | release-suffix: LIN64 32 | cmake-args: -D32BLIT_DIR=$GITHUB_WORKSPACE/32blit-sdk 33 | apt-packages: libsdl2-dev libsdl2-image-dev libsdl2-net-dev python3-setuptools 34 | 35 | - os: ubuntu-20.04 36 | name: STM32 37 | release-suffix: STM32 38 | cmake-args: -DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/32blit-sdk/32blit.toolchain 39 | apt-packages: gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib python3-setuptools 40 | 41 | - os: ubuntu-20.04 42 | pico-sdk: true 43 | name: PicoSystem 44 | cache-key: picosystem 45 | release-suffix: PicoSystem 46 | cmake-args: -DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/32blit-sdk/pico.toolchain -DPICO_BOARD=pimoroni_picosystem 47 | apt-packages: gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib python3-setuptools 48 | 49 | - os: ubuntu-20.04 50 | name: Emscripten 51 | release-suffix: WEB 52 | cmake-args: -D32BLIT_DIR=$GITHUB_WORKSPACE/32blit-sdk 53 | cmake-prefix: emcmake 54 | apt-packages: python3-setuptools 55 | 56 | - os: macos-latest 57 | name: macOS 58 | release-suffix: MACOS 59 | cmake-args: -D32BLIT_DIR=$GITHUB_WORKSPACE/32blit-sdk 60 | brew-packages: sdl2 sdl2_image sdl2_net 61 | 62 | - os: windows-latest 63 | name: Visual Studio 64 | release-suffix: WIN64 65 | cmake-args: -D32BLIT_DIR=$GITHUB_WORKSPACE/32blit-sdk -DSDL2_DIR=$GITHUB_WORKSPACE/32blit-sdk/vs/sdl 66 | 67 | runs-on: ${{matrix.os}} 68 | 69 | env: 70 | RELEASE_FILE: ${{github.event.repository.name}}-${{github.event.release.tag_name}}-${{matrix.release-suffix}} 71 | 72 | steps: 73 | # Check out the main repo 74 | - name: Checkout 75 | uses: actions/checkout@v2 76 | with: 77 | path: main 78 | 79 | # Check out the 32Blit API we build against 80 | - name: Checkout 32Blit API 81 | uses: actions/checkout@v2 82 | with: 83 | repository: 32blit/32blit-sdk 84 | path: 32blit-sdk 85 | 86 | # pico sdk/extras for some builds 87 | - name: Checkout Pico SDK 88 | if: matrix.pico-sdk 89 | uses: actions/checkout@v2 90 | with: 91 | repository: raspberrypi/pico-sdk 92 | path: pico-sdk 93 | submodules: true 94 | 95 | - name: Checkout Pico Extras 96 | if: matrix.pico-sdk 97 | uses: actions/checkout@v2 98 | with: 99 | repository: raspberrypi/pico-extras 100 | path: pico-extras 101 | 102 | # Linux dependencies 103 | - name: Install Linux deps 104 | if: runner.os == 'Linux' 105 | run: | 106 | sudo apt update && sudo apt install ${{matrix.apt-packages}} 107 | pip3 install 32blit 108 | 109 | # MacOS dependencies 110 | - name: Install macOS deps 111 | if: runner.os == 'macOS' 112 | run: | 113 | brew install ${{matrix.brew-packages}} 114 | python3 -m pip install 32blit 115 | 116 | # Windows dependencies 117 | - name: Install Windows deps 118 | if: runner.os == 'Windows' 119 | shell: bash 120 | run: | 121 | python -m pip install 32blit 122 | 123 | # Emscripten SDK setup 124 | - name: Setup Emscripten cache 125 | if: matrix.name == 'Emscripten' 126 | id: cache-system-libraries 127 | uses: actions/cache@v2 128 | with: 129 | path: ${{env.EM_CACHE_FOLDER}} 130 | key: ${{env.EM_VERSION}}-${{runner.os}} 131 | 132 | - name: Setup Emscripten 133 | if: matrix.name == 'Emscripten' 134 | uses: mymindstorm/setup-emsdk@v7 135 | with: 136 | version: ${{env.EM_VERSION}} 137 | actions-cache-folder: ${{env.EM_CACHE_FOLDER}} 138 | 139 | - name: Pre-build Emscripten ports 140 | if: matrix.name == 'Emscripten' 141 | run: embuilder.py build sdl2 sdl2-image-jpg sdl2-net 142 | 143 | # Set up the cmake build environment 144 | - name: Create Build Environment 145 | run: cmake -E make_directory ${{runner.workspace}}/main/build 146 | 147 | # Ask cmake to build the makefiles 148 | - name: Configure CMake 149 | shell: bash 150 | working-directory: ${{runner.workspace}}/main/build 151 | run: ${{matrix.cmake-prefix}} cmake $GITHUB_WORKSPACE/main -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCPACK_PACKAGE_FILE_NAME=${{env.RELEASE_FILE}} ${{matrix.cmake-args}} 152 | 153 | # And then run the build itself 154 | - name: Build 155 | working-directory: ${{runner.workspace}}/main/build 156 | shell: bash 157 | run: | 158 | cmake --build . --config $BUILD_TYPE -j 2 159 | 160 | # When it's a release, generate tar/zip files of the build 161 | - name: Package Release 162 | if: github.event_name == 'release' && matrix.release-suffix != '' 163 | shell: bash 164 | working-directory: ${{runner.workspace}}/main/build 165 | run: | 166 | cmake --build . --config $BUILD_TYPE --target package 167 | 168 | # Push the tar file to the release 169 | - name: Upload tar 170 | if: github.event_name == 'release' && matrix.release-suffix != '' 171 | uses: actions/upload-release-asset@v1 172 | env: 173 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 174 | with: 175 | asset_path: ${{runner.workspace}}/main/build/${{env.RELEASE_FILE}}.tar.gz 176 | upload_url: ${{github.event.release.upload_url}} 177 | asset_name: ${{env.RELEASE_FILE}}.tar.gz 178 | asset_content_type: application/octet-stream 179 | 180 | # Push the zip file to the release 181 | - name: Upload zip 182 | if: github.event_name == 'release' && matrix.release-suffix != '' 183 | uses: actions/upload-release-asset@v1 184 | env: 185 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 186 | with: 187 | asset_path: ${{runner.workspace}}/main/build/${{env.RELEASE_FILE}}.zip 188 | upload_url: ${{github.event.release.upload_url}} 189 | asset_name: ${{env.RELEASE_FILE}}.zip 190 | asset_content_type: application/zip 191 | -------------------------------------------------------------------------------- /assets/level02.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 7 | 3,49,3,17,2,2,2,2,2,2,3,3,3,2,2,2,2,2,3,17,18,17,3,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 8 | 3,2,3,17,2,2,2,2,2,2,2,3,2,2,17,17,17,2,3,18,17,18,3,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 9 | 3,2,3,17,2,2,17,2,17,2,2,2,2,2,17,18,18,2,3,17,18,17,3,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 10 | 3,2,2,2,2,2,17,2,17,2,2,2,2,2,17,2,2,2,3,2,2,2,3,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 11 | 3,3,3,3,3,3,3,18,3,3,3,3,3,18,3,3,3,3,3,2,2,2,3,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 12 | 3,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,3,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 13 | 3,17,2,17,2,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,17,2,3,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 14 | 3,17,2,17,2,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,17,3,3,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 15 | 3,17,18,17,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1,33,1,3,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 16 | 3,17,2,17,2,2,2,2,17,17,17,2,3,3,3,2,17,2,3,1,1,1,3,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 17 | 3,17,2,17,2,2,2,2,2,18,17,2,2,18,3,2,17,2,3,1,1,1,3,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 18 | 3,17,18,17,2,2,2,2,17,17,17,2,3,3,3,2,2,2,2,1,1,1,3,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 19 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,3,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 20 | 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 21 | 3,17,2,2,2,18,17,2,2,2,2,2,2,2,2,2,2,2,3,2,17,5,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 22 | 3,17,2,2,2,17,18,2,2,2,2,2,2,2,2,2,2,2,3,2,2,17,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 23 | 3,17,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,17,3,2,2,18,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 24 | 3,2,2,2,2,2,2,2,2,1,1,1,1,18,1,1,1,2,2,2,2,2,17,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 25 | 3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 26 | 3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 27 | 3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 28 | 3,2,3,2,2,2,2,2,17,17,2,2,2,17,17,2,2,2,2,2,2,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 29 | 3,2,3,2,2,2,2,17,17,17,17,2,17,17,17,17,2,2,2,2,2,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 30 | 3,2,3,2,2,2,17,17,17,17,17,17,17,17,17,17,17,2,2,2,2,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 31 | 3,2,3,2,2,2,17,17,17,17,17,17,17,17,17,17,17,2,2,2,2,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 32 | 3,2,3,2,2,2,2,17,17,17,17,17,17,17,17,17,2,2,2,2,2,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 33 | 3,2,3,2,2,2,2,2,17,17,17,17,17,17,17,2,2,2,2,2,2,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 34 | 3,2,3,2,2,2,2,2,2,17,17,17,17,17,2,2,2,2,2,2,2,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 35 | 3,2,3,2,2,2,2,2,2,2,17,17,17,2,2,2,2,2,2,2,2,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 36 | 3,2,3,2,2,2,2,2,2,2,2,17,2,2,2,2,2,2,2,2,2,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 37 | 3,2,3,3,3,3,3,3,3,3,3,17,3,3,3,3,3,3,3,3,3,3,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 38 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 39 | 3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 40 | 3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 41 | 3,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 42 | 3,2,2,2,2,2,2,2,2,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 43 | 3,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 44 | 3,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 45 | 3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 46 | 3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 47 | 3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 48 | 3,2,2,2,2,2,2,1,1,1,1,2,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 49 | 3,2,2,2,2,2,2,2,1,1,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 50 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 51 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 52 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 53 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 54 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 55 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 56 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 57 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 58 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 59 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 60 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 61 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 62 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 63 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 64 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 65 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 66 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 67 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 68 | 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3, 69 | 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /rocks-and-diamonds.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "rocks-and-diamonds.hpp" 7 | 8 | using namespace blit; 9 | 10 | #define PLAYER_TOP (player.position.y) 11 | #define PLAYER_BOTTOM (player.position.y + player.size.y) 12 | #define PLAYER_RIGHT (player.position.x + player.size.x) 13 | #define PLAYER_LEFT (player.position.x) 14 | 15 | const Point P_LEFT(-1, 0); 16 | const Point P_RIGHT(1, 0); 17 | const Point P_BELOW(0, 1); 18 | const Point P_ABOVE(0, -1); 19 | 20 | const Point P_ALEFT = P_LEFT + P_ABOVE; 21 | const Point P_ARIGHT = P_RIGHT + P_ABOVE; 22 | const Point P_BLEFT = P_LEFT + P_BELOW; 23 | const Point P_BRIGHT = P_RIGHT + P_BELOW; 24 | 25 | const Size LEVEL_SIZE(64, 64); 26 | 27 | const void* levels[] = { 28 | &asset_assets_level00_tmx, 29 | &asset_assets_level01_tmx, 30 | &asset_assets_level02_tmx, 31 | &asset_assets_level03_tmx 32 | }; 33 | 34 | uint8_t *level_data; 35 | 36 | Timer timer_level_update; 37 | Timer timer_level_animate; 38 | TileMap* level; 39 | 40 | struct Feedback { 41 | bool rock_thunk; 42 | }; 43 | 44 | struct Player { 45 | Point start; 46 | Point position; 47 | Point screen_location; 48 | uint32_t score; 49 | Vec2 camera; 50 | Point size = Point(1, 1); 51 | bool facing = true; 52 | bool has_key; 53 | uint32_t level; 54 | bool dead; 55 | }; 56 | 57 | Player player; 58 | 59 | Feedback feedback; 60 | 61 | Mat3 camera; 62 | 63 | enum entityType { 64 | // Terrain 65 | NOTHING = 0x00, 66 | DIRT = 0x01, 67 | WALL = 0x02, 68 | STAIRS = 0x03, 69 | LOCKED_STAIRS = 0x04, 70 | 71 | // Rocks and diamonds 72 | ROCK = 0x10, 73 | DIAMOND = 0x11, 74 | 75 | // Player animations... or lack thereof 76 | PLAYER = 0x30, 77 | PLAYER_FL = 0x31, 78 | PLAYER_SQUASHED = 0x3e, 79 | PLAYER_DEAD = 0x3f, 80 | 81 | // Collectable entities that aren't diamonds 82 | KEY_SILVER = 0x20, 83 | KEY_GOLD = 0x21, 84 | 85 | // Animations, ho boy this is ugly! 86 | DIRT_ANIM_1 = 0x50, 87 | DIRT_ANIM_2 = 0x51, 88 | DIRT_ANIM_3 = 0x52, 89 | DIRT_ANIM_4 = 0x53, 90 | 91 | // So ugly, oh boy! 92 | BOMB_ANIM_1 = 0x60, 93 | BOMB_ANIM_2 = 0x61, 94 | BOMB_ANIM_3 = 0x62, 95 | BOMB_ANIM_4 = 0x63, 96 | BOMB_ANIM_5 = 0x64, 97 | BOMB_ANIM_6 = 0x65, 98 | }; 99 | 100 | // Line-interrupt callback for level->draw that applies our camera transformation 101 | // This can be expanded to add effects like camera shake, wavy dream-like stuff, all the fun! 102 | Mat3 level_line_interrupt_callback(uint8_t y) { 103 | (void)y; // Camera is updated elsewhere and is scanline-independent 104 | return camera; 105 | }; 106 | 107 | void update_camera(uint32_t time) { 108 | (void)time; 109 | 110 | static uint32_t thunk_a_bunch = 0; 111 | // Create a camera transform that centers around the player's position 112 | if(player.camera.x < player.position.x) { 113 | player.camera.x += 0.1f; 114 | } 115 | if(player.camera.x > player.position.x) { 116 | player.camera.x -= 0.1f; 117 | } 118 | if(player.camera.y < player.position.y) { 119 | player.camera.y += 0.1f; 120 | } 121 | if(player.camera.y > player.position.y) { 122 | player.camera.y -= 0.1f; 123 | } 124 | 125 | if(feedback.rock_thunk) { 126 | thunk_a_bunch = 10; 127 | feedback.rock_thunk = 0; 128 | } 129 | 130 | camera = Mat3::identity(); 131 | camera *= Mat3::translation(Vec2(player.camera.x * 8.0f, player.camera.y * 8.0f)); // offset to middle of world 132 | camera *= Mat3::translation(Vec2(-screen.bounds.w / 2, -screen.bounds.h / 2)); // transform to centre of framebuffer 133 | 134 | if(thunk_a_bunch){ 135 | camera *= Mat3::translation(Vec2( 136 | float(blit::random() & 0x03) - 1.5f, 137 | float(blit::random() & 0x03) - 1.5f 138 | )); 139 | thunk_a_bunch--; 140 | vibration = thunk_a_bunch / 10.0f; 141 | } 142 | 143 | 144 | } 145 | 146 | Point level_first(entityType entity) { 147 | for(auto x = 0; x < LEVEL_SIZE.w; x++) { 148 | for(auto y = 0; y < LEVEL_SIZE.h; y++) { 149 | if (level_data[y * LEVEL_SIZE.w + x] == entity) { 150 | return Point(x, y); 151 | } 152 | } 153 | } 154 | return Point(-1, -1); 155 | } 156 | 157 | void level_set(Point location, entityType entity) { 158 | level_data[location.y * LEVEL_SIZE.w + location.x] = entity; 159 | } 160 | 161 | bool player_at(Point location) { 162 | return (player.position.x == location.x && player.position.y == location.y); 163 | } 164 | 165 | entityType level_get(Point location) { 166 | static Rect level_bounds(Point(0, 0), LEVEL_SIZE); 167 | if(!level_bounds.contains(location)) { 168 | return WALL; 169 | } 170 | entityType entity = (entityType)level_data[location.y * LEVEL_SIZE.w + location.x]; 171 | if(entity == NOTHING && player_at(location)) { 172 | entity = PLAYER; 173 | } 174 | return entity; 175 | } 176 | 177 | void level_set(Point location, entityType entity, bool not_nothing) { 178 | if(not_nothing) { 179 | if(level_get(location) != NOTHING) { 180 | level_set(location, entity); 181 | } 182 | } else { 183 | level_set(location, entity); 184 | } 185 | } 186 | 187 | void animate_level(Timer &timer) { 188 | (void)timer; 189 | 190 | Point location = Point(0, 0); 191 | for(location.y = LEVEL_SIZE.h - 1; location.y > -1; location.y--) { 192 | for(location.x = 0; location.x < LEVEL_SIZE.w + 1; location.x++) { 193 | entityType current = level_get(location); 194 | 195 | if(current == DIRT_ANIM_4) { 196 | level_set(location, NOTHING); 197 | } else if(current == DIRT_ANIM_3) { 198 | level_set(location, DIRT_ANIM_4); 199 | } else if(current == DIRT_ANIM_2) { 200 | level_set(location, DIRT_ANIM_3); 201 | } else if(current == DIRT_ANIM_1) { 202 | level_set(location, DIRT_ANIM_2); 203 | } 204 | 205 | if(current == BOMB_ANIM_1) { 206 | level_set(location, BOMB_ANIM_2); 207 | } else if(current == BOMB_ANIM_2) { 208 | level_set(location, BOMB_ANIM_3); 209 | } else if(current == BOMB_ANIM_3) { 210 | level_set(location, BOMB_ANIM_4); 211 | } else if(current == BOMB_ANIM_4) { 212 | level_set(location, BOMB_ANIM_5); 213 | } else if(current == BOMB_ANIM_5) { 214 | level_set(location, BOMB_ANIM_6); 215 | } else if(current == BOMB_ANIM_6) { 216 | level_set(location, NOTHING); 217 | level_set(location + P_BELOW, DIRT_ANIM_1, true); 218 | level_set(location + P_ABOVE, DIRT_ANIM_1, true); 219 | level_set(location + P_RIGHT, DIRT_ANIM_1, true); 220 | level_set(location + P_LEFT, DIRT_ANIM_1, true); 221 | level_set(location + P_BRIGHT, DIRT_ANIM_1, true); 222 | level_set(location + P_ARIGHT, DIRT_ANIM_1, true); 223 | level_set(location + P_BLEFT, DIRT_ANIM_1, true); 224 | level_set(location + P_ALEFT, DIRT_ANIM_1, true); 225 | } 226 | } 227 | } 228 | } 229 | 230 | void update_level(Timer &timer) { 231 | (void)timer; 232 | 233 | Point location = Point(0, 0); 234 | for(location.y = LEVEL_SIZE.h - 1; location.y > 0; location.y--) { 235 | for(location.x = 0; location.x < LEVEL_SIZE.w; location.x++) { 236 | Point location_below = location + P_BELOW; 237 | entityType current = level_get(location); 238 | entityType below = level_get(location_below); 239 | 240 | for(entityType check_entity : {ROCK, DIAMOND}) { 241 | if(current == check_entity) { 242 | if (below == NOTHING) { 243 | // If the space underneath is empty, fall down 244 | level_set(location, NOTHING); 245 | level_set(location_below, check_entity); 246 | 247 | if(check_entity == ROCK) { 248 | // Add a little *THUNK* effect for rocks falling directly down 249 | Point location_land = location_below + P_BELOW; 250 | switch (level_get(location_land)) { 251 | case WALL: 252 | feedback.rock_thunk = true; 253 | break; 254 | case PLAYER: 255 | player.dead = true; 256 | feedback.rock_thunk = true; 257 | level_set(location_land, PLAYER_SQUASHED); 258 | default: 259 | break; 260 | } 261 | } 262 | } else if (below == PLAYER_SQUASHED && check_entity == ROCK) { 263 | level_set(location, NOTHING); 264 | level_set(location_below, PLAYER_DEAD); 265 | } else if (below == ROCK || below == DIAMOND) { 266 | // If the space below is a rock or a diamond, check to the left/right 267 | // and "roll" down the stack 268 | entityType left = level_get(location + P_LEFT); 269 | entityType below_left = level_get(location + P_BLEFT); 270 | entityType right = level_get(location + P_RIGHT); 271 | entityType below_right = level_get(location + P_BRIGHT); 272 | 273 | if(left == NOTHING && below_left == NOTHING){ 274 | level_set(location, NOTHING); 275 | level_set(location + Point(-1, 1), check_entity); 276 | } else if(right == NOTHING && below_right == NOTHING){ 277 | level_set(location, NOTHING); 278 | level_set(location + Point(1, 1), check_entity); 279 | } 280 | } 281 | } 282 | } 283 | 284 | } 285 | } 286 | } 287 | 288 | void new_game(uint32_t level) { 289 | // Get a pointer to the map header 290 | TMX *tmx = (TMX *)levels[level]; 291 | 292 | // Bail if the map is oversized 293 | if(tmx->width > LEVEL_SIZE.w) return; 294 | if(tmx->height > LEVEL_SIZE.h) return; 295 | 296 | // Clear the level data 297 | memset(level_data, 0, LEVEL_SIZE.area()); 298 | 299 | // Load the level data from the map memory 300 | for(auto x = 0u; x < tmx->width; x++) { 301 | for(auto y = 0u; y < tmx->height; y++) { 302 | auto src = y * tmx->width + x; 303 | auto dst = y * LEVEL_SIZE.w + x; 304 | level_data[dst] = tmx->data[src]; 305 | } 306 | } 307 | 308 | player.start = level_first(PLAYER); 309 | level_set(player.start, NOTHING); 310 | player.position = player.start; 311 | player.camera = Vec2(player.position); 312 | player.has_key = false; 313 | player.score = 0; 314 | player.dead = false; 315 | 316 | player.screen_location = Point(screen.bounds.w / 2, screen.bounds.h / 2); 317 | player.screen_location += Point(1, 1); 318 | } 319 | 320 | void init() { 321 | set_screen_mode(ScreenMode::lores); 322 | 323 | // Load the spritesheet from the linked binary blob 324 | screen.sprites = Surface::load(asset_sprites); 325 | 326 | // Allocate memory for the writeable copy of the level 327 | level_data = (uint8_t *)malloc(LEVEL_SIZE.area()); 328 | 329 | // Load our level data into the TileMap 330 | level = new TileMap((uint8_t *)level_data, nullptr, Size(LEVEL_SIZE.w, LEVEL_SIZE.h), screen.sprites); 331 | 332 | timer_level_update.init(update_level, 250, -1); 333 | timer_level_update.start(); 334 | 335 | timer_level_animate.init(animate_level, 100, -1); 336 | timer_level_animate.start(); 337 | 338 | new_game(0); 339 | } 340 | 341 | void render(uint32_t time) { 342 | (void)time; 343 | 344 | screen.pen = Pen(0, 0, 0); 345 | screen.clear(); 346 | 347 | // Draw our level 348 | level->draw(&screen, Rect(0, 0, screen.bounds.w, screen.bounds.h), level_line_interrupt_callback); 349 | 350 | // Draw our character sprite 351 | if(!player.dead) { 352 | screen.sprite(player.facing ? entityType::PLAYER : entityType::PLAYER_FL, player.screen_location); 353 | } 354 | 355 | // Draw the header bar 356 | screen.pen = Pen(255, 255, 255); 357 | screen.rectangle(Rect(0, 0, screen.bounds.w, 10)); 358 | screen.pen = Pen(0, 0, 0); 359 | screen.text("Level: " + std::to_string(player.level) + " Score: " + std::to_string(player.score), minimal_font, Point(2, 2)); 360 | 361 | if(player.has_key) { 362 | screen.sprite(entityType::KEY_SILVER, Point(screen.bounds.w - 10, 1)); 363 | } 364 | // screen.text(std::to_string(player.position.x), minimal_font, Point(0, 0)); 365 | // screen.text(std::to_string(player.position.y), minimal_font, Point(0, 10)); 366 | } 367 | 368 | void update(uint32_t time) { 369 | (void)time; 370 | 371 | Point movement = Point(0, 0); 372 | 373 | if(buttons.pressed & Button::B) { 374 | new_game(player.level); 375 | } 376 | 377 | if(buttons.pressed & Button::A) { 378 | if(level_get(player.position + Point(0, 1)) == NOTHING) { 379 | level_set(player.position + Point(0, 1), BOMB_ANIM_1); 380 | } 381 | } 382 | 383 | if(!player.dead) { 384 | if(buttons.pressed & Button::DPAD_UP) { 385 | movement.y = -1; 386 | } 387 | if(buttons.pressed & Button::DPAD_DOWN) { 388 | movement.y = 1; 389 | } 390 | if(buttons.pressed & Button::DPAD_LEFT) { 391 | player.facing = false; 392 | movement.x = -1; 393 | } 394 | if(buttons.pressed & Button::DPAD_RIGHT) { 395 | player.facing = true; 396 | movement.x = 1; 397 | } 398 | 399 | player.position += movement; 400 | 401 | entityType standing_on = level_get(player.position); 402 | 403 | switch(standing_on) { 404 | case WALL: 405 | player.position -= movement; 406 | break; 407 | case ROCK: 408 | // Push rocks if there's an empty space the other side of them 409 | if(movement.x > 0 && level_get(player.position + Point(1, 0)) == NOTHING){ 410 | level_set(player.position + Point(1, 0), ROCK); 411 | level_set(player.position, NOTHING); 412 | } 413 | else if(movement.x < 0 && level_get(player.position + Point(-1, 0)) == NOTHING){ 414 | level_set(player.position + Point(-1, 0), ROCK); 415 | level_set(player.position, NOTHING); 416 | } 417 | else { 418 | player.position -= movement; 419 | } 420 | break; 421 | case DIAMOND: 422 | // Collect diamonds! 423 | player.score += 1; 424 | level_set(player.position, NOTHING); 425 | break; 426 | case DIRT: 427 | // Dig dirt! 428 | level_set(player.position, DIRT_ANIM_1); 429 | break; 430 | case KEY_SILVER: 431 | player.has_key = true; 432 | level_set(player.position, NOTHING); 433 | break; 434 | case LOCKED_STAIRS: 435 | if(player.has_key) { 436 | level_set(player.position, STAIRS); 437 | } 438 | player.position -= movement; 439 | break; 440 | case STAIRS: 441 | player.level++; 442 | new_game(player.level); 443 | break; 444 | default: 445 | break; 446 | } 447 | } 448 | 449 | update_camera(time); 450 | } --------------------------------------------------------------------------------