Skip to content

Commit

Permalink
Option to overwrite original files when saving (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
g026r authored Sep 28, 2024
1 parent 0452292 commit 539db7f
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 152 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,23 @@ experimental software that is doing something Analogue was not expecting users t

## How to Install

Download the appropriate version for your operating system from [the latest release](https://github.com/g026r/pocket-library-toolkit/releases/latest) & extract the archive. I recommend placing it in the root of your Pocket's SD card.
Download the appropriate version for your operating system
from [the latest release](https://github.com/g026r/pocket-library-toolkit/releases/latest) & extract the archive. I
recommend placing it in the root of your Pocket's SD card.

Run the application & select the actions you desire. A basic [user guide](docs/userguide.md) is available.

Once complete, and then copy the files the tool generates over to the correct locations under your SD card's System directory _**making backups of any originals before replacing them**_.
Once complete, then copy the files the tool generates over to the correct locations under your SD card's System
directory _**making backups of any originals before replacing them**_.

## But Why?

Because I can get remarkably anal about these things.

First off: 95% of Pocket users won't need or even want this.

This software is for the users who are annoyed that their library shows `Famicom Mini 01 - Super Mario Bros.` but also
`Famicom Mini 22: Nazo no Murasame Jou`, that it's `The Lion King` but `NewZealand Story, The`.
This software is for the users who are annoyed that their library shows _Famicom Mini 01 - Super Mario Bros._ but also
_Famicom Mini 22: Nazo no Murasame Jou_, that it's _The Lion King_ but _NewZealand Story, The_.

It's for those users who have one of the small number of carts that the Pocket misidentifies & who'd rather it appeared
in their library under the correct name.
Expand All @@ -33,7 +36,7 @@ manually editing the binary file themselves.
## Limitations

The library info screen for a given cart is stored in the Pocket's internal memory. Even if your library
now shows "Sagaia" instead of "Mani 4 in 1 - Taito", clicking into it or loading the cart will still show you the
now shows "_Sagaia_" instead of "_Mani 4 in 1 - Taito_", clicking into it or loading the cart will still show you the
original info.

Additionally, if you have two different entries with the same cart signature, it's likely that only the playtime for the
Expand Down
14 changes: 11 additions & 3 deletions cmd/playfix/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@ package main

import (
"encoding/binary"
"fmt"
"log"
"os"
"path/filepath"

"github.com/g026r/pocket-toolkit/pkg/io"
)

// Simple application to fix played times & nothing else.

func main() {
entries, err := io.LoadEntries(os.DirFS("./"))
ex, err := os.Executable()
if err != nil {
log.Fatal(err)
}
p, err := io.LoadPlaytimes(os.DirFS("./"))
root := filepath.Dir(ex)

entries, err := io.LoadEntries(os.DirFS(root))
if err != nil {
log.Fatal(err)
}
p, err := io.LoadPlaytimes(os.DirFS(root))
if err != nil {
log.Fatal(err)
}
Expand All @@ -28,7 +36,7 @@ func main() {
defer func() {
_ = out.Close()
if complete { // Overwrite the original with the temp file if successful; delete it if not.
err = os.Rename(out.Name(), "System/Played Games/playtimes.bin")
err = os.Rename(out.Name(), fmt.Sprintf("%s/System/Played Games/playtimes.bin", root))
} else {
err = os.Remove(out.Name())
}
Expand Down
59 changes: 12 additions & 47 deletions pkg/io/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,16 @@ type Config struct {
AdvancedEditing bool `json:"advanced_editing"`
ShowAdd bool `json:"show_add"`
GenerateNew bool `json:"generate_new"`
SaveUnmodified bool `json:"save_unmodified"`
Overwrite bool `json:"overwrite"`
}

type jsonEntry struct {
models.System `json:"system"`
Name string `json:"name"`
Crc32 string `json:"crc"`
Sig string `json:"signature"`
Magic string `json:"magic"` // TODO: Work out all possible mappings for this
Magic string `json:"magic"` // TODO: Work out all possible mappings for this?
}

func (j jsonEntry) Entry() models.Entry {
Expand Down Expand Up @@ -249,8 +251,11 @@ func LoadConfig() (Config, error) {
AdvancedEditing: false,
ShowAdd: false,
GenerateNew: true,
SaveUnmodified: false,
Overwrite: false,
}
//// FIXME: Use the program's dir rather than the cwd
// FIXME: When compiling, use the program's dir rather than the cwd
// FIXME: When testing, use the cwd & remember to comment out the filepath.Dir call
//dir, err := os.Getwd()
dir, err := os.Executable()
if err != nil {
Expand Down Expand Up @@ -302,23 +307,7 @@ func LoadInternal() (map[models.System][]models.Entry, error) {
return library, nil
}

func SaveLibrary(e []models.Entry, t map[uint32]models.PlayTime, tick chan any) error {
wd, err := os.Getwd()
if err != nil {
return err
}
l, err := os.Create(fmt.Sprintf("%s/pocket-toolkit/list.bin", wd))
if err != nil {
return err
}
defer l.Close()

p, err := os.Create(fmt.Sprintf("%s/pocket-toolkit/playtimes.bin", wd))
if err != nil {
return err
}
defer p.Close()

func SaveLibrary(l io.Writer, e []models.Entry, p io.Writer, t map[uint32]models.PlayTime, tick chan any) error {
// Prep list.bin
if err := binary.Write(l, binary.BigEndian, ListHeader); err != nil {
return err
Expand Down Expand Up @@ -377,32 +366,7 @@ func SaveLibrary(e []models.Entry, t map[uint32]models.PlayTime, tick chan any)
return nil
}

func SaveThumbs(t map[models.System]models.Thumbnails, tick chan any) error {
wd, err := os.Getwd()
if err != nil {
return err
}

for sys, thumbs := range t {
if !thumbs.Modified {
continue // Not changed. For speed reasons, don't save.
}

f, err := os.Create(fmt.Sprintf("%s/pocket-toolkit/%s_thumbs.bin", wd, strings.ToLower(sys.String())))
if err != nil {
return err
}

err = writeThumbsFile(f, thumbs.Images, tick)
_ = f.Close() // Close explicitly rather than defer as defer in a loop is not best practice
if err != nil {
return err
}
}
return nil
}

func writeThumbsFile(t io.Writer, img []models.Image, tick chan any) error {
func SaveThumbsFile(t io.Writer, img []models.Image, tick chan any) error {
if err := binary.Write(t, binary.LittleEndian, ThumbnailHeader); err != nil {
return err
}
Expand Down Expand Up @@ -444,8 +408,9 @@ func SaveConfig(config Config) error {
if err != nil {
return err
}
//// FIXME: Use the program's dir rather than the cwd
//dir, err := os.Getwd()
// FIXME: When compiling, use the program's dir rather than the cwd
// FIXME: When testing, use the cwd & remember to comment out the filepath.Dir call
// dir, err := os.Getwd()
dir, err := os.Executable()
if err != nil {
return err
Expand Down
74 changes: 41 additions & 33 deletions pkg/ui/menus.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,22 @@ const (
about
save
quit
add
edit
rm
fix
libAdd
libEdit
libRm
libFix
back
missing
single
genlib
all
prune
showAdd
advEdit
rmThumbs
genNew
tmMissing
tmSingle
tmGenlib
tmAll
tmPrune
cfgShowAdd
cfgAdvEdit
cfgRmThumbs
cfgGenNew
cfgUnmodified
cfgOverwrite
)

var (
Expand Down Expand Up @@ -73,23 +75,25 @@ var (
menuItem{"Save & Quit", save},
menuItem{"Quit", quit}}
libraryOptions = []list.Item{
menuItem{"Add entry", add},
menuItem{"Edit entry", edit},
menuItem{"Remove entry", rm},
menuItem{"Fix played times", fix},
menuItem{"Add entry", libAdd},
menuItem{"Edit entry", libEdit},
menuItem{"Remove entry", libRm},
menuItem{"Fix played times", libFix},
menuItem{"Back", back}}
thumbOptions = []list.Item{
menuItem{"Generate missing thumbnails", missing},
menuItem{"Regenerate single game", single},
menuItem{"Regenerate full library", genlib},
menuItem{"Prune orphaned thumbnails", prune},
menuItem{"Generate complete system thumbnails", all},
menuItem{"Generate tmMissing thumbnails", tmMissing},
menuItem{"Regenerate tmSingle game", tmSingle},
menuItem{"Regenerate full library", tmGenlib},
menuItem{"Prune orphaned thumbnails", tmPrune},
menuItem{"Generate complete system thumbnails", tmAll},
menuItem{"Back", back}}
configOptions = []list.Item{
menuItem{"Remove thumbnail when removing game", rmThumbs},
menuItem{"Generate new thumbnail when editing game", genNew},
//menuItem{"Show advanced library editing fields " + italic.Render("(Experimental)"), advEdit},
//menuItem{"Show 'Add to Library' " + italic.Render("(Experimental)"), showAdd},
menuItem{"Remove thumbnail when removing game", cfgRmThumbs},
menuItem{"Generate new thumbnail when editing game", cfgGenNew},
menuItem{"Overwrite original files on save", cfgOverwrite},
menuItem{"Always save _thumbs.bin files, even if unmodified", cfgUnmodified},
//menuItem{"Show advanced library editing fields " + italic.Render("(Experimental)"), cfgAdvEdit},
//menuItem{"Show 'Add to Library' " + italic.Render("(Experimental)"), cfgShowAdd},
menuItem{"Back", back}}

// esc consists of the items to be performed if esc is typed
Expand Down Expand Up @@ -211,7 +215,7 @@ var (
}
)

// defaulAction is a default action for sub menus allowing numeric navigation.
// defaultAction is a default action for sub menus allowing numeric navigation.
// It's not easily doable for game list menus as there may be too many items to handle key-presses without storing the previous press & waiting to process it.
func defaultAction(scr screen, menu *list.Model, m *Model, msg tea.Msg) (*Model, tea.Cmd) {
if k, ok := msg.(tea.KeyMsg); ok {
Expand Down Expand Up @@ -303,14 +307,18 @@ func (d configDelegate) Render(w goio.Writer, m list.Model, index int, listItem
str = fmt.Sprintf("%d. [%%s] %s", index+1, i)
var b bool
switch i.key {
case advEdit:
b = d.AdvancedEditing
case showAdd:
b = d.ShowAdd
case rmThumbs:
case cfgRmThumbs:
b = d.RemoveImages
case genNew:
case cfgGenNew:
b = d.GenerateNew
case cfgUnmodified:
b = d.SaveUnmodified
case cfgOverwrite:
b = d.Overwrite
case cfgAdvEdit:
b = d.AdvancedEditing
case cfgShowAdd:
b = d.ShowAdd
default:
// If we don't know what this value is, return
return
Expand Down
Loading

0 comments on commit 539db7f

Please sign in to comment.