Beispiel #1
0
// Load a game
func (deck *ControlDeck) Load(filename string) (err string, success bool) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Sprintf("Failed to load %s: %s", filename, r)
            success = false
        }
    }()


    deck.InsertedCartridge = cartridge.LoadFile(filename)

    // Check ROM against known hashes, and set deck.InsertedCartridge.SHA1
    // TODO: maybe this should be in nesfile, or in controldeck?
    matches := cartdb.Identify(cartdb.Load(), deck.InsertedCartridge)
    fmt.Printf("Cartridge SHA-1 = %s\n", deck.InsertedCartridge.SHA1)
    if len(matches) != 0 {
        fmt.Printf("cartdb: found %d matching cartridges:\n", len(matches))
    }
    for i, match := range matches {
        fmt.Printf("%d. ", i)
        cartdb.DumpMatch(match)
    }
    // TODO: use info here, to display title/image, or use mapper


    deck.InsertedCartridge.LoadPRG(deck.CPU)
    deck.InsertedCartridge.LoadCHR(deck.PPU)

    // nestest.nes (TODO: better way to have local additions to cartdb!)
    if deck.InsertedCartridge.SHA1 == "4131307F0F69F2A5C54B7D438328C5B2A5ED0820" {
        // TODO: only do this when running in automated mode, still want GUI mode unaffected
        fmt.Printf("Identified nestest; mapping for automation\n")

        deck.CPU.MapOver(0xc66e, 
                // The known-correct log http://nickmass.com/images/nestest.log ends at $C66E, on RTS
                func(address uint16)(value uint8) { 
                    // http://nesdev.com/bbs/viewtopic.php?t=7130
                    result := deck.CPU.ReadFrom(2) << 8 | deck.CPU.ReadFrom(3)

                    if result == 0 {
                        fmt.Printf("Nestest automation: Pass\n")
                    } else {
                        fmt.Printf("Nestest automation: FAIL with code %.4x\n", result)
                    }
                    // Signal to stop CPU (KIL instruction)
                    // TODO: find a better way to quit the program. Could quit here, but
                    // then last instruction trace wouldn't match expected log.
                    deck.InternalRAM[0x0001] = 0x02

                    return 0x60 },
                func(address uint16, value uint8) { },
                "nestest-automation")
    }

    return err, true
}
Beispiel #2
0
// Read a bunch of files from a directory
func (deck *ControlDeck) LoadDir(dirname string) {
    filenames, err := ioutil.ReadDir(dirname)
    if err != nil {
        panic(fmt.Sprintf("LoadDir(%s) failed: %s", dirname, err))
    }

    mapperUsage := make(map[string]int)

    // Show information about each file
    for _, fileInfo := range filenames {
        path := fmt.Sprintf("%s/%s", dirname, fileInfo.Name)
        fmt.Printf("%s\n", path)
        cart := cartridge.LoadFile(path)
        fmt.Printf("%s\t%s\n", cart.MapperName, fileInfo.Name)
        mapperUsage[cart.MapperName] += 1
    }

    // Show mapper usage frequency
    fmt.Printf("\n")
    for mapper, count := range mapperUsage {
        fmt.Printf("%d\t%s\n", count, mapper)
    }
}