mirror of
https://github.com/giongto35/cloud-game.git
synced 2026-07-25 19:13:52 +00:00
remove audio, fix input channel
This commit is contained in:
parent
173e64cd01
commit
950f76240a
4 changed files with 125 additions and 38 deletions
87
index.html
87
index.html
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
21
ui/run.go
21
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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue