diff --git a/index.html b/index.html
index cdde3012..abac3cbc 100644
--- a/index.html
+++ b/index.html
@@ -56,6 +56,12 @@ let log = msg => {
document.getElementById('div').innerHTML += msg + '
'
}
+
+const dataChannelOptions = {
+ ordered: false, // do not guarantee order
+ maxPacketLifeTime: 3000, // in milliseconds
+};
+
let inputChannel = pc.createDataChannel('foo')
inputChannel.onclose = () => console.log('inputChannel has closed')
inputChannel.onopen = () => console.log('inputChannel has opened')
@@ -81,14 +87,46 @@ pc.onicecandidate = event => {
pc.createOffer({offerToReceiveVideo: true, offerToReceiveAudio: true}).then(d => pc.setLocalDescription(d)).catch(log)
+
+keyState = {
+ // controllers
+ a: false,
+ b: false,
+ start: false,
+ select: false,
+
+ // navigators
+ up: false,
+ down: false,
+ left: false,
+ right: false,
+}
+
+keyMap = {
+ 37: "left",
+ 38: "up",
+ 39: "right",
+ 40: "down",
+
+ 90: "a",
+ 88: "b",
+ 67: "start",
+ 86: "select",
+}
+
document.body.onkeydown = function(e){
- inputChannel.send(e.keyCode)
+ if (e.keyCode in keyMap) {
+ keyState[keyMap[e.keyCode]] = true;
+ }
};
document.body.onkeyup = function(e){
- inputChannel.send(-e.keyCode)
+ if (e.keyCode in keyMap) {
+ keyState[keyMap[e.keyCode]] = false;
+ }
};
+
window.startSession = () => {
let sd = remoteSessionDescription
if (sd === '') {
@@ -96,9 +134,50 @@ window.startSession = () => {
}
try {
- pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd))))
+ pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd))),
+
+ // success
+ () => {
+
+ fps = 60; // input frame per second
+
+ setInterval(() => {
+ // prepare key
+ /*
+ const (
+ ButtonA = iota
+ ButtonB
+ ButtonSelect
+ ButtonStart
+ ButtonUp
+ ButtonDown
+ ButtonLeft
+ ButtonRight
+ )
+ */
+
+ st = "";
+ ["a", "b", "select", "start", "up", "down", "left", "right"].forEach(elem => {
+ st += keyState[elem]?1:0;
+ });
+ ss = parseInt(st, 2);
+ console.log(`Key state string: ${st} ==> ${ss}`);
+
+ // send
+ inputChannel.send(ss);
+
+ }, 1000 / fps)
+
+
+ },
+
+ // error callback
+ (exp) => {
+ console.log("setRemoteDescription failed, we are doomed");
+ console.log(exp);
+ });
} catch (e) {
- alert(e)
+ alert(e);
}
}
diff --git a/ui/director.go b/ui/director.go
index 88fba3aa..a6feedb6 100644
--- a/ui/director.go
+++ b/ui/director.go
@@ -15,16 +15,17 @@ type View interface {
}
type Director struct {
- audio *Audio
+ // audio *Audio
view View
timestamp float64
imageChannel chan *image.RGBA
inputChannel chan int
}
-func NewDirector(audio *Audio, imageChannel chan *image.RGBA, inputChannel chan int) *Director {
+func NewDirector(imageChannel chan *image.RGBA, inputChannel chan int) *Director {
+// func NewDirector(audio *Audio, imageChannel chan *image.RGBA, inputChannel chan int) *Director {
director := Director{}
- director.audio = audio
+ // director.audio = audio
director.imageChannel = imageChannel
director.inputChannel = inputChannel
return &director
diff --git a/ui/gameview.go b/ui/gameview.go
index 5c9d7b75..313b3173 100644
--- a/ui/gameview.go
+++ b/ui/gameview.go
@@ -3,6 +3,9 @@ package ui
import (
"image"
+ "fmt"
+ // "strconv"
+
"github.com/giongto35/game-online/nes"
)
@@ -16,14 +19,14 @@ type GameView struct {
record bool
frames []image.Image
- keyPressed []bool
+ keyPressed [8]bool
imageChannel chan *image.RGBA
inputChannel chan int
}
func NewGameView(director *Director, console *nes.Console, title, hash string, imageChannel chan *image.RGBA, inputChannel chan int) View {
- gameview := &GameView{director, console, title, hash, false, nil, make([]bool, 255), imageChannel, inputChannel}
+ gameview := &GameView{director, console, title, hash, false, nil, [8]bool{false}, imageChannel, inputChannel}
go gameview.ListenToInputChannel()
return gameview
}
@@ -31,18 +34,20 @@ func NewGameView(director *Director, console *nes.Console, title, hash string, i
func (view *GameView) ListenToInputChannel() {
for {
key := <-view.inputChannel
- if key < 0 {
- view.keyPressed[-key] = false
- } else {
- view.keyPressed[key] = true
+ s := fmt.Sprintf("%.8b", key)
+ for i := 0; i < len(s); i++ {
+ if s[i] == '1' {
+ view.keyPressed[i] = true
+ } else {
+ view.keyPressed[i] = false
+ }
}
-
}
}
func (view *GameView) Enter() {
- view.console.SetAudioChannel(view.director.audio.channel)
- view.console.SetAudioSampleRate(view.director.audio.sampleRate)
+ // view.console.SetAudioChannel(view.director.audio.channel)
+ // view.console.SetAudioSampleRate(view.director.audio.sampleRate)
// load state
if err := view.console.LoadState(savePath(view.hash)); err == nil {
return
@@ -59,8 +64,8 @@ func (view *GameView) Enter() {
}
func (view *GameView) Exit() {
- view.console.SetAudioChannel(nil)
- view.console.SetAudioSampleRate(0)
+ // view.console.SetAudioChannel(nil)
+ // view.console.SetAudioSampleRate(0)
// save sram
cartridge := view.console.Cartridge
if cartridge.Battery != 0 {
@@ -87,14 +92,15 @@ func (view *GameView) Update(t, dt float64) {
func (view *GameView) updateControllers() {
// TODO: switch case
- var buttons [8]bool
- buttons[nes.ButtonLeft] = view.keyPressed[37]
- buttons[nes.ButtonUp] = view.keyPressed[38]
- buttons[nes.ButtonRight] = view.keyPressed[39]
- buttons[nes.ButtonDown] = view.keyPressed[40]
- buttons[nes.ButtonA] = view.keyPressed[32]
- buttons[nes.ButtonB] = view.keyPressed[17]
- buttons[nes.ButtonStart] = view.keyPressed[13]
- buttons[nes.ButtonSelect] = view.keyPressed[16]
- view.console.Controller1.SetButtons(buttons)
+ // var buttons [8]bool
+ // buttons[nes.ButtonLeft] = view.keyPressed[37]
+ // buttons[nes.ButtonUp] = view.keyPressed[38]
+ // buttons[nes.ButtonRight] = view.keyPressed[39]
+ // buttons[nes.ButtonDown] = view.keyPressed[40]
+ // buttons[nes.ButtonA] = view.keyPressed[32]
+ // buttons[nes.ButtonB] = view.keyPressed[17]
+ // buttons[nes.ButtonStart] = view.keyPressed[13]
+ // buttons[nes.ButtonSelect] = view.keyPressed[16]
+ // view.console.Controller1.SetButtons(buttons)
+ view.console.Controller1.SetButtons(view.keyPressed)
}
diff --git a/ui/run.go b/ui/run.go
index 5b5e342b..5822bd28 100644
--- a/ui/run.go
+++ b/ui/run.go
@@ -2,10 +2,10 @@ package ui
import (
"image"
- "log"
+ // "log"
"runtime"
- "github.com/gordonklaus/portaudio"
+ // "github.com/gordonklaus/portaudio"
)
const (
@@ -25,16 +25,17 @@ func init() {
func Run(paths []string, imageChannel chan *image.RGBA, inputChannel chan int) {
// initialize audio
- portaudio.Initialize()
- defer portaudio.Terminate()
+ // portaudio.Initialize()
+ // defer portaudio.Terminate()
- audio := NewAudio()
- if err := audio.Start(); err != nil {
- log.Fatalln(err)
- }
- defer audio.Stop()
+ // audio := NewAudio()
+ // if err := audio.Start(); err != nil {
+ // log.Fatalln(err)
+ // }
+ // defer audio.Stop()
// run director
- director := NewDirector(audio, imageChannel, inputChannel)
+ director := NewDirector(imageChannel, inputChannel)
+ // director := NewDirector(audio, imageChannel, inputChannel)
director.Start(paths)
}