Merge branch 'master' of github.com:gtalent/nostalgia
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
#setup libraries
|
||||
|
||||
if(NOSTALGIA_BUILD_TYPE STREQUAL "Native")
|
||||
find_package(SDL2 CONFIG REQUIRED)
|
||||
if(NOSTALGIA_BUILD_STUDIO)
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
find_package(Qt5QuickWidgets REQUIRED)
|
||||
|
@ -2,6 +2,7 @@ add_library(
|
||||
NostalgiaCore
|
||||
core.cpp
|
||||
gfx.cpp
|
||||
media.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
@ -9,9 +10,8 @@ target_link_libraries(
|
||||
OxFS
|
||||
)
|
||||
|
||||
if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
|
||||
add_subdirectory(gba)
|
||||
elseif(NOSTALGIA_BUILD_TYPE STREQUAL "Native")
|
||||
add_subdirectory(gba)
|
||||
if(NOSTALGIA_BUILD_TYPE STREQUAL "Native")
|
||||
add_subdirectory(sdl)
|
||||
add_subdirectory(userland)
|
||||
endif()
|
||||
|
@ -12,10 +12,7 @@
|
||||
namespace nostalgia::core {
|
||||
|
||||
ox::Error init(Context *ctx) {
|
||||
auto err = OxError(0);
|
||||
err = initGfx(ctx);
|
||||
initHeap(); // this does nothing in userland builds
|
||||
return err;
|
||||
return initGfx(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,23 +1,35 @@
|
||||
add_library(
|
||||
NostalgiaCore-GBA
|
||||
core.cpp
|
||||
gfx.cpp
|
||||
media.cpp
|
||||
mem.cpp
|
||||
panic.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
NostalgiaCore-GBA PUBLIC
|
||||
NostalgiaCore
|
||||
GbaStartup
|
||||
OxFS
|
||||
OxStd
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
|
||||
add_library(
|
||||
NostalgiaCore-GBA
|
||||
DESTINATION
|
||||
include/nostalgia/core
|
||||
)
|
||||
core.cpp
|
||||
gfx.cpp
|
||||
media.cpp
|
||||
mem.cpp
|
||||
panic.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
NostalgiaCore-GBA PUBLIC
|
||||
NostalgiaCore
|
||||
GbaStartup
|
||||
OxFS
|
||||
OxStd
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
NostalgiaCore-GBA
|
||||
DESTINATION
|
||||
include/nostalgia/core
|
||||
)
|
||||
endif()
|
||||
|
||||
# tests
|
||||
if(NOSTALGIA_BUILD_TYPE STREQUAL "Native")
|
||||
add_executable(NostalgiaCore-GBA_Test
|
||||
tests.cpp
|
||||
mem.cpp
|
||||
)
|
||||
target_link_libraries(NostalgiaCore-GBA_Test NostalgiaCore)
|
||||
add_test("NostalgiaCore-GBA\\ Test\\ malloc" NostalgiaCore-GBA_Test malloc)
|
||||
endif()
|
||||
|
@ -45,7 +45,7 @@
|
||||
typedef uint16_t BgMapTile[1024];
|
||||
#define MEM_BG_MAP reinterpret_cast<BgMapTile*>(0x06000000)
|
||||
|
||||
#define MEM_ROM *reinterpret_cast<char*>(0x08000000)
|
||||
#define MEM_ROM reinterpret_cast<char*>(0x08000000)
|
||||
|
||||
#define MEM_WRAM_BEGIN reinterpret_cast<uint8_t*>(0x02000000)
|
||||
#define MEM_WRAM_END reinterpret_cast<uint8_t*>(0x0203FFFF)
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <nostalgia/core/gfx.hpp>
|
||||
|
||||
#include "addresses.hpp"
|
||||
#include "panic.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
@ -102,7 +101,7 @@ ox::Error shutdownGfx() {
|
||||
case 3:
|
||||
return REG_BG3CNT;
|
||||
default:
|
||||
panic("Looking up non-existent register");
|
||||
oxPanic("Looking up non-existent register", OxError(1));
|
||||
return REG_BG0CNT;
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ char *loadRom(const char*) {
|
||||
constexpr auto headerP2Len = 16;
|
||||
constexpr auto headerLen = headerP1Len + headerP2Len + 1;
|
||||
|
||||
for (auto current = &MEM_ROM; current < reinterpret_cast<char*>(0x0a000000); current += headerLen) {
|
||||
for (auto current = MEM_ROM; current < reinterpret_cast<char*>(0x0a000000); current += headerLen) {
|
||||
if (ox_memcmp(current, headerP1, headerP1Len) == 0 &&
|
||||
ox_memcmp(current + headerP1Len, headerP2, headerP2Len) == 0) {
|
||||
return current + headerLen;
|
||||
|
@ -7,11 +7,9 @@
|
||||
*/
|
||||
|
||||
#include "addresses.hpp"
|
||||
#include "ox/std/bit.hpp"
|
||||
#include "ox/std/types.hpp"
|
||||
#include "panic.hpp"
|
||||
|
||||
#include <ox/std/std.hpp>
|
||||
#include <ox/std/assert.hpp>
|
||||
#include <ox/std/bit.hpp>
|
||||
|
||||
// this warning is too dumb to realize that it can actually confirm the hard
|
||||
// coded address aligns with the requirement of HeapSegment, so it must be
|
||||
@ -25,6 +23,10 @@
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
static class HeapSegment *volatile g_heapBegin = nullptr;
|
||||
static class HeapSegment *volatile g_heapEnd = nullptr;
|
||||
static class HeapSegment *volatile heapIdx = nullptr;
|
||||
|
||||
static constexpr std::size_t alignedSize(std::size_t sz) {
|
||||
return sz + (sz & 7);
|
||||
}
|
||||
@ -38,39 +40,35 @@ struct HeapSegment {
|
||||
std::size_t size;
|
||||
uint8_t inUse;
|
||||
|
||||
void init(std::size_t maxSize = ox::bit_cast<std::size_t>(HEAP_END)) {
|
||||
this->size = maxSize - reinterpret_cast<std::size_t>(this);
|
||||
void init(std::size_t maxSize = ox::bit_cast<std::size_t>(g_heapEnd)) {
|
||||
this->size = maxSize - ox::bit_cast<std::size_t>(this);
|
||||
this->inUse = false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *data() {
|
||||
return reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(this) + alignedSize(this));
|
||||
return ox::bit_cast<T*>(ox::bit_cast<uint8_t*>(this) + alignedSize(this));
|
||||
}
|
||||
|
||||
template<typename T = uint8_t>
|
||||
T *end() {
|
||||
const auto size = alignedSize(this) + alignedSize(this->size);
|
||||
auto e = reinterpret_cast<uintptr_t>(reinterpret_cast<uint8_t*>(this) + size);
|
||||
return reinterpret_cast<T*>(e);
|
||||
auto e = ox::bit_cast<uintptr_t>(ox::bit_cast<uint8_t*>(this) + size);
|
||||
return ox::bit_cast<T*>(e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static HeapSegment *volatile heapIdx = nullptr;
|
||||
|
||||
void initHeap() {
|
||||
heapIdx = HEAP_BEGIN;
|
||||
heapIdx->init();
|
||||
void initHeap(char *heapBegin, char *heapEnd) {
|
||||
g_heapBegin = ox::bit_cast<HeapSegment*>(heapBegin);
|
||||
g_heapEnd = ox::bit_cast<HeapSegment*>(heapEnd);
|
||||
heapIdx = g_heapBegin;
|
||||
heapIdx->size = ox::bit_cast<std::size_t>(heapEnd) - ox::bit_cast<std::size_t>(heapIdx);
|
||||
heapIdx->inUse = false;
|
||||
}
|
||||
|
||||
static HeapSegment *findSegmentFor(std::size_t sz) {
|
||||
for (auto s = HEAP_BEGIN; s + sz < HEAP_END; s = s->end<HeapSegment>()) {
|
||||
if (s->size >= sz && !s->inUse) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
void initHeap() {
|
||||
initHeap(ox::bit_cast<char*>(HEAP_BEGIN), ox::bit_cast<char*>(HEAP_END));
|
||||
}
|
||||
|
||||
struct SegmentPair {
|
||||
@ -90,6 +88,16 @@ static SegmentPair findSegmentOf(void *ptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
static HeapSegment *findSegmentFor(std::size_t sz) {
|
||||
for (auto s = g_heapBegin; s <= g_heapEnd; s = s->end<HeapSegment>()) {
|
||||
if (s->size >= sz && !s->inUse) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
oxPanic("malloc: could not find segment", OxError(1));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] void *malloc(std::size_t allocSize) {
|
||||
const auto targetSize = alignedSize(sizeof(HeapSegment)) + alignedSize(allocSize);
|
||||
auto seg = findSegmentFor(targetSize);
|
||||
@ -99,9 +107,8 @@ static SegmentPair findSegmentOf(void *ptr) {
|
||||
const auto bytesRemaining = seg->size - targetSize;
|
||||
seg->size = targetSize;
|
||||
seg->inUse = true;
|
||||
auto out = seg->data<void>();
|
||||
seg->end<HeapSegment>()->init(bytesRemaining);
|
||||
return out;
|
||||
return seg->data<void>();
|
||||
}
|
||||
|
||||
void free(void *ptr) {
|
||||
@ -111,12 +118,14 @@ void free(void *ptr) {
|
||||
} else if (p.segment) {
|
||||
p.segment->inUse = false;
|
||||
} else {
|
||||
panic("Bad heap free");
|
||||
oxPanic("Bad heap free", OxError(1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifndef OX_USE_STDLIB
|
||||
|
||||
using namespace nostalgia;
|
||||
|
||||
void *operator new(std::size_t allocSize) {
|
||||
@ -142,3 +151,13 @@ void operator delete(void *ptr, unsigned) {
|
||||
void operator delete[](void *ptr, unsigned) {
|
||||
core::free(ptr);
|
||||
}
|
||||
|
||||
void operator delete(void *ptr, unsigned long int) {
|
||||
core::free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void *ptr, unsigned long int) {
|
||||
core::free(ptr);
|
||||
}
|
||||
|
||||
#endif
|
@ -7,15 +7,21 @@
|
||||
*/
|
||||
|
||||
#include "../core.hpp"
|
||||
#include "panic.hpp"
|
||||
#include "../gfx.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
namespace ox {
|
||||
|
||||
void panic(const char *msg) {
|
||||
using namespace nostalgia::core;
|
||||
|
||||
void panic(const char*, int, const char *msg, ox::Error err) {
|
||||
oxIgnoreError(initGfx(nullptr));
|
||||
oxIgnoreError(initConsole(nullptr));
|
||||
ox::BString<23> serr = "Error code: ";
|
||||
serr += err;
|
||||
puts(nullptr, 32 + 0, 1, "SADNESS...");
|
||||
puts(nullptr, 32 + 0, 4, "UNEXPECTED STATE:");
|
||||
puts(nullptr, 32 + 2, 6, msg);
|
||||
puts(nullptr, 32 + 2, 7, serr.c_str());
|
||||
puts(nullptr, 32 + 0, 10, "PLEASE RESTART THE SYSTEM");
|
||||
// TODO: properly end program execution, this wastes power
|
||||
while (1);
|
||||
|
@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 - 2019 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
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
void panic(const char *msg);
|
||||
|
||||
}
|
||||
|
50
src/nostalgia/core/gba/tests.cpp
Normal file
50
src/nostalgia/core/gba/tests.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
#include <nostalgia/core/mem.hpp>
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
[[nodiscard]] void *malloc(std::size_t allocSize);
|
||||
|
||||
void free(void *ptr);
|
||||
|
||||
void initHeap(char *heapBegin, char *heapEnd);
|
||||
|
||||
}
|
||||
|
||||
using namespace nostalgia;
|
||||
|
||||
int testMalloc(std::string) {
|
||||
std::vector<char> buff(ox::units::MB);
|
||||
core::initHeap(&buff.front(), &buff.back());
|
||||
oxAssert(core::malloc(5) != nullptr, "malloc is broken");
|
||||
oxAssert(core::malloc(5) != nullptr, "malloc is broken");
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::map<std::string, int(*)(std::string)> tests = {
|
||||
{
|
||||
{ "malloc", testMalloc },
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, const char **args) {
|
||||
int retval = -1;
|
||||
if (argc > 1) {
|
||||
auto testName = args[1];
|
||||
std::string testArg = "";
|
||||
if (args[2]) {
|
||||
testArg = args[2];
|
||||
}
|
||||
if (tests.find(testName) != tests.end()) {
|
||||
retval = tests[testName](testArg);
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
31
src/nostalgia/core/media.cpp
Normal file
31
src/nostalgia/core/media.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2016 - 2020 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 "media.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
ox::FileSystem *loadRomFs(const char *path) {
|
||||
const auto lastDot = ox_lastIndexOf(path, '.');
|
||||
const auto fsExt = lastDot != -1 ? path + lastDot : "";
|
||||
if (ox_strcmp(fsExt, ".oxfs") == 0) {
|
||||
auto rom = core::loadRom(path);
|
||||
if (!rom) {
|
||||
return nullptr;
|
||||
}
|
||||
return new ox::FileSystem32(rom, 32 * ox::units::MB, unloadRom);
|
||||
} else {
|
||||
#ifdef OX_HAS_PASSTHROUGHFS
|
||||
return new ox::PassThroughFS(path);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -8,10 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/types.hpp>
|
||||
#include <ox/fs/fs.hpp>
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
ox::FileSystem *loadRomFs(const char *path);
|
||||
|
||||
char *loadRom(const char *path = "");
|
||||
|
||||
void unloadRom(char*);
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <ox/fs/fs.hpp>
|
||||
#include <ox/std/units.hpp>
|
||||
#include <nostalgia/core/core.hpp>
|
||||
#include <nostalgia/world/world.hpp>
|
||||
|
||||
using namespace nostalgia;
|
||||
@ -28,29 +29,12 @@ ox::Error run(ox::FileSystem *fs) {
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
if (argc > 1) {
|
||||
ox::FileSystem *fs = nullptr;
|
||||
char *rom = nullptr;
|
||||
auto path = argv[1];
|
||||
const auto lastDot = ox_lastIndexOf(path, '.');
|
||||
const auto fsExt = lastDot != -1 ? path + lastDot : "";
|
||||
if (ox_strcmp(fsExt, ".oxfs") == 0) {
|
||||
rom = core::loadRom(path);
|
||||
if (!rom) {
|
||||
return 1;
|
||||
}
|
||||
fs = new (ox_alloca(sizeof(ox::FileStore32))) ox::FileSystem32(ox::FileStore32(rom, 32 * ox::units::MB));
|
||||
} else {
|
||||
#ifdef OX_HAS_PASSTHROUGHFS
|
||||
fs = new (ox_alloca(sizeof(ox::PassThroughFS))) ox::PassThroughFS(path);
|
||||
#else
|
||||
return 2;
|
||||
#endif
|
||||
}
|
||||
auto fs = core::loadRomFs(path);
|
||||
auto err = run(fs);
|
||||
oxAssert(err, "Something went wrong...");
|
||||
fs->~FileSystem();
|
||||
core::unloadRom(rom);
|
||||
delete fs;
|
||||
return err;
|
||||
}
|
||||
return 3;
|
||||
return 1;
|
||||
}
|
||||
|
@ -6,8 +6,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
@ -54,7 +52,7 @@ int main(int argc, const char **args) {
|
||||
try {
|
||||
run(ox::ClArgs(argc, args));
|
||||
} catch (const ox::Error &err) {
|
||||
oxPanic(err, "pack failed");
|
||||
oxPanic("pack failed", err);
|
||||
std::cerr << "pack failed...\n";
|
||||
return static_cast<int>(err);
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ struct VerificationPair {
|
||||
std::cout << "copying directory: " << path << '\n';
|
||||
std::vector<VerificationPair> verficationPairs;
|
||||
// copy
|
||||
oxReturnError(src->ls(path.c_str(), [&verficationPairs, src, dest, path](const char *name, ox::InodeId_t) {
|
||||
oxReturnError(src->ls(path.c_str(), [&verficationPairs, src, dest, path](std::string name, ox::InodeId_t) {
|
||||
std::cout << "reading " << name << '\n';
|
||||
auto currentFile = path + name;
|
||||
auto [stat, err] = src->stat((currentFile).c_str());
|
||||
|
Reference in New Issue
Block a user