mirror of https://github.com/mgba-emu/mgba.git
3DS: Update to new API
This commit is contained in:
parent
631b287b3a
commit
e65d12d35e
|
@ -213,8 +213,9 @@ void GBAConfigDirectory(char* out, size_t outLength) {
|
|||
snprintf(out, outLength, "/%s", projectName);
|
||||
mkdir(out, 0777);
|
||||
#elif defined(_3DS)
|
||||
UNUSED(portable);
|
||||
snprintf(out, outLength, "/%s", projectName);
|
||||
FSUSER_CreateDirectory(0, sdmcArchive, FS_makePath(PATH_CHAR, out));
|
||||
FSUSER_CreateDirectory(sdmcArchive, fsMakePath(PATH_ASCII, out), 0);
|
||||
#else
|
||||
getcwd(out, outLength);
|
||||
strncat(out, PATH_SEP "portable.ini", outLength - strlen(out));
|
||||
|
|
|
@ -18,7 +18,7 @@ struct VFile3DS {
|
|||
|
||||
struct VDirEntry3DS {
|
||||
struct VDirEntry d;
|
||||
FS_dirent ent;
|
||||
FS_DirectoryEntry ent;
|
||||
char utf8Name[256];
|
||||
};
|
||||
|
||||
|
@ -49,14 +49,15 @@ static struct VDir* _vd3dOpenDir(struct VDir* vd, const char* path);
|
|||
static const char* _vd3deName(struct VDirEntry* vde);
|
||||
static enum VFSType _vd3deType(struct VDirEntry* vde);
|
||||
|
||||
struct VFile* VFileOpen3DS(FS_archive* archive, const char* path, int flags) {
|
||||
struct VFile* VFileOpen3DS(FS_Archive* archive, const char* path, int flags) {
|
||||
struct VFile3DS* vf3d = malloc(sizeof(struct VFile3DS));
|
||||
if (!vf3d) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
FS_path newPath = FS_makePath(PATH_CHAR, path);
|
||||
Result res = FSUSER_OpenFile(0, &vf3d->handle, *archive, newPath, flags, FS_ATTRIBUTE_NONE);
|
||||
// TODO: Use UTF-16
|
||||
FS_Path newPath = fsMakePath(PATH_ASCII, path);
|
||||
Result res = FSUSER_OpenFile(&vf3d->handle, *archive, newPath, flags, 0);
|
||||
if (res & 0xFFFC03FF) {
|
||||
free(vf3d);
|
||||
return 0;
|
||||
|
@ -175,8 +176,9 @@ struct VDir* VDirOpen(const char* path) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
FS_path newPath = FS_makePath(PATH_CHAR, path);
|
||||
Result res = FSUSER_OpenDirectory(0, &vd3d->handle, sdmcArchive, newPath);
|
||||
// TODO: Use UTF-16
|
||||
FS_Path newPath = fsMakePath(PATH_ASCII, path);
|
||||
Result res = FSUSER_OpenDirectory(&vd3d->handle, sdmcArchive, newPath);
|
||||
if (res & 0xFFFC03FF) {
|
||||
free(vd3d);
|
||||
return 0;
|
||||
|
@ -207,8 +209,9 @@ static bool _vd3dClose(struct VDir* vd) {
|
|||
static void _vd3dRewind(struct VDir* vd) {
|
||||
struct VDir3DS* vd3d = (struct VDir3DS*) vd;
|
||||
FSDIR_Close(vd3d->handle);
|
||||
FS_path newPath = FS_makePath(PATH_CHAR, vd3d->path);
|
||||
FSUSER_OpenDirectory(0, &vd3d->handle, sdmcArchive, newPath);
|
||||
// TODO: Use UTF-16
|
||||
FS_Path newPath = fsMakePath(PATH_ASCII, vd3d->path);
|
||||
FSUSER_OpenDirectory(&vd3d->handle, sdmcArchive, newPath);
|
||||
}
|
||||
|
||||
static struct VDirEntry* _vd3dListNext(struct VDir* vd) {
|
||||
|
@ -264,7 +267,7 @@ static const char* _vd3deName(struct VDirEntry* vde) {
|
|||
|
||||
static enum VFSType _vd3deType(struct VDirEntry* vde) {
|
||||
struct VDirEntry3DS* vd3de = (struct VDirEntry3DS*) vde;
|
||||
if (vd3de->ent.isDirectory) {
|
||||
if (vd3de->ent.attributes & FS_ATTRIBUTE_DIRECTORY) {
|
||||
return VFS_DIRECTORY;
|
||||
}
|
||||
return VFS_FILE;
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
#include <3ds.h>
|
||||
|
||||
extern FS_archive sdmcArchive;
|
||||
extern FS_Archive sdmcArchive;
|
||||
|
||||
struct VFile* VFileOpen3DS(FS_archive* archive, const char* path, int flags);
|
||||
struct VFile* VFileOpen3DS(FS_Archive* archive, const char* path, int flags);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <3ds.h>
|
||||
#include <3ds/gpu/gpu.h>
|
||||
#include <3ds/gpu/gx.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
@ -42,57 +44,12 @@ static int pendingEvents = 0;
|
|||
|
||||
static const struct ctrTexture* activeTexture = NULL;
|
||||
|
||||
static u32 _f24FromFloat(float f) {
|
||||
u32 i;
|
||||
memcpy(&i, &f, 4);
|
||||
|
||||
u32 mantissa = (i << 9) >> 9;
|
||||
s32 exponent = (i << 1) >> 24;
|
||||
u32 sign = (i << 0) >> 31;
|
||||
|
||||
// Truncate mantissa
|
||||
mantissa >>= 7;
|
||||
|
||||
// Re-bias exponent
|
||||
exponent = exponent - 127 + 63;
|
||||
if (exponent < 0) {
|
||||
// Underflow: flush to zero
|
||||
return sign << 23;
|
||||
} else if (exponent > 0x7F) {
|
||||
// Overflow: saturate to infinity
|
||||
return sign << 23 | 0x7F << 16;
|
||||
}
|
||||
|
||||
return sign << 23 | exponent << 16 | mantissa;
|
||||
}
|
||||
|
||||
static u32 _f31FromFloat(float f) {
|
||||
u32 i;
|
||||
memcpy(&i, &f, 4);
|
||||
|
||||
u32 mantissa = (i << 9) >> 9;
|
||||
s32 exponent = (i << 1) >> 24;
|
||||
u32 sign = (i << 0) >> 31;
|
||||
|
||||
// Re-bias exponent
|
||||
exponent = exponent - 127 + 63;
|
||||
if (exponent < 0) {
|
||||
// Underflow: flush to zero
|
||||
return sign << 30;
|
||||
} else if (exponent > 0x7F) {
|
||||
// Overflow: saturate to infinity
|
||||
return sign << 30 | 0x7F << 23;
|
||||
}
|
||||
|
||||
return sign << 30 | exponent << 23 | mantissa;
|
||||
}
|
||||
|
||||
void ctrClearPending(int events) {
|
||||
int toClear = events & pendingEvents;
|
||||
if (toClear & (1 << GSPEVENT_PSC0)) {
|
||||
if (toClear & (1 << GSPGPU_EVENT_PSC0)) {
|
||||
gspWaitForPSC0();
|
||||
}
|
||||
if (toClear & (1 << GSPEVENT_PPF)) {
|
||||
if (toClear & (1 << GSPGPU_EVENT_PPF)) {
|
||||
gspWaitForPPF();
|
||||
}
|
||||
pendingEvents ^= toClear;
|
||||
|
@ -103,39 +60,39 @@ static void _GPU_SetFramebuffer(intptr_t colorBuffer, intptr_t depthBuffer, u16
|
|||
u32 buf[4];
|
||||
|
||||
// Unknown
|
||||
GPUCMD_AddWrite(GPUREG_0111, 0x00000001);
|
||||
GPUCMD_AddWrite(GPUREG_0110, 0x00000001);
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_FLUSH, 0x00000001);
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_INVALIDATE, 0x00000001);
|
||||
|
||||
// Set depth/color buffer address and dimensions
|
||||
buf[0] = depthBuffer >> 3;
|
||||
buf[1] = colorBuffer >> 3;
|
||||
buf[2] = (0x01) << 24 | ((h-1) & 0xFFF) << 12 | (w & 0xFFF) << 0;
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_DEPTHBUFFER_LOC, buf, 3);
|
||||
GPUCMD_AddWrite(GPUREG_006E, buf[2]);
|
||||
GPUCMD_AddWrite(GPUREG_RENDERBUF_DIM, buf[2]);
|
||||
|
||||
// Set depth/color buffer pixel format
|
||||
GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_FORMAT, 3 /* D248S */ );
|
||||
GPUCMD_AddWrite(GPUREG_COLORBUFFER_FORMAT, 0 /* RGBA8 */ << 16 | 2 /* Unknown */);
|
||||
GPUCMD_AddWrite(GPUREG_011B, 0); // Unknown
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_BLOCK32, 0); // Unknown
|
||||
|
||||
// Enable color/depth buffers
|
||||
buf[0] = colorBuffer != 0 ? 0xF : 0x0;
|
||||
buf[1] = buf[0];
|
||||
buf[2] = depthBuffer != 0 ? 0x2 : 0x0;
|
||||
buf[3] = buf[2];
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_0112, buf, 4);
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_COLORBUFFER_READ, buf, 4);
|
||||
}
|
||||
|
||||
static void _GPU_SetViewportEx(u16 x, u16 y, u16 w, u16 h) {
|
||||
u32 buf[4];
|
||||
|
||||
buf[0] = _f24FromFloat(w / 2.0f);
|
||||
buf[1] = _f31FromFloat(2.0f / w) << 1;
|
||||
buf[2] = _f24FromFloat(h / 2.0f);
|
||||
buf[3] = _f31FromFloat(2.0f / h) << 1;
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_0041, buf, 4);
|
||||
buf[0] = f32tof24(w / 2.0f);
|
||||
buf[1] = f32tof31(2.0f / w) << 1;
|
||||
buf[2] = f32tof24(h / 2.0f);
|
||||
buf[3] = f32tof31(2.0f / h) << 1;
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_VIEWPORT_WIDTH, buf, 4);
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_0068, (y & 0xFFFF) << 16 | (x & 0xFFFF) << 0);
|
||||
GPUCMD_AddWrite(GPUREG_VIEWPORT_XY, (y & 0xFFFF) << 16 | (x & 0xFFFF) << 0);
|
||||
|
||||
buf[0] = 0;
|
||||
buf[1] = 0;
|
||||
|
@ -259,7 +216,7 @@ void ctrGpuBeginFrame(int screen) {
|
|||
fw = 320;
|
||||
}
|
||||
|
||||
_GPU_SetFramebuffer(osConvertVirtToPhys((u32)gpuColorBuffer[screen]), 0, 240, fw);
|
||||
_GPU_SetFramebuffer(osConvertVirtToPhys(gpuColorBuffer[screen]), 0, 240, fw);
|
||||
}
|
||||
|
||||
void ctrGpuBeginDrawing(void) {
|
||||
|
@ -282,8 +239,8 @@ void ctrGpuBeginDrawing(void) {
|
|||
GPU_SetAlphaTest(false, GPU_ALWAYS, 0);
|
||||
|
||||
// Unknown
|
||||
GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0);
|
||||
GPUCMD_AddWrite(GPUREG_0118, 0);
|
||||
GPUCMD_AddMaskedWrite(GPUREG_EARLYDEPTH_TEST1, 0x1, 0);
|
||||
GPUCMD_AddWrite(GPUREG_EARLYDEPTH_TEST2, 0);
|
||||
|
||||
GPU_SetTexEnv(0,
|
||||
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0), // RGB
|
||||
|
@ -299,7 +256,7 @@ void ctrGpuBeginDrawing(void) {
|
|||
_setDummyTexEnv(5);
|
||||
|
||||
// Configure vertex attribute format
|
||||
u32 bufferOffsets[] = { osConvertVirtToPhys((u32)ctrVertexBuffer) - VRAM_BASE };
|
||||
u32 bufferOffsets[] = { osConvertVirtToPhys(ctrVertexBuffer) - VRAM_BASE };
|
||||
u64 arrayTargetAttributes[] = { 0x210 };
|
||||
u8 numAttributesInArray[] = { 3 };
|
||||
GPU_SetAttributeBuffers(
|
||||
|
@ -332,29 +289,29 @@ void ctrGpuEndFrame(int screen, void* outputFramebuffer, int w, int h) {
|
|||
|
||||
const u32 GX_CROP_INPUT_LINES = (1 << 2);
|
||||
|
||||
ctrClearPending(1 << GSPEVENT_PSC0);
|
||||
ctrClearPending(1 << GSPEVENT_PPF);
|
||||
ctrClearPending(1 << GSPGPU_EVENT_PSC0);
|
||||
ctrClearPending(1 << GSPGPU_EVENT_PPF);
|
||||
|
||||
GX_SetDisplayTransfer(NULL,
|
||||
GX_DisplayTransfer(
|
||||
colorBuffer, GX_BUFFER_DIM(240, fw),
|
||||
outputFramebuffer, GX_BUFFER_DIM(h, w),
|
||||
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) |
|
||||
GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) |
|
||||
GX_CROP_INPUT_LINES);
|
||||
pendingEvents |= (1 << GSPEVENT_PPF);
|
||||
pendingEvents |= (1 << GSPGPU_EVENT_PPF);
|
||||
}
|
||||
|
||||
void ctrGpuEndDrawing(void) {
|
||||
ctrClearPending(1 << GSPEVENT_PPF);
|
||||
ctrClearPending(1 << GSPGPU_EVENT_PPF);
|
||||
gfxSwapBuffersGpu();
|
||||
gspWaitForEvent(GSPEVENT_VBlank0, false);
|
||||
gspWaitForEvent(GSPGPU_EVENT_VBlank0, false);
|
||||
|
||||
void* gpuColorBuffer0End = (char*)gpuColorBuffer[0] + 240 * 400 * 4;
|
||||
void* gpuColorBuffer1End = (char*)gpuColorBuffer[1] + 240 * 320 * 4;
|
||||
GX_SetMemoryFill(NULL,
|
||||
GX_MemoryFill(
|
||||
gpuColorBuffer[0], 0x00000000, gpuColorBuffer0End, GX_FILL_32BIT_DEPTH | GX_FILL_TRIGGER,
|
||||
gpuColorBuffer[1], 0x00000000, gpuColorBuffer1End, GX_FILL_32BIT_DEPTH | GX_FILL_TRIGGER);
|
||||
pendingEvents |= 1 << GSPEVENT_PSC0;
|
||||
pendingEvents |= 1 << GSPGPU_EVENT_PSC0;
|
||||
}
|
||||
|
||||
void ctrSetViewportSize(s16 w, s16 h) {
|
||||
|
@ -382,7 +339,7 @@ void ctrActivateTexture(const struct ctrTexture* texture) {
|
|||
|
||||
GPU_SetTextureEnable(GPU_TEXUNIT0);
|
||||
GPU_SetTexture(
|
||||
GPU_TEXUNIT0, (u32*)osConvertVirtToPhys((u32)texture->data),
|
||||
GPU_TEXUNIT0, (u32*)osConvertVirtToPhys(texture->data),
|
||||
texture->width, texture->height,
|
||||
GPU_TEXTURE_MAG_FILTER(texture->filter) | GPU_TEXTURE_MIN_FILTER(texture->filter) |
|
||||
GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_BORDER) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_BORDER),
|
||||
|
@ -444,15 +401,15 @@ void ctrFlushBatch(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
ctrClearPending((1 << GSPEVENT_PSC0));
|
||||
ctrClearPending((1 << GSPGPU_EVENT_PSC0));
|
||||
|
||||
GSPGPU_FlushDataCache(NULL, (u8*)ctrVertexBuffer, VERTEX_INDEX_BUFFER_SIZE);
|
||||
GPU_DrawElements(GPU_UNKPRIM, (u32*)(osConvertVirtToPhys((u32)ctrIndexBuffer) - VRAM_BASE), ctrNumQuads * 6);
|
||||
GSPGPU_FlushDataCache(ctrVertexBuffer, VERTEX_INDEX_BUFFER_SIZE);
|
||||
GPU_DrawElements(GPU_GEOMETRY_PRIM, (u32*)(osConvertVirtToPhys(ctrIndexBuffer) - VRAM_BASE), ctrNumQuads * 6);
|
||||
|
||||
GPU_FinishDrawing();
|
||||
GPUCMD_Finalize();
|
||||
GSPGPU_FlushDataCache(NULL, (u8*)gpuCommandList, COMMAND_LIST_LENGTH * sizeof(u32));
|
||||
GPUCMD_FlushAndRun(NULL);
|
||||
GSPGPU_FlushDataCache((u8*)gpuCommandList, COMMAND_LIST_LENGTH * sizeof(u32));
|
||||
GPUCMD_FlushAndRun();
|
||||
|
||||
gspWaitForP3D();
|
||||
|
||||
|
|
|
@ -26,18 +26,23 @@
|
|||
|
||||
extern char* fake_heap_start;
|
||||
extern char* fake_heap_end;
|
||||
u32 __linear_heap;
|
||||
u32 __heapBase;
|
||||
static u32 __heap_size = 0x02400000;
|
||||
static u32 __linear_heap_size = 0x01400000;
|
||||
extern u32 __ctru_linear_heap;
|
||||
extern u32 __ctru_heap;
|
||||
extern u32 __ctru_heap_size;
|
||||
extern u32 __ctru_linear_heap_size;
|
||||
static u32 __custom_heap_size = 0x02400000;
|
||||
static u32 __custom_linear_heap_size = 0x01400000;
|
||||
|
||||
extern void (*__system_retAddr)(void);
|
||||
|
||||
void __destroy_handle_list(void);
|
||||
void envDestroyHandles(void);
|
||||
|
||||
void __appExit();
|
||||
|
||||
void __libc_fini_array(void);
|
||||
|
||||
Result __sync_fini(void) __attribute__((weak));
|
||||
|
||||
uint32_t* romBuffer;
|
||||
size_t romBufferSize;
|
||||
|
||||
|
@ -58,36 +63,16 @@ bool allocateRomBuffer(void) {
|
|||
void __system_allocateHeaps() {
|
||||
u32 tmp=0;
|
||||
|
||||
__ctru_heap_size = __custom_heap_size;
|
||||
__ctru_linear_heap_size = __custom_linear_heap_size;
|
||||
|
||||
// Allocate the application heap
|
||||
__heapBase = 0x08000000;
|
||||
svcControlMemory(&tmp, __heapBase, 0x0, __heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
|
||||
__ctru_heap = 0x08000000;
|
||||
svcControlMemory(&tmp, __ctru_heap, 0x0, __ctru_heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
|
||||
|
||||
// Allocate the linear heap
|
||||
svcControlMemory(&__linear_heap, 0x0, 0x0, __linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
||||
svcControlMemory(&__ctru_linear_heap, 0x0, 0x0, __ctru_linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
||||
// Set up newlib heap
|
||||
fake_heap_start = (char*)__heapBase;
|
||||
fake_heap_end = fake_heap_start + __heap_size;
|
||||
}
|
||||
|
||||
void __attribute__((noreturn)) __libctru_exit(int rc)
|
||||
{
|
||||
UNUSED(rc);
|
||||
|
||||
u32 tmp=0;
|
||||
|
||||
// Unmap the linear heap
|
||||
svcControlMemory(&tmp, __linear_heap, 0x0, __linear_heap_size, MEMOP_FREE, 0x0);
|
||||
|
||||
// Unmap the application heap
|
||||
svcControlMemory(&tmp, __heapBase, 0x0, __heap_size, MEMOP_FREE, 0x0);
|
||||
|
||||
// Close some handles
|
||||
__destroy_handle_list();
|
||||
|
||||
// Jump to the loader if it provided a callback
|
||||
if (__system_retAddr)
|
||||
__system_retAddr();
|
||||
|
||||
// Since above did not jump, end this process
|
||||
svcExitProcess();
|
||||
fake_heap_start = (char*)__ctru_heap;
|
||||
fake_heap_end = fake_heap_start + __ctru_heap_size;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ struct GUIFont* GUIFontCreate(void) {
|
|||
tex->width = 256;
|
||||
tex->height = 128;
|
||||
|
||||
GSPGPU_FlushDataCache(NULL, (u8*)font, font_size);
|
||||
GX_RequestDma(NULL, (u32*)font, tex->data, font_size);
|
||||
GSPGPU_FlushDataCache(font, font_size);
|
||||
GX_RequestDma((u32*) font, tex->data, font_size);
|
||||
gspWaitForDMA();
|
||||
|
||||
return guiFont;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "ctr-gpu.h"
|
||||
|
||||
#include <3ds.h>
|
||||
#include <3ds/gpu/gx.h>
|
||||
|
||||
static enum ScreenMode {
|
||||
SM_PA_BOTTOM,
|
||||
|
@ -32,7 +33,7 @@ static enum ScreenMode {
|
|||
#define AUDIO_SAMPLES 0x80
|
||||
#define AUDIO_SAMPLE_BUFFER (AUDIO_SAMPLES * 24)
|
||||
|
||||
FS_archive sdmcArchive;
|
||||
FS_Archive sdmcArchive;
|
||||
|
||||
static struct GBA3DSRotationSource {
|
||||
struct GBARotationSource d;
|
||||
|
@ -76,8 +77,8 @@ static void _csndPlaySound(u32 flags, u32 sampleRate, float vol, void* left, voi
|
|||
flags |= SOUND_ONE_SHOT;
|
||||
}
|
||||
|
||||
pleft = osConvertVirtToPhys((u32) left);
|
||||
pright = osConvertVirtToPhys((u32) right);
|
||||
pleft = osConvertVirtToPhys(left);
|
||||
pright = osConvertVirtToPhys(right);
|
||||
|
||||
u32 timer = CSND_TIMER(sampleRate);
|
||||
if (timer < 0x0042) {
|
||||
|
@ -149,8 +150,8 @@ static void _drawEnd(void) {
|
|||
static int _batteryState(void) {
|
||||
u8 charge;
|
||||
u8 adapter;
|
||||
PTMU_GetBatteryLevel(0, &charge);
|
||||
PTMU_GetBatteryChargeState(0, &adapter);
|
||||
PTMU_GetBatteryLevel(&charge);
|
||||
PTMU_GetBatteryChargeState(&adapter);
|
||||
int state = 0;
|
||||
if (adapter) {
|
||||
state |= BATTERY_CHARGING;
|
||||
|
@ -284,8 +285,8 @@ static void _drawFrame(struct GBAGUIRunner* runner, bool faded) {
|
|||
void* outputBuffer = renderer.outputBuffer;
|
||||
struct ctrTexture* tex = &gbaOutputTexture;
|
||||
|
||||
GSPGPU_FlushDataCache(NULL, outputBuffer, 256 * VIDEO_VERTICAL_PIXELS * 2);
|
||||
GX_SetDisplayTransfer(NULL,
|
||||
GSPGPU_FlushDataCache(outputBuffer, 256 * VIDEO_VERTICAL_PIXELS * 2);
|
||||
GX_DisplayTransfer(
|
||||
outputBuffer, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS),
|
||||
tex->data, GX_BUFFER_DIM(256, 256),
|
||||
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB565) |
|
||||
|
@ -324,9 +325,9 @@ static void _drawScreenshot(struct GBAGUIRunner* runner, const uint32_t* pixels,
|
|||
memset(&newPixels[y * 256 + VIDEO_HORIZONTAL_PIXELS], 0, (256 - VIDEO_HORIZONTAL_PIXELS) * sizeof(u32));
|
||||
}
|
||||
|
||||
GSPGPU_FlushDataCache(NULL, (void*)newPixels, 256 * VIDEO_VERTICAL_PIXELS * sizeof(u32));
|
||||
GX_SetDisplayTransfer(NULL,
|
||||
(void*)newPixels, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS),
|
||||
GSPGPU_FlushDataCache(newPixels, 256 * VIDEO_VERTICAL_PIXELS * sizeof(u32));
|
||||
GX_DisplayTransfer(
|
||||
(u32*) newPixels, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS),
|
||||
tex->data, GX_BUFFER_DIM(256, 256),
|
||||
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB565) |
|
||||
GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB565) |
|
||||
|
@ -433,8 +434,8 @@ static void _postAudioBuffer(struct GBAAVStream* stream, struct GBAAudio* audio)
|
|||
#elif RESAMPLE_LIBRARY == RESAMPLE_NN
|
||||
GBAAudioCopy(audio, &audioLeft[audioPos], &audioRight[audioPos], AUDIO_SAMPLES);
|
||||
#endif
|
||||
GSPGPU_FlushDataCache(0, (void*) &audioLeft[audioPos], AUDIO_SAMPLES * sizeof(int16_t));
|
||||
GSPGPU_FlushDataCache(0, (void*) &audioRight[audioPos], AUDIO_SAMPLES * sizeof(int16_t));
|
||||
GSPGPU_FlushDataCache(&audioLeft[audioPos], AUDIO_SAMPLES * sizeof(int16_t));
|
||||
GSPGPU_FlushDataCache(&audioRight[audioPos], AUDIO_SAMPLES * sizeof(int16_t));
|
||||
audioPos = (audioPos + AUDIO_SAMPLES) % AUDIO_SAMPLE_BUFFER;
|
||||
if (audioPos == AUDIO_SAMPLES * 3) {
|
||||
u8 playing = 0;
|
||||
|
@ -448,9 +449,6 @@ static void _postAudioBuffer(struct GBAAVStream* stream, struct GBAAudio* audio)
|
|||
}
|
||||
|
||||
int main() {
|
||||
ptmInit();
|
||||
hasSound = !csndInit();
|
||||
|
||||
rotation.d.sample = _sampleRotation;
|
||||
rotation.d.readTiltX = _readTiltX;
|
||||
rotation.d.readTiltY = _readTiltY;
|
||||
|
@ -464,6 +462,9 @@ int main() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
ptmuInit();
|
||||
hasSound = !csndInit();
|
||||
|
||||
if (hasSound) {
|
||||
audioLeft = linearMemAlign(AUDIO_SAMPLE_BUFFER * sizeof(int16_t), 0x80);
|
||||
audioRight = linearMemAlign(AUDIO_SAMPLE_BUFFER * sizeof(int16_t), 0x80);
|
||||
|
@ -472,6 +473,7 @@ int main() {
|
|||
gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, false);
|
||||
|
||||
if (ctrInitGpu() < 0) {
|
||||
gbaOutputTexture.data = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -483,18 +485,22 @@ int main() {
|
|||
gbaOutputTexture.data = vramAlloc(256 * 256 * 2);
|
||||
void* outputTextureEnd = (u8*)gbaOutputTexture.data + 256 * 256 * 2;
|
||||
|
||||
if (!gbaOutputTexture.data) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Zero texture data to make sure no garbage around the border interferes with filtering
|
||||
GX_SetMemoryFill(NULL,
|
||||
GX_MemoryFill(
|
||||
gbaOutputTexture.data, 0x0000, outputTextureEnd, GX_FILL_16BIT_DEPTH | GX_FILL_TRIGGER,
|
||||
NULL, 0, NULL, 0);
|
||||
gspWaitForPSC0();
|
||||
|
||||
sdmcArchive = (FS_archive) {
|
||||
ARCH_SDMC,
|
||||
(FS_path) { PATH_EMPTY, 1, (const u8*)"" },
|
||||
0, 0
|
||||
sdmcArchive = (FS_Archive) {
|
||||
ARCHIVE_SDMC,
|
||||
(FS_Path) { PATH_EMPTY, 1, "" },
|
||||
0
|
||||
};
|
||||
FSUSER_OpenArchive(0, &sdmcArchive);
|
||||
FSUSER_OpenArchive(&sdmcArchive);
|
||||
|
||||
struct GUIFont* font = GUIFontCreate();
|
||||
|
||||
|
@ -549,10 +555,14 @@ int main() {
|
|||
GBAGUIDeinit(&runner);
|
||||
|
||||
cleanup:
|
||||
linearFree(renderer.outputBuffer);
|
||||
if (renderer.outputBuffer) {
|
||||
linearFree(renderer.outputBuffer);
|
||||
}
|
||||
|
||||
ctrDeinitGpu();
|
||||
vramFree(gbaOutputTexture.data);
|
||||
if (gbaOutputTexture.data) {
|
||||
ctrDeinitGpu();
|
||||
vramFree(gbaOutputTexture.data);
|
||||
}
|
||||
|
||||
gfxExit();
|
||||
|
||||
|
@ -560,7 +570,8 @@ cleanup:
|
|||
linearFree(audioLeft);
|
||||
linearFree(audioRight);
|
||||
}
|
||||
|
||||
csndExit();
|
||||
ptmExit();
|
||||
ptmuExit();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,11 @@
|
|||
#include <3ds.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#ifdef _3DS
|
||||
// ctrulib already has a type called Thread
|
||||
#define Thread CustomThread
|
||||
#endif
|
||||
|
||||
#define THREAD_ENTRY void
|
||||
typedef ThreadFunc ThreadEntry;
|
||||
|
||||
|
|
Loading…
Reference in New Issue