diff --git a/CREDITS.txt b/CREDITS.txt
index ff0c966..74ef77e 100644
--- a/CREDITS.txt
+++ b/CREDITS.txt
@@ -9,6 +9,17 @@ And the rest in alphabetical order:
BR:
Player name list
+ Team switching
+ "Are you sure?" on quit
+ Improved key binding system
+
+Ericson2314:
+ Rearranged the build tree
+ Added an SSE-optimised matrix-vector multiply
+
+rakiru:
+ Scroll wheel to switch tools
+ Lent his VPS to host an Iceball server
topo:
FPS counter
diff --git a/docs/READ_THIS_FIRST.txt b/docs/READ_THIS_FIRST.txt
index fa9f8cd..188c498 100644
--- a/docs/READ_THIS_FIRST.txt
+++ b/docs/READ_THIS_FIRST.txt
@@ -145,8 +145,7 @@ F5 = release mouse cursor
F1 = show some debug information
TAB = show names / scores
-
-[ TODO: add , for teamswitch ]
+, = switch teams
Note that there is no weapon select key. This isn't Ace of Jagex.
@@ -156,8 +155,6 @@ For each tool, here is what each mouse button does:
3: Gun: L = shoot, R = zoom
4: Grenade: L press = pull the pin, L release = throw
-[ TODO: These will eventually be valid! ]
-
A few notes:
- If you left-click-dig with the spade, you can get blocks back which you can
build stuff with later.
diff --git a/docs/changelog.txt b/docs/changelog.txt
index fc820ae..71e18aa 100644
--- a/docs/changelog.txt
+++ b/docs/changelog.txt
@@ -1,23 +1,32 @@
-0.1.0.0 - Released YYYY-MM-DD.
+0.1.0/0.0 - Released YYYY-MM-DD.
- Initial release.
-------------------------------------------------------------------------------
Version scheme:
-w.x.y.za
+Engine: w.x.ya
+Engine (git): w.x.ya-z
+Game: w.x.ya/p.qb-r
+
w.x = major base engine version. Note, 0.10 is > 0.9.
-y = minor base engine version, for quick fixes.
-z = major game version.
-a = minor game version (a lowercase letter), for quick fixes.
+y = minor base engine version, for bugfixes and whatnot. optional.
+a = subminor base engine version, for last-minute fixes. optional.
+z = git version. optional, must be 0 for releases and >=1 for nonreleases!
+
+p.qb-r = same as above but for game code (p is equivalent to w.x).
+p.q is mandatory; b is optional.
+These start at 0.0.
Note, if you increase one of these, you reset those after it to zero
-(or blank for "a").
+(or blank for "a"/"b").
-"a" should never go past the letter z.
-But if it does, you might as well just bump "z" up a digit,
-and reset "a" to blank.
+"a"/"b" should never go past the letter z.
+But if it does, you might as well just bump "y"/"q" up a digit,
+and reset "a"/"b" to blank.
Ultimately:
-- servers should always have the latest w.x.y.za version, and
-- clients and servers alike must always have the latest w.x version.
-
+- servers must always have the latest w.x.ya release version of the engine
+- clients must always have the latest w.x release version
+- clients ideally should have the latest w.x.ya release version
+- servers ideally should have the latest w.x.ya/p.qb version of the game component
+- clients do not need the game component at all
diff --git a/docs/modding_lua.txt b/docs/modding_lua.txt
index 567fdee..91d55a4 100644
--- a/docs/modding_lua.txt
+++ b/docs/modding_lua.txt
@@ -26,11 +26,13 @@ lua base library stuff:
error @
print @
loadstring @
- loadfile @ (TODO: filter the path)
- dofile @ (TODO: filter the path)
+ loadfile @
+ dofile @
_G @
nothing else yet
+ (TODO: work out what we want to keep,
+ as there's stuff being used that isn't listed here!)
check http://www.lua.org/manual/5.1/ for more info on these
@@ -53,6 +55,13 @@ common.base_dir @
writing to this string will *not* change the base dir,
so *don't write to it* or else you'll just screw up your own code!
+common.version = {cmp={w,x,y,a,z},num,str="w.x.ya-z"} @
+ current engine version
+
+ cmp is for the individual version components
+ num is a comparable number (bit count for each: 5,5,7,5,10)
+ str is the version as a string
+
client/server.hook_tick = fn(sec_curtime, sec_delta)->sec_wait @
sets a hook called every "tick"
returns a number telling it how long it wants to wait for
diff --git a/include/common.h b/include/common.h
index 529bee7..38d7f6b 100644
--- a/include/common.h
+++ b/include/common.h
@@ -15,6 +15,15 @@
along with Iceball. If not, see .
*/
+#define VERSION_W 0
+#define VERSION_X 0
+#define VERSION_Y 0
+#define VERSION_A 0
+#define VERSION_Z 1
+// Remember to bump "Z" basically every time you change the engine!
+// Z can only be 0 for official releases!
+
+
#define MODEL_BONE_MAX 256
#define MODEL_POINT_MAX 4096
#define PACKET_LEN_MAX 1280
diff --git a/pkg/base/client_start.lua b/pkg/base/client_start.lua
index 26307c0..1a34bac 100644
--- a/pkg/base/client_start.lua
+++ b/pkg/base/client_start.lua
@@ -53,8 +53,10 @@ while true do
end
end]]
---map_fname = "*MAP"
-map_fname = "pkg/MAP" -- hackish workaround so iceballfornoobs-004 still works
+map_fname = "*MAP"
+if not common.version then
+ map_fname = "pkg/MAP" -- hackish workaround so iceballfornoobs-004 still works
+end
if not map_fname then
error("server should have sent map name by now")
diff --git a/pkg/base/common.lua b/pkg/base/common.lua
index f50f0fa..38b9714 100644
--- a/pkg/base/common.lua
+++ b/pkg/base/common.lua
@@ -17,6 +17,8 @@
print("base dir:",common.base_dir)
+dofile("pkg/base/version.lua")
+
-- base dir stuff
DIR_PKG_ROOT = DIR_PKG_ROOT or "pkg/base"
DIR_PKG_LIB = DIR_PKG_LIB or DIR_PKG_ROOT
@@ -371,127 +373,6 @@ players = {max = 32, current = 1}
intent = {}
nades = {head = 1, tail = 0}
-function string.split(s, sep, plain)
- local start = 1
- local done = false
- local function pass(i, j, ...)
- if i then
- local seg = s:sub(start, i - 1)
- start = j + 1
- return seg, ...
- else
- done = true
- return s:sub(start)
- end
- end
- local result = {}
- while not done do
- if sep == '' then done = true result[#result+1]=s end
- result[#result+1]=pass(s:find(sep, start, plain))
- end
- return result
-end
-
--- trim the character 'sep' from the left hand side of the string
-function string.triml(s, sep)
- sep = string.byte(sep)
- if s == '' then return s end
- local pos = 1
- while string.byte(s,pos)==sep and #s<=pos do pos = pos + 1 end
- return string.sub(s, pos+1)
-end
-
--- trim the character 'sep' from the right hand side of the string
-function string.trimr(s, sep)
- sep = string.byte(sep)
- if s == '' then return s end
- local pos = #s
- while string.byte(s, pos)==sep and pos>=1 do pos = pos - 1 end
- return string.sub(s, 1, pos)
-end
-
--- trim the character 'sep' from both sides of the string
-function string.trim(s, sep)
- return string.triml(string.trimr(s, sep), sep)
-end
-
-function parse_commandline_options(options)
- local user_toggles = {} -- toggle options (key is name, value is position)
- local user_settings = {} -- key-value pairs
- local loose = {} -- loose strings, filenames, etc.
-
- for k, v in pairs(options) do
- local setting_pair = string.split(v, "=")
- local first = string.byte(v,1)
- if first==string.byte('-') then -- we are toggling an option or setting a value
- if #setting_pair == 2 then -- we are setting a key to a value
- user_settings[string.triml(setting_pair[1], '-')]=setting_pair[2]
- print(string.triml(setting_pair[1], '-'),"trimmed")
- else
- user_toggles[string.triml(v, '-')]=k
- end
- else -- add to the loose values
- loose[#loose+1] = v
- end
- end
- return loose, user_toggles, user_settings
-end
-
---[[Create an alarm object. When run, counts down to the specified value
-based on the time delta passed in.
-
-time: The time limit of the alarm. Ignored with values less than 1.
-progress: the progress towards the time limit.
-active: Whether alarm is running or not.
-on_frame: Callback run every frame, passed in the dT of that frame.
-on_trigger: Callback run when alarm reaches its limit, passed in the dT of that frame.
-loop: Whether the alarm will continue after the first run.
-preserve_accumulator: Whether looping transfers overflow dT from the previous run
-
-]]
-function alarm(options)
-
- this = {}
-
- this.time = options.time or 1
- this.progress = options.progress or 0
- this.active = options.active or true
- this.loop = options.loop or false
- this.preserve_accumulator = options.preserve_accumulator or true
- this.on_frame = options.on_frame or nil
- this.on_trigger = options.on_trigger or nil
-
- function this.tick(dT)
- if this.active then
- this.progress = this.progress + dT
- if this.on_frame ~= nil then this.on_frame(dT) end
- while this.progress >= this.time and this.active do
- if this.on_trigger ~= nil then this.on_trigger(dT) end
- if this.loop and this.time > 0 then
- if this.preserve_accumulator then
- this.progress = this.progress - this.time
- else
- this.progress = 0
- end
- else
- this.active = false
- end
- end
- end
- end
-
- function this.restart()
- this.progress = 0
- this.active = true
- end
-
- function this.time_remaining()
- return this.time - this.progress
- end
-
- return this
-end
-
function sort_players()
players_sorted = {}
for k,v in ipairs(players) do
diff --git a/pkg/base/lib_util.lua b/pkg/base/lib_util.lua
index 79904c0..4cc5ee8 100644
--- a/pkg/base/lib_util.lua
+++ b/pkg/base/lib_util.lua
@@ -114,3 +114,58 @@ function parse_commandline_options(options)
end
return loose, user_toggles, user_settings
end
+
+--[[Create an alarm object. When run, counts down to the specified value
+based on the time delta passed in.
+
+time: The time limit of the alarm. Ignored with values less than 1.
+progress: the progress towards the time limit.
+active: Whether alarm is running or not.
+on_frame: Callback run every frame, passed in the dT of that frame.
+on_trigger: Callback run when alarm reaches its limit, passed in the dT of that frame.
+loop: Whether the alarm will continue after the first run.
+preserve_accumulator: Whether looping transfers overflow dT from the previous run
+
+]]
+function alarm(options)
+
+ this = {}
+
+ this.time = options.time or 1
+ this.progress = options.progress or 0
+ this.active = options.active or true
+ this.loop = options.loop or false
+ this.preserve_accumulator = options.preserve_accumulator or true
+ this.on_frame = options.on_frame or nil
+ this.on_trigger = options.on_trigger or nil
+
+ function this.tick(dT)
+ if this.active then
+ this.progress = this.progress + dT
+ if this.on_frame ~= nil then this.on_frame(dT) end
+ while this.progress >= this.time and this.active do
+ if this.on_trigger ~= nil then this.on_trigger(dT) end
+ if this.loop and this.time > 0 then
+ if this.preserve_accumulator then
+ this.progress = this.progress - this.time
+ else
+ this.progress = 0
+ end
+ else
+ this.active = false
+ end
+ end
+ end
+ end
+
+ function this.restart()
+ this.progress = 0
+ this.active = true
+ end
+
+ function this.time_remaining()
+ return this.time - this.progress
+ end
+
+ return this
+end
diff --git a/pkg/base/main_client.lua b/pkg/base/main_client.lua
index 9779d18..33bacea 100644
--- a/pkg/base/main_client.lua
+++ b/pkg/base/main_client.lua
@@ -17,6 +17,53 @@
print("pkg/base/main_client.lua starting")
+dofile("pkg/base/version.lua")
+
+vernotes = ""
+
+local cver = common.version
+
+if cver == nil then
+ cver = {
+ cmp={0,0,0,0,-1004},
+ num=-1,
+ str="iceballfornoobs-004 (or pre-0.0-1 git)",
+ }
+ vernotes = [[
+This is one of a multitude of old versions,
+most likely iceballfornoobs-004.
+
+CLIENT ISSUES (all pre-0.0-1):
+- PMF models have the wrong Z value when close to the screen edges,
+ and can be seen through walls
+
+CLIENT ISSUES (iceballfornoobs-004 and some later builds):
+- Client does pathname security checks for non-clsave files
+
+We will inform you once we have a newer noob build.
+
+If you're using a git build, please upgrade!
+ ]]
+elseif cver.num == VERSION_ENGINE.num then
+ vernotes = [[
+This is the expected version.
+ ]]
+elseif cver.num > VERSION_ENGINE.num and cver.cmp[5] == 0 then
+ vernotes = [[
+This is a newer version than this mod expects.
+Please tell the server owner to upgrade.
+ ]]
+elseif cver.num > VERSION_ENGINE.num then
+ vernotes = [[
+This is a newer version than this mod expects.
+ ]]
+else
+ vernotes = [[
+This is an older version than this mod expects.
+You should have 0.0.0-1.
+ ]]
+end
+
-- please excuse this hack.
a1,a2,a3,a4,a5,a6,a7,a8,a9,a10 = ...
@@ -74,6 +121,12 @@ do
font_mini.print(2, 2+(i-koffs)*8, 0xFFFFFFFF, "LOAD: "..fnlist[i])
end
font_mini.print(2, sh-10, 0xFFFFFFFF, loadstr)
+
+ font_mini.print(2, 2+(12)*8, 0xFFFFFFFF, "Version: "..cver.str)
+ local l = string.split(vernotes,"\n")
+ for i=1,#l do
+ font_mini.print(2, 2+(i+14)*8, 0xFFFFFFFF, l[i])
+ end
end
function client.hook_tick(sec_current, sec_delta)
diff --git a/pkg/base/main_server.lua b/pkg/base/main_server.lua
index 78a770e..5174c2c 100644
--- a/pkg/base/main_server.lua
+++ b/pkg/base/main_server.lua
@@ -18,6 +18,12 @@
print("pkg/base/main_server.lua starting")
print(...)
+if common.version == nil then
+ error("You must have at least version 0.0-1 to run this server!"
+ .." iceballfornoobs-004 is FAR TOO OLD!"
+ .." If you are using an old git version, PLEASE UPDATE!")
+end
+
dofile("pkg/base/common.lua")
client_list = {fdlist={}}
@@ -72,9 +78,9 @@ end
function server.hook_file(sockfd, ftype, fname)
print("hook_file:", sockfd, ftype, fname)
- --if (ftype == "icemap" or ftype == "map") and fname == "*MAP" then
- if (ftype == "icemap" or ftype == "map") and fname == "pkg/MAP" then
- -- hackish workaround so iceballfornoobs-004 still works
+ if (ftype == "icemap" or ftype == "map") and (fname == "pkg/MAP" or fname == "*MAP") then
+ -- pkg/MAP is a hackish workaround so iceballfornoobs-004 still works
+ -- once -004 support is dropped, please remove that approach!
return map_loaded
end
diff --git a/pkg/base/version.lua b/pkg/base/version.lua
new file mode 100644
index 0000000..898af81
--- /dev/null
+++ b/pkg/base/version.lua
@@ -0,0 +1,27 @@
+--[[
+ This file is part of Ice Lua Components.
+
+ Ice Lua Components is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Ice Lua Components 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with Ice Lua Components. If not, see .
+]]
+
+VERSION_ENGINE = {
+ cmp={0,0,0,0,1},
+ num=1,
+ str="0.0-1",
+}
+
+VERSION_MOD = {
+ cmp={0,0,0,1},
+ str="0.0-1"
+}
diff --git a/src/lua.c b/src/lua.c
index 8347bae..1ad11f8 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -228,6 +228,45 @@ int icelua_initfetch(void)
return 0;
}
+void icelua_pushversion(lua_State *L, const char *tabname)
+{
+ char vbuf[32];
+
+ snprintf(vbuf, 31, "%i.%i", VERSION_W, VERSION_X);
+ if(VERSION_Y != 0)
+ snprintf(vbuf+strlen(vbuf), 31-strlen(vbuf), ".%i", VERSION_Y);
+ if(VERSION_A != 0)
+ snprintf(vbuf+strlen(vbuf), 31-strlen(vbuf), "%c", VERSION_A+96);
+ if(VERSION_Z != 0)
+ snprintf(vbuf+strlen(vbuf), 31-strlen(vbuf), "-%i", VERSION_Z);
+
+ lua_getglobal(L, tabname);
+
+ lua_newtable(L);
+
+ lua_pushstring(L, vbuf);
+ lua_setfield(L, -2, "str");
+
+ lua_pushinteger(L,
+ (((((((VERSION_W<<5) + VERSION_X
+ )<<7) + VERSION_Y
+ )<<5) + VERSION_A
+ )<<10) + VERSION_Z);
+ lua_setfield(L, -2, "num");
+
+ lua_newtable(L);
+ lua_pushinteger(L, 1); lua_pushinteger(L, VERSION_W); lua_settable(L, -3);
+ lua_pushinteger(L, 2); lua_pushinteger(L, VERSION_X); lua_settable(L, -3);
+ lua_pushinteger(L, 3); lua_pushinteger(L, VERSION_Y); lua_settable(L, -3);
+ lua_pushinteger(L, 4); lua_pushinteger(L, VERSION_A); lua_settable(L, -3);
+ lua_pushinteger(L, 5); lua_pushinteger(L, VERSION_Z); lua_settable(L, -3);
+ lua_setfield(L, -2, "cmp");
+
+ lua_setfield(L, -2, "version");
+
+ lua_pop(L, 1);
+}
+
int icelua_init(void)
{
int i, argct;
@@ -273,7 +312,7 @@ int icelua_init(void)
icelua_loadbasefuncs(lstate_client);
icelua_loadbasefuncs(lstate_server);
- // shove some pathnames in
+ // shove some pathnames / versions in
if(lstate_server != NULL)
{
lua_getglobal(lstate_server, "common");
@@ -284,7 +323,17 @@ int icelua_init(void)
lua_pushstring(lstate_server, mod_basedir+4);
lua_setfield(lstate_server, -2, "base_dir");
lua_pop(lstate_server, 1);
+
+ icelua_pushversion(lstate_server, "common");
+ icelua_pushversion(lstate_server, "server");
}
+
+ if(lstate_client != NULL)
+ {
+ icelua_pushversion(lstate_client, "common");
+ icelua_pushversion(lstate_client, "client");
+ }
+
/*
NOTE:
to call stuff, use lua_pcall.
diff --git a/src/render.c b/src/render.c
index 562f7cd..8c6e828 100644
--- a/src/render.c
+++ b/src/render.c
@@ -1505,13 +1505,15 @@ void render_pmf_bone(uint32_t *pixels, int width, int height, int pitch, camera_
}
// get correct centre depth
- float max_axis = fabsf(x);
- if(max_axis < fabsf(y))
- max_axis = fabsf(y);
- if(max_axis < fabsf(z))
- max_axis = fabsf(z);
- float dlen = sqrtf(x*x+y*y+z*z);
- float depth = max_axis/dlen;
+ float m = fabsf(x);
+ if(m < fabsf(y))
+ m = fabsf(y);
+ if(m < fabsf(z))
+ m = fabsf(z);
+ //float dlen2 = x*x + y*y + z*z;
+ //float dlen = sqrtf(dlen2);
+ //float depth = sqrtf(2*m*m - dlen2);
+ float depth = m;
// cameranananinate
if(!islocal)
@@ -1524,7 +1526,7 @@ void render_pmf_bone(uint32_t *pixels, int width, int height, int pitch, camera_
y = ny;
z = nz;
}
- depth *= z*rezoom;
+ //depth *= z*rezoom;
// plotinate
render_pmf_box(-x, y, z, depth, pt->radius*scale, color);
diff --git a/src/vecmath.c b/src/vecmath.c
index 2fa42e0..309ef4c 100644
--- a/src/vecmath.c
+++ b/src/vecmath.c
@@ -37,12 +37,12 @@ vec4f_t mtx_apply_vec(matrix_t *mtx, vec4f_t *vec)
vec4f_t ret = {.m = {}}; //c99 + vector extensions, hopefully it optimizes
vec4f_t accum;
- const mask[4] = {0x00,0x55,0xAA,0xFF};
+ const int mask[4] = {0x00,0x55,0xAA,0xFF};
for(i = 0; i < 4; i++)
{
accum.m = vec->m;
- __builtin_ia32_shufps(accum.m, accum.m, mask[i]);
+ _mm_shuffle_ps(accum.m, accum.m, mask[i]);
accum.m *= mtx->c[i].m;
ret.m += accum.m;
}