mirror of
https://github.com/NotImplementedLife/FSPDS.git
synced 2025-06-19 01:15:34 -04:00
415 lines
9.5 KiB
C++
415 lines
9.5 KiB
C++
#include <nds.h>
|
|
#include "scenes.hpp"
|
|
#include "simple_scene.hpp"
|
|
#include "folder_icon.h"
|
|
#include "filesystem.hpp"
|
|
#include "opt_box.h"
|
|
#include "globals.hpp"
|
|
#include "strings.hpp"
|
|
|
|
class FolderPickerScene : public SimpleScene
|
|
{
|
|
const char* flipnote_locations[4] = { "/flipnotes", "/private/ds/app/4b475556", "/private/ds/app/4B475545", "/private/ds/app/4B47554A" };
|
|
|
|
ObjFrame* folder_normal_frame;
|
|
ObjFrame* folder_highlighted_frame;
|
|
ObjFrame* folder_back_frame;
|
|
|
|
DirStream dirstream;
|
|
|
|
Sprite* folder_icons[5];
|
|
Vector<char*> subfolders;
|
|
|
|
char* current_path;
|
|
int depth=0;
|
|
int selected_index=0;
|
|
int max_subfolders = 65536;
|
|
|
|
Sprite* pick_box;
|
|
|
|
Stack<int> selected_indices;
|
|
|
|
VwfEngine* vwf = new VwfEngine(Resources::Fonts::default_8x16);
|
|
void init() override
|
|
{
|
|
Debug::log("Initing");
|
|
SimpleScene::init();
|
|
Debug::log("Requiring");
|
|
require_tiledmap_4bpp(MAIN_BG2, 256, 256, 32*24);
|
|
require_tiledmap_4bpp(SUB_BG2, 256, 256, 32*24);
|
|
|
|
begin_sprites_init();
|
|
|
|
Debug::log("Framing");
|
|
folder_normal_frame = new ObjFrame(&ROA_folder_icon8,0,0);
|
|
folder_highlighted_frame = new ObjFrame(&ROA_folder_icon8,0,1);
|
|
folder_back_frame = new ObjFrame(&ROA_folder_icon8,0,2);
|
|
|
|
Debug::log("Allocating");
|
|
Debug::log(" normal frame");
|
|
get_obj_allocator_sub()->allocate(folder_normal_frame);
|
|
Debug::log(" highlighted frame");
|
|
get_obj_allocator_sub()->allocate(folder_highlighted_frame);
|
|
Debug::log(" back frame");
|
|
get_obj_allocator_sub()->allocate(folder_back_frame);
|
|
|
|
Debug::log("creating sprites");
|
|
for(int i=0;i<5;i++)
|
|
{
|
|
folder_icons[i] = create_sprite(new Sprite(SIZE_32x32, Engine::Sub));
|
|
folder_icons[i]->set_default_allocator(nullptr);
|
|
folder_icons[i]->add_frame(i%2==0?folder_normal_frame : folder_highlighted_frame);
|
|
folder_icons[i]->set_position(8,8+32*i);
|
|
}
|
|
|
|
pick_box = create_sprite(new Sprite(SIZE_64x32, Engine::Sub));
|
|
pick_box->add_frame(new ObjFrame(&ROA_opt_box8,0,0));
|
|
pick_box->set_position(188, 168);
|
|
pick_box->set_priority(3);
|
|
|
|
end_sprites_init();
|
|
key_down.add_event(&FolderPickerScene::on_key_down, this);
|
|
|
|
current_path = (char*)malloc(32768);
|
|
|
|
if(current_path==nullptr)
|
|
{
|
|
Debug::log("ALLOCATION FAILED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! _ CURRENT PATH");
|
|
}
|
|
strcpy(current_path, "/");
|
|
|
|
dirstream.open(current_path);
|
|
clear_subfolders();
|
|
}
|
|
|
|
void on_key_down(void*, void* _k)
|
|
{
|
|
int keys = (int)_k;
|
|
if(keys & KEY_LEFT)
|
|
{
|
|
if(selected_index>=5)
|
|
{
|
|
selected_index-=5;
|
|
display_page(selected_index/5);
|
|
}
|
|
}
|
|
else if(keys & KEY_RIGHT)
|
|
{
|
|
if(selected_index<max_subfolders-5)
|
|
{
|
|
selected_index+=5;
|
|
display_page(selected_index/5);
|
|
}
|
|
}
|
|
else if(keys & KEY_UP)
|
|
{
|
|
if(selected_index>=1)
|
|
{
|
|
selected_index--;
|
|
display_page(selected_index/5);
|
|
}
|
|
}
|
|
else if(keys & KEY_DOWN)
|
|
{
|
|
if(selected_index<max_subfolders-1)
|
|
{
|
|
selected_index++;
|
|
display_page(selected_index/5);
|
|
}
|
|
}
|
|
else if(keys & KEY_A)
|
|
{
|
|
enter_selected();
|
|
}
|
|
else if(keys & KEY_B)
|
|
{
|
|
go_back();
|
|
}
|
|
else if(keys & KEY_SELECT)
|
|
{
|
|
done();
|
|
}
|
|
else if(keys & KEY_TOUCH)
|
|
{
|
|
touchRead(&touch);
|
|
if(touch_in_rect(188, 168, 64, 32))
|
|
done();
|
|
}
|
|
}
|
|
|
|
void done()
|
|
{
|
|
picked_folder_path = new char[strlen(current_path)+1];
|
|
strcpy(picked_folder_path, current_path);
|
|
close()->next(folder_picker_next_scene_gen());
|
|
}
|
|
|
|
touchPosition touch;
|
|
|
|
bool touch_in_rect(int x, int y, int w, int h)
|
|
{
|
|
if(touch.px<x || touch.px>=x+w) return false;
|
|
if(touch.py<y || touch.py>=y+h) return false;
|
|
return true;
|
|
}
|
|
|
|
__attribute__((noinline))
|
|
void run() override
|
|
{
|
|
solve_map_requirements();
|
|
load_assets();
|
|
|
|
bgSetPriority(7,3);
|
|
bgSetPriority(6,2);
|
|
|
|
BG_PALETTE[0x91]=BG_PALETTE_SUB[0x91]=Colors::Black;
|
|
BG_PALETTE[0x92]=BG_PALETTE_SUB[0x92]=Colors::Blue;
|
|
|
|
vwf->set_render_space(bgGetGfxPtr(2),24,32);
|
|
VwfEngine::prepare_map(*vwf, MAIN_BG2, 32, 0, 0, 0x9);
|
|
vwf->clear(Pal4bit);
|
|
|
|
vwf->set_cursor(6, Strings::pcx_pick_a_directory);
|
|
vwf->put_text(Strings::str_pick_a_directory, Pal4bit, SolidColorBrush(0x1));
|
|
|
|
vwf->set_cursor(9, 8);
|
|
vwf->put_text("Enter in a directory of your choice, then touch the", Pal4bit, SolidColorBrush(0x1));
|
|
vwf->set_cursor(10, 8);
|
|
vwf->put_text("Select button.", Pal4bit, SolidColorBrush(0x1));
|
|
|
|
|
|
vwf->set_render_space(bgGetGfxPtr(6),24,32);
|
|
VwfEngine::prepare_map(*vwf, SUB_BG2, 32, 0, 0, 0x9);
|
|
vwf->clear(Pal4bit);
|
|
|
|
vwf->set_cursor(10, 20);
|
|
vwf->put_text("Touch the screen to return to title", Pal4bit, SolidColorBrush(0x1));
|
|
|
|
Hardware::MainEngine::objEnable(128, true); // set to 128
|
|
Hardware::SubEngine::objEnable(128, true); // set to 128
|
|
|
|
display_page(0);
|
|
|
|
Scene::run();
|
|
}
|
|
|
|
void frame() override
|
|
{
|
|
if(!(depth==0 && max_subfolders==0))
|
|
display_item(selected_index%5);
|
|
GenericScene256::frame();
|
|
}
|
|
|
|
static int measure_string(const char* text)
|
|
{
|
|
Debug::log("MEASURED TEXT = %s", text);
|
|
int result=0;
|
|
for(;*text;++text)
|
|
result+=Resources::Fonts::default_8x16.get_glyph_width(*text);
|
|
Debug::log("RESULT = %i", result);
|
|
return result;
|
|
}
|
|
|
|
bool is_default_location(const char* name)
|
|
{
|
|
char* tmp = (char*)malloc(strlen(current_path) + strlen(name)+1);
|
|
strcpy(tmp, current_path);
|
|
strcat(tmp, name);
|
|
for(int i=0;i<4;i++)
|
|
{
|
|
if(strcmp(tmp, flipnote_locations[i])==0)
|
|
{
|
|
free(tmp);
|
|
return true;
|
|
}
|
|
}
|
|
free(tmp);
|
|
return false;
|
|
}
|
|
|
|
VwfEngine sel_vwf = VwfEngine(Resources::Fonts::default_8x16);
|
|
char* list_buffer[5] = { nullptr, nullptr, nullptr, nullptr };
|
|
int list_tiles_len[5]= { 0,0,0,0 };
|
|
int sel_scroll = 0;
|
|
|
|
void display_page(int page)
|
|
{
|
|
int last_id = page*5+4;
|
|
|
|
char* name = new char[256];
|
|
while(last_id+1>=subfolders.size() && dirstream.next(name))
|
|
{
|
|
char* dirname = (char*)malloc(strlen(name)+1);
|
|
if(dirname==nullptr)
|
|
{
|
|
Debug::log("ALLOCATION FAILED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! _ DIRRRR");
|
|
}
|
|
strcpy(dirname, name);
|
|
subfolders.push_back(dirname);
|
|
Debug::log(dirname);
|
|
}
|
|
delete[] name;
|
|
|
|
if(last_id+1>=subfolders.size())
|
|
{
|
|
max_subfolders = subfolders.size();
|
|
}
|
|
|
|
vwf->clear(Pal4bit);
|
|
|
|
for(int i=0;i<5;i++)
|
|
{
|
|
delete[] list_buffer[i];
|
|
list_buffer[i] = nullptr;
|
|
list_tiles_len[i]=0;
|
|
}
|
|
|
|
int k=page*5;
|
|
int i=0;
|
|
for(;i<5 && k<subfolders.size();i++, k++)
|
|
{
|
|
folder_icons[i]->show();
|
|
if(k==0 && depth>0)
|
|
{
|
|
folder_icons[i]->set_frame(0, folder_back_frame);
|
|
}
|
|
else
|
|
{
|
|
folder_icons[i]->set_frame(0, is_default_location(subfolders[k]) ? folder_highlighted_frame : folder_normal_frame);
|
|
}
|
|
Debug::log(subfolders[k]);
|
|
|
|
list_tiles_len[i] = (measure_string(subfolders[k])+8)/8;
|
|
list_buffer[i] = new char[list_tiles_len[i]*64]();
|
|
sel_vwf.set_render_space(list_buffer[i], 2, list_tiles_len[i]);
|
|
sel_vwf.put_text(subfolders[k], Pal4bit, SolidColorBrush(0x1+(k==selected_index)));
|
|
sel_scroll = 0;
|
|
display_item(i);
|
|
|
|
//vwf->set_cursor(1+2*i, 42);
|
|
//vwf->put_text(subfolders[k], Pal4bit, SolidColorBrush(0x1 + (k==selected_index)));
|
|
}
|
|
for(;i<5;i++)
|
|
{
|
|
folder_icons[i]->hide();
|
|
}
|
|
|
|
vwf->set_cursor(11, 256-4-64+(64-Strings::len_select)/2);
|
|
vwf->put_text(Strings::str_select, Pal4bit, SolidColorBrush(0x1));
|
|
}
|
|
|
|
void display_item(int i)
|
|
{
|
|
short* gfx = (short*)((int)bgGetGfxPtr(6) + 64*32*(1+2*i)+64*6);
|
|
short* src = (short*)list_buffer[i];
|
|
|
|
if(selected_index%5 == i && list_tiles_len[i]>24)
|
|
{
|
|
int w = 32*(sel_scroll/16);
|
|
src+=w;
|
|
int sz = list_tiles_len[i]*32 - w;
|
|
int k=0;
|
|
for(;k<min(24*32, sz);k++) *(gfx++) = *(src++);
|
|
volatile int zero=0;
|
|
for(;k<24*32;k++) *(gfx++) = zero;
|
|
sel_scroll++;
|
|
if(sel_scroll>=16*list_tiles_len[i])
|
|
sel_scroll=0;
|
|
}
|
|
else
|
|
{
|
|
for(int k=0;k<min(24*32, list_tiles_len[i]*32);k++)
|
|
{
|
|
*(gfx++) = *(src++);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static char* sptr(const char* val)
|
|
{
|
|
char* r = (char*)malloc(strlen(val)+1);
|
|
strcpy(r, val);
|
|
return r;
|
|
}
|
|
|
|
void enter_selected()
|
|
{
|
|
if(depth==0 && max_subfolders==0)
|
|
return;
|
|
if(depth>0 && selected_index==0)
|
|
{
|
|
depth--;
|
|
char* c = current_path + strlen(current_path)-1;
|
|
while(*(--c)!='/');
|
|
*(++c)='\0';
|
|
Debug::log("After back: %s", current_path);
|
|
selected_index = selected_indices.pop();
|
|
}
|
|
else
|
|
{
|
|
strcat(current_path, subfolders[selected_index]);
|
|
strcat(current_path, "/");
|
|
depth++;
|
|
Debug::log("nav: %s", current_path);
|
|
selected_indices.push(selected_index);
|
|
selected_index=0;
|
|
}
|
|
dirstream.open(current_path);
|
|
clear_subfolders();
|
|
display_page(selected_index/5);
|
|
}
|
|
|
|
void go_back()
|
|
{
|
|
if(depth==0) return;
|
|
depth--;
|
|
char* c = current_path + strlen(current_path)-1;
|
|
while(*(--c)!='/');
|
|
*(++c)='\0';
|
|
Debug::log("After back: %s", current_path);
|
|
selected_index = selected_indices.pop();
|
|
dirstream.open(current_path);
|
|
clear_subfolders();
|
|
display_page(selected_index/5);
|
|
}
|
|
|
|
void clear_subfolders()
|
|
{
|
|
for(int i=0;i<subfolders.size();i++)
|
|
free(subfolders[i]);
|
|
subfolders.clear();
|
|
if(depth>0)
|
|
subfolders.push_back(sptr("Back"));
|
|
max_subfolders=65536;
|
|
}
|
|
|
|
~FolderPickerScene()
|
|
{
|
|
key_down.remove_event(&FolderPickerScene::on_key_down, this);
|
|
delete vwf;
|
|
clear_subfolders();
|
|
|
|
dirstream.close();
|
|
|
|
for(int i=0;i<5;i++)
|
|
{
|
|
folder_icons[i]->set_frame(0, nullptr);
|
|
delete folder_icons[i];
|
|
delete[] list_buffer[i];
|
|
}
|
|
delete pick_box;
|
|
|
|
delete folder_normal_frame;
|
|
delete folder_highlighted_frame;
|
|
delete folder_back_frame;
|
|
|
|
free(current_path);
|
|
}
|
|
|
|
};
|
|
|
|
Scene* get_folder_picker_scene()
|
|
{
|
|
return new FolderPickerScene();
|
|
} |