remove audio, fix input channel

This commit is contained in:
exel 2019-04-04 23:34:51 +08:00
parent 173e64cd01
commit 950f76240a
4 changed files with 125 additions and 38 deletions

View file

@ -56,6 +56,12 @@ let log = msg => {
document.getElementById('div').innerHTML += msg + '<br>'
}
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);
}
}

View file

@ -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

View file

@ -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)
}

View file

@ -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)
}