mirror of
https://github.com/RocketRobz/SuperAllStarPhotoStudio.git
synced 2025-06-18 17:15:35 -04:00
More DS(i) prep work
Now compiles
This commit is contained in:
parent
1d573d0349
commit
36e2c2278d
@ -23,8 +23,8 @@ makearm9:
|
||||
cp arm9/$(TARGET).elf $(TARGET).arm9.elf
|
||||
|
||||
$(TARGET).nds: makearm7 makearm9
|
||||
ndstool -u 00030004 -g HPHA -c $(TARGET).nds -7 $(TARGET).arm7.elf -9 $(TARGET).arm9.elf -d $(NITRODATA) \
|
||||
-b icon.bmp "Super Photo Studio;RocketRobz"
|
||||
ndstool -c $(TARGET).nds -7 $(TARGET).arm7.elf -9 $(TARGET).arm9.elf -d $(NITRODATA) \
|
||||
-g HPHA 00 "SUPERPHOTO" -z 80040000 -u 00030004 -a 00000138 -b icon.bmp "Super Photo Studio;RocketRobz"
|
||||
|
||||
clean:
|
||||
@echo clean ...
|
||||
|
11
nds/arm9/ds_arm9_hi.mem
Normal file
11
nds/arm9/ds_arm9_hi.mem
Normal file
@ -0,0 +1,11 @@
|
||||
/*--------------------------------------------------------------------------------
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License,
|
||||
v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
obtain one at https://mozilla.org/MPL/2.0/.
|
||||
--------------------------------------------------------------------------------*/
|
||||
MEMORY {
|
||||
ewram : ORIGIN = 0x02004000, LENGTH = 3M + 512K - 0x4000
|
||||
dtcm : ORIGIN = 0x0b000000, LENGTH = 16K
|
||||
vectors : ORIGIN = 0x01000000, LENGTH = 256
|
||||
itcm : ORIGIN = 0x01000100, LENGTH = 32K - 256
|
||||
}
|
8
nds/arm9/ds_arm9_hi.specs
Normal file
8
nds/arm9/ds_arm9_hi.specs
Normal file
@ -0,0 +1,8 @@
|
||||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T ../ds_arm9_hi.mem%s -T ds_arm9.ld%s --gc-sections
|
||||
|
||||
*startfile:
|
||||
ds_arm9_crt0%O%s crti%O%s crtbegin%O%s
|
||||
|
113
nds/arm9/include/nitrofs.h
Normal file
113
nds/arm9/include/nitrofs.h
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
nitrofs.h - eris's wai ossum nitro filesystem device driver header
|
||||
Based on information found at http://frangoassado.org/ds/rom_spec.txt and from the #dsdev ppls
|
||||
Kallisti (K) 2008-01-26 All rights reversed.
|
||||
|
||||
2008-05-19 v0.2 - New And Improved!! :DDD
|
||||
* fix'd the fseek SEEK_CUR issue (my fseek funct should not have returned a value :/)
|
||||
* also thx to wintermute's input realized:
|
||||
* if you dont give ndstool the -o wifilogo.bmp option it will run on emulators in gba mode
|
||||
* you then dont need the gba's LOADEROFFSET, so it was set to 0x000
|
||||
|
||||
2008-05-21 v0.3 - newer and more improved
|
||||
* fixed some issues with ftell() (again was fseek's fault u_u;;)
|
||||
* fixed possible error in detecting sc.gba files when using dldi
|
||||
* readded support for .gba files in addition to .nds emu
|
||||
* added stat() support for completedness :)
|
||||
|
||||
2008-05-30 v0.5.Turbo - major speed improvement
|
||||
* This version uses a single filehandle to access the .nds file when not in GBA mode
|
||||
improving the speed it takes to open a .nds file by around 106ms. This is great for
|
||||
situations requiring reading alot of seperate small files. However it does take a little
|
||||
bit longer when reading from multiple files simultainously
|
||||
(around 122ms over 10,327 0x100 byte reads between 2 files).
|
||||
2008-06-09
|
||||
* Fixed bug with SEEK_END where it wouldnt utilize the submitted position..
|
||||
(now can fseek(f,-128,SEEK_END) to read from end of file :D)
|
||||
|
||||
2008-06-18 v0.6.Turbo - . and .. :D
|
||||
* Today i have added full "." and ".." support.
|
||||
dirnext() will return . and .. first, and all relevent operations will
|
||||
support . and .. in pathnames.
|
||||
|
||||
2018-09-05 v0.9 - modernize devoptab (by RonnChyran)
|
||||
* Updated for libsysbase change in devkitARM r46 and above.
|
||||
*/
|
||||
|
||||
#ifndef NITROFS_H
|
||||
#define NITROFS_H
|
||||
|
||||
#include <sys/dir.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int nitroFSInit(const char *ndsfile);
|
||||
DIR_ITER *nitroFSDirOpen(struct _reent *r, DIR_ITER *dirState, const char *path);
|
||||
int nitroDirReset(struct _reent *r, DIR_ITER *dirState);
|
||||
int nitroFSDirNext(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st);
|
||||
int nitroFSDirClose(struct _reent *r, DIR_ITER *dirState);
|
||||
int nitroFSOpen(struct _reent *r, void *fileStruct, const char *path, int flags, int mode);
|
||||
int nitroFSClose(struct _reent *r, void *fd);
|
||||
ssize_t nitroFSRead(struct _reent *r, void *fd, char *ptr, size_t len);
|
||||
off_t nitroFSSeek(struct _reent *r, void *fd, off_t pos, int dir);
|
||||
int nitroFSFstat(struct _reent *r, void *fd, struct stat *st);
|
||||
int nitroFSstat(struct _reent *r, const char *file, struct stat *st);
|
||||
int nitroFSChdir(struct _reent *r, const char *name);
|
||||
#define LOADERSTR "PASS" //look for this
|
||||
#define LOADERSTROFFSET 0xac
|
||||
#define LOADEROFFSET 0x0200
|
||||
#define FNTOFFSET 0x40
|
||||
#define FATOFFSET 0x48
|
||||
|
||||
#define NITRONAMELENMAX 0x80 //max file name is 127 +1 for zero byte :D
|
||||
#define NITROMAXPATHLEN 0x100 //256 bytes enuff?
|
||||
|
||||
#define NITROROOT 0xf000 //root entry_file_id
|
||||
#define NITRODIRMASK 0x0fff //remove leading 0xf
|
||||
|
||||
#define NITROISDIR 0x80 //mask to indicate this name entry is a dir, other 7 bits = name length
|
||||
|
||||
//Directory filename subtable entry structure
|
||||
struct ROM_FNTDir
|
||||
{
|
||||
u32 entry_start;
|
||||
u16 entry_file_id;
|
||||
u16 parent_id;
|
||||
};
|
||||
|
||||
//Yo, dis table is fat (describes the structures
|
||||
struct ROM_FAT
|
||||
{
|
||||
u32 top; //start of file in rom image
|
||||
u32 bottom; //end of file in rom image
|
||||
};
|
||||
|
||||
struct nitroFSStruct
|
||||
{
|
||||
off_t pos; //where in the file am i?
|
||||
off_t start; //where in the rom this file starts
|
||||
off_t end; //where in the rom this file ends
|
||||
};
|
||||
|
||||
struct nitroDIRStruct
|
||||
{
|
||||
off_t pos; //where in the file am i?
|
||||
off_t namepos; //ptr to next name to lookup in list
|
||||
struct ROM_FAT romfat;
|
||||
u16 entry_id; //which entry this is (for files only) incremented with each new file in dir?
|
||||
u16 dir_id; //which directory entry this is.. used ofc for dirs only
|
||||
u16 cur_dir_id; //which directory entry we are using
|
||||
u16 parent_id; //who is the parent of the current directory (this can be used to easily ../ )
|
||||
u8 spc; //system path count.. used by dirnext, when 0=./ 1=../ >=2 actual dirs
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -28,6 +28,7 @@
|
||||
#include "screenCommon.hpp"
|
||||
|
||||
#include <nds.h>
|
||||
#include <gl2d.h>
|
||||
#include <unistd.h>
|
||||
|
||||
std::unique_ptr<Screen> usedScreen, tempScreen; // tempScreen used for "fade" effects.
|
||||
@ -46,6 +47,46 @@ void Gui::DrawSprite(int x, int y, float ScaleX, float ScaleY) {
|
||||
|
||||
// Initialize GUI.
|
||||
void Gui::init(void) {
|
||||
//////////////////////////////////////////////////////////
|
||||
videoSetMode(MODE_5_3D | DISPLAY_BG3_ACTIVE);
|
||||
videoSetModeSub(MODE_3_2D | DISPLAY_BG3_ACTIVE);
|
||||
|
||||
// Initialize gl2d
|
||||
glScreen2D();
|
||||
// Make gl2d render on transparent stage.
|
||||
glClearColor(31, 31, 31, 0);
|
||||
glDisable(GL_CLEAR_BMP);
|
||||
|
||||
// Clear the GL texture state
|
||||
glResetTextures();
|
||||
|
||||
// Set up enough texture memory for our textures
|
||||
// Bank A is just 128kb and we are using 194 kb of
|
||||
// sprites
|
||||
vramSetBankA(VRAM_A_TEXTURE);
|
||||
vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
|
||||
vramSetBankC(VRAM_C_SUB_BG_0x06200000);
|
||||
vramSetBankD(VRAM_D_MAIN_BG_0x06000000);
|
||||
vramSetBankE(VRAM_E_TEX_PALETTE);
|
||||
vramSetBankF(VRAM_F_TEX_PALETTE_SLOT4);
|
||||
vramSetBankG(VRAM_G_MAIN_SPRITE);
|
||||
vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE);
|
||||
vramSetBankI(VRAM_I_SUB_SPRITE_EXT_PALETTE);
|
||||
|
||||
// vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE); // Not sure this does anything...
|
||||
lcdMainOnBottom();
|
||||
|
||||
int bg3Main = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
|
||||
bgSetPriority(bg3Main, 3);
|
||||
|
||||
int bg2Main = bgInit(2, BgType_Bmp8, BgSize_B8_256x256, 6, 0);
|
||||
nocashMessage(std::to_string(bg2Main).c_str());
|
||||
bgSetPriority(bg2Main, 0);
|
||||
|
||||
int bg3Sub = bgInitSub(3, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
|
||||
bgSetPriority(bg3Sub, 3);
|
||||
|
||||
bgSetPriority(0, 1); // Set 3D to below text
|
||||
}
|
||||
|
||||
// Load a Font.
|
||||
|
@ -10,13 +10,45 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nitrofs.h"
|
||||
#include "photoStudio.hpp"
|
||||
#include "rocketRobz.hpp"
|
||||
#include "screen.hpp"
|
||||
|
||||
bool isInit = true;
|
||||
bool exiting = false;
|
||||
bool rocketRobzScreen = true;
|
||||
int delay = 0;
|
||||
|
||||
char verText[32];
|
||||
int studioBg = 0;
|
||||
int iFps = 60;
|
||||
|
||||
bool renderTop = true; // Disable to prevent second character from flickering
|
||||
|
||||
void Play_Music(void) {
|
||||
}
|
||||
|
||||
void sndSelect(void) {
|
||||
}
|
||||
|
||||
void sndBack(void) {
|
||||
}
|
||||
|
||||
void sndHighlight(void) {
|
||||
}
|
||||
|
||||
bool showCursor = false;
|
||||
int cursorAlpha = 0;
|
||||
|
||||
u32 hDown = 0;
|
||||
u32 hHeld = 0;
|
||||
touchPosition touch;
|
||||
|
||||
bool touchingBackButton(void) {
|
||||
return (touch.px >= 5 && touch.px < 5+32 && touch.py >= 158 && touch.py < 158+34);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void stop(void) {
|
||||
//---------------------------------------------------------------------------------
|
||||
@ -38,6 +70,22 @@ void doPause() {
|
||||
int main(int argc, char **argv) {
|
||||
defaultExceptionHandler();
|
||||
|
||||
if (!fatInitDefault()) {
|
||||
consoleDemoInit();
|
||||
iprintf("fatInitDefault failed!");
|
||||
stop();
|
||||
}
|
||||
|
||||
if (!nitroFSInit(argv[0])) {
|
||||
consoleDemoInit();
|
||||
iprintf("NitroFS init failed!");
|
||||
stop();
|
||||
}
|
||||
|
||||
Gui::init();
|
||||
|
||||
Gui::setScreen(std::make_unique<RocketRobz>(), false); // Set screen to product identification.
|
||||
|
||||
while (1) {
|
||||
// Scan hid shared memory for input events
|
||||
scanKeys();
|
||||
@ -45,10 +93,30 @@ int main(int argc, char **argv) {
|
||||
hDown = keysDown();
|
||||
hHeld = keysHeld();
|
||||
|
||||
if (exiting) {
|
||||
if (!fadeout) break;
|
||||
}
|
||||
|
||||
if (isInit) {
|
||||
delay++;
|
||||
if (rocketRobzScreen) {
|
||||
if (delay > iFps*9) {
|
||||
Gui::setScreen(std::make_unique<PhotoStudio>(), true); // Set after delay to the photo studio.
|
||||
isInit = false;
|
||||
}
|
||||
} else
|
||||
if (delay > iFps*6) {
|
||||
fadeout = true;
|
||||
fadealpha = 255;
|
||||
Gui::setScreen(std::make_unique<RocketRobz>(), true); // Set after delay to RocketRobz's screen.
|
||||
rocketRobzScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
touchRead(&touch);
|
||||
|
||||
Gui::setScreen(std::make_unique<RocketRobz>(), false); // Set screen to product identification.
|
||||
Gui::ScreenLogic(hDown, hHeld, touch, true); // Call the logic of the current screen here.
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
477
nds/arm9/source/nitrofs.c
Normal file
477
nds/arm9/source/nitrofs.c
Normal file
@ -0,0 +1,477 @@
|
||||
/*
|
||||
nitrofs.c - eris's wai ossum nitro filesystem device driver
|
||||
Based on information found at http://frangoassado.org/ds/rom_spec.txt and from the #dsdev ppls
|
||||
Kallisti (K) 2008-01-26 All rights reversed.
|
||||
|
||||
2008-05-19 v0.2 - New And Improved!! :DDD
|
||||
* fix'd the fseek SEEK_CUR issue (my fseek funct should not have returned a value :/)
|
||||
* also thx to wintermute's input realized:
|
||||
* if you dont give ndstool the -o wifilogo.bmp option it will run on emulators in gba mode
|
||||
* you then dont need the gba's LOADEROFFSET, so it was set to 0x000
|
||||
|
||||
2008-05-21 v0.3 - newer and more improved
|
||||
* fixed some issues with ftell() (again was fseek's fault u_u;;)
|
||||
* fixed possible error in detecting sc.gba files when using dldi
|
||||
* readded support for .gba files in addition to .nds emu
|
||||
* added stat() support for completedness :)
|
||||
|
||||
2008-05-22 v0.3.1 - slight update
|
||||
* again fixed fseek(), this time SEEK_END oddly i kinda forgot about it >_> sry
|
||||
* also went ahead and inlined the functions, makes slight proformance improvement
|
||||
|
||||
2008-05-26 v0.4 - added chdir
|
||||
* added proper chdir functionality
|
||||
|
||||
2008-05-30 v0.5.Turbo - major speed improvement
|
||||
* This version uses a single filehandle to access the .nds file when not in GBA mode
|
||||
improving the speed it takes to open a .nds file by around 106ms. This is great for
|
||||
situations requiring reading alot of seperate small files. However it does take a little
|
||||
bit longer when reading from multiple files simultainously
|
||||
(around 122ms over 10,327 0x100 byte reads between 2 files).
|
||||
2008-06-09
|
||||
* Fixed bug with SEEK_END where it wouldnt utilize the submitted position..
|
||||
(now can fseek(f,-128,SEEK_END) to read from end of file :D)
|
||||
|
||||
2008-06-18 v0.6.Turbo - . and .. :D
|
||||
* Today i have added full "." and ".." support.
|
||||
dirnext() will return . and .. first, and all relevent operations will
|
||||
support . and .. in pathnames.
|
||||
|
||||
2009-05-10 v0.7.Turbo - small changes @_@?!
|
||||
|
||||
2009-08-08 v0.8.Turbo - fix fix fix
|
||||
* fixed problem with some cards where the header would be loaded to GBA ram even if running
|
||||
in NDS mode causing nitroFSInit() to think it was a valid GBA cart header and attempt to
|
||||
read from GBA SLOT instead of SLOT 1. Fixed this by making it check that filename is not NULL
|
||||
and then to try FAT/SLOT1 first. The NULL option allows forcing nitroFS to use gba.
|
||||
|
||||
2018-09-05 v0.9 - modernize devoptab (by RonnChyran)
|
||||
* Updated for libsysbase change in devkitARM r46 and above.
|
||||
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <nds.h>
|
||||
#include "nitrofs.h"
|
||||
#include "tonccpy.h"
|
||||
|
||||
//This seems to be a typo! memory.h has REG_EXEMEMCNT
|
||||
#ifndef REG_EXMEMCNT
|
||||
#define REG_EXMEMCNT (*(vuint16 *)0x04000204)
|
||||
#endif
|
||||
|
||||
#define __itcm __attribute__((section(".itcm")))
|
||||
|
||||
//Globals!
|
||||
u32 fntOffset; //offset to start of filename table
|
||||
u32 fatOffset; //offset to start of file alloc table
|
||||
bool hasLoader; //single global nds filehandle (is null if not in dldi/fat mode)
|
||||
u16 chdirpathid; //default dir path id...
|
||||
FILE *ndsFile;
|
||||
off_t ndsFileLastpos; //Used to determine need to fseek or not
|
||||
|
||||
devoptab_t nitroFSdevoptab = {
|
||||
"nitro", // const char *name;
|
||||
sizeof(struct nitroFSStruct), // int structSize;
|
||||
&nitroFSOpen, // int (*open_r)(struct _reent *r, void *fileStruct, const char *path,int flags,int mode);
|
||||
&nitroFSClose, // int (*close_r)(struct _reent *r,void* fd);
|
||||
NULL, // int (*write_r)(struct _reent *r,void* fd,const char *ptr,int len);
|
||||
&nitroFSRead, // int (*read_r)(struct _reent *r,void* fd,char *ptr,int len);
|
||||
&nitroFSSeek, // int (*seek_r)(struct _reent *r,void* fd,int pos,int dir);
|
||||
&nitroFSFstat, // int (*fstat_r)(struct _reent *r,void* fd,struct stat *st);
|
||||
&nitroFSstat, // int (*stat_r)(struct _reent *r,const char *file,struct stat *st);
|
||||
NULL, // int (*link_r)(struct _reent *r,const char *existing, const char *newLink);
|
||||
NULL, // int (*unlink_r)(struct _reent *r,const char *name);
|
||||
&nitroFSChdir, // int (*chdir_r)(struct _reent *r,const char *name);
|
||||
NULL, // int (*rename_r) (struct _reent *r, const char *oldName, const char *newName);
|
||||
NULL, // int (*mkdir_r) (struct _reent *r, const char *path, int mode);
|
||||
sizeof(struct nitroDIRStruct), // int dirStateSize;
|
||||
&nitroFSDirOpen, // DIR_ITER* (*diropen_r)(struct _reent *r, DIR_ITER *dirState, const char *path);
|
||||
&nitroDirReset, // int (*dirreset_r)(struct _reent *r, DIR_ITER *dirState);
|
||||
&nitroFSDirNext, // int (*dirnext_r)(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat);
|
||||
&nitroFSDirClose // int (*dirclose_r)(struct _reent *r, DIR_ITER *dirState);
|
||||
|
||||
};
|
||||
|
||||
//K, i decided to inline these, improves speed slightly..
|
||||
//these 2 'sub' functions deal with actually reading from either gba rom or .nds file :)
|
||||
//what i rly rly rly wanna know is how an actual nds cart reads from itself, but it seems no one can tell me ~_~
|
||||
//so, instead we have this weird weird haxy try gbaslot then try dldi method. If i (or you!!) ever do figure out
|
||||
//how to read the proper way can replace these 4 functions and everything should work normally :)
|
||||
|
||||
//reads from rom image either gba rom or dldi
|
||||
inline ssize_t nitroSubRead(off_t *npos, void *ptr, size_t len)
|
||||
{
|
||||
if (ndsFile != NULL)
|
||||
{ //read from ndsfile
|
||||
if (ndsFileLastpos != *npos)
|
||||
fseek(ndsFile, *npos, SEEK_SET); //if we need to, move! (might want to verify this succeed)
|
||||
len = fread(ptr, 1, len, ndsFile);
|
||||
}
|
||||
else
|
||||
{ //reading from gbarom
|
||||
tonccpy(ptr, *npos + (void *)GBAROM, len); //len isnt checked here because other checks exist in the callers (hopefully)
|
||||
}
|
||||
if (len > 0)
|
||||
*npos += len;
|
||||
ndsFileLastpos = *npos; //save the current file nds pos
|
||||
return (len);
|
||||
}
|
||||
|
||||
//seek around
|
||||
inline void nitroSubSeek(off_t *npos, int pos, int dir)
|
||||
{
|
||||
if ((dir == SEEK_SET) || (dir == SEEK_END)) //otherwise just set the pos :)
|
||||
*npos = pos;
|
||||
else if (dir == SEEK_CUR)
|
||||
*npos += pos; //see ez!
|
||||
}
|
||||
|
||||
//Figure out if its gba or ds, setup stuff
|
||||
int __itcm
|
||||
nitroFSInit(const char *ndsfile)
|
||||
{
|
||||
off_t pos = 0;
|
||||
char romstr[0x10];
|
||||
chdirpathid = NITROROOT;
|
||||
ndsFileLastpos = 0;
|
||||
ndsFile = NULL;
|
||||
if (ndsfile != NULL)
|
||||
{
|
||||
if ((ndsFile = fopen(ndsfile, "rb")))
|
||||
{
|
||||
nitroSubRead(&pos, romstr, strlen(LOADERSTR));
|
||||
if (strncmp(romstr, LOADERSTR, strlen(LOADERSTR)) == 0)
|
||||
{
|
||||
nitroSubSeek(&pos, LOADEROFFSET + FNTOFFSET, SEEK_SET);
|
||||
nitroSubRead(&pos, &fntOffset, sizeof(fntOffset));
|
||||
nitroSubSeek(&pos, LOADEROFFSET + FATOFFSET, SEEK_SET);
|
||||
nitroSubRead(&pos, &fatOffset, sizeof(fatOffset));
|
||||
fatOffset += LOADEROFFSET;
|
||||
fntOffset += LOADEROFFSET;
|
||||
hasLoader = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
nitroSubSeek(&pos, FNTOFFSET, SEEK_SET);
|
||||
nitroSubRead(&pos, &fntOffset, sizeof(fntOffset));
|
||||
nitroSubSeek(&pos, FATOFFSET, SEEK_SET);
|
||||
nitroSubRead(&pos, &fatOffset, sizeof(fatOffset));
|
||||
hasLoader = false;
|
||||
}
|
||||
setvbuf(ndsFile, NULL, _IONBF, 0); //we dont need double buffs u_u
|
||||
AddDevice(&nitroFSdevoptab);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
REG_EXMEMCNT &= ~ARM7_OWNS_CARD; //give us gba slot ownership
|
||||
if (strncmp(((const char *)GBAROM) + LOADERSTROFFSET, LOADERSTR, strlen(LOADERSTR)) == 0)
|
||||
{ // We has gba rahm
|
||||
printf("yes i think this is GBA?!\n");
|
||||
if (strncmp(((const char *)GBAROM) + LOADERSTROFFSET + LOADEROFFSET, LOADERSTR, strlen(LOADERSTR)) == 0)
|
||||
{ //Look for second magic string, if found its a sc.nds or nds.gba
|
||||
printf("sc/gba\n");
|
||||
fntOffset = ((u32) * (u32 *)(((const char *)GBAROM) + FNTOFFSET + LOADEROFFSET)) + LOADEROFFSET;
|
||||
fatOffset = ((u32) * (u32 *)(((const char *)GBAROM) + FATOFFSET + LOADEROFFSET)) + LOADEROFFSET;
|
||||
hasLoader = true;
|
||||
AddDevice(&nitroFSdevoptab);
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
{ //Ok, its not a .gba build, so must be emulator
|
||||
printf("gba, must be emu\n");
|
||||
fntOffset = ((u32) * (u32 *)(((const char *)GBAROM) + FNTOFFSET));
|
||||
fatOffset = ((u32) * (u32 *)(((const char *)GBAROM) + FATOFFSET));
|
||||
hasLoader = false;
|
||||
AddDevice(&nitroFSdevoptab);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
//Directory functs
|
||||
DIR_ITER *nitroFSDirOpen(struct _reent *r, DIR_ITER *dirState, const char *path)
|
||||
{
|
||||
struct nitroDIRStruct *dirStruct = (struct nitroDIRStruct *)dirState->dirStruct; //this makes it lots easier!
|
||||
struct stat st;
|
||||
char dirname[NITRONAMELENMAX];
|
||||
char *cptr;
|
||||
char mydirpath[NITROMAXPATHLEN]; //to hold copy of path string
|
||||
char *dirpath = mydirpath;
|
||||
bool pathfound;
|
||||
if ((cptr = strchr(path, ':')))
|
||||
path = cptr + 1; //move path past any device names (if it was nixy style wouldnt need this step >_>)
|
||||
strncpy(dirpath, path, sizeof(mydirpath) - 1); //copy the string (as im gonna mutalate it)
|
||||
dirStruct->pos = 0;
|
||||
if (*dirpath == '/') //if first character is '/' use absolute root path plz
|
||||
dirStruct->cur_dir_id = NITROROOT; //first root dir
|
||||
else
|
||||
dirStruct->cur_dir_id = chdirpathid; //else use chdirpath
|
||||
nitroDirReset(r, dirState); //set dir to current path
|
||||
do
|
||||
{
|
||||
while ((cptr = strchr(dirpath, '/')) == dirpath)
|
||||
{
|
||||
dirpath++; //move past any leading / or // together
|
||||
}
|
||||
if (cptr)
|
||||
*cptr = 0; //erase /
|
||||
if (*dirpath == 0)
|
||||
{ //are we at the end of the path string?? if so there is nothing to search for we're already here !
|
||||
pathfound = true; //mostly this handles searches for root or / or no path specified cases
|
||||
break;
|
||||
}
|
||||
pathfound = false;
|
||||
while (nitroFSDirNext(r, dirState, dirname, &st) == 0)
|
||||
{
|
||||
if ((st.st_mode == S_IFDIR) && !(strcmp(dirname, dirpath)))
|
||||
{ //if its a directory and name matches dirpath
|
||||
dirStruct->cur_dir_id = dirStruct->dir_id; //move us to the next dir in tree
|
||||
nitroDirReset(r, dirState); //set dir to current path we just found...
|
||||
pathfound = true;
|
||||
break;
|
||||
}
|
||||
};
|
||||
if (!pathfound)
|
||||
break;
|
||||
dirpath = cptr + 1; //move to right after last / we found
|
||||
} while (cptr); // go till after the last /
|
||||
if (pathfound)
|
||||
{
|
||||
return (dirState);
|
||||
}
|
||||
else
|
||||
{
|
||||
r->_errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int nitroFSDirClose(struct _reent *r, DIR_ITER *dirState)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*Consts containing relative system path strings*/
|
||||
const char *syspaths[2] = {
|
||||
".",
|
||||
".."};
|
||||
|
||||
//reset dir to start of entry selected by dirStruct->cur_dir_id which should be set in dirOpen okai?!
|
||||
int nitroDirReset(struct _reent *r, DIR_ITER *dirState)
|
||||
{
|
||||
struct nitroDIRStruct *dirStruct = (struct nitroDIRStruct *)dirState->dirStruct; //this makes it lots easier!
|
||||
struct ROM_FNTDir dirsubtable;
|
||||
off_t *pos = &dirStruct->pos;
|
||||
nitroSubSeek(pos, fntOffset + ((dirStruct->cur_dir_id & NITRODIRMASK) * sizeof(struct ROM_FNTDir)), SEEK_SET);
|
||||
nitroSubRead(pos, &dirsubtable, sizeof(dirsubtable));
|
||||
dirStruct->namepos = dirsubtable.entry_start; //set namepos to first entry in this dir's table
|
||||
dirStruct->entry_id = dirsubtable.entry_file_id; //get number of first file ID in this branch
|
||||
dirStruct->parent_id = dirsubtable.parent_id; //save parent ID in case we wanna add ../ functionality
|
||||
dirStruct->spc = 0; //system path counter, first two dirnext's deliver . and ..
|
||||
return (0);
|
||||
}
|
||||
|
||||
int nitroFSDirNext(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st)
|
||||
{
|
||||
unsigned char next;
|
||||
struct nitroDIRStruct *dirStruct = (struct nitroDIRStruct *)dirState->dirStruct; //this makes it lots easier!
|
||||
off_t *pos = &dirStruct->pos;
|
||||
if (dirStruct->spc <= 1)
|
||||
{
|
||||
if (st)
|
||||
st->st_mode = S_IFDIR;
|
||||
if ((dirStruct->spc == 0) || (dirStruct->cur_dir_id == NITROROOT))
|
||||
{ // "." or its already root (no parent)
|
||||
dirStruct->dir_id = dirStruct->cur_dir_id;
|
||||
}
|
||||
else
|
||||
{ // ".."
|
||||
dirStruct->dir_id = dirStruct->parent_id;
|
||||
}
|
||||
strcpy(filename, syspaths[dirStruct->spc++]);
|
||||
return (0);
|
||||
}
|
||||
nitroSubSeek(pos, fntOffset + dirStruct->namepos, SEEK_SET);
|
||||
nitroSubRead(pos, &next, sizeof(next));
|
||||
// next: high bit 0x80 = entry isdir.. other 7 bits r size, the 16 bits following name are dir's entryid (starts with f000)
|
||||
// 00 = endoftable //
|
||||
if (next)
|
||||
{
|
||||
if (next & NITROISDIR)
|
||||
{
|
||||
if (st)
|
||||
st->st_mode = S_IFDIR;
|
||||
next &= NITROISDIR ^ 0xff; //invert bits and mask off 0x80
|
||||
nitroSubRead(pos, filename, next);
|
||||
nitroSubRead(&dirStruct->pos, &dirStruct->dir_id, sizeof(dirStruct->dir_id)); //read the dir_id
|
||||
//grr cant get the struct member size?, just wanna test it so moving on...
|
||||
// nitroSubRead(pos,&dirStruct->dir_id,sizeof(u16)); //read the dir_id
|
||||
dirStruct->namepos += next + sizeof(u16) + 1; //now we points to next one plus dir_id size:D
|
||||
}
|
||||
else
|
||||
{
|
||||
if (st)
|
||||
st->st_mode = 0;
|
||||
nitroSubRead(pos, filename, next);
|
||||
dirStruct->namepos += next + 1; //now we points to next one :D
|
||||
//read file info to get filesize (and for fileopen)
|
||||
nitroSubSeek(pos, fatOffset + (dirStruct->entry_id * sizeof(struct ROM_FAT)), SEEK_SET);
|
||||
nitroSubRead(pos, &dirStruct->romfat, sizeof(dirStruct->romfat)); //retrieve romfat entry (contains filestart and end positions)
|
||||
dirStruct->entry_id++; //advance ROM_FNTStrFile ptr
|
||||
if (st)
|
||||
st->st_size = dirStruct->romfat.bottom - dirStruct->romfat.top; //calculate filesize
|
||||
}
|
||||
filename[(int)next] = 0; //zero last char
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
r->_errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
//fs functs
|
||||
int nitroFSOpen(struct _reent *r, void *fileStruct, const char *path, int flags, int mode)
|
||||
{
|
||||
struct nitroFSStruct *fatStruct = (struct nitroFSStruct *)fileStruct;
|
||||
struct nitroDIRStruct dirStruct;
|
||||
DIR_ITER dirState;
|
||||
dirState.dirStruct = &dirStruct; //create a temp dirstruct
|
||||
struct _reent dre;
|
||||
struct stat st; //all these are just used for reading the dir ~_~
|
||||
char dirfilename[NITROMAXPATHLEN]; // to hold a full path (i tried to avoid using so much stack but blah :/)
|
||||
char *filename; // to hold filename
|
||||
char *cptr; //used to string searching and manipulation
|
||||
cptr = (char *)path + strlen(path); //find the end...
|
||||
filename = NULL;
|
||||
do
|
||||
{
|
||||
if ((*cptr == '/') || (*cptr == ':'))
|
||||
{ // split at either / or : (whichever comes first form the end!)
|
||||
cptr++;
|
||||
strncpy(dirfilename, path, cptr - path); //copy string up till and including/ or : zero rest
|
||||
dirfilename[cptr - path] = 0; //it seems strncpy doesnt always zero?!
|
||||
filename = cptr; //filename = now remainder of string
|
||||
break;
|
||||
}
|
||||
} while (cptr-- != path); //search till start
|
||||
if (!filename)
|
||||
{ //we didnt find a / or : ? shouldnt realyl happen but if it does...
|
||||
filename = (char *)path; //filename = complete path
|
||||
dirfilename[0] = 0; //make directory path ""
|
||||
}
|
||||
if (nitroFSDirOpen(&dre, &dirState, dirfilename))
|
||||
{
|
||||
fatStruct->start = 0;
|
||||
while (nitroFSDirNext(&dre, &dirState, dirfilename, &st) == 0)
|
||||
{
|
||||
if (!(st.st_mode & S_IFDIR) && (strcmp(dirfilename, filename) == 0))
|
||||
{ //Found the *file* youre looking for!!
|
||||
fatStruct->start = dirStruct.romfat.top;
|
||||
fatStruct->end = dirStruct.romfat.bottom;
|
||||
if (hasLoader)
|
||||
{
|
||||
fatStruct->start += LOADEROFFSET;
|
||||
fatStruct->end += LOADEROFFSET;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fatStruct->start)
|
||||
{
|
||||
nitroSubSeek(&fatStruct->pos, fatStruct->start, SEEK_SET); //seek to start of file
|
||||
return (0); //woot!
|
||||
}
|
||||
nitroFSDirClose(&dre, &dirState);
|
||||
}
|
||||
if (r->_errno == 0)
|
||||
{
|
||||
r->_errno = ENOENT;
|
||||
}
|
||||
return (-1); //teh fail
|
||||
}
|
||||
|
||||
int nitroFSClose(struct _reent *r, void* fd)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
ssize_t nitroFSRead(struct _reent *r, void* fd, char *ptr, size_t len)
|
||||
{
|
||||
struct nitroFSStruct *fatStruct = (struct nitroFSStruct *)fd;
|
||||
off_t *npos = &fatStruct->pos;
|
||||
if (*npos + len > fatStruct->end)
|
||||
len = fatStruct->end - *npos; //dont let us read past the end plz!
|
||||
if (*npos > fatStruct->end)
|
||||
return (0); //hit eof
|
||||
return (nitroSubRead(npos, ptr, len));
|
||||
}
|
||||
|
||||
off_t nitroFSSeek(struct _reent *r, void* fd, off_t pos, int dir)
|
||||
{
|
||||
//need check for eof here...
|
||||
struct nitroFSStruct *fatStruct = (struct nitroFSStruct *)fd;
|
||||
off_t *npos = &fatStruct->pos;
|
||||
if (dir == SEEK_SET)
|
||||
pos += fatStruct->start; //add start from .nds file offset
|
||||
else if (dir == SEEK_END)
|
||||
pos += fatStruct->end; //set start to end of file (useless?)
|
||||
if (pos > fatStruct->end)
|
||||
return (-1); //dont let us read past the end plz!
|
||||
nitroSubSeek(npos, pos, dir);
|
||||
return (*npos - fatStruct->start);
|
||||
}
|
||||
|
||||
int nitroFSFstat(struct _reent *r, void* fd, struct stat *st)
|
||||
{
|
||||
struct nitroFSStruct *fatStruct = (struct nitroFSStruct *)fd;
|
||||
st->st_size = fatStruct->end - fatStruct->start;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int nitroFSstat(struct _reent *r, const char *file, struct stat *st)
|
||||
{
|
||||
struct nitroFSStruct fatStruct;
|
||||
struct nitroDIRStruct dirStruct;
|
||||
DIR_ITER dirState;
|
||||
|
||||
if (nitroFSOpen(NULL, &fatStruct, file, 0, 0) >= 0)
|
||||
{
|
||||
st->st_mode = S_IFREG;
|
||||
st->st_size = fatStruct.end - fatStruct.start;
|
||||
return (0);
|
||||
}
|
||||
|
||||
dirState.dirStruct = &dirStruct;
|
||||
if ((nitroFSDirOpen(r, &dirState, file) != NULL))
|
||||
{
|
||||
|
||||
st->st_mode = S_IFDIR;
|
||||
nitroFSDirClose(r, &dirState);
|
||||
return (0);
|
||||
}
|
||||
r->_errno = ENOENT;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int nitroFSChdir(struct _reent *r, const char *name)
|
||||
{
|
||||
struct nitroDIRStruct dirStruct;
|
||||
DIR_ITER dirState;
|
||||
dirState.dirStruct = &dirStruct;
|
||||
if ((name != NULL) && (nitroFSDirOpen(r, &dirState, name) != NULL))
|
||||
{
|
||||
chdirpathid = dirStruct.cur_dir_id;
|
||||
nitroFSDirClose(r, &dirState);
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
r->_errno = ENOENT;
|
||||
return (-1);
|
||||
}
|
||||
}
|
BIN
nds/icon.bmp
Normal file
BIN
nds/icon.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 630 B |
@ -35,6 +35,9 @@
|
||||
#define KEY_DRIGHT KEY_RIGHT
|
||||
#define KEY_ZL KEY_L
|
||||
#define KEY_ZR KEY_R
|
||||
|
||||
void gspWaitForVBlank(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static int charPageOrder[] = {
|
||||
@ -251,6 +254,7 @@ const char* PhotoStudio::import_characterFileName(void) const {
|
||||
}
|
||||
|
||||
const char* PhotoStudio::import_SS2CharacterNames(int i) const {
|
||||
#ifdef _3DS
|
||||
switch (sysRegion) {
|
||||
default:
|
||||
return import_ss2CharacterNames[i];
|
||||
@ -258,9 +262,13 @@ const char* PhotoStudio::import_SS2CharacterNames(int i) const {
|
||||
case CFG_REGION_AUS:
|
||||
return import_nsbCharacterNames[i];
|
||||
}
|
||||
#else
|
||||
return import_ss2CharacterNames[i];
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* PhotoStudio::ss1Title(void) const {
|
||||
#ifdef _3DS
|
||||
switch (sysRegion) {
|
||||
default:
|
||||
return "Style Savvy";
|
||||
@ -272,9 +280,13 @@ const char* PhotoStudio::ss1Title(void) const {
|
||||
case CFG_REGION_KOR:
|
||||
return "Namanui Collection: Girls Style";
|
||||
}
|
||||
#else
|
||||
return "Style Savvy";
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* PhotoStudio::ss2Title(void) const {
|
||||
#ifdef _3DS
|
||||
switch (sysRegion) {
|
||||
default:
|
||||
return "Style Savvy: Trendsetters";
|
||||
@ -286,9 +298,13 @@ const char* PhotoStudio::ss2Title(void) const {
|
||||
case CFG_REGION_KOR:
|
||||
return "Girls Style: Paesyeon Lideo Seon-eon!";
|
||||
}
|
||||
#else
|
||||
return "Style Savvy: Trendsetters";
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* PhotoStudio::ss3Title(void) const {
|
||||
#ifdef _3DS
|
||||
switch (sysRegion) {
|
||||
default:
|
||||
return "Style Savvy: Fashion Forward";
|
||||
@ -300,9 +316,13 @@ const char* PhotoStudio::ss3Title(void) const {
|
||||
case CFG_REGION_KOR:
|
||||
return "Girls Style: Kirakira * Code";
|
||||
}
|
||||
#else
|
||||
return "Style Savvy: Fashion Forward";
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* PhotoStudio::ss4Title(void) const {
|
||||
#ifdef _3DS
|
||||
switch (sysRegion) {
|
||||
default:
|
||||
return "Style Savvy: Styling Star";
|
||||
@ -314,6 +334,9 @@ const char* PhotoStudio::ss4Title(void) const {
|
||||
case CFG_REGION_KOR:
|
||||
return "Girls Style: Star Stylist";
|
||||
}
|
||||
#else
|
||||
return "Style Savvy: Styling Star";
|
||||
#endif
|
||||
}
|
||||
|
||||
int PhotoStudio::getBgNum(void) const {
|
||||
@ -335,6 +358,7 @@ int PhotoStudio::getBgNum(void) const {
|
||||
}
|
||||
|
||||
void PhotoStudio::drawMsg(void) const {
|
||||
#ifdef _3DS
|
||||
GFX::DrawSprite(sprites_msg_idx, 0, 8, 1, 1);
|
||||
GFX::DrawSprite(sprites_msg_idx, 160, 8, -1, 1);
|
||||
GFX::DrawSprite(messageNo == 4 ? sprites_icon_question_idx : sprites_icon_msg_idx, 132, -2);
|
||||
@ -345,6 +369,7 @@ void PhotoStudio::drawMsg(void) const {
|
||||
GFX::DrawSprite(sprites_button_msg_shadow_idx, 114, 197);
|
||||
GFX::DrawSprite(sprites_button_msg_idx, 115, 188);
|
||||
Gui::DrawString(134, 196, 0.70, MSG_BUTTONTEXT, " OK!");
|
||||
#endif
|
||||
}
|
||||
|
||||
void PhotoStudio::loadChrImage(void) {
|
||||
@ -356,11 +381,20 @@ void PhotoStudio::loadChrImage(void) {
|
||||
} else {
|
||||
sprintf(chrFilePath, "romfs:/gfx/null.t3x"); // All Seasons
|
||||
}*/
|
||||
#ifdef NDS
|
||||
sprintf(chrFilePath, "nitrofs:/graphics/char/%s.png", import_characterFileName());
|
||||
#else
|
||||
sprintf(chrFilePath, "romfs:/gfx/%s.t3x", import_characterFileName());
|
||||
#endif
|
||||
previewCharacterFound[currentCharNum] = GFX::loadCharSprite(currentCharNum, chrFilePath, chrFilePath);
|
||||
} else {
|
||||
#ifdef NDS
|
||||
sprintf(chrFilePath, "nitrofs:/graphics/char/ss%i_%s.png", 4, import_characterName()); // All Seasons
|
||||
sprintf(chrFilePath2, "nitrofs:/graphics/char/ss%i_%s%i.png", 4, import_characterName(), seasonNo[currentCharNum]); // One Season
|
||||
#else
|
||||
sprintf(chrFilePath, "romfs:/gfx/ss%i_%s.t3x", 4, import_characterName()); // All Seasons
|
||||
sprintf(chrFilePath2, "romfs:/gfx/ss%i_%s%i.t3x", 4, import_characterName(), seasonNo[currentCharNum]); // One Season
|
||||
#endif
|
||||
previewCharacterFound[currentCharNum] = GFX::loadCharSprite(currentCharNum, chrFilePath, chrFilePath2);
|
||||
}
|
||||
if (previewCharacterFound[0] && !characterPicked[1]) {
|
||||
@ -371,6 +405,7 @@ void PhotoStudio::loadChrImage(void) {
|
||||
|
||||
|
||||
void PhotoStudio::Draw(void) const {
|
||||
#ifdef _3DS
|
||||
animateBg = bgCanAnimate;
|
||||
|
||||
if (!musicPlayStarted) {
|
||||
@ -655,6 +690,7 @@ void PhotoStudio::Draw(void) const {
|
||||
}
|
||||
|
||||
if (fadealpha > 0) Gui::Draw_Rect(0, 0, 400, 240, C2D_Color32(fadecolor, fadecolor, fadecolor, fadealpha)); // Fade in/out effect
|
||||
#endif
|
||||
}
|
||||
|
||||
void PhotoStudio::preview() const {
|
||||
@ -710,8 +746,10 @@ void PhotoStudio::Logic(u32 hDown, u32 hHeld, touchPosition touch) {
|
||||
sndSelect();
|
||||
showMessage = false;
|
||||
}
|
||||
#ifdef _3DS
|
||||
} else if (subScreenMode == 10) {
|
||||
SettingsLogic(hDown, hHeld, touch);
|
||||
#endif
|
||||
} else if (subScreenMode == 2) {
|
||||
if (showCursor) {
|
||||
if (hDown & KEY_DUP) {
|
||||
@ -1025,9 +1063,11 @@ void PhotoStudio::Logic(u32 hDown, u32 hHeld, touchPosition touch) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _3DS
|
||||
if (hDown & KEY_SELECT) {
|
||||
sndSelect();
|
||||
subScreenMode = 10;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ static int rr_fadeAlpha = 0;
|
||||
static int rr_fadeType = true;
|
||||
|
||||
void RocketRobz::Draw(void) const {
|
||||
#ifdef _3DS
|
||||
fadecolor = 0; // Always use black color for fading effects
|
||||
|
||||
Gui::ScreenDraw(Top);
|
||||
@ -36,6 +37,7 @@ void RocketRobz::Draw(void) const {
|
||||
}
|
||||
if (rr_fadeAlpha > 0) Gui::Draw_Rect(0, 0, 320, 240, C2D_Color32(0, 0, 0, rr_fadeAlpha)); // Fade in/out effect
|
||||
if (fadealpha > 0) Gui::Draw_Rect(0, 0, 320, 240, C2D_Color32(fadecolor, fadecolor, fadecolor, fadealpha)); // Fade in/out effect
|
||||
#endif
|
||||
|
||||
int fadeFPS;
|
||||
switch (iFps) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
#ifdef _3DS
|
||||
|
||||
#include "photoStudio.hpp"
|
||||
#include "screenvars.h"
|
||||
|
||||
@ -106,4 +108,6 @@ void PhotoStudio::SettingsLogic(u32 hDown, u32 hHeld, touchPosition touch) {
|
||||
sndBack();
|
||||
subScreenMode = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user