Add support world drawing

This commit is contained in:
Gary Talent 2017-11-09 21:43:59 -06:00
parent 539aa1e7eb
commit 2edee450aa
22 changed files with 232 additions and 61 deletions

View File

@ -14,11 +14,15 @@ if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
-nostdlib -nostdlib
-fno-exceptions -fno-exceptions
-fno-rtti -fno-rtti
-fno-strict-aliasing
-mthumb-interwork
-mthumb
) )
endif() endif()
add_definitions( add_definitions(
-std=c++11 -std=c++14
-fdiagnostics-color
-Wall -Wall
-Wsign-compare -Wsign-compare
) )
@ -45,7 +49,7 @@ else()
set(NOSTALGIA_DIST_RESOURCES share) set(NOSTALGIA_DIST_RESOURCES share)
endif() endif()
if (CMAKE_BUILD_TYPE STREQUAL "Release") if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_definitions( add_definitions(
-Werror -Werror
) )

View File

@ -3,4 +3,4 @@ FROM wombatant/devenv:latest
ENV DEVKITPRO /opt/devkitPro ENV DEVKITPRO /opt/devkitPro
ENV DEVKITARM ${DEVKITPRO}/devkitARM ENV DEVKITARM ${DEVKITPRO}/devkitARM
RUN dnf install -y findutils RUN dnf install -y findutils ninja-build

View File

@ -1,9 +1,9 @@
all: gba_build gba_debug_build native_build native_debug_build windows_release windows_debug all: gba_build gba_debug_build native_build native_debug_build windows_release windows_debug
ifneq ($(shell which gmake),) ifneq ($(shell which gmake),)
MAKE="gmake -j" MAKE="gmake"
else else
MAKE="make -j" MAKE="make"
endif endif
gba_build: gba_build:

Binary file not shown.

After

Width:  |  Height:  |  Size: 921 B

View File

@ -3,18 +3,21 @@
set -e set -e
BIN=./dist/current/bin/ 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_MEDIA=nostalgia_media.oxfs
NOSTALGA_GBA=nostalgia.gba NOSTALGA_GBA=nostalgia.gba
MEDIA_HEADER=media_header.txt MEDIA_HEADER=media_header.txt
CHARSET_FILE=src/nostalgia/core/studio/charset.png CHARSET_FILE=src/nostalgia/core/studio/charset.png
TILESHEET_TEST_REGION1=media/tilesheet_test_region1.png
echo NOSTALGIA_MEDIA_HEADER_________ > $MEDIA_HEADER echo NOSTALGIA_MEDIA_HEADER_________ > $MEDIA_HEADER
$BIN/oxfs format 32 1k $NOSTALGA_MEDIA oxfs format 32 1k $NOSTALGA_MEDIA
$BIN/nost-pack -fs $NOSTALGA_MEDIA -img $CHARSET_FILE -inode 101 -tiles 127 -bpp 4 -c 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 cat $NOSTALGA_BIN $MEDIA_HEADER $NOSTALGA_MEDIA > $NOSTALGA_GBA
rm -f $MEDIA_HEADER $NOSTALGA_MEDIA rm -f $MEDIA_HEADER $NOSTALGA_MEDIA
${DEVKITARM}/bin/gbafix $NOSTALGA_GBA gbafix $NOSTALGA_GBA

View File

@ -11,5 +11,5 @@ namespace = "namespace nostalgia {\nnamespace %s {\n\n}\n}" % pkg
hpp = "#pragma once\n" hpp = "#pragma once\n"
cpp = "#include \"%s.hpp\"\n\n%s" % (name, namespace) cpp = "#include \"%s.hpp\"\n\n%s" % (name, namespace)
open("src/%s/%s.hpp" % (pkg, name), "w").write(hpp) open("src/nostalgia/%s/%s.hpp" % (pkg, name), "w").write(hpp)
open("src/%s/%s.cpp" % (pkg, name), "w").write(cpp) open("src/nostalgia/%s/%s.cpp" % (pkg, name), "w").write(cpp)

View File

@ -7,6 +7,10 @@ project=$(pwd)/
TARGET=$1 TARGET=$1
BUILD_TYPE=$2 BUILD_TYPE=$2
#if [[ $(which ninja) != "ninja not found" ]]; then
# buildTool="-GNinja"
#fi
if [[ $TARGET == windows ]]; then if [[ $TARGET == windows ]]; then
toolchain="-DCMAKE_TOOLCHAIN_FILE=cmake/Modules/Mingw.cmake" toolchain="-DCMAKE_TOOLCHAIN_FILE=cmake/Modules/Mingw.cmake"
elif [[ $TARGET == gba ]]; then elif [[ $TARGET == gba ]]; then
@ -28,6 +32,7 @@ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_INSTALL_PREFIX="$distDir" \ -DCMAKE_INSTALL_PREFIX="$distDir" \
-DCMAKE_INSTALL_RPATH="$project/dist/${TARGET}-${BUILD_TYPE}/lib/nostalgia" \ -DCMAKE_INSTALL_RPATH="$project/dist/${TARGET}-${BUILD_TYPE}/lib/nostalgia" \
-DNOSTALGIA_IDE_BUILD=OFF \ -DNOSTALGIA_IDE_BUILD=OFF \
$buildTool \
$buildTypeArgs \ $buildTypeArgs \
$toolchain \ $toolchain \
$project $project

View File

@ -10,7 +10,11 @@
namespace nostalgia { namespace nostalgia {
namespace common { 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 { bool Bounds::intersects(Bounds o) const {

View File

@ -19,10 +19,9 @@ class Bounds {
int width = 0; int width = 0;
int height = 0; int height = 0;
/** Bounds() = default;
* Constructor
*/ Bounds(int x, int y, int w, int h);
Bounds();
bool intersects(Bounds other) const; bool intersects(Bounds other) const;

View File

@ -16,6 +16,7 @@ elseif(NOSTALGIA_BUILD_TYPE STREQUAL "Native")
set( set(
CPP CPP
qt/gfx.cpp qt/gfx.cpp
userland/media.cpp
userland/mem.cpp userland/mem.cpp
) )
endif() endif()
@ -34,6 +35,7 @@ install(
FILES FILES
core.hpp core.hpp
gfx.hpp gfx.hpp
media.hpp
gba/gba.hpp gba/gba.hpp
DESTINATION DESTINATION
include/nostalgia/core include/nostalgia/core

View File

@ -11,6 +11,8 @@
#include <ox/fs/filesystem.hpp> #include <ox/fs/filesystem.hpp>
#include "gfx.hpp" #include "gfx.hpp"
#include "media.hpp"
#include "types.hpp"
namespace nostalgia { namespace nostalgia {
namespace core { namespace core {

View File

@ -8,9 +8,13 @@
#include <ox/fs/filesystem.hpp> #include <ox/fs/filesystem.hpp>
#include <ox/std/std.hpp> #include <ox/std/std.hpp>
#include "../media.hpp"
#include "addresses.hpp" #include "addresses.hpp"
#include "media.hpp"
#include "gba.hpp" #include "gba.hpp"
#include "panic.hpp"
#include "../gfx.hpp" #include "../gfx.hpp"
namespace nostalgia { namespace nostalgia {
@ -22,6 +26,7 @@ using namespace ox;
#define TILE8_ADDR ((CharBlock8*) 0x06000000) #define TILE8_ADDR ((CharBlock8*) 0x06000000)
const auto GBA_TILE_COLUMNS = 32; const auto GBA_TILE_COLUMNS = 32;
const auto GBA_TILE_ROWS = 32;
// map ASCII values to the nostalgia charset // map ASCII values to the nostalgia charset
static char charMap[128] = { static char charMap[128] = {
@ -170,7 +175,7 @@ ox::Error initConsole(Context*) {
const auto CharsetInode = 101; const auto CharsetInode = 101;
const auto PaletteStart = sizeof(GbaImageDataHeader); const auto PaletteStart = sizeof(GbaImageDataHeader);
ox::Error err = 0; ox::Error err = 0;
auto fs = (FileStore32*) findMedia(); auto fs = (FileStore32*) loadRom();
GbaImageDataHeader imgData; GbaImageDataHeader imgData;
@ -199,6 +204,37 @@ ox::Error initConsole(Context*) {
return err; 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. // Do NOT use Context in the GBA version of this function.
void puts(Context*, int loc, const char *str) { void puts(Context*, int loc, const char *str) {
for (int i = 0; str[i]; i++) { 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) { void setTile(Context *ctx, int layer, int column, int row, uint8_t tile) {
MEM_BG_MAP[28 + layer][row * GBA_TILE_COLUMNS + column] = tile; if (column < GBA_TILE_COLUMNS && row < GBA_TILE_ROWS) {
MEM_BG_MAP[28 + layer][row * GBA_TILE_COLUMNS + column] = tile;
}
} }
} }

View File

@ -9,12 +9,13 @@
#include <ox/fs/filesystem.hpp> #include <ox/fs/filesystem.hpp>
#include <ox/std/std.hpp> #include <ox/std/std.hpp>
#include "addresses.hpp" #include "addresses.hpp"
#include "media.hpp"
#include "../media.hpp"
namespace nostalgia { namespace nostalgia {
namespace core { namespace core {
uint8_t *findMedia() { uint8_t *loadRom(const char*) {
// put the header in the wrong order to prevent mistaking this code for the // put the header in the wrong order to prevent mistaking this code for the
// media section // media section
const static auto headerP2 = "_HEADER_________"; const static auto headerP2 = "_HEADER_________";
@ -29,7 +30,7 @@ uint8_t *findMedia() {
return current + headerLen; return current + headerLen;
} }
} }
return 0; return nullptr;
} }
} }

View File

@ -5,11 +5,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
#include <ox/std/types.hpp> #include <ox/std/types.hpp>
#include "context.hpp" #include "context.hpp"
#include "types.hpp"
namespace nostalgia { namespace nostalgia {
namespace core { namespace core {
@ -18,9 +20,11 @@ ox::Error initGfx(Context *ctx);
ox::Error initConsole(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 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);
} }
} }

View File

@ -13,7 +13,7 @@
namespace nostalgia { namespace nostalgia {
namespace core { namespace core {
uint8_t *findMedia(); uint8_t *loadRom(const char *path = "");
} }
} }

View File

@ -19,8 +19,15 @@ ox::Error initConsole(Context *ctx) {
return 1; return 1;
} }
ox::Error loadTileSheet(Context *ctx, InodeId_t inode) {
return 1;
}
void puts(Context *ctx, int loc, const char *str) { void puts(Context *ctx, int loc, const char *str) {
} }
void setTile(Context *ctx, int layer, int column, int row, uint8_t tile) {
}
} }
} }

View File

@ -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 <ox/fs/filestore.hpp>
namespace nostalgia {
namespace core {
typedef ox::FileStore32::InodeId_t InodeId_t;
}
}

View File

@ -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 <ox/fs/filesystem.hpp>
#include <ox/std/std.hpp>
#include "../media.hpp"
namespace nostalgia {
namespace core {
uint8_t *loadRom(const char*) {
return nullptr;
}
}
}

View File

@ -17,9 +17,11 @@ endif()
target_link_libraries( target_link_libraries(
nostalgia nostalgia
NostalgiaWorld
NostalgiaCommon
NostalgiaCore NostalgiaCore
OxStd
OxFS OxFS
OxStd
) )
add_custom_target("nostalgia.bin") add_custom_target("nostalgia.bin")

View File

@ -6,16 +6,19 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#include <nostalgia/core/core.hpp> #include <nostalgia/world/world.hpp>
using namespace nostalgia::common;
using namespace nostalgia::core; using namespace nostalgia::core;
using namespace nostalgia::world;
int main() { int main() {
ox::FileSystem32 fs(loadRom(), false);
Context ctx; Context ctx;
init(&ctx); init(&ctx);
initConsole(&ctx); ctx.rom = &fs;
puts(&ctx, 9 * 32 + 8, "HELLO,WORLD!"); Zone zone(&ctx, Bounds{0, 0, 40, 40}, 102);
puts(&ctx, 10 * 32 + 8, "01234 56789"); zone.draw(&ctx);
while (1); while (1);
return 0; return 0;
} }

View File

@ -11,24 +11,42 @@
namespace nostalgia { namespace nostalgia {
namespace world { 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; 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() { 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) { Tile *Zone::tile(int x, int y) {
return &m_tiles[row * m_bounds.width + column]; return &m_tiles[x * m_bounds.width + y];
} }
void Zone::setTile(int row, int column, TileDef *td) { void Zone::setTile(int x, int y, Tile *td) {
m_tiles[row * m_bounds.width + column] = *td; m_tiles[x * m_bounds.width + y] = *td;
} }
} }

View File

@ -8,7 +8,7 @@
#pragma once #pragma once
#include <ox/std/types.hpp> #include <ox/mc/mc.hpp>
#include <nostalgia/common/common.hpp> #include <nostalgia/common/common.hpp>
#include <nostalgia/core/core.hpp> #include <nostalgia/core/core.hpp>
@ -16,56 +16,94 @@
namespace nostalgia { namespace nostalgia {
namespace world { namespace world {
struct TileDef { struct Tile {
uint16_t bgTile; uint8_t bgTile = 0;
uint8_t type = 0;
void *occupant = nullptr;
}; };
template<typename T> template<typename T>
ox::Error ioOp(T *io, TileDef *obj) { ox::Error ioOpRead(T *io, Tile *obj) {
ox::Error err = 0; ox::Error err = 0;
io->setFields(1); io->setFields(2);
err |= io->op("bgTile", &obj->bgTile); err |= io->op("bgTile", &obj->bgTile);
err |= io->op("type", &obj->type);
return err; return err;
} }
struct RegionDef { struct Zone {
uint32_t tileSheetInodes[20];
};
struct ZoneDef { template<typename T>
int32_t width = 0; friend ox::Error ioOpRead(T*, Zone*);
int32_t height = 0;
};
class Zone { template<typename T>
friend ox::Error ioOpWrite(T*, Zone*);
private: protected:
static const int FIELDS;
common::Bounds m_bounds; common::Bounds m_bounds;
TileDef *m_tiles = nullptr; Tile *m_tiles = nullptr;
public: public:
Zone(core::Context *ctx, common::Bounds bnds, core::InodeId_t tileSheet);
Zone(common::Bounds bnds);
void draw(core::Context *ctx); void draw(core::Context *ctx);
size_t size(); 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<typename T>
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: template<typename T>
Zone *m_zones; 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<typename T>
friend ox::Error ioOpRead(T*, Region*);
template<typename T>
friend ox::Error ioOpWrite(T*, Region*);
protected:
static const int FIELDS;
Zone *m_zones = nullptr;
public: public:
}; };
template<typename T>
ox::Error ioOpRead(T *io, Region *obj) {
ox::Error err = 0;
io->setFields(Region::FIELDS);
return err;
}
template<typename T>
ox::Error ioOpWrite(T *io, Region *obj) {
ox::Error err = 0;
io->setFields(Region::FIELDS);
return err;
}
} }
} }