Skip to content

Commit

Permalink
Add scripts to romfs and browse them properly
Browse files Browse the repository at this point in the history
  • Loading branch information
piepie62 committed Oct 11, 2018
1 parent 8888689 commit fa5ae02
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 76 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ assets/romfs/mg/*.json
assets/romfs/mg/*.bin
assets/romfs/gfx/*
!assets/romfs/gfx/pkm_spritesheet.t3x
!assets/romfs/gfx/types_spritesheet.t3x
!assets/romfs/gfx/types_spritesheet.t3x
assets/romfs/scripts/
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ GRAPHICS := assets/gfx/ui # \
ROMFS := assets/romfs
GFXBUILD := $(ROMFS)/gfx
PACKER := EventsGalleryPacker
SCRIPTS := PKSM-Scripts

# If left blank, will try to use "icon.png", "$(TARGET).png", or the default ctrulib icon, in that order
ICON := assets/icon.png
Expand Down Expand Up @@ -214,8 +215,11 @@ endif
#---------------------------------------------------------------------------------
all:
@mkdir -p $(BUILD) $(GFXBUILD) $(OUTDIR)
@cd $(BUILD)/$(PACKER) && python packer.py
@cd $(BUILD)/$(PACKER) && python3 packer.py
@cd $(BUILD)/$(PACKER) && mv out/*.bin out/*.json ../../assets/romfs/mg
@cd $(BUILD)/$(SCRIPTS) && python3 genScripts.py
@rm -r assets/romfs/scripts
@cd $(BUILD)/$(SCRIPTS) && mv -f scripts ../../assets/romfs
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile $(OUTPUT).3dsx
@bannertool makebanner -i "$(BANNER_IMAGE)" -a "$(BANNER_AUDIO)" -o $(BUILD)/banner.bnr
@bannertool makesmdh -s "$(APP_TITLE)" -l "$(APP_DESCRIPTION)" -p "$(APP_AUTHOR)" -i "$(APP_ICON)" -f "$(ICON_FLAGS)" -o $(BUILD)/icon.icn
Expand Down
6 changes: 3 additions & 3 deletions include/gui/screen/ScriptScreen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define SCRIPTSCREEN_HPP

#include "Screen.hpp"
#include "Directory.hpp"
#include "STDirectory.hpp"
#include "Hid.hpp"

class ScriptScreen : public Screen
Expand All @@ -44,10 +44,10 @@ class ScriptScreen : public Screen
void updateEntries();
void applyScript();
std::string currDirString;
size_t origDirLength;
Directory currDir;
STDirectory currDir;
std::vector<std::pair<std::string, bool>> currFiles;
Hid hid;
bool sdSearch;
};

#endif
59 changes: 59 additions & 0 deletions include/io/STDirectory.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* This file is part of PKSM
* Copyright (C) 2016-2018 Bernardo Giordano, Admiral Fish, piepie62
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/

#ifndef STDIRECTORY_HPP
#define STDIRECTORY_HPP

#include <dirent.h>
#include <3ds.h>
#include <errno.h>
#include <string>
#include <vector>

struct STDirectoryEntry {
std::string name;
bool directory;
};

class STDirectory
{
public:
STDirectory(const std::string& root);
~STDirectory(void) { };

Result error(void);
std::string item(size_t index);
bool folder(size_t index);
bool good(void);
size_t count(void);

private:
std::vector<STDirectoryEntry> mList;
Result mError;
bool mGood;
};

#endif
177 changes: 106 additions & 71 deletions source/gui/screen/ScriptScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,38 +40,38 @@ namespace
{
case 7:
case 8:
return "/3ds/PKSM/scripts/hgss";
return "/scripts/hgss";
case 10:
case 11:
return "/3ds/PKSM/scripts/dp";
return "/scripts/dp";
case 12:
return "/3ds/PKSM/scripts/pt";
return "/scripts/pt";
case 20:
case 21:
return "/3ds/PKSM/scripts/bw";
return "/scripts/bw";
case 22:
case 23:
return "/3ds/PKSM/scripts/b2w2";
return "/scripts/b2w2";
case 24:
case 25:
return "/3ds/PKSM/scripts/xy";
return "/scripts/xy";
case 26:
case 27:
return "/3ds/PKSM/scripts/oras";
return "/scripts/oras";
case 30:
case 31:
return "/3ds/PKSM/scripts/sm";
return "/scripts/sm";
case 32:
case 33:
return "/3ds/PKSM/scripts/usum";
return "/scripts/usum";
default:
return "";
}
}
}

ScriptScreen::ScriptScreen() : currDirString(getScriptDir(TitleLoader::save->version())), origDirLength(currDirString.size()),
currDir(Archive::sd(), StringUtils::UTF8toUTF16(currDirString)), hid(8, 1)
ScriptScreen::ScriptScreen() : currDirString("romfs:" + getScriptDir(TitleLoader::save->version())),
currDir(currDirString), hid(8, 1), sdSearch(false)
{
updateEntries();
}
Expand Down Expand Up @@ -105,6 +105,7 @@ void ScriptScreen::draw() const
Gui::backgroundBottom(true);
C2D_DrawRectSolid(20, 40, 0.5f, 280, 60, C2D_Color32(128, 128, 128, 255));
C2D_DrawRectSolid(21, 41, 0.5f, 278, 58, COLOR_MASKBLACK);
Gui::staticText(GFX_BOTTOM, 224, "Press \uE002 to switch between built-in scripts and ones on the SD card", FONT_SIZE_9, FONT_SIZE_9, COLOR_WHITE);

Gui::dynamicText(currFiles[hid.fullIndex()].first, 30, 44, FONT_SIZE_11, FONT_SIZE_11, COLOR_WHITE);
}
Expand All @@ -115,15 +116,15 @@ void ScriptScreen::update(touchPosition* touch)
u32 down = hidKeysDown();
if (down & KEY_B)
{
if (currDirString.size() == origDirLength)
if (currDirString == (sdSearch ? "/3ds/PKSM" : "romfs:") + getScriptDir(TitleLoader::save->version()))
{
Gui::screenBack();
return;
}
else
{
currDirString = currDirString.substr(0, currDirString.find_last_of('/'));
currDir = Directory(Archive::sd(), StringUtils::UTF8toUTF16(currDirString));
currDir = STDirectory(currDirString);
updateEntries();
}
}
Expand All @@ -132,7 +133,7 @@ void ScriptScreen::update(touchPosition* touch)
if (currFiles[hid.fullIndex()].second)
{
currDirString += '/' + currFiles[hid.fullIndex()].first;
currDir = Directory(Archive::sd(), StringUtils::UTF8toUTF16(currDirString));
currDir = STDirectory(currDirString);
updateEntries();
}
else
Expand All @@ -143,6 +144,13 @@ void ScriptScreen::update(touchPosition* touch)
}
}
}
else if (down & KEY_X)
{
sdSearch = !sdSearch;
currDirString = (sdSearch ? "/3ds/PKSM" : "romfs:") + getScriptDir(TitleLoader::save->version());
currDir = STDirectory(currDirString);
updateEntries();
}
}

void ScriptScreen::updateEntries()
Expand All @@ -151,7 +159,11 @@ void ScriptScreen::updateEntries()
currFiles.clear();
for (size_t i = 0; i < currDir.count(); i++)
{
currFiles.push_back(std::make_pair(StringUtils::UTF16toUTF8(currDir.item(i)), currDir.folder(i)));
std::string item = currDir.item(i);
if (item != "." && item != "..")
{
currFiles.push_back(std::make_pair(item, currDir.folder(i)));
}
}
std::sort(currFiles.begin(), currFiles.end(), [this](std::pair<std::string, bool>& first, std::pair<std::string, bool>& second)
{
Expand All @@ -170,75 +182,98 @@ void ScriptScreen::updateEntries()
});
}

void ScriptScreen::applyScript()
static std::pair<u8*, size_t> scriptRead(std::string path)
{
FSStream in(Archive::sd(), StringUtils::UTF8toUTF16(currDirString + '/' + currFiles[hid.fullIndex()].first), FS_OPEN_READ);
if (in.good())
u8* data = nullptr;
size_t size = 0;
if (path.find("romfs") == 0)
{
size_t size = in.size();
u8* data = new u8[size];
in.read(data, size);
in.close();

for (size_t i = 0; i < strlen(MAGIC); i++)
FILE *fptr = fopen(path.c_str(), "rt");
fseek(fptr, 0, SEEK_END);
size = ftell(fptr);
rewind(fptr);
data = new u8[size];
fread(data, size, 1, fptr);
fclose(fptr);
}
else
{
FSStream in(Archive::sd(), StringUtils::UTF8toUTF16(path), FS_OPEN_READ);
if (in.good())
{
if (data[i] != MAGIC[i])
{
Gui::warn("Not a valid script!");
return;
}
size = in.size();
u8* data = new u8[size];
in.read(data, size);
in.close();
}
else
{
Gui::warn("Could not open script file!");
in.close();
}
}

return {data, size};
}

void ScriptScreen::applyScript()
{
auto scriptData = scriptRead(currDirString + '/' + currFiles[hid.fullIndex()].first);

size_t index = strlen(MAGIC);
while (index < size)
for (size_t i = 0; i < strlen(MAGIC); i++)
{
if (scriptData.first[i] != MAGIC[i])
{
u32 offset = *(u32*)(data + index);
u32 length = *(u32*)(data + index + 4);
u32 repeat = *(u32*)(data + index + 8 + length);
Gui::warn("Not a valid script!");
return;
}
}

size_t index = strlen(MAGIC);
while (index < scriptData.second)
{
u32 offset = *(u32*)(scriptData.first + index);
u32 length = *(u32*)(scriptData.first + index + 4);
u32 repeat = *(u32*)(scriptData.first + index + 8 + length);

if (TitleLoader::save->generation() == 4)
if (TitleLoader::save->generation() == 4)
{
u32 sbo = 0;
u32 gbo = 0;
switch (TitleLoader::save->version())
{
u32 sbo = 0;
u32 gbo = 0;
switch (TitleLoader::save->version())
{
case 7:
case 8:
sbo = ((SavHGSS*)TitleLoader::save.get())->sbo;
gbo = ((SavHGSS*)TitleLoader::save.get())->gbo;
break;
case 10:
case 11:
sbo = ((SavDP*)TitleLoader::save.get())->sbo;
gbo = ((SavDP*)TitleLoader::save.get())->gbo;
break;
case 12:
sbo = ((SavPT*)TitleLoader::save.get())->sbo;
gbo = ((SavPT*)TitleLoader::save.get())->gbo;
break;
}
if (TitleLoader::save->boxOffset(0, 0) - sbo <= offset && TitleLoader::save->boxOffset(TitleLoader::save->boxes, 0) - sbo >= offset)
{
offset += sbo;
}
else
{
offset += gbo;
}
case 7:
case 8:
sbo = ((SavHGSS*)TitleLoader::save.get())->sbo;
gbo = ((SavHGSS*)TitleLoader::save.get())->gbo;
break;
case 10:
case 11:
sbo = ((SavDP*)TitleLoader::save.get())->sbo;
gbo = ((SavDP*)TitleLoader::save.get())->gbo;
break;
case 12:
sbo = ((SavPT*)TitleLoader::save.get())->sbo;
gbo = ((SavPT*)TitleLoader::save.get())->gbo;
break;
}

for (size_t i = 0; i < repeat; i++)
if (TitleLoader::save->boxOffset(0, 0) - sbo <= offset && TitleLoader::save->boxOffset(TitleLoader::save->boxes, 0) - sbo >= offset)
{
offset += sbo;
}
else
{
std::copy(data + index + 8, data + index + 8 + length, TitleLoader::save->data + offset + i * length);
offset += gbo;
}
}

index += 12 + length;
for (size_t i = 0; i < repeat; i++)
{
std::copy(scriptData.first + index + 8, scriptData.first + index + 8 + length, TitleLoader::save->data + offset + i * length);
}

delete[] data;
}
else
{
Gui::warn("Could not open script file!");
index += 12 + length;
}

delete[] scriptData.first;
}
Loading

0 comments on commit fa5ae02

Please sign in to comment.