Compare commits

...

4 Commits

Author SHA1 Message Date
1eb8fa629b Version bump to v0.3.5
All checks were successful
Build / Build (push) Successful in 15s
Release / Build and Release (push) Successful in 19s
2026-07-03 17:24:19 +02:00
13e03cc327 hid: Allow Power button regardless of Joy Con connection 2026-07-03 17:24:04 +02:00
fc292fc0d3 ci: add Gitea release workflow with AllgemeinerProblemLoeser.bin asset
Build on v* tag push or workflow_dispatch and attach output binary via
gitea-release-action.
2026-07-03 17:22:50 +02:00
1b63a03b01 Reboot to Hekate menu once without changing hekate_ipl.ini
Mariko: RTC REBOOT_REASON_MENU + PMIC reboot. Erista: patch in-memory
boot_cfg on valid Hekate payload and try common SD paths.
2026-07-03 17:17:56 +02:00
7 changed files with 133 additions and 7 deletions

40
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
permissions:
contents: write
jobs:
release:
name: Build and Release
runs-on: ubuntu-latest
container: devkitpro/devkita64:latest
steps:
- name: Install dependencies
run: apt-get update && apt-get install -y nodejs
- name: Checkout latest code
uses: actions/checkout@v5
with:
clean: true
submodules: recursive
fetch-depth: 0
- name: Build
run: |
export DEVKITPRO=/opt/devkitpro
make -j4 all
shell: bash
- name: Publish release
uses: https://gitea.com/actions/gitea-release-action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
files: |-
output/AllgemeinerProblemLoeser.bin

View File

@@ -11,7 +11,7 @@ include $(DEVKITARM)/base_rules
IPL_LOAD_ADDR := 0x40008000 IPL_LOAD_ADDR := 0x40008000
APLVERSION_MAJOR := 0 APLVERSION_MAJOR := 0
APLVERSION_MINOR := 3 APLVERSION_MINOR := 3
APLVERSION_BUGFX := 4 APLVERSION_BUGFX := 5
################################################################################ ################################################################################

View File

@@ -74,6 +74,8 @@ Input_t *hidRead(){
else else
inputs.a = inputs.power; inputs.a = inputs.power;
inputs.a |= inputs.power;
return &inputs; return &inputs;
} }

View File

@@ -94,7 +94,26 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
} }
} }
int launch_payload(char *path) #define HEKATE_BOOT_CFG_OFFSET 0x94
#define HEKATE_MAGIC_OFFSET 0x118
#define HEKATE_MAGIC 0x43544349u
#define HEKATE_PAYLOAD_MAX 0x24000
static void _patch_hekate_menu_skip(void *buf, u32 size)
{
if (size > HEKATE_PAYLOAD_MAX)
return;
if (*(u32 *)((u8 *)buf + HEKATE_MAGIC_OFFSET) != HEKATE_MAGIC)
return;
boot_cfg_t *cfg = (boot_cfg_t *)((u8 *)buf + HEKATE_BOOT_CFG_OFFSET);
memset(cfg, 0, sizeof(boot_cfg_t));
cfg->boot_cfg = 1;
cfg->autoboot = 0;
}
int launch_payload_ex(char *path, bool force_hekate_menu)
{ {
gfx_clear_grey(0x1B); gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0); gfx_con_setpos(0, 0);
@@ -134,6 +153,16 @@ int launch_payload(char *path)
f_close(&fp); f_close(&fp);
if (force_hekate_menu)
{
if (size > HEKATE_PAYLOAD_MAX || *(u32 *)((u8 *)buf + HEKATE_MAGIC_OFFSET) != HEKATE_MAGIC)
{
sd_unmount();
return 2;
}
_patch_hekate_menu_skip(buf, size);
}
sd_unmount(); sd_unmount();
if (size < 0x30000) if (size < 0x30000)
@@ -160,6 +189,11 @@ int launch_payload(char *path)
return 1; return 1;
} }
int launch_payload(char *path)
{
return launch_payload_ex(path, false);
}
extern void pivot_stack(u32 stack_top); extern void pivot_stack(u32 stack_top);
#define EXCP_EN_ADDR 0x4003FFFC #define EXCP_EN_ADDR 0x4003FFFC

View File

@@ -105,10 +105,8 @@ void HandleSD(){
extern bool is_sd_inited; extern bool is_sd_inited;
extern int launch_payload(char *path);
void RebootToHekate(){ void RebootToHekate(){
launch_payload("sd:/bootloader/update.bin"); reboot_to_hekate_menu();
} }
void MountOrUnmountSD(){ void MountOrUnmountSD(){
@@ -153,7 +151,7 @@ void EnterMainMenu(){
sd_unmount(); sd_unmount();
// // -- Exit -- // // -- Exit --
mainMenuEntries[MainRebootHekate].hide = (!sd_get_card_mounted() || !FileExists("sd:/bootloader/update.bin")); mainMenuEntries[MainRebootHekate].hide = !h_cfg.t210b01 && (!sd_get_card_mounted() || !hekate_reboot_available());
mainMenuEntries[MainRebootRCM].hide = h_cfg.t210b01; mainMenuEntries[MainRebootRCM].hide = h_cfg.t210b01;
mainMenuEntries[FixMarikoWarmbootSleep].hide = !h_cfg.t210b01; mainMenuEntries[FixMarikoWarmbootSleep].hide = !h_cfg.t210b01;

View File

@@ -11,10 +11,58 @@
#include "../hid/hid.h" #include "../hid/hid.h"
#include "../fs/fsutils.h" #include "../fs/fsutils.h"
#include "../config.h" #include "../config.h"
#include <rtc/max77620-rtc.h>
#include <string.h>
extern hekate_config h_cfg; extern hekate_config h_cfg;
extern int launch_payload(char *path); extern int launch_payload_ex(char *path, bool force_hekate_menu);
static const char *hekate_payload_paths[] = {
"sd:/atmosphere/reboot_payload.bin",
"sd:/bootloader/update.bin",
"sd:/bootloader/payloads/hekate.bin",
"sd:/sept/payload.bin",
};
bool hekate_reboot_available(void)
{
if (h_cfg.t210b01)
return true;
for (u32 i = 0; i < sizeof(hekate_payload_paths) / sizeof(hekate_payload_paths[0]); i++)
{
if (FileExists(hekate_payload_paths[i]))
return true;
}
return false;
}
void reboot_to_hekate_menu(void)
{
if (h_cfg.t210b01)
{
rtc_reboot_reason_t rr = {0};
rr.dec.reason = REBOOT_REASON_MENU;
max77620_rtc_set_reboot_reason(&rr);
power_set_state(POWER_OFF_REBOOT);
return;
}
for (u32 i = 0; i < sizeof(hekate_payload_paths) / sizeof(hekate_payload_paths[0]); i++)
{
if (!FileExists(hekate_payload_paths[i]))
continue;
if (launch_payload_ex((char *)hekate_payload_paths[i], true) != 2)
return;
}
gfx_clearscreen();
gfx_printf("\n\nHekate nicht gefunden.\n\nDruecke eine Taste um zurueckzukehren");
hidWait();
}
void inline __attribute__((always_inline)) power_off(){ void inline __attribute__((always_inline)) power_off(){
power_set_state(POWER_OFF_RESET); power_set_state(POWER_OFF_RESET);

View File

@@ -6,6 +6,10 @@ void MaskIn(char *mod, u32 bitstream, char mask);
bool StrEndsWith(char *begin, char *end); bool StrEndsWith(char *begin, char *end);
void WaitFor(u32 ms); void WaitFor(u32 ms);
void RebootToPayloadOrRcm(); void RebootToPayloadOrRcm();
void reboot_to_hekate_menu(void);
bool hekate_reboot_available(void);
int launch_payload_ex(char *path, bool force_hekate_menu);
int launch_payload(char *path);
#define FREE(x) free(x); x = NULL; #define FREE(x) free(x); x = NULL;
char *ShowKeyboard(const char *toEdit, u8 alwaysRet); char *ShowKeyboard(const char *toEdit, u8 alwaysRet);