diff --git a/README.md b/README.md index 4f7b4ca..f3212cb 100644 --- a/README.md +++ b/README.md @@ -44,12 +44,13 @@ Settings are stored in `/3ds/open_agb_firm/config.ini`. ### General General settings. -`u8 backlight` - Backlight brightness +`u8 backlight` - Backlight brightness in luminance (cd/m²) * Default: `64` * Possible values: * Old 3DS: `20`-`117` * New 3DS: `16`-`142` * Values ≤`64` are recommended. +* Hardware calibration from your CTRNAND is required to get the correct brightness for both LCDs. `u8 backlightSteps` - How much to adjust backlight brightness by * Default: `5` diff --git a/arm11/Makefile b/arm11/Makefile index 64f6cde..93f88b8 100644 --- a/arm11/Makefile +++ b/arm11/Makefile @@ -22,7 +22,7 @@ BUILD := build SOURCES += ../source ../source/arm11 ../libraries/inih DATA := INCLUDES += ../include ../libraries -DEFINES := -DARM11 -D__3DS__ -DLIBN3DS_LEGACY=1 -DVERS_STRING=\"$(VERS_STRING)\" \ +DEFINES := -D__ARM11__ -D__3DS__ -DLIBN3DS_LEGACY=1 -DVERS_STRING=\"$(VERS_STRING)\" \ -DVERS_MAJOR=$(VERS_MAJOR) -DVERS_MINOR=$(VERS_MINOR) ASSETS := @@ -35,11 +35,11 @@ endif #--------------------------------------------------------------------------------- ARCH := -march=armv6k+vfpv2 -mtune=mpcore -mfloat-abi=hard -mtp=soft -marm -mthumb-interwork -masm-syntax-unified -CFLAGS := $(ARCH) -std=c17 -O2 -gdwarf-4 -flto -mword-relocations \ +CFLAGS := $(ARCH) -std=c2x -O2 -gdwarf-4 -flto -mword-relocations \ -ffunction-sections -fno-math-errno -Wall -Wextra CFLAGS += $(INCLUDE) $(DEFINES) -CXXFLAGS := $(ARCH) -std=c++17 -O2 -gdwarf-4 -flto -fno-rtti -fno-exceptions \ +CXXFLAGS := $(ARCH) -std=c++23 -O2 -gdwarf-4 -flto -fno-rtti -fno-exceptions \ -mword-relocations -ffunction-sections -fno-math-errno -Wall -Wextra CXXFLAGS += $(INCLUDE) $(DEFINES) diff --git a/arm9/Makefile b/arm9/Makefile index 3a2a67b..93b1441 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -21,8 +21,8 @@ include $(TOPDIR)/../libraries/libn3ds/libn3ds9.mk BUILD := build SOURCES += ../source/arm9 DATA := -INCLUDES += ../include ../thirdparty -DEFINES := -DARM9 -D__3DS__ -DLIBN3DS_LEGACY=1 -DVERS_STRING=\"$(VERS_STRING)\" \ +INCLUDES += ../include +DEFINES := -D__ARM9__ -D__3DS__ -DLIBN3DS_LEGACY=1 -DVERS_STRING=\"$(VERS_STRING)\" \ -DVERS_MAJOR=$(VERS_MAJOR) -DVERS_MINOR=$(VERS_MINOR) ifneq ($(strip $(NO_DEBUG)),) @@ -34,11 +34,11 @@ endif #--------------------------------------------------------------------------------- ARCH := -march=armv5te -mtune=arm946e-s -mfloat-abi=soft -mtp=soft -marm -mthumb-interwork -masm-syntax-unified -CFLAGS := $(ARCH) -std=c17 -O2 -gdwarf-4 -flto -mword-relocations \ +CFLAGS := $(ARCH) -std=c2x -O2 -gdwarf-4 -flto -mword-relocations \ -ffunction-sections -Wall -Wextra CFLAGS += $(INCLUDE) $(DEFINES) -CXXFLAGS := $(ARCH) -std=c++17 -O2 -gdwarf-4 -flto -fno-rtti -fno-exceptions \ +CXXFLAGS := $(ARCH) -std=c++23 -O2 -gdwarf-4 -flto -fno-rtti -fno-exceptions \ -mword-relocations -ffunction-sections -Wall -Wextra CXXFLAGS += $(INCLUDE) $(DEFINES) diff --git a/include/arm11/bitmap.h b/include/arm11/bitmap.h new file mode 100644 index 0000000..db8eb1a --- /dev/null +++ b/include/arm11/bitmap.h @@ -0,0 +1,87 @@ +#pragma once + +/* + * This file is part of open_agb_firm + * Copyright (C) 2024 profi200 + * + * 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 3 of the License, 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, see . + */ + +#include "types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct +{ + u16 magic; // "BM" + u32 fileSize; + u16 reserved; + u16 reserved2; + u32 pixelOffset; // From file start. +} PACKED BmpHeader; +static_assert(sizeof(BmpHeader) == 14); + +/*typedef enum +{ + BI_RGB = 0x0000, + BI_RLE8 = 0x0001, + BI_RLE4 = 0x0002, + BI_BITFIELDS = 0x0003, + BI_JPEG = 0x0004, + BI_PNG = 0x0005, + BI_CMYK = 0x000B, + BI_CMYKRLE8 = 0x000C, + BI_CMYKRLE4 = 0x000D +} Compression;*/ + +typedef struct +{ + u32 headerSize; // Size of this header. 40 bytes. + s32 width; + s32 height; // If >=0, pixel lines are in order bottom to top. Otherwise top to bottom. + u16 colorPlanes; // Must be 1. + u16 bitsPerPixel; // 1, 4, 8, 16, 24, 32. + u32 compression; + u32 imageSize; // Can be 0 if compression is 0. + s32 xPixelsPerMeter; + s32 yPixelsPerMeter; + u32 colorsUsed; + u32 colorsImportant; +} PACKED Bitmapinfoheader; +static_assert(sizeof(Bitmapinfoheader) == 0x28); + +typedef struct +{ + BmpHeader header; + Bitmapinfoheader dib; + u32 rMask; // Optional. + u32 gMask; // Optional. + u32 bMask; // Optional. +} PACKED BmpV1WithMasks; +static_assert(sizeof(BmpV1WithMasks) == 0x42); + +typedef struct +{ + BmpHeader header; + Bitmapinfoheader dib; +} PACKED BmpV1; +static_assert(sizeof(BmpV1) == 0x36); + +#ifdef __cplusplus +} // extern "C" +#endif \ No newline at end of file diff --git a/include/arm11/config.h b/include/arm11/config.h index e1d5c6a..4bc379b 100644 --- a/include/arm11/config.h +++ b/include/arm11/config.h @@ -22,6 +22,11 @@ #include "oaf_error_codes.h" +#ifdef __cplusplus +extern "C" +{ +#endif + typedef struct { // [general] @@ -58,3 +63,7 @@ typedef struct Result parseOafConfig(const char *const path, OafConfig *const cfg, const bool newCfgOnError); + +#ifdef __cplusplus +} // extern "C" +#endif \ No newline at end of file diff --git a/include/arm11/filebrowser.h b/include/arm11/filebrowser.h index 7485675..b121aea 100644 --- a/include/arm11/filebrowser.h +++ b/include/arm11/filebrowser.h @@ -22,4 +22,13 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + Result browseFiles(const char *const basePath, char selected[512]); + +#ifdef __cplusplus +} // extern "C" +#endif \ No newline at end of file diff --git a/include/arm11/gpu_cmd_lists.h b/include/arm11/gpu_cmd_lists.h index 6aea6d9..168c9ce 100644 --- a/include/arm11/gpu_cmd_lists.h +++ b/include/arm11/gpu_cmd_lists.h @@ -21,6 +21,11 @@ #include "types.h" +#ifdef __cplusplus +extern "C" +{ +#endif + #define GPU_RENDER_BUF_ADDR (0x18180000) #define GBA_INIT_LIST_SIZE (1136) #define GBA_LIST2_SIZE (448) @@ -32,3 +37,7 @@ extern u8 gbaGpuList2[GBA_LIST2_SIZE]; void patchGbaGpuCmdList(u8 scaleType); + +#ifdef __cplusplus +} // extern "C" +#endif \ No newline at end of file diff --git a/include/arm11/open_agb_firm.h b/include/arm11/open_agb_firm.h index e74de71..653a3e7 100644 --- a/include/arm11/open_agb_firm.h +++ b/include/arm11/open_agb_firm.h @@ -22,8 +22,17 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + Result oafParseConfigEarly(void); void changeBacklight(s16 amount); Result oafInitAndRun(void); void oafUpdate(void); -void oafFinish(void); \ No newline at end of file +void oafFinish(void); + +#ifdef __cplusplus +} // extern "C" +#endif \ No newline at end of file diff --git a/include/arm11/patch.h b/include/arm11/patch.h index efb6b19..8e8a6b3 100644 --- a/include/arm11/patch.h +++ b/include/arm11/patch.h @@ -18,4 +18,15 @@ * along with this program. If not, see . */ -Result patchRom(const char *const gamePath, u32 *romSize); \ No newline at end of file + + +#ifdef __cplusplus +extern "C" +{ +#endif + +Result patchRom(const char *const gamePath, u32 *romSize); + +#ifdef __cplusplus +} // extern "C" +#endif \ No newline at end of file diff --git a/include/arm11/save_type.h b/include/arm11/save_type.h index e43bff1..1f5de20 100644 --- a/include/arm11/save_type.h +++ b/include/arm11/save_type.h @@ -23,6 +23,11 @@ #include "arm11/config.h" +#ifdef __cplusplus +extern "C" +{ +#endif + typedef struct { u8 sha1[20]; @@ -34,4 +39,8 @@ static_assert(sizeof(GbaDbEntry) == 28, "Error: GBA DB entry struct is not packe u16 detectSaveType(const u32 romSize, const u16 defaultSave); -u16 getSaveType(const OafConfig *const cfg, const u32 romSize, const char *const savePath); \ No newline at end of file +u16 getSaveType(const OafConfig *const cfg, const u32 romSize, const char *const savePath); + +#ifdef __cplusplus +} // extern "C" +#endif \ No newline at end of file diff --git a/include/oaf_error_codes.h b/include/oaf_error_codes.h index 5f42273..7454cf0 100644 --- a/include/oaf_error_codes.h +++ b/include/oaf_error_codes.h @@ -21,6 +21,11 @@ #include "error_codes.h" +#ifdef __cplusplus +extern "C" +{ +#endif + #define MAKE_CUSTOM_ERR(e) (CUSTOM_ERR_OFFSET + (e)) // Keep errors in the range of 0-CUSTOM_ERR_OFFSET - 1. @@ -38,7 +43,11 @@ enum const char* oafResult2String(Result res); -#ifdef ARM11 +#ifdef __ARM11__ void printError(Result res); void printErrorWaitInput(Result res, u32 waitKeys); -#endif // ifdef ARM11 +#endif // ifdef __ARM11__ + +#ifdef __cplusplus +} // extern "C" +#endif \ No newline at end of file diff --git a/source/arm11/config.c b/source/arm11/config.c index c54e431..46d1143 100644 --- a/source/arm11/config.c +++ b/source/arm11/config.c @@ -165,4 +165,4 @@ Result parseOafConfig(const char *const path, OafConfig *const cfg, const bool n free(iniBuf); return res; -} +} \ No newline at end of file diff --git a/source/arm11/filebrowser.c b/source/arm11/filebrowser.c index d89619d..e977777 100644 --- a/source/arm11/filebrowser.c +++ b/source/arm11/filebrowser.c @@ -240,4 +240,4 @@ end: ee_printf("\x1b[2J"); return res; -} +} \ No newline at end of file diff --git a/source/arm11/gpu_cmd_lists.c b/source/arm11/gpu_cmd_lists.c index 6640075..5fd071d 100644 --- a/source/arm11/gpu_cmd_lists.c +++ b/source/arm11/gpu_cmd_lists.c @@ -72,7 +72,7 @@ alignas(16) u8 gbaGpuInitList[GBA_INIT_LIST_SIZE] = 0x18, 0x01, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x4F, 0x80, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, // Last 4 bytes: GPUREG_TEXUNIT0_PARAM. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, // Last 4 bytes: GPUREG_TEXUNIT0_TYPE. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x02, 0x00, 0x00, 0x00, // Last 4 bytes: GPUREG_TEXUNIT0_TYPE. 0x8E, 0x00, 0x0F, 0x00, 0x01, 0x10, 0x01, 0x00, 0x80, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x07, 0x00, @@ -213,4 +213,4 @@ void patchGbaGpuCmdList(u8 scaleType) flushDCacheRange(gbaGpuInitList, sizeof(gbaGpuInitList)); flushDCacheRange(gbaGpuList2, sizeof(gbaGpuList2)); -} +} \ No newline at end of file diff --git a/source/arm11/main.c b/source/arm11/main.c index 6a9a4d2..8f1243d 100644 --- a/source/arm11/main.c +++ b/source/arm11/main.c @@ -30,11 +30,10 @@ int main(void) { - Result res = fMount(FS_DRIVE_SDMC); - if(res == RES_OK) res = oafParseConfigEarly(); - GFX_init(GFX_BGR8, GFX_RGB565); + Result res = oafParseConfigEarly(); + GFX_init(GFX_BGR8, GFX_R5G6B5, GFX_TOP_2D); changeBacklight(0); // Apply backlight config. - consoleInit(SCREEN_BOT, NULL); + consoleInit(GFX_LCD_BOT, NULL); //CODEC_init(); if(res == RES_OK && (res = oafInitAndRun()) == RES_OK) @@ -53,9 +52,9 @@ int main(void) CODEC_deinit(); GFX_deinit(); - fUnmount(FS_DRIVE_SDMC); + fUnmount(FS_DRIVE_SDMC); // TODO: Move elsewhere. __systemDeinit() already calls it. power_off(); return 0; -} +} \ No newline at end of file diff --git a/source/arm11/open_agb_firm.c b/source/arm11/open_agb_firm.c index 02b3e45..5034de8 100644 --- a/source/arm11/open_agb_firm.c +++ b/source/arm11/open_agb_firm.c @@ -29,8 +29,8 @@ #include "fs.h" #include "fsutil.h" #include "arm11/fmt.h" -#include "arm11/drivers/lcd.h" -#include "arm11/drivers/lgyfb.h" +#include "arm11/drivers/gx.h" +#include "arm11/drivers/lgycap.h" #include "drivers/gfx.h" #include "arm11/drivers/mcu.h" #include "kernel.h" @@ -41,10 +41,12 @@ #include "arm11/drivers/codec.h" #include "arm11/save_type.h" #include "arm11/patch.h" +#include "arm11/bitmap.h" -#define OAF_WORK_DIR "sdmc:/3ds/open_agb_firm" -#define OAF_SAVE_DIR "saves" // Relative to work dir. +#define OAF_WORK_DIR "sdmc:/3ds/open_agb_firm" +#define OAF_SAVE_DIR "saves" // Relative to work dir. +#define OAF_SCREENSHOT_DIR "screenshots" // Relative to work dir. @@ -164,6 +166,7 @@ static void adjustGammaTableForGba(void) const float contrast = g_oafConfig.contrast; const float brightness = g_oafConfig.brightness / contrast; const float contrastInTargetGamma = powf(contrast, targetGamma); + vu32 *const color_lut_data = &getGxRegs()->pdc0.color_lut_data; for(u32 i = 0; i < 256; i++) { // Adjust i with brightness and convert to target gamma. @@ -173,40 +176,79 @@ static void adjustGammaTableForGba(void) const u32 res = clamp_s32(lroundf(powf(contrastInTargetGamma * adjusted, lcdGamma) * 255), 0, 255); // Same adjustment for red/green/blue. - REG_LCD_PDC0_GTBL_FIFO = res<<16 | res<<8 | res; + *color_lut_data = res<<16 | res<<8 | res; } } static Result dumpFrameTex(void) { - // Stop LgyFb before dumping the frame to prevent glitches. - LGYFB_stop(); + // Stop LgyCap before dumping the frame to prevent glitches. + LGYCAP_stop(LGYCAP_DEV_TOP); - // 512x-512 (hight negative to flip vertically). - // Pixels at offset 0x40. - alignas(4) static const u8 bmpHeader[54] = + // A1BGR5 format (alpha ignored). + constexpr u32 alignment = 0x80; // Make PPF happy. + alignas(4) static BmpV1WithMasks bmpHeaders = { - 0x42, 0x4D, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x28, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xFE, - 0xFF, 0xFF, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x13, 0x0B, - 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + { + .magic = 0x4D42, + .fileSize = alignment + 240 * 160 * 2, + .reserved = 0, + .reserved2 = 0, + .pixelOffset = alignment + }, + { + .headerSize = sizeof(Bitmapinfoheader), + .width = 240, + .height = -160, + .colorPlanes = 1, + .bitsPerPixel = 16, + .compression = 3, // Bitfields. + .imageSize = 240 * 160 * 2, + .xPixelsPerMeter = 0, + .yPixelsPerMeter = 0, + .colorsUsed = 0, + .colorsImportant = 0 + }, + .rMask = 0xF800, + .gMask = 0x07C0, + .bMask = 0x003E }; - GX_displayTransfer((u32*)0x18200000, 240u<<16 | 512, (u32*)0x18400040, 240u<<16 | 512, 1u<<12 | 1u<<8); + u32 outDim = PPF_DIM(240, 160); + u32 fileSize = alignment + 240 * 160 * 2; + if(g_oafConfig.scaler > 1) + { + outDim = PPF_DIM(360, 240); + fileSize = alignment + 360 * 240 * 2; + + bmpHeaders.header.fileSize = fileSize; + bmpHeaders.dib.width = 360; + bmpHeaders.dib.height = -240; + bmpHeaders.dib.imageSize = 360 * 240 * 2; + } + + // Transfer frame data out of the 512x512 texture. + // We will use the currently hidden frame buffer as temporary buffer. + // Note: This is a race with the currently displaying frame buffer + // because we just swapped buffers in the gfx handler function. + u32 *const tmpBuf = GFX_getBuffer(GFX_LCD_TOP, GFX_SIDE_LEFT); + GX_displayTransfer((u32*)0x18200000, PPF_DIM(512, 240), tmpBuf + (alignment / 4), outDim, + PPF_O_FMT(GX_RGB5A1) | PPF_I_FMT(GX_RGB5A1) | PPF_CROP_EN); + memcpy(tmpBuf, &bmpHeaders, sizeof(bmpHeaders)); GFX_waitForPPF(); - memcpy((void*)0x18400000, bmpHeader, sizeof(bmpHeader)); + // Get current date & time. RtcTimeDate td; - char fn[32]; MCU_getRtcTimeDate(&td); - ee_sprintf(fn, "texture_dump_%04X%02X%02X%02X%02X%02X.bmp", td.y + 0x2000, td.mon, td.d, td.h, td.min, td.s); - const Result res = fsQuickWrite(fn, (void*)0x18400000, 0x40 + 512 * 512 * 3); - // Restart LgyFb. - LGYFB_start(); + // Construct file path from date & time. Then write the file. + char fn[36]; + ee_sprintf(fn, OAF_SCREENSHOT_DIR "/%04X_%02X_%02X_%02X_%02X_%02X.bmp", + td.y + 0x2000, td.mon, td.d, td.h, td.min, td.s); + const Result res = fsQuickWrite(fn, tmpBuf, fileSize); + + // Restart LgyCap. + LGYCAP_start(LGYCAP_DEV_TOP); return res; } @@ -220,10 +262,17 @@ static void gbaGfxHandler(void *args) if(waitForEvent(event) != KRES_OK) break; clearEvent(event); - // Rotate the frame using the GPU. - // 240x160 no scaling: 184 µs - // 240x160 bilinear x1.5: 408 µs - // 360x240 no scaling: 437 µs + // All measurements are the worst timings in ~30 seconds of runtime. + // Measured with timer prescaler 1. + // BGR8: + // 240x160 no scaling: ~184 µs + // 240x160 bilinear x1.5: ~408 µs + // 360x240 no scaling: ~437 µs + // + // A1BGR5: + // 240x160 no scaling: ~188 µs (25300 ticks) + // 240x160 bilinear x1.5: ~407 µs (54619 ticks) + // 360x240 no scaling: ~400 µs (53725 ticks) static bool inited = false; u32 listSize; const u32 *list; @@ -241,9 +290,10 @@ static void gbaGfxHandler(void *args) } GX_processCommandList(listSize, list); GFX_waitForP3D(); - GX_displayTransfer((u32*)GPU_RENDER_BUF_ADDR, 400u<<16 | 240, GFX_getFramebuffer(SCREEN_TOP), 400u<<16 | 240, 1u<<12 | 1u<<8); + GX_displayTransfer((u32*)GPU_RENDER_BUF_ADDR, PPF_DIM(240, 400), GFX_getBuffer(GFX_LCD_TOP, GFX_SIDE_LEFT), + PPF_DIM(240, 400), PPF_O_FMT(GX_BGR8) | PPF_I_FMT(GX_BGR8)); GFX_waitForPPF(); - GFX_swapFramebufs(); + GFX_swapBuffers(); // Trigger only if both are held and at least one is detected as newly pressed down. if(hidKeysHeld() == (KEY_Y | KEY_SELECT) && hidKeysDown() != 0) @@ -272,7 +322,7 @@ void changeBacklight(s16 amount) newVal = (newVal < min ? min : newVal); g_oafConfig.backlight = (u8)newVal; - GFX_setBrightness((u8)newVal, (u8)newVal); + GFX_setLcdLuminance(newVal); } static void updateBacklight(void) @@ -292,23 +342,23 @@ static void updateBacklight(void) changeBacklight(-steps); // Disable backlight switching in debug builds on 2DS. - const GfxBlight lcd = (MCU_getSystemModel() != 3 ? GFX_BLIGHT_TOP : GFX_BLIGHT_BOT); + const GfxBl lcd = (MCU_getSystemModel() != SYS_MODEL_2DS ? GFX_BL_TOP : GFX_BL_BOT); #ifndef NDEBUG - if(lcd != GFX_BLIGHT_BOT) + if(lcd != GFX_BL_BOT) #endif { // Turn off backlight. if(backlightOn && kHeld == (KEY_X | KEY_DLEFT)) { backlightOn = false; - GFX_powerOffBacklights(lcd); + GFX_powerOffBacklight(lcd); } // Turn on backlight. if(!backlightOn && kHeld == (KEY_X | KEY_DRIGHT)) { backlightOn = true; - GFX_powerOnBacklights(lcd); + GFX_powerOnBacklight(lcd); } } } @@ -407,6 +457,10 @@ Result oafParseConfigEarly(void) res = fMkdir(OAF_SAVE_DIR); if(res != RES_OK && res != RES_FR_EXIST) break; + // Create screenshots folder. + res = fMkdir(OAF_SCREENSHOT_DIR); + if(res != RES_OK && res != RES_FR_EXIST) break; + // Parse the config. res = parseOafConfig("config.ini", &g_oafConfig, true); } while(0); @@ -436,31 +490,18 @@ KHandle setupFrameCapture(const u8 scaler) 0, 0, 0, 0, 0, 0, 0, 0 }; - ScalerCfg gbaCfg; + LgyCapCfg gbaCfg; + gbaCfg.cnt = LGYCAP_OUT_SWIZZLE | LGYCAP_ROT_NONE | LGYCAP_OUT_FMT_A1BGR5 | (is240x160 ? 0 : LGYCAP_HSCALE_EN | LGYCAP_VSCALE_EN); gbaCfg.w = (is240x160 ? 240 : 360); gbaCfg.h = (is240x160 ? 160 : 240); gbaCfg.vLen = 6; gbaCfg.vPatt = 0b00011011; memcpy(gbaCfg.vMatrix, matrix, 6 * 8 * 2); gbaCfg.hLen = 6; - gbaCfg.hPatt = (is240x160 ? 0b00111111 : 0b00011011); + gbaCfg.hPatt = 0b00011011; + memcpy(gbaCfg.hMatrix, &matrix[6 * 8], 6 * 8 * 2); - if(is240x160) - { - memset(gbaCfg.hMatrix, 0, 6 * 8 * 2); - s16 *const identityRow = &gbaCfg.hMatrix[3 * 8]; - for(unsigned i = 0; i < 6; i++) - { - // Set identity entries. - identityRow[i] = 0x4000; - } - } - else - { - memcpy(gbaCfg.hMatrix, &matrix[6 * 8], 6 * 8 * 2); - } - - return LGYFB_init(&gbaCfg); + return LGYCAP_init(LGYCAP_DEV_TOP, &gbaCfg); } Result oafInitAndRun(void) @@ -522,7 +563,8 @@ Result oafInitAndRun(void) // Force black and turn the backlight off on the bottom screen. // Don't turn the backlight off on 2DS (1 panel). GFX_setForceBlack(false, true); - if(MCU_getSystemModel() != 3) GFX_powerOffBacklights(GFX_BLIGHT_BOT); + if(MCU_getSystemModel() != SYS_MODEL_2DS) + GFX_powerOffBacklight(GFX_BL_BOT); #endif // Initialize frame capture and frame handler. @@ -543,16 +585,17 @@ Result oafInitAndRun(void) if(g_oafConfig.scaler == 0) // No borders for scaled modes. { // Abuse currently invisible frame buffer as temporary buffer. - void *const borderBuf = GFX_getFramebuffer(SCREEN_TOP); + void *const borderBuf = GFX_getBuffer(GFX_LCD_TOP, GFX_SIDE_LEFT); if(fsQuickRead("border.bgr", borderBuf, 400 * 240 * 3) == RES_OK) { // Copy border in swizzled form to GPU render buffer. - GX_displayTransfer(borderBuf, 400u<<16 | 240, (u32*)GPU_RENDER_BUF_ADDR, 400u<<16 | 240, 1u<<12 | 1u<<8 | 1u<<1); + GX_displayTransfer(borderBuf, PPF_DIM(240, 400), (u32*)GPU_RENDER_BUF_ADDR, + PPF_DIM(240, 400), PPF_O_FMT(GX_BGR8) | PPF_I_FMT(GX_BGR8) | PPF_OUT_TILED); GFX_waitForPPF(); } } - // Sync LgyFb start with LCD VBlank. + // Sync LgyCap start with LCD VBlank. GFX_waitForVBlank0(); LGY11_switchMode(); } @@ -586,7 +629,7 @@ void oafFinish(void) { // frameReadyEvent deleted by this function. // gbaGfxHandler() will automatically terminate. - LGYFB_deinit(); + LGYCAP_deinit(LGYCAP_DEV_TOP); g_frameReadyEvent = 0; LGY11_deinit(); -} +} \ No newline at end of file diff --git a/source/arm9/main.c b/source/arm9/main.c index 8f18ea2..73f1af7 100644 --- a/source/arm9/main.c +++ b/source/arm9/main.c @@ -27,4 +27,4 @@ int main(void) while(1) __wfi(); return 0; -} +} \ No newline at end of file diff --git a/source/oaf_error_codes.c b/source/oaf_error_codes.c index e62cb3e..6879b87 100644 --- a/source/oaf_error_codes.c +++ b/source/oaf_error_codes.c @@ -18,10 +18,10 @@ #include "oaf_error_codes.h" #include "drivers/gfx.h" -#ifdef ARM11 - #include "arm11/fmt.h" - #include "arm11/drivers/hid.h" -#endif +#ifdef __ARM11__ +#include "arm11/fmt.h" +#include "arm11/drivers/hid.h" +#endif // #ifdef __ARM11__ @@ -36,7 +36,7 @@ const char* oafResult2String(Result res) return (res < CUSTOM_ERR_OFFSET ? result2String(res) : oafResultStrings[res - CUSTOM_ERR_OFFSET]); } -#ifdef ARM11 +#ifdef __ARM11__ void printError(Result res) { ee_printf("Error: %s.\n", oafResult2String(res)); @@ -63,4 +63,4 @@ void printErrorWaitInput(Result res, u32 waitKeys) if(hidGetExtraKeys(0) & (KEY_POWER_HELD | KEY_POWER)) break; } } -#endif // ifdef ARM11 +#endif // ifdef __ARM11__ \ No newline at end of file