From 2edee450aa734a098a2dc98f1853242a93d2b482 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 9 Nov 2017 21:43:59 -0600 Subject: [PATCH] Add support world drawing --- CMakeLists.txt | 8 ++- Dockerfile | 2 +- build/Makefile | 4 +- media/tilesheet_test_region1.png | Bin 0 -> 921 bytes scripts/gba-pkg | 13 ++-- scripts/newcpp | 4 +- scripts/setup_build | 5 ++ src/nostalgia/common/bounds.cpp | 6 +- src/nostalgia/common/bounds.hpp | 7 +-- src/nostalgia/core/CMakeLists.txt | 2 + src/nostalgia/core/core.hpp | 2 + src/nostalgia/core/gba/gfx.cpp | 46 ++++++++++++-- src/nostalgia/core/gba/media.cpp | 7 ++- src/nostalgia/core/gfx.hpp | 6 +- src/nostalgia/core/{gba => }/media.hpp | 2 +- src/nostalgia/core/qt/gfx.cpp | 7 +++ src/nostalgia/core/types.hpp | 19 ++++++ src/nostalgia/core/userland/media.cpp | 22 +++++++ src/nostalgia/player/CMakeLists.txt | 4 +- src/nostalgia/player/main.cpp | 11 ++-- src/nostalgia/world/world.cpp | 34 +++++++--- src/nostalgia/world/world.hpp | 82 ++++++++++++++++++------- 22 files changed, 232 insertions(+), 61 deletions(-) create mode 100644 media/tilesheet_test_region1.png rename src/nostalgia/core/{gba => }/media.hpp (89%) create mode 100644 src/nostalgia/core/types.hpp create mode 100644 src/nostalgia/core/userland/media.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c9ad213..0d1fdc64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,11 +14,15 @@ if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA") -nostdlib -fno-exceptions -fno-rtti + -fno-strict-aliasing + -mthumb-interwork + -mthumb ) endif() add_definitions( - -std=c++11 + -std=c++14 + -fdiagnostics-color -Wall -Wsign-compare ) @@ -45,7 +49,7 @@ else() set(NOSTALGIA_DIST_RESOURCES share) endif() -if (CMAKE_BUILD_TYPE STREQUAL "Release") +if(CMAKE_BUILD_TYPE STREQUAL "Release") add_definitions( -Werror ) diff --git a/Dockerfile b/Dockerfile index 42107f47..692a1083 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,4 +3,4 @@ FROM wombatant/devenv:latest ENV DEVKITPRO /opt/devkitPro ENV DEVKITARM ${DEVKITPRO}/devkitARM -RUN dnf install -y findutils +RUN dnf install -y findutils ninja-build diff --git a/build/Makefile b/build/Makefile index 804953d7..a79652c6 100644 --- a/build/Makefile +++ b/build/Makefile @@ -1,9 +1,9 @@ all: gba_build gba_debug_build native_build native_debug_build windows_release windows_debug ifneq ($(shell which gmake),) - MAKE="gmake -j" +MAKE="gmake" else - MAKE="make -j" +MAKE="make" endif gba_build: diff --git a/media/tilesheet_test_region1.png b/media/tilesheet_test_region1.png new file mode 100644 index 0000000000000000000000000000000000000000..0d19647127e7bc2ce633cab8a615357262ffe41d GIT binary patch literal 921 zcmeHFJ!o1{6#ha|ct`_|QfS{Rba66LD77s-UofQFpy_M6xV+$y!NtLb{y5xABtvm< zd2|wP21kidES==NMKYh3-9Y`OZ1_ob#P~?s>nP-d+#f z3IJG7K24Z}3a|!cm9&fQ_cLG>yE}VZWb(z~3*cmN?z%4Ld`A8mW(y!BjYI=h*e~(P*_=?RLA<>2$l@!C){P4t?JrkH^#Ll-A+=^7aGbUU_Av zUm)&(IUr*@nK1U=)J8oc;A%J5;_|a(nHwYH?(w^;jiT~w=icb;r|0)KKlJW=JT!au p#gFT6uOB|X{OQMDK3Vzw61Vf{;OP46;Z?()dy-q}#Odb#(J$B%0?Ysa literal 0 HcmV?d00001 diff --git a/scripts/gba-pkg b/scripts/gba-pkg index 4eb62655..4a1313a9 100755 --- a/scripts/gba-pkg +++ b/scripts/gba-pkg @@ -3,18 +3,21 @@ set -e BIN=./dist/current/bin/ -NOSTALGA_BIN=build/gba-release/src/nostalgia/player/nostalgia.bin +PATH=$BIN:${DEVKITARM}/bin/:$PATH +NOSTALGA_BIN=build/gba-*/src/nostalgia/player/nostalgia.bin NOSTALGA_MEDIA=nostalgia_media.oxfs NOSTALGA_GBA=nostalgia.gba MEDIA_HEADER=media_header.txt CHARSET_FILE=src/nostalgia/core/studio/charset.png +TILESHEET_TEST_REGION1=media/tilesheet_test_region1.png echo NOSTALGIA_MEDIA_HEADER_________ > $MEDIA_HEADER -$BIN/oxfs format 32 1k $NOSTALGA_MEDIA -$BIN/nost-pack -fs $NOSTALGA_MEDIA -img $CHARSET_FILE -inode 101 -tiles 127 -bpp 4 -c +oxfs format 32 1k $NOSTALGA_MEDIA +nost-pack -fs $NOSTALGA_MEDIA -img $CHARSET_FILE -inode 101 -tiles 127 -bpp 4 -c +nost-pack -fs $NOSTALGA_MEDIA -img $TILESHEET_TEST_REGION1 -inode 102 -tiles 4 -bpp 4 -c -${DEVKITARM}/bin/padbin 32 $NOSTALGA_BIN +padbin 32 $NOSTALGA_BIN cat $NOSTALGA_BIN $MEDIA_HEADER $NOSTALGA_MEDIA > $NOSTALGA_GBA rm -f $MEDIA_HEADER $NOSTALGA_MEDIA -${DEVKITARM}/bin/gbafix $NOSTALGA_GBA +gbafix $NOSTALGA_GBA diff --git a/scripts/newcpp b/scripts/newcpp index 73620a2f..9e38da5e 100755 --- a/scripts/newcpp +++ b/scripts/newcpp @@ -11,5 +11,5 @@ namespace = "namespace nostalgia {\nnamespace %s {\n\n}\n}" % pkg hpp = "#pragma once\n" cpp = "#include \"%s.hpp\"\n\n%s" % (name, namespace) -open("src/%s/%s.hpp" % (pkg, name), "w").write(hpp) -open("src/%s/%s.cpp" % (pkg, name), "w").write(cpp) +open("src/nostalgia/%s/%s.hpp" % (pkg, name), "w").write(hpp) +open("src/nostalgia/%s/%s.cpp" % (pkg, name), "w").write(cpp) diff --git a/scripts/setup_build b/scripts/setup_build index 6ffcfbc0..e78c9297 100755 --- a/scripts/setup_build +++ b/scripts/setup_build @@ -7,6 +7,10 @@ project=$(pwd)/ TARGET=$1 BUILD_TYPE=$2 +#if [[ $(which ninja) != "ninja not found" ]]; then +# buildTool="-GNinja" +#fi + if [[ $TARGET == windows ]]; then toolchain="-DCMAKE_TOOLCHAIN_FILE=cmake/Modules/Mingw.cmake" elif [[ $TARGET == gba ]]; then @@ -28,6 +32,7 @@ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DCMAKE_INSTALL_PREFIX="$distDir" \ -DCMAKE_INSTALL_RPATH="$project/dist/${TARGET}-${BUILD_TYPE}/lib/nostalgia" \ -DNOSTALGIA_IDE_BUILD=OFF \ + $buildTool \ $buildTypeArgs \ $toolchain \ $project diff --git a/src/nostalgia/common/bounds.cpp b/src/nostalgia/common/bounds.cpp index fb01cdba..d1bff07e 100644 --- a/src/nostalgia/common/bounds.cpp +++ b/src/nostalgia/common/bounds.cpp @@ -10,7 +10,11 @@ namespace nostalgia { namespace common { -Bounds::Bounds() { +Bounds::Bounds(int x, int y, int w, int h) { + this->x = x; + this->y = y; + this->width = w; + this->height = h; } bool Bounds::intersects(Bounds o) const { diff --git a/src/nostalgia/common/bounds.hpp b/src/nostalgia/common/bounds.hpp index 4e3f8f07..a6ba3822 100644 --- a/src/nostalgia/common/bounds.hpp +++ b/src/nostalgia/common/bounds.hpp @@ -19,10 +19,9 @@ class Bounds { int width = 0; int height = 0; - /** - * Constructor - */ - Bounds(); + Bounds() = default; + + Bounds(int x, int y, int w, int h); bool intersects(Bounds other) const; diff --git a/src/nostalgia/core/CMakeLists.txt b/src/nostalgia/core/CMakeLists.txt index ddedb16d..69b38626 100644 --- a/src/nostalgia/core/CMakeLists.txt +++ b/src/nostalgia/core/CMakeLists.txt @@ -16,6 +16,7 @@ elseif(NOSTALGIA_BUILD_TYPE STREQUAL "Native") set( CPP qt/gfx.cpp + userland/media.cpp userland/mem.cpp ) endif() @@ -34,6 +35,7 @@ install( FILES core.hpp gfx.hpp + media.hpp gba/gba.hpp DESTINATION include/nostalgia/core diff --git a/src/nostalgia/core/core.hpp b/src/nostalgia/core/core.hpp index 1d0d2e83..04262a60 100644 --- a/src/nostalgia/core/core.hpp +++ b/src/nostalgia/core/core.hpp @@ -11,6 +11,8 @@ #include #include "gfx.hpp" +#include "media.hpp" +#include "types.hpp" namespace nostalgia { namespace core { diff --git a/src/nostalgia/core/gba/gfx.cpp b/src/nostalgia/core/gba/gfx.cpp index 54476eab..1bc27fc7 100644 --- a/src/nostalgia/core/gba/gfx.cpp +++ b/src/nostalgia/core/gba/gfx.cpp @@ -8,9 +8,13 @@ #include #include + +#include "../media.hpp" + #include "addresses.hpp" -#include "media.hpp" #include "gba.hpp" +#include "panic.hpp" + #include "../gfx.hpp" namespace nostalgia { @@ -22,6 +26,7 @@ using namespace ox; #define TILE8_ADDR ((CharBlock8*) 0x06000000) const auto GBA_TILE_COLUMNS = 32; +const auto GBA_TILE_ROWS = 32; // map ASCII values to the nostalgia charset static char charMap[128] = { @@ -170,7 +175,7 @@ ox::Error initConsole(Context*) { const auto CharsetInode = 101; const auto PaletteStart = sizeof(GbaImageDataHeader); ox::Error err = 0; - auto fs = (FileStore32*) findMedia(); + auto fs = (FileStore32*) loadRom(); GbaImageDataHeader imgData; @@ -199,6 +204,37 @@ ox::Error initConsole(Context*) { return err; } +ox::Error loadTileSheet(Context *ctx, InodeId_t inode) { + ox::Error err = 0; + const auto PaletteStart = sizeof(GbaImageDataHeader); + GbaImageDataHeader imgData; + + auto fs = (ox::FileStore32*) ctx->rom->buff(); + REG_BG0CNT = (28 << 8) | 1; + if (fs) { + // load the header + err |= fs->read(inode, 0, sizeof(imgData), &imgData, nullptr); + + // load palette + err |= fs->read(inode, PaletteStart, + 512, (uint16_t*) &MEM_PALLETE_BG[0], nullptr); + + if (imgData.bpp == 4) { + err |= fs->read(inode, __builtin_offsetof(GbaImageData, tiles), + sizeof(Tile) * imgData.tileCount, (uint16_t*) &TILE_ADDR[0][1], nullptr); + } else if (imgData.bpp == 8) { + REG_BG0CNT |= (1 << 7); // set to use 8 bits per pixel + err |= fs->read(inode, __builtin_offsetof(GbaImageData, tiles), + sizeof(Tile8) * imgData.tileCount, (uint16_t*) &TILE8_ADDR[0][1], nullptr); + } else { + err = 1; + } + } else { + err = 1; + } + return err; +} + // Do NOT use Context in the GBA version of this function. void puts(Context*, int loc, const char *str) { for (int i = 0; str[i]; i++) { @@ -206,8 +242,10 @@ void puts(Context*, int loc, const char *str) { } } -void setTile(Context *ctx, int layer, int column, int row, uint16_t tile) { - MEM_BG_MAP[28 + layer][row * GBA_TILE_COLUMNS + column] = tile; +void setTile(Context *ctx, int layer, int column, int row, uint8_t tile) { + if (column < GBA_TILE_COLUMNS && row < GBA_TILE_ROWS) { + MEM_BG_MAP[28 + layer][row * GBA_TILE_COLUMNS + column] = tile; + } } } diff --git a/src/nostalgia/core/gba/media.cpp b/src/nostalgia/core/gba/media.cpp index 35695551..b0700f10 100644 --- a/src/nostalgia/core/gba/media.cpp +++ b/src/nostalgia/core/gba/media.cpp @@ -9,12 +9,13 @@ #include #include #include "addresses.hpp" -#include "media.hpp" + +#include "../media.hpp" namespace nostalgia { namespace core { -uint8_t *findMedia() { +uint8_t *loadRom(const char*) { // put the header in the wrong order to prevent mistaking this code for the // media section const static auto headerP2 = "_HEADER_________"; @@ -29,7 +30,7 @@ uint8_t *findMedia() { return current + headerLen; } } - return 0; + return nullptr; } } diff --git a/src/nostalgia/core/gfx.hpp b/src/nostalgia/core/gfx.hpp index 7ecf436a..b006bf6e 100644 --- a/src/nostalgia/core/gfx.hpp +++ b/src/nostalgia/core/gfx.hpp @@ -5,11 +5,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + #pragma once #include #include "context.hpp" +#include "types.hpp" namespace nostalgia { namespace core { @@ -18,9 +20,11 @@ ox::Error initGfx(Context *ctx); ox::Error initConsole(Context *ctx); +ox::Error loadTileSheet(Context *ctx, InodeId_t inode); + void puts(Context *ctx, int loc, const char *str); -void setTile(Context *ctx, int layer, int column, int row, uint16_t tile); +void setTile(Context *ctx, int layer, int column, int row, uint8_t tile); } } diff --git a/src/nostalgia/core/gba/media.hpp b/src/nostalgia/core/media.hpp similarity index 89% rename from src/nostalgia/core/gba/media.hpp rename to src/nostalgia/core/media.hpp index 1acc95d1..92864a71 100644 --- a/src/nostalgia/core/gba/media.hpp +++ b/src/nostalgia/core/media.hpp @@ -13,7 +13,7 @@ namespace nostalgia { namespace core { -uint8_t *findMedia(); +uint8_t *loadRom(const char *path = ""); } } diff --git a/src/nostalgia/core/qt/gfx.cpp b/src/nostalgia/core/qt/gfx.cpp index 0c090adb..3553d231 100644 --- a/src/nostalgia/core/qt/gfx.cpp +++ b/src/nostalgia/core/qt/gfx.cpp @@ -19,8 +19,15 @@ ox::Error initConsole(Context *ctx) { return 1; } +ox::Error loadTileSheet(Context *ctx, InodeId_t inode) { + return 1; +} + void puts(Context *ctx, int loc, const char *str) { } +void setTile(Context *ctx, int layer, int column, int row, uint8_t tile) { +} + } } diff --git a/src/nostalgia/core/types.hpp b/src/nostalgia/core/types.hpp new file mode 100644 index 00000000..015e7091 --- /dev/null +++ b/src/nostalgia/core/types.hpp @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2017 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include + +namespace nostalgia { +namespace core { + +typedef ox::FileStore32::InodeId_t InodeId_t; + +} +} diff --git a/src/nostalgia/core/userland/media.cpp b/src/nostalgia/core/userland/media.cpp new file mode 100644 index 00000000..42b24ed4 --- /dev/null +++ b/src/nostalgia/core/userland/media.cpp @@ -0,0 +1,22 @@ +/* + * Copyright 2016-2017 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include +#include + +#include "../media.hpp" + +namespace nostalgia { +namespace core { + +uint8_t *loadRom(const char*) { + return nullptr; +} + +} +} diff --git a/src/nostalgia/player/CMakeLists.txt b/src/nostalgia/player/CMakeLists.txt index c12201e5..1ee6c55b 100644 --- a/src/nostalgia/player/CMakeLists.txt +++ b/src/nostalgia/player/CMakeLists.txt @@ -17,9 +17,11 @@ endif() target_link_libraries( nostalgia + NostalgiaWorld + NostalgiaCommon NostalgiaCore - OxStd OxFS + OxStd ) add_custom_target("nostalgia.bin") diff --git a/src/nostalgia/player/main.cpp b/src/nostalgia/player/main.cpp index c2de8ac1..ce00fdd1 100644 --- a/src/nostalgia/player/main.cpp +++ b/src/nostalgia/player/main.cpp @@ -6,16 +6,19 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include +#include +using namespace nostalgia::common; using namespace nostalgia::core; +using namespace nostalgia::world; int main() { + ox::FileSystem32 fs(loadRom(), false); Context ctx; init(&ctx); - initConsole(&ctx); - puts(&ctx, 9 * 32 + 8, "HELLO,WORLD!"); - puts(&ctx, 10 * 32 + 8, "01234 56789"); + ctx.rom = &fs; + Zone zone(&ctx, Bounds{0, 0, 40, 40}, 102); + zone.draw(&ctx); while (1); return 0; } diff --git a/src/nostalgia/world/world.cpp b/src/nostalgia/world/world.cpp index 74ec9b22..f2567e1d 100644 --- a/src/nostalgia/world/world.cpp +++ b/src/nostalgia/world/world.cpp @@ -11,24 +11,42 @@ namespace nostalgia { namespace world { -Zone::Zone(common::Bounds bnds) { +using namespace common; +using namespace core; + +const int Zone::FIELDS = 1; +const int Region::FIELDS = 0; + + +Zone::Zone(Context *ctx, Bounds bnds, InodeId_t tileSheet) { const auto size = bnds.width * bnds.height; - m_tiles = new TileDef[size]; + m_tiles = new Tile[size]; + m_bounds = bnds; + core::loadTileSheet(ctx, tileSheet); } -void Zone::draw(core::Context *ctx) { +void Zone::draw(Context *ctx) { + for (int x = 0; x < m_bounds.width; x++) { + for (int y = 0; y < m_bounds.height; y++) { + auto t = tile(x, y); + core::setTile(ctx, 0, x * 2, y * 2, t->bgTile); + core::setTile(ctx, 0, x * 2 + 1, y * 2, t->bgTile + 1); + core::setTile(ctx, 0, x * 2 + 1, y * 2 + 1, t->bgTile + 2); + core::setTile(ctx, 0, x * 2, y * 2 + 1, t->bgTile + 3); + } + } } size_t Zone::size() { - return sizeof(Zone) + m_bounds.width * m_bounds.height * sizeof(TileDef); + return sizeof(Zone) + m_bounds.width * m_bounds.height * sizeof(Tile); } -TileDef *Zone::tile(int row, int column) { - return &m_tiles[row * m_bounds.width + column]; +Tile *Zone::tile(int x, int y) { + return &m_tiles[x * m_bounds.width + y]; } -void Zone::setTile(int row, int column, TileDef *td) { - m_tiles[row * m_bounds.width + column] = *td; +void Zone::setTile(int x, int y, Tile *td) { + m_tiles[x * m_bounds.width + y] = *td; } } diff --git a/src/nostalgia/world/world.hpp b/src/nostalgia/world/world.hpp index b1af5d16..d8f963e1 100644 --- a/src/nostalgia/world/world.hpp +++ b/src/nostalgia/world/world.hpp @@ -8,7 +8,7 @@ #pragma once -#include +#include #include #include @@ -16,56 +16,94 @@ namespace nostalgia { namespace world { -struct TileDef { - uint16_t bgTile; +struct Tile { + uint8_t bgTile = 0; + uint8_t type = 0; + void *occupant = nullptr; }; template -ox::Error ioOp(T *io, TileDef *obj) { +ox::Error ioOpRead(T *io, Tile *obj) { ox::Error err = 0; - io->setFields(1); + io->setFields(2); err |= io->op("bgTile", &obj->bgTile); + err |= io->op("type", &obj->type); return err; } -struct RegionDef { - uint32_t tileSheetInodes[20]; -}; +struct Zone { -struct ZoneDef { - int32_t width = 0; - int32_t height = 0; -}; + template + friend ox::Error ioOpRead(T*, Zone*); -class Zone { + template + friend ox::Error ioOpWrite(T*, Zone*); - private: + protected: + static const int FIELDS; common::Bounds m_bounds; - TileDef *m_tiles = nullptr; + Tile *m_tiles = nullptr; public: - - Zone(common::Bounds bnds); + Zone(core::Context *ctx, common::Bounds bnds, core::InodeId_t tileSheet); void draw(core::Context *ctx); size_t size(); - TileDef *tile(int row, int column); + Tile *tile(int x, int y); - void setTile(int row, int column, TileDef *td); + void setTile(int x, int y, Tile *td); }; -class Region { +template +ox::Error ioOpRead(T *io, Zone *obj) { + ox::Error err = 0; + io->setFields(Zone::FIELDS); + err |= io->op("bounds", &obj->m_bounds); + return err; +} - private: - Zone *m_zones; +template +ox::Error ioOpWrite(T *io, Zone *obj) { + ox::Error err = 0; + io->setFields(Zone::FIELDS); + err |= io->op("bounds", &obj->m_bounds); + return err; +} + + +struct Region { + + template + friend ox::Error ioOpRead(T*, Region*); + + template + friend ox::Error ioOpWrite(T*, Region*); + + protected: + static const int FIELDS; + Zone *m_zones = nullptr; public: }; +template +ox::Error ioOpRead(T *io, Region *obj) { + ox::Error err = 0; + io->setFields(Region::FIELDS); + return err; +} + +template +ox::Error ioOpWrite(T *io, Region *obj) { + ox::Error err = 0; + io->setFields(Region::FIELDS); + return err; +} + } }