diff --git a/CMakeLists.txt b/CMakeLists.txt index 238c6ded..91407876 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ if(NOT MSVC) include(GBA) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc++") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-unwind-tables") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") diff --git a/cmake/modules/FindSDL2.cmake b/cmake/modules/FindSDL2.cmake new file mode 100644 index 00000000..a827f905 --- /dev/null +++ b/cmake/modules/FindSDL2.cmake @@ -0,0 +1,386 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# Copyright 2019 Amine Ben Hassouna +# Copyright 2000-2019 Kitware, Inc. and Contributors +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: + +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. + +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. + +# * Neither the name of Kitware, Inc. nor the names of Contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#[=======================================================================[.rst: +FindSDL2 +-------- + +Locate SDL2 library + +This module defines the following 'IMPORTED' targets: + +:: + + SDL2::Core + The SDL2 library, if found. + Libraries should link to SDL2::Core + + SDL2::Main + The SDL2main library, if found. + Applications should link to SDL2::Main instead of SDL2::Core + + + +This module will set the following variables in your project: + +:: + + SDL2_LIBRARIES, the name of the library to link against + SDL2_INCLUDE_DIRS, where to find SDL.h + SDL2_FOUND, if false, do not try to link to SDL2 + SDL2MAIN_FOUND, if false, do not try to link to SDL2main + SDL2_VERSION_STRING, human-readable string containing the version of SDL2 + + + +This module responds to the following cache variables: + +:: + + SDL2_PATH + Set a custom SDL2 Library path (default: empty) + + SDL2_NO_DEFAULT_PATH + Disable search SDL2 Library in default path. + If SDL2_PATH (default: ON) + Else (default: OFF) + + SDL2_INCLUDE_DIR + SDL2 headers path. + + SDL2_LIBRARY + SDL2 Library (.dll, .so, .a, etc) path. + + SDL2MAIN_LIBRAY + SDL2main Library (.a) path. + + SDL2_BUILDING_LIBRARY + This flag is useful only when linking to SDL2_LIBRARIES insead of + SDL2::Main. It is required only when building a library that links to + SDL2_LIBRARIES, because only applications need main() (No need to also + link to SDL2main). + If this flag is defined, then no SDL2main will be added to SDL2_LIBRARIES + and no SDL2::Main target will be created. + + +Don't forget to include SDLmain.h and SDLmain.m in your project for the +OS X framework based version. (Other versions link to -lSDL2main which +this module will try to find on your behalf.) Also for OS X, this +module will automatically add the -framework Cocoa on your behalf. + + +Additional Note: If you see an empty SDL2_LIBRARY in your project +configuration, it means CMake did not find your SDL2 library +(SDL2.dll, libsdl2.so, SDL2.framework, etc). Set SDL2_LIBRARY to point +to your SDL2 library, and configure again. Similarly, if you see an +empty SDL2MAIN_LIBRARY, you should set this value as appropriate. These +values are used to generate the final SDL2_LIBRARIES variable and the +SDL2::Core and SDL2::Main targets, but when these values are unset, +SDL2_LIBRARIES, SDL2::Core and SDL2::Main does not get created. + + +$SDL2DIR is an environment variable that would correspond to the +./configure --prefix=$SDL2DIR used in building SDL2. l.e.galup 9-20-02 + + + +Created by Amine Ben Hassouna: + Adapt FindSDL.cmake to SDL2 (FindSDL2.cmake). + Add cache variables for more flexibility: + SDL2_PATH, SDL2_NO_DEFAULT_PATH (for details, see doc above). + Mark 'Threads' as a required dependency for non-OSX systems. + Modernize the FindSDL2.cmake module by creating specific targets: + SDL2::Core and SDL2::Main (for details, see doc above). + + +Original FindSDL.cmake module: + Modified by Eric Wing. Added code to assist with automated building + by using environmental variables and providing a more + controlled/consistent search behavior. Added new modifications to + recognize OS X frameworks and additional Unix paths (FreeBSD, etc). + Also corrected the header search path to follow "proper" SDL + guidelines. Added a search for SDLmain which is needed by some + platforms. Added a search for threads which is needed by some + platforms. Added needed compile switches for MinGW. + +On OSX, this will prefer the Framework version (if found) over others. +People will have to manually change the cache value of SDL2_LIBRARY to +override this selection or set the SDL2_PATH variable or the CMake +environment CMAKE_INCLUDE_PATH to modify the search paths. + +Note that the header path has changed from SDL/SDL.h to just SDL.h +This needed to change because "proper" SDL convention is #include +"SDL.h", not . This is done for portability reasons +because not all systems place things in SDL/ (see FreeBSD). +#]=======================================================================] + +# Define options for searching SDL2 Library in a custom path + +set(SDL2_PATH "" CACHE STRING "Custom SDL2 Library path") + +set(_SDL2_NO_DEFAULT_PATH OFF) +if(SDL2_PATH) + set(_SDL2_NO_DEFAULT_PATH ON) +endif() + +set(SDL2_NO_DEFAULT_PATH ${_SDL2_NO_DEFAULT_PATH} + CACHE BOOL "Disable search SDL2 Library in default path") +unset(_SDL2_NO_DEFAULT_PATH) + +set(SDL2_NO_DEFAULT_PATH_CMD) +if(SDL2_NO_DEFAULT_PATH) + set(SDL2_NO_DEFAULT_PATH_CMD NO_DEFAULT_PATH) +endif() + +# Search for the SDL2 include directory +find_path(SDL2_INCLUDE_DIR SDL.h + HINTS + ENV SDL2DIR + ${SDL2_NO_DEFAULT_PATH_CMD} + PATH_SUFFIXES SDL2 + # path suffixes to search inside ENV{SDL2DIR} + include/SDL2 include + PATHS ${SDL2_PATH} + DOC "Where the SDL2 headers can be found" +) + +set(SDL2_INCLUDE_DIRS "${SDL2_INCLUDE_DIR}") + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(VC_LIB_PATH_SUFFIX lib/x64) +else() + set(VC_LIB_PATH_SUFFIX lib/x86) +endif() + +# SDL-2.0 is the name used by FreeBSD ports... +# don't confuse it for the version number. +find_library(SDL2_LIBRARY + NAMES SDL2 SDL-2.0 + HINTS + ENV SDL2DIR + ${SDL2_NO_DEFAULT_PATH_CMD} + PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX} + PATHS ${SDL2_PATH} + DOC "Where the SDL2 Library can be found" +) + +set(SDL2_LIBRARIES "${SDL2_LIBRARY}") + +if(NOT SDL2_BUILDING_LIBRARY) + if(NOT SDL2_INCLUDE_DIR MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + + if(SDL2_PATH) + set(SDL2MAIN_LIBRARY_PATHS "${SDL2_PATH}") + endif() + + if(NOT SDL2_NO_DEFAULT_PATH) + set(SDL2MAIN_LIBRARY_PATHS + /sw + /opt/local + /opt/csw + /opt + "${SDL2MAIN_LIBRARY_PATHS}" + ) + endif() + + find_library(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + ENV SDL2DIR + ${SDL2_NO_DEFAULT_PATH_CMD} + PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX} + PATHS ${SDL2MAIN_LIBRARY_PATHS} + DOC "Where the SDL2main library can be found" + ) + unset(SDL2MAIN_LIBRARY_PATHS) + endif() +endif() + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +if(NOT APPLE) + find_package(Threads QUIET) + if(NOT CMAKE_THREAD_LIBS_INIT) + set(SDL2_THREADS_NOT_FOUND "Could NOT find Threads (Threads is required by SDL2).") + if(SDL2_FIND_REQUIRED) + message(FATAL_ERROR ${SDL2_THREADS_NOT_FOUND}) + else() + if(NOT SDL2_FIND_QUIETLY) + message(STATUS ${SDL2_THREADS_NOT_FOUND}) + endif() + return() + endif() + unset(SDL2_THREADS_NOT_FOUND) + endif() +endif() + +# MinGW needs an additional link flag, -mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -mwindows +if(MINGW) + set(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "link flags for MinGW") +endif() + +if(SDL2_LIBRARY) + # For SDL2main + if(SDL2MAIN_LIBRARY AND NOT SDL2_BUILDING_LIBRARY) + list(FIND SDL2_LIBRARIES "${SDL2MAIN_LIBRARY}" _SDL2_MAIN_INDEX) + if(_SDL2_MAIN_INDEX EQUAL -1) + set(SDL2_LIBRARIES "${SDL2MAIN_LIBRARY}" ${SDL2_LIBRARIES}) + endif() + unset(_SDL2_MAIN_INDEX) + endif() + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + if(APPLE) + set(SDL2_LIBRARIES ${SDL2_LIBRARIES} "-framework Cocoa") + endif() + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + if(NOT APPLE) + set(SDL2_LIBRARIES ${SDL2_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) + endif() + + # For MinGW library + if(MINGW) + set(SDL2_LIBRARIES ${MINGW32_LIBRARY} ${SDL2_LIBRARIES}) + endif() + +endif() + +# Read SDL2 version +if(SDL2_INCLUDE_DIR AND EXISTS "${SDL2_INCLUDE_DIR}/SDL_version.h") + file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$") + file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$") + file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$") + string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MAJOR "${SDL2_VERSION_MAJOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MINOR "${SDL2_VERSION_MINOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_PATCH "${SDL2_VERSION_PATCH_LINE}") + set(SDL2_VERSION_STRING ${SDL2_VERSION_MAJOR}.${SDL2_VERSION_MINOR}.${SDL2_VERSION_PATCH}) + unset(SDL2_VERSION_MAJOR_LINE) + unset(SDL2_VERSION_MINOR_LINE) + unset(SDL2_VERSION_PATCH_LINE) + unset(SDL2_VERSION_MAJOR) + unset(SDL2_VERSION_MINOR) + unset(SDL2_VERSION_PATCH) +endif() + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 + REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR + VERSION_VAR SDL2_VERSION_STRING) + +if(SDL2MAIN_LIBRARY) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2main + REQUIRED_VARS SDL2MAIN_LIBRARY SDL2_INCLUDE_DIR + VERSION_VAR SDL2_VERSION_STRING) +endif() + + +mark_as_advanced(SDL2_PATH + SDL2_NO_DEFAULT_PATH + SDL2_LIBRARY + SDL2MAIN_LIBRARY + SDL2_INCLUDE_DIR + SDL2_BUILDING_LIBRARY) + + +# SDL2:: targets (SDL2::Core and SDL2::Main) +if(SDL2_FOUND) + + # SDL2::Core target + if(SDL2_LIBRARY AND NOT TARGET SDL2::Core) + add_library(SDL2::Core UNKNOWN IMPORTED) + set_target_properties(SDL2::Core PROPERTIES + IMPORTED_LOCATION "${SDL2_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}") + + if(APPLE) + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # For more details, please see above. + else() + # For threads, as mentioned Apple doesn't need this. + # For more details, please see above. + set_property(TARGET SDL2::Core APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Threads::Threads) + endif() + endif() + + # SDL2::Main target + # Applications should link to SDL2::Main instead of SDL2::Core + # For more details, please see above. + if(NOT SDL2_BUILDING_LIBRARY AND NOT TARGET SDL2::Main) + + if(SDL2_INCLUDE_DIR MATCHES ".framework" OR NOT SDL2MAIN_LIBRARY) + add_library(SDL2::Main INTERFACE IMPORTED) + set_property(TARGET SDL2::Main PROPERTY + INTERFACE_LINK_LIBRARIES SDL2::Core) + elseif(SDL2MAIN_LIBRARY) + # MinGW requires that the mingw32 library is specified before the + # libSDL2main.a static library when linking. + # The SDL2::MainInternal target is used internally to make sure that + # CMake respects this condition. + add_library(SDL2::MainInternal UNKNOWN IMPORTED) + set_property(TARGET SDL2::MainInternal PROPERTY + IMPORTED_LOCATION "${SDL2MAIN_LIBRARY}") + set_property(TARGET SDL2::MainInternal PROPERTY + INTERFACE_LINK_LIBRARIES SDL2::Core) + + add_library(SDL2::Main INTERFACE IMPORTED) + + if(MINGW) + # MinGW needs an additional link flag '-mwindows' and link to mingw32 + set_property(TARGET SDL2::Main PROPERTY + INTERFACE_LINK_LIBRARIES "mingw32" "-mwindows") + endif() + + set_property(TARGET SDL2::Main APPEND PROPERTY + INTERFACE_LINK_LIBRARIES SDL2::MainInternal) + endif() + + endif() +endif() diff --git a/src/nostalgia/CMakeLists.txt b/src/nostalgia/CMakeLists.txt index 4111e6cd..708e6e23 100644 --- a/src/nostalgia/CMakeLists.txt +++ b/src/nostalgia/CMakeLists.txt @@ -6,6 +6,10 @@ if(NOSTALGIA_BUILD_STUDIO) set(CMAKE_AUTOMOC ON) endif() +if(NOSTALGIA_BUILD_TYPE STREQUAL "Native") + find_package(SDL2 REQUIRED) +endif() + #project packages add_subdirectory(core) diff --git a/src/nostalgia/core/CMakeLists.txt b/src/nostalgia/core/CMakeLists.txt index 1a753972..a584eabb 100644 --- a/src/nostalgia/core/CMakeLists.txt +++ b/src/nostalgia/core/CMakeLists.txt @@ -13,14 +13,14 @@ elseif(NOSTALGIA_BUILD_STUDIO) set( CPP - qt/gfx.cpp + #qt/gfx.cpp userland/media.cpp userland/mem.cpp ) else() set( CPP - qt/gfx.cpp # does not currently use any Qt stuff, but will need to replace with SDL version + #qt/gfx.cpp # does not currently use any Qt stuff, but will need to replace with SDL version userland/media.cpp userland/mem.cpp ) @@ -32,12 +32,21 @@ add_library( core.cpp ) +target_link_libraries( + NostalgiaCore PUBLIC + NostalgiaCommon +) + +if(NOSTALGIA_BUILD_TYPE STREQUAL "Native") + add_subdirectory(sdl) +endif() if(NOSTALGIA_BUILD_STUDIO) add_subdirectory(studio) endif() install( FILES + consts.hpp core.hpp gfx.hpp media.hpp diff --git a/src/nostalgia/core/consts.hpp b/src/nostalgia/core/consts.hpp new file mode 100644 index 00000000..d8de8e78 --- /dev/null +++ b/src/nostalgia/core/consts.hpp @@ -0,0 +1,9 @@ + +#pragma once + +namespace nostalgia::core { + +constexpr auto FileExt_ng = ".ng"; +constexpr auto FileExt_npal = ".npal"; + +} diff --git a/src/nostalgia/core/core.hpp b/src/nostalgia/core/core.hpp index 6caa797c..e6fd94ae 100644 --- a/src/nostalgia/core/core.hpp +++ b/src/nostalgia/core/core.hpp @@ -10,6 +10,7 @@ #include +#include "consts.hpp" #include "gfx.hpp" #include "media.hpp" #include "types.hpp" @@ -18,4 +19,6 @@ namespace nostalgia::core { ox::Error init(Context *ctx); +ox::Error run(); + } diff --git a/src/nostalgia/core/gba/gba.hpp b/src/nostalgia/core/gba/gba.hpp index 35390c1c..11728843 100644 --- a/src/nostalgia/core/gba/gba.hpp +++ b/src/nostalgia/core/gba/gba.hpp @@ -16,9 +16,9 @@ typedef struct { uint32_t data[8]; } __attribute__((aligned(4))) Tile, Tile4; // d-tile: double-sized tile (8bpp) typedef struct { uint32_t data[16]; } __attribute__((aligned(4))) Tile8; // tile block: 32x16 tiles, 16x16 d-tiles -typedef uint16_t Palette[256]; -typedef Tile CharBlock[512]; -typedef Tile8 CharBlock8[256]; +using Palette = uint16_t[256]; +using CharBlock = Tile[512]; +using CharBlock8 = Tile8[256]; struct __attribute__((packed)) GbaImageDataHeader { uint8_t bpp = 0; @@ -27,6 +27,7 @@ struct __attribute__((packed)) GbaImageDataHeader { struct __attribute__((packed)) GbaImageData { GbaImageDataHeader header; + uint8_t colors = 0; // colors in the palette Palette __attribute__((packed)) pal = {}; uint8_t tiles[1]; }; diff --git a/src/nostalgia/core/gba/gfx.cpp b/src/nostalgia/core/gba/gfx.cpp index 104b1988..f59e83a9 100644 --- a/src/nostalgia/core/gba/gfx.cpp +++ b/src/nostalgia/core/gba/gfx.cpp @@ -204,7 +204,7 @@ ox::Error initConsole(Context*) { return err; } -ox::Error loadTileSheet(Context*, InodeId_t inode) { +ox::Error loadTileSheet(Context*, ox::FileAddress inode) { ox::Error err(0); const auto PaletteStart = sizeof(GbaImageDataHeader); GbaImageDataHeader imgData; @@ -217,15 +217,15 @@ ox::Error loadTileSheet(Context*, InodeId_t inode) { // load palette err |= fs.read(inode, PaletteStart, - 512, (uint16_t*) &MEM_PALLETE_BG[0], nullptr); + 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); + 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); + sizeof(Tile8) * imgData.tileCount, (uint16_t*) &TILE8_ADDR[0][1], nullptr); } else { err = OxError(1); } diff --git a/src/nostalgia/core/gfx.hpp b/src/nostalgia/core/gfx.hpp index bc5a5dcd..5d1c7c09 100644 --- a/src/nostalgia/core/gfx.hpp +++ b/src/nostalgia/core/gfx.hpp @@ -15,11 +15,43 @@ namespace nostalgia::core { +using Color = uint16_t; + +struct NostalgiaPalette { + static constexpr auto Fields = 1; + ox::Vector colors; +}; + +struct NostalgiaGraphic { + static constexpr auto Fields = 4; + uint8_t bpp = 0; + ox::FileAddress defaultPalette; + ox::Vector pal; + ox::Vector tiles; +}; + +template +ox::Error modelWrite(T *io, NostalgiaGraphic *ng) { + io->setTypeInfo("nostalgia::core::NostalgiaGraphic", NostalgiaGraphic::Fields); + oxReturnError(io->field("bpp", &ng->bpp)); + oxReturnError(io->field("defaultPalette", &ng->defaultPalette)); + oxReturnError(io->field("pal", &ng->pal)); + oxReturnError(io->field("tiles", &ng->tiles)); + return OxError(0); +} + +template +ox::Error modelWrite(T *io, NostalgiaPalette *pal) { + io->setTypeInfo("nostalgia::core::NostalgiaPalette", NostalgiaPalette::Fields); + oxReturnError(io->field("colors", &pal->colors)); + return OxError(0); +} + ox::Error initGfx(Context *ctx); ox::Error initConsole(Context *ctx); -ox::Error loadTileSheet(Context *ctx, InodeId_t inode); +ox::Error loadTileSheet(Context *ctx, ox::FileAddress file); void puts(Context *ctx, int loc, const char *str); diff --git a/src/nostalgia/core/qt/CMakeLists.txt b/src/nostalgia/core/qt/CMakeLists.txt new file mode 100644 index 00000000..b622c461 --- /dev/null +++ b/src/nostalgia/core/qt/CMakeLists.txt @@ -0,0 +1,18 @@ +add_library( + NostalgiaCore-Qt SHARED + gfx.cpp +) + +target_link_libraries( + NostalgiaCore-Qt PUBLIC + NostalgiaStudio + OxFS + OxStd +) + +install( + TARGETS + NostalgiaCore-Qt + LIBRARY DESTINATION + ${NOSTALGIA_DIST_PLUGIN} +) diff --git a/src/nostalgia/core/sdl/CMakeLists.txt b/src/nostalgia/core/sdl/CMakeLists.txt new file mode 100644 index 00000000..175c635e --- /dev/null +++ b/src/nostalgia/core/sdl/CMakeLists.txt @@ -0,0 +1,19 @@ +add_library( + NostalgiaCore-SDL + core.cpp + gfx.cpp +) + +target_link_libraries( + NostalgiaCore-SDL PUBLIC + SDL2::Main + OxFS + OxStd +) + +install( + TARGETS + NostalgiaCore-SDL + DESTINATION + ${NOSTALGIA_DIST_PLUGIN} +) diff --git a/src/nostalgia/core/sdl/core.cpp b/src/nostalgia/core/sdl/core.cpp new file mode 100644 index 00000000..ccbe48a6 --- /dev/null +++ b/src/nostalgia/core/sdl/core.cpp @@ -0,0 +1,36 @@ +/* + * 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/. + */ + +#include + +#include + +namespace nostalgia::core { + +ox::Error run() { + for (auto running = true; running;) { + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_q) { + running = false; + } + break; + case SDL_QUIT: { + running = false; + break; + } + } + } + SDL_Delay(1); + } + return OxError(0); +} + +} diff --git a/src/nostalgia/core/sdl/gfx.cpp b/src/nostalgia/core/sdl/gfx.cpp new file mode 100644 index 00000000..1650b565 --- /dev/null +++ b/src/nostalgia/core/sdl/gfx.cpp @@ -0,0 +1,36 @@ +/* + * 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/. + */ + +#include + +#include "../gfx.hpp" + +namespace nostalgia::core { + +static SDL_Window *window = nullptr; + +ox::Error initGfx(Context*) { + window = SDL_CreateWindow("nostalgia", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1024, 768, SDL_WINDOW_SHOWN); + return OxError(window == nullptr); +} + +ox::Error initConsole(Context*) { + return OxError(1); +} + +ox::Error loadTileSheet(Context*, ox::FileAddress) { + return OxError(1); +} + +void puts(Context*, int, const char*) { +} + +void setTile(Context*, int, int, int, uint8_t) { +} + +} diff --git a/src/nostalgia/core/studio/CMakeLists.txt b/src/nostalgia/core/studio/CMakeLists.txt index 09bee3cc..cc233047 100644 --- a/src/nostalgia/core/studio/CMakeLists.txt +++ b/src/nostalgia/core/studio/CMakeLists.txt @@ -3,6 +3,7 @@ if(NOSTALGIA_BUILD_TYPE STREQUAL "Native") add_library( NostalgiaCore-Studio SHARED import_tilesheet_wizard.cpp + new_tilesheet_wizard.cpp plugin.cpp ) endif() @@ -12,6 +13,7 @@ target_link_libraries( Qt5::Core Qt5::Widgets NostalgiaStudio + NostalgiaPack OxFS OxStd ) diff --git a/src/nostalgia/core/studio/import_tilesheet_wizard.cpp b/src/nostalgia/core/studio/import_tilesheet_wizard.cpp index e4ade551..d448b9f1 100644 --- a/src/nostalgia/core/studio/import_tilesheet_wizard.cpp +++ b/src/nostalgia/core/studio/import_tilesheet_wizard.cpp @@ -7,13 +7,21 @@ */ #include +#include #include +#include +#include + #include "import_tilesheet_wizard.hpp" namespace nostalgia::core { -ImportTilesheetWizardPage::ImportTilesheetWizardPage(const studio::Context *ctx) { +static const auto PaletteOption_Bundle = QObject::tr("Bundle"); +static const auto PaletteOption_New = QObject::tr("New"); +static const auto PaletteOptions = QStringList{PaletteOption_Bundle, PaletteOption_New}; + +ImportTilesheetWizardMainPage::ImportTilesheetWizardMainPage(const studio::Context *ctx) { m_ctx = ctx; addLineEdit(tr("&Tile Sheet Name:"), QString(TileSheetName) + "*", "", [this](QString) { auto importPath = field(ImportPath).toString(); @@ -28,44 +36,52 @@ ImportTilesheetWizardPage::ImportTilesheetWizardPage(const studio::Context *ctx) auto fileTypes = "(*.png);;(*.bmp);;(*.jpg);;(*.jpeg)"; addPathBrowse(tr("Tile Sheet &Path:"), QString(ImportPath) + "*", "", QFileDialog::ExistingFile, fileTypes); - //addComboBox(tr("Bits Per Pixe&l:"), BPP, {tr("Auto"), "4", "8"}); + addLineEdit(tr("Til&es:"), QString(TileCount), ""); } -int ImportTilesheetWizardPage::accept() { - auto tilesheetName = field(TileSheetName).toString(); - auto importPath = field(ImportPath).toString(); - QFile importFile(importPath); - if (importFile.exists()) { - return importImage(importFile, field(TileSheetName).toString()); - } else { - return 1; - } -} +ImportTilesheetWizardPalettePage::ImportTilesheetWizardPalettePage(const studio::Context *ctx) { + m_ctx = ctx; + auto cb = addComboBox(tr("P&alette:"), Palette, PaletteOptions); + auto name = addLineEdit(tr("Palette &Name:"), PaletteName); + name->setDisabled(true); -int ImportTilesheetWizardPage::importImage(QFile &srcFile, QString tilesheetName) { - if (srcFile.exists()) { - srcFile.open(QIODevice::ReadOnly); - auto buff = srcFile.readAll(); - QImage srcImg; - if (srcImg.loadFromData(buff)) { - int err = 0; - // ensure image is PNG - QByteArray out; - QBuffer outBuffer(&out); - outBuffer.open(QIODevice::WriteOnly); - srcImg.save(&outBuffer, "PNG"); - // make sure tile sheet directory exists - m_ctx->project->mkdir(TileSheetDir); - // write image - err |= m_ctx->project->write(TileSheetDir + tilesheetName + ".png", reinterpret_cast(out.data()), out.size()); - err |= m_ctx->project->saveRomFs(); - return err; - } else { - return 1; + connect(cb, QOverload::of(&QComboBox::currentIndexChanged), [name](int idx) { + if (idx == 1) { + name->setDisabled(false); + } else { + name->setDisabled(true); + } } - } else { - return 2; + ); + cb->setCurrentIndex(0); +} + +int ImportTilesheetWizardPalettePage::accept() { + const auto tilesheetName = field(TileSheetName).toString(); + const auto importPath = field(ImportPath).toString(); + const auto tileCount = field(TileCount).toInt(); + const auto palette = field(Palette).toInt(); + const auto paletteName = field(PaletteName).toString(); + const auto outPath = TileSheetDir + tilesheetName + FileExt_ng; + if (!QFile(importPath).exists()) { + return OxError(1); } + auto ng = imgToNg(importPath, tileCount, 0); + if (!ng) { + return OxError(1); + } + if (palette != PaletteOptions.indexOf(PaletteOption_Bundle)) { + const auto outPath = PaletteDir + paletteName + FileExt_npal; + core::NostalgiaPalette pal; + pal.colors = std::move(ng->pal); + auto [buff, err] = toBuffer(&pal); + oxReturnError(err); + oxReturnError(m_ctx->project->write(outPath, buff.data(), buff.size())); + } + auto [buff, err] = toBuffer(ng.get()); + oxReturnError(err); + oxReturnError(m_ctx->project->write(outPath, buff.data(), buff.size())); + return m_ctx->project->saveRomFs(); } } diff --git a/src/nostalgia/core/studio/import_tilesheet_wizard.hpp b/src/nostalgia/core/studio/import_tilesheet_wizard.hpp index 5048b157..8f06d47d 100644 --- a/src/nostalgia/core/studio/import_tilesheet_wizard.hpp +++ b/src/nostalgia/core/studio/import_tilesheet_wizard.hpp @@ -12,21 +12,32 @@ namespace nostalgia::core { -class ImportTilesheetWizardPage: public studio::WizardFormPage { +constexpr auto TileSheetDir = "/TileSheets/"; +constexpr auto PaletteDir = "/Palettes/"; +constexpr auto TileSheetName = "tilesheetName"; +constexpr auto ImportPath = "importPath"; +constexpr auto Palette = "palette"; +constexpr auto PaletteName = "paletteName"; +constexpr auto TileCount = "tileCount"; + +class ImportTilesheetWizardMainPage: public studio::WizardFormPage { private: - static constexpr auto TileSheetDir = "/TileSheets/"; - static constexpr auto TileSheetName = "projectName"; - static constexpr auto ImportPath = "projectPath"; //static constexpr auto BPP = "bpp"; const studio::Context *m_ctx = nullptr; public: - ImportTilesheetWizardPage(const studio::Context *args); + ImportTilesheetWizardMainPage(const studio::Context *args); +}; + +class ImportTilesheetWizardPalettePage: public studio::WizardFormPage { + private: + //static constexpr auto BPP = "bpp"; + const studio::Context *m_ctx = nullptr; + + public: + ImportTilesheetWizardPalettePage(const studio::Context *args); int accept(); - - private: - int importImage(QFile &srcFile, QString dest); }; } diff --git a/src/nostalgia/core/studio/new_tilesheet_wizard.cpp b/src/nostalgia/core/studio/new_tilesheet_wizard.cpp new file mode 100644 index 00000000..a361c67a --- /dev/null +++ b/src/nostalgia/core/studio/new_tilesheet_wizard.cpp @@ -0,0 +1,29 @@ +/* + * 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/. + */ + +#include +#include + +#include "new_tilesheet_wizard.hpp" + +namespace nostalgia::core { + +NewTilesheetWizardPage::NewTilesheetWizardPage(const studio::Context *ctx) { + m_ctx = ctx; + addLineEdit(tr("&Tile Sheet Name:"), QString(TileSheetName) + "*", "", [](QString) { + return 0; + } + ); +} + +int NewTilesheetWizardPage::accept() { + auto tilesheetName = field(TileSheetName).toString(); + return 0; +} + +} diff --git a/src/nostalgia/core/studio/new_tilesheet_wizard.hpp b/src/nostalgia/core/studio/new_tilesheet_wizard.hpp new file mode 100644 index 00000000..c3a0c21d --- /dev/null +++ b/src/nostalgia/core/studio/new_tilesheet_wizard.hpp @@ -0,0 +1,29 @@ +/* + * 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 + +#include + +namespace nostalgia::core { + +class NewTilesheetWizardPage: public studio::WizardFormPage { + private: + static constexpr auto TileSheetDir = "/TileSheets/"; + static constexpr auto TileSheetName = "projectName"; + const studio::Context *m_ctx = nullptr; + + public: + NewTilesheetWizardPage(const studio::Context *args); + + int accept(); + + private: +}; + +} diff --git a/src/nostalgia/core/studio/plugin.cpp b/src/nostalgia/core/studio/plugin.cpp index 3593d775..ca9f88ec 100644 --- a/src/nostalgia/core/studio/plugin.cpp +++ b/src/nostalgia/core/studio/plugin.cpp @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "new_tilesheet_wizard.hpp" #include "import_tilesheet_wizard.hpp" #include "plugin.hpp" @@ -17,13 +18,27 @@ namespace nostalgia::core { Plugin::Plugin() { } -QVector Plugin::importWizards(const studio::Context *args) { +QVector Plugin::newWizards(const Context *ctx) { return { { tr("Tile Sheet"), - [args]() { + [ctx]() { QVector pgs; - pgs.push_back(new ImportTilesheetWizardPage(args)); + pgs.push_back(new NewTilesheetWizardPage(ctx)); + return pgs; + } + } + }; +} + +QVector Plugin::importWizards(const studio::Context *ctx) { + return { + { + tr("Tile Sheet"), + [ctx]() { + QVector pgs; + pgs.push_back(new ImportTilesheetWizardMainPage(ctx)); + pgs.push_back(new ImportTilesheetWizardPalettePage(ctx)); return pgs; } } diff --git a/src/nostalgia/core/studio/plugin.hpp b/src/nostalgia/core/studio/plugin.hpp index e04c8983..8d3db8e2 100644 --- a/src/nostalgia/core/studio/plugin.hpp +++ b/src/nostalgia/core/studio/plugin.hpp @@ -22,6 +22,8 @@ class Plugin: public QObject, studio::Plugin { public: Plugin(); + QVector newWizards(const studio::Context *ctx) override; + QVector importWizards(const studio::Context *args) override; }; diff --git a/src/nostalgia/player/CMakeLists.txt b/src/nostalgia/player/CMakeLists.txt index bcc4f370..f6f1ab3f 100644 --- a/src/nostalgia/player/CMakeLists.txt +++ b/src/nostalgia/player/CMakeLists.txt @@ -6,11 +6,13 @@ if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA") main.cpp startup.s ) + set(NOSTALGIA_PLAYER_DEPS "") else() add_executable( nostalgia main.cpp ) + set(NOSTALGIA_PLAYER_DEPS "NostalgiaCore-SDL") endif() if(COMMAND OBJCOPY_FILE) @@ -27,11 +29,8 @@ endif() target_link_libraries( nostalgia NostalgiaWorld - NostalgiaCommon NostalgiaCore - OxFS - OxStd - OxMetalClaw + ${NOSTALGIA_PLAYER_DEPS} ) add_custom_target("nostalgia.bin") diff --git a/src/nostalgia/player/main.cpp b/src/nostalgia/player/main.cpp index e933200a..dc10ff1d 100644 --- a/src/nostalgia/player/main.cpp +++ b/src/nostalgia/player/main.cpp @@ -13,28 +13,27 @@ using namespace nostalgia::common; using namespace nostalgia::core; using namespace nostalgia::world; -int run() { - while(1); - ox::FileSystem32 fs(ox::FileStore32(loadRom(), 32 * ox::units::MB)); +int run(ox::FileSystem *fs) { Context ctx; init(&ctx); - ctx.rom = &fs; - //Zone zone(&ctx, Bounds{0, 0, 40, 40}, 102); - //zone.draw(&ctx); - while (1); + ctx.rom = fs; + Zone zone(&ctx, Bounds{0, 0, 40, 40}, "/TileSheets/GeneralWorld"); + zone.draw(&ctx); + run(); return 0; } #ifndef OX_USE_STDLIB extern "C" void _start() { - run(); + ox::FileSystem32 fs(ox::FileStore32(loadRom(), 32 * ox::units::MB)); + run(&fs); } #else int main() { - return run(); + return run(nullptr); } #endif diff --git a/src/nostalgia/player/startup.s b/src/nostalgia/player/startup.s new file mode 100644 index 00000000..f26cfb3c --- /dev/null +++ b/src/nostalgia/player/startup.s @@ -0,0 +1,9 @@ + +_entry: + + +reset: + @ disable interrupts + @ cpsid if + +@ vim:ft=arm diff --git a/src/nostalgia/studio/lib/wizard.cpp b/src/nostalgia/studio/lib/wizard.cpp index 9f45c759..51ab4146 100644 --- a/src/nostalgia/studio/lib/wizard.cpp +++ b/src/nostalgia/studio/lib/wizard.cpp @@ -169,7 +169,7 @@ bool WizardFormPage::validatePage() { return retval; } -void WizardFormPage::addComboBox(QString displayName, QString fieldName, QVector options) { +QComboBox *WizardFormPage::addComboBox(QString displayName, QString fieldName, QStringList options) { auto lbl = new QLabel(displayName, this); auto cb = new QComboBox(this); lbl->setBuddy(cb); @@ -199,9 +199,11 @@ void WizardFormPage::addComboBox(QString displayName, QString fieldName, QVector ); m_currentLine++; + + return cb; } -void WizardFormPage::addLineEdit(QString displayName, QString fieldName, QString defaultVal, function validator) { +QLineEdit *WizardFormPage::addLineEdit(QString displayName, QString fieldName, QString defaultVal, function validator) { auto lbl = new QLabel(displayName, this); auto le = new QLineEdit(this); lbl->setBuddy(le); @@ -229,6 +231,7 @@ void WizardFormPage::addLineEdit(QString displayName, QString fieldName, QString ); m_currentLine++; + return le; } void WizardFormPage::addPathBrowse(QString displayName, QString fieldName, QString defaultVal, diff --git a/src/nostalgia/studio/lib/wizard.hpp b/src/nostalgia/studio/lib/wizard.hpp index 261be315..de6f0e2b 100644 --- a/src/nostalgia/studio/lib/wizard.hpp +++ b/src/nostalgia/studio/lib/wizard.hpp @@ -10,10 +10,12 @@ #include +#include #include #include #include #include +#include #include #include #include @@ -86,9 +88,9 @@ class WizardFormPage: public QWizardPage { bool validatePage() override; - void addComboBox(QString displayName, QString fieldName, QVector options); + QComboBox *addComboBox(QString displayName, QString fieldName, QStringList options); - void addLineEdit(QString displayName, QString fieldName, + QLineEdit *addLineEdit(QString displayName, QString fieldName, QString defaultVal = "", std::function validator = [](QString) { return 0; }); diff --git a/src/nostalgia/tools/pack/imgconv.cpp b/src/nostalgia/tools/pack/imgconv.cpp index 12e5c1c0..86636bb7 100644 --- a/src/nostalgia/tools/pack/imgconv.cpp +++ b/src/nostalgia/tools/pack/imgconv.cpp @@ -56,28 +56,34 @@ namespace { return colors.size(); } -[[nodiscard]] std::vector pngToGba(QString argInPath, int argTiles, int argBpp) { - QImage src(argInPath); +[[nodiscard]] std::unique_ptr imgToNg(QString argSrc, int argTiles, int argBpp) { + constexpr auto TilePixels = 64; + QImage src(argSrc); if (src.isNull()) { return {}; } + const auto Pixels = argTiles ? argTiles * TilePixels : src.width() * src.height(); if (argTiles == 0) { - argTiles = (src.width() * src.height()) / 64; + argTiles = Pixels / 64; } + const auto Colors = countColors(src, argTiles); if (argBpp != 4 && argBpp != 8) { - argBpp = countColors(src, argTiles) > 16 ? 8 : 4; + argBpp = Colors > 16 ? 8 : 4; } QMap colors; - const auto imgDataBuffSize = sizeof(core::GbaImageData) + 1 + argTiles * 64; - std::vector imgDataBuff(imgDataBuffSize); - auto id = new (imgDataBuff.data()) core::GbaImageData; - id->header.bpp = argBpp; - id->header.tileCount = argTiles; - int colorId = 0; + auto ng = std::make_unique(); + ng->pal.resize(countColors(src, argTiles)); + if (argBpp == 4) { + ng->tiles.resize(Pixels / 2); + } else { + ng->tiles.resize(Pixels); + } + ng->bpp = argBpp; + int colorIdx = 0; // copy pixels as color ids for (int x = 0; x < src.width(); x++) { for (int y = 0; y < src.height(); y++) { @@ -86,18 +92,18 @@ namespace { const auto c = src.pixel(x, y); // assign color a color id for the palette if (!colors.contains(c)) { - colors[c] = colorId; - colorId++; + colors[c] = colorIdx; + colorIdx++; } // set pixel color if (argBpp == 4) { if (destI % 2) { // is odd number pixel - id->tiles[destI / 2] |= colors[c] << 4; + ng->tiles[destI / 2] |= colors[c] << 4; } else { - id->tiles[destI / 2] |= colors[c]; + ng->tiles[destI / 2] |= colors[c]; } } else { - id->tiles[destI] = colors[c]; + ng->tiles[destI] = colors[c]; } } } @@ -106,10 +112,10 @@ namespace { // store colors in palette with the corresponding color id for (auto key : colors.keys()) { auto colorId = colors[key]; - id->pal[colorId] = toGbaColor(key); + ng->pal[colorId] = toGbaColor(key); } - return imgDataBuff; + return ng; } } diff --git a/src/nostalgia/tools/pack/imgconv.hpp b/src/nostalgia/tools/pack/imgconv.hpp index b84c227c..bbb11f37 100644 --- a/src/nostalgia/tools/pack/imgconv.hpp +++ b/src/nostalgia/tools/pack/imgconv.hpp @@ -11,8 +11,24 @@ #include #include +#include + +#include + namespace nostalgia { -[[nodiscard]] std::vector pngToGba(QString argInPath, int argTiles, int argBpp = -1); +template +[[nodiscard]] ox::ValErr> toBuffer(T *data, std::size_t buffSize = ox::units::MB) { + std::vector buff(buffSize); + std::size_t sz = 0; + oxReturnError(ox::writeMC(buff.data(), buff.size(), data, &sz)); + if (sz > buffSize) { + return OxError(1); + } + buff.resize(sz); + return buff; +} + +[[nodiscard]] std::unique_ptr imgToNg(QString argInPath, int argTiles, int argBpp = -1); } diff --git a/src/nostalgia/tools/pack/pack.cpp b/src/nostalgia/tools/pack/pack.cpp index 4aa9bcf4..ba673d20 100644 --- a/src/nostalgia/tools/pack/pack.cpp +++ b/src/nostalgia/tools/pack/pack.cpp @@ -27,12 +27,12 @@ namespace { * @return error * stub for now */ -[[nodiscard]] ox::Error pathToInode(std::vector*) { +[[nodiscard]] ox::Error pathToInode(std::vector*) { return OxError(0); } // stub for now -[[nodiscard]] ox::Error toMetalClaw(std::vector*) { +[[nodiscard]] ox::Error toMetalClaw(std::vector*) { return OxError(0); } @@ -50,7 +50,7 @@ namespace { // do transforms if (endsWith(path, ".claw")) { // load file - std::vector buff(stat.size); + std::vector buff(stat.size); oxReturnError(dest->read(path.c_str(), buff.data(), buff.size())); // do transformations oxReturnError(pathToInode(&buff)); @@ -63,8 +63,8 @@ namespace { }); } -[[nodiscard]] ox::Error verifyFile(ox::FileSystem32 *fs, const std::string &path, const std::vector &expected) noexcept { - std::vector buff(expected.size()); +[[nodiscard]] ox::Error verifyFile(ox::FileSystem32 *fs, const std::string &path, const std::vector &expected) noexcept { + std::vector buff(expected.size()); oxReturnError(fs->read(path.c_str(), buff.data(), buff.size())); return OxError(buff == expected ? 0 : 1); } @@ -81,15 +81,15 @@ namespace { oxReturnError(dest->mkdir(currentFile.c_str(), true)); oxReturnError(copy(src, dest, currentFile + '/')); } else { - std::vector buff; + std::vector buff; // do transforms - constexpr std::string_view PngExt = ".png"; - constexpr std::string_view GbagExt = ".ng"; - if (endsWith(currentFile, PngExt)) { + const std::string OldExt = path.substr(path.find_last_of('.')); + constexpr std::string_view NgExt = ".ng"; + if (OldExt != NgExt) { // load file from full path and transform const auto fullPath = src->basePath() + currentFile; - buff = pngToGba(fullPath.c_str(), 0, 0); - currentFile = currentFile.substr(0, currentFile.size() - PngExt.size()) + GbagExt.data(); + oxReturnError(toBuffer(imgToNg(fullPath.c_str(), 0, 0).get()).get(&buff)); + currentFile = currentFile.substr(0, currentFile.size() - OldExt.size()) + NgExt.data(); if (!buff.size()) { return OxError(1); } diff --git a/src/nostalgia/world/CMakeLists.txt b/src/nostalgia/world/CMakeLists.txt index 47d6fb15..fe3ba1eb 100644 --- a/src/nostalgia/world/CMakeLists.txt +++ b/src/nostalgia/world/CMakeLists.txt @@ -4,6 +4,12 @@ add_library( world.cpp ) +target_link_libraries( + NostalgiaWorld PUBLIC + NostalgiaCore + OxMetalClaw +) + #install(TARGETS NostalgiaCommon DESTINATION lib) install( FILES diff --git a/src/nostalgia/world/world.cpp b/src/nostalgia/world/world.cpp index 04f12e15..d278123f 100644 --- a/src/nostalgia/world/world.cpp +++ b/src/nostalgia/world/world.cpp @@ -13,7 +13,7 @@ namespace nostalgia::world { using namespace common; using namespace core; -Zone::Zone(Context *ctx, Bounds bnds, InodeId_t tileSheet) { +Zone::Zone(Context *ctx, Bounds bnds, ox::FileAddress tileSheet) { const auto size = bnds.width * bnds.height; m_tiles = new Tile[size]; m_bounds = bnds; diff --git a/src/nostalgia/world/world.hpp b/src/nostalgia/world/world.hpp index 598f91e2..0cdc7792 100644 --- a/src/nostalgia/world/world.hpp +++ b/src/nostalgia/world/world.hpp @@ -17,11 +17,10 @@ namespace nostalgia::world { struct Tile { - static constexpr auto Fields = 3; + static constexpr auto Fields = 2; uint8_t bgTile = 0; uint8_t type = 0; - void *occupant = nullptr; }; template @@ -48,7 +47,7 @@ struct Zone { Tile *m_tiles = nullptr; public: - Zone(core::Context *ctx, common::Bounds bnds, core::InodeId_t tileSheet); + Zone(core::Context *ctx, common::Bounds bnds, ox::FileAddress tileSheet); void draw(core::Context *ctx);