From de29b11a88dbdd3af0824e59b51528b91ee73c54 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 30 Nov 2017 22:49:38 +0100 Subject: First commit. Version works on Linux (keyboard only, not configurable) --- src/3ds/audio.c | 316 ++++++++++++++++++++++++++++++++++++++ src/3ds/audio.h | 51 +++++++ src/3ds/graphics.c | 435 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/3ds/graphics.h | 67 +++++++++ src/3ds/input.c | 56 +++++++ src/3ds/input.h | 25 +++ src/3ds/system.c | 48 ++++++ src/3ds/system.h | 12 ++ 8 files changed, 1010 insertions(+) create mode 100644 src/3ds/audio.c create mode 100644 src/3ds/audio.h create mode 100644 src/3ds/graphics.c create mode 100644 src/3ds/graphics.h create mode 100644 src/3ds/input.c create mode 100644 src/3ds/input.h create mode 100644 src/3ds/system.c create mode 100644 src/3ds/system.h (limited to 'src/3ds') diff --git a/src/3ds/audio.c b/src/3ds/audio.c new file mode 100644 index 0000000..a63c88e --- /dev/null +++ b/src/3ds/audio.c @@ -0,0 +1,316 @@ +#include "audio.h" +#include +#include +#include + +const int MODE_NDSP = 1, + MODE_CSND = 2; + +int audioMode = 0; + +PHL_Sound loadWav(char* fname); +PHL_Music loadRaw(char* fname, u32 sampleRate, u32 bitsPerSample, u16 numChannels, u8 loop); + +void PHL_AudioInit() +{ + int loadMode = 0; + + Result rdsp = ndspInit(); + if (rdsp) { + //printf("\nNDSP Failed: %08lX\n", rdsp); + //loadMode = MODE_CSND; + loadMode = 0; //DSP or no sound for you! CSND a shit. + }else{ + loadMode = MODE_NDSP; + } + + if (loadMode == MODE_NDSP) { + //printf("\nNDSP Audio Mode"); + + ndspSetOutputMode(NDSP_OUTPUT_STEREO); + ndspSetOutputCount(1); + + audioMode = MODE_NDSP; + } + + else if (loadMode == MODE_CSND) { + //printf("\nCSND Audio Mode"); + + csndInit(); + audioMode = MODE_CSND; + } +} + +void PHL_AudioClose() +{ + if (audioMode == MODE_NDSP) { + ndspExit(); + } + + else if (audioMode == MODE_CSND) { + csndExit(); + } +} + +//Each system can use a custom music file format +PHL_Music PHL_LoadMusic(char* fname, int loop) +{ + return loadRaw(fname, 32000, 16, 1, loop); +} + +PHL_Music loadRaw(char* fname, u32 sampleRate, u32 bitsPerSample, u16 numChannels, u8 loop) +{ + PHL_Music result; + + char fullPath[128]; + strcpy(fullPath, "romfs:/"); + strcat(fullPath, fname); + strcat(fullPath, ".raw"); + + FILE* file; + if ((file = fopen(fullPath, "rb"))) + { + u32 size; + + fseek(file, 0, SEEK_END); + size = ftell(file); + + fseek(file, 0, SEEK_SET); + + result.sampleRate = sampleRate; + result.dataSize = size; + result.bitsPerSample = bitsPerSample; + result.numChannels = numChannels; + + if(bitsPerSample == 8) { + result.ndspFormat = (numChannels == 1) ? + NDSP_FORMAT_MONO_PCM8 : + NDSP_FORMAT_STEREO_PCM8; + } + else { + result.ndspFormat = (numChannels == 1) ? + NDSP_FORMAT_MONO_PCM16 : + NDSP_FORMAT_STEREO_PCM16; + } + + result.loop = loop; + + result.data = linearAlloc(size); + fread(result.data, 1, size, file); + + fclose(file); + } + + return result; + +} + +PHL_Sound PHL_LoadSound(char* fname) +{ + return loadWav(fname); +} + +PHL_Sound loadWav(char* fname) +{ + PHL_Sound snd; + + char fullPath[128]; + strcpy(fullPath, "romfs:/"); + strcat(fullPath, fname); + + FILE* f; + if ( (f = fopen(fullPath, "rb")) ) + { + //Check for valid fileName + u32 sig; + fread(&sig, 4, 1, f); + + if (sig == 0x46464952) //RIFF + { + u32 chunkSize; + u32 format; + + fread(&chunkSize, 4, 1, f); + fread(&format, 4, 1, f); + + if (format == 0x45564157) //WAVE + { + u32 subchunk1ID; + fread(&subchunk1ID, 4, 1, f); + + if (subchunk1ID == 0x20746D66) //fmt + { + u32 subchunk1Size; + u16 audioFormat; + u16 numChannels; + u32 sampleRate; + u32 byteRate; + u16 blockAlign; + u16 bitsPerSample; + + fread(&subchunk1Size, 4, 1, f); + fread(&audioFormat, 2, 1, f); + fread(&numChannels, 2, 1, f); + fread(&sampleRate, 4, 1, f); + fread(&byteRate, 4, 1, f); + fread(&blockAlign, 2, 1, f); + fread(&bitsPerSample, 2, 1, f); + + //Search for 'data' + for (int i = 0; i < 100; i++) { + u8 c; + fread(&c, 1, 1, f); + if (c == 0x64) { //'d' + fread(&c, 1, 1, f); + if (c == 0x61) { //'a' + fread(&c, 1, 1, f); + if (c == 0x74) { //'t' + fread(&c, 1, 1, f); + if (c == 0x61) { //'a' + i = 100; + } + } + } + } + } + + u32 subchunk2Size; + fread(&subchunk2Size, 4, 1, f); + + snd.numChannels = numChannels; + + if(bitsPerSample == 8) + { + snd.ndspFormat = (numChannels == 1) ? + NDSP_FORMAT_MONO_PCM8 : + NDSP_FORMAT_STEREO_PCM8; + } + else + { + snd.ndspFormat = (numChannels == 1) ? + NDSP_FORMAT_MONO_PCM16 : + NDSP_FORMAT_STEREO_PCM16; + } + + snd.sampleRate = sampleRate; + snd.dataSize = subchunk2Size; + snd.bitsPerSample = bitsPerSample; + + snd.data = (u8*)(linearAlloc(subchunk2Size)); + fread(snd.data, 1, subchunk2Size, f); + } + } + } + + fclose(f); + } + + return snd; +} + +void PHL_PlayMusic(PHL_Music snd) +{ + if (snd.data != NULL) { + if (audioMode == MODE_NDSP) + { + ndspChnReset(0); + ndspChnSetInterp(0, NDSP_INTERP_NONE); + ndspChnSetRate(0, (float)snd.sampleRate); + ndspChnSetFormat(0, snd.ndspFormat); + + + memset(&waveBuf[0], 0, sizeof(ndspWaveBuf)); + waveBuf[0].data_vaddr = (u32)(snd.data); + waveBuf[0].nsamples = snd.dataSize / (snd.bitsPerSample >> 3) / snd.numChannels; + waveBuf[0].looping = snd.loop; + waveBuf[0].status = NDSP_WBUF_FREE; + + DSP_FlushDataCache(snd.data, snd.dataSize); + ndspChnWaveBufAdd(0, &waveBuf[0]); + } + + else if (audioMode == MODE_CSND) + { + u32 flags = SOUND_FORMAT_16BIT; + + if (snd.loop == 1) { + flags = SOUND_FORMAT_16BIT | SOUND_REPEAT; + } + + int channel = (0 + 1) * 8; + csndPlaySound(channel, flags, snd.sampleRate, 1, 0, snd.data, snd.data, snd.dataSize); + } + } +} + +void PHL_PlaySound(PHL_Sound snd, int channel) +{ + if (snd.data != NULL) { + if (audioMode == MODE_NDSP) + { + ndspChnReset(channel); + ndspChnSetInterp(channel, NDSP_INTERP_NONE); + ndspChnSetRate(channel, (float)snd.sampleRate); + ndspChnSetFormat(channel, snd.ndspFormat); + + + memset(&waveBuf[channel], 0, sizeof(ndspWaveBuf)); + waveBuf[channel].data_vaddr = (u32)(snd.data); + waveBuf[channel].nsamples = snd.dataSize / (snd.bitsPerSample >> 3) / snd.numChannels; + waveBuf[channel].looping = false; + waveBuf[channel].status = NDSP_WBUF_FREE; + + DSP_FlushDataCache(snd.data, snd.dataSize); + ndspChnWaveBufAdd(channel, &waveBuf[channel]); + } + + else if (audioMode == MODE_CSND) + { + channel = (channel + 1) * 8; + csndPlaySound(channel, SOUND_FORMAT_16BIT, snd.sampleRate, 1, 0, snd.data, snd.data, snd.dataSize); + } + } +} + +void PHL_StopMusic() +{ + if (audioMode == MODE_NDSP) + { + ndspChnWaveBufClear(0); + } + + else if (audioMode == MODE_CSND) + { + CSND_SetPlayState(8, 0); + } +} + +void PHL_StopSound(PHL_Sound snd, int channel) +{ + if (audioMode == MODE_NDSP) + { + ndspChnWaveBufClear(channel); + } + + else if (audioMode == MODE_CSND) + { + channel = (channel + 1) * 8; + CSND_SetPlayState(channel, 0); + } +} + +void PHL_FreeMusic(PHL_Music snd) +{ + if (snd.data != NULL) { + linearFree(snd.data); + snd.data = NULL; + } +} + +void PHL_FreeSound(PHL_Sound snd) +{ + if (snd.data != NULL) { + linearFree(snd.data); + snd.data = NULL; + } +} \ No newline at end of file diff --git a/src/3ds/audio.h b/src/3ds/audio.h new file mode 100644 index 0000000..28b615c --- /dev/null +++ b/src/3ds/audio.h @@ -0,0 +1,51 @@ +#ifndef AUDIO_H +#define AUDIO_H + +#include <3ds.h> + +typedef struct { + u16 sampleRate; + u32 dataSize; + u16 bitsPerSample; + u16 ndspFormat; + u16 numChannels; + u8 loop; + u8* data; + //int used; +} PHL_Music; + +typedef struct{ + u32 sampleRate; + u32 dataSize; + u16 bitsPerSample; + u16 ndspFormat; + u16 numChannels; + u8* data; +} PHL_Sound; + +ndspWaveBuf waveBuf[6]; //One for each channel? + +void PHL_AudioInit(); +void PHL_AudioClose(); + +PHL_Music PHL_LoadMusic(char* fname, int loop); //Same as PHL_LoadSound, but expects a file name without extension +PHL_Sound PHL_LoadSound(char* fname); + +void PHL_PlayMusic(PHL_Music snd); +void PHL_PlaySound(PHL_Sound snd, int channel); + +void PHL_StopMusic(); +void PHL_StopSound(PHL_Sound snd, int channel); + +/* +PHL_Music PHL_LoadMusic(char* fname, int channel); //Same as PHL_LoadSound, but expects a file name without extension +PHL_Sound PHL_LoadSound(char* fname, int loop, int stream, int channel); + +void PHL_PlayMusic(PHL_Music snd); +void PHL_PlaySound(PHL_Sound snd); +*/ + +void PHL_FreeMusic(PHL_Music snd); +void PHL_FreeSound(PHL_Sound snd); + +#endif \ No newline at end of file diff --git a/src/3ds/graphics.c b/src/3ds/graphics.c new file mode 100644 index 0000000..dd82955 --- /dev/null +++ b/src/3ds/graphics.c @@ -0,0 +1,435 @@ +//3DS graphics.c +#include "graphics.h" +#include +#include +#include +#include "../game.h" +#include "../qda.h" +#include "../hero.h" + +Screen scrnTop = { GFX_TOP, + GFX_LEFT, + 400, + 240 }; + +Screen scrnBottom = { GFX_BOTTOM, + GFX_LEFT, + 320, + 240 }; + +PHL_Rect offset/*, crop*/; + +//One time graphics setup +void PHL_GraphicsInit() +{ + gfxInitDefault(); + + activeScreen = &scrnTop; + /* + offset.w = 320; + offset.h = 240; + offset.x = (activeScreen->width - offset.w) / 2; + offset.y = (activeScreen->height - offset.h) / 2; + + crop.w = 320; + crop.h = 320; + crop.x = 0; + crop.y = 0; + + db.width = activeScreen->width; + db.height = activeScreen->height; + */ + PHL_ResetDrawbuffer(); + + //Create background image + backBuffer = PHL_NewSurface(640, 480); + + //consoleInit(GFX_BOTTOM, NULL); + //printf("Console Init"); +} + +void PHL_GraphicsExit() +{ + gfxExit(); +} + +void PHL_StartDrawing() +{ + PHL_ResetDrawbuffer(); + + gfxFlushBuffers(); +} + +void PHL_EndDrawing() +{ + gfxSwapBuffers(); + gspWaitForVBlank(); +} + +void PHL_ForceScreenUpdate() +{ + //Draw black borders on sides of top screen + /* + PHL_DrawRect(-80, 0, 80, 480, PHL_NewRGB(0, 0, 0)); + PHL_DrawRect(640, 0, 80, 480, PHL_NewRGB(0, 0, 0)); + + gspWaitForVBlank(); + gfxSwapBuffers(); + + gfxFlushBuffers(); + swapScreen(GFX_TOP, GFX_LEFT); + */ + + //PHL_DrawRect(0, 0, 640, 48, PHL_NewRGB(0, 0, 0)); + //gfxSwapBuffers(); +} + +void PHL_SetDrawbuffer(PHL_Surface surf) +{ + db = surf; + + offset.w = db.width; + offset.h = db.height; + offset.x = 0; + offset.y = 0; + /* + crop.w = db.width; + crop.h = db.height; + crop.x = 0; + crop.y = 0; + */ +} + +void PHL_ResetDrawbuffer() +{ + db.width = activeScreen->width; + db.height = activeScreen->height; + db.pxdata = gfxGetFramebuffer(activeScreen->screen, activeScreen->side, NULL, NULL); + + offset.w = 320; + offset.h = 240; + offset.x = (activeScreen->width - offset.w) / 2; + offset.y = (activeScreen->height - offset.h) / 2; + /* + crop.w = 320; + crop.h = 240; + crop.x = 0; + crop.y = 0;*/ +} + +PHL_RGB PHL_NewRGB(u8 r, u8 g, u8 b) +{ + PHL_RGB c = { r, g, b }; + return c; +} + +void PHL_SetColorKey(PHL_Surface surf, u8 r, u8 g, u8 b) +{ + PHL_RGB key = { r, g, b }; + surf.colorKey = key; +} + +PHL_Surface PHL_NewSurface(u16 w, u16 h) +{ + PHL_Surface surf; + + surf.width = w / 2; + surf.height = h / 2; + //printf("\nWidth: %d", surf.width); + surf.pxdata = malloc(surf.width * surf.height * 3 * sizeof(u8)); + surf.colorKey = PHL_NewRGB(0xFF, 0x00, 0xFF); + + return surf; +} + +void PHL_FreeSurface(PHL_Surface surf) +{ + if (surf.pxdata != NULL) { + free(surf.pxdata); + surf.pxdata = NULL; + } +} + +PHL_Surface PHL_LoadBMP(int index) +{ + PHL_Surface surf; + + FILE* f; + if ( (f = fopen("romfs:/bmp.qda", "rb")) ) + { + //Save bmp data + u8* bmpFile = malloc(headers[index].size * sizeof(u8)); + + fseek(f, headers[index].offset, SEEK_SET); + fread(bmpFile, headers[index].size, 1, f); + fclose(f); + + //Create surface + u16 w, h; + memcpy(&w, &bmpFile[18], 2); + memcpy(&h, &bmpFile[22], 2); + + surf = PHL_NewSurface(w * 2, h * 2); + + //Load Palette + PHL_RGB palette[20][18]; + + int count = 0; + for (int dx = 0; dx < 20; dx++) + { + for (int dy = 0; dy < 16; dy++) + { + palette[dx][dy].b = bmpFile[54 + count]; + palette[dx][dy].g = bmpFile[54 + count + 1]; + palette[dx][dy].r = bmpFile[54 + count + 2]; + + count += 4; + } + } + + //Fill pixels + count = 0; + for (int dx = w; dx > 0; dx--) + { + for (int dy = 0; dy < h; dy++) + { + int pix = w - dx + w * dy; + int px = bmpFile[1078 + pix] / 16; + int py = bmpFile[1078 + pix] % 16; + + //Get transparency from first palette color + if (dx == w && dy == 0) { + //Darkness special case + if (index == 27) { + surf.colorKey = PHL_NewRGB(0x00, 0x00, 0x00); + }else{ + surf.colorKey = palette[0][0]; + } + } + + PHL_RGB c = palette[px][py]; + surf.pxdata[count] = c.b; + surf.pxdata[count+1] = c.g; + surf.pxdata[count+2] = c.r; + + count += 3; + } + } + + //Cleanup + free(bmpFile); + } + + return surf; +} + +void PHL_DrawRect(s16 x, s16 y, u16 w, u16 h, PHL_RGB col) +{ + //Quake Shake + if (quakeTimer > 0) { + int val = quakeTimer % 4; + if (val == 0) { + y -= 2; + }else if (val == 2) { + y += 2; + } + } + + //Shrink values for small 3ds screen + x /= 2; + y /= 2; + + x += offset.x; + y += offset.y; + + w /= 2; + h /= 2; + + s16 x2 = x + w; + s16 y2 = y + h; + + //Keep drawing within screen + if (x < offset.x) { x = offset.x; } + if (y < offset.y) { y = offset.y; } + if (x2 > offset.x + offset.w) { x2 = offset.x + offset.w; } + if (y2 > offset.y + offset.h) { y2 = offset.y + offset.h; } + + w = x2 - x; + h = y2 - y; + + u32 p = ((db.height - h - y) + (x * db.height)) * 3; + + for (int i = 0; i < w; i++) + { + for (int a = 0; a < h; a++) + { + db.pxdata[p] = col.b; + db.pxdata[p+1] = col.g; + db.pxdata[p+2] = col.r; + + p += 3; + } + p += (db.height - h) * 3; + } +} + +void PHL_DrawSurface(s16 x, s16 y, PHL_Surface surf) +{ + PHL_DrawSurfacePart(x, y, 0, 0, surf.width * 2, surf.height * 2, surf); +} + +void PHL_DrawSurfacePart(s16 x, s16 y, s16 cropx, s16 cropy, s16 cropw, s16 croph, PHL_Surface surf) +{ + if (surf.pxdata != NULL) + { + //Quake Shake + if (quakeTimer > 0) { + int val = quakeTimer % 4; + if (val == 0) { + y -= 2; + }else if (val == 2) { + y += 2; + } + } + + //Shrink values for small 3ds screen + x = (int)x / 2; + y = (int)y / 2; + + cropx = cropx / 2; + cropy = cropy / 2; + cropw /= 2; + croph /= 2; + + if (x > offset.w || y > offset.h || x + cropw < 0 || y + croph < 0) { + //image is outside of screen, so don't bother drawing + } + else{ + //Crop pixels that are outside of screen + if (x < 0) { + cropx += -(x); + cropw -= -(x); + x = 0; + } + if (y < 0) { + cropy += -(y); + croph -= -(y); + y = 0; + } + + //3DS exclusive optimization + if (roomDarkness == 1) { + //if (1) { + int cornerX = (herox / 2) - 80; + int cornerY = (heroy / 2) + 10 - 80; + + if (x < cornerX) { + cropx += cornerX - x; + cropw -= cornerX - x; + x = cornerX; + } + if (y < cornerY) { + cropy += cornerY - y; + croph -= cornerY - y; + y = cornerY; + } + if (x + cropw > cornerX + 160) { + cropw -= (x + cropw) - (cornerX + 160); + } + if (y + croph > cornerY + 160) { + croph -= (y + croph) - (cornerY + 160); + } + } + + if (x + cropw > offset.w) { + cropw -= (x + cropw) - (offset.w); + } + if (y + croph > offset.h) { + croph -= (y + croph) - (offset.h); + } + + x += offset.x; + y += offset.y; + + u32 p = ((offset.h - croph - y) + (x * offset.h)) * 3; + u32 c = ((surf.height - cropy - croph) + surf.height * cropx) * 3; + + for (int i = 0; i < cropw; i++) + { + for (int a = 0; a < croph; a++) + { + if (surf.colorKey.r != surf.pxdata[c+2] || + surf.colorKey.g != surf.pxdata[c+1] || + surf.colorKey.b != surf.pxdata[c] ) + { + + db.pxdata[p] = surf.pxdata[c]; + db.pxdata[p+1] = surf.pxdata[c+1]; + db.pxdata[p+2] = surf.pxdata[c+2]; + } + + c += 3; + p += 3; + } + + p += (offset.h - croph) * 3; + c += (surf.height - croph) * 3; + } + } + } +} + +void PHL_DrawBackground(PHL_Background back, PHL_Background fore) +{ + PHL_DrawSurface(0, 0, backBuffer); +} + +void PHL_UpdateBackground(PHL_Background back, PHL_Background fore) +{ + int tempDarkness = roomDarkness; + roomDarkness = 0; + + PHL_SetDrawbuffer(backBuffer); + + int xx, yy; + + for (yy = 0; yy < 12; yy++) + { + for (xx = 0; xx < 16; xx++) + { + //Draw Background tiles + PHL_DrawSurfacePart(xx * 40, yy * 40, back.tileX[xx][yy] * 40, back.tileY[xx][yy] * 40, 40, 40, images[imgTiles]); + + //Only draw foreground tile if not a blank tile + if (fore.tileX[xx][yy] != 0 || fore.tileY[xx][yy] != 0) { + PHL_DrawSurfacePart(xx * 40, yy * 40, fore.tileX[xx][yy] * 40, fore.tileY[xx][yy] * 40, 40, 40, images[imgTiles]); + } + } + } + + PHL_ResetDrawbuffer(); + + roomDarkness = tempDarkness; +} + +//3DS exclusive. Changes which screen to draw on +void swapScreen(gfxScreen_t screen, gfx3dSide_t side) +{ + //Clear old screen + PHL_StartDrawing(); + PHL_DrawRect(0, 0, 640, 480, PHL_NewRGB(0, 0, 0)); + PHL_EndDrawing(); + PHL_StartDrawing(); + PHL_DrawRect(0, 0, 640, 480, PHL_NewRGB(0, 0, 0)); + PHL_EndDrawing(); + + if (screen == GFX_TOP) + { + activeScreen = &scrnTop; + } + else{ + activeScreen = &scrnBottom; + } + + PHL_ResetDrawbuffer(); +} \ No newline at end of file diff --git a/src/3ds/graphics.h b/src/3ds/graphics.h new file mode 100644 index 0000000..badd898 --- /dev/null +++ b/src/3ds/graphics.h @@ -0,0 +1,67 @@ +//3DS graphics.h +#ifndef GRAPHICS_H +#define GRAPHICS_H + +#include <3ds.h> + +typedef struct { + u8 r; + u8 g; + u8 b; +} PHL_RGB; + +typedef struct { + u8* pxdata; + u16 width; + u16 height; + PHL_RGB colorKey; +} PHL_Surface; + +typedef struct { + gfxScreen_t screen; + gfx3dSide_t side; + u16 width; + u16 height; +} Screen; + +typedef struct { + int tileX[16][12]; + int tileY[16][12]; +} PHL_Background; + +PHL_Surface db; +Screen* activeScreen; + +PHL_Surface backBuffer; + +void PHL_GraphicsInit(); +void PHL_GraphicsExit(); + +void PHL_StartDrawing(); +void PHL_EndDrawing(); + +void PHL_ForceScreenUpdate(); + +void PHL_SetDrawbuffer(PHL_Surface surf); +void PHL_ResetDrawbuffer(); + +PHL_RGB PHL_NewRGB(u8 r, u8 g, u8 b); +void PHL_SetColorKey(PHL_Surface surf, u8 r, u8 g, u8 b); + +PHL_Surface PHL_NewSurface(u16 w, u16 h); +void PHL_FreeSurface(PHL_Surface surf); + +PHL_Surface PHL_LoadBMP_Debug(int index); +PHL_Surface PHL_LoadBMP(int index); + +void PHL_DrawRect(s16 x, s16 y, u16 w, u16 h, PHL_RGB col); + +void PHL_DrawSurface(s16 x, s16 y, PHL_Surface surf); +void PHL_DrawSurfacePart(s16 x, s16 y, s16 cropx, s16 cropy, s16 cropw, s16 croph, PHL_Surface surf); + +void PHL_DrawBackground(PHL_Background back, PHL_Background fore); +void PHL_UpdateBackground(PHL_Background back, PHL_Background fore); + +void swapScreen(gfxScreen_t screen, gfx3dSide_t side); + +#endif \ No newline at end of file diff --git a/src/3ds/input.c b/src/3ds/input.c new file mode 100644 index 0000000..0d99b24 --- /dev/null +++ b/src/3ds/input.c @@ -0,0 +1,56 @@ +#include "input.h" + +void updateKey(Button* btn, int state); + +void PHL_ScanInput() +{ + hidScanInput(); + u32 kDown = hidKeysHeld(); + + updateKey(&btnUp, kDown & KEY_UP); + updateKey(&btnDown, kDown & KEY_DOWN); + updateKey(&btnLeft, kDown & KEY_LEFT); + updateKey(&btnRight, kDown & KEY_RIGHT); + + updateKey(&btnStart, kDown & KEY_START); + updateKey(&btnSelect, kDown & KEY_SELECT); + + updateKey(&btnFaceRight, kDown & KEY_A); + updateKey(&btnFaceDown, kDown & KEY_B); + updateKey(&btnFaceLeft, kDown & KEY_Y); + + updateKey(&btnL, kDown & KEY_L); + updateKey(&btnR, kDown & KEY_R); + + updateKey(&btnAccept, kDown & KEY_A); + updateKey(&btnDecline, kDown & KEY_B); + /* + //Start button + if (kDown & KEY_START) { + btnStart.pressed = 1; + }else{ + btnStart.pressed = 0; + } + */ +} + +void updateKey(Button* btn, int state) +{ + if (state) { + if (btn->held == 1) { + btn->pressed = 0; + }else{ + btn->pressed = 1; + } + btn->held = 1; + btn->released = 0; + }else{ + if (btn->held == 1) { + btn->released = 1; + }else{ + btn->released = 0; + } + btn->held = 0; + btn->pressed = 0; + } +} \ No newline at end of file diff --git a/src/3ds/input.h b/src/3ds/input.h new file mode 100644 index 0000000..7b7076e --- /dev/null +++ b/src/3ds/input.h @@ -0,0 +1,25 @@ +#ifndef INPUT_H +#define INPUT_H + +#include <3ds.h> + +typedef struct { + int pressed, + held, + released; +} Button; + +Button btnUp, btnDown, btnLeft, btnRight; +Button btnFaceUp, btnFaceDown, btnFaceLeft, btnFaceRight; + +Button btnL, btnR; +Button btnStart, btnSelect; + +Button btnAccept; +Button btnDecline; + +int axisX, axisY; + +void PHL_ScanInput(); + +#endif \ No newline at end of file diff --git a/src/3ds/system.c b/src/3ds/system.c new file mode 100644 index 0000000..9b824cb --- /dev/null +++ b/src/3ds/system.c @@ -0,0 +1,48 @@ +#include "system.h" +#include <3ds.h> +#include "../PHL.h" +#include +#include + +int quitGame = 0; + +int PHL_MainLoop() +{ + if (quitGame == 1) { + return 0; + } + + return aptMainLoop(); +} + +void PHL_ConsoleInit() +{ + consoleInit(activeScreen->screen, NULL); +} + +void PHL_GameQuit() +{ + quitGame = 1; +} + +void PHL_ErrorScreen(char* message) +{ + consoleInit(GFX_TOP, NULL); + + printf(message); + printf("\n\nPress START to close"); + + u32 kDown; + while (PHL_MainLoop()) { + //gfxFlushBuffers(); + //gfxSwapBuffers(); + hidScanInput(); + kDown = hidKeysHeld(); + + if (kDown & KEY_START) { break; } + + gspWaitForVBlank(); + } + + exit(1); +} \ No newline at end of file diff --git a/src/3ds/system.h b/src/3ds/system.h new file mode 100644 index 0000000..c29d25f --- /dev/null +++ b/src/3ds/system.h @@ -0,0 +1,12 @@ +#ifndef SYSTEM_H +#define SYSTEM_H + +//int quitGame; + +int PHL_MainLoop(); +void PHL_ConsoleInit(); +void PHL_GameQuit(); + +void PHL_ErrorScreen(char* message); + +#endif \ No newline at end of file -- cgit v1.2.3