fixed sdmc example

This commit is contained in:
smea 2014-11-19 15:53:36 -08:00
parent ce226ec1b2
commit 5ecb358b56
2 changed files with 76 additions and 131 deletions

View File

@ -1,92 +1,19 @@
#include <3ds/types.h> ///////////////////////////////////////
#include <3ds/srv.h> // SDMC example //
#include <3ds/svc.h> ///////////////////////////////////////
#include <3ds/gpu/gx.h>
#include <3ds/services/apt.h> //this example shows you how to load a binary image file from the SD card and display it on the lower screen
#include <3ds/services/gsp.h> //for this to work you should copy test.bin to the root of your SD card
#include <3ds/services/hid.h> //this file was generated with GIMP by saving a 240x320 image to raw RGB
#include <3ds/services/fs.h>
#include <3ds.h>
#include "costable.h" #include "costable.h"
u8* gspHeap; //this will contain the data read from SDMC
u32* gxCmdBuf; u8* buffer;
u8 currentBuffer;
u8* topLeftFramebuffers[2];
Handle gspEvent, gspSharedMemHandle;
void gspGpuInit()
{
gspInit();
GSPGPU_AcquireRight(NULL, 0x0);
GSPGPU_SetLcdForceBlack(NULL, 0x0);
//set subscreen to blue
u32 regData=0x01FF0000;
GSPGPU_WriteHWRegs(NULL, 0x202A04, &regData, 4);
//grab main left screen framebuffer addresses
GSPGPU_ReadHWRegs(NULL, 0x400468, (u32*)&topLeftFramebuffers, 8);
//convert PA to VA (assuming FB in VRAM)
topLeftFramebuffers[0]+=0x7000000;
topLeftFramebuffers[1]+=0x7000000;
//setup our gsp shared mem section
u8 threadID;
svcCreateEvent(&gspEvent, 0x0);
GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &threadID);
svcMapMemoryBlock(gspSharedMemHandle, 0x10002000, 0x3, 0x10000000);
//map GSP heap
svcControlMemory((u32*)&gspHeap, 0x0, 0x0, 0x2000000, 0x10003, 0x3);
//wait until we can write stuff to it
svcWaitSynchronization(gspEvent, 0x55bcb0);
//GSP shared mem : 0x2779F000
gxCmdBuf=(u32*)(0x10002000+0x800+threadID*0x200);
currentBuffer=0;
}
void gspGpuExit()
{
GSPGPU_UnregisterInterruptRelayQueue(NULL);
//unmap GSP shared mem
svcUnmapMemoryBlock(gspSharedMemHandle, 0x10002000);
svcCloseHandle(gspSharedMemHandle);
svcCloseHandle(gspEvent);
gspExit();
//free GSP heap
svcControlMemory((u32*)&gspHeap, (u32)gspHeap, 0x0, 0x2000000, MEMOP_FREE, 0x0);
}
void swapBuffers()
{
u32 regData;
GSPGPU_ReadHWRegs(NULL, 0x400478, &regData, 4);
regData^=1;
currentBuffer=regData&1;
GSPGPU_WriteHWRegs(NULL, 0x400478, &regData, 4);
}
void copyBuffer()
{
//copy topleft FB
u8 copiedBuffer=currentBuffer^1;
u8* bufAdr=&gspHeap[0x46500*copiedBuffer];
GSPGPU_FlushDataCache(NULL, bufAdr, 0x46500);
GX_RequestDma(gxCmdBuf, (u32*)bufAdr, (u32*)topLeftFramebuffers[copiedBuffer], 0x46500);
}
//3DS has VFPs so we could just use cos
//but we're old school so LUT4life
s32 pcCos(u16 v) s32 pcCos(u16 v)
{ {
return costable[v&0x1FF]; return costable[v&0x1FF];
@ -94,71 +21,88 @@ s32 pcCos(u16 v)
void renderEffect() void renderEffect()
{ {
u8* bufAdr=&gspHeap[0x46500*currentBuffer]; static int cnt;
u8* bufAdr=gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
if(!currentBuffer)return;
int i, j; int i, j;
for(i=1;i<400;i++) for(i=1;i<400;i++)
{ {
for(j=1;j<240;j++) for(j=1;j<240;j++)
{ {
u32 v=(j+i*240)*3; u32 v=(j+i*240)*3;
bufAdr[v]=(pcCos(i)+4096)/32; bufAdr[v]=(pcCos(i+cnt)+4096)/32;
bufAdr[v+1]=0x00; bufAdr[v+1]=(pcCos(j-256+cnt)+4096)/64;
bufAdr[v+2]=0xFF*currentBuffer; bufAdr[v+2]=(pcCos(i+128-cnt)+4096)/32;
}
} }
} }
int main() cnt++;
}
int main(int argc, char** argv)
{ {
srvInit(); //initialize the services we're going to be using
srvInit(); //needed for everything
aptInit(); //needed for everything
hidInit(NULL); //needed for input
gfxInit(); //makes displaying to screen easier
fsInit(); //needed for filesystem stuff
aptInit(APPID_APPLICATION); u64 size;
gspGpuInit();
hidInit(NULL);
Handle fsuHandle;
srvGetServiceHandle(&fsuHandle, "fs:USER");
FSUSER_Initialize(fsuHandle);
Handle fileHandle;
u32 bytesRead; u32 bytesRead;
Handle fileHandle;
//setup SDMC archive
FS_archive sdmcArchive=(FS_archive){ARCH_SDMC, (FS_path){PATH_EMPTY, 1, (u8*)""}}; FS_archive sdmcArchive=(FS_archive){ARCH_SDMC, (FS_path){PATH_EMPTY, 1, (u8*)""}};
FS_path filePath=(FS_path){PATH_CHAR, 10, (u8*)"/test.bin"}; //create file path struct (note : FS_makePath actually only supports PATH_CHAR, it will change in the future)
FSUSER_OpenFileDirectly(fsuHandle, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE); FS_path filePath=FS_makePath(PATH_CHAR, "/test.bin");
FSFILE_Read(fileHandle, &bytesRead, 0x0, (u32*)gspHeap, 0x46500);
FSFILE_Close(fileHandle);
APP_STATUS status; //open file
while((status=aptGetStatus())!=APP_EXITING) Result ret=FSUSER_OpenFileDirectly(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE);
//check for errors : exit if there is one
if(ret)goto exit;
//get file size
ret=FSFILE_GetSize(fileHandle, &size);
if(ret)goto exit;
//allocate a buffer on linear heap (could just be a malloc fwiw)
buffer=linearAlloc(size);
if(!buffer)goto exit;
//read contents !
ret=FSFILE_Read(fileHandle, &bytesRead, 0x0, buffer, size);
if(ret || size!=bytesRead)goto exit;
//close the file because we like being nice and tidy
ret=FSFILE_Close(fileHandle);
if(ret)goto exit;
while(aptMainLoop())
{ {
if(status==APP_RUNNING) //exit when user hits B
{ hidScanInput();
u32 PAD=hidSharedMem[7]; if(keysHeld()&KEY_B)break;
//render rainbow
renderEffect(); renderEffect();
swapBuffers();
copyBuffer(); //copy buffer to lower screen (don't have to do it every frame)
u32 regData=PAD|0x01000000; memcpy(gfxGetFramebuffer(GFX_BOTTOM, GFX_BOTTOM, NULL, NULL), buffer, size);
GSPGPU_WriteHWRegs(NULL, 0x202A04, &regData, 4);
svcSleepThread(1000000000); //wait & swap
} gfxSwapBuffersGpu();
else if(status == APP_SUSPENDING) gspWaitForEvent(GSPEVENT_VBlank0, false);
{
aptReturnToMenu();
}
else if(status == APP_SLEEPMODE)
{
aptWaitStatusEvent();
}
} }
svcCloseHandle(fsuHandle); //cleanup and return
//returning from main() returns to hbmenu when run under ninjhax
exit:
//closing all handles is super important
svcCloseHandle(fileHandle);
//closing all services even more so
gfxExit();
hidExit(); hidExit();
gspGpuExit();
aptExit(); aptExit();
svcExitProcess(); srvExit();
return 0; return 0;
} }

1
examples/sdmc/test.bin Normal file

File diff suppressed because one or more lines are too long