From 70cee814069a3062b78dc23572601ceebc14853c Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 14 Oct 2017 03:13:26 -0500 Subject: [PATCH] Add more complete implementation for custom new/delete, add panic --- Makefile | 6 +-- scripts/build_rom.sh | 21 +++++--- src/nostalgia/core/CMakeLists.txt | 2 + src/nostalgia/core/core.cpp | 2 + src/nostalgia/core/gba/addresses.hpp | 3 ++ src/nostalgia/core/gba/gfx.cpp | 60 ++++++++++++++++++---- src/nostalgia/core/gba/mem.cpp | 70 ++++++++++++++++++++++++-- src/nostalgia/core/gba/panic.cpp | 27 ++++++++++ src/nostalgia/core/gba/panic.hpp | 20 ++++++++ src/nostalgia/core/gfx.hpp | 2 +- src/nostalgia/core/mem.hpp | 15 ++++++ src/nostalgia/core/studio/charset.png | Bin 1250 -> 1312 bytes src/nostalgia/core/userland/mem.cpp | 16 ++++++ src/nostalgia/world/world.cpp | 26 ++++++++++ src/nostalgia/world/world.hpp | 51 +++++++++++++++++-- 15 files changed, 293 insertions(+), 28 deletions(-) create mode 100644 src/nostalgia/core/gba/panic.cpp create mode 100644 src/nostalgia/core/gba/panic.hpp create mode 100644 src/nostalgia/core/mem.hpp create mode 100644 src/nostalgia/core/userland/mem.cpp diff --git a/Makefile b/Makefile index 9ea6c270..b6cff604 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ endif make: ${ENV_RUN} ${MAKE} -j -C build HOST_ENV=${HOST_ENV} -build_rom: +build-rom: ${ENV_RUN} ${MAKE} -j -C build ARGS="install" HOST_ENV=${HOST_ENV} ${ENV_RUN} ${MAKE} -j -C build HOST_ENV=${HOST_ENV} ${ENV_RUN} ./scripts/build_rom.sh @@ -34,8 +34,8 @@ run: install ./dist/current/bin/nostalgia -debug run-studio: install ./dist/current/bin/nostalgia-studio -profile dist/current/share/nostalgia-studio.json -gba-run: make - mgba-qt build/current/nostalgia.bin +gba-run: build-rom + mgba-qt nostalgia.gba gdb: make gdb ./build/current/src/wombat/wombat gdb-studio: make diff --git a/scripts/build_rom.sh b/scripts/build_rom.sh index bf4a6d2b..4eb62655 100755 --- a/scripts/build_rom.sh +++ b/scripts/build_rom.sh @@ -2,12 +2,19 @@ set -e -echo NOSTALGIA_MEDIA_HEADER_________ > media_header.txt +BIN=./dist/current/bin/ +NOSTALGA_BIN=build/gba-release/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 -./dist/current/bin/oxfs format 32 1k nostalgia_media.oxfs -./dist/current/bin/nost-pack -fs nostalgia_media.oxfs -img charset.png -inode 101 -tiles 40 -bpp 4 -c +echo NOSTALGIA_MEDIA_HEADER_________ > $MEDIA_HEADER -${DEVKITARM}/bin/padbin 32 build/gba-release/nostalgia.bin -cat build/gba-release/nostalgia.bin media_header.txt nostalgia_media.oxfs > nostalgia.gba -rm -f media_header.txt -${DEVKITARM}/bin/gbafix nostalgia.gba +$BIN/oxfs format 32 1k $NOSTALGA_MEDIA +$BIN/nost-pack -fs $NOSTALGA_MEDIA -img $CHARSET_FILE -inode 101 -tiles 127 -bpp 4 -c + +${DEVKITARM}/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 diff --git a/src/nostalgia/core/CMakeLists.txt b/src/nostalgia/core/CMakeLists.txt index 62546d1c..ddedb16d 100644 --- a/src/nostalgia/core/CMakeLists.txt +++ b/src/nostalgia/core/CMakeLists.txt @@ -7,6 +7,7 @@ if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA") gba/gfx.cpp gba/media.cpp gba/mem.cpp + gba/panic.cpp ) elseif(NOSTALGIA_BUILD_TYPE STREQUAL "Native") set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -15,6 +16,7 @@ elseif(NOSTALGIA_BUILD_TYPE STREQUAL "Native") set( CPP qt/gfx.cpp + userland/mem.cpp ) endif() diff --git a/src/nostalgia/core/core.cpp b/src/nostalgia/core/core.cpp index 489ca583..3b203e4b 100644 --- a/src/nostalgia/core/core.cpp +++ b/src/nostalgia/core/core.cpp @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "mem.hpp" #include "core.hpp" namespace nostalgia { @@ -14,6 +15,7 @@ namespace core { ox::Error init(Context *ctx) { ox::Error err = 0; err = initGfx(ctx); + initHeap(); // this does nothing in userland builds return err; } diff --git a/src/nostalgia/core/gba/addresses.hpp b/src/nostalgia/core/gba/addresses.hpp index fde6f283..b0a2d205 100644 --- a/src/nostalgia/core/gba/addresses.hpp +++ b/src/nostalgia/core/gba/addresses.hpp @@ -46,3 +46,6 @@ typedef uint16_t BgMapTile[1024]; #define MEM_BG_MAP ((BgMapTile*) 0x06000000) #define MEM_ROM *((uint8_t*) 0x08000000) + +#define MEM_WRAM_BEGIN ((uint8_t*) 0x02000000) +#define MEM_WRAM_END ((uint8_t*) 0x0203FFFF) diff --git a/src/nostalgia/core/gba/gfx.cpp b/src/nostalgia/core/gba/gfx.cpp index fe40fb8a..0d43b596 100644 --- a/src/nostalgia/core/gba/gfx.cpp +++ b/src/nostalgia/core/gba/gfx.cpp @@ -21,6 +21,8 @@ using namespace ox; #define TILE_ADDR ((CharBlock*) 0x06000000) #define TILE8_ADDR ((CharBlock8*) 0x06000000) +const auto GBA_TILE_COLUMNS = 32; + // map ASCII values to the nostalgia charset static char charMap[128] = { 0, @@ -63,13 +65,13 @@ static char charMap[128] = { 0, 0, 0, - 0, - 0, + 42, // ( + 43, // ) 0, 0, 37, // , 0, - 0, + 39, // . 0, 27, // 0 28, // 1 @@ -81,10 +83,10 @@ static char charMap[128] = { 34, // 7 35, // 8 36, // 9 - 0, - 0, - 0, - 0, + 40, // : + 0, // ; + 0, // < + 41, // = 0, 0, 0, @@ -114,6 +116,41 @@ static char charMap[128] = { 24, // X 25, // Y 26, // Z + 44, // [ + 0, // backslash + 45, // ] + 0, + 0, + 0, + 1, // a + 2, // b + 3, // c + 4, // d + 5, // e + 6, // f + 7, // g + 8, // h + 9, // i + 10, // j + 11, // k + 12, // l + 13, // m + 14, // n + 15, // o + 16, // p + 17, // q + 18, // r + 19, // s + 20, // t + 21, // u + 22, // v + 23, // w + 24, // x + 25, // y + 26, // z + 46, // { + 0, // | + 48, // } }; ox::Error initGfx(Context *ctx) { @@ -127,7 +164,8 @@ ox::Error initGfx(Context *ctx) { return 0; } -ox::Error initConsole(Context *ctx) { +// Do NOT use Context in the GBA version of this function. +ox::Error initConsole(Context*) { const auto CharsetInode = 101; const auto PaletteStart = sizeof(GbaImageDataHeader); ox::Error err = 0; @@ -160,13 +198,15 @@ ox::Error initConsole(Context *ctx) { return err; } -void puts(Context *ctx, int loc, const char *str) { +// 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++) { MEM_BG_MAP[28][loc + i] = charMap[(int) str[i]]; } } -void setTileMap(Context *ctx, int layer, int columns, int rows, uint16_t *buff) { +void setTile(Context *ctx, int layer, int column, int row, uint16_t tile) { + MEM_BG_MAP[28 + layer][row * GBA_TILE_COLUMNS + column] = tile; } } diff --git a/src/nostalgia/core/gba/mem.cpp b/src/nostalgia/core/gba/mem.cpp index 3483927b..f0a9fee8 100644 --- a/src/nostalgia/core/gba/mem.cpp +++ b/src/nostalgia/core/gba/mem.cpp @@ -7,14 +7,25 @@ */ #include "addresses.hpp" +#include "panic.hpp" namespace nostalgia { namespace core { -static uint8_t *_heapPtr = MEM_WRAM_END; +struct HeapSegment { + size_t size; + uint8_t inUse; + HeapSegment *next; +}; -void clearHeap() { - _heapPtr = MEM_WRAM_END; +static HeapSegment *_heapIdx = nullptr; + +void initHeap() { + _heapIdx = (HeapSegment*) MEM_WRAM_END; + // set size to half of WRAM + _heapIdx->size = (MEM_WRAM_END - MEM_WRAM_BEGIN) / 2; + _heapIdx->next = nullptr; + _heapIdx->inUse = false; } } @@ -23,9 +34,60 @@ void clearHeap() { using namespace nostalgia::core; void *operator new(size_t sz) { - return _heapPtr -= sz; + // add space for heap segment header data + sz += sizeof(HeapSegment); + auto out = _heapIdx; + while (out && out->size < sz) { + out = out->next; + } + + // panic if the allocation failed + if (out == nullptr) { + panic("Heap allocation failed"); + } + + // update size for the heap segment now that it is to be considered + // allocated + out->size = sz; + out->next = (HeapSegment*) (((uint8_t*) out) + sz); + out->inUse = true; + + auto hs = *_heapIdx; + hs.size -= sz; + if (hs.size == 0) { + _heapIdx = hs.next; + } else { + _heapIdx = (HeapSegment*) (((uint8_t*) _heapIdx) - sz); + *_heapIdx = hs; + } + + return out; } void operator delete(void *ptr) { + HeapSegment *prev = nullptr; + HeapSegment *current = _heapIdx; + while (current && current != ptr) { + prev = current; + current = current->next; + } + + // ptr was found as a valid memory allocation, deallocate it + if (current) { + // mark as not in use + prev->inUse = false; + + // join with next if next is also unused + if (current->next && !current->next->inUse) { + current->size += current->next->size; + current->next = current->next->next; + } + + // join with prev if prev is also unused + if (prev && !prev->inUse) { + prev->size += current->size; + prev->next = current->next; + } + } } diff --git a/src/nostalgia/core/gba/panic.cpp b/src/nostalgia/core/gba/panic.cpp new file mode 100644 index 00000000..85e66bfc --- /dev/null +++ b/src/nostalgia/core/gba/panic.cpp @@ -0,0 +1,27 @@ +/* + * 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 "../core.hpp" +#include "panic.hpp" + +namespace nostalgia { +namespace core { + +void panic(const char *msg) { + initConsole(nullptr); + puts(nullptr, 1 * 32 + 0, "SADNESS..."); + puts(nullptr, 4 * 32 + 0, "UNEXPECTED STATE:"); + puts(nullptr, 6 * 32 + 2, msg); + puts(nullptr, 10 * 32 + 0, "PLEASE RESTART THE SYSTEM"); + // TODO: properly end program execution, this wastes power + while (1); +} + +} +} + diff --git a/src/nostalgia/core/gba/panic.hpp b/src/nostalgia/core/gba/panic.hpp new file mode 100644 index 00000000..fd97eba5 --- /dev/null +++ b/src/nostalgia/core/gba/panic.hpp @@ -0,0 +1,20 @@ +/* + * 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 "panic.hpp" + +namespace nostalgia { +namespace core { + +void panic(const char *msg); + +} +} + diff --git a/src/nostalgia/core/gfx.hpp b/src/nostalgia/core/gfx.hpp index c8068757..7ecf436a 100644 --- a/src/nostalgia/core/gfx.hpp +++ b/src/nostalgia/core/gfx.hpp @@ -20,7 +20,7 @@ ox::Error initConsole(Context *ctx); void puts(Context *ctx, int loc, const char *str); -void setTileMap(Context *ctx, int layer, int columns, int rows, uint16_t *buff); +void setTile(Context *ctx, int layer, int column, int row, uint16_t tile); } } diff --git a/src/nostalgia/core/mem.hpp b/src/nostalgia/core/mem.hpp new file mode 100644 index 00000000..51527998 --- /dev/null +++ b/src/nostalgia/core/mem.hpp @@ -0,0 +1,15 @@ +/* + * 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/. + */ + +namespace nostalgia { +namespace core { + +void initHeap(); + +} +} diff --git a/src/nostalgia/core/studio/charset.png b/src/nostalgia/core/studio/charset.png index 20bae7eb0351ee1e4636e7df76c122a3047a5b19..e37d792c0768c508c7ab6dc4092fe557eb89e340 100644 GIT binary patch delta 440 zcmV;p0Z0Dg37`tFJp+HvNklZucY2ar)eyf8{m$ym@?|tbgBa z%Q+?0cIff>^D^-a=O&Teyss8u)^}!jI=|nbHNpDZ6-i6%RDgdJcqu@i?6l{W zVk>t(U%!U1?Z!<3Qp=SBln$SX@E+V*zLcImj71@@I0x%4NnQT0=n za94mi+k35nbf^1+^`#Ej9saBi7{>zK1)ASBV@dE+o&gi%v;?;QHIyHgnd--tMeIaO;ZkPxh6 zj1e&&uTef+=aJ7NU4OJq_l@V}bd0ObnC(aH=H+>$K2Gnu`>(i0?>D#ao%PSVW4Wh< z+AclbzlVwEbY29q>-XIR%>2#>Pxto)S_7=#T{CHcof42HUJ`#0?NS8pgz&{QcFPeMyFx63AolN;xPW~ zuNOm`)HVTcJOx#rHyxe=Y19~FE%B?#vejBZZ40cw>W4)2Ewn53lBD#-&839pOf3oe z)O4k|`X0SS0$ThxOhEl@xZf7oJmJ>I#pdi|{E>hUjkr5)f$hJB8@g%Old%Ci7jS1^ X5rhJ8NnyJ#00000NkvXXu0mjfop-#i diff --git a/src/nostalgia/core/userland/mem.cpp b/src/nostalgia/core/userland/mem.cpp new file mode 100644 index 00000000..f7a66dcd --- /dev/null +++ b/src/nostalgia/core/userland/mem.cpp @@ -0,0 +1,16 @@ +/* + * 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/. + */ + +namespace nostalgia { +namespace core { + +void initHeap() { +} + +} +} diff --git a/src/nostalgia/world/world.cpp b/src/nostalgia/world/world.cpp index fa9c7ac7..b7d1b68b 100644 --- a/src/nostalgia/world/world.cpp +++ b/src/nostalgia/world/world.cpp @@ -11,5 +11,31 @@ namespace nostalgia { namespace world { +Zone::Zone() { + m_bounds.x = -1; + m_bounds.y = -1; + m_bounds.width = -1; + m_bounds.height = -1; +} + +void Zone::draw(core::Context *ctx) { +} + +size_t Zone::size() { + return sizeof(Zone) + m_bounds.width * m_bounds.height * sizeof(TileDef); +} + +TileDef *Zone::tiles() { + return (TileDef*) (this + 1); +} + +TileDef *Zone::tile(int row, int column) { + return &tiles()[row * m_bounds.width + column]; +} + +void Zone::setTile(int row, int column, TileDef *td) { + tiles()[row * m_bounds.width + column] = *td; +} + } } diff --git a/src/nostalgia/world/world.hpp b/src/nostalgia/world/world.hpp index ae899727..88bc9dd0 100644 --- a/src/nostalgia/world/world.hpp +++ b/src/nostalgia/world/world.hpp @@ -10,13 +10,58 @@ #include +#include +#include + namespace nostalgia { namespace world { +struct TileDef { + uint16_t bgTile; +}; + +template +ox::Error ioOp(T *io, TileDef *obj) { + ox::Error err = 0; + io->setFields(1); + err |= io->op("bgTile", &obj->bgTile); + return err; +} + + struct ZoneDef { - int width = 0; - int height = 0; - uint16_t tileMap; + int32_t width = 0; + int32_t height = 0; +}; + +class Zone { + + private: + common::Bounds m_bounds; + + public: + + Zone(); + + void draw(core::Context *ctx); + + size_t size(); + + TileDef *tiles(); + + TileDef *tile(int row, int column); + + void setTile(int row, int column, TileDef *td); + +}; + +class Region { + + private: + Zone *m_zones; + + public: + }; }