/* * Copyright (C) 1997-2001 Id Software, Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307, USA. * */ /* Modifications Copyright 2003-2004 Bytonic Software Copyright 2010 Google Inc. */ package com.googlecode.gwtquake.shared.common; import com.googlecode.gwtquake.shared.game.*; public class Delta { // // writing functions // public static void WriteDeltaUsercmd(Buffer buf, UserCommand from, UserCommand cmd) { int bits; // // send the movement message // bits = 0; if (cmd.angles[0] != from.angles[0]) bits |= Constants.CM_ANGLE1; if (cmd.angles[1] != from.angles[1]) bits |= Constants.CM_ANGLE2; if (cmd.angles[2] != from.angles[2]) bits |= Constants.CM_ANGLE3; if (cmd.forwardmove != from.forwardmove) bits |= Constants.CM_FORWARD; if (cmd.sidemove != from.sidemove) bits |= Constants.CM_SIDE; if (cmd.upmove != from.upmove) bits |= Constants.CM_UP; if (cmd.buttons != from.buttons) bits |= Constants.CM_BUTTONS; if (cmd.impulse != from.impulse) bits |= Constants.CM_IMPULSE; Buffers.writeByte(buf, bits); if ((bits & Constants.CM_ANGLE1) != 0) buf.WriteShort(cmd.angles[0]); if ((bits & Constants.CM_ANGLE2) != 0) buf.WriteShort(cmd.angles[1]); if ((bits & Constants.CM_ANGLE3) != 0) buf.WriteShort(cmd.angles[2]); if ((bits & Constants.CM_FORWARD) != 0) buf.WriteShort(cmd.forwardmove); if ((bits & Constants.CM_SIDE) != 0) buf.WriteShort(cmd.sidemove); if ((bits & Constants.CM_UP) != 0) buf.WriteShort(cmd.upmove); if ((bits & Constants.CM_BUTTONS) != 0) Buffers.writeByte(buf, cmd.buttons); if ((bits & Constants.CM_IMPULSE) != 0) Buffers.writeByte(buf, cmd.impulse); Buffers.writeByte(buf, cmd.msec); Buffers.writeByte(buf, cmd.lightlevel); } /* * ================== WriteDeltaEntity * * Writes part of a packetentities message. Can delta from either a baseline * or a previous packet_entity ================== */ public static void WriteDeltaEntity(EntityState from, EntityState to, Buffer msg, boolean force, boolean newentity) { int bits; if (0 == to.number) Com.Error(Constants.ERR_FATAL, "Unset entity number"); if (to.number >= Constants.MAX_EDICTS) Com.Error(Constants.ERR_FATAL, "Entity number >= MAX_EDICTS"); // send an update bits = 0; if (to.number >= 256) bits |= Constants.U_NUMBER16; // number8 is implicit otherwise if (to.origin[0] != from.origin[0]) bits |= Constants.U_ORIGIN1; if (to.origin[1] != from.origin[1]) bits |= Constants.U_ORIGIN2; if (to.origin[2] != from.origin[2]) bits |= Constants.U_ORIGIN3; if (to.angles[0] != from.angles[0]) bits |= Constants.U_ANGLE1; if (to.angles[1] != from.angles[1]) bits |= Constants.U_ANGLE2; if (to.angles[2] != from.angles[2]) bits |= Constants.U_ANGLE3; if (to.skinnum != from.skinnum) { if (to.skinnum < 256) bits |= Constants.U_SKIN8; else if (to.skinnum < 0x10000) bits |= Constants.U_SKIN16; else bits |= (Constants.U_SKIN8 | Constants.U_SKIN16); } if (to.frame != from.frame) { if (to.frame < 256) bits |= Constants.U_FRAME8; else bits |= Constants.U_FRAME16; } if (to.effects != from.effects) { if (to.effects < 256) bits |= Constants.U_EFFECTS8; else if (to.effects < 0x8000) bits |= Constants.U_EFFECTS16; else bits |= Constants.U_EFFECTS8 | Constants.U_EFFECTS16; } if (to.renderfx != from.renderfx) { if (to.renderfx < 256) bits |= Constants.U_RENDERFX8; else if (to.renderfx < 0x8000) bits |= Constants.U_RENDERFX16; else bits |= Constants.U_RENDERFX8 | Constants.U_RENDERFX16; } if (to.solid != from.solid) bits |= Constants.U_SOLID; // event is not delta compressed, just 0 compressed if (to.event != 0) bits |= Constants.U_EVENT; if (to.modelindex != from.modelindex) bits |= Constants.U_MODEL; if (to.modelindex2 != from.modelindex2) bits |= Constants.U_MODEL2; if (to.modelindex3 != from.modelindex3) bits |= Constants.U_MODEL3; if (to.modelindex4 != from.modelindex4) bits |= Constants.U_MODEL4; if (to.sound != from.sound) bits |= Constants.U_SOUND; if (newentity || (to.renderfx & Constants.RF_BEAM) != 0) bits |= Constants.U_OLDORIGIN; // // write the message // if (bits == 0 && !force) return; // nothing to send! //---------- if ((bits & 0xff000000) != 0) bits |= Constants.U_MOREBITS3 | Constants.U_MOREBITS2 | Constants.U_MOREBITS1; else if ((bits & 0x00ff0000) != 0) bits |= Constants.U_MOREBITS2 | Constants.U_MOREBITS1; else if ((bits & 0x0000ff00) != 0) bits |= Constants.U_MOREBITS1; Buffers.writeByte(msg, bits & 255); if ((bits & 0xff000000) != 0) { Buffers.writeByte(msg, (bits >>> 8) & 255); Buffers.writeByte(msg, (bits >>> 16) & 255); Buffers.writeByte(msg, (bits >>> 24) & 255); } else if ((bits & 0x00ff0000) != 0) { Buffers.writeByte(msg, (bits >>> 8) & 255); Buffers.writeByte(msg, (bits >>> 16) & 255); } else if ((bits & 0x0000ff00) != 0) { Buffers.writeByte(msg, (bits >>> 8) & 255); } //---------- if ((bits & Constants.U_NUMBER16) != 0) msg.WriteShort(to.number); else Buffers.writeByte(msg, to.number); if ((bits & Constants.U_MODEL) != 0) Buffers.writeByte(msg, to.modelindex); if ((bits & Constants.U_MODEL2) != 0) Buffers.writeByte(msg, to.modelindex2); if ((bits & Constants.U_MODEL3) != 0) Buffers.writeByte(msg, to.modelindex3); if ((bits & Constants.U_MODEL4) != 0) Buffers.writeByte(msg, to.modelindex4); if ((bits & Constants.U_FRAME8) != 0) Buffers.writeByte(msg, to.frame); if ((bits & Constants.U_FRAME16) != 0) msg.WriteShort(to.frame); if ((bits & Constants.U_SKIN8) != 0 && (bits & Constants.U_SKIN16) != 0) //used for laser // colors msg.putInt(to.skinnum); else if ((bits & Constants.U_SKIN8) != 0) Buffers.writeByte(msg, to.skinnum); else if ((bits & Constants.U_SKIN16) != 0) msg.WriteShort(to.skinnum); if ((bits & (Constants.U_EFFECTS8 | Constants.U_EFFECTS16)) == (Constants.U_EFFECTS8 | Constants.U_EFFECTS16)) msg.putInt(to.effects); else if ((bits & Constants.U_EFFECTS8) != 0) Buffers.writeByte(msg, to.effects); else if ((bits & Constants.U_EFFECTS16) != 0) msg.WriteShort(to.effects); if ((bits & (Constants.U_RENDERFX8 | Constants.U_RENDERFX16)) == (Constants.U_RENDERFX8 | Constants.U_RENDERFX16)) msg.putInt(to.renderfx); else if ((bits & Constants.U_RENDERFX8) != 0) Buffers.writeByte(msg, to.renderfx); else if ((bits & Constants.U_RENDERFX16) != 0) msg.WriteShort(to.renderfx); if ((bits & Constants.U_ORIGIN1) != 0) Buffers.WriteCoord(msg, to.origin[0]); if ((bits & Constants.U_ORIGIN2) != 0) Buffers.WriteCoord(msg, to.origin[1]); if ((bits & Constants.U_ORIGIN3) != 0) Buffers.WriteCoord(msg, to.origin[2]); if ((bits & Constants.U_ANGLE1) != 0) Buffers.WriteAngle(msg, to.angles[0]); if ((bits & Constants.U_ANGLE2) != 0) Buffers.WriteAngle(msg, to.angles[1]); if ((bits & Constants.U_ANGLE3) != 0) Buffers.WriteAngle(msg, to.angles[2]); if ((bits & Constants.U_OLDORIGIN) != 0) { Buffers.WriteCoord(msg, to.old_origin[0]); Buffers.WriteCoord(msg, to.old_origin[1]); Buffers.WriteCoord(msg, to.old_origin[2]); } if ((bits & Constants.U_SOUND) != 0) Buffers.writeByte(msg, to.sound); if ((bits & Constants.U_EVENT) != 0) Buffers.writeByte(msg, to.event); if ((bits & Constants.U_SOLID) != 0) msg.WriteShort(to.solid); } //============================================================ // // reading functions // public static void ReadDeltaUsercmd(Buffer msg_read, UserCommand from, UserCommand move) { int bits; //memcpy(move, from, sizeof(* move)); // IMPORTANT!! copy without new move.set(from); bits = Buffers.readUnsignedByte(msg_read); // read current angles if ((bits & Constants.CM_ANGLE1) != 0) move.angles[0] = msg_read.getShort(); if ((bits & Constants.CM_ANGLE2) != 0) move.angles[1] = msg_read.getShort(); if ((bits & Constants.CM_ANGLE3) != 0) move.angles[2] = msg_read.getShort(); // read movement if ((bits & Constants.CM_FORWARD) != 0) move.forwardmove = msg_read.getShort(); if ((bits & Constants.CM_SIDE) != 0) move.sidemove = msg_read.getShort(); if ((bits & Constants.CM_UP) != 0) move.upmove = msg_read.getShort(); // read buttons if ((bits & Constants.CM_BUTTONS) != 0) move.buttons = (byte) Buffers.readUnsignedByte(msg_read); if ((bits & Constants.CM_IMPULSE) != 0) move.impulse = (byte) Buffers.readUnsignedByte(msg_read); // read time to run command move.msec = (byte) Buffers.readUnsignedByte(msg_read); // read the light level move.lightlevel = (byte) Buffers.readUnsignedByte(msg_read); } }