From 2829e7c6a7ba989662d8ce0a726bfb65d843404b Mon Sep 17 00:00:00 2001 From: SlyVTT Date: Fri, 21 Apr 2023 20:27:02 +0200 Subject: [PATCH] Initial commit --- .gitignore | 14 ++ CMakeLists.txt | 83 +++++++ README.md | 0 assets-cg/converters.py | 56 +++++ assets-cg/example.png | Bin 0 -> 3816 bytes assets-cg/font.png | Bin 0 -> 19394 bytes assets-cg/fxconv-metadata.txt | 4 + assets-cg/icon-cg.xcf | Bin 0 -> 55168 bytes assets-cg/icon-sel.png | Bin 0 -> 17593 bytes assets-cg/icon-uns.png | Bin 0 -> 13126 bytes assets-cg/levels/fxconv-metadata.txt | 8 + assets-cg/levels/level1.json | 44 ++++ assets-cg/levels/level1.tmx | 40 ++++ assets-cg/levels/level2.json | 44 ++++ assets-cg/levels/level2.tmx | 40 ++++ assets-cg/levels/level3.json | 44 ++++ assets-cg/levels/level3.tmx | 40 ++++ assets-cg/levels/tileset.png | Bin 0 -> 8483 bytes assets-cg/levels/tilesetnpp.json | 14 ++ assets-cg/levels/tilesetnpp.tsx | 4 + assets-cg/sprites/fxconv-metadata.txt | 4 + assets-cg/sprites/rectangle.png | Bin 0 -> 86 bytes assets-cg/sprites/running.png | Bin 0 -> 651 bytes assets-cg/sprites/static.png | Bin 0 -> 260 bytes assets-cg/sprites/walking.png | Bin 0 -> 372 bytes build | 3 + capture | 1 + clean | 2 + send | 1 + src/background.cpp | 97 ++++++++ src/background.h | 45 ++++ src/extrakeyboard.cpp | 160 +++++++++++++ src/extrakeyboard.h | 94 ++++++++ src/main.cpp | 308 ++++++++++++++++++++++++++ src/player.cpp | 174 +++++++++++++++ src/player.h | 69 ++++++ src/utilities.cpp | 27 +++ src/utilities.h | 6 + 38 files changed, 1426 insertions(+) create mode 100755 .gitignore create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 assets-cg/converters.py create mode 100644 assets-cg/example.png create mode 100644 assets-cg/font.png create mode 100644 assets-cg/fxconv-metadata.txt create mode 100644 assets-cg/icon-cg.xcf create mode 100644 assets-cg/icon-sel.png create mode 100644 assets-cg/icon-uns.png create mode 100644 assets-cg/levels/fxconv-metadata.txt create mode 100644 assets-cg/levels/level1.json create mode 100644 assets-cg/levels/level1.tmx create mode 100644 assets-cg/levels/level2.json create mode 100644 assets-cg/levels/level2.tmx create mode 100644 assets-cg/levels/level3.json create mode 100644 assets-cg/levels/level3.tmx create mode 100644 assets-cg/levels/tileset.png create mode 100644 assets-cg/levels/tilesetnpp.json create mode 100644 assets-cg/levels/tilesetnpp.tsx create mode 100644 assets-cg/sprites/fxconv-metadata.txt create mode 100644 assets-cg/sprites/rectangle.png create mode 100644 assets-cg/sprites/running.png create mode 100644 assets-cg/sprites/static.png create mode 100644 assets-cg/sprites/walking.png create mode 100755 build create mode 100755 capture create mode 100755 clean create mode 100755 send create mode 100644 src/background.cpp create mode 100644 src/background.h create mode 100644 src/extrakeyboard.cpp create mode 100644 src/extrakeyboard.h create mode 100644 src/main.cpp create mode 100644 src/player.cpp create mode 100644 src/player.h create mode 100644 src/utilities.cpp create mode 100644 src/utilities.h diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..baadade --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Build files +/build-fx +/build-cg +/build-cg-push +/*.g1a +/*.g3a + +# Python bytecode +__pycache__/ + +# Common IDE files +*.sublime-project +*.sublime-workspace +.vscode diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..be22e43 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,83 @@ +# Configure with [fxsdk build-fx] or [fxsdk build-cg], which provide the +# toolchain file and module path of the fxSDK + +cmake_minimum_required(VERSION 3.15) +project(Npp VERSION 1.0 LANGUAGES CXX C ASM) + +include(GenerateG3A) +include(Fxconv) + +find_package(Azur 0.1 REQUIRED) +find_package(Gint 2.9 REQUIRED) +find_package(LibProf 2.4 REQUIRED) + + +fxconv_declare_converters(assets-cg/converters.py) + +add_custom_command( + OUTPUT "${CMAKE_CURRENT_LIST_DIR}/assets-cg/levels/level1.json" + COMMENT "Convert Tiled TMX map to usable JSON file" + COMMAND tiled --export-tileset json tilesetnpp.tsx tilesetnpp.json + COMMAND find | grep .*.tmx | sed 's/.tmx//g' | xargs -l bash -c 'tiled --export-map json $$0.tmx $$0.json' + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/assets-cg/levels/ + DEPENDS assets-cg/levels/level1.tmx + + OUTPUT "${CMAKE_CURRENT_LIST_DIR}/assets-cg/levels/level2.json" + COMMENT "Convert Tiled TMX map to usable JSON file" + COMMAND tiled --export-tileset json tilesetnpp.tsx tilesetnpp.json + COMMAND find | grep .*.tmx | sed 's/.tmx//g' | xargs -l bash -c 'tiled --export-map json $$0.tmx $$0.json' + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/assets-cg/levels/ + DEPENDS assets-cg/levels/level2.tmx + + OUTPUT "${CMAKE_CURRENT_LIST_DIR}/assets-cg/levels/level3.json" + COMMENT "Convert Tiled TMX map to usable JSON file" + COMMAND tiled --export-tileset json tilesetnpp.tsx tilesetnpp.json + COMMAND find | grep .*.tmx | sed 's/.tmx//g' | xargs -l bash -c 'tiled --export-map json $$0.tmx $$0.json' + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/assets-cg/levels/ + DEPENDS assets-cg/levels/level3.tmx + + assets-cg/converters.py + assets-cg/levels/tileset.png + assets-cg/levels/tilesetnpp.tsx) + + + +set(SOURCES + src/main.cpp + src/extrakeyboard.cpp + src/utilities.cpp + src/player.cpp + src/background.cpp + # ... +) +# Shared assets, fx-9860G-only assets and fx-CG-50-only assets +set(ASSETS + # ... +) + +set(ASSETS_cg + assets-cg/font.png + + #assets-cg/sprites/walking.png + #assets-cg/sprites/running.png + #assets-cg/sprites/static.png + assets-cg/sprites/rectangle.png + + assets-cg/levels/tileset.png + assets-cg/levels/level1.json + assets-cg/levels/level2.json + assets-cg/levels/level3.json + # ... +) + +fxconv_declare_assets(${ASSETS} ${ASSETS_cg} WITH_METADATA) + +add_executable(myaddin ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}}) +target_compile_options(myaddin PRIVATE -Wall -Wextra -O3 -std=c++20) +target_link_options(myaddin PRIVATE -Wl,-Map=Build_Addin.map -Wl,--print-memory-usage) +target_link_libraries(myaddin Azur::Azur -lnum LibProf::LibProf Gint::Gint -lstdc++) + +if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50) + generate_g3a(TARGET myaddin OUTPUT "NppClone.g3a" + NAME "cgN++" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png) +endif() diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/assets-cg/converters.py b/assets-cg/converters.py new file mode 100644 index 0000000..b1917af --- /dev/null +++ b/assets-cg/converters.py @@ -0,0 +1,56 @@ +from random import randint +import fxconv +import json +import pathlib +import csv + +def convert(input, output, params, target): + if params["custom-type"] == "map": + convert_map(input, output, params, target) + return 0 + else: + return 1 + +def convert_map(input, output, params, target): + data = json.load(open(input, "r")) + + #find the tileset in use. it's a relative path (like ../tileset.tsx) + nameTileset = data["tilesets"][0]["source"].replace(".tsx","") + print(nameTileset) + #the name of the tileset without the .something + nameTilesetFree = nameTileset.split("/")[-1] + #count the number of "back" (cd ..) to locate the tileset on the computer + nbRetour = nameTileset.count("..")+1 + #create the tileset absolute path + tilesetPath = "/".join(input.split("/")[:-nbRetour]) + "/" + nameTileset + ".json" + + tileset = open(tilesetPath, "r") + data_tileset = json.load(tileset) + tileset_size = data_tileset.get("columns") + tileset.close() + + + #Extract from the json the width, height + w, h = data["width"], data["height"] + + #nbTileLayer is the number of "true" layers (without ObjectsLayer) + nbTilelayer = ["data" in i for i in data["layers"]].count(True) + + structMap = fxconv.Structure() + + structMap += fxconv.u32(w) + fxconv.u32(h) + fxconv.u32(nbTilelayer) + structMap += fxconv.ref(f"img_{nameTilesetFree}") + structMap += fxconv.u32(tileset_size) + + #generate the array of tiles from the layer + for i in range(nbTilelayer): + layer_data = bytes() + layer = data["layers"][i] + for tile in layer["data"]: + layer_data += fxconv.u16(tile) + + structMap += fxconv.ptr(layer_data) + + #generate ! + fxconv.elf(structMap, output, "_" + params["name"], **target) + diff --git a/assets-cg/example.png b/assets-cg/example.png new file mode 100644 index 0000000000000000000000000000000000000000..8826800383eeae92dade9545feaeb68faf0720f2 GIT binary patch literal 3816 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 eRZ5JQiUR=bBzf^!G-(0=0000Z%G&$ju0 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 literal 0 HcmV?d00001 diff --git a/assets-cg/fxconv-metadata.txt b/assets-cg/fxconv-metadata.txt new file mode 100644 index 0000000..5e3f5a8 --- /dev/null +++ b/assets-cg/fxconv-metadata.txt @@ -0,0 +1,4 @@ +*.png: + type: bopti-image + name_regex: (.*)\.png img_\1 + profile: p8_rgb565a diff --git a/assets-cg/icon-cg.xcf b/assets-cg/icon-cg.xcf new file mode 100644 index 0000000000000000000000000000000000000000..5b854f07eac00072a519754783db3331323791d7 GIT binary patch literal 55168 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 Ol}iESO+rylvHuUZ)lew_ literal 0 HcmV?d00001 diff --git a/assets-cg/icon-sel.png b/assets-cg/icon-sel.png new file mode 100644 index 0000000000000000000000000000000000000000..55c44a6b72c00fb728c6c0d36be3ab0efdc99b43 GIT binary patch literal 17593 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

K#MLjP^4)*Q`O=z4 z#tIeDci=5=Rn92f>lL~ec5DXO?m7Q7@xcfK9XZPcCXltSs?ln~>m$TjBh9;*saZ*} z>sBt&$AUlVV^c}IORFF1Vx7bT>m z89IAcX6m@AiT!AVX-tIGGYk><;5_qO9XT^f4ysA9FJ=CN)XvnA7p<_uEu4VKcl|)L z3CGW9L`;KMdRn?I4D$3a6rEmP=D19_xgozuXNUX+O6DNot*qPG%44EFmnzq$H@AJy zXCVsEgi3ILwCi(SJZC3kkt$knQ0?CTitMy}z^NTzZQnaRoL8xBFCbExsckj7b{8}S rgIPK`)TsqULITKNgPx?_3~a6ZCjPwI`Sy1s0Dz2yqIjLCamfDy2(zSK literal 0 HcmV?d00001 diff --git a/assets-cg/icon-uns.png b/assets-cg/icon-uns.png new file mode 100644 index 0000000000000000000000000000000000000000..2706c9dd2941f9610930dabe8cb70c92eec4203d GIT binary patch literal 13126 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

L>pmE+HMM~=8mCilopZyG6J7@ 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 literal 0 HcmV?d00001 diff --git a/assets-cg/levels/fxconv-metadata.txt b/assets-cg/levels/fxconv-metadata.txt new file mode 100644 index 0000000..1682884 --- /dev/null +++ b/assets-cg/levels/fxconv-metadata.txt @@ -0,0 +1,8 @@ +*.json: + custom-type: map + name_regex: (.*)\.json map_\1 + +tileset.png: + type: bopti-image + name: img_tilesetnpp + profile: p8_rgb565a diff --git a/assets-cg/levels/level1.json b/assets-cg/levels/level1.json new file mode 100644 index 0000000..a278493 --- /dev/null +++ b/assets-cg/levels/level1.json @@ -0,0 +1,44 @@ +{ "compressionlevel":-1, + "height":14, + "infinite":false, + "layers":[ + { + "data":[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + "height":14, + "id":1, + "name":"Background", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":25, + "x":0, + "y":0 + }, + { + "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, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":14, + "id":2, + "name":"Foreground", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":25, + "x":0, + "y":0 + }], + "nextlayerid":3, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.8.0", + "tileheight":16, + "tilesets":[ + { + "firstgid":1, + "source":"tilesetnpp.tsx" + }], + "tilewidth":16, + "type":"map", + "version":"1.8", + "width":25 +} \ No newline at end of file diff --git a/assets-cg/levels/level1.tmx b/assets-cg/levels/level1.tmx new file mode 100644 index 0000000..2201472 --- /dev/null +++ b/assets-cg/levels/level1.tmx @@ -0,0 +1,40 @@ + + + + + +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +2,0,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0,2, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +2,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,2, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 + + + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + + diff --git a/assets-cg/levels/level2.json b/assets-cg/levels/level2.json new file mode 100644 index 0000000..9985cc7 --- /dev/null +++ b/assets-cg/levels/level2.json @@ -0,0 +1,44 @@ +{ "compressionlevel":-1, + "height":14, + "infinite":false, + "layers":[ + { + "data":[2, 2, 2, 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, 0, 0, 0, 0, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 4, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 4, 2, 5, 6, 0, 7, 8, 2, 3, 0, 0, 0, 0, 0, 0, 4, 2, 2, 0, 0, 20, 2, 2, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 2, 19, 0, 0, 2, 2, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 2, 2, 0, 0, 0, 23, 24, 2, 21, 22, 0, 0, 0, 2, 2, 2, 2, 0, 0, 2, 2, 1, 0, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 2, 2, 0, 0, 0, 2, 3, 1, 4, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 2, 2, 19, 0, 20, 2, 1, 0, 1, 2, 19, 0, 20, 2, 2, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 0, 0, 4, 2, 2, 2, 2, 2, 5, 6, 1, 2, 1, 7, 8, 2, 2, 2, 2, 2, 3, 0, 0, 2, 2, 19, 0, 0, 33, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 20, 2, 2, 2, 19, 0, 33, 0, 0, 1, 0, 0, 23, 24, 2, 21, 22, 1, 0, 0, 0, 0, 33, 0, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], + "height":14, + "id":1, + "name":"Background", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":25, + "x":0, + "y":0 + }, + { + "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, 36, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 35, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 51, 0, 0, 0, 11, 0, 0, 0, 51, 0, 0, 0, 0, 0, 66, 0, 0, 0, 35, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":14, + "id":2, + "name":"Foreground", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":25, + "x":0, + "y":0 + }], + "nextlayerid":4, + "nextobjectid":3, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.8.0", + "tileheight":16, + "tilesets":[ + { + "firstgid":1, + "source":"tilesetnpp.tsx" + }], + "tilewidth":16, + "type":"map", + "version":"1.8", + "width":25 +} \ No newline at end of file diff --git a/assets-cg/levels/level2.tmx b/assets-cg/levels/level2.tmx new file mode 100644 index 0000000..7dda437 --- /dev/null +++ b/assets-cg/levels/level2.tmx @@ -0,0 +1,40 @@ + + + + + +2,2,2,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,0,0,0,0,4,2,2,2,2,2,2,2,2,2,3,0,0,0,0,4,2,2, +2,3,0,0,0,0,0,0,4,2,5,6,0,7,8,2,3,0,0,0,0,0,0,4,2, +2,0,0,20,2,2,19,0,0,0,0,0,0,0,0,0,0,0,20,2,2,19,0,0,2, +2,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,2, +2,0,0,2,2,2,2,0,0,0,23,24,2,21,22,0,0,0,2,2,2,2,0,0,2, +2,1,0,2,2,2,2,0,0,0,2,2,2,2,2,0,0,0,2,2,2,2,0,0,2, +2,0,0,2,2,2,2,0,0,0,2,3,1,4,2,0,0,0,2,2,2,2,0,0,2, +2,0,0,2,2,2,2,19,0,20,2,1,0,1,2,19,0,20,2,2,2,2,0,0,2, +2,0,0,2,2,2,2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,2,0,0,2, +2,0,0,4,2,2,2,2,2,5,6,1,2,1,7,8,2,2,2,2,2,3,0,0,2, +2,19,0,0,33,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,33,0,0,20,2, +2,2,19,0,33,0,0,1,0,0,23,24,2,21,22,1,0,0,0,0,33,0,20,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 + + + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,36,36,0,0,0,0,0,0,0,0,0,0,0,0,0,36,36,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,67,0,0,0,0,0,67,0,0,0,0,0,0,0,0,0, +0,0,66,0,0,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,0,0,66,0,0, +0,35,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0, +0,0,66,0,0,0,0,0,0,52,0,0,0,0,0,35,0,0,0,0,0,0,66,0,0, +0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0, +0,0,66,0,0,0,0,0,51,0,0,0,11,0,0,0,51,0,0,0,0,0,66,0,0, +0,35,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,65,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + + diff --git a/assets-cg/levels/level3.json b/assets-cg/levels/level3.json new file mode 100644 index 0000000..a67d7d3 --- /dev/null +++ b/assets-cg/levels/level3.json @@ -0,0 +1,44 @@ +{ "compressionlevel":-1, + "height":14, + "infinite":false, + "layers":[ + { + "data":[1, 1, 1, 1, 23, 24, 2, 2, 21, 22, 1, 1, 1, 1, 1, 23, 24, 2, 2, 21, 22, 1, 1, 1, 1, 1, 1, 1, 20, 5, 6, 0, 34, 7, 8, 21, 22, 1, 23, 24, 5, 6, 34, 0, 7, 8, 19, 1, 1, 1, 1, 1, 20, 3, 0, 0, 0, 34, 0, 0, 4, 2, 2, 2, 3, 0, 0, 34, 0, 0, 0, 4, 19, 1, 1, 1, 20, 3, 0, 0, 0, 0, 34, 0, 0, 0, 10, 2, 9, 0, 0, 0, 34, 0, 0, 0, 0, 4, 19, 1, 42, 9, 0, 0, 0, 0, 2, 2, 0, 0, 0, 26, 2, 25, 0, 0, 0, 2, 2, 1, 1, 1, 1, 10, 41, 58, 25, 0, 0, 23, 24, 2, 2, 41, 0, 0, 0, 2, 0, 0, 0, 42, 2, 2, 21, 22, 0, 0, 26, 57, 2, 0, 0, 20, 2, 2, 2, 2, 57, 0, 0, 0, 0, 0, 0, 0, 58, 2, 2, 2, 2, 19, 0, 0, 2, 2, 0, 0, 4, 2, 2, 2, 2, 2, 21, 22, 0, 0, 0, 23, 24, 2, 2, 2, 2, 2, 3, 0, 0, 2, 10, 41, 0, 0, 7, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 0, 0, 42, 9, 26, 57, 0, 0, 0, 0, 4, 2, 5, 6, 0, 0, 0, 0, 0, 7, 8, 2, 3, 0, 0, 0, 0, 58, 25, 1, 4, 19, 0, 0, 0, 0, 33, 0, 0, 0, 20, 2, 19, 0, 0, 0, 33, 0, 0, 0, 0, 20, 3, 1, 1, 1, 4, 19, 0, 0, 0, 33, 0, 0, 20, 2, 2, 2, 19, 0, 0, 33, 0, 0, 0, 20, 3, 1, 1, 1, 1, 1, 4, 21, 22, 0, 33, 23, 24, 5, 6, 1, 7, 8, 21, 22, 33, 0, 23, 24, 3, 1, 1, 1, 1, 1, 1, 1, 7, 8, 2, 2, 5, 6, 1, 1, 1, 1, 1, 7, 8, 2, 2, 5, 6, 1, 1, 1, 1], + "height":14, + "id":1, + "name":"Background", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":25, + "x":0, + "y":0 + }, + { + "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, 66, 0, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 0, 0, 66, 49, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], + "height":14, + "id":2, + "name":"Foreground", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":25, + "x":0, + "y":0 + }], + "nextlayerid":3, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.8.0", + "tileheight":16, + "tilesets":[ + { + "firstgid":1, + "source":"tilesetnpp.tsx" + }], + "tilewidth":16, + "type":"map", + "version":"1.8", + "width":25 +} \ No newline at end of file diff --git a/assets-cg/levels/level3.tmx b/assets-cg/levels/level3.tmx new file mode 100644 index 0000000..3984d01 --- /dev/null +++ b/assets-cg/levels/level3.tmx @@ -0,0 +1,40 @@ + + + + + +1,1,1,1,23,24,2,2,21,22,1,1,1,1,1,23,24,2,2,21,22,1,1,1,1, +1,1,1,20,5,6,0,34,7,8,21,22,1,23,24,5,6,34,0,7,8,19,1,1,1, +1,1,20,3,0,0,0,34,0,0,4,2,2,2,3,0,0,34,0,0,0,4,19,1,1, +1,20,3,0,0,0,0,34,0,0,0,10,2,9,0,0,0,34,0,0,0,0,4,19,1, +42,9,0,0,0,0,2,2,0,0,0,26,2,25,0,0,0,2,2,1,1,1,1,10,41, +58,25,0,0,23,24,2,2,41,0,0,0,2,0,0,0,42,2,2,21,22,0,0,26,57, +2,0,0,20,2,2,2,2,57,0,0,0,0,0,0,0,58,2,2,2,2,19,0,0,2, +2,0,0,4,2,2,2,2,2,21,22,0,0,0,23,24,2,2,2,2,2,3,0,0,2, +10,41,0,0,7,8,2,2,2,2,2,2,2,2,2,2,2,2,2,5,6,0,0,42,9, +26,57,0,0,0,0,4,2,5,6,0,0,0,0,0,7,8,2,3,0,0,0,0,58,25, +1,4,19,0,0,0,0,33,0,0,0,20,2,19,0,0,0,33,0,0,0,0,20,3,1, +1,1,4,19,0,0,0,33,0,0,20,2,2,2,19,0,0,33,0,0,0,20,3,1,1, +1,1,1,4,21,22,0,33,23,24,5,6,1,7,8,21,22,33,0,23,24,3,1,1,1, +1,1,1,1,7,8,2,2,5,6,1,1,1,1,1,7,8,2,2,5,6,1,1,1,1 + + + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,66,0,0,0,0,66,0,0,0,66,0,0,0,0,66,0,0,0,0,0, +0,0,0,0,66,0,0,0,0,0,66,0,0,0,66,0,0,0,0,0,66,49,0,0,0, +0,0,0,66,0,0,0,0,0,0,66,0,0,0,66,0,0,0,0,0,0,66,0,0,0, +0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0, +0,0,66,0,0,0,0,0,0,0,0,0,65,0,0,0,0,0,0,0,0,0,66,0,0, +0,0,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0,0, +0,0,0,0,66,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,66,0,0,0,0, +0,0,0,0,0,66,0,0,0,0,1,1,1,1,1,0,0,0,0,66,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0 + + + diff --git a/assets-cg/levels/tileset.png b/assets-cg/levels/tileset.png new file mode 100644 index 0000000000000000000000000000000000000000..0afb6641732bab40e720176964b2c91ea1ec1c3a GIT binary patch literal 8483 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 a>!)TM;{fUCP;KLO*cg3Ny=OXS!~P3q{?;x4 literal 0 HcmV?d00001 diff --git a/assets-cg/levels/tilesetnpp.json b/assets-cg/levels/tilesetnpp.json new file mode 100644 index 0000000..73c3fdb --- /dev/null +++ b/assets-cg/levels/tilesetnpp.json @@ -0,0 +1,14 @@ +{ "columns":16, + "image":"tileset.png", + "imageheight":256, + "imagewidth":256, + "margin":0, + "name":"tileset", + "spacing":0, + "tilecount":256, + "tiledversion":"1.8.0", + "tileheight":16, + "tilewidth":16, + "type":"tileset", + "version":"1.8" +} \ No newline at end of file diff --git a/assets-cg/levels/tilesetnpp.tsx b/assets-cg/levels/tilesetnpp.tsx new file mode 100644 index 0000000..b99293a --- /dev/null +++ b/assets-cg/levels/tilesetnpp.tsx @@ -0,0 +1,4 @@ + + + + diff --git a/assets-cg/sprites/fxconv-metadata.txt b/assets-cg/sprites/fxconv-metadata.txt new file mode 100644 index 0000000..5e3f5a8 --- /dev/null +++ b/assets-cg/sprites/fxconv-metadata.txt @@ -0,0 +1,4 @@ +*.png: + type: bopti-image + name_regex: (.*)\.png img_\1 + profile: p8_rgb565a diff --git a/assets-cg/sprites/rectangle.png b/assets-cg/sprites/rectangle.png new file mode 100644 index 0000000000000000000000000000000000000000..0bfe08973caeb7b50d150318b64ad131ef3bbebb GIT binary patch literal 86 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`vYsxEAr`&KbAFmUuxDm%=oC7; jn5{?3AnQPa5d*_~Gp4r=60c7H6*73b`njxgN@xNAI#(9C literal 0 HcmV?d00001 diff --git a/assets-cg/sprites/running.png b/assets-cg/sprites/running.png new file mode 100644 index 0000000000000000000000000000000000000000..03aa2eea506061e35232a3ccb415fe9f80325121 GIT binary patch literal 651 zcmV;60(AX}P)+>DB>#VGatfHkS_UnXV)O1L;mJiatfC6=FMnF7fn@+-<|PLa@d02a`7ZS{ zGom6ms`hvB2Z!fB01(l|Kj}l!cVM?agP(P8S+HV+H*N%oXB;zwD3*hj&PD)%X97|| zNca!zg%b6%qc38|EL&4~)GICMF38YL3SWt9w;@x^S>e$ks!6nPdpC{X0o_LefQP4i zcRu;4;dqkCL$gI z3RLkad5!f>n34*hDJxryHcU^EY!8t3PF{HG@(l zipUw1(a+2$A6An~`=VFu l1>2QKCrsQHj>1aY@e7d23to}FkP-j@002ovPDHLkV1lm#FopmC literal 0 HcmV?d00001 diff --git a/assets-cg/sprites/static.png b/assets-cg/sprites/static.png new file mode 100644 index 0000000000000000000000000000000000000000..8dca238883a2a0e6a96003fff70a3114789bb133 GIT binary patch literal 260 zcmV+f0sH=mP)WF!;0l%R#{#dJRmj@-0{+NE!V?%_Tg{h--dyx!-v0tw>B_r z>@ckvd?!y^zYiEdRY$g;jeJH>0-zNb4d_~!oz);cyOT$4w(#f%?o{Pvf2@?T*YvCT zKzKBUieMYs26ilBw@|xQyX&X~D*-&VUCbe7Wsnz;DqslrEmnGF7&a~65ni*g#_z3z z7Kg|&TPSM?((EEhwr+&PTX9>w=a(Y1-DCo&@T@5iwWC#W)<13iP8?!7m93bW|B3Z& zFA3Se6Atm!V?e}?RXrJ=Dpm!ujsg+C$k37DGt+S99Bp0y#crXD0000 +#include + +#include +#include + + + +extern struct Map map_level1; +extern struct Map map_level2; +extern struct Map map_level3; + +extern bool drawbackground; + +struct Map *map_level; + + +Background::Background( ) +{ + map_level = &map_level2; +} + +Background::~Background( ) +{ + +} + +void Background::ChangeMap( int level, Player *MyPlayer ) +{ + if(level==1) map_level = &map_level1; + else if(level==2) map_level = &map_level2; + else if(level==3) map_level = &map_level3; + else map_level = &map_level1; + + UpdateDataMap( MyPlayer ); +} + +void Background::UpdateDataMap( Player *MyPlayer ) +{ + for(int i=0; iw; i++) + { + for(int j=0; j<=map_level->h; j++) + { + uint16_t index = (j) * map_level->w + (i) % map_level->w; + uint16_t currentTile = map_level->layers[1][ index ]; + if (currentTile==11) + { + MyPlayer->x = libnum::num( i*16 - 4 + 8 ); + MyPlayer->y = libnum::num( j*16 + 8 ); + MyPlayer->vx = 0; + MyPlayer->vy = 0; + MyPlayer->Update( 0.0f, 0.0f, 0.0f ); + } + } + } +} + +void Background::Render( void ) +{ + for(int u=!drawbackground; unblayers;u++) + { + for(int i=0; iw; i++) + { + for(int j=0; j<=map_level->h; j++) + { + uint16_t index = (j) * map_level->w + (i) % map_level->w; + uint16_t currentTile = map_level->layers[u][ index ]; + if (currentTile!=0 && currentTile!=11) + { + uint16_t xtile = ((currentTile % map_level->tileset_size)-1) * 16; + uint16_t ytile = (currentTile / map_level->tileset_size) * 16; + azrp_subimage_p8( i*16-4, j*16, map_level->tileset, xtile, ytile, 16, 16, DIMAGE_NONE ); + } + } + } + } +} + +void Background::Update( float dt ) +{ + +} + +bool Background::CanGo( Player *MyPlayer ) +{ + int tileX = ((int) MyPlayer->x+4) >> 4 ; + int tileY = ((int) MyPlayer->y+8) >> 4; + + int tileIndex = tileY*map_level->w + tileX; + + int tileValue = map_level->layers[0][ tileIndex ]; + + if (tileValue==0 || tileValue==1) return true; + else return false; +} \ No newline at end of file diff --git a/src/background.h b/src/background.h new file mode 100644 index 0000000..74eeff7 --- /dev/null +++ b/src/background.h @@ -0,0 +1,45 @@ +#ifndef BACKGROUND_H +#define BACKGROUND_H + + +#include +#include + +#include + +#include +#include "num/num.h" + +#include "player.h" + +struct Map { + /*width, height and the number of layer of the map*/ + int w, h, nblayers; + + /*the tileset to use*/ + bopti_image_t *tileset; + int tileset_size; + + /*list of all the tiles*/ + short *layers[]; +}; + + +class Background +{ + public: + Background( ); + ~Background( ); + + void Update( float dt ); + void Render( ); + + void ChangeMap( int level, Player *MyPlayer ); + void UpdateDataMap( Player *MyPlayer ); + + bool CanGo( Player *MyPlayer ); +}; + + + +#endif diff --git a/src/extrakeyboard.cpp b/src/extrakeyboard.cpp new file mode 100644 index 0000000..29492d4 --- /dev/null +++ b/src/extrakeyboard.cpp @@ -0,0 +1,160 @@ +#include "extrakeyboard.h" +#include +#include +#include + + +typedef struct +{ + bool pressed; + uint32_t since = 0; +} keyinfo; + + +keyinfo MyKeyMapper[MYKEY_LASTENUM+1]; + + +KeyboardExtra::KeyboardExtra() +{ + uint32_t timer = rtc_ticks(); + now = timer; + for(int i=0; i<=MYKEY_LASTENUM; i++) MyKeyMapper[i] = { .pressed = false, .since = timer }; +} + + +KeyboardExtra::~KeyboardExtra() +{ + +} + + +void KeyboardExtra::Update( float dt ) +{ + uint32_t timer = rtc_ticks(); + + now = timer; + + key_event_t ev; + + int keycode = -1; + + while((ev = pollevent()).type != KEYEV_NONE) + { + if (ev.key == KEY_F1) keycode = MYKEY_F1; + else if(ev.key == KEY_F2) keycode = MYKEY_F2; + else if(ev.key == KEY_F3) keycode = MYKEY_F3; + else if(ev.key == KEY_F4) keycode = MYKEY_F4; + else if(ev.key == KEY_F5) keycode = MYKEY_F5; + else if(ev.key == KEY_F6) keycode = MYKEY_F6; + + else if(ev.key == KEY_SHIFT) keycode = MYKEY_SHIFT; + else if(ev.key == KEY_OPTN) keycode = MYKEY_OPTN; + else if(ev.key == KEY_VARS) keycode = MYKEY_VARS; + else if(ev.key == KEY_MENU) keycode = MYKEY_MENU; + else if(ev.key == KEY_LEFT) keycode = MYKEY_LEFT; + else if(ev.key == KEY_UP) keycode = MYKEY_UP; + + else if(ev.key == KEY_ALPHA) keycode = MYKEY_ALPHA; + else if(ev.key == KEY_SQUARE) keycode = MYKEY_SQUARE; + else if(ev.key == KEY_POWER) keycode = MYKEY_POWER; + else if(ev.key == KEY_EXIT) keycode = MYKEY_EXIT; + else if(ev.key == KEY_DOWN) keycode = MYKEY_DOWN; + else if(ev.key == KEY_RIGHT) keycode = MYKEY_RIGHT; + + else if(ev.key == KEY_XOT) keycode = MYKEY_XOT; + else if(ev.key == KEY_LOG) keycode = MYKEY_LOG; + else if(ev.key == KEY_LN) keycode = MYKEY_LN; + else if(ev.key == KEY_SIN) keycode = MYKEY_SIN; + else if(ev.key == KEY_COS) keycode = MYKEY_COS; + else if(ev.key == KEY_TAN) keycode = MYKEY_TAN; + + else if(ev.key == KEY_FRAC) keycode = MYKEY_FRAC; + else if(ev.key == KEY_FD) keycode = MYKEY_FD; + else if(ev.key == KEY_LEFTP) keycode = MYKEY_LEFTP; + else if(ev.key == KEY_RIGHTP) keycode = MYKEY_RIGHTP; + else if(ev.key == KEY_COMMA) keycode = MYKEY_COMMA; + else if(ev.key == KEY_ARROW) keycode = MYKEY_ARROW; + + else if(ev.key == KEY_7) keycode = MYKEY_7; + else if(ev.key == KEY_8) keycode = MYKEY_8; + else if(ev.key == KEY_9) keycode = MYKEY_9; + else if(ev.key == KEY_DEL) keycode = MYKEY_DEL; + + else if(ev.key == KEY_4) keycode = MYKEY_4; + else if(ev.key == KEY_5) keycode = MYKEY_5; + else if(ev.key == KEY_6) keycode = MYKEY_6; + else if(ev.key == KEY_MUL) keycode = MYKEY_MUL; + else if(ev.key == KEY_DIV) keycode = MYKEY_DIV; + + else if(ev.key == KEY_1) keycode = MYKEY_1; + else if(ev.key == KEY_2) keycode = MYKEY_2; + else if(ev.key == KEY_3) keycode = MYKEY_3; + else if(ev.key == KEY_ADD) keycode = MYKEY_ADD; + else if(ev.key == KEY_SUB) keycode = MYKEY_SUB; + + else if(ev.key == KEY_0) keycode = MYKEY_0; + else if(ev.key == KEY_DOT) keycode = MYKEY_DOT; + else if(ev.key == KEY_EXP) keycode = MYKEY_EXP; + else if(ev.key == KEY_NEG) keycode = MYKEY_NEG; + else if(ev.key == KEY_EXE) keycode = MYKEY_EXE; + + else if(ev.key == KEY_ACON) keycode = MYKEY_ACON; + + + if(keycode!=-1) + { + if (ev.type == KEYEV_DOWN) MyKeyMapper[keycode] = { .pressed = true, .since = timer }; + else if (ev.type == KEYEV_UP) MyKeyMapper[keycode] = { .pressed = false, .since = timer }; + else if (ev.type == KEYEV_HOLD) {} + } + else + { + // do nothing, just unstack the event from the events queue + }; + } +} + + +bool KeyboardExtra::IsKeyPressedEvent( int key ) +{ + return (MyKeyMapper[key].pressed && MyKeyMapper[key].since == now); +} + + +bool KeyboardExtra::IsKeyReleasedEvent( int key ) +{ + return (!MyKeyMapper[key].pressed && MyKeyMapper[key].since == now); +} + + +bool KeyboardExtra::IsKeyPressed( int key ) +{ + return MyKeyMapper[key].pressed; +} + + +bool KeyboardExtra::IsKeyReleased( int key ) +{ + return (!MyKeyMapper[key].pressed); +} + + +uint32_t KeyboardExtra::IsKeyHoldPressed( int key ) +{ + if (MyKeyMapper[key].pressed && MyKeyMapper[key].since < now) + return (uint32_t) (now-MyKeyMapper[key].since); + else return 0; +} + + +uint32_t KeyboardExtra::IsKeyHoldReleased( int key ) +{ + if (!MyKeyMapper[key].pressed && MyKeyMapper[key].since < now) + return (uint32_t) (now-MyKeyMapper[key].since); + else return 0; +} + +uint32_t KeyboardExtra::GetLastTickKeyEvent( int key ) +{ + return (uint32_t) MyKeyMapper[key].since; +} \ No newline at end of file diff --git a/src/extrakeyboard.h b/src/extrakeyboard.h new file mode 100644 index 0000000..151d1d1 --- /dev/null +++ b/src/extrakeyboard.h @@ -0,0 +1,94 @@ +#ifndef EXTRAKEYBOARD_H +#define EXTRAKEYBOARD_H + +#include + + +enum +{ + MYKEY_F1=0, + MYKEY_F2, + MYKEY_F3, + MYKEY_F4, + MYKEY_F5, + MYKEY_F6, + + MYKEY_SHIFT, + MYKEY_OPTN, + MYKEY_VARS, + MYKEY_MENU, + MYKEY_LEFT, + MYKEY_UP, + + MYKEY_ALPHA, + MYKEY_SQUARE, + MYKEY_POWER, + MYKEY_EXIT, + MYKEY_DOWN, + MYKEY_RIGHT, + + MYKEY_XOT, + MYKEY_LOG, + MYKEY_LN, + MYKEY_SIN, + MYKEY_COS, + MYKEY_TAN, + + MYKEY_FRAC, + MYKEY_FD, + MYKEY_LEFTP, + MYKEY_RIGHTP, + MYKEY_COMMA, + MYKEY_ARROW, + + MYKEY_7, + MYKEY_8, + MYKEY_9, + MYKEY_DEL, + + MYKEY_4, + MYKEY_5, + MYKEY_6, + MYKEY_MUL, + MYKEY_DIV, + + MYKEY_1, + MYKEY_2, + MYKEY_3, + MYKEY_ADD, + MYKEY_SUB, + + MYKEY_0, + MYKEY_DOT, + MYKEY_EXP, + MYKEY_NEG, + MYKEY_EXE, + + MYKEY_ACON, + + MYKEY_LASTENUM, +}; + + + +class KeyboardExtra +{ + public: + KeyboardExtra(); + ~KeyboardExtra(); + + void Update( float dt ); + bool IsKeyPressedEvent( int key ); + bool IsKeyReleasedEvent( int key ); + bool IsKeyPressed( int key ); + bool IsKeyReleased( int key ); + uint32_t IsKeyHoldPressed( int key ); + uint32_t IsKeyHoldReleased( int key ); + uint32_t GetLastTickKeyEvent( int key ); + + private: + uint32_t now; +}; + + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..17b2d42 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,308 @@ +#define DEBUG_MODE 1 +#define BIAS 1 +#define NOBIAS (1-BIAS) + + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "extrakeyboard.h" +#include "utilities.h" + +#include "player.h" +#include "background.h" + + +bool screenshot = false; +bool record = false; +bool textoutput = false; +bool exitToOS = false; +uint8_t texttodraw=1; + + +#define SCALE_PIXEL 1 +#define X_RESOL (DWIDTH / SCALE_PIXEL) +#define Y_RESOL (DHEIGHT / SCALE_PIXEL) + +float elapsedTime = 0.0f; +uint32_t time_update=0, time_render=0; +prof_t perf_update, perf_render; + + +static kmalloc_arena_t extended_ram = { 0 }; +static kmalloc_arena_t *_uram; +kmalloc_gint_stats_t *_uram_stats; +kmalloc_gint_stats_t *extram_stats; + + +KeyboardExtra MyKeyboard; +Background MyBackground; +Player MyPlayer( 198, 180 ); + + +bool drawbackground = true; + + +static void hook_prefrag(int id, void *fragment, int size) +{ + if(!screenshot && !record) + return; + + /* Screenshot takes precedence */ + char const *type = screenshot ? "image" : "video"; + + int pipe = usb_ff_bulk_output(); + + if(id == 0) { + usb_fxlink_header_t h; + usb_fxlink_image_t sh; + int size = azrp_width * azrp_height * 2; + + usb_fxlink_fill_header(&h, "fxlink", type, size + sizeof sh); + sh.width = htole32(azrp_width); + sh.height = htole32(azrp_height); + sh.pixel_format = htole32(USB_FXLINK_IMAGE_RGB565); + + usb_write_sync(pipe, &h, sizeof h, false); + usb_write_sync(pipe, &sh, sizeof sh, false); + } + + usb_write_sync(pipe, fragment, size, false); + + if(id == azrp_frag_count - 1) { + usb_commit_sync(pipe); + screenshot = false; + } +} + + +static void update( float dt ) +{ + MyPlayer.Update( dt, 0.0f, 1.0f ); +} + + +static void render( void ) +{ + + MyBackground.Render(); + MyPlayer.Render(); + + #if(BIAS) + if (texttodraw>=1) Azur_draw_text(1,01, "FPS = %.0f", (float) (1000000.0f / elapsedTime) ); + //if (texttodraw>=1) Azur_draw_text(1,11, "Part.= %d - Bull.= %d", MyParticles.size(), MyPlayerBullets.size() ); + //if (texttodraw>=1 && !MyEnemies.empty()) Azur_draw_text(1,21, "Ennmy Life= %d", MyEnemies[0]->life ); + + if (texttodraw>=2) Azur_draw_text(1,31, "Update = %.3f ms", (float) time_update / 1000.0f ); + if (texttodraw>=2) Azur_draw_text(1,41, "Render = %.3f ms", (float) time_render / 1000.0f ); + if (texttodraw>=2) Azur_draw_text(1,51, ">Total = %.0f ms", (float) elapsedTime / 1000.0f ); + + if (texttodraw>=3) Azur_draw_text(1,81, "Mem Used : %d", _uram_stats->used_memory + extram_stats->used_memory); + if (texttodraw>=3) Azur_draw_text(1,91, "Mem Free : %d", _uram_stats->free_memory + extram_stats->free_memory); + if (texttodraw>=3) Azur_draw_text(1,101, "Mem Peak Used : %d", _uram_stats->peak_used_memory + extram_stats->peak_used_memory ); + #endif + +} + + + +static void get_inputs( float dt ) +{ + if (MyKeyboard.IsKeyPressed(MYKEY_SHIFT) && MyKeyboard.IsKeyHoldPressed(MYKEY_EXIT)) {exitToOS = true; }; + + + #if(DEBUG_MODE) + if(MyKeyboard.IsKeyPressed(MYKEY_SHIFT) && MyKeyboard.IsKeyPressedEvent(MYKEY_7) && usb_is_open() ) {screenshot = true;}; + if(MyKeyboard.IsKeyPressed(MYKEY_SHIFT) && MyKeyboard.IsKeyPressedEvent(MYKEY_8) && usb_is_open()) {record = true; }; + if(MyKeyboard.IsKeyPressed(MYKEY_SHIFT) && MyKeyboard.IsKeyPressedEvent(MYKEY_9) && usb_is_open()) {record = false; }; + + if(MyKeyboard.IsKeyPressedEvent(MYKEY_VARS)) { drawbackground = !drawbackground; } + + if(MyKeyboard.IsKeyPressed(MYKEY_SHIFT) && MyKeyboard.IsKeyPressedEvent(MYKEY_F1)) { texttodraw = 0; } + if(MyKeyboard.IsKeyPressed(MYKEY_SHIFT) && MyKeyboard.IsKeyPressedEvent(MYKEY_F2)) { texttodraw = 1; } + if(MyKeyboard.IsKeyPressed(MYKEY_SHIFT) && MyKeyboard.IsKeyPressedEvent(MYKEY_F3)) { texttodraw = 2; } + if(MyKeyboard.IsKeyPressed(MYKEY_SHIFT) && MyKeyboard.IsKeyPressedEvent(MYKEY_F4)) { texttodraw = 3; } + + if(MyKeyboard.IsKeyPressedEvent(MYKEY_F1)) { MyBackground.ChangeMap(1, &MyPlayer); } + if(MyKeyboard.IsKeyPressedEvent(MYKEY_F2)) { MyBackground.ChangeMap(2, &MyPlayer); } + if(MyKeyboard.IsKeyPressedEvent(MYKEY_F3)) { MyBackground.ChangeMap(3, &MyPlayer); } + if(MyKeyboard.IsKeyPressedEvent(MYKEY_F4)) { MyBackground.ChangeMap(4, &MyPlayer); } + if(MyKeyboard.IsKeyPressedEvent(MYKEY_F5)) { MyBackground.ChangeMap(5, &MyPlayer); } + if(MyKeyboard.IsKeyPressedEvent(MYKEY_F6)) { MyBackground.ChangeMap(6, &MyPlayer); } + #endif + + + if(MyKeyboard.IsKeyPressed(MYKEY_ALPHA) && MyKeyboard.IsKeyPressed(MYKEY_LEFT)) + { + MyPlayer.Walk_Left( dt ); + } + else if(MyKeyboard.IsKeyPressed(MYKEY_ALPHA) && MyKeyboard.IsKeyPressed(MYKEY_RIGHT)) + { + MyPlayer.Walk_Right( dt ); + } + else if(MyKeyboard.IsKeyPressed(MYKEY_LEFT)) + { + MyPlayer.Run_Left( dt ); + } + else if(MyKeyboard.IsKeyPressed(MYKEY_RIGHT)) + { + MyPlayer.Run_Right( dt ); + } + else + { + MyPlayer.No_Order( dt ); + } + + if(MyKeyboard.IsKeyPressed(MYKEY_SHIFT)) + { + MyPlayer.Jump( dt ); + } +} + + + +bool AddMoreRAM( void ) +{ + /* allow more RAM */ + char const *osv = (char*) 0x80020020; + + if((!strncmp(osv, "03.", 3) && osv[3] <= '6') && gint[HWCALC] == HWCALC_FXCG50) // CG-50 + { + extended_ram.name = "extram"; + extended_ram.is_default = true; + extended_ram.start = (void *)0x8c200000; + extended_ram.end = (void *)0x8c4e0000 ; + + kmalloc_init_arena(&extended_ram, true); + kmalloc_add_arena(&extended_ram ); + return true; + } + else if (gint[HWCALC] == HWCALC_PRIZM) // CG-10/20 + { + + extended_ram.name = "extram"; + extended_ram.is_default = true; + + uint16_t *vram1, *vram2; + dgetvram(&vram1, &vram2); + dsetvram(vram1, vram1); + + extended_ram.start = vram2; + extended_ram.end = (char *)vram2 + 396*224*2; + + kmalloc_init_arena(&extended_ram, true); + kmalloc_add_arena(&extended_ram ); + return false; + + } + else if (gint[HWCALC] == HWCALC_FXCG_MANAGER) // CG-50 EMULATOR + { + + extended_ram.name = "extram"; + extended_ram.is_default = true; + extended_ram.start = (void *)0x88200000; + extended_ram.end = (void *)0x884e0000 ; + + kmalloc_init_arena(&extended_ram, true); + kmalloc_add_arena(&extended_ram ); + return true; + } +} + +void FreeMoreRAM( void ) +{ + memset(extended_ram.start, 0, (char *)extended_ram.end - (char *)extended_ram.start); +} + + +int main(void) +{ + exitToOS = false; + + _uram = kmalloc_get_arena("_uram"); + + bool canWeAllocate3Mb = AddMoreRAM(); + + __printf_enable_fp(); + __printf_enable_fixed(); + + azrp_config_scale(SCALE_PIXEL); + + azrp_shader_clear_configure(); + azrp_shader_image_rgb16_configure(); + azrp_shader_image_p8_configure(); + azrp_shader_image_p4_configure(); + azrp_shader_triangle_configure(); + + azrp_hook_set_prefrag(hook_prefrag); + + usb_interface_t const *interfaces[] = { &usb_ff_bulk, NULL }; + usb_open(interfaces, GINT_CALL_NULL); + + prof_init(); + + do + { + perf_update = prof_make(); + prof_enter(perf_update); + + { + // all the stuff to be update should be put here + MyKeyboard.Update( elapsedTime ); + + get_inputs( elapsedTime ); + + update( elapsedTime ); + + // update the RAM consumption status + _uram_stats = kmalloc_get_gint_stats(_uram); + extram_stats = kmalloc_get_gint_stats(&extended_ram); + } + + prof_leave(perf_update); + time_update = prof_time(perf_update); + + perf_render = prof_make(); + prof_enter(perf_render); + + { + // all the stuff to be rendered should be put here + azrp_clear( C_WHITE ); + render(); + azrp_update(); + } + + prof_leave(perf_render); + time_render = prof_time(perf_render); + + elapsedTime = ((float) (time_update+time_render)); + + } + while (exitToOS==false); + + + prof_quit(); + usb_close(); + + + FreeMoreRAM( ); + + return 1; +} diff --git a/src/player.cpp b/src/player.cpp new file mode 100644 index 0000000..5bfd271 --- /dev/null +++ b/src/player.cpp @@ -0,0 +1,174 @@ +#include "player.h" +#include +#include +#include "background.h" + +/* +extern bopti_image_t img_walking; +extern bopti_image_t img_running; +extern bopti_image_t img_static; +*/ + +extern bopti_image_t img_rectangle; + + +static uint32_t framecounter = 0; + +extern Background MyBackground; + + +Player::Player( int16_t _x, int16_t _y ) +{ + x = libnum::num(_x); + y = libnum::num(_y); + + width = 8; + height = 8; + speed = 10; + + xmin = (int) x - width; + xmax = (int) x + width; + ymin = (int) y - height; + ymax = (int) y + height; + + last_tick = rtc_ticks(); +} + +Player::~Player() +{ + + +} + +void Player::Update( float dt, libnum::num ax, libnum::num ay ) +{ + libnum::num DeltaTime = libnum::num( dt / 60000.0f ); + vx += ax * DeltaTime; + vy += ay * DeltaTime; + + libnum::num xtemp = x + vx * DeltaTime; + libnum::num ytemp = y + vy * DeltaTime; + + if (MyBackground.CanGo( this )) + { + x = xtemp; + y = ytemp; + } + + xmin = (int) x - width; + xmax = (int) x + width; + ymin = (int) y - height; + ymax = (int) y + height; + +} + +void Player::Render( void ) +{ + uint32_t temptick = rtc_ticks(); + if (temptick-last_tick>=10) + { + last_tick = temptick; + framecounter++; + } + /* + if (action==RUN) + { + uint8_t frameinternal = framecounter % 8; + azrp_subimage_p8_effect(xmin, ymin, &img_running, frameinternal*16, 0, 16, 16, direction==RIGHT ? DIMAGE_NONE : IMAGE_HFLIP ); + } + else if (action==WALK) + { + uint8_t frameinternal = framecounter % 7; + azrp_subimage_p8_effect(xmin, ymin, &img_walking, frameinternal*16, 0, 16, 16, direction==RIGHT ? DIMAGE_NONE : IMAGE_HFLIP ); + } + else if (action==STATIC) + { + uint8_t frameinternal = framecounter % 8; + azrp_subimage_p8_effect(xmin, ymin, &img_static, frameinternal*16, 0, 16, 16, DIMAGE_NONE); + } + */ + + azrp_image_p8_effect(xmin, ymin, &img_rectangle, DIMAGE_NONE); + + +} + +void Player::Set_Speed( uint8_t _sp ) +{ + speed = _sp; +} + +void Player::Walk_Left( float dt ) +{ + libnum::num a = libnum::num( dt / 60000.0f ); + + x -= a * libnum::num( speed/3 ); + + this->direction = LEFT; + this->action = WALK; +} + +void Player::Walk_Right( float dt ) +{ + libnum::num a = libnum::num( dt / 60000.0f ); + + x += a * libnum::num( speed/3 ); + + this->direction = RIGHT; + this->action = WALK; +} + +void Player::Run_Left( float dt ) +{ + libnum::num a = libnum::num( dt / 60000.0f ); + + x -= a * libnum::num( speed ); + + this->direction = LEFT; + this->action = RUN; +} + +void Player::Run_Right( float dt ) +{ + libnum::num a = libnum::num( dt / 60000.0f ); + + x += a * libnum::num( speed ); + + this->direction = RIGHT; + this->action = RUN; +} + +void Player::Jump( float dt ) +{ + if (this->action==WALK) + { + //this->vx = speed / 3; + this->vy = -speed / 2; + } + else if (this->action==RUN) + { + //this->vx = speed; + this->vy = -speed; + } + else + { + //this->vx = 0; + this->vy = -speed /2; + } + + this->direction = LEFT; + this->action = JUMP; + + if (this->direction==LEFT) + { + this->vx = -this->vx; + } +} + +void Player::No_Order( float dt ) +{ + if (this->action == RUN || this->action == WALK) + { + this->action == BREAK; + } +} diff --git a/src/player.h b/src/player.h new file mode 100644 index 0000000..d40b56b --- /dev/null +++ b/src/player.h @@ -0,0 +1,69 @@ +#ifndef PLAYER_H +#define PLAYER_H + +#include +#include + +#include +#include + +#include + +enum +{ + LEFT = -2, + RIGHT = -1, + STATIC = 0, + BREAK = 1, + WALK = 2, + RUN = 3, + JUMP = 4, + FALL = 5, +}; + + + +class Player +{ + public: + Player( int16_t _x, int16_t _y ); + ~Player(); + + void Update( float dt, libnum::num ax, libnum::num ay ); + void Render( ); + + void Walk_Left( float dt ); + void Walk_Right( float dt ); + + void Run_Left( float dt ); + void Run_Right( float dt ); + + void No_Order( float dt ); + + void Jump( float dt ); + + + void Go_Up( int action, float dt ); + void Go_Down( int action, float dt ); + + + void Set_Speed( uint8_t _sp ); + + libnum::num x, y; // center position of the player + libnum::num vx, vy; // speed of the player as per x and y coordinates + + uint8_t width, height; // width and height - for the hitbox + int16_t xmin, xmax, ymin, ymax; // square hitbox (to speed up the impact calculations) + + int16_t life; + uint8_t speed; // speed of the player + uint32_t last_tick; + + int8_t direction = STATIC; + int8_t action = STATIC; +}; + + + + +#endif \ No newline at end of file diff --git a/src/utilities.cpp b/src/utilities.cpp new file mode 100644 index 0000000..570ddac --- /dev/null +++ b/src/utilities.cpp @@ -0,0 +1,27 @@ +#include +#include + +#include +#include +#include +#include + +/* Render text with Azur images - quite bad, but I don't have time lol. */ +void Azur_draw_text(int x, int y, char const *fmt, ...) +{ + char str[128]; + va_list args; + va_start(args, fmt); + vsnprintf(str, 128, fmt, args); + va_end(args); + + extern bopti_image_t img_font; + + for(int i = 0; str[i]; i++) { + if(str[i] < 32 || str[i] >= 0x7f) continue; + + int row = (str[i] - 32) >> 4; + int col = (str[i] - 32) & 15; + azrp_subimage(x + 5 * i, y, &img_font, 7 * col + 1, 9 * row + 1, 6, 8, DIMAGE_NONE); + } +} diff --git a/src/utilities.h b/src/utilities.h new file mode 100644 index 0000000..41fbdd3 --- /dev/null +++ b/src/utilities.h @@ -0,0 +1,6 @@ +#ifndef UTILITIES_H +#define UTILITIES_H + +void Azur_draw_text(int x, int y, char const *fmt, ...); + +#endif \ No newline at end of file