diff --git a/Makefile b/Makefile index 60ac532d..93d559ab 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,7 @@ SRCS = \ menu/components/common.c \ menu/components/context_menu.c \ menu/components/file_list.c \ + menu/cpak_handler.c \ menu/disk_info.c \ menu/fonts.c \ menu/hdmi.c \ @@ -56,6 +57,7 @@ SRCS = \ menu/views/fault.c \ menu/views/file_info.c \ menu/views/image_viewer.c \ + menu/views/joypad_controller_pak.c \ menu/views/text_viewer.c \ menu/views/load_disk.c \ menu/views/load_emulator.c \ @@ -66,7 +68,6 @@ SRCS = \ menu/views/settings_editor.c \ menu/views/rtc.c \ menu/views/flashcart_info.c \ - menu/views/joypad_controller_pak.c \ utils/fs.c FONTS = \ diff --git a/src/menu/cpak_handler.c b/src/menu/cpak_handler.c new file mode 100644 index 00000000..4213cc9e --- /dev/null +++ b/src/menu/cpak_handler.c @@ -0,0 +1,40 @@ +#include + +#include +#include +#include +#include +#include "../utils/fs.h" +#include "cpak_handler.h" + +uint8_t pak_data[128 * MEMPAK_BLOCK_SIZE]; + +int clone_pak_content_to_file(char *path, uint8_t jpad_port) { + // get the pak content + int err; + for (int i = 0; i < 128; i++) { + err = read_mempak_sector(jpad_port, i, &pak_data[i * MEMPAK_BLOCK_SIZE]); + if (err) { + // there was an issue reading the content (-1 if the sector was out of bounds or sector_data was null + // -2 if there was an error reading part of a sector + return err; + } + } + + FIL fil; + UINT bytes_written; + if (f_open(&fil, strip_sd_prefix(path), FA_WRITE | FA_CREATE_ALWAYS) != FR_OK) { + return 1; + } + + FRESULT fw_err = f_write(&fil, &pak_data, sizeof(pak_data), &bytes_written); + + f_close(&fil); + + if (fw_err) { + return fw_err; + } + else { + return 0; + } +} diff --git a/src/menu/cpak_handler.h b/src/menu/cpak_handler.h new file mode 100644 index 00000000..31a7653a --- /dev/null +++ b/src/menu/cpak_handler.h @@ -0,0 +1,15 @@ +/** + * @file cpak_handler.h + * @brief ControllerPak handler + * @ingroup menu + */ + +#include +#include + +#ifndef CPAK_HANDLER_H__ +#define CPAK_HANDLER_H__ + +int clone_pak_content_to_file(char *path, uint8_t jpad_port); + +#endif diff --git a/src/menu/views/joypad_controller_pak.c b/src/menu/views/joypad_controller_pak.c index 350134b1..40fd8755 100644 --- a/src/menu/views/joypad_controller_pak.c +++ b/src/menu/views/joypad_controller_pak.c @@ -1,4 +1,5 @@ #include "views.h" +#include "../cpak_handler.h" static int accessory_is_cpak[4]; @@ -10,7 +11,11 @@ static void process (menu_t *menu) { } if (menu->actions.enter) { - // do something?! + // TODO: handle all ports + if (accessory_is_cpak[0]) { + // TODO: preferably with the time added to the filename so it does not overwrite the existing one! + clone_pak_content_to_file("sd://cpak/cpak_backup.mpk", 0); + } } if (menu->actions.back) { @@ -32,21 +37,30 @@ static void draw (menu_t *menu, surface_t *d) { "\n" ); - // Backup to SD, restore from SD, and/or Repair functions. + // TODO: Backup from other ports, restore from SD, and/or Repair functions. // Bonus would be to handle individual per game entries! component_main_text_draw( ALIGN_LEFT, VALIGN_TOP, "\n" "\n" - "Not yet implemented!\n" + "Clone Controller Pak (1) to SD Card.\n" + "If it is available.\n" ); - - component_actions_bar_text_draw( - ALIGN_LEFT, VALIGN_TOP, - "\n" // "A: Clone PAK to SD Card\n" - "B: Back" - ); + if (accessory_is_cpak[0]) { + component_actions_bar_text_draw( + ALIGN_LEFT, VALIGN_TOP, + "A: Clone\n" + "B: Back" + ); + } + else { + component_actions_bar_text_draw( + ALIGN_LEFT, VALIGN_TOP, + "\n" + "B: Back" + ); + } rdpq_detach_show(); }