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