Skip to content

Commit

Permalink
Merge pull request #3 from ev1l0rd/card-region-check
Browse files Browse the repository at this point in the history
Card region check
  • Loading branch information
noirscape authored Apr 11, 2018
2 parents d13c9c2 + f2f5bf8 commit 028782d
Show file tree
Hide file tree
Showing 8 changed files with 328 additions and 136 deletions.
12 changes: 12 additions & 0 deletions source/const.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _CONSTH_
#define _CONSTH_

#define PAL_TITLEID 0x00040000001BFB00
#define USA_TITLEID 0x00040000001BB200
#define JPN_TITLEID 0x00040000001BFC00

#define PAL_LOWID PAL_TITLEID ^ 0x4000000000000
#define USA_LOWID USA_TITLEID ^ 0x4000000000000
#define JPN_LOWID USA_TITLEID ^ 0x4000000000000

#endif
61 changes: 21 additions & 40 deletions source/editprofile.c
Original file line number Diff line number Diff line change
@@ -1,41 +1,19 @@
#include <3ds.h>
#include <stdio.h>
#include <stdlib.h>
#include "struct.h"

Result edit_profile(int profile_num, int fusion_mode)
Result edit_profile(int profile_num, bool fusion_mode, u32 lowid, InstallType install_type)
{

// Determine region for the TID
u8 region_code;

Result res = CFGU_SecureInfoGetRegion(&region_code);
if(R_FAILED(res)) return res;

u32 highid = 0x00040000;
u32 lowid = 0;

switch(region_code)
{
case CFG_REGION_JPN:
lowid = 0x001BFC00;
break;
case CFG_REGION_USA:
lowid = 0x001BB200;
break;
case CFG_REGION_EUR:
case CFG_REGION_AUS:
lowid = 0x001BFB00;
break;
default:
lowid = 0x00;
break;
}

FS_MediaType media_type = (install_type == SD_CARD) ? MEDIATYPE_SD : MEDIATYPE_GAME_CARD;
// Open save archive
const u32 path[3] = { MEDIATYPE_SD, lowid, highid };
const u32 path[3] = { media_type, lowid, 0x00040000 };

FS_Archive save_archive;

res = FSUSER_OpenArchive(&save_archive, ARCHIVE_USER_SAVEDATA, (FS_Path){PATH_BINARY, 12, path});
FS_ArchiveID archive_id = (install_type == SD_CARD) ? ARCHIVE_USER_SAVEDATA : ARCHIVE_GAMECARD_SAVEDATA;

Result res;
res = FSUSER_OpenArchive(&save_archive, archive_id, (FS_Path){PATH_BINARY, 12, path});
if(R_FAILED(res)) return res;

char profile_path[0x107] = {0};
Expand Down Expand Up @@ -120,16 +98,19 @@ Result edit_profile(int profile_num, int fusion_mode)
return res;
}

// Remove secure value
u64 in = ((u64)SECUREVALUE_SLOT_SD << 32) | (((u64)lowid >> 8) << 8);
u8 out;
res = FSUSER_ControlSecureSave(SECURESAVE_ACTION_DELETE, &in, 8, &out, 1);
if(R_FAILED(res))
// Remove secure value if this is an SD card installation, otherwise, carry on.
if (install_type == SD_CARD)
{
FSUSER_CloseArchive(save_archive);
printf("Couldn't remove secure value.\n");
return res;
}
u64 in = ((u64)SECUREVALUE_SLOT_SD << 32) | (((u64)lowid >> 8) << 8);
u8 out;
res = FSUSER_ControlSecureSave(SECURESAVE_ACTION_DELETE, &in, 8, &out, 1);
if(R_FAILED(res))
{
FSUSER_CloseArchive(save_archive);
printf("Couldn't remove secure value.\n");
return res;
}
}

// Close archive
FSUSER_CloseArchive(save_archive);
Expand Down
8 changes: 7 additions & 1 deletion source/editprofile.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
#ifndef _EDITPROFILEH_
#define _EDITPROFILEH_

#include <3ds.h>
#include <stdio.h>
#include <stdlib.h>
#include "struct.h"
Result edit_profile(int profile_num, bool fusion_mode, u32 lowid, InstallType install_type);

Result edit_profile(char profile_num, int fusion_mode);
#endif
226 changes: 137 additions & 89 deletions source/main.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
#include <stdio.h>
#include <3ds.h>
#include "editprofile.h"
#include "main.h"
#include "title.h"
#include "const.h"
#include "struct.h"

typedef enum {
/* Default sort but its commented to make it easy on _my_ mind. */
MAIN_SCREEN = 0,
SELECT_SAVE = 1,
FUSION_OR_NOT = 2,
THE_WIZARD_IS_BUSY = 3,
SUCCESS = 4
}States;

int main() {
int main()
{
cfguInit();
gfxInitDefault();
PrintConsole topScreen, bottomScreen;
Expand All @@ -21,13 +15,20 @@ int main() {
consoleSelect(&topScreen);

States state = MAIN_SCREEN;
int profile_num;
int fusion_mode = 0;
int not_busy = 1;
Regions regions_found = {false, false, false, 0};
int profile_num = 0;
bool fusion_mode = false;
bool not_busy = true;
bool save_unseen = true;
bool fusion_unseen = true;
bool region_autochecked = false;
InstallType install_type;
u32 lowid;

printf("Metroid: SAMUS RETURNS amiibo unlocker v0.2-alpha\nThis unlocker is in ALPHA. Bugs and stuff are expected.\nPress A to continue.\n");
printf("Metroid: SAMUS RETURNS amiibo unlocker v1.1a\nPress A to continue.\n");

while(aptMainLoop()) {
while(aptMainLoop())
{
hidScanInput();
u32 kDown = hidKeysDown();
if (kDown & KEY_START && not_busy)
Expand All @@ -36,86 +37,133 @@ int main() {
break;
}

if (state == MAIN_SCREEN) // State 0 = introduction
{
if (kDown & KEY_A)
{
printSaveSelect();
state = SELECT_SAVE;
}
}
if (state == SELECT_SAVE) // State 1 = Save select
{
if (kDown & KEY_Y) // Save 1 was chosen
{
profile_num = 0;
printf("You selected the 1st save file.\n");
printFusionSelect();
state = FUSION_OR_NOT;
}
if (kDown & KEY_B) // Save 2 was chosen
{
profile_num = 1;
printf("You selected the 2nd save file.\n");
printFusionSelect();
state = FUSION_OR_NOT;
}
if (kDown & KEY_X) // Save 3 was chosen
{
profile_num = 2;
printf("You selected the 3rd save file.\n");
printFusionSelect();
state = FUSION_OR_NOT;
}
}
if (state == FUSION_OR_NOT) // State 2 = Fusion mode, yay or nay
{
if (kDown & KEY_A)
{
fusion_mode = 1;
printf("Enabled fusion mode.\n");
state = THE_WIZARD_IS_BUSY;
}
if (kDown & KEY_B)
{
printf("Not enabling fusion mode.\n");
state = THE_WIZARD_IS_BUSY;
}
}
if (state == THE_WIZARD_IS_BUSY) // The wizard is busy installing your software, don't touch anything.
{
not_busy = 0;
Result res = edit_profile(profile_num, fusion_mode);
if(R_FAILED(res)) {
int cursorX = topScreen.cursorX;
int cursorY = topScreen.cursorY;
printf("\x1b[30;16H%4lx\n", res);
topScreen.cursorX = cursorX;
topScreen.cursorY = cursorY;
printf("Something went wrong, please see the error message below.\n");
} else {
printf("Amiibo's have been unlocked for the selected save file. Press START to exit.");
}
not_busy = 1;
state = SUCCESS;
switch(state){
case MAIN_SCREEN:
if (kDown & KEY_A)
{
state = VERSION_TO_EDIT;
}
break;

case VERSION_TO_EDIT: // Determining region
if (!region_autochecked)
{
lowid = title_check(&regions_found, &install_type);
if (regions_found.total_regions == 0)
{
printf("Press START to exit.\n");
state = SUCCESS;
}
else if (regions_found.total_regions == 1)
{
state = SELECT_SAVE;
}
else
{
region_autochecked = true;
// Insert code here to display stuff about region selection
if(regions_found.JPN)
printf("JPN region detected. Press X to use this region.\n");
if(regions_found.USA)
printf("USA region detected. Press Y to use this region.\n");
if(regions_found.PAL)
printf("PAL region detected. Press A to use this region.\n");
}
}
else
{
if (kDown & KEY_X && regions_found.JPN) // JPN region
{
printf("JPN region selected.\n");
lowid = JPN_LOWID;
state = SELECT_SAVE;
}
if (kDown & KEY_Y && regions_found.USA) // USA region
{
printf("USA region selected.\n");
lowid = USA_LOWID;
state = SELECT_SAVE;
}
if (kDown & KEY_A && regions_found.PAL) // PAL region
{
printf("PAL region selected.\n");
lowid = PAL_LOWID;
state = SELECT_SAVE;
}
}
break;

case SELECT_SAVE: // Save file selection
if (save_unseen)
{
printf("\n---------------------\nSelect a save file to modify.\nY for save 1, B for save 2, X for save 3.\nPress START to exit.\n");
save_unseen = false;
}
if (kDown & KEY_Y) // Save 1 was chosen
{
profile_num = 0;
printf("You selected the 1st save file.\n");
state = FUSION_OR_NOT;
}
if (kDown & KEY_B) // Save 2 was chosen
{
profile_num = 1;
printf("You selected the 2nd save file.\n");
state = FUSION_OR_NOT;
}
if (kDown & KEY_X) // Save 3 was chosen
{
profile_num = 2;
printf("You selected the 3rd save file.\n");
state = FUSION_OR_NOT;
}
break;

case FUSION_OR_NOT: // Enable fusion mode, yay or nay?
if (fusion_unseen)
{
printf("\n---------------------\nEnable fusion mode for this save file?\n A for yes, B for no.\n");
fusion_unseen = false;
}
if (kDown & KEY_A)
{
fusion_mode = true;
printf("Enabled fusion mode.\n");
state = THE_WIZARD_IS_BUSY;
}
if (kDown & KEY_B)
{
printf("Not enabling fusion mode.\n");
state = THE_WIZARD_IS_BUSY;
}
break;

case THE_WIZARD_IS_BUSY: // Here the editing happens
not_busy = false;
Result res = edit_profile(profile_num, fusion_mode, lowid, install_type);
if(R_FAILED(res))
{
printf("\x1b[s\x1b[30;16H%4lx\n\x1b[u", res);
printf("Something went wrong, please see the error message below.\n");
}
else
{
printf("Amiibo's have been unlocked for the selected save file. Press START to exit.");
}
not_busy = true;
state = SUCCESS;
break;

case SUCCESS:
break;
}
// State 4 is technically success, but it just means it isn't listening to anything anymore and waits for closing.

gfxFlushBuffers();
gfxSwapBuffers();
gspWaitForVBlank();
}

cfguExit();
fsExit();
gfxExit();
return 0;
}

void printSaveSelect() {
printf("\n---------------------\nSelect a save file to modify.\nY for save 1, B for save 2, X for save 3.\nPress START to exit.\n");
}

void printFusionSelect() {
printf("\n---------------------\nEnable fusion mode for this save file?\n A for yes, B for no.\n");
}
}
6 changes: 0 additions & 6 deletions source/main.h

This file was deleted.

Loading

0 comments on commit 028782d

Please sign in to comment.