NetPlay controls synch strategy improved

This commit is contained in:
ppeccin 2018-01-22 22:36:00 -02:00
parent a3662995c6
commit 7bcee30e74
4 changed files with 64 additions and 75 deletions

View file

@ -75,12 +75,12 @@ jt.NetClient = function(room) {
if (disabledControls.has(control))
return room.showOSD("Function not available in NetPlay Client mode", true, true);
// Send only to server, do not process locally
// Store change to be sent only to Server, do not process locally
controlsToSend.push((control << 4) | press ); // binary encoded, always < 16000
};
this.processLocalControlValue = function (control, value) {
// Send only to server, do not process locally
// Store change to be sent only to Server, do not process locally
controlsToSend.push(control + (value + 10)); // always > 16000
};
@ -136,7 +136,7 @@ jt.NetClient = function(room) {
sessionID = message.sessionID;
nick = message.clientNick;
wsOnly = wsOnlyDesired || message.wsOnly;
// nextUpdate = -1;
justJoined = true;
if (wsOnly) return enterNetClientMode();
@ -214,36 +214,9 @@ jt.NetClient = function(room) {
function onServerNetUpdate(netUpdate) {
// window.console.log(netUpdate);
// Not needed in an ordered DataChannel?
//if (netUpdate.u !== nextUpdate && nextUpdate >= 0) {
// jt.Util.error("NetPlay Client expected update: " + nextUpdate + ", but got: " + netUpdate.u);
// self.leaveSession(true, "NetPlay session ended: Update sequence error");
//}
//nextUpdate = netUpdate.u + 1;
// NetClient gets no local clock, so we use the chance...
// NetClient gets no local clock, so...
console.getConsoleControlsSocket().controlsClockPulse();
// Full Update?
if (netUpdate.s) {
console.loadStateExtended(netUpdate.s);
// Change Controls Mode automatically to adapt to Server
room.consoleControls.setP1ControlsAndPaddleMode(!netUpdate.cm.p1, netUpdate.cm.pd);
}
// Apply controls changes
if (netUpdate.c) {
var controls = netUpdate.c;
for (var i = 0, len = controls.length; i < len; ++i) {
var control = controls[i];
if (control < 16000)
consoleControlsSocket.controlStateChanged(control >> 4, control & 0x01); // binary encoded
else
consoleControlsSocket.controlValueChanged(control & ~0x3fff, (control & 0x3fff) - 10);
}
}
console.videoClockPulseApplyPulldowns(netUpdate.v);
atariConsole.getConsoleControlsSocket().controlsClockPulse();
// Send local controls to Server. We always send a message even when empty to keep the channel active
if (dataChannelActive)
@ -253,6 +226,30 @@ jt.NetClient = function(room) {
// Or fallback to WebSocket relayed through the Session Server (BAD!)
ws.send(JSON.stringify({ javatariUpdate: { c: controlsToSend.length ? controlsToSend : undefined } }));
controlsToSend.length = 0;
// Full Update?
if (netUpdate.s) {
atariConsole.loadStateExtended(netUpdate.s);
if (justJoined) {
// Change Controls Mode automatically to adapt to Server
room.consoleControls.setP1ControlsAndPaddleMode(!netUpdate.cm.p1, netUpdate.cm.pd);
justJoined = false;
}
} else {
// Apply controls changes from Server
if (netUpdate.c) {
var controls = netUpdate.c;
for (var i = 0, len = controls.length; i < len; ++i) {
var control = controls[i];
if (control < 16000)
consoleControlsSocket.controlStateChanged(control >> 4, control & 0x01); // binary encoded
else
consoleControlsSocket.controlValueChanged(control & ~0x3fff, (control & 0x3fff) - 10);
}
}
}
atariConsole.videoClockPulseApplyPulldowns(netUpdate.v);
}
function keepAlive() {
@ -286,8 +283,8 @@ jt.NetClient = function(room) {
}
var console = room.console;
var consoleControlsSocket = console.getConsoleControlsSocket();
var atariConsole = room.console;
var consoleControlsSocket = atariConsole.getConsoleControlsSocket();
var controlsToSend = new Array(100); controlsToSend.length = 0; // pre allocate empty Array
@ -297,6 +294,7 @@ jt.NetClient = function(room) {
var nick;
var nickDesired;
var wsOnlyDesired = false;
var justJoined = false;
var keepAliveTimer;
var rtcConnectionConfig;
@ -307,7 +305,6 @@ jt.NetClient = function(room) {
var dataChannelActive = false;
var dataChannelFragmentData = "";
// var nextUpdate = -1;
var cc = jt.ConsoleControls;
var disabledControls = new Set([

View file

@ -57,9 +57,7 @@ jt.NetServer = function(room) {
};
this.netVideoClockPulse = function() {
//++updates; Not needed in an ordered DataChannel?
var videoPulls = console.videoClockPulseGetNextPulldowns();
var videoPulls = atariConsole.videoClockPulseGetNextPulldowns();
var data, dataFull, dataNormal;
for (var cNick in clients) {
@ -69,19 +67,16 @@ jt.NetServer = function(room) {
if (client.justJoined || nextUpdateFull) {
client.justJoined = false;
if (!dataFull) {
//netUpdateFull.u = updates;
netUpdateFull.s = atariConsole.saveStateExtended();
netUpdateFull.cm = { p1: room.consoleControls.isP1ControlsMode(), pd: room.consoleControls.isPaddleMode() };
netUpdateFull.s = console.saveStateExtended();
netUpdateFull.v = videoPulls;
netUpdateFull.c = controlsToProcess.length ? controlsToProcess : undefined;
dataFull = JSON.stringify(netUpdateFull);
}
data = dataFull;
} else {
if (!dataNormal) {
// netUpdate.u = updates;
netUpdate.c = controlsToSend.length ? controlsToSend : undefined;
netUpdate.v = videoPulls;
netUpdate.c = controlsToProcess.length ? controlsToProcess : undefined;
dataNormal = JSON.stringify(netUpdate);
}
data = dataNormal;
@ -99,34 +94,25 @@ jt.NetServer = function(room) {
}
}
if (nextUpdateFull) nextUpdateFull = false;
nextUpdateFull = false;
controlsToSend.length = 0;
if (controlsToProcess.length) {
for (var i = 0, len = controlsToProcess.length; i < len; ++i) {
var control = controlsToProcess[i];
if (control < 16000)
consoleControlsSocket.controlStateChanged(control >> 4, control & 0x01); // binary encoded
else
consoleControlsSocket.controlValueChanged(control & ~0x3fff, (control & 0x3fff) - 10);
}
controlsToProcess.length = 0;
}
console.videoClockPulseApplyPulldowns(videoPulls);
atariConsole.videoClockPulseApplyPulldowns(videoPulls);
};
this.processLocalControlState = function (control, press) {
if (localOnlyControls.has(control))
// Process local-only controls right away, do not store
consoleControlsSocket.controlStateChanged(control, press);
else
// Just store changes, to be processed on netVideoClockPulse
controlsToProcess.push((control << 4) | press ); // binary encoded, always < 16000
consoleControlsSocket.controlStateChanged(control, press);
// Store changes to be sent to Clients
if (!localOnlyControls.has(control))
controlsToSend.push((control << 4) | press ); // binary encoded, always < 16000
};
this.processLocalControlValue = function (control, value) {
// Just store changes, to be processed on netVideoClockPulse
controlsToProcess.push(control + (value + 10)); // always > 16000
consoleControlsSocket.controlValueChanged(control, value);
// Store changes to be sent to Clients
controlsToSend.push(control + (value + 10)); // always > 16000
};
this.processCheckLocalPeripheralControl = function (control) {
@ -188,8 +174,7 @@ jt.NetServer = function(room) {
} catch (e) {}
sessionID = message.sessionID;
// updates = 0;
controlsToProcess.length = 0;
controlsToSend.length = 0;
room.enterNetServerMode(self);
room.showOSD('NetPlay session "' + message.sessionID + '" started', true);
@ -290,8 +275,16 @@ jt.NetServer = function(room) {
}
function onClientNetUpdate(netUpdate) {
// Store remote controls to process on netVideoClockPulse
if (netUpdate.c) controlsToProcess.push.apply(controlsToProcess, netUpdate.c);
if (!netUpdate.c) return;
// Apply changes as if they were local controls
for (var i = 0, changes = netUpdate.c, len = changes.length; i < len; ++i) {
var change = changes[i];
if (change < 16000)
self.processLocalControlState(change >> 4, change & 0x01); // binary encoded
else
self.processLocalControlValue(change & ~0x3fff, (change & 0x3fff) - 10);
}
}
function keepAlive() {
@ -329,10 +322,10 @@ jt.NetServer = function(room) {
}
var console = room.console;
var consoleControlsSocket = console.getConsoleControlsSocket();
var atariConsole = room.console;
var consoleControlsSocket = atariConsole.getConsoleControlsSocket();
var controlsToProcess = new Array(100); controlsToProcess.length = 0; // pre allocate empty Array
var controlsToSend = new Array(100); controlsToSend.length = 0; // pre allocate empty Array
var netUpdate = { v: 0, c: undefined };
var netUpdateFull = { cm: {}, s: {}, v: 0, c: undefined };
var nextUpdateFull = false;
@ -344,8 +337,6 @@ jt.NetServer = function(room) {
var clients = {};
var wsOnly = false;
// var updates = 0;
var rtcConnectionConfig;
var dataChannelConfig;

View file

@ -37,7 +37,7 @@
<div id="footer-space"></div>
<div id="footer">
<div class="container">
<script>Javatari.WEB_EXTENSIONS_SERVER = "wmsx.herokuapp.com";</script>
<script>Javatari.WEB_EXTENSIONS_SERVER = "webmsx.herokuapp.com";</script>
<p>Created by <a href="http://twitter.com/ppeccin" target="_blank">Paulo A. Peccin</a></p>
<p>v4.0.1 &nbsp;<a href="https://github.com/ppeccin/javatari.js" target="_blank">Docs & Project Homepage</a></p>
</div>

View file

@ -127,7 +127,8 @@
<script>
Javatari.AUTO_POWER_ON_DELAY = 0;
// Javatari.CARTRIDGE_URL = "roms/Pitfall.bin";
Javatari.WEB_EXTENSIONS_SERVER = "webmsx.herokuapp.com";
// Javatari.CARTRIDGE_URL = "roms/Pitfall.bin";
</script>