mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-09-28 20:26:55 -05:00
Begin to show my final form
This commit is contained in:
4
Makefile
4
Makefile
@@ -38,7 +38,7 @@ INCLUDES := inc
|
||||
EXEFS_SRC := exefs_src
|
||||
APP_TITLE := JKSV
|
||||
APP_AUTHOR := JK_
|
||||
APP_VERSION := 06/29/2018
|
||||
APP_VERSION := 07/01/2018
|
||||
ROMFS := romfs
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
@@ -56,7 +56,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := `freetype-config --libs` -lpng
|
||||
LIBS := `freetype-config --libs` -lpng -ljpeg
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
||||
@@ -7,7 +7,7 @@ JKSV for Switch. Mostly to get used to libnx. Reuses a lot of code of JKSM for 3
|
||||
# Building:
|
||||
1. Requires [devkitPro](https://devkitpro.org/) devkitA64
|
||||
2. Requires switch-freetype
|
||||
3. libpng
|
||||
3. libpng and libjpeg-turbo
|
||||
|
||||
# Credits and Thanks:
|
||||
* [shared-font](https://github.com/switchbrew/switch-portlibs-examples) example by yellows8
|
||||
|
||||
25
inc/data.h
25
inc/data.h
@@ -6,12 +6,32 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
namespace data
|
||||
{
|
||||
extern bool sysSave, forceMountable;
|
||||
|
||||
//Loads user + title info
|
||||
void loadDataInfo();
|
||||
void exit();
|
||||
|
||||
//Class to help not load the same icons over and over
|
||||
class icn
|
||||
{
|
||||
public:
|
||||
void load(const uint64_t& _id, const uint8_t *jpegData, const size_t& jpegSize);
|
||||
void setIcon(const uint64_t& _id, const gfx::tex& _set);
|
||||
void draw(unsigned x, unsigned y);
|
||||
void drawHalf(unsigned x, unsigned y);
|
||||
uint64_t getTitleID();
|
||||
|
||||
void deleteData();
|
||||
|
||||
private:
|
||||
uint64_t titleID;
|
||||
gfx::tex iconTex;
|
||||
};
|
||||
|
||||
//Class to store title info
|
||||
class titledata
|
||||
@@ -30,6 +50,9 @@ namespace data
|
||||
//Returns ID
|
||||
uint64_t getID();
|
||||
|
||||
//Game icon
|
||||
icn icon;
|
||||
|
||||
FsSaveDataType getType();
|
||||
|
||||
private:
|
||||
@@ -59,6 +82,8 @@ namespace data
|
||||
//Vector for storing save data info for user
|
||||
std::vector<titledata> titles;
|
||||
|
||||
gfx::tex icn;
|
||||
|
||||
private:
|
||||
u128 userID;
|
||||
std::string username, userSafe;
|
||||
|
||||
14
inc/gfx.h
14
inc/gfx.h
@@ -7,7 +7,7 @@ namespace gfx
|
||||
{
|
||||
//Inits graphics and shared font. Code for shared font is from switch-portlibs examples
|
||||
bool init();
|
||||
bool fini();
|
||||
bool exit();
|
||||
|
||||
//Changes gfx mode to linear double
|
||||
void switchMode();
|
||||
@@ -42,11 +42,21 @@ namespace gfx
|
||||
Others will have issues.
|
||||
*/
|
||||
void loadFromFile(const std::string& path);
|
||||
//Icons
|
||||
void loadJpegMem(const uint8_t *txData, const uint32_t& jpegSz);
|
||||
//Frees memory used by data
|
||||
~tex();
|
||||
void deleteData();
|
||||
uint16_t getWidth();
|
||||
uint16_t getHeight();
|
||||
const uint32_t *getDataPointer();
|
||||
|
||||
void draw(uint32_t x, uint32_t y);
|
||||
void drawNoBlend(uint32_t x, uint32_t y);
|
||||
|
||||
//For lazy-scaling icons
|
||||
//Skips every-other pixel and row, so 1/2 scale
|
||||
void drawNoBlendSkip(unsigned x, unsigned y);
|
||||
|
||||
//These only repeat pixels.
|
||||
void drawRepeatHori(uint32_t x, uint32_t y, uint32_t w);
|
||||
void drawRepeatHoriNoBlend(uint32_t x, uint32_t y, uint32_t w);
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace ui
|
||||
bool confirm(const std::string& q);
|
||||
bool confirmTransfer(const std::string& f, const std::string& t);
|
||||
bool confirmDelete(const std::string& p);
|
||||
void debShowTex(gfx::tex tx);
|
||||
void drawTextbox(unsigned x, unsigned y, unsigned w, unsigned h);
|
||||
}
|
||||
|
||||
|
||||
1
inc/ui.h
1
inc/ui.h
@@ -22,6 +22,7 @@ namespace ui
|
||||
|
||||
//Loads in the A, B, X, Y button graphics
|
||||
void init();
|
||||
void exit();
|
||||
|
||||
//Prepares menus for use
|
||||
void userMenuInit();
|
||||
|
||||
BIN
romfs/img/icn/icnDefault.png
Normal file
BIN
romfs/img/icn/icnDefault.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 251 B |
Binary file not shown.
|
Before Width: | Height: | Size: 221 B |
91
src/data.cpp
91
src/data.cpp
@@ -38,15 +38,27 @@ static int getUserIndex(const u128& id)
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Default icon if one isn't found. For system saves
|
||||
gfx::tex defIcn;
|
||||
|
||||
namespace data
|
||||
{
|
||||
titledata curData;
|
||||
user curUser;
|
||||
std::vector<icn> icons;
|
||||
std::vector<user> users;
|
||||
bool sysSave = false, forceMountable = true;
|
||||
|
||||
void loadDataInfo()
|
||||
{
|
||||
//Load default icon
|
||||
defIcn.loadFromFile("romfs:/img/icn/icnDefault.png");
|
||||
|
||||
//Create icon for it
|
||||
icn defIcnIcon;
|
||||
defIcnIcon.setIcon((uint64_t)0, defIcn);
|
||||
icons.push_back(defIcnIcon);
|
||||
|
||||
for(unsigned i = 0; i < users.size(); i++)
|
||||
users[i].titles.clear();
|
||||
|
||||
@@ -102,6 +114,60 @@ namespace data
|
||||
for(unsigned i = 0; i < users.size(); i++)
|
||||
std::sort(users[i].titles.begin(), users[i].titles.end(), sortTitles);
|
||||
|
||||
curUser = users[0];
|
||||
}
|
||||
|
||||
void exit()
|
||||
{
|
||||
for(unsigned i = 0; i < users.size(); i++)
|
||||
users[i].icn.deleteData();
|
||||
|
||||
for(unsigned i = 1; i < icons.size(); i++)
|
||||
icons[i].deleteData();
|
||||
}
|
||||
|
||||
void icn::load(const uint64_t& _id, const uint8_t *jpegData, const size_t& jpegSize)
|
||||
{
|
||||
titleID = _id;
|
||||
|
||||
iconTex.loadJpegMem(jpegData, jpegSize);
|
||||
}
|
||||
|
||||
void icn::setIcon(const uint64_t& _id, const gfx::tex& _set)
|
||||
{
|
||||
titleID = _id;
|
||||
iconTex = _set;
|
||||
}
|
||||
|
||||
void icn::draw(unsigned x, unsigned y)
|
||||
{
|
||||
iconTex.drawNoBlend(x, y);
|
||||
}
|
||||
|
||||
void icn::drawHalf(unsigned x, unsigned y)
|
||||
{
|
||||
iconTex.drawNoBlendSkip(x, y);
|
||||
}
|
||||
|
||||
uint64_t icn::getTitleID()
|
||||
{
|
||||
return titleID;
|
||||
}
|
||||
|
||||
void icn::deleteData()
|
||||
{
|
||||
iconTex.deleteData();
|
||||
}
|
||||
|
||||
int findIcnIndex(const uint64_t& titleID)
|
||||
{
|
||||
for(unsigned i = 0; i < icons.size(); i++)
|
||||
{
|
||||
if(icons[i].getTitleID() == titleID)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool titledata::init(const FsSaveDataInfo& inf)
|
||||
@@ -142,6 +208,20 @@ namespace data
|
||||
{
|
||||
title.assign(ent->name);
|
||||
titleSafe = util::safeString(ent->name);
|
||||
|
||||
int iconIndex = findIcnIndex(id);
|
||||
if(iconIndex == -1)
|
||||
{
|
||||
uint32_t icnSize = outSz - sizeof(dat->nacp);
|
||||
icn newIcon;
|
||||
newIcon.load(id, dat->icon, icnSize);
|
||||
icons.push_back(newIcon);
|
||||
|
||||
icon = icons[findIcnIndex(id)];
|
||||
}
|
||||
else
|
||||
icon = icons[iconIndex];
|
||||
|
||||
delete dat;
|
||||
}
|
||||
else
|
||||
@@ -150,6 +230,7 @@ namespace data
|
||||
sprintf(tmp, "%016lX", (u64)id);
|
||||
title.assign(tmp);
|
||||
titleSafe = util::safeString(tmp);
|
||||
icon = icons[0];
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -208,6 +289,15 @@ namespace data
|
||||
username = "Unknown";
|
||||
userSafe = util::safeString(username);
|
||||
|
||||
size_t sz = 0;
|
||||
accountProfileGetImageSize(&prof, &sz);
|
||||
uint8_t *profJpeg = new uint8_t[sz];
|
||||
|
||||
accountProfileLoadImage(&prof, profJpeg, sz, &sz);
|
||||
icn.loadJpegMem(profJpeg, sz);
|
||||
|
||||
delete[] profJpeg;
|
||||
|
||||
accountProfileClose(&prof);
|
||||
|
||||
return true;
|
||||
@@ -237,6 +327,7 @@ namespace data
|
||||
{
|
||||
username = "Unknown";
|
||||
userSafe = "Unknown";
|
||||
icn = defIcn;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
91
src/gfx.cpp
91
src/gfx.cpp
@@ -4,6 +4,9 @@
|
||||
#include <cstdio>
|
||||
#include <switch.h>
|
||||
#include <png.h>
|
||||
#include <jpeglib.h>
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
@@ -62,7 +65,7 @@ namespace gfx
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fini()
|
||||
bool exit()
|
||||
{
|
||||
if(faceret == 0)
|
||||
FT_Done_Face(face);
|
||||
@@ -306,10 +309,77 @@ namespace gfx
|
||||
}
|
||||
}
|
||||
|
||||
tex::~tex()
|
||||
void tex::loadJpegMem(const uint8_t *txData, const uint32_t& jpegSz)
|
||||
{
|
||||
struct jpeg_decompress_struct jpegInfo;
|
||||
struct jpeg_error_mgr error;
|
||||
|
||||
jpegInfo.err = jpeg_std_error(&error);
|
||||
|
||||
jpeg_create_decompress(&jpegInfo);
|
||||
jpeg_mem_src(&jpegInfo, txData, jpegSz);
|
||||
jpeg_read_header(&jpegInfo, true);
|
||||
|
||||
//make sure we have RGB
|
||||
if(jpegInfo.jpeg_color_space == JCS_YCbCr)
|
||||
jpegInfo.out_color_space = JCS_RGB;
|
||||
|
||||
width = jpegInfo.image_width;
|
||||
height = jpegInfo.image_height;
|
||||
|
||||
data = new uint32_t[width * height];
|
||||
|
||||
jpeg_start_decompress(&jpegInfo);
|
||||
|
||||
JSAMPARRAY row = (JSAMPARRAY)new JSAMPARRAY[sizeof(JSAMPROW)];
|
||||
row[0] = (JSAMPROW)new JSAMPROW[(sizeof(JSAMPLE) * width) * 3];
|
||||
|
||||
uint8_t *ptr;
|
||||
|
||||
for(unsigned y = 0, i = 0; y < height; y++)
|
||||
{
|
||||
jpeg_read_scanlines(&jpegInfo, row, 1);
|
||||
unsigned x;
|
||||
for(x = 0, ptr = row[0]; x < width; x++, ptr += 3, i++)
|
||||
{
|
||||
uint8_t r, g, b;
|
||||
r = ptr[0];
|
||||
g = ptr[1];
|
||||
b = ptr[2];
|
||||
|
||||
data[i] = 0xFF << 24 | b << 16 | g << 8 | r;
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&jpegInfo);
|
||||
jpeg_destroy_decompress(&jpegInfo);
|
||||
|
||||
delete row[0];
|
||||
delete[] row;
|
||||
}
|
||||
|
||||
void tex::deleteData()
|
||||
{
|
||||
if(data != NULL)
|
||||
{
|
||||
delete[] data;
|
||||
data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t tex::getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
uint16_t tex::getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
const uint32_t *tex::getDataPointer()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
void tex::draw(uint32_t x, uint32_t y)
|
||||
@@ -347,6 +417,23 @@ namespace gfx
|
||||
}
|
||||
}
|
||||
|
||||
void tex::drawNoBlendSkip(unsigned x, unsigned y)
|
||||
{
|
||||
if(data != NULL)
|
||||
{
|
||||
unsigned tY, tX, i = 0;
|
||||
uint32_t *fb = (uint32_t *)gfxGetFramebuffer(NULL, NULL);
|
||||
|
||||
for(tY = y; tY < y + (height / 2); tY++, i += width)
|
||||
{
|
||||
for(tX = x; tX < x + (width / 2); tX++, i += 2)
|
||||
{
|
||||
fb[tY * frameBufWidth + tX] = data[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tex::drawRepeatHori(uint32_t x, uint32_t y, uint32_t w)
|
||||
{
|
||||
if(data != NULL)
|
||||
|
||||
12
src/main.cpp
12
src/main.cpp
@@ -33,14 +33,11 @@ extern "C"
|
||||
}
|
||||
}
|
||||
|
||||
extern int mstate;
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
gfx::init();
|
||||
data::loadDataInfo();
|
||||
ui::init();
|
||||
ui::userMenuInit();
|
||||
data::loadDataInfo();
|
||||
|
||||
bool run = true;
|
||||
while(appletMainLoop() && run)
|
||||
@@ -57,12 +54,9 @@ int main(int argc, const char *argv[])
|
||||
data::sysSave = true;
|
||||
data::forceMountable = false;
|
||||
data::loadDataInfo();
|
||||
ui::userMenuInit();
|
||||
|
||||
//Just to be sure
|
||||
fsdevUnmountDevice("sv");
|
||||
|
||||
mstate = 0;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_PLUS)
|
||||
@@ -72,5 +66,7 @@ int main(int argc, const char *argv[])
|
||||
|
||||
gfx::handleBuffs();
|
||||
}
|
||||
gfx::fini();
|
||||
gfx::exit();
|
||||
ui::exit();
|
||||
data::exit();
|
||||
}
|
||||
|
||||
@@ -186,6 +186,30 @@ namespace ui
|
||||
return confirm(confMess);
|
||||
}
|
||||
|
||||
void debShowTex(gfx::tex tx)
|
||||
{
|
||||
unsigned tbX = 256, tbY = 128;
|
||||
unsigned tbW = 768, tbH = 464;
|
||||
|
||||
unsigned texX = tbX + ((tbW / 2) - (tx.getWidth() / 2));
|
||||
unsigned texY = tbY + ((tbH / 2) - (tx.getHeight() / 2));
|
||||
|
||||
while(true)
|
||||
{
|
||||
hidScanInput();
|
||||
|
||||
uint64_t down = hidKeysDown(CONTROLLER_P1_AUTO);
|
||||
|
||||
if(down & KEY_A)
|
||||
break;
|
||||
|
||||
ui::drawTextbox(tbX, tbY, tbW, tbH);
|
||||
tx.drawNoBlend(texX, texY);
|
||||
|
||||
gfx::handleBuffs();
|
||||
}
|
||||
}
|
||||
|
||||
void drawTextbox(unsigned x, unsigned y, unsigned w, unsigned h)
|
||||
{
|
||||
//Top
|
||||
|
||||
321
src/ui.cpp
321
src/ui.cpp
@@ -21,10 +21,10 @@ enum menuState
|
||||
int mstate = USR_SEL;
|
||||
|
||||
//Button controlled menus
|
||||
static ui::menu userMenu, titleMenu, folderMenu, devMenu, saveMenu, sdMenu, copyMenu;
|
||||
static ui::menu folderMenu, devMenu, saveMenu, sdMenu, copyMenu;
|
||||
|
||||
//Bar at top
|
||||
static gfx::tex buttonA, buttonB, buttonX, buttonY, titleBar;
|
||||
static gfx::tex buttonA, buttonB, buttonX, buttonY;
|
||||
|
||||
//Shown if someone tries to write to system saves
|
||||
static const std::string sysSaveMess = "No system saves until we get public NAND restore.";
|
||||
@@ -53,8 +53,6 @@ namespace ui
|
||||
switch(gthm)
|
||||
{
|
||||
case ColorSetId_Light:
|
||||
titleBar.loadFromFile("romfs:/img/topbar_lght.png");
|
||||
|
||||
//Dark corners
|
||||
cornerTopLeft.loadFromFile("romfs:/img/tbox/tboxCornerTopLeft_drk.png");
|
||||
cornerTopRight.loadFromFile("romfs:/img/tbox/tboxCornerTopRight_drk.png");
|
||||
@@ -77,8 +75,6 @@ namespace ui
|
||||
|
||||
default:
|
||||
case ColorSetId_Dark:
|
||||
titleBar.loadFromFile("romfs:/img/topbar_drk.png");
|
||||
|
||||
//Light corners
|
||||
cornerTopLeft.loadFromFile("romfs:/img/tbox/tboxCornerTopLeft_lght.png");
|
||||
cornerTopRight.loadFromFile("romfs:/img/tbox/tboxCornerTopRight_lght.png");
|
||||
@@ -113,19 +109,22 @@ namespace ui
|
||||
copyMenu.addOpt("Back");
|
||||
}
|
||||
|
||||
void userMenuInit()
|
||||
void exit()
|
||||
{
|
||||
userMenu.reset();
|
||||
for(unsigned i = 0; i < data::users.size(); i++)
|
||||
userMenu.addOpt(data::users[i].getUsername());
|
||||
}
|
||||
cornerTopLeft.deleteData();
|
||||
cornerTopRight.deleteData();
|
||||
cornerBottomLeft.deleteData();
|
||||
cornerBottomRight.deleteData();
|
||||
|
||||
void titleMenuPrepare(data::user& usr)
|
||||
{
|
||||
titleMenu.reset();
|
||||
horEdgeTop.deleteData();
|
||||
horEdgeBot.deleteData();
|
||||
vertEdgeLeft.deleteData();
|
||||
vertEdgeRight.deleteData();
|
||||
|
||||
for(unsigned i = 0; i < usr.titles.size(); i++)
|
||||
titleMenu.addOpt(usr.titles[i].getTitle());
|
||||
buttonA.deleteData();
|
||||
buttonB.deleteData();
|
||||
buttonX.deleteData();
|
||||
buttonY.deleteData();
|
||||
}
|
||||
|
||||
void folderMenuPrepare(data::user& usr, data::titledata& dat)
|
||||
@@ -143,19 +142,16 @@ namespace ui
|
||||
|
||||
void drawTitleBar(const std::string& txt)
|
||||
{
|
||||
titleBar.drawRepeatHoriNoBlend(0, 0, 1280);
|
||||
gfx::drawText(txt, 16, 16, 64, mnuTxt);
|
||||
}
|
||||
|
||||
void drawUI()
|
||||
{
|
||||
gfx::clearBufferColor(clearClr);
|
||||
ui::drawTitleBar("JKSV - 06/29/2018");
|
||||
ui::drawTitleBar("JKSV - 07/01/2018");
|
||||
|
||||
switch(mstate)
|
||||
{
|
||||
case USR_SEL:
|
||||
case TTL_SEL:
|
||||
case FLD_SEL:
|
||||
gfx::drawRectangle(448, 64, 1, 592, rectLt);
|
||||
gfx::drawRectangle(449, 64, 2, 592, rectSh);
|
||||
@@ -164,6 +160,15 @@ namespace ui
|
||||
gfx::drawRectangle(16, 657, 1248, 2, rectSh);
|
||||
break;
|
||||
|
||||
case USR_SEL:
|
||||
case TTL_SEL:
|
||||
gfx::drawRectangle(16, 64, 1248, 1, rectLt);
|
||||
gfx::drawRectangle(16, 65, 1248, 2, rectSh);
|
||||
|
||||
gfx::drawRectangle(16, 656, 1248, 1, rectLt);
|
||||
gfx::drawRectangle(16, 657, 1248, 2, rectSh);
|
||||
break;
|
||||
|
||||
case ADV_MDE:
|
||||
gfx::drawRectangle(640, 64, 1, 592, rectLt);
|
||||
gfx::drawRectangle(641, 64, 2, 592, rectSh);
|
||||
@@ -177,8 +182,6 @@ namespace ui
|
||||
{
|
||||
case USR_SEL:
|
||||
{
|
||||
//Menu
|
||||
userMenu.print(16, 88, mnuTxt, 424);
|
||||
//Input guide
|
||||
unsigned startX = 1010;
|
||||
buttonA.draw(startX, 672);
|
||||
@@ -190,9 +193,6 @@ namespace ui
|
||||
|
||||
case TTL_SEL:
|
||||
{
|
||||
//Menu
|
||||
titleMenu.print(16, 88, mnuTxt, 424);
|
||||
//Input guide
|
||||
unsigned startX = 914;
|
||||
buttonA.draw(startX, 672);
|
||||
gfx::drawText("Select", startX += 38, 668, 32, mnuTxt);
|
||||
@@ -205,8 +205,6 @@ namespace ui
|
||||
|
||||
case FLD_SEL:
|
||||
{
|
||||
//Menus
|
||||
titleMenu.print(16, 88, mnuTxt, 424);
|
||||
folderMenu.print(458, 88, mnuTxt, 806);
|
||||
//Input guide
|
||||
unsigned startX = 726;
|
||||
@@ -234,13 +232,68 @@ namespace ui
|
||||
|
||||
void updateUserMenu(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
userMenu.handleInput(down, held);
|
||||
static int start = 0, selected = 0;
|
||||
|
||||
if(down & KEY_A)
|
||||
static uint8_t clrShft = 0;
|
||||
static bool clrAdd = true;
|
||||
|
||||
static unsigned selRectX = 64, selRectY = 74;
|
||||
|
||||
if(clrAdd)
|
||||
{
|
||||
data::curUser = data::users[userMenu.getSelected()];
|
||||
titleMenuPrepare(data::curUser);
|
||||
clrShft += 4;
|
||||
if(clrShft > 63)
|
||||
clrAdd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
clrShft--;
|
||||
if(clrShft == 0)
|
||||
clrAdd = true;
|
||||
}
|
||||
|
||||
|
||||
if(down & KEY_RIGHT)
|
||||
{
|
||||
if((unsigned)selected < data::users.size() - 1)
|
||||
selected++;
|
||||
|
||||
if(selected >= (int)start + 32)
|
||||
start += 8;
|
||||
}
|
||||
else if(down & KEY_LEFT)
|
||||
{
|
||||
if(selected > 0)
|
||||
selected--;
|
||||
|
||||
if(selected < (int)start)
|
||||
start -= 8;
|
||||
}
|
||||
else if(down & KEY_UP)
|
||||
{
|
||||
selected -= 8;
|
||||
if(selected < 0)
|
||||
selected = 0;
|
||||
|
||||
if(selected - start >= 32)
|
||||
start -= 8;
|
||||
}
|
||||
else if(down & KEY_DOWN)
|
||||
{
|
||||
selected += 8;
|
||||
if(selected > (int)data::users.size() - 1)
|
||||
selected = data::users.size() - 1;
|
||||
|
||||
if(selected - start >= 32)
|
||||
start += 8;
|
||||
}
|
||||
else if(down & KEY_A)
|
||||
{
|
||||
data::curUser = data::users[selected];
|
||||
//Reset this
|
||||
start = 0;
|
||||
selected = 0;
|
||||
selRectX = 64, selRectY = 74;
|
||||
mstate = TTL_SEL;
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
@@ -248,22 +301,126 @@ namespace ui
|
||||
for(unsigned i = 0; i < data::users.size(); i++)
|
||||
fs::dumpAllUserSaves(data::users[i]);
|
||||
}
|
||||
|
||||
unsigned x = 70, y = 80;
|
||||
unsigned endUser = start + 32;
|
||||
if(start + 32 > (int)data::users.size())
|
||||
endUser = data::users.size();
|
||||
|
||||
uint32_t rectClr = 0xFF << 24 | ((0xBB + clrShft) & 0xFF) << 16 | ((0x60 + clrShft)) << 8 | 0x00;
|
||||
gfx::drawRectangle(selRectX, selRectY, 140, 140, rectClr);
|
||||
|
||||
for(unsigned i = start; i < endUser; y += 144)
|
||||
{
|
||||
unsigned endRow = i + 8;
|
||||
for(unsigned tX = x; i < endRow; i++, tX += 144)
|
||||
{
|
||||
if(i == endUser)
|
||||
break;
|
||||
|
||||
if((int)i == selected)
|
||||
{
|
||||
if(selRectX != tX - 6)
|
||||
{
|
||||
if(selRectX < tX - 6)
|
||||
selRectX += 24;
|
||||
else
|
||||
selRectX -= 24;
|
||||
}
|
||||
|
||||
if(selRectY != y - 6)
|
||||
{
|
||||
if(selRectY < y - 6)
|
||||
selRectY += 24;
|
||||
else
|
||||
selRectX -= 24;
|
||||
}
|
||||
|
||||
std::string username = data::users[selected].getUsername();
|
||||
unsigned userWidth = gfx::getTextWidth(username, 32);
|
||||
int userRectWidth = userWidth + 32, userRectX = (tX + 64) - (userRectWidth / 2);
|
||||
if(userRectX < 16)
|
||||
userRectX = 16;
|
||||
|
||||
if(userRectX + userRectWidth > 1264)
|
||||
userRectX = 1264 - userRectWidth;
|
||||
|
||||
drawTextbox(userRectX, y - 50, userRectWidth, 38);
|
||||
gfx::drawText(username, userRectX + 16, y - 50, 32, txtClr);
|
||||
}
|
||||
data::users[i].icn.drawNoBlendSkip(tX, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateTitleMenu(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
titleMenu.handleInput(down, held);
|
||||
//Static vars so they don't change on every loop
|
||||
//Where to start in titles, selected title
|
||||
static int start = 0, selected = 0;
|
||||
|
||||
if(down & KEY_A)
|
||||
//Color shift for rect
|
||||
static uint8_t clrShft = 0;
|
||||
//Whether or not we're adding or subtracting from clrShft
|
||||
static bool clrAdd = true;
|
||||
|
||||
//Selected rectangle X and Y.
|
||||
static unsigned selRectX = 64, selRectY = 74;
|
||||
|
||||
if(clrAdd)
|
||||
{
|
||||
data::curData = data::curUser.titles[titleMenu.getSelected()];
|
||||
clrShft += 4;
|
||||
if(clrShft > 63)
|
||||
clrAdd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
clrShft--;
|
||||
if(clrShft == 0)
|
||||
clrAdd = true;
|
||||
}
|
||||
|
||||
if(down & KEY_RIGHT)
|
||||
{
|
||||
if(selected < (int)data::curUser.titles.size() - 1)
|
||||
selected++;
|
||||
|
||||
if(selected >= (int)start + 32)
|
||||
start += 8;
|
||||
}
|
||||
else if(down & KEY_LEFT)
|
||||
{
|
||||
if(selected > 0)
|
||||
selected--;
|
||||
|
||||
if(selected < (int)start)
|
||||
start -= 8;
|
||||
}
|
||||
else if(down & KEY_UP)
|
||||
{
|
||||
selected -= 8;
|
||||
if(selected < 0)
|
||||
selected = 0;
|
||||
|
||||
if(selected < start)
|
||||
start -= 8;
|
||||
}
|
||||
else if(down & KEY_DOWN)
|
||||
{
|
||||
selected += 8;
|
||||
if(selected > (int)data::curUser.titles.size() - 1)
|
||||
selected = data::curUser.titles.size() - 1;
|
||||
|
||||
if(selected - start >= 32)
|
||||
start += 8;
|
||||
}
|
||||
else if(down & KEY_A)
|
||||
{
|
||||
data::curData = data::curUser.titles[selected];
|
||||
if(fs::mountSave(data::curUser, data::curData))
|
||||
{
|
||||
util::makeTitleDir(data::curUser, data::curData);
|
||||
|
||||
folderMenuPrepare(data::curUser, data::curData);
|
||||
|
||||
mstate = FLD_SEL;
|
||||
}
|
||||
}
|
||||
@@ -272,40 +429,68 @@ namespace ui
|
||||
fs::dumpAllUserSaves(data::curUser);
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
mstate = USR_SEL;
|
||||
|
||||
if(data::sysSave)
|
||||
{
|
||||
std::string drawType = "Type: ";
|
||||
switch(data::curUser.titles[titleMenu.getSelected()].getType())
|
||||
{
|
||||
case FsSaveDataType_SystemSaveData:
|
||||
drawType += "System Save";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_SaveData:
|
||||
drawType += "Save Data";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_BcatDeliveryCacheStorage:
|
||||
drawType += "Bcat Delivery Cache";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_DeviceSaveData:
|
||||
drawType += "Device Save";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_TemporaryStorage:
|
||||
drawType += "Temp Storage";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_CacheStorage:
|
||||
drawType += "Cache Storage";
|
||||
break;
|
||||
}
|
||||
|
||||
gfx::drawText(drawType, 16, 668, 32, mnuTxt);
|
||||
start = 0;
|
||||
selected = 0;
|
||||
selRectX = 64;
|
||||
selRectY = 74;
|
||||
mstate = USR_SEL;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned x = 70, y = 80;
|
||||
|
||||
unsigned endTitle = start + 32;
|
||||
if(start + 32 > (int)data::curUser.titles.size())
|
||||
endTitle = data::curUser.titles.size();
|
||||
|
||||
//draw Rect so it's always behind icons
|
||||
uint32_t rectClr = 0xFF << 24 | ((0xBB + clrShft) & 0xFF) << 16 | ((0x60 + clrShft)) << 8 | 0x00;
|
||||
gfx::drawRectangle(selRectX, selRectY, 140, 140, rectClr);
|
||||
|
||||
for(unsigned i = start; i < endTitle; y += 144)
|
||||
{
|
||||
unsigned endRow = i + 8;
|
||||
for(unsigned tX = x; i < endRow; i++, tX += 144)
|
||||
{
|
||||
if(i == endTitle)
|
||||
break;
|
||||
|
||||
if((int)i == selected)
|
||||
{
|
||||
//Most Switch icons seem to be 256x256, we're drawing them 128x128
|
||||
if(selRectX != tX - 6)
|
||||
{
|
||||
if(selRectX < tX - 6)
|
||||
selRectX += 24;
|
||||
else
|
||||
selRectX -= 24;
|
||||
}
|
||||
|
||||
if(selRectY != y - 6)
|
||||
{
|
||||
if(selRectY < y - 6)
|
||||
selRectY += 24;
|
||||
else
|
||||
selRectY -= 24;
|
||||
}
|
||||
|
||||
std::string title = data::curUser.titles[selected].getTitle();
|
||||
unsigned titleWidth = gfx::getTextWidth(title, 32);
|
||||
int rectWidth = titleWidth + 32, rectX = (tX + 64) - (rectWidth / 2);
|
||||
if(rectX < 16)
|
||||
rectX = 16;
|
||||
|
||||
if(rectX + rectWidth > 1264)
|
||||
rectX = 1264 - rectWidth;
|
||||
|
||||
drawTextbox(rectX, y - 50, rectWidth, 38);
|
||||
gfx::drawText(title, rectX + 16, y - 50, 32, txtClr);
|
||||
}
|
||||
data::curUser.titles[i].icon.drawHalf(tX, y);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void updateFolderMenu(const uint64_t& down, const uint64_t& held)
|
||||
|
||||
Reference in New Issue
Block a user