mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 21:52:48 +00:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
3e5c7c6400 | ||
|
31c66e70db | ||
|
b0ded0f62f | ||
|
d3359a1d05 | ||
|
ef32538f5a | ||
|
1d1b604775 | ||
|
62b507666c | ||
|
197673e1c1 | ||
|
e942afff10 | ||
|
106f42c700 | ||
|
3367faa383 |
12
Makefile
12
Makefile
@ -55,9 +55,13 @@ release: clean
|
|||||||
|
|
||||||
@cp $(FIRM) $(RELDIR)
|
@cp $(FIRM) $(RELDIR)
|
||||||
@cp $(OUTDIR)/$(FLAVOR)_ntr.firm $(RELDIR)/ntrboot/
|
@cp $(OUTDIR)/$(FLAVOR)_ntr.firm $(RELDIR)/ntrboot/
|
||||||
|
@cp $(OUTDIR)/$(FLAVOR)_ntr.firm.sha $(RELDIR)/ntrboot/
|
||||||
@cp $(OUTDIR)/$(FLAVOR)_ntr_dev.firm $(RELDIR)/ntrboot/
|
@cp $(OUTDIR)/$(FLAVOR)_ntr_dev.firm $(RELDIR)/ntrboot/
|
||||||
|
@cp $(OUTDIR)/$(FLAVOR)_ntr_dev.firm.sha $(RELDIR)/ntrboot/
|
||||||
@cp $(OUTDIR)/$(FLAVOR).firm $(RELDIR)/
|
@cp $(OUTDIR)/$(FLAVOR).firm $(RELDIR)/
|
||||||
|
@cp $(OUTDIR)/$(FLAVOR).firm.sha $(RELDIR)/
|
||||||
@cp $(OUTDIR)/$(FLAVOR)_dev.firm $(RELDIR)/
|
@cp $(OUTDIR)/$(FLAVOR)_dev.firm $(RELDIR)/
|
||||||
|
@cp $(OUTDIR)/$(FLAVOR)_dev.firm.sha $(RELDIR)/
|
||||||
@cp $(ELF) $(RELDIR)/elf
|
@cp $(ELF) $(RELDIR)/elf
|
||||||
@cp $(CURDIR)/README.md $(RELDIR)
|
@cp $(CURDIR)/README.md $(RELDIR)
|
||||||
@cp -R $(CURDIR)/resources/gm9 $(RELDIR)/gm9
|
@cp -R $(CURDIR)/resources/gm9 $(RELDIR)/gm9
|
||||||
@ -77,7 +81,11 @@ vram0:
|
|||||||
firm: $(ELF) vram0
|
firm: $(ELF) vram0
|
||||||
@test `wc -c <$(VRAM_OUT)` -le 3145728
|
@test `wc -c <$(VRAM_OUT)` -le 3145728
|
||||||
@mkdir -p $(call dirname,"$(FIRM)") $(call dirname,"$(FIRMD)")
|
@mkdir -p $(call dirname,"$(FIRM)") $(call dirname,"$(FIRMD)")
|
||||||
firmtool build $(FIRM) $(FTFLAGS) -g -A 0x18000000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy
|
@echo "[VERSION] $(VERSION)"
|
||||||
firmtool build $(FIRMD) $(FTDFLAGS) -g -A 0x18000000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy
|
@echo "[BUILD] $(DBUILTL)"
|
||||||
|
@echo "[FIRM] $(FIRM)"
|
||||||
|
@firmtool build $(FIRM) $(FTFLAGS) -g -A 0x18000000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy
|
||||||
|
@echo "[FIRM] $(FIRMD)"
|
||||||
|
@firmtool build $(FIRMD) $(FTDFLAGS) -g -A 0x18000000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy
|
||||||
|
|
||||||
.FORCE:
|
.FORCE:
|
||||||
|
15
README.md
15
README.md
@ -24,7 +24,7 @@ You may now run GodMode9 via holding the X Button (or any other button you chose
|
|||||||
## How to build this / developer info
|
## How to build this / developer info
|
||||||
Build `GodMode9.firm` via `make firm`. This requires [firmtool](https://github.com/TuxSH/firmtool), [Python 3.5+](https://www.python.org/downloads/) and [devkitARM](https://sourceforge.net/projects/devkitpro/) installed).
|
Build `GodMode9.firm` via `make firm`. This requires [firmtool](https://github.com/TuxSH/firmtool), [Python 3.5+](https://www.python.org/downloads/) and [devkitARM](https://sourceforge.net/projects/devkitpro/) installed).
|
||||||
|
|
||||||
You may run `make release` to get a nice, release-ready package of all required files. To build __SafeMode9__ (a bricksafe variant of GodMode9, with limited write permissions) instead of GodMode9, compile with `make FLAVOR=SafeMode9`. To switch screens, compile with `make SWITCH_SCREENS=1`. For additional customization, you may choose the internal font by replacing `font.pbm` inside the `data` directory. You may also hardcode the brightness via `make FIXED_BRIGHTNESS=x`, whereas `x` is a value between 0...15.
|
You may run `make release` to get a nice, release-ready package of all required files. To build __SafeMode9__ (a bricksafe variant of GodMode9, with limited write permissions) instead of GodMode9, compile with `make FLAVOR=SafeMode9`. To switch screens, compile with `make SWITCH_SCREENS=1`. For additional customization, you may choose the internal font by replacing `font_default.pbm` inside the `data` directory. You may also hardcode the brightness via `make FIXED_BRIGHTNESS=x`, whereas `x` is a value between 0...15.
|
||||||
|
|
||||||
Further customization is possible by hardcoding `aeskeydb.bin` (just put the file into the `data` folder when compiling). All files put into the `data` folder will turn up in the `V:` drive, but keep in mind there's a hard 3MB limit for all files inside, including overhead. A standalone script runner is compiled by providing `autorun.gm9` (again, in the `data` folder) and building with `make SCRIPT_RUNNER=1`.
|
Further customization is possible by hardcoding `aeskeydb.bin` (just put the file into the `data` folder when compiling). All files put into the `data` folder will turn up in the `V:` drive, but keep in mind there's a hard 3MB limit for all files inside, including overhead. A standalone script runner is compiled by providing `autorun.gm9` (again, in the `data` folder) and building with `make SCRIPT_RUNNER=1`.
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ To build a .firm signed with SPI boot keys (for ntrboot and the like), run `make
|
|||||||
|
|
||||||
|
|
||||||
## Bootloader mode
|
## Bootloader mode
|
||||||
Same as [boot9strap](https://github.com/SciresM/boot9strap), GodMode9 can be installed to the system FIRM partition ('FIRM0'). When executed from a FIRM partition, GodMode9 will default to bootloader mode and try to boot, in order, `FIRM from FCRAM` (see [A9NC](https://github.com/d0k3/A9NC/releases)), `0:/bootonce.firm` (will be deleted on a successful boot), `0:/boot.firm`, `1:/boot.firm`. In bootloader mode, hold R+LEFT on boot to enter the boot menu. *Installing GodMode9 to a FIRM partition is only recommended for developers and will overwrite [boot9strap](https://github.com/SciresM/boot9strap)*.
|
Same as [boot9strap](https://github.com/SciresM/boot9strap) or [fastboot3ds](https://github.com/derrekr/fastboot3DS), GodMode9 can be installed to the system FIRM partition ('FIRM0'). When executed from a FIRM partition, GodMode9 will default to bootloader mode and try to boot, in order, `FIRM from FCRAM` (see [A9NC](https://github.com/d0k3/A9NC/releases)), `0:/bootonce.firm` (will be deleted on a successful boot), `0:/boot.firm`, `1:/boot.firm`. In bootloader mode, hold R+LEFT on boot to enter the boot menu. *Installing GodMode9 to a FIRM partition is only recommended for developers and will overwrite [boot9strap](https://github.com/SciresM/boot9strap) or any other bootloader you have installed in there*.
|
||||||
|
|
||||||
|
|
||||||
## Write permissions system
|
## Write permissions system
|
||||||
@ -45,8 +45,8 @@ GodMode9 provides a write permissions system, which will protect you from accide
|
|||||||
|
|
||||||
|
|
||||||
## Support files
|
## Support files
|
||||||
For certain functionality, GodMode9 may need 'support files'. Support files should be placed into `0:/gm9/support`. Support files contain additional information that is required in decryption operations. A list of support files, and what they do, is found below. Please don't ask for support files - find them yourself.
|
For certain functionality, GodMode9 may need 'support files'. Support files should be placed into either `0:/gm9/support` or `1:/gm9/support`. Support files contain additional information that is required in decryption operations. A list of support files, and what they do, is found below. Please don't ask for support files - find them yourself.
|
||||||
* __`aeskeydb.bin`__: This should contain 0x25keyX, 0x18keyX and 0x1BkeyX to enable decryption of 7x / Secure3 / Secure4 encrypted NCCH files, 0x11key95 / 0x11key96 for FIRM decrypt support and 0x11keyOTP / 0x11keyIVOTP for 'secret' sector 0x96 crypto support. Entrypoints other than [boot9strap](https://github.com/SciresM/boot9strap) may require a aeskeydb.bin file. A known perfect `aeskeydb.bin` can be found somewhere on the net, is exactly 1024 byte big and has an MD5 of A5B28945A7C051D7A0CD18AF0E580D1B. Have fun hunting!
|
* __`aeskeydb.bin`__: This should contain 0x25keyX, 0x18keyX and 0x1BkeyX to enable decryption of 7x / Secure3 / Secure4 encrypted NCCH files, 0x11key95 / 0x11key96 for FIRM decrypt support and 0x11keyOTP / 0x11keyIVOTP for 'secret' sector 0x96 crypto support. Entrypoints other than [boot9strap](https://github.com/SciresM/boot9strap) or [fastboot3ds](https://github.com/derrekr/fastboot3DS) may require a aeskeydb.bin file. A known perfect `aeskeydb.bin` can be found somewhere on the net, is exactly 1024 byte big and has an MD5 of A5B28945A7C051D7A0CD18AF0E580D1B. Have fun hunting!
|
||||||
* __`seeddb.bin`__: This file is required to decrypt and mount seed encrypted NCCHs and CIAs if the seed in question is not installed to your NAND. Note that your seeddb.bin must also contain the seed for the specific game you need to decrypt.
|
* __`seeddb.bin`__: This file is required to decrypt and mount seed encrypted NCCHs and CIAs if the seed in question is not installed to your NAND. Note that your seeddb.bin must also contain the seed for the specific game you need to decrypt.
|
||||||
* __`encTitleKeys.bin`__ / __`decTitleKeys.bin`__: These files are optional and provide titlekeys, which are required to create updatable CIAs from NCCH / NCSD files. CIAs created without these files will still work, but won't be updatable from eShop.
|
* __`encTitleKeys.bin`__ / __`decTitleKeys.bin`__: These files are optional and provide titlekeys, which are required to create updatable CIAs from NCCH / NCSD files. CIAs created without these files will still work, but won't be updatable from eShop.
|
||||||
|
|
||||||
@ -127,14 +127,14 @@ With the possibilites GodMode9 provides, not everything may be obvious at first
|
|||||||
|
|
||||||
### System file handling
|
### System file handling
|
||||||
* __Check and fix CMACs (for any file that has them)__: The option will turn up in the A button menu if it is available for a given file (f.e. system savegames, `ticket.db`, etc...). This can also be done for multiple files at once if they are marked.
|
* __Check and fix CMACs (for any file that has them)__: The option will turn up in the A button menu if it is available for a given file (f.e. system savegames, `ticket.db`, etc...). This can also be done for multiple files at once if they are marked.
|
||||||
* __Mount ticket.db files and dump tickets__: Mount the file via the A button menu. Tickets are sorted into `eshop` (stuff from eshop, probably legit), `system` (system tickets, probably legit) and `unknown` (everything else, never legit) categories.
|
* __Mount ticket.db files and dump tickets__: Mount the file via the A button menu. Tickets are sorted into `eshop` (stuff from eshop), `system` (system tickets), `unknown` (typically empty) and `hidden` (hidden tickets, found via a deeper scan) categories. All tickets displayed are legit, fake tickets are ignored
|
||||||
* __Inject any NCCH CXI file into Health & Safety__: The option is found inside the A button menu for any NCCH CXI file. NCCH CXIs are found, f.e. inside of CIAs. Keep in mind there is a (system internal) size restriction on H&S injectable apps.
|
* __Inject any NCCH CXI file into Health & Safety__: The option is found inside the A button menu for any NCCH CXI file. NCCH CXIs are found, f.e. inside of CIAs. Keep in mind there is a (system internal) size restriction on H&S injectable apps.
|
||||||
* __Inject and dump GBA VC saves__: Find the options to do this inside the A button menu for `agbsave.bin` in the `S:` drive. Keep in mind that you need to start the specific GBA game on your console before dumping / injecting the save.
|
* __Inject and dump GBA VC saves__: Find the options to do this inside the A button menu for `agbsave.bin` in the `S:` drive. Keep in mind that you need to start the specific GBA game on your console before dumping / injecting the save.
|
||||||
* __Dump a copy of boot9, boot11 & your OTP__: This works on sighax, via boot9strap only. These files are found inside the `M:` drive and can be copied from there to any other place.
|
* __Dump a copy of boot9, boot11 & your OTP__: This works on sighax, via boot9strap only. These files are found inside the `M:` drive and can be copied from there to any other place.
|
||||||
|
|
||||||
### Support file handling
|
### Support file handling
|
||||||
* __Build `decTitleKeys.bin` / `encTitleKeys.bin` / `seeddb.bin`__: Press the HOME button, select `More...` -> `Build support files`. `decTitleKeys.bin` / `encTitleKeys.bin` can also be created / merged from tickets, `ticket.db` and other `decTitleKeys.bin` / `encTitleKeys.bin` files via the A button menu.
|
* __Build `decTitleKeys.bin` / `encTitleKeys.bin` / `seeddb.bin`__: Press the HOME button, select `More...` -> `Build support files`. `decTitleKeys.bin` / `encTitleKeys.bin` can also be created / merged from tickets, `ticket.db` and merged from other `decTitleKeys.bin` / `encTitleKeys.bin` files via the A button menu.
|
||||||
* __Build, mount, decrypt and encrypt `aeskeydb.bin`__: AES key databases can be built from other `aeskeydb.bin` or legacy `slot??Key?.bin` files. Just select one or more files, press A on one of them and then select `Build aeskeydb.bin`. Options for mounting, decrypting and encrypting are also found in the A button menu.
|
* __Build, mount, decrypt and encrypt `aeskeydb.bin`__: AES key databases can be merged from other `aeskeydb.bin` or build from legacy `slot??Key?.bin` files. Just select one or more files, press A on one of them and then select `Build aeskeydb.bin`. Options for mounting, decrypting and encrypting are also found in the A button menu.
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
@ -161,6 +161,7 @@ This tool would not have been possible without the help of numerous people. Than
|
|||||||
* **JaySea**, **YodaDaCoda**, **liomajor**, **Supster131**, **imanoob**, **Kasher_CS** and countless others from freenode #Cakey and the GBAtemp forums for testing, feedback and helpful hints
|
* **JaySea**, **YodaDaCoda**, **liomajor**, **Supster131**, **imanoob**, **Kasher_CS** and countless others from freenode #Cakey and the GBAtemp forums for testing, feedback and helpful hints
|
||||||
* **Shadowhand** for being awesome and [hosting my nightlies](https://d0k3.secretalgorithm.com/)
|
* **Shadowhand** for being awesome and [hosting my nightlies](https://d0k3.secretalgorithm.com/)
|
||||||
* **Plailect** for putting his trust in my tools and recommending this in [The Guide](https://3ds.guide/)
|
* **Plailect** for putting his trust in my tools and recommending this in [The Guide](https://3ds.guide/)
|
||||||
|
* **SirNapkin1334** for testing, bug reports and for hosting the official [GodMode9 Discord channel](https://discord.gg/EGu6Qxw)
|
||||||
* **Project Nayuki** for [qrcodegen](https://github.com/nayuki/QR-Code-generator)
|
* **Project Nayuki** for [qrcodegen](https://github.com/nayuki/QR-Code-generator)
|
||||||
* **Amazingmax fonts** for the Amazdoom font
|
* **Amazingmax fonts** for the Amazdoom font
|
||||||
* The fine folks on **freenode #Cakey**
|
* The fine folks on **freenode #Cakey**
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
PROCESSOR := ARM11
|
||||||
|
|
||||||
TARGET := $(shell basename $(CURDIR))
|
TARGET := $(shell basename $(CURDIR))
|
||||||
|
|
||||||
SOURCE := source
|
SOURCE := source
|
||||||
BUILD := build
|
BUILD := build
|
||||||
|
|
||||||
SUBARCH := -DARM11 -mcpu=mpcore -mtune=mpcore -mfloat-abi=soft -marm
|
SUBARCH := -D$(PROCESSOR) -mcpu=mpcore -mtune=mpcore -mfloat-abi=soft -marm
|
||||||
INCDIRS := source
|
INCDIRS := source
|
||||||
INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)")
|
INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)")
|
||||||
|
|
||||||
@ -26,12 +28,14 @@ clean:
|
|||||||
|
|
||||||
$(TARGET).elf: $(OBJECTS)
|
$(TARGET).elf: $(OBJECTS)
|
||||||
@mkdir -p "$(@D)"
|
@mkdir -p "$(@D)"
|
||||||
$(CC) $(LDFLAGS) $^ -o $@
|
@$(CC) $(LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
$(BUILD)/%.o: $(SOURCE)/%.c
|
$(BUILD)/%.o: $(SOURCE)/%.c
|
||||||
@mkdir -p "$(@D)"
|
@mkdir -p "$(@D)"
|
||||||
$(CC) -c $(CFLAGS) -o $@ $<
|
@echo "[$(PROCESSOR)] $<"
|
||||||
|
@$(CC) -c $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
$(BUILD)/%.o: $(SOURCE)/%.s
|
$(BUILD)/%.o: $(SOURCE)/%.s
|
||||||
@mkdir -p "$(@D)"
|
@mkdir -p "$(@D)"
|
||||||
$(CC) -c $(ASFLAGS) -o $@ $<
|
@echo "[$(PROCESSOR)] $<"
|
||||||
|
@$(CC) -c $(ASFLAGS) -o $@ $<
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
PROCESSOR := ARM9
|
||||||
|
|
||||||
TARGET := $(shell basename $(CURDIR))
|
TARGET := $(shell basename $(CURDIR))
|
||||||
|
|
||||||
SOURCE := source
|
SOURCE := source
|
||||||
BUILD := build
|
BUILD := build
|
||||||
|
|
||||||
SUBARCH := -DARM9 -mcpu=arm946e-s -mtune=arm946e-s -mfloat-abi=soft -mthumb
|
SUBARCH := -D$(PROCESSOR) -mcpu=arm946e-s -mtune=arm946e-s -mfloat-abi=soft -mthumb
|
||||||
INCDIRS := source source/common source/filesys source/crypto source/fatfs source/nand source/virtual source/game source/gamecart source/quicklz source/qrcodegen source/system source/utils
|
INCDIRS := source source/common source/filesys source/crypto source/fatfs source/nand source/virtual source/game source/gamecart source/quicklz source/qrcodegen source/system source/utils
|
||||||
INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)")
|
INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)")
|
||||||
|
|
||||||
@ -26,12 +28,14 @@ clean:
|
|||||||
|
|
||||||
$(TARGET).elf: $(OBJECTS)
|
$(TARGET).elf: $(OBJECTS)
|
||||||
@mkdir -p "$(@D)"
|
@mkdir -p "$(@D)"
|
||||||
$(CC) $(LDFLAGS) $^ -o $@
|
@$(CC) $(LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
$(BUILD)/%.o: $(SOURCE)/%.c
|
$(BUILD)/%.o: $(SOURCE)/%.c
|
||||||
@mkdir -p "$(@D)"
|
@mkdir -p "$(@D)"
|
||||||
$(CC) -c $(CFLAGS) -o $@ $<
|
@echo "[$(PROCESSOR)] $<"
|
||||||
|
@$(CC) -c $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
$(BUILD)/%.o: $(SOURCE)/%.s
|
$(BUILD)/%.o: $(SOURCE)/%.s
|
||||||
@mkdir -p "$(@D)"
|
@mkdir -p "$(@D)"
|
||||||
$(CC) -c $(ASFLAGS) -o $@ $<
|
@echo "[$(PROCESSOR)] $<"
|
||||||
|
@$(CC) -c $(ASFLAGS) -o $@ $<
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "lottery.h"
|
||||||
|
|
||||||
#define RGB(r,g,b) ((r)<<24|(b)<<16|(g)<<8|(r))
|
#define RGB(r,g,b) ((b)<<16|(g)<<8|(r))
|
||||||
|
|
||||||
// a base set of colors below
|
// a base set of colors below
|
||||||
#define COLOR_BLACK RGB(0x00, 0x00, 0x00)
|
#define COLOR_BLACK RGB(0x00, 0x00, 0x00)
|
||||||
@ -31,8 +32,8 @@
|
|||||||
#define COLOR_SUPERFUCHSIA RGB(0xFF, 0x00, 0xEF)
|
#define COLOR_SUPERFUCHSIA RGB(0xFF, 0x00, 0xEF)
|
||||||
|
|
||||||
// standard colors - used everywhere
|
// standard colors - used everywhere
|
||||||
#define COLOR_STD_BG COLOR_BLACK
|
#define COLOR_STD_BG LOTTERY_COLOR_BG
|
||||||
#define COLOR_STD_FONT COLOR_WHITE
|
#define COLOR_STD_FONT LOTTERY_COLOR_FONT
|
||||||
|
|
||||||
// colors for GodMode9 file browser
|
// colors for GodMode9 file browser
|
||||||
#define COLOR_SIDE_BAR COLOR_DARKGREY
|
#define COLOR_SIDE_BAR COLOR_DARKGREY
|
||||||
|
54
arm9/source/common/lottery.c
Normal file
54
arm9/source/common/lottery.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "lottery.h"
|
||||||
|
#include "rtc.h"
|
||||||
|
#include "colors.h"
|
||||||
|
#include "vram0.h"
|
||||||
|
|
||||||
|
#define LOTTERY_MAX 8
|
||||||
|
|
||||||
|
const LotteryTheme lo_theme[] =
|
||||||
|
{
|
||||||
|
{ // standard scheme
|
||||||
|
COLOR_WHITE,
|
||||||
|
COLOR_BLACK,
|
||||||
|
VRAM0_SPLASH_PCX,
|
||||||
|
VRAM0_FONT_PBM,
|
||||||
|
false
|
||||||
|
},
|
||||||
|
{ // bricked scheme
|
||||||
|
RGB(0xFF, 0xFF, 0x00),
|
||||||
|
RGB(0x00, 0x00, 0xFF),
|
||||||
|
"lottery/bricked/bootrom_splash.pcx",
|
||||||
|
"lottery/bricked/font_nbraille_4x6.pbm",
|
||||||
|
true
|
||||||
|
},
|
||||||
|
{ // C64 scheme
|
||||||
|
RGB(0x7B, 0x71, 0xD5),
|
||||||
|
RGB(0x41, 0x30, 0xA4),
|
||||||
|
"lottery/c64/c64_splash.pcx",
|
||||||
|
"lottery/c64/font_c64_8x8.pbm",
|
||||||
|
false
|
||||||
|
},
|
||||||
|
{ // mirror scheme
|
||||||
|
COLOR_WHITE,
|
||||||
|
COLOR_BLACK,
|
||||||
|
"lottery/mirror/mirror_splash.pcx",
|
||||||
|
"lottery/mirror/font_6x10_mr.pbm",
|
||||||
|
false
|
||||||
|
},
|
||||||
|
{ // zuish scheme
|
||||||
|
COLOR_WHITE,
|
||||||
|
COLOR_BLACK,
|
||||||
|
"lottery/zuish/zuish_splash.pcx",
|
||||||
|
"lottery/zuish/font_zuish_8x8.pbm",
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 lo_n = 0;
|
||||||
|
|
||||||
|
u32 InitLottery(void) {
|
||||||
|
DsTime dstime;
|
||||||
|
get_dstime(&dstime);
|
||||||
|
lo_n = (DSTIMEGET(&dstime, bcd_s)>>1) % LOTTERY_MAX;
|
||||||
|
return lo_n;
|
||||||
|
}
|
26
arm9/source/common/lottery.h
Normal file
26
arm9/source/common/lottery.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
|
||||||
|
// general scheme access
|
||||||
|
#define LOTTERY_N ((lo_n > 4) ? 0 : lo_n)
|
||||||
|
#define LOTTERY_COLOR_FONT (lo_theme[LOTTERY_N].color_font)
|
||||||
|
#define LOTTERY_COLOR_BG (lo_theme[LOTTERY_N].color_bg)
|
||||||
|
#define LOTTERY_SPLASH (lo_theme[LOTTERY_N].splash)
|
||||||
|
#define LOTTERY_FONT (lo_theme[LOTTERY_N].font)
|
||||||
|
#define LOTTERY_PROMPTHACK (lo_theme[LOTTERY_N].prompthack)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const u32 color_font;
|
||||||
|
const u32 color_bg;
|
||||||
|
const char* splash;
|
||||||
|
const char* font;
|
||||||
|
const bool prompthack;
|
||||||
|
} __attribute__((packed)) LotteryTheme;
|
||||||
|
|
||||||
|
extern const LotteryTheme lo_theme[];
|
||||||
|
extern u32 lo_n;
|
||||||
|
|
||||||
|
u32 InitLottery(void);
|
@ -14,6 +14,7 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
|
#include "lottery.h"
|
||||||
|
|
||||||
#define STRBUF_SIZE 512 // maximum size of the string buffer
|
#define STRBUF_SIZE 512 // maximum size of the string buffer
|
||||||
#define FONT_MAX_WIDTH 8
|
#define FONT_MAX_WIDTH 8
|
||||||
@ -95,7 +96,7 @@ bool SetFontFromPbm(const void* pbm, u32 pbm_size) {
|
|||||||
|
|
||||||
if (!pbm) {
|
if (!pbm) {
|
||||||
u64 pbm_size64 = 0;
|
u64 pbm_size64 = 0;
|
||||||
pbm = FindVTarFileInfo(VRAM0_FONT_PBM, &pbm_size64);
|
pbm = FindVTarFileInfo(LOTTERY_FONT, &pbm_size64);
|
||||||
pbm_size = (u32) pbm_size64;
|
pbm_size = (u32) pbm_size64;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,6 +277,7 @@ void DrawStringCenter(u8* screen, int color, int bgcolor, const char *format, ..
|
|||||||
u32 h = GetDrawStringHeight(str);
|
u32 h = GetDrawStringHeight(str);
|
||||||
int x = (w >= SCREEN_WIDTH(screen)) ? 0 : (SCREEN_WIDTH(screen) - w) >> 1;
|
int x = (w >= SCREEN_WIDTH(screen)) ? 0 : (SCREEN_WIDTH(screen) - w) >> 1;
|
||||||
int y = (h >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - h) >> 1;
|
int y = (h >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - h) >> 1;
|
||||||
|
if (LOTTERY_PROMPTHACK) x = y = 8;
|
||||||
|
|
||||||
DrawStringF(screen, x, y, color, bgcolor, str);
|
DrawStringF(screen, x, y, color, bgcolor, str);
|
||||||
}
|
}
|
||||||
|
@ -33,17 +33,27 @@
|
|||||||
// see: https://www.3dbrew.org/wiki/NCCH/Extended_Header
|
// see: https://www.3dbrew.org/wiki/NCCH/Extended_Header
|
||||||
// very limited, contains only required stuff
|
// very limited, contains only required stuff
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
// SCI (system control info)
|
||||||
char name[8];
|
char name[8];
|
||||||
u8 reserved[0x5];
|
u8 reserved0[0x5];
|
||||||
u8 flag; // bit 1 for SD, bit 0 for compressed .code
|
u8 flag; // bit 1 for SD, bit 0 for compressed .code
|
||||||
u16 remaster_version;
|
u16 remaster_version;
|
||||||
u8 sci_data[0x30];
|
u8 sci_data[0x30];
|
||||||
u8 dependencies[0x180];
|
u8 dependencies[0x180];
|
||||||
u8 sys_info[0x40];
|
u64 savedata_size;
|
||||||
u8 aci_data[0x200];
|
u64 jump_id;
|
||||||
|
u8 reserved1[0x30];
|
||||||
|
// ACI (access control info)
|
||||||
|
u64 aci_title_id;
|
||||||
|
u32 aci_core_version;
|
||||||
|
u8 aci_data[0x200 - 0xC];
|
||||||
|
// signature and key
|
||||||
u8 signature[0x100];
|
u8 signature[0x100];
|
||||||
u8 public_key[0x100];
|
u8 public_key[0x100];
|
||||||
u8 aci_limit_data[0x200];
|
// limitACI (access control info)
|
||||||
|
u64 aci_limit_title_id;
|
||||||
|
u32 aci_limit_core_version;
|
||||||
|
u8 aci_limit_data[0x200 - 0xC];
|
||||||
} __attribute__((packed)) NcchExtHeader;
|
} __attribute__((packed)) NcchExtHeader;
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/NCCH#NCCH_Header
|
// see: https://www.3dbrew.org/wiki/NCCH#NCCH_Header
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "vram0.h"
|
#include "vram0.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
#include "lottery.h"
|
||||||
|
|
||||||
|
|
||||||
#define N_PANES 2
|
#define N_PANES 2
|
||||||
@ -47,7 +48,7 @@ typedef struct {
|
|||||||
|
|
||||||
u32 SplashInit(const char* modestr) {
|
u32 SplashInit(const char* modestr) {
|
||||||
u64 splash_size;
|
u64 splash_size;
|
||||||
u8* splash = FindVTarFileInfo(VRAM0_SPLASH_PCX, &splash_size);
|
u8* splash = FindVTarFileInfo(LOTTERY_SPLASH, &splash_size);
|
||||||
u8* bitmap = (u8*) malloc(SCREEN_SIZE_TOP);
|
u8* bitmap = (u8*) malloc(SCREEN_SIZE_TOP);
|
||||||
const char* namestr = FLAVOR " " VERSION;
|
const char* namestr = FLAVOR " " VERSION;
|
||||||
const char* loadstr = "booting...";
|
const char* loadstr = "booting...";
|
||||||
@ -61,7 +62,7 @@ u32 SplashInit(const char* modestr) {
|
|||||||
if (splash && bitmap && PCX_Decompress(bitmap, SCREEN_SIZE_TOP, splash, splash_size)) {
|
if (splash && bitmap && PCX_Decompress(bitmap, SCREEN_SIZE_TOP, splash, splash_size)) {
|
||||||
PCXHdr* hdr = (PCXHdr*) (void*) splash;
|
PCXHdr* hdr = (PCXHdr*) (void*) splash;
|
||||||
DrawBitmap(TOP_SCREEN, -1, -1, PCX_Width(hdr), PCX_Height(hdr), bitmap);
|
DrawBitmap(TOP_SCREEN, -1, -1, PCX_Width(hdr), PCX_Height(hdr), bitmap);
|
||||||
} else DrawStringF(TOP_SCREEN, 10, 10, COLOR_STD_FONT, COLOR_TRANSPARENT, "(" VRAM0_SPLASH_PCX " not found)");
|
} else DrawStringF(TOP_SCREEN, 10, 10, COLOR_STD_FONT, COLOR_TRANSPARENT, "(%s not found)", LOTTERY_SPLASH);
|
||||||
if (modestr) DrawStringF(TOP_SCREEN, SCREEN_WIDTH_TOP - 10 - GetDrawStringWidth(modestr),
|
if (modestr) DrawStringF(TOP_SCREEN, SCREEN_WIDTH_TOP - 10 - GetDrawStringWidth(modestr),
|
||||||
SCREEN_HEIGHT - 10 - GetDrawStringHeight(modestr), COLOR_STD_FONT, COLOR_TRANSPARENT, modestr);
|
SCREEN_HEIGHT - 10 - GetDrawStringHeight(modestr), COLOR_STD_FONT, COLOR_TRANSPARENT, modestr);
|
||||||
|
|
||||||
@ -1932,7 +1933,8 @@ u32 GodMode(int entrypoint) {
|
|||||||
show_splash = !bootloader;
|
show_splash = !bootloader;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// init font
|
// init font / lottery
|
||||||
|
InitLottery();
|
||||||
if (!SetFontFromPbm(NULL, 0)) return exit_mode;
|
if (!SetFontFromPbm(NULL, 0)) return exit_mode;
|
||||||
|
|
||||||
// show splash screen (if enabled)
|
// show splash screen (if enabled)
|
||||||
|
@ -1303,7 +1303,7 @@ u32 BuildCiaFromNcchFile(const char* path_ncch, const char* path_cia) {
|
|||||||
|
|
||||||
// load NCCH header / extheader, get save size && title id
|
// load NCCH header / extheader, get save size && title id
|
||||||
if (LoadNcchHeaders(&ncch, &exthdr, NULL, path_ncch, 0) == 0) {
|
if (LoadNcchHeaders(&ncch, &exthdr, NULL, path_ncch, 0) == 0) {
|
||||||
save_size = getle32(exthdr.sys_info);
|
save_size = (u32) exthdr.savedata_size;
|
||||||
has_exthdr = true;
|
has_exthdr = true;
|
||||||
} else if (LoadNcchHeaders(&ncch, NULL, NULL, path_ncch, 0) != 0) {
|
} else if (LoadNcchHeaders(&ncch, NULL, NULL, path_ncch, 0) != 0) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -1375,7 +1375,7 @@ u32 BuildCiaFromNcsdFile(const char* path_ncsd, const char* path_cia) {
|
|||||||
// load first content NCCH / extheader
|
// load first content NCCH / extheader
|
||||||
if (LoadNcchHeaders(&ncch, &exthdr, NULL, path_ncsd, NCSD_CNT0_OFFSET) != 0)
|
if (LoadNcchHeaders(&ncch, &exthdr, NULL, path_ncsd, NCSD_CNT0_OFFSET) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
save_size = getle32(exthdr.sys_info);
|
save_size = (u32) exthdr.savedata_size;
|
||||||
|
|
||||||
// build the CIA stub
|
// build the CIA stub
|
||||||
CiaStub* cia = (CiaStub*) malloc(sizeof(CiaStub));
|
CiaStub* cia = (CiaStub*) malloc(sizeof(CiaStub));
|
||||||
@ -1844,6 +1844,7 @@ u32 CheckHealthAndSafetyInject(const char* hsdrv) {
|
|||||||
|
|
||||||
u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
|
u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
|
||||||
NcchHeader ncch;
|
NcchHeader ncch;
|
||||||
|
NcchExtHeader exthdr;
|
||||||
|
|
||||||
// write permissions
|
// write permissions
|
||||||
if (!CheckWritePermissions(destdrv))
|
if (!CheckWritePermissions(destdrv))
|
||||||
@ -1867,12 +1868,12 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check input file / crypto
|
// check input file / crypto
|
||||||
if ((LoadNcchHeaders(&ncch, NULL, NULL, path, 0) != 0) ||
|
if ((LoadNcchHeaders(&ncch, &exthdr, NULL, path, 0) != 0) ||
|
||||||
!(NCCH_IS_CXI(&ncch)) || (SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0))
|
!(NCCH_IS_CXI(&ncch)) || (SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// check crypto, get sig
|
// check crypto, get sig
|
||||||
if ((LoadNcchHeaders(&ncch, NULL, NULL, path_cxi, 0) != 0) ||
|
if ((LoadNcchHeaders(&ncch, &exthdr, NULL, path_cxi, 0) != 0) ||
|
||||||
(SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0) || !(NCCH_IS_CXI(&ncch)))
|
(SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0) || !(NCCH_IS_CXI(&ncch)))
|
||||||
return 1;
|
return 1;
|
||||||
u8 sig[0x100];
|
u8 sig[0x100];
|
||||||
@ -1890,14 +1891,17 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
|
|||||||
if (CryptNcchNcsdBossFirmFile(path, path_cxi, GAME_NCCH, CRYPTO_DECRYPT, 0, 0, NULL, NULL) != 0)
|
if (CryptNcchNcsdBossFirmFile(path, path_cxi, GAME_NCCH, CRYPTO_DECRYPT, 0, 0, NULL, NULL) != 0)
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
// fix up the injected H&S NCCH header (copy H&S signature, title ID)
|
// fix up the injected H&S NCCH header / extheader (copy H&S signature, title ID to multiple locations)
|
||||||
if ((ret == 0) && (LoadNcchHeaders(&ncch, NULL, NULL, path_cxi, 0) == 0)) {
|
if ((ret == 0) && (LoadNcchHeaders(&ncch, &exthdr, NULL, path_cxi, 0) == 0)) {
|
||||||
UINT bw;
|
|
||||||
ncch.programId = tid_hs;
|
ncch.programId = tid_hs;
|
||||||
ncch.partitionId = tid_hs;
|
ncch.partitionId = tid_hs;
|
||||||
|
exthdr.jump_id = tid_hs;
|
||||||
|
exthdr.aci_title_id = tid_hs;
|
||||||
|
exthdr.aci_limit_title_id = tid_hs;
|
||||||
memcpy(ncch.signature, sig, 0x100);
|
memcpy(ncch.signature, sig, 0x100);
|
||||||
if ((fvx_qwrite(path_cxi, &ncch, 0, sizeof(NcchHeader), &bw) != FR_OK) ||
|
sha_quick(ncch.hash_exthdr, &exthdr, 0x400, SHA256_MODE);
|
||||||
(bw != sizeof(NcchHeader)))
|
if ((fvx_qwrite(path_cxi, &ncch, 0, sizeof(NcchHeader), NULL) != FR_OK) ||
|
||||||
|
(fvx_qwrite(path_cxi, &exthdr, NCCH_EXTHDR_OFFSET, sizeof(NcchExtHeader), NULL) != FR_OK))
|
||||||
ret = 1;
|
ret = 1;
|
||||||
} else ret = 1;
|
} else ret = 1;
|
||||||
|
|
||||||
|
@ -674,10 +674,11 @@ bool BuildVGameTadDir(void) {
|
|||||||
u32 n = 0;
|
u32 n = 0;
|
||||||
|
|
||||||
// read header, setup table
|
// read header, setup table
|
||||||
|
u8 hdr_data[TAD_HEADER_LEN];
|
||||||
|
TadHeader* hdr = (TadHeader*) hdr_data;
|
||||||
TadContentTable tbl;
|
TadContentTable tbl;
|
||||||
TadHeader hdr;
|
ReadGameImageBytes(hdr_data, TAD_HEADER_OFFSET, TAD_HEADER_LEN);
|
||||||
ReadGameImageBytes(&hdr, TAD_HEADER_OFFSET, TAD_HEADER_LEN);
|
if (BuildTadContentTable(&tbl, hdr_data) != 0) {
|
||||||
if (BuildTadContentTable(&tbl, &hdr) != 0) {
|
|
||||||
n_templates_tad = 0;
|
n_templates_tad = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -711,17 +712,17 @@ bool BuildVGameTadDir(void) {
|
|||||||
|
|
||||||
// contents
|
// contents
|
||||||
for (u32 i = 0; i < TAD_NUM_CONTENT; content_offset = tbl.content_end[i++]) {
|
for (u32 i = 0; i < TAD_NUM_CONTENT; content_offset = tbl.content_end[i++]) {
|
||||||
if (!hdr.content_size[i]) continue; // nothing in section
|
if (!hdr->content_size[i]) continue; // nothing in section
|
||||||
// use proper names, fix TMD handling
|
// use proper names, fix TMD handling
|
||||||
snprintf(templates[n].name, 32, NAME_TAD_CONTENT, hdr.title_id, name_type[i]);
|
snprintf(templates[n].name, 32, NAME_TAD_CONTENT, hdr->title_id, name_type[i]);
|
||||||
templates[n].offset = content_offset;
|
templates[n].offset = content_offset;
|
||||||
templates[n].size = hdr.content_size[i];
|
templates[n].size = hdr->content_size[i];
|
||||||
templates[n].keyslot = 0xFF;
|
templates[n].keyslot = 0xFF;
|
||||||
templates[n].flags = 0;
|
templates[n].flags = 0;
|
||||||
n++;
|
n++;
|
||||||
if (i == 1) { // SRL content
|
if (i == 1) { // SRL content
|
||||||
memcpy(templates + n, templates + n - 1, sizeof(VirtualFile));
|
memcpy(templates + n, templates + n - 1, sizeof(VirtualFile));
|
||||||
snprintf(templates[n].name, 32, NAME_TAD_CONTENT, hdr.title_id, "srl");
|
snprintf(templates[n].name, 32, NAME_TAD_CONTENT, hdr->title_id, "srl");
|
||||||
templates[n].flags |= (VFLAG_NDS | VFLAG_DIR);
|
templates[n].flags |= (VFLAG_NDS | VFLAG_DIR);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
BIN
data/lottery/bricked/bootrom_splash.pcx
Normal file
BIN
data/lottery/bricked/bootrom_splash.pcx
Normal file
Binary file not shown.
BIN
data/lottery/bricked/font_nbraille_4x6.pbm
Normal file
BIN
data/lottery/bricked/font_nbraille_4x6.pbm
Normal file
Binary file not shown.
BIN
data/lottery/c64/c64_splash.pcx
Normal file
BIN
data/lottery/c64/c64_splash.pcx
Normal file
Binary file not shown.
BIN
data/lottery/c64/font_c64_8x8.pbm
Normal file
BIN
data/lottery/c64/font_c64_8x8.pbm
Normal file
Binary file not shown.
BIN
data/lottery/mirror/font_6x10_mr.pbm
Normal file
BIN
data/lottery/mirror/font_6x10_mr.pbm
Normal file
Binary file not shown.
BIN
data/lottery/mirror/mirror_splash.pcx
Normal file
BIN
data/lottery/mirror/mirror_splash.pcx
Normal file
Binary file not shown.
BIN
data/lottery/zuish/font_zuish_8x8.pbm
Normal file
BIN
data/lottery/zuish/font_zuish_8x8.pbm
Normal file
Binary file not shown.
BIN
data/lottery/zuish/zuish_splash.pcx
Normal file
BIN
data/lottery/zuish/zuish_splash.pcx
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user