You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
2.5 KiB
Go
109 lines
2.5 KiB
Go
package game
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/md5"
|
|
"encoding/gob"
|
|
"fmt"
|
|
"log"
|
|
|
|
"code.rocketnine.space/tslocum/boxbrawl/world"
|
|
|
|
"github.com/assemblaj/ggpo"
|
|
)
|
|
|
|
const frameDelay int = 2
|
|
|
|
type GameSession struct {
|
|
backend ggpo.Backend
|
|
game *Game
|
|
saveStates map[int]*Game
|
|
}
|
|
|
|
func NewGameSession() *GameSession {
|
|
g := &GameSession{}
|
|
game, _ := NewGame()
|
|
g.game = game
|
|
g.saveStates = make(map[int]*Game)
|
|
return g
|
|
}
|
|
|
|
func (g *GameSession) SaveGameState(stateID int) int {
|
|
g.saveStates[stateID] = g.game.clone()
|
|
checksum := calculateChecksum([]byte(g.saveStates[stateID].String()))
|
|
return checksum
|
|
}
|
|
|
|
func calculateChecksum(buffer []byte) int {
|
|
cSum := md5.Sum(buffer)
|
|
checksum := 0
|
|
for i := 0; i < len(cSum); i++ {
|
|
checksum += int(cSum[i])
|
|
}
|
|
return checksum
|
|
}
|
|
|
|
func (g *GameSession) LoadGameState(stateID int) {
|
|
*g.game = *g.saveStates[stateID]
|
|
}
|
|
|
|
func (g *GameSession) LogGameState(fileName string, buffer []byte, len int) {
|
|
var game2 Game
|
|
var buf bytes.Buffer = *bytes.NewBuffer(buffer)
|
|
dec := gob.NewDecoder(&buf)
|
|
err := dec.Decode(&game2)
|
|
if err != nil {
|
|
log.Fatal("decode error:", err)
|
|
}
|
|
log.Printf("%s Game State: %s\n", fileName, game2.String())
|
|
}
|
|
|
|
func (g *GameSession) SetBackend(backend ggpo.Backend) {
|
|
}
|
|
|
|
func (g *Game) String() string {
|
|
return fmt.Sprintf("%s : %s ", g.Players[0].String(), g.Players[1].String())
|
|
}
|
|
|
|
func (g *GameSession) AdvanceFrame(flags int) {
|
|
//fmt.Println("Advancing frame from callback.")
|
|
var disconnectFlags int
|
|
|
|
// Make sure we fetch the inputs from GGPO and use these to update
|
|
// the game state instead of reading from the keyboard.
|
|
inputs, result := g.backend.SyncInput(&disconnectFlags)
|
|
if result == nil {
|
|
input := decodeInputs(inputs)
|
|
g.game.AdvanceFrame(input, disconnectFlags)
|
|
}
|
|
}
|
|
|
|
func (g *GameSession) OnEvent(info *ggpo.Event) {
|
|
switch info.Code {
|
|
case ggpo.EventCodeRunning:
|
|
// We are fully connected now.
|
|
if world.ConnectPromptVisible {
|
|
log.Println("Connection established")
|
|
world.ConnectPromptVisible = false
|
|
}
|
|
case ggpo.EventCodeConnectionInterrupted:
|
|
log.Println("Connection interrupted")
|
|
case ggpo.EventCodeConnectionResumed:
|
|
log.Println("Connection resumed")
|
|
case ggpo.EventCodeDisconnectedFromPeer:
|
|
log.Println("Connection lost")
|
|
default:
|
|
if world.Debug == 0 {
|
|
return
|
|
}
|
|
switch info.Code {
|
|
case ggpo.EventCodeConnectedToPeer:
|
|
log.Println("Connected to peer")
|
|
case ggpo.EventCodeSynchronizingWithPeer:
|
|
log.Println("Synchronizing with peer")
|
|
case ggpo.EventCodeSynchronizedWithPeer:
|
|
log.Println("Synchronized with peer")
|
|
}
|
|
}
|
|
}
|