Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ Then the game will start:

## Default Keymap
### First Player
| NES Key | PC | Mac |
|-------------------|------------------|--------------|
| <kbd>Start</kbd> | <kbd>Enter</kbd> | <kbd>↩</kbd> |
| <kbd>Select</kbd> | <kbd>Tab</kbd> | <kbd></kbd> |
| <kbd>←</kbd> | <kbd>Left</kbd> | <kbd>←</kbd> |
| <kbd>→</kbd> | <kbd>Right</kbd> | <kbd>→</kbd> |
| <kbd>↑</kbd> | <kbd>Up</kbd> | <kbd>↑</kbd> |
| <kbd>↓</kbd> | <kbd>Down</kbd> | <kbd>↓</kbd> |
| <kbd>A</kbd> | <kbd>X</kbd> | <kbd>X</kbd> |
| <kbd>B</kbd> | <kbd>Z</kbd> | <kbd>Z</kbd> |
| NES Key | PC | Mac |
|-------------------|--------------------|--------------|
| <kbd>Start</kbd> | <kbd>Enter</kbd> | <kbd>↩</kbd> |
| <kbd>Select</kbd> | <kbd>Control</kbd> | <kbd></kbd> |
| <kbd>←</kbd> | <kbd>Left</kbd> | <kbd>←</kbd> |
| <kbd>→</kbd> | <kbd>Right</kbd> | <kbd>→</kbd> |
| <kbd>↑</kbd> | <kbd>Up</kbd> | <kbd>↑</kbd> |
| <kbd>↓</kbd> | <kbd>Down</kbd> | <kbd>↓</kbd> |
| <kbd>A</kbd> | <kbd>X</kbd> | <kbd>X</kbd> |
| <kbd>B</kbd> | <kbd>Z</kbd> | <kbd>Z</kbd> |


4 changes: 2 additions & 2 deletions cmd/opcode_gen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ func main() {
inst.VariableCycles = m[4] != ""

fmt.Printf("opcode=%02x: %v\n", opcode, inst)
fmt.Fprintf(fout, "0x%02x: {0x%02x, \"%s\", %s, %d, %v},\n",
inst.OpCode, inst.OpCode, inst.Nemonics, inst.AddressingMode.String(), inst.Cycles, inst.VariableCycles)
fmt.Fprintf(fout, "0x%02x: {0x%02x, \"%s\", %d, %d, %v},\n",
inst.OpCode, inst.OpCode, inst.Nemonics, inst.AddressingMode, inst.Cycles, inst.VariableCycles)
}
row++
}
Expand Down
21 changes: 2 additions & 19 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,6 @@ module github.com/vfreex/gones
go 1.12

require (
fyne.io/fyne v1.0.1
github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 // indirect
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 // indirect
github.com/jackmordaunt/icns v1.0.0 // indirect
github.com/josephspurrier/goversioninfo v0.0.0-20190209210621-63e6d1acd3dd // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/pkg/sftp v1.10.0 // indirect
github.com/spf13/afero v1.2.2 // indirect
github.com/srwiley/oksvg v0.0.0-20190414003808-c520f0a6c5cc // indirect
github.com/stretchr/objx v0.2.0 // indirect
go.uber.org/atomic v1.4.0 // indirect
go.uber.org/multierr v1.1.0 // indirect
go.uber.org/zap v1.10.0
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f // indirect
golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff // indirect
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 // indirect
golang.org/x/sys v0.0.0-20190528012530-adf421d2caf4 // indirect
golang.org/x/text v0.3.2 // indirect
golang.org/x/tools v0.0.0-20190525145741-7be61e1b0e51 // indirect
fyne.io/fyne/v2 v2.2.1
go.uber.org/zap v1.17.0
)
693 changes: 634 additions & 59 deletions go.sum

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pkg/emulator/cpu/addressing.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (cpu *Cpu) AddressOperand(am AddressingMode) (memory.Ptr, int) {
case IZY:
return cpu.AddressIzy()
default:
panic(fmt.Errorf("unsupported addressing mode: %s", am))
panic(fmt.Errorf("unsupported addressing mode: %d", am))
}
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/emulator/cpu/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ func (cpu *Cpu) logInstruction() {
case 1:
arguments[0] = cpu.Memory.Peek(cpu.PC + 1)
}
logger.Debugf("L%04x: %s %s ; %02x (%s-%s) %s",
logger.Debugf("L%04x: %s %s ; %02x (%s-%d) %s",
cpu.PC, info.Nemonics, formatInstructionArgument(info.AddressingMode, arguments),
opcode, info.Nemonics, info.AddressingMode.String(), hex.EncodeToString(arguments))
opcode, info.Nemonics, info.AddressingMode, hex.EncodeToString(arguments))
}

func formatInstructionArgument(am AddressingMode, args []byte) string {
Expand Down
4 changes: 2 additions & 2 deletions pkg/emulator/cpu/cpu_instruction_handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ func TestOpcodeHandlers(t *testing.T) {
for opcode, info := range InstructionInfos {
handler := opcodeHandlers[opcode]
if handler == nil {
log.Printf("Opcode %02x (%s %s) is not implmeneted yet.", opcode, info.Nemonics, info.AddressingMode)
log.Printf("Opcode %02x (%s %d) is not implmeneted yet.", opcode, info.Nemonics, info.AddressingMode)
continue
}
if handler.AddressingMode != info.AddressingMode {
t.Fatalf("BUG: Addressing mode for %02x opcodeHandlers doesn't match the info in InstructionInfos: got %s, expected: %s",
t.Fatalf("BUG: Addressing mode for %02x opcodeHandlers doesn't match the info in InstructionInfos: got %d, expected: %d",
opcode, handler.AddressingMode, info.AddressingMode)
}
}
Expand Down
69 changes: 30 additions & 39 deletions pkg/emulator/nes/display.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package nes

import (
"fyne.io/fyne"
"fyne.io/fyne/app"
"fyne.io/fyne/canvas"
"fyne.io/fyne/driver/desktop"
"fyne.io/fyne/widget"
"github.com/vfreex/gones/pkg/emulator/joypad"
"github.com/vfreex/gones/pkg/emulator/ppu"
"image"
"image/color"
"math/rand"
"time"

"github.com/vfreex/gones/pkg/emulator/joypad"
"github.com/vfreex/gones/pkg/emulator/ppu"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/widget"
)

// resolution 256x240
Expand All @@ -25,16 +28,15 @@ type NesDiplay struct {
screenPixels *[SCREEN_HEIGHT][SCREEN_WIDTH]ppu.RBGColor
app fyne.App
mainWindow fyne.Window
raster *canvas.Raster
canvasObj fyne.CanvasObject
canvasObj *canvas.Image
NextCh chan int
StepInstruction bool
StepFrame bool
RequestReset bool
PressedKeys byte
ReleasedKeys byte
Keys byte
img *image.RGBA
img *image.NRGBA
}

var rnd = rand.New(rand.NewSource(time.Now().Unix()))
Expand All @@ -52,8 +54,8 @@ func NewDisplay(screenPixels *[SCREEN_HEIGHT][SCREEN_WIDTH]ppu.RBGColor) *NesDip
}
gameCanvas := display.render()
mainWindow.SetContent(
widget.NewVBox(gameCanvas,
widget.NewHBox(
container.NewVBox(gameCanvas,
container.NewHBox(
widget.NewButton(">", func() {
display.StepInstruction = true
display.StepFrame = false
Expand Down Expand Up @@ -102,11 +104,9 @@ func NewDisplay(screenPixels *[SCREEN_HEIGHT][SCREEN_WIDTH]ppu.RBGColor) *NesDip
display.Keys |= joypad.Button_B
case fyne.KeyX:
display.Keys |= joypad.Button_A
case fyne.KeyTab:
fallthrough
case "LeftControl":
case desktop.KeyControlLeft:
fallthrough
case "RightControl":
case desktop.KeyControlRight:
display.Keys |= joypad.Button_Select
}
})
Expand Down Expand Up @@ -134,11 +134,9 @@ func NewDisplay(screenPixels *[SCREEN_HEIGHT][SCREEN_WIDTH]ppu.RBGColor) *NesDip
display.Keys &= ^ joypad.Button_B
case fyne.KeyX:
display.Keys &= ^ joypad.Button_A
case fyne.KeyTab:
case desktop.KeyControlLeft:
fallthrough
case "LeftControl":
fallthrough
case "RightControl":
case desktop.KeyControlRight:
display.Keys &= ^ joypad.Button_Select
}
})
Expand All @@ -147,24 +145,10 @@ func NewDisplay(screenPixels *[SCREEN_HEIGHT][SCREEN_WIDTH]ppu.RBGColor) *NesDip
}

func (p *NesDiplay) render() fyne.CanvasObject {
//p.update()
lastW, lastH := 0, 0
p.raster = canvas.NewRaster(func(w, h int) image.Image {
if p.img == nil || w != lastW || h != lastH {
p.img = image.NewRGBA(image.Rect(0, 0, w, h))
lastW = w
lastH = h
}
for y := 0; y < h; y++ {
for x := 0; x < w; x++ {
pixel := p.screenPixels[y*SCREEN_HEIGHT/h][x*SCREEN_WIDTH/w]
p.img.SetRGBA(x, y, color.RGBA{R: byte(pixel >> 16), G: byte(pixel >> 8), B: byte(pixel >> 0), A: 0xff})
}
}
return p.img
})
p.raster.SetMinSize(fyne.NewSize(SCREEN_WIDTH*2, SCREEN_HEIGHT*2))
p.canvasObj = p.raster
p.img = image.NewNRGBA(image.Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT))
p.canvasObj = canvas.NewImageFromImage(p.img)
p.canvasObj.ScaleMode = canvas.ImageScalePixels
p.canvasObj.SetMinSize(fyne.NewSize(SCREEN_WIDTH*2, SCREEN_HEIGHT*2))
return p.canvasObj
}

Expand All @@ -174,5 +158,12 @@ func (p *NesDiplay) Show() {

func (p *NesDiplay) Refresh() {
//temp += 0x100000
p.mainWindow.Canvas().Refresh(p.canvasObj)
for y := 0; y < SCREEN_HEIGHT; y++ {
for x := 0; x < SCREEN_WIDTH; x++ {
pixel := p.screenPixels[y][x]
p.img.SetNRGBA(x, y, color.NRGBA{R: byte(pixel >> 16), G: byte(pixel >> 8), B: byte(pixel >> 0), A: 0xff})
}
}

p.canvasObj.Refresh()
}
8 changes: 4 additions & 4 deletions pkg/emulator/nes/nes.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (nes *NESImpl) Start() error {
go func() {
for tick := range nes.ticker.C {
//tick:=time.Now()
logger.Infof("At time %v", tick)
logger.Debugf("At time %v", tick)

spentCycles := int64(0)
loop := 0
Expand All @@ -153,16 +153,16 @@ func (nes *NESImpl) Start() error {
spentCycles += cycles
loop++
//logger.Debug("")
//logger.Infof("spent %d/%d CPU cycles", spentCycles, cpuCyclesPerFrame)
//logger.Debugf("spent %d/%d CPU cycles", spentCycles, cpuCyclesPerFrame)
}
//nes.display.Refresh()
// update joypad
nes.joypads.Joypads[0].Buttons = nes.display.Keys
//logger.SetOutput(os.Stderr)
logger.Info("----------------------------------------------------------")
logger.Debug("----------------------------------------------------------")
now := time.Now()
actualTime := now.Sub(tick)
logger.Infof("spent %v/%v to render frame #%d after running %v loops / %v cycles",
logger.Debugf("spent %v/%v to render frame #%d after running %v loops / %v cycles",
actualTime, interval, frames, loop, spentCycles)
frames++
//nes.ticker.Stop()
Expand Down