From 33cb9a66d477aa439473f95304bb1a0954da0d54 Mon Sep 17 00:00:00 2001 From: Fabrice de Gans Date: Fri, 15 Mar 2024 18:25:04 -0700 Subject: [PATCH] [Build] Move System.h and most of Util.h to core/ * Move System.h to core/base. * Move most of the functionality out of Util.h to core/base. * Fix corresponding headers. --- CMakeLists.txt | 13 +- src/Util.cpp | 501 --------------------- src/Util.h | 16 - src/Util_common.cpp | 43 +- src/Util_desktop.cpp | 58 +++ src/common/SoundDriver.h | 64 --- src/common/SoundSDL.h | 2 +- src/core/base/CMakeLists.txt | 10 +- src/core/base/file_util.cpp | 137 ------ src/core/base/file_util.h | 10 + src/core/base/file_util_common.cpp | 47 ++ src/core/base/file_util_desktop.cpp | 252 +++++++++++ src/core/base/file_util_libretro.cpp | 50 ++ src/core/base/image_util.cpp | 193 ++++++++ src/core/base/image_util.h | 13 + src/core/base/sound_driver.h | 48 ++ src/{System.h => core/base/system.h} | 108 +++-- src/filters/2xSaI.cpp | 2 +- src/filters/admame.cpp | 2 +- src/filters/bilinear.cpp | 2 +- src/filters/hq2x.cpp | 2 +- src/filters/interframe.cpp | 6 +- src/filters/interframe.hpp | 2 + src/filters/pixel.cpp | 2 +- src/filters/scanline.cpp | 2 +- src/filters/simpleFilter.cpp | 2 +- src/filters/xbrzfilter.cpp | 2 +- src/gb/GB.cpp | 9 +- src/gb/gbCheats.cpp | 14 +- src/gb/gbCheats.h | 2 +- src/gb/gbDis.cpp | 4 +- src/gb/gbGfx.cpp | 2 +- src/gb/gbMemory.cpp | 3 +- src/gb/gbPrinter.cpp | 9 +- src/gb/gbPrinter.h | 2 +- src/gb/gbSGB.cpp | 2 +- src/gb/gbSound.cpp | 2 +- src/gba/CheatSearch.h | 2 +- src/gba/Cheats.cpp | 11 +- src/gba/Cheats.h | 2 +- src/gba/GBA-arm.cpp | 16 - src/gba/GBA-thumb.cpp | 19 +- src/gba/GBA.cpp | 8 +- src/gba/GBA.h | 3 +- src/gba/GBAGfx.cpp | 6 +- src/gba/GBAinline.h | 2 +- src/gba/RTC.cpp | 12 +- src/gba/Sound.cpp | 3 +- src/gba/agbprint.cpp | 4 +- src/gba/agbprint.h | 2 + src/gba/armdis.cpp | 4 +- src/gba/debugger-expr-yacc.cpp | 2 - src/gba/debugger-expr.y | 2 - src/gba/elf.cpp | 1 + src/gba/elf.h | 3 + src/gba/gbafilter.h | 7 +- src/libretro/Makefile.common | 1 - src/libretro/SoundRetro.h | 2 +- src/libretro/UtilRetro.cpp | 61 --- src/libretro/libretro.cpp | 3 +- src/sdl/ConfigManager.h | 6 +- src/sdl/SDL.cpp | 2 +- src/sdl/debugger.cpp | 22 +- src/sdl/expr.cpp | 2 - src/sdl/expr.ypp | 2 +- src/sdl/exprNode.h | 2 + src/sdl/text.cpp | 2 +- src/wx/config/internal/option-internal.cpp | 2 +- src/wx/dsound.cpp | 5 +- src/wx/faudio.cpp | 4 +- src/wx/gfxviewers.cpp | 57 +++ src/wx/guiinit.cpp | 5 +- src/wx/openal.cpp | 2 +- src/wx/panel.cpp | 2 + src/wx/sys.cpp | 1 + src/wx/wxvbam.cpp | 2 +- src/wx/xaudio2.cpp | 4 +- third_party/include/stb/CMakeLists.txt | 9 + 78 files changed, 924 insertions(+), 1021 deletions(-) delete mode 100644 src/Util.cpp create mode 100644 src/Util_desktop.cpp delete mode 100644 src/common/SoundDriver.h delete mode 100644 src/core/base/file_util.cpp create mode 100644 src/core/base/file_util_desktop.cpp create mode 100644 src/core/base/image_util.cpp create mode 100644 src/core/base/image_util.h create mode 100644 src/core/base/sound_driver.h rename src/{System.h => core/base/system.h} (55%) delete mode 100644 src/libretro/UtilRetro.cpp create mode 100644 third_party/include/stb/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f19eb86..004b8539 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -385,14 +385,15 @@ if(ENABLE_NLS) endif() if(NOT TRANSLATIONS_ONLY) + add_subdirectory(third_party/include/stb) add_subdirectory(src/core/fex) add_subdirectory(src/core/base) endif() set( SRC_MAIN - src/Util.cpp src/Util_common.cpp + src/Util_desktop.cpp src/common/SoundSDL.cpp ) @@ -402,9 +403,7 @@ endif() set( HDR_MAIN - src/System.h src/Util.h - src/common/SoundDriver.h src/common/SoundSDL.h ) @@ -640,16 +639,9 @@ if(ENABLE_DEBUGGER) ) endif() -set( - HDR_STB_IMAGE - third_party/include/stb/stb_image.h - third_party/include/stb/stb_image_write.h -) - include_directories( ${ZLIB_INCLUDE_DIR} third_party/include - third_party/include/stb ) if(ENABLE_FFMPEG) @@ -675,7 +667,6 @@ if(NOT TRANSLATIONS_ONLY) ${HDR_FILTERS} ${SRC_DEBUGGER} ${HDR_DEBUGGER} - ${HDR_STB_IMAGE} ) target_include_directories(vbamcore PUBLIC ${SDL2_INCLUDE_DIRS}) endif() diff --git a/src/Util.cpp b/src/Util.cpp deleted file mode 100644 index 52098282..00000000 --- a/src/Util.cpp +++ /dev/null @@ -1,501 +0,0 @@ -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#else // _WIN32 -#include -#include -#endif // _WIN32 - -#include - - -#define STB_IMAGE_IMPLEMENTATION -extern "C" { -#include "stb_image.h" -} - -#define STBI_MSC_SECURE_CRT -#define STB_IMAGE_WRITE_IMPLEMENTATION -extern "C" { -#include "stb_image_write.h" -} - -#include "core/fex/fex.h" -#include "core/base/file_util.h" -#include "core/base/message.h" -#include "System.h" -#include "Util.h" -#include "gba/Globals.h" - -#ifndef _MSC_VER -#define _stricmp strcasecmp -#endif // ! _MSC_VER - -extern int systemColorDepth; -extern int systemRedShift; -extern int systemGreenShift; -extern int systemBlueShift; - -extern uint16_t systemColorMap16[0x10000]; -extern uint32_t systemColorMap32[0x10000]; - -#define MAX_CART_SIZE 0x8000000 // 128MB - -// Get user-specific config dir manually. -// apple: ~/Library/Application Support/ -// windows: %APPDATA%/ -// unix: ${XDG_CONFIG_HOME:-~/.config}/ -std::string get_xdg_user_config_home() -{ - std::string path; -#ifdef __APPLE__ - std::string home(getenv("HOME")); - path = home + "/Library/Application Support"; -#elif _WIN32 - char *app_data_env = getenv("LOCALAPPDATA"); - if (!app_data_env) app_data_env = getenv("APPDATA"); - std::string app_data(app_data_env); - path = app_data; -#else // Unix - char *xdg_var = getenv("XDG_CONFIG_HOME"); - if (!xdg_var || !*xdg_var) - { - std::string xdg_default(getenv("HOME")); - path = xdg_default + "/.config"; - } - else - { - path = xdg_var; - } -#endif - return path + FILE_SEP; -} - -// Get user-specific data dir manually. -// apple: ~/Library/Application Support/ -// windows: %APPDATA%/ -// unix: ${XDG_DATA_HOME:-~/.local/share}/ -std::string get_xdg_user_data_home() -{ - std::string path; -#ifdef __APPLE__ - std::string home(getenv("HOME")); - path = home + "/Library/Application Support"; -#elif _WIN32 - char *app_data_env = getenv("LOCALAPPDATA"); - if (!app_data_env) app_data_env = getenv("APPDATA"); - std::string app_data(app_data_env); - path = app_data; -#else // Unix - char *xdg_var = getenv("XDG_DATA_HOME"); - if (!xdg_var || !*xdg_var) - { - std::string xdg_default(getenv("HOME")); - path = xdg_default + "/.local/share"; - } - else - { - path = xdg_var; - } -#endif - return path + FILE_SEP; -} - -void utilReadScreenPixels(uint8_t *dest, int w, int h) -{ - uint8_t *b = dest; - int sizeX = w; - int sizeY = h; - switch (systemColorDepth) { - case 16: { - uint16_t *p = (uint16_t *)(g_pix + (w + 2) * 2); // skip first black line - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { - uint16_t v = *p++; - - *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R - *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G - *b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B - } - p++; // skip black pixel for filters - p++; // skip black pixel for filters - } - } break; - case 24: { - uint8_t *pixU8 = (uint8_t *)g_pix; - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { - if (systemRedShift < systemBlueShift) { - *b++ = *pixU8++; // R - *b++ = *pixU8++; // G - *b++ = *pixU8++; // B - } else { - uint8_t blue = *pixU8++; - uint8_t green = *pixU8++; - uint8_t red = *pixU8++; - - *b++ = red; - *b++ = green; - *b++ = blue; - } - } - } - } break; - case 32: { - uint32_t *pixU32 = (uint32_t *)(g_pix + 4 * (w + 1)); - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { - uint32_t v = *pixU32++; - *b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B - *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G - *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R - } - pixU32++; - } - } break; - } -} - -#define CHANNEL_NUM 3 // RGB - -bool utilWritePNGFile(const char *fileName, int w, int h, uint8_t *pix) -{ - uint8_t *writeBuffer = new uint8_t[w * h * CHANNEL_NUM]; - - uint8_t *b = writeBuffer; - - int sizeX = w; - int sizeY = h; - - switch (systemColorDepth) - { - case 16: { - uint16_t *p = (uint16_t *)(pix + (w + 2) * 2); // skip first black line - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { - uint16_t v = *p++; - - *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R - *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G - *b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B - } - p++; // skip black pixel for filters - p++; // skip black pixel for filters - } - } break; - case 24: { - uint8_t *pixU8 = (uint8_t *)pix; - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { - if (systemRedShift < systemBlueShift) { - *b++ = *pixU8++; // R - *b++ = *pixU8++; // G - *b++ = *pixU8++; // B - } else { - uint8_t blue = *pixU8++; - uint8_t green = *pixU8++; - uint8_t red = *pixU8++; - - *b++ = red; - *b++ = green; - *b++ = blue; - } - } - } - } break; - case 32: { - uint32_t *pixU32 = (uint32_t *)(pix + 4 * (w + 1)); - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { - uint32_t v = *pixU32++; - - *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R - *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G - *b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B - } - pixU32++; - } - } break; - } - - bool ret = (0 != stbi_write_png(fileName, w, h, CHANNEL_NUM, writeBuffer, w * CHANNEL_NUM)); - delete[] writeBuffer; - return ret; -} - -bool utilWriteBMPFile(const char *fileName, int w, int h, uint8_t *pix) -{ - uint8_t writeBuffer[512 * 3]; - - FILE *fp = fopen(fileName, "wb"); - - if (!fp) { - systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), fileName); - return false; - } - - struct { - uint8_t ident[2]; - uint8_t filesize[4]; - uint8_t reserved[4]; - uint8_t dataoffset[4]; - uint8_t headersize[4]; - uint8_t width[4]; - uint8_t height[4]; - uint8_t planes[2]; - uint8_t bitsperpixel[2]; - uint8_t compression[4]; - uint8_t datasize[4]; - uint8_t hres[4]; - uint8_t vres[4]; - uint8_t colors[4]; - uint8_t importantcolors[4]; - // uint8_t pad[2]; - } bmpheader; - memset(&bmpheader, 0, sizeof(bmpheader)); - - bmpheader.ident[0] = 'B'; - bmpheader.ident[1] = 'M'; - - uint32_t fsz = sizeof(bmpheader) + w * h * 3; - utilPutDword(bmpheader.filesize, fsz); - utilPutDword(bmpheader.dataoffset, 0x36); - utilPutDword(bmpheader.headersize, 0x28); - utilPutDword(bmpheader.width, w); - utilPutDword(bmpheader.height, h); - utilPutDword(bmpheader.planes, 1); - utilPutDword(bmpheader.bitsperpixel, 24); - utilPutDword(bmpheader.datasize, 3 * w * h); - - fwrite(&bmpheader, 1, sizeof(bmpheader), fp); - - uint8_t *b = writeBuffer; - - int sizeX = w; - int sizeY = h; - - switch (systemColorDepth) { - case 16: { - uint16_t *p = (uint16_t *)(pix + (w + 2) * (h)*2); // skip first black line - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { - uint16_t v = *p++; - - *b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B - *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G - *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R - } - p++; // skip black pixel for filters - p++; // skip black pixel for filters - p -= 2 * (w + 2); - fwrite(writeBuffer, 1, 3 * w, fp); - - b = writeBuffer; - } - } break; - case 24: { - uint8_t *pixU8 = (uint8_t *)pix + 3 * w * (h - 1); - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { - if (systemRedShift > systemBlueShift) { - *b++ = *pixU8++; // B - *b++ = *pixU8++; // G - *b++ = *pixU8++; // R - } else { - uint8_t red = *pixU8++; - uint8_t green = *pixU8++; - uint8_t blue = *pixU8++; - - *b++ = blue; - *b++ = green; - *b++ = red; - } - } - pixU8 -= 2 * 3 * w; - fwrite(writeBuffer, 1, 3 * w, fp); - - b = writeBuffer; - } - } break; - case 32: { - uint32_t *pixU32 = (uint32_t *)(pix + 4 * (w + 1) * (h)); - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { - uint32_t v = *pixU32++; - - *b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B - *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G - *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R - } - pixU32++; - pixU32 -= 2 * (w + 1); - - fwrite(writeBuffer, 1, 3 * w, fp); - - b = writeBuffer; - } - } break; - } - - fclose(fp); - - return true; -} - -bool utilIsGzipFile(const char *file) -{ - if (strlen(file) > 3) { - const char *p = strrchr(file, '.'); - - if (p != NULL) { - if (_stricmp(p, ".gz") == 0) - return true; - if (_stricmp(p, ".z") == 0) - return true; - } - } - - return false; -} - -// Opens and scans archive using accept(). Returns fex_t if found. -// If error or not found, displays message and returns NULL. -static fex_t *scan_arc(const char *file, bool (*accept)(const char *), char (&buffer)[2048]) -{ - fex_t *fe; - fex_err_t err = fex_open(&fe, file); - if (!fe) { - systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s: %s"), file, err); - return NULL; - } - - // Scan filenames - bool found = false; - while (!fex_done(fe)) { - strncpy(buffer, fex_name(fe), sizeof buffer); - buffer[sizeof buffer - 1] = '\0'; - - utilStripDoubleExtension(buffer, buffer); - - if (accept(buffer)) { - found = true; - break; - } - - err = fex_next(fe); - if (err) { - systemMessage(MSG_BAD_ZIP_FILE, - N_("Cannot read archive %s: %s"), - file, - err); - fex_close(fe); - return NULL; - } - } - - if (!found) { - systemMessage(MSG_NO_IMAGE_ON_ZIP, N_("No image found in file %s"), file); - fex_close(fe); - return NULL; - } - return fe; -} - -static bool utilIsImage(const char *file) -{ - return utilIsGBAImage(file) || utilIsGBImage(file); -} - -IMAGE_TYPE utilFindType(const char *file, char (&buffer)[2048]); - -IMAGE_TYPE utilFindType(const char *file) -{ - char buffer[2048]; - return utilFindType(file, buffer); -} - -IMAGE_TYPE utilFindType(const char *file, char (&buffer)[2048]) -{ - fex_t *fe = scan_arc(file, utilIsImage, buffer); - if (!fe) - return IMAGE_UNKNOWN; - fex_close(fe); - file = buffer; - return utilIsGBAImage(file) ? IMAGE_GBA : IMAGE_GB; -} - -static int utilGetSize(int size) -{ - int res = 1; - while (res < size) - res <<= 1; - return res; -} - -uint8_t *utilLoad(const char *file, bool (*accept)(const char *), uint8_t *data, int &size) -{ - // find image file - char buffer[2048]; - fex_t *fe = scan_arc(file, accept, buffer); - if (!fe) - return NULL; - - // Allocate space for image - fex_err_t err = fex_stat(fe); - int fileSize = fex_size(fe); - if (size == 0) - size = fileSize; - - if (size > MAX_CART_SIZE) - return NULL; - - uint8_t *image = data; - - if (image == NULL) { - // allocate buffer memory if none was passed to the function - image = (uint8_t *)malloc(utilGetSize(size)); - if (image == NULL) { - fex_close(fe); - systemMessage(MSG_OUT_OF_MEMORY, - N_("Failed to allocate memory for %s"), - "data"); - return NULL; - } - size = fileSize; - } - - // Read image - int read = fileSize <= size ? fileSize : size; // do not read beyond file - err = fex_read(fe, image, read); - fex_close(fe); - if (err) { - systemMessage(MSG_ERROR_READING_IMAGE, - N_("Error reading image from %s: %s"), - buffer, - err); - if (data == NULL) - free(image); - return NULL; - } - - size = fileSize; - - return image; -} - -void replaceAll(std::string &str, const std::string &from, const std::string &to) -{ - if (from.empty()) - return; - size_t start_pos = 0; - while ((start_pos = str.find(from, start_pos)) != std::string::npos) { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with - // 'yx' - } -} diff --git a/src/Util.h b/src/Util.h index 850d1aa1..72155148 100644 --- a/src/Util.h +++ b/src/Util.h @@ -1,7 +1,6 @@ #ifndef UTIL_H #define UTIL_H -#include #include #ifdef _WIN32 @@ -10,24 +9,9 @@ #define FILE_SEP '/' #endif -#define FREAD_UNCHECKED(A,B,C,D) (void)(fread(A,B,C,D) + 1) - -enum IMAGE_TYPE { IMAGE_UNKNOWN = -1, IMAGE_GBA = 0, IMAGE_GB = 1 }; - std::string get_xdg_user_config_home(); std::string get_xdg_user_data_home(); -void utilReadScreenPixels(uint8_t *dest, int w, int h); -#ifndef __LIBRETRO__ -bool utilWritePNGFile(const char *, int, int, uint8_t *); -bool utilWriteBMPFile(const char *, int, int, uint8_t *); -#endif -bool utilIsGBAImage(const char *); -bool utilIsGBImage(const char *); -IMAGE_TYPE utilFindType(const char *); -uint8_t *utilLoad(const char *, bool (*)(const char *), uint8_t *, int &); - -void utilPutDword(uint8_t *, uint32_t); void utilGBAFindSave(const int); void utilUpdateSystemColorMaps(bool lcd = false); diff --git a/src/Util_common.cpp b/src/Util_common.cpp index eda40701..44241c44 100644 --- a/src/Util_common.cpp +++ b/src/Util_common.cpp @@ -2,8 +2,8 @@ #include -#include "System.h" #include "core/base/port.h" +#include "core/base/system.h" #include "gba/Globals.h" #include "gba/RTC.h" #include "gba/gbafilter.h" @@ -12,47 +12,6 @@ #define strcasecmp _stricmp #endif // defined(_MSC_VER) -bool utilIsGBAImage(const char* file) { - coreOptions.cpuIsMultiBoot = false; - if (strlen(file) > 4) { - const char* p = strrchr(file, '.'); - - if (p != NULL) { - if ((strcasecmp(p, ".agb") == 0) || (strcasecmp(p, ".gba") == 0) || - (strcasecmp(p, ".bin") == 0) || (strcasecmp(p, ".elf") == 0)) - return true; - if (strcasecmp(p, ".mb") == 0) { - coreOptions.cpuIsMultiBoot = true; - return true; - } - } - } - - return false; -} - -bool utilIsGBImage(const char* file) { - if (strlen(file) > 4) { - const char* p = strrchr(file, '.'); - - if (p != NULL) { - if ((strcasecmp(p, ".dmg") == 0) || (strcasecmp(p, ".gb") == 0) || - (strcasecmp(p, ".gbc") == 0) || (strcasecmp(p, ".cgb") == 0) || - (strcasecmp(p, ".sgb") == 0)) - return true; - } - } - - return false; -} - -void utilPutDword(uint8_t* p, uint32_t value) { - *p++ = value & 255; - *p++ = (value >> 8) & 255; - *p++ = (value >> 16) & 255; - *p = (value >> 24) & 255; -} - void utilUpdateSystemColorMaps(bool lcd) { switch (systemColorDepth) { case 16: { diff --git a/src/Util_desktop.cpp b/src/Util_desktop.cpp new file mode 100644 index 00000000..19cc8d37 --- /dev/null +++ b/src/Util_desktop.cpp @@ -0,0 +1,58 @@ +#include "Util.h" + +#include + +// Get user-specific config dir manually. +// apple: ~/Library/Application Support/ +// windows: %APPDATA%/ +// unix: ${XDG_CONFIG_HOME:-~/.config}/ +std::string get_xdg_user_config_home() +{ + std::string path; +#ifdef __APPLE__ + std::string home(getenv("HOME")); + path = home + "/Library/Application Support"; +#elif _WIN32 + char *app_data_env = getenv("LOCALAPPDATA"); + if (!app_data_env) app_data_env = getenv("APPDATA"); + std::string app_data(app_data_env); + path = app_data; +#else // Unix + char *xdg_var = getenv("XDG_CONFIG_HOME"); + if (!xdg_var || !*xdg_var) { + std::string xdg_default(getenv("HOME")); + path = xdg_default + "/.config"; + } else { + path = xdg_var; + } +#endif + return path + FILE_SEP; +} + +// Get user-specific data dir manually. +// apple: ~/Library/Application Support/ +// windows: %APPDATA%/ +// unix: ${XDG_DATA_HOME:-~/.local/share}/ +std::string get_xdg_user_data_home() +{ + std::string path; +#ifdef __APPLE__ + std::string home(getenv("HOME")); + path = home + "/Library/Application Support"; +#elif _WIN32 + char *app_data_env = getenv("LOCALAPPDATA"); + if (!app_data_env) app_data_env = getenv("APPDATA"); + std::string app_data(app_data_env); + path = app_data; +#else // Unix + char *xdg_var = getenv("XDG_DATA_HOME"); + if (!xdg_var || !*xdg_var) { + std::string xdg_default(getenv("HOME")); + path = xdg_default + "/.local/share"; + } else { + path = xdg_var; + } +#endif + return path + FILE_SEP; +} + diff --git a/src/common/SoundDriver.h b/src/common/SoundDriver.h deleted file mode 100644 index c6d405bf..00000000 --- a/src/common/SoundDriver.h +++ /dev/null @@ -1,64 +0,0 @@ -// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. -// Copyright (C) 2015 VBA-M development team - -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2, or(at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -#ifndef __VBA_SOUND_DRIVER_H__ -#define __VBA_SOUND_DRIVER_H__ - -#include // for uint16_t - -/** - * Sound driver abstract interface for the core to use to output sound. - * Subclass this to implement a new sound driver. - */ -class SoundDriver -{ - public: - /** - * Destructor. Free the resources allocated by the sound driver. - */ - virtual ~SoundDriver(){}; - - /** - * Initialize the sound driver. - * @param sampleRate In Hertz - */ - virtual bool init(long sampleRate) = 0; - - /** - * Tell the driver that the sound stream has paused - */ - virtual void pause() = 0; - - /** - * Reset the sound driver - */ - virtual void reset() = 0; - - /** - * Tell the driver that the sound stream has resumed - */ - virtual void resume() = 0; - - /** - * Write length bytes of data from the finalWave buffer to the driver output buffer. - */ - virtual void write(uint16_t *finalWave, int length) = 0; - - virtual void setThrottle(unsigned short throttle) = 0; -}; - -#endif // __VBA_SOUND_DRIVER_H__ diff --git a/src/common/SoundSDL.h b/src/common/SoundSDL.h index 35189e86..14f8c872 100644 --- a/src/common/SoundSDL.h +++ b/src/common/SoundSDL.h @@ -21,7 +21,7 @@ #include #include "core/base/ringbuffer.h" -#include "SoundDriver.h" +#include "core/base/sound_driver.h" class SoundSDL : public SoundDriver { public: diff --git a/src/core/base/CMakeLists.txt b/src/core/base/CMakeLists.txt index e6fa2dae..3c841524 100644 --- a/src/core/base/CMakeLists.txt +++ b/src/core/base/CMakeLists.txt @@ -26,8 +26,9 @@ add_dependencies(vbam-core-base vbam-core-base-generated) target_sources(vbam-core-base PRIVATE - file_util.cpp file_util_common.cpp + file_util_desktop.cpp + image_util.cpp internal/file_util_internal.cpp internal/file_util_internal.h internal/memgzio.c @@ -38,18 +39,23 @@ target_sources(vbam-core-base PUBLIC array.h file_util.h + image_util.h message.h patch.h port.h ringbuffer.h sizes.h + sound_driver.h + system.h + version.h ) target_include_directories(vbam-core-base + PRIVATE ${STB_INCLUDE_DIR} PUBLIC ${ZLIB_INCLUDE_DIR} ) target_link_libraries(vbam-core-base - INTERFACE vbam-fex + INTERFACE vbam-fex stb-image PUBLIC ${ZLIB_LIBRARY} ) diff --git a/src/core/base/file_util.cpp b/src/core/base/file_util.cpp deleted file mode 100644 index b8e491f6..00000000 --- a/src/core/base/file_util.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include "file_util.h" - -#if defined(__LIBRETRO__) -#error "This file is only for non-libretro builds" -#endif - -#include - -#include "core/base/internal/file_util_internal.h" -#include "core/base/internal/memgzio.h" - -#if defined(_MSC_VER) -#define strcasecmp _stricmp -#endif // defined(_MSC_VER) - -namespace { - -bool utilIsGzipFile(const char* file) { - if (strlen(file) > 3) { - const char* p = strrchr(file, '.'); - - if (p != nullptr) { - if (strcasecmp(p, ".gz") == 0) - return true; - if (strcasecmp(p, ".z") == 0) - return true; - } - } - - return false; -} - -int(ZEXPORT *utilGzWriteFunc)(gzFile, const voidp, unsigned int) = nullptr; -int(ZEXPORT *utilGzReadFunc)(gzFile, voidp, unsigned int) = nullptr; -int(ZEXPORT *utilGzCloseFunc)(gzFile) = nullptr; -z_off_t(ZEXPORT *utilGzSeekFunc)(gzFile, z_off_t, int) = nullptr; - -} // namespace - -void utilStripDoubleExtension(const char* file, char* buffer) { - if (buffer != file) // allows conversion in place - strcpy(buffer, file); - - if (utilIsGzipFile(file)) { - char* p = strrchr(buffer, '.'); - - if (p) - *p = 0; - } -} - -gzFile utilAutoGzOpen(const char* file, const char* mode) { -#if defined(_WIN32) - - std::wstring wfile = core::internal::ToUTF16(file); - if (wfile.empty()) { - return nullptr; - } - - return gzopen_w(wfile.data(), mode); - -#else // !defined(_WIN32) - - return gzopen(file, mode); - -#endif // defined(_WIN32) -} - -gzFile utilGzOpen(const char* file, const char* mode) { - utilGzWriteFunc = (int(ZEXPORT*)(gzFile, void* const, unsigned int))gzwrite; - utilGzReadFunc = gzread; - utilGzCloseFunc = gzclose; - utilGzSeekFunc = gzseek; - - return utilAutoGzOpen(file, mode); -} - -gzFile utilMemGzOpen(char* memory, int available, const char* mode) { - utilGzWriteFunc = memgzwrite; - utilGzReadFunc = memgzread; - utilGzCloseFunc = memgzclose; - utilGzSeekFunc = memgzseek; - - return memgzopen(memory, available, mode); -} - -int utilGzWrite(gzFile file, const voidp buffer, unsigned int len) { - return utilGzWriteFunc(file, buffer, len); -} - -int utilGzRead(gzFile file, voidp buffer, unsigned int len) { - return utilGzReadFunc(file, buffer, len); -} - -int utilGzClose(gzFile file) { - return utilGzCloseFunc(file); -} - -z_off_t utilGzSeek(gzFile file, z_off_t offset, int whence) { - return utilGzSeekFunc(file, offset, whence); -} - - -long utilGzMemTell(gzFile file) { - return memtell(file); -} - -void utilWriteData(gzFile gzFile, variable_desc* data) { - while (data->address) { - utilGzWrite(gzFile, data->address, data->size); - data++; - } -} - -void utilReadData(gzFile gzFile, variable_desc* data) { - while (data->address) { - utilGzRead(gzFile, data->address, data->size); - data++; - } -} - -void utilReadDataSkip(gzFile gzFile, variable_desc* data) { - while (data->address) { - utilGzSeek(gzFile, data->size, SEEK_CUR); - data++; - } -} - -int utilReadInt(gzFile gzFile) { - int i = 0; - utilGzRead(gzFile, &i, sizeof(int)); - return i; -} - -void utilWriteInt(gzFile gzFile, int i) { - utilGzWrite(gzFile, &i, sizeof(int)); -} diff --git a/src/core/base/file_util.h b/src/core/base/file_util.h index 6d89b8e7..34ca4a6a 100644 --- a/src/core/base/file_util.h +++ b/src/core/base/file_util.h @@ -2,6 +2,7 @@ #define VBAM_CORE_BASE_FILE_UTIL_H_ #include +#include #if defined(__LIBRETRO__) #include @@ -9,13 +10,22 @@ #include #endif // defined(__LIBRETRO__) +#include "core/base/system.h" + +#define FREAD_UNCHECKED(A,B,C,D) (void)(fread(A,B,C,D) + 1) + // save game typedef struct { void *address; int size; } variable_desc; +void utilPutDword(uint8_t *, uint32_t); FILE* utilOpenFile(const char *filename, const char *mode); +uint8_t *utilLoad(const char *, bool (*)(const char *), uint8_t *, int &); +IMAGE_TYPE utilFindType(const char *); +bool utilIsGBAImage(const char *); +bool utilIsGBImage(const char *); #if defined(__LIBRETRO__) diff --git a/src/core/base/file_util_common.cpp b/src/core/base/file_util_common.cpp index 97eef2ea..36d749a4 100644 --- a/src/core/base/file_util_common.cpp +++ b/src/core/base/file_util_common.cpp @@ -1,7 +1,20 @@ #include "file_util.h" +#include + #include "core/base/internal/file_util_internal.h" +#if defined(_MSC_VER) +#define strcasecmp _stricmp +#endif // defined(_MSC_VER) + +void utilPutDword(uint8_t* p, uint32_t value) { + *p++ = value & 255; + *p++ = (value >> 8) & 255; + *p++ = (value >> 16) & 255; + *p = (value >> 24) & 255; +} + FILE* utilOpenFile(const char* filename, const char* mode) { #ifdef _WIN32 std::wstring wfilename = core::internal::ToUTF16(filename); @@ -19,3 +32,37 @@ FILE* utilOpenFile(const char* filename, const char* mode) { return fopen(filename, mode); #endif // _WIN32 } + +bool utilIsGBAImage(const char* file) { + coreOptions.cpuIsMultiBoot = false; + if (strlen(file) > 4) { + const char* p = strrchr(file, '.'); + + if (p != nullptr) { + if ((strcasecmp(p, ".agb") == 0) || (strcasecmp(p, ".gba") == 0) || + (strcasecmp(p, ".bin") == 0) || (strcasecmp(p, ".elf") == 0)) + return true; + if (strcasecmp(p, ".mb") == 0) { + coreOptions.cpuIsMultiBoot = true; + return true; + } + } + } + + return false; +} + +bool utilIsGBImage(const char* file) { + if (strlen(file) > 4) { + const char* p = strrchr(file, '.'); + + if (p != nullptr) { + if ((strcasecmp(p, ".dmg") == 0) || (strcasecmp(p, ".gb") == 0) || + (strcasecmp(p, ".gbc") == 0) || (strcasecmp(p, ".cgb") == 0) || + (strcasecmp(p, ".sgb") == 0)) + return true; + } + } + + return false; +} diff --git a/src/core/base/file_util_desktop.cpp b/src/core/base/file_util_desktop.cpp new file mode 100644 index 00000000..6f9c366d --- /dev/null +++ b/src/core/base/file_util_desktop.cpp @@ -0,0 +1,252 @@ +#include "file_util.h" + +#if defined(__LIBRETRO__) +#error "This file is only for non-libretro builds" +#endif + +#include +#include + +#include "core/base/internal/file_util_internal.h" +#include "core/base/internal/memgzio.h" +#include "core/base/message.h" +#include "core/fex/fex.h" + +#if defined(_MSC_VER) +#define strcasecmp _stricmp +#endif // defined(_MSC_VER) + +#define MAX_CART_SIZE 0x8000000 // 128MB + +namespace { + +bool utilIsGzipFile(const char* file) { + if (strlen(file) > 3) { + const char* p = strrchr(file, '.'); + + if (p != nullptr) { + if (strcasecmp(p, ".gz") == 0) + return true; + if (strcasecmp(p, ".z") == 0) + return true; + } + } + + return false; +} + +// Opens and scans archive using accept(). Returns fex_t if found. +// If error or not found, displays message and returns nullptr. +fex_t* scanArchive(const char* file, bool (*accept)(const char*), char (&buffer)[2048]) { + fex_t* fe; + fex_err_t err = fex_open(&fe, file); + if (!fe) { + systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s: %s"), file, err); + return nullptr; + } + + // Scan filenames + bool found = false; + while (!fex_done(fe)) { + strncpy(buffer, fex_name(fe), sizeof buffer); + buffer[sizeof buffer - 1] = '\0'; + + utilStripDoubleExtension(buffer, buffer); + + if (accept(buffer)) { + found = true; + break; + } + + err = fex_next(fe); + if (err) { + systemMessage(MSG_BAD_ZIP_FILE, N_("Cannot read archive %s: %s"), file, err); + fex_close(fe); + return nullptr; + } + } + + if (!found) { + systemMessage(MSG_NO_IMAGE_ON_ZIP, N_("No image found in file %s"), file); + fex_close(fe); + return nullptr; + } + return fe; +} + +bool utilIsImage(const char* file) { + return utilIsGBAImage(file) || utilIsGBImage(file); +} + +int utilGetSize(int size) { + int res = 1; + while (res < size) + res <<= 1; + return res; +} + +IMAGE_TYPE utilFindType(const char* file, char (&buffer)[2048]) { + fex_t* fe = scanArchive(file, utilIsImage, buffer); + if (!fe) { + return IMAGE_UNKNOWN; + } + + fex_close(fe); + file = buffer; + return utilIsGBAImage(file) ? IMAGE_GBA : IMAGE_GB; +} + +int(ZEXPORT* utilGzWriteFunc)(gzFile, const voidp, unsigned int) = nullptr; +int(ZEXPORT* utilGzReadFunc)(gzFile, voidp, unsigned int) = nullptr; +int(ZEXPORT* utilGzCloseFunc)(gzFile) = nullptr; +z_off_t(ZEXPORT* utilGzSeekFunc)(gzFile, z_off_t, int) = nullptr; + +} // namespace + +uint8_t* utilLoad(const char* file, bool (*accept)(const char*), uint8_t* data, int& size) { + // find image file + char buffer[2048]; + fex_t* fe = scanArchive(file, accept, buffer); + if (!fe) + return nullptr; + + // Allocate space for image + fex_err_t err = fex_stat(fe); + int fileSize = fex_size(fe); + if (size == 0) + size = fileSize; + + if (size > MAX_CART_SIZE) + return nullptr; + + uint8_t* image = data; + + if (image == nullptr) { + // allocate buffer memory if none was passed to the function + image = (uint8_t*)malloc(utilGetSize(size)); + if (image == nullptr) { + fex_close(fe); + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), "data"); + return nullptr; + } + size = fileSize; + } + + // Read image + int read = fileSize <= size ? fileSize : size; // do not read beyond file + err = fex_read(fe, image, read); + fex_close(fe); + if (err) { + systemMessage(MSG_ERROR_READING_IMAGE, N_("Error reading image from %s: %s"), buffer, err); + if (data == nullptr) + free(image); + return nullptr; + } + + size = fileSize; + + return image; +} + +IMAGE_TYPE utilFindType(const char* file) { + char buffer[2048]; + return utilFindType(file, buffer); +} + +void utilStripDoubleExtension(const char* file, char* buffer) { + if (buffer != file) // allows conversion in place + strcpy(buffer, file); + + if (utilIsGzipFile(file)) { + char* p = strrchr(buffer, '.'); + + if (p) + *p = 0; + } +} + +gzFile utilAutoGzOpen(const char* file, const char* mode) { +#if defined(_WIN32) + + std::wstring wfile = core::internal::ToUTF16(file); + if (wfile.empty()) { + return nullptr; + } + + return gzopen_w(wfile.data(), mode); + +#else // !defined(_WIN32) + + return gzopen(file, mode); + +#endif // defined(_WIN32) +} + +gzFile utilGzOpen(const char* file, const char* mode) { + utilGzWriteFunc = (int(ZEXPORT*)(gzFile, void* const, unsigned int))gzwrite; + utilGzReadFunc = gzread; + utilGzCloseFunc = gzclose; + utilGzSeekFunc = gzseek; + + return utilAutoGzOpen(file, mode); +} + +gzFile utilMemGzOpen(char* memory, int available, const char* mode) { + utilGzWriteFunc = memgzwrite; + utilGzReadFunc = memgzread; + utilGzCloseFunc = memgzclose; + utilGzSeekFunc = memgzseek; + + return memgzopen(memory, available, mode); +} + +int utilGzWrite(gzFile file, const voidp buffer, unsigned int len) { + return utilGzWriteFunc(file, buffer, len); +} + +int utilGzRead(gzFile file, voidp buffer, unsigned int len) { + return utilGzReadFunc(file, buffer, len); +} + +int utilGzClose(gzFile file) { + return utilGzCloseFunc(file); +} + +z_off_t utilGzSeek(gzFile file, z_off_t offset, int whence) { + return utilGzSeekFunc(file, offset, whence); +} + +long utilGzMemTell(gzFile file) { + return memtell(file); +} + +void utilWriteData(gzFile gzFile, variable_desc* data) { + while (data->address) { + utilGzWrite(gzFile, data->address, data->size); + data++; + } +} + +void utilReadData(gzFile gzFile, variable_desc* data) { + while (data->address) { + utilGzRead(gzFile, data->address, data->size); + data++; + } +} + +void utilReadDataSkip(gzFile gzFile, variable_desc* data) { + while (data->address) { + utilGzSeek(gzFile, data->size, SEEK_CUR); + data++; + } +} + +int utilReadInt(gzFile gzFile) { + int i = 0; + utilGzRead(gzFile, &i, sizeof(int)); + return i; +} + +void utilWriteInt(gzFile gzFile, int i) { + utilGzWrite(gzFile, &i, sizeof(int)); +} diff --git a/src/core/base/file_util_libretro.cpp b/src/core/base/file_util_libretro.cpp index 555d647a..d2a0e524 100644 --- a/src/core/base/file_util_libretro.cpp +++ b/src/core/base/file_util_libretro.cpp @@ -4,8 +4,58 @@ #error "This file is only for libretro builds" #endif +#include #include +IMAGE_TYPE utilFindType(const char* file) { + if (utilIsGBAImage(file)) + return IMAGE_GBA; + + if (utilIsGBImage(file)) + return IMAGE_GB; + + return IMAGE_UNKNOWN; +} + +static int utilGetSize(int size) { + int res = 1; + while (res < size) + res <<= 1; + return res; +} + +uint8_t* utilLoad(const char* file, bool (*)(const char*), uint8_t* data, int& size) { + FILE* fp = nullptr; + + fp = fopen(file, "rb"); + if (!fp) { + log("Failed to open file %s", file); + return nullptr; + } + fseek(fp, 0, SEEK_END); // go to end + + size = ftell(fp); // get position at end (length) + rewind(fp); + + uint8_t* image = data; + if (image == nullptr) { + image = (uint8_t*)malloc(utilGetSize(size)); + if (image == nullptr) { + log("Failed to allocate memory for %s", file); + return nullptr; + } + } + + if (fread(image, 1, size, fp) != (size_t)size) { + log("Failed to read from %s", file); + fclose(fp); + return nullptr; + } + + fclose(fp); + return image; +} + // Not endian safe, but VBA itself doesn't seem to care, so hey <_< void utilWriteIntMem(uint8_t*& data, int val) { memcpy(data, &val, sizeof(int)); diff --git a/src/core/base/image_util.cpp b/src/core/base/image_util.cpp new file mode 100644 index 00000000..375c0f0d --- /dev/null +++ b/src/core/base/image_util.cpp @@ -0,0 +1,193 @@ +#include "image_util.h" + +#define STB_IMAGE_IMPLEMENTATION +#define STB_IMAGE_WRITE_IMPLEMENTATION +extern "C" { +#include +} // extern "C" + +#include "core/base/file_util.h" +#include "core/base/system.h" +#include "core/base/message.h" + +bool utilWritePNGFile(const char* fileName, int w, int h, uint8_t* pix) { + static constexpr size_t kNumChannels = 3; + uint8_t* writeBuffer = new uint8_t[w * h * kNumChannels]; + + uint8_t* b = writeBuffer; + + int sizeX = w; + int sizeY = h; + + switch (systemColorDepth) { + case 16: { + uint16_t* p = (uint16_t*)(pix + (w + 2) * 2); // skip first black line + for (int y = 0; y < sizeY; y++) { + for (int x = 0; x < sizeX; x++) { + uint16_t v = *p++; + + *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R + *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G + *b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B + } + p++; // skip black pixel for filters + p++; // skip black pixel for filters + } + } break; + case 24: { + uint8_t* pixU8 = (uint8_t*)pix; + for (int y = 0; y < sizeY; y++) { + for (int x = 0; x < sizeX; x++) { + if (systemRedShift < systemBlueShift) { + *b++ = *pixU8++; // R + *b++ = *pixU8++; // G + *b++ = *pixU8++; // B + } else { + uint8_t blue = *pixU8++; + uint8_t green = *pixU8++; + uint8_t red = *pixU8++; + + *b++ = red; + *b++ = green; + *b++ = blue; + } + } + } + } break; + case 32: { + uint32_t* pixU32 = (uint32_t*)(pix + 4 * (w + 1)); + for (int y = 0; y < sizeY; y++) { + for (int x = 0; x < sizeX; x++) { + uint32_t v = *pixU32++; + + *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R + *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G + *b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B + } + pixU32++; + } + } break; + } + + bool ret = (0 != stbi_write_png(fileName, w, h, kNumChannels, writeBuffer, w * kNumChannels)); + delete[] writeBuffer; + return ret; +} + +bool utilWriteBMPFile(const char* fileName, int w, int h, uint8_t* pix) { + uint8_t writeBuffer[512 * 3]; + + FILE* fp = fopen(fileName, "wb"); + + if (!fp) { + systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), fileName); + return false; + } + + struct { + uint8_t ident[2]; + uint8_t filesize[4]; + uint8_t reserved[4]; + uint8_t dataoffset[4]; + uint8_t headersize[4]; + uint8_t width[4]; + uint8_t height[4]; + uint8_t planes[2]; + uint8_t bitsperpixel[2]; + uint8_t compression[4]; + uint8_t datasize[4]; + uint8_t hres[4]; + uint8_t vres[4]; + uint8_t colors[4]; + uint8_t importantcolors[4]; + // uint8_t pad[2]; + } bmpheader; + memset(&bmpheader, 0, sizeof(bmpheader)); + + bmpheader.ident[0] = 'B'; + bmpheader.ident[1] = 'M'; + + uint32_t fsz = sizeof(bmpheader) + w * h * 3; + utilPutDword(bmpheader.filesize, fsz); + utilPutDword(bmpheader.dataoffset, 0x36); + utilPutDword(bmpheader.headersize, 0x28); + utilPutDword(bmpheader.width, w); + utilPutDword(bmpheader.height, h); + utilPutDword(bmpheader.planes, 1); + utilPutDword(bmpheader.bitsperpixel, 24); + utilPutDword(bmpheader.datasize, 3 * w * h); + + fwrite(&bmpheader, 1, sizeof(bmpheader), fp); + + uint8_t* b = writeBuffer; + + int sizeX = w; + int sizeY = h; + + switch (systemColorDepth) { + case 16: { + uint16_t* p = (uint16_t*)(pix + (w + 2) * (h) * 2); // skip first black line + for (int y = 0; y < sizeY; y++) { + for (int x = 0; x < sizeX; x++) { + uint16_t v = *p++; + + *b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B + *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G + *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R + } + p++; // skip black pixel for filters + p++; // skip black pixel for filters + p -= 2 * (w + 2); + fwrite(writeBuffer, 1, 3 * w, fp); + + b = writeBuffer; + } + } break; + case 24: { + uint8_t* pixU8 = (uint8_t*)pix + 3 * w * (h - 1); + for (int y = 0; y < sizeY; y++) { + for (int x = 0; x < sizeX; x++) { + if (systemRedShift > systemBlueShift) { + *b++ = *pixU8++; // B + *b++ = *pixU8++; // G + *b++ = *pixU8++; // R + } else { + uint8_t red = *pixU8++; + uint8_t green = *pixU8++; + uint8_t blue = *pixU8++; + + *b++ = blue; + *b++ = green; + *b++ = red; + } + } + pixU8 -= 2 * 3 * w; + fwrite(writeBuffer, 1, 3 * w, fp); + + b = writeBuffer; + } + } break; + case 32: { + uint32_t* pixU32 = (uint32_t*)(pix + 4 * (w + 1) * (h)); + for (int y = 0; y < sizeY; y++) { + for (int x = 0; x < sizeX; x++) { + uint32_t v = *pixU32++; + + *b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B + *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G + *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R + } + pixU32++; + pixU32 -= 2 * (w + 1); + + fwrite(writeBuffer, 1, 3 * w, fp); + + b = writeBuffer; + } + } break; + } + + fclose(fp); + + return true; +} diff --git a/src/core/base/image_util.h b/src/core/base/image_util.h new file mode 100644 index 00000000..c8f6354b --- /dev/null +++ b/src/core/base/image_util.h @@ -0,0 +1,13 @@ +#ifndef VBAM_CORE_BASE_IMAGE_UTIL_H_ +#define VBAM_CORE_BASE_IMAGE_UTIL_H_ + +#if defined(__LIBRETRO__) +#error "This file is not meant for compilation in libretro builds." +#endif // defined(__LIBRETRO__) + +#include + +bool utilWritePNGFile(const char*, int, int, uint8_t*); +bool utilWriteBMPFile(const char*, int, int, uint8_t*); + +#endif // VBAM_CORE_BASE_IMAGE_UTIL_H_ \ No newline at end of file diff --git a/src/core/base/sound_driver.h b/src/core/base/sound_driver.h new file mode 100644 index 00000000..5f229a47 --- /dev/null +++ b/src/core/base/sound_driver.h @@ -0,0 +1,48 @@ +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. +// Copyright (C) 2015 VBA-M development team + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or(at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +#ifndef VBAM_CORE_BASE_SOUND_DRIVER_H_ +#define VBAM_CORE_BASE_SOUND_DRIVER_H_ + +#include + +// Sound driver abstract interface for the core to use to output sound. +// Subclass this to implement a new sound driver. +class SoundDriver { +public: + virtual ~SoundDriver() = default; + + // Initialize the sound driver. `sampleRate` in Hertz. + // Returns true if the driver was successfully initialized. + virtual bool init(long sampleRate) = 0; + + // Pause the sound driver. + virtual void pause() = 0; + + // Reset the sound driver. + virtual void reset() = 0; + + // Resume the sound driver, following a pause. + virtual void resume() = 0; + + // Write length bytes of data from the finalWave buffer to the driver output buffer. + virtual void write(uint16_t* finalWave, int length) = 0; + + virtual void setThrottle(unsigned short throttle) = 0; +}; + +#endif // VBAM_CORE_BASE_SOUND_DRIVER_H_ diff --git a/src/System.h b/src/core/base/system.h similarity index 55% rename from src/System.h rename to src/core/base/system.h index d60ac5e5..41016725 100644 --- a/src/System.h +++ b/src/core/base/system.h @@ -1,50 +1,55 @@ -#ifndef SYSTEM_H -#define SYSTEM_H +#ifndef VBAM_CORE_BASE_SYSTEM_H_ +#define VBAM_CORE_BASE_SYSTEM_H_ #include -#include "core/base/message.h" - class SoundDriver; -struct EmulatedSystem { - // main emulation function - void (*emuMain)(int); - // reset emulator - void (*emuReset)(); - // clean up memory - void (*emuCleanUp)(); - // load battery file - bool (*emuReadBattery)(const char *); - // write battery file - bool (*emuWriteBattery)(const char *); -#ifdef __LIBRETRO__ - // load state - bool (*emuReadState)(const uint8_t *); - // load state - unsigned (*emuWriteState)(uint8_t *); -#else - // load state - bool (*emuReadState)(const char *); - // save state - bool (*emuWriteState)(const char *); -#endif - // load memory state (rewind) - bool (*emuReadMemState)(char *, int); - // write memory state (rewind) - bool (*emuWriteMemState)(char *, int, long &); - // write PNG file - bool (*emuWritePNG)(const char *); - // write BMP file - bool (*emuWriteBMP)(const char *); - // emulator update CPSR (ARM only) - void (*emuUpdateCPSR)(); - // emulator has debugger - bool emuHasDebugger; - // clock ticks to emulate - int emuCount; +enum IMAGE_TYPE { + IMAGE_UNKNOWN = -1, + IMAGE_GBA = 0, + IMAGE_GB = 1 }; +struct EmulatedSystem { + // main emulation function + void (*emuMain)(int); + // reset emulator + void (*emuReset)(); + // clean up memory + void (*emuCleanUp)(); + // load battery file + bool (*emuReadBattery)(const char*); + // write battery file + bool (*emuWriteBattery)(const char*); +#ifdef __LIBRETRO__ + // load state + bool (*emuReadState)(const uint8_t*); + // load state + unsigned (*emuWriteState)(uint8_t*); +#else + // load state + bool (*emuReadState)(const char*); + // save state + bool (*emuWriteState)(const char*); +#endif + // load memory state (rewind) + bool (*emuReadMemState)(char*, int); + // write memory state (rewind) + bool (*emuWriteMemState)(char*, int, long&); + // write PNG file + bool (*emuWritePNG)(const char*); + // write BMP file + bool (*emuWriteBMP)(const char*); + // emulator update CPSR (ARM only) + void (*emuUpdateCPSR)(); + // emulator has debugger + bool emuHasDebugger; + // clock ticks to emulate + int emuCount; +}; + +// The `coreOptions` object must be instantiated by the embedder. extern struct CoreOptions { bool cpuIsMultiBoot = false; bool mirroringEnable = true; @@ -67,13 +72,14 @@ extern struct CoreOptions { uint32_t speedup_throttle = 100; uint32_t speedup_frame_skip = 9; uint32_t throttle = 100; - const char *loadDotCodeFile = nullptr; - const char *saveDotCodeFile = nullptr; + const char* loadDotCodeFile = nullptr; + const char* saveDotCodeFile = nullptr; } coreOptions; -extern void log(const char *, ...); +// The following functions must be implemented by the emulator. +extern void log(const char*, ...); extern bool systemPauseOnFrame(); -extern void systemGbPrint(uint8_t *, int, int, int, int, int); +extern void systemGbPrint(uint8_t*, int, int, int, int, int); extern void systemScreenCapture(int); extern void systemDrawScreen(); extern void systemSendScreen(); @@ -82,11 +88,11 @@ extern bool systemReadJoypads(); // return information about the given joystick, -1 for default joystick extern uint32_t systemReadJoypad(int); extern uint32_t systemGetClock(); -extern void systemSetTitle(const char *); -extern SoundDriver *systemSoundInit(); -extern void systemOnWriteDataToSoundBuffer(const uint16_t *finalWave, int length); +extern void systemSetTitle(const char*); +extern SoundDriver* systemSoundInit(); +extern void systemOnWriteDataToSoundBuffer(const uint16_t* finalWave, int length); extern void systemOnSoundShutdown(); -extern void systemScreenMessage(const char *); +extern void systemScreenMessage(const char*); extern void systemUpdateMotionSensor(); extern int systemGetSensorX(); extern int systemGetSensorY(); @@ -100,7 +106,7 @@ extern void systemShowSpeed(int); extern void system10Frames(); extern void systemFrame(); extern void systemGbBorderOn(); -extern void (*dbgOutput)(const char *s, uint32_t addr); +extern void (*dbgOutput)(const char* s, uint32_t addr); extern void (*dbgSignal)(int sig, int number); extern uint16_t systemColorMap16[0x10000]; extern uint32_t systemColorMap32[0x10000]; @@ -113,7 +119,9 @@ extern int systemVerbose; extern int systemFrameSkip; extern int systemSaveUpdateCounter; extern int systemSpeed; + #define MAX_CHEATS 16384 #define SYSTEM_SAVE_UPDATED 30 #define SYSTEM_SAVE_NOT_UPDATED 0 -#endif // SYSTEM_H + +#endif // VBAM_CORE_BASE_SYSTEM_H_ \ No newline at end of file diff --git a/src/filters/2xSaI.cpp b/src/filters/2xSaI.cpp index d6ab51e4..f550be24 100644 --- a/src/filters/2xSaI.cpp +++ b/src/filters/2xSaI.cpp @@ -1,4 +1,4 @@ -#include "../System.h" +#include "core/base/system.h" extern int RGB_LOW_BITS_MASK; diff --git a/src/filters/admame.cpp b/src/filters/admame.cpp index 094101d0..50bd0a6a 100644 --- a/src/filters/admame.cpp +++ b/src/filters/admame.cpp @@ -35,7 +35,7 @@ * - the whole source code of the program is released with the binary. */ -#include "../System.h" +#include #ifdef MMX extern "C" bool cpu_mmx; diff --git a/src/filters/bilinear.cpp b/src/filters/bilinear.cpp index 2d9d6fc3..a74a4cb0 100644 --- a/src/filters/bilinear.cpp +++ b/src/filters/bilinear.cpp @@ -4,7 +4,7 @@ ** Written: 6/14/00 - JSF **/ -#include "../System.h" +#include "core/base/system.h" #define RGB(r,g,b) ((r)>>3) << systemRedShift |\ ((g) >> 3) << systemGreenShift |\ diff --git a/src/filters/hq2x.cpp b/src/filters/hq2x.cpp index 8fd39b97..04599146 100644 --- a/src/filters/hq2x.cpp +++ b/src/filters/hq2x.cpp @@ -27,7 +27,7 @@ * file, but you are not obligated to do so. If you do not wish to * do so, delete this exception statement from your version. */ -#include "../System.h" + #include "interp.h" /***************************************************************************/ diff --git a/src/filters/interframe.cpp b/src/filters/interframe.cpp index f255d748..ba42c734 100644 --- a/src/filters/interframe.cpp +++ b/src/filters/interframe.cpp @@ -1,9 +1,7 @@ -#include "../System.h" -#include -#include - #include "interframe.hpp" +#include + #ifdef MMX extern "C" bool cpu_mmx; #endif diff --git a/src/filters/interframe.hpp b/src/filters/interframe.hpp index 6a482866..c5065e94 100644 --- a/src/filters/interframe.hpp +++ b/src/filters/interframe.hpp @@ -3,6 +3,8 @@ #ifndef INTERFRAME_HPP #define INTERFRAME_HPP +#include + extern int RGB_LOW_BITS_MASK; void InterframeFilterInit(); diff --git a/src/filters/pixel.cpp b/src/filters/pixel.cpp index 8aff7181..d9dbb4b0 100644 --- a/src/filters/pixel.cpp +++ b/src/filters/pixel.cpp @@ -1,4 +1,4 @@ -#include "../System.h" +#include extern int RGB_LOW_BITS_MASK; diff --git a/src/filters/scanline.cpp b/src/filters/scanline.cpp index c74ff4c1..e19bf894 100644 --- a/src/filters/scanline.cpp +++ b/src/filters/scanline.cpp @@ -1,4 +1,4 @@ -#include "../System.h" +#include extern int RGB_LOW_BITS_MASK; diff --git a/src/filters/simpleFilter.cpp b/src/filters/simpleFilter.cpp index 7d86159e..3a0496e4 100644 --- a/src/filters/simpleFilter.cpp +++ b/src/filters/simpleFilter.cpp @@ -1,4 +1,4 @@ -#include "../System.h" +#include void Simple2x16(uint8_t *srcPtr, uint32_t srcPitch, uint8_t * /* deltaPtr */, uint8_t *dstPtr, uint32_t dstPitch, int width, int height) diff --git a/src/filters/xbrzfilter.cpp b/src/filters/xbrzfilter.cpp index bfe45114..131bbb0a 100644 --- a/src/filters/xbrzfilter.cpp +++ b/src/filters/xbrzfilter.cpp @@ -1,4 +1,4 @@ -#include "../System.h" +#include #include "xBRZ/xbrz.h" diff --git a/src/gb/GB.cpp b/src/gb/GB.cpp index 9d3c94c1..33fd8175 100644 --- a/src/gb/GB.cpp +++ b/src/gb/GB.cpp @@ -8,12 +8,12 @@ #include #include -#include "core/base/file_util.h" -#include "core/base/sizes.h" -#include "../System.h" -#include "../Util.h" #include "../gba/GBALink.h" #include "../gba/Sound.h" +#include "core/base/file_util.h" +#include "core/base/message.h" +#include "core/base/sizes.h" +#include "core/base/system.h" #include "gbCheats.h" #include "gbGlobals.h" #include "gbMemory.h" @@ -21,6 +21,7 @@ #include "gbSound.h" #if !defined(__LIBRETRO__) +#include "core/base/image_util.h" #include "core/base/patch.h" #endif // defined(__LIBRETRO__) diff --git a/src/gb/gbCheats.cpp b/src/gb/gbCheats.cpp index 7743b79b..c88132cf 100644 --- a/src/gb/gbCheats.cpp +++ b/src/gb/gbCheats.cpp @@ -1,14 +1,14 @@ -#include -#include -#include -#include +#include "gbCheats.h" -#include "../System.h" -#include "../Util.h" +#include +#include +#include + +#include "core/base/message.h" +#include "core/base/system.h" #include "core/base/file_util.h" #include "gb.h" -#include "gbCheats.h" #include "gbGlobals.h" gbCheat gbCheatList[MAX_CHEATS]; diff --git a/src/gb/gbCheats.h b/src/gb/gbCheats.h index fc2a32a5..513513e9 100644 --- a/src/gb/gbCheats.h +++ b/src/gb/gbCheats.h @@ -7,7 +7,7 @@ #include #endif // defined(__LIBRETRO__) -#include "../System.h" +#include "core/base/system.h" struct gbXxCheat { char cheatDesc[100]; diff --git a/src/gb/gbDis.cpp b/src/gb/gbDis.cpp index b9638908..42202b7a 100644 --- a/src/gb/gbDis.cpp +++ b/src/gb/gbDis.cpp @@ -1,7 +1,5 @@ -#include -#include +#include -#include "../System.h" #include "gbGlobals.h" typedef struct { diff --git a/src/gb/gbGfx.cpp b/src/gb/gbGfx.cpp index 9018228f..f9d3b1c6 100644 --- a/src/gb/gbGfx.cpp +++ b/src/gb/gbGfx.cpp @@ -1,6 +1,6 @@ #include -#include "../System.h" +#include "core/base/system.h" #include "gbGlobals.h" #include "gbSGB.h" diff --git a/src/gb/gbMemory.cpp b/src/gb/gbMemory.cpp index 08a429bd..00b2fb52 100644 --- a/src/gb/gbMemory.cpp +++ b/src/gb/gbMemory.cpp @@ -2,11 +2,12 @@ #include -#include "../System.h" #include "core/base/port.h" #include "core/base/sizes.h" +#include "core/base/system.h" #include "gb.h" #include "gbGlobals.h" + uint8_t gbDaysinMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; extern int gbGBCColorType; extern gbRegister PC; diff --git a/src/gb/gbPrinter.cpp b/src/gb/gbPrinter.cpp index 6bd06c7e..530d59a5 100644 --- a/src/gb/gbPrinter.cpp +++ b/src/gb/gbPrinter.cpp @@ -1,6 +1,9 @@ -#include "../System.h" -#include -#include +#include "gbPrinter.h" + +#include +#include + +#include "core/base/system.h" uint8_t gbPrinterStatus = 0; int gbPrinterState = 0; diff --git a/src/gb/gbPrinter.h b/src/gb/gbPrinter.h index 582cc490..8a8ada86 100644 --- a/src/gb/gbPrinter.h +++ b/src/gb/gbPrinter.h @@ -1,7 +1,7 @@ #ifndef GBPRINTER_H #define GBPRINTER_H -#include "../System.h" +#include uint8_t gbPrinterSend(uint8_t b); diff --git a/src/gb/gbSGB.cpp b/src/gb/gbSGB.cpp index ce939c53..c20333ad 100644 --- a/src/gb/gbSGB.cpp +++ b/src/gb/gbSGB.cpp @@ -3,7 +3,7 @@ #include "core/base/file_util.h" #include "core/base/port.h" -#include "../System.h" +#include "core/base/system.h" #include "gb.h" #include "gbGlobals.h" diff --git a/src/gb/gbSound.cpp b/src/gb/gbSound.cpp index a7a7a8e5..af7545f5 100644 --- a/src/gb/gbSound.cpp +++ b/src/gb/gbSound.cpp @@ -2,7 +2,7 @@ #include -#include "../System.h" +#include "core/base/system.h" #include "core/base/file_util.h" #include "../gba/Sound.h" #include "gb.h" diff --git a/src/gba/CheatSearch.h b/src/gba/CheatSearch.h index be709e5b..9fe7383e 100644 --- a/src/gba/CheatSearch.h +++ b/src/gba/CheatSearch.h @@ -1,7 +1,7 @@ #ifndef CHEATSEARCH_H #define CHEATSEARCH_H -#include "../System.h" +#include struct CheatSearchBlock { int size; diff --git a/src/gba/Cheats.cpp b/src/gba/Cheats.cpp index 089eaa68..f0daf47c 100644 --- a/src/gba/Cheats.cpp +++ b/src/gba/Cheats.cpp @@ -1,11 +1,10 @@ -#include -#include -#include -#include +#include "Cheats.h" + +#include +#include #include "core/base/file_util.h" -#include "../Util.h" -#include "Cheats.h" +#include "core/base/message.h" #include "GBA.h" #include "GBAinline.h" #include "Globals.h" diff --git a/src/gba/Cheats.h b/src/gba/Cheats.h index 856f9c3e..f9e76887 100644 --- a/src/gba/Cheats.h +++ b/src/gba/Cheats.h @@ -3,7 +3,7 @@ #include -#include "../System.h" +#include "core/base/system.h" #if !defined(__LIBRETRO__) #include diff --git a/src/gba/GBA-arm.cpp b/src/gba/GBA-arm.cpp index 0a6fd046..cdb6b20f 100644 --- a/src/gba/GBA-arm.cpp +++ b/src/gba/GBA-arm.cpp @@ -1,23 +1,7 @@ -#include -#include -#include -#include -#include - -#include "../System.h" -#include "../Util.h" -#include "Cheats.h" -#include "EEprom.h" -#include "Flash.h" #include "GBA.h" #include "GBAcpu.h" #include "GBAinline.h" #include "Globals.h" -#include "Sound.h" -#include "Sram.h" -#include "agbprint.h" -#include "bios.h" -#include "elf.h" #include "remote.h" #ifdef PROFILING diff --git a/src/gba/GBA-thumb.cpp b/src/gba/GBA-thumb.cpp index 6e67b634..d0b47b85 100644 --- a/src/gba/GBA-thumb.cpp +++ b/src/gba/GBA-thumb.cpp @@ -1,26 +1,15 @@ -#include -#include -#include -#include -#include +#include +#include +#include + #ifndef _MSC_VER #include #endif -#include "../System.h" -#include "../Util.h" -#include "Cheats.h" -#include "EEprom.h" -#include "Flash.h" #include "GBA.h" #include "GBAcpu.h" #include "GBAinline.h" #include "Globals.h" -#include "Sound.h" -#include "Sram.h" -#include "agbprint.h" -#include "bios.h" -#include "elf.h" #include "remote.h" #ifdef PROFILING diff --git a/src/gba/GBA.cpp b/src/gba/GBA.cpp index caaf5eba..c55a096a 100644 --- a/src/gba/GBA.cpp +++ b/src/gba/GBA.cpp @@ -10,8 +10,8 @@ #endif #include "core/base/file_util.h" -#include "../System.h" -#include "../Util.h" +#include "core/base/message.h" +#include "core/base/system.h" #include "core/base/port.h" #include "core/base/sizes.h" #include "Cheats.h" @@ -30,6 +30,10 @@ #include "elf.h" #include "ereader.h" +#if !defined(__LIBRETRO__) +#include "core/base/image_util.h" +#endif // !__LIBRETRO__ + #ifdef PROFILING #include "prof/prof.h" #endif diff --git a/src/gba/GBA.h b/src/gba/GBA.h index 30f15d5f..f8aa77fa 100644 --- a/src/gba/GBA.h +++ b/src/gba/GBA.h @@ -3,8 +3,7 @@ #include -#include "../System.h" -#include "../Util.h" +#include "core/base/system.h" const uint64_t TICKS_PER_SECOND = 16777216; diff --git a/src/gba/GBAGfx.cpp b/src/gba/GBAGfx.cpp index 81a28a57..e006d740 100644 --- a/src/gba/GBAGfx.cpp +++ b/src/gba/GBAGfx.cpp @@ -1,6 +1,8 @@ -#include #include "GBAGfx.h" -#include "../System.h" + +#if defined(TILED_RENDERING) +#include +#endif // defined(TILED_RENDERING) int g_coeff[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, diff --git a/src/gba/GBAinline.h b/src/gba/GBAinline.h index c171ecc7..7574973e 100644 --- a/src/gba/GBAinline.h +++ b/src/gba/GBAinline.h @@ -3,7 +3,7 @@ #include -#include "../System.h" +#include "core/base/system.h" #include "core/base/port.h" #include "GBALink.h" #include "GBAcpu.h" diff --git a/src/gba/RTC.cpp b/src/gba/RTC.cpp index 7531c342..49de350f 100644 --- a/src/gba/RTC.cpp +++ b/src/gba/RTC.cpp @@ -1,13 +1,15 @@ -#include "../System.h" +#include "RTC.h" + +#include +#include + +#include "core/base/file_util.h" +#include "core/base/message.h" #include "core/base/port.h" #include "GBA.h" #include "GBAinline.h" #include "Globals.h" -#include "core/base/file_util.h" -#include -#include -#include enum RTCSTATE { IDLE = 0, diff --git a/src/gba/Sound.cpp b/src/gba/Sound.cpp index 92b96fe1..e9aceeed 100644 --- a/src/gba/Sound.cpp +++ b/src/gba/Sound.cpp @@ -5,14 +5,13 @@ #include "core/base/file_util.h" #include "core/base/port.h" +#include "core/base/sound_driver.h" #include "GBA.h" #include "Globals.h" #include "../apu/Gb_Apu.h" #include "../apu/Multi_Buffer.h" -#include "../common/SoundDriver.h" - #define NR10 0x60 #define NR11 0x62 #define NR12 0x63 diff --git a/src/gba/agbprint.cpp b/src/gba/agbprint.cpp index f0f38f20..ac480b3f 100644 --- a/src/gba/agbprint.cpp +++ b/src/gba/agbprint.cpp @@ -1,8 +1,6 @@ -#include -#include +#include "agbprint.h" #include "core/base/port.h" -#include "../System.h" #include "GBA.h" #include "Globals.h" diff --git a/src/gba/agbprint.h b/src/gba/agbprint.h index 14b5528a..20e790ab 100644 --- a/src/gba/agbprint.h +++ b/src/gba/agbprint.h @@ -1,6 +1,8 @@ #ifndef AGBPRINT_H #define AGBPRINT_H +#include + void agbPrintEnable(bool enable); bool agbPrintIsEnabled(); void agbPrintReset(); diff --git a/src/gba/armdis.cpp b/src/gba/armdis.cpp index f520b8e9..bca0c735 100644 --- a/src/gba/armdis.cpp +++ b/src/gba/armdis.cpp @@ -1,11 +1,11 @@ +#include "armdis.h" + /************************************************************************/ /* Arm/Thumb command set disassembler */ /************************************************************************/ -#include #include #include "core/base/port.h" -#include "../System.h" #include "GBA.h" #include "armdis.h" #include "elf.h" diff --git a/src/gba/debugger-expr-yacc.cpp b/src/gba/debugger-expr-yacc.cpp index 0337708e..5932e0d7 100644 --- a/src/gba/debugger-expr-yacc.cpp +++ b/src/gba/debugger-expr-yacc.cpp @@ -78,13 +78,11 @@ #include -#include "../System.h" #include "GBA.h" #include "core/base/port.h" #include #include -#include unsigned int dexp_result = 0; extern int dexp_error(const char *); diff --git a/src/gba/debugger-expr.y b/src/gba/debugger-expr.y index f186a3f9..9fe2c2e7 100644 --- a/src/gba/debugger-expr.y +++ b/src/gba/debugger-expr.y @@ -1,13 +1,11 @@ %{ #include -#include "../System.h" #include "GBA.h" #include "core/base/port.h" #include #include -#include unsigned int dexp_result = 0; extern int dexp_error(const char *); diff --git a/src/gba/elf.cpp b/src/gba/elf.cpp index f978a519..24d5a84a 100644 --- a/src/gba/elf.cpp +++ b/src/gba/elf.cpp @@ -2,6 +2,7 @@ #include #include +#include "core/base/message.h" #include "core/base/port.h" #include "GBA.h" #include "elf.h" diff --git a/src/gba/elf.h b/src/gba/elf.h index 7c87dd43..efb61f24 100644 --- a/src/gba/elf.h +++ b/src/gba/elf.h @@ -1,6 +1,9 @@ #ifndef ELF_H #define ELF_H +#include +#include + enum LocationType { LOCATION_register, LOCATION_memory, LOCATION_value }; diff --git a/src/gba/gbafilter.h b/src/gba/gbafilter.h index 69a19dfc..246c6c95 100644 --- a/src/gba/gbafilter.h +++ b/src/gba/gbafilter.h @@ -1,5 +1,10 @@ -#include "../System.h" +#ifndef VBAM_GBA_GBAFILTER_H_ +#define VBAM_GBA_GBAFILTER_H_ + +#include void gbafilter_pal(uint16_t* buf, int count); void gbafilter_pal32(uint32_t* buf, int count); void gbafilter_pad(uint8_t* buf, int count); + +#endif // VBAM_GBA_GBAFILTER_H_ \ No newline at end of file diff --git a/src/libretro/Makefile.common b/src/libretro/Makefile.common index 675c5ba2..5b0612ec 100644 --- a/src/libretro/Makefile.common +++ b/src/libretro/Makefile.common @@ -22,7 +22,6 @@ SOURCES_CXX += \ SOURCES_CXX += \ $(CORE_DIR)/libretro/libretro.cpp \ - $(CORE_DIR)/libretro/UtilRetro.cpp \ $(CORE_DIR)/libretro/SoundRetro.cpp SOURCES_CXX += \ diff --git a/src/libretro/SoundRetro.h b/src/libretro/SoundRetro.h index 43ef5403..63638bf3 100644 --- a/src/libretro/SoundRetro.h +++ b/src/libretro/SoundRetro.h @@ -18,7 +18,7 @@ #ifndef __VBA_SOUND_RETRO_H__ #define __VBA_SOUND_RETRO_H__ -#include "../common/SoundDriver.h" +#include "core/base/sound_driver.h" class SoundRetro : public SoundDriver { public: diff --git a/src/libretro/UtilRetro.cpp b/src/libretro/UtilRetro.cpp deleted file mode 100644 index a1609538..00000000 --- a/src/libretro/UtilRetro.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include - -#include "Util.h" -#include "gba/gbafilter.h" - -IMAGE_TYPE utilFindType(const char* file) -{ - if (utilIsGBAImage(file)) - return IMAGE_GBA; - - if (utilIsGBImage(file)) - return IMAGE_GB; - - return IMAGE_UNKNOWN; -} - -static int utilGetSize(int size) -{ - int res = 1; - while(res < size) - res <<= 1; - return res; -} - -uint8_t *utilLoad(const char *file, bool (*accept)(const char *), uint8_t *data, int &size) -{ - FILE *fp = NULL; - - fp = fopen(file,"rb"); - if (!fp) - { - log("Failed to open file %s", file); - return NULL; - } - fseek(fp, 0, SEEK_END); //go to end - - size = ftell(fp); // get position at end (length) - rewind(fp); - - uint8_t *image = data; - if(image == NULL) - { - image = (uint8_t *)malloc(utilGetSize(size)); - if(image == NULL) - { - log("Failed to allocate memory for %s", file); - return NULL; - } - } - - if (fread(image, 1, size, fp) != (size_t)size) { - log("Failed to read from %s", file); - fclose(fp); - return NULL; - } - - fclose(fp); - return image; -} diff --git a/src/libretro/libretro.cpp b/src/libretro/libretro.cpp index 57e2f820..535b063b 100644 --- a/src/libretro/libretro.cpp +++ b/src/libretro/libretro.cpp @@ -10,8 +10,9 @@ #include "libretro_core_options.h" #include "scrc32.h" -#include "../System.h" +#include "core/base/system.h" #include "../Util.h" +#include "core/base/file_util.h" #include "core/base/port.h" #include "core/base/sizes.h" #include "../apu/Blip_Buffer.h" diff --git a/src/sdl/ConfigManager.h b/src/sdl/ConfigManager.h index b27ebae3..a50df871 100644 --- a/src/sdl/ConfigManager.h +++ b/src/sdl/ConfigManager.h @@ -3,21 +3,17 @@ #pragma once -#include "../System.h" +#include "core/base/system.h" #include "../sdl/filters.h" #include #ifndef __GNUC__ #define HAVE_DECL_GETOPT 0 #define __STDC__ 1 -#ifndef __LIBRETRO__ #include "getopt.h" -#endif #else // ! __GNUC__ #define HAVE_DECL_GETOPT 1 -#ifndef __LIBRETRO__ #include -#endif #endif // ! __GNUC__ extern const char *biosFileNameGB; diff --git a/src/sdl/SDL.cpp b/src/sdl/SDL.cpp index 4150cfcf..fc8c5837 100644 --- a/src/sdl/SDL.cpp +++ b/src/sdl/SDL.cpp @@ -44,6 +44,7 @@ #include #include "core/base/file_util.h" +#include "core/base/message.h" #include "core/base/patch.h" #include "core/base/version.h" #include "../Util.h" @@ -56,7 +57,6 @@ #include "../gba/GBA.h" #include "../gba/RTC.h" #include "../gba/Sound.h" -#include "../gba/agbprint.h" #include "../common/SoundSDL.h" diff --git a/src/sdl/debugger.cpp b/src/sdl/debugger.cpp index 4b2d2905..bd5ae751 100644 --- a/src/sdl/debugger.cpp +++ b/src/sdl/debugger.cpp @@ -289,11 +289,11 @@ static void debuggerPrintBaseType(Type* t, uint32_t value, uint32_t location, } if (t->size == 8) { - u64 value = 0; + uint64_t value = 0; if (type == LOCATION_memory) { - value = debuggerReadMemory(location) | ((u64)debuggerReadMemory(location + 4) << 32); + value = debuggerReadMemory(location) | ((uint64_t)debuggerReadMemory(location + 4) << 32); } else if (type == LOCATION_register) { - value = reg[location].I | ((u64)reg[location + 1].I << 32); + value = reg[location].I | ((uint64_t)reg[location + 1].I << 32); } switch (t->encoding) { case DW_ATE_signed: @@ -1590,8 +1590,8 @@ void debuggerDoSearch() SearchStart = 0x02000000; continue; } else { - start = bios + (SearchStart & 0x3FFF); - end = bios + 0x3FFF; + start = g_bios + (SearchStart & 0x3FFF); + end = g_bios + 0x3FFF; break; }; case 2: @@ -1655,8 +1655,8 @@ void debuggerDoSearch() case 12: case 13: if (final <= 0x09FFFFFF) { - start = rom + (SearchStart & 0x01FFFFFF); - end = rom + 0x01FFFFFF; + start = g_rom + (SearchStart & 0x01FFFFFF); + end = g_rom + 0x01FFFFFF; break; }; default: @@ -1698,8 +1698,8 @@ void debuggerDoSearch() unsigned int AddressToGBA(uint8_t* mem) { - if (mem >= &bios[0] && mem <= &bios[0x3fff]) - return 0x00000000 + (mem - &bios[0]); + if (mem >= &g_bios[0] && mem <= &g_bios[0x3fff]) + return 0x00000000 + (mem - &g_bios[0]); else if (mem >= &g_workRAM[0] && mem <= &g_workRAM[0x3ffff]) return 0x02000000 + (mem - &g_workRAM[0]); else if (mem >= &g_internalRAM[0] && mem <= &g_internalRAM[0x7fff]) @@ -1712,8 +1712,8 @@ unsigned int AddressToGBA(uint8_t* mem) return 0x06000000 + (mem - &g_vram[0]); else if (mem >= &g_oam[0] && mem <= &g_oam[0x3ff]) return 0x07000000 + (mem - &g_oam[0]); - else if (mem >= &rom[0] && mem <= &rom[0x1ffffff]) - return 0x08000000 + (mem - &rom[0]); + else if (mem >= &g_rom[0] && mem <= &g_rom[0x1ffffff]) + return 0x08000000 + (mem - &g_rom[0]); else return 0xFFFFFFFF; }; diff --git a/src/sdl/expr.cpp b/src/sdl/expr.cpp index 0b8cc978..6183a557 100644 --- a/src/sdl/expr.cpp +++ b/src/sdl/expr.cpp @@ -90,8 +90,6 @@ enum yytokentype { #include #include -#include "../System.h" -#include "../gba/elf.h" #include "exprNode.h" extern int yyerror(const char*); diff --git a/src/sdl/expr.ypp b/src/sdl/expr.ypp index 7ab99e8a..25034ad6 100644 --- a/src/sdl/expr.ypp +++ b/src/sdl/expr.ypp @@ -4,7 +4,7 @@ #include #include -#include "../System.h" +#include "core/base/system.h" #include "../gba/elf.h" #include "exprNode.h" diff --git a/src/sdl/exprNode.h b/src/sdl/exprNode.h index 89be8289..394042df 100644 --- a/src/sdl/exprNode.h +++ b/src/sdl/exprNode.h @@ -17,6 +17,8 @@ // along with this program; if not, write to the Free Software Foundation, // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +#include "../gba/elf.h" + struct Node { Type* type; uint32_t location; diff --git a/src/sdl/text.cpp b/src/sdl/text.cpp index d5481cd7..3d7e45a7 100644 --- a/src/sdl/text.cpp +++ b/src/sdl/text.cpp @@ -20,7 +20,7 @@ /* Code originally from fceu/drawing.h file, adapted by Forgotten */ -#include "../System.h" +#include "core/base/system.h" extern int RGB_LOW_BITS_MASK; diff --git a/src/wx/config/internal/option-internal.cpp b/src/wx/config/internal/option-internal.cpp index 125ccd9f..957ea3f5 100644 --- a/src/wx/config/internal/option-internal.cpp +++ b/src/wx/config/internal/option-internal.cpp @@ -10,7 +10,7 @@ #include #include -#include "../System.h" +#include "core/base/system.h" #include "../gba/Sound.h" #include "../gb/gbGlobals.h" #include "opts.h" diff --git a/src/wx/dsound.cpp b/src/wx/dsound.cpp index dbe45f14..347b265e 100644 --- a/src/wx/dsound.cpp +++ b/src/wx/dsound.cpp @@ -2,9 +2,8 @@ #include "wxvbam.h" // Internals -#include "../System.h" -#include "../common/SoundDriver.h" -#include "../gba/GBA.h" +#include "core/base/sound_driver.h" +#include "core/base/system.h" #include "../gba/Globals.h" #include "../gba/Sound.h" diff --git a/src/wx/faudio.cpp b/src/wx/faudio.cpp index a49bec67..f34fee82 100644 --- a/src/wx/faudio.cpp +++ b/src/wx/faudio.cpp @@ -5,7 +5,7 @@ #include // Interface -#include "../common/SoundDriver.h" +#include "core/base/sound_driver.h" // FAudio #include @@ -16,7 +16,7 @@ #include // Internals -#include "../System.h" // for systemMessage() +#include "core/base/system.h" // for systemMessage() #include "../gba/Globals.h" int GetFADevices(FAudio* fa, wxArrayString* names, wxArrayString* ids, diff --git a/src/wx/gfxviewers.cpp b/src/wx/gfxviewers.cpp index d9630254..103fca1b 100644 --- a/src/wx/gfxviewers.cpp +++ b/src/wx/gfxviewers.cpp @@ -9,6 +9,63 @@ #include "viewsupt.h" #include "wxvbam.h" +namespace { +void utilReadScreenPixels(uint8_t* dest, int w, int h) { + uint8_t* b = dest; + int sizeX = w; + int sizeY = h; + switch (systemColorDepth) { + case 16: { + uint16_t* p = (uint16_t*)(g_pix + (w + 2) * 2); // skip first black line + for (int y = 0; y < sizeY; y++) { + for (int x = 0; x < sizeX; x++) { + uint16_t v = *p++; + + *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R + *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G + *b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B + } + p++; // skip black pixel for filters + p++; // skip black pixel for filters + } + } break; + case 24: { + uint8_t* pixU8 = (uint8_t*)g_pix; + for (int y = 0; y < sizeY; y++) { + for (int x = 0; x < sizeX; x++) { + if (systemRedShift < systemBlueShift) { + *b++ = *pixU8++; // R + *b++ = *pixU8++; // G + *b++ = *pixU8++; // B + } else { + uint8_t blue = *pixU8++; + uint8_t green = *pixU8++; + uint8_t red = *pixU8++; + + *b++ = red; + *b++ = green; + *b++ = blue; + } + } + } + } break; + case 32: { + uint32_t* pixU32 = (uint32_t*)(g_pix + 4 * (w + 1)); + for (int y = 0; y < sizeY; y++) { + for (int x = 0; x < sizeX; x++) { + uint32_t v = *pixU32++; + *b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B + *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G + *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R + } + pixU32++; + } + } break; + } +} + +} // namespace + // FIXME: many of these read e.g. palette data directly without regard to // byte order. Need to determine where things are stored in emulated machine // order and where in native order, and swap the latter on big-endian diff --git a/src/wx/guiinit.cpp b/src/wx/guiinit.cpp index daaae316..175d5b27 100644 --- a/src/wx/guiinit.cpp +++ b/src/wx/guiinit.cpp @@ -8,7 +8,6 @@ #include "wxvbam.h" #include -#include #include #include @@ -33,11 +32,10 @@ #include #include +#include "../Util.h" #include "../gba/CheatSearch.h" -#include "config/game-control.h" #include "config/option-proxy.h" #include "config/option.h" -#include "config/user-input.h" #include "dialogs/accel-config.h" #include "dialogs/directories-config.h" #include "dialogs/display-config.h" @@ -46,7 +44,6 @@ #include "dialogs/joypad-config.h" #include "opts.h" #include "widgets/option-validator.h" -#include "widgets/user-input-ctrl.h" #include "wxhead.h" #if defined(__WXGTK__) diff --git a/src/wx/openal.cpp b/src/wx/openal.cpp index c03ef4f5..b220ba4f 100644 --- a/src/wx/openal.cpp +++ b/src/wx/openal.cpp @@ -8,7 +8,7 @@ #include "wxvbam.h" // Interface -#include "../common/SoundDriver.h" +#include "core/base/sound_driver.h" // OpenAL #include "openal.h" diff --git a/src/wx/panel.cpp b/src/wx/panel.cpp index 0f0cc228..f780adc9 100644 --- a/src/wx/panel.cpp +++ b/src/wx/panel.cpp @@ -21,6 +21,8 @@ #include #include +#include "../Util.h" +#include "core/base/file_util.h" #include "core/base/patch.h" #include "core/base/version.h" #include "../gb/gbPrinter.h" diff --git a/src/wx/sys.cpp b/src/wx/sys.cpp index 35458879..4e975519 100644 --- a/src/wx/sys.cpp +++ b/src/wx/sys.cpp @@ -6,6 +6,7 @@ #include #include +#include "core/base/image_util.h" #include "../common/SoundSDL.h" #include "config/game-control.h" #include "config/option-proxy.h" diff --git a/src/wx/wxvbam.cpp b/src/wx/wxvbam.cpp index 3c6c7307..afe1f582 100644 --- a/src/wx/wxvbam.cpp +++ b/src/wx/wxvbam.cpp @@ -37,6 +37,7 @@ // The built-in vba-over.ini #include "builtin-over.h" +#include "../Util.h" #include "config/game-control.h" #include "config/option-proxy.h" #include "config/option.h" @@ -45,7 +46,6 @@ #include "wayland.h" #include "widgets/group-check-box.h" #include "widgets/user-input-ctrl.h" -#include "wxhead.h" #ifdef __WXGTK__ #include diff --git a/src/wx/xaudio2.cpp b/src/wx/xaudio2.cpp index 3aa3dbcd..b0293eef 100644 --- a/src/wx/xaudio2.cpp +++ b/src/wx/xaudio2.cpp @@ -5,7 +5,7 @@ #include // Interface -#include "../common/SoundDriver.h" +#include "core/base/sound_driver.h" // XAudio2 #if _MSC_VER @@ -20,7 +20,7 @@ #include // Internals -#include "../System.h" // for systemMessage() +#include "core/base/system.h" // for systemMessage() #include "../gba/Globals.h" int GetXA2Devices(IXAudio2* xa, wxArrayString* names, wxArrayString* ids, diff --git a/third_party/include/stb/CMakeLists.txt b/third_party/include/stb/CMakeLists.txt new file mode 100644 index 00000000..e3587e24 --- /dev/null +++ b/third_party/include/stb/CMakeLists.txt @@ -0,0 +1,9 @@ +# Defines the `STB_INCLUDE_DIR` variable and `stb-image` target. + +# STB Image library dependency (header-only). +set(STB_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR} PARENT_SCOPE) +add_library(stb-image INTERFACE) +target_sources(stb-image + INTERFACE + stb_image_write.h +)