diff --git a/cmd/WiiUDownloader/main.go b/cmd/WiiUDownloader/main.go index 20f0d0f..7bae239 100644 --- a/cmd/WiiUDownloader/main.go +++ b/cmd/WiiUDownloader/main.go @@ -1,9 +1,10 @@ package main -import ( - "fmt" -) +import wiiudownloader "github.com/Xpl0itU/WiiUDownloader" func main() { - fmt.Println("Hello World!") + win := NewMainWindow(wiiudownloader.GetTitleEntries(wiiudownloader.TITLE_CATEGORY_GAME)) + + win.ShowAll() + Main() } diff --git a/cmd/WiiUDownloader/mainwindow.go b/cmd/WiiUDownloader/mainwindow.go new file mode 100644 index 0000000..379ce13 --- /dev/null +++ b/cmd/WiiUDownloader/mainwindow.go @@ -0,0 +1,99 @@ +package main + +import ( + "fmt" + "log" + + wiiudownloader "github.com/Xpl0itU/WiiUDownloader" + "github.com/gotk3/gotk3/glib" + "github.com/gotk3/gotk3/gtk" +) + +type MainWindow struct { + window *gtk.Window + titles []wiiudownloader.TitleEntry +} + +func NewMainWindow(entries []wiiudownloader.TitleEntry) *MainWindow { + gtk.Init(nil) + + win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) + if err != nil { + log.Fatal("Unable to create window:", err) + } + + win.SetTitle("WiiUDownloaderGo") + win.SetDefaultSize(400, 300) + win.Connect("destroy", func() { + gtk.MainQuit() + }) + + return &MainWindow{ + window: win, + titles: entries, + } +} + +func (mw *MainWindow) ShowAll() { + store, err := gtk.ListStoreNew(glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_STRING) + if err != nil { + log.Fatal("Unable to create list store:", err) + } + + for _, entry := range mw.titles { + iter := store.Append() + err = store.Set(iter, + []int{0, 1, 2}, + []interface{}{entry.Name, fmt.Sprintf("%016x", entry.TitleID), wiiudownloader.GetFormattedRegion(entry.Region)}, + ) + if err != nil { + log.Fatal("Unable to set values:", err) + } + } + + treeView, err := gtk.TreeViewNewWithModel(store) + if err != nil { + log.Fatal("Unable to create tree view:", err) + } + + renderer, err := gtk.CellRendererTextNew() + if err != nil { + log.Fatal("Unable to create cell renderer:", err) + } + column, err := gtk.TreeViewColumnNewWithAttribute("Name", renderer, "text", 0) + if err != nil { + log.Fatal("Unable to create tree view column:", err) + } + treeView.AppendColumn(column) + + renderer, err = gtk.CellRendererTextNew() + if err != nil { + log.Fatal("Unable to create cell renderer:", err) + } + column, err = gtk.TreeViewColumnNewWithAttribute("Title ID", renderer, "text", 1) + if err != nil { + log.Fatal("Unable to create tree view column:", err) + } + treeView.AppendColumn(column) + + column, err = gtk.TreeViewColumnNewWithAttribute("Region", renderer, "text", 2) + if err != nil { + log.Fatal("Unable to create tree view column:", err) + } + treeView.AppendColumn(column) + + scrollable, err := gtk.ScrolledWindowNew(nil, nil) + if err != nil { + log.Fatal("Unable to create scrolled window:", err) + } + scrollable.SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrollable.Add(treeView) + + mw.window.Add(scrollable) + + mw.window.ShowAll() +} + +func Main() { + gtk.Main() +} diff --git a/go.mod b/go.mod index ecebce7..36d0480 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module github.com/Xpl0itU/WiiUDownloader go 1.20 -require github.com/cavaliergopher/grab/v3 v3.0.1 +require ( + github.com/cavaliergopher/grab/v3 v3.0.1 + github.com/gotk3/gotk3 v0.6.2 +) diff --git a/go.sum b/go.sum index 0188458..9ecacfa 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4= github.com/cavaliergopher/grab/v3 v3.0.1/go.mod h1:1U/KNnD+Ft6JJiYoYBAimKH2XrYptb8Kl3DFGmsjpq4= +github.com/gotk3/gotk3 v0.6.2 h1:sx/PjaKfKULJPTPq8p2kn2ZbcNFxpOJqi4VLzMbEOO8= +github.com/gotk3/gotk3 v0.6.2/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q= diff --git a/gtitles.go b/gtitles.go index 17c8a3e..1930733 100644 --- a/gtitles.go +++ b/gtitles.go @@ -43,22 +43,22 @@ const ( ) type TitleEntry struct { - name string - titleID uint64 - region uint8 + Name string + TitleID uint64 + Region uint8 key uint8 } -func getTitleEntries(category uint8) []TitleEntry { +func GetTitleEntries(category uint8) []TitleEntry { entriesSize := getTitleEntriesSize(category) entriesSlice := make([]TitleEntry, entriesSize) cEntries := C.getTitleEntries(C.TITLE_CATEGORY(category)) cSlice := (*[1 << 28]C.TitleEntry)(unsafe.Pointer(cEntries))[:entriesSize:entriesSize] for i := 0; i < entriesSize; i++ { entriesSlice[i] = TitleEntry{ - name: C.GoString(cSlice[i].name), - titleID: uint64(cSlice[i].tid), - region: uint8(cSlice[i].region), + Name: C.GoString(cSlice[i].name), + TitleID: uint64(cSlice[i].tid), + Region: uint8(cSlice[i].region), key: uint8(cSlice[i].key), } } @@ -68,3 +68,28 @@ func getTitleEntries(category uint8) []TitleEntry { func getTitleEntriesSize(category uint8) int { return int(C.getTitleEntriesSize(C.TITLE_CATEGORY(category))) } + +func GetFormattedRegion(region uint8) string { + if region&MCP_REGION_EUROPE != 0 { + if region&MCP_REGION_USA != 0 { + if region&MCP_REGION_JAPAN != 0 { + return "All" + } + return "USA/Europe" + } + if region&MCP_REGION_JAPAN != 0 { + return "Europe/Japan" + } + return "Europe" + } + if region&MCP_REGION_USA != 0 { + if region&MCP_REGION_JAPAN != 0 { + return "USA/Japan" + } + return "USA" + } + if region&MCP_REGION_JAPAN != 0 { + return "Japan" + } + return "Unknown" +}