Compare commits

..
35 Commits
Author SHA1 Message Date
alufolie91 3204b5c3b4 Merge branch 'Saturn-Next' into netstuff 2026-02-23 17:02:32 +01:00
alufolie91 cd02242a01 fix splitscreen clients being unable to join saturn servers
lmao oops idk dumb copy paste sry
2026-02-23 17:02:13 +01:00
alufolie91 e35dc9e097 fix g_in_exiting_signal_handler
every "flag" set by signal handlers must be of type "volatile sig_atomic_t"
everything else may fail to be correctly set, read or get optimized away which rendered this basically useless
2026-02-23 16:20:48 +01:00
alufolie91 f4dc161831 dont let SIGINT/SIGTERM do work in signal handler take 2
the earlier approach still raised the default signal within this, which basically just skipped everything and ended up NOT calling I_Quit at all
Basically this is to ensure we dont call I_Quit at all from a signal handler as it is NOT async safe and can cause serious issues like deadlocks and such, instead SIGINT and SIGTERM will just signal the main loop/thread to safely call I_Quit instead
2026-02-23 16:01:14 +01:00
alufolie91 1d6c27baca lua_pushlstring: prefer luaS_newlstr over luaS_new
the latter calls strlen which is not needed as the empty string has no length
2026-02-22 14:01:27 +01:00
alufolie91 009df228d6 fix memory leak when fetching masterserver rules
strdup returns a malloc´d string!
2026-02-22 13:33:57 +01:00
alufolie91 7746e494cf fix memory leak within http masterserver handling
errbuf gets malloc´d!
2026-02-22 13:33:54 +01:00
alufolie91 90a88983f1 k_hud: make the hud offset vars static 2026-02-22 13:33:49 +01:00
alufolie91 22a4fe63db Fix minimap angle display colour for skins that use non default startcolor
i.e. they use a different colour than "green" to remap their skincolor on
2026-02-22 13:33:46 +01:00
Alug d77508f481 init superactions global
was missed before
2026-02-16 19:27:56 +01:00
Alug 53321d33d5 mark some nightsmode stuff with likely/unlikely i missed
and in some cases move around the conditionals
i love backwards compat Zzz....
2026-02-16 19:27:52 +01:00
Alug 5c28f6afd8 Revert "fix new compiler warnings from new gcc version"
This reverts commit d49001143f.
2026-02-16 19:04:51 +01:00
Alug d49001143f fix new compiler warnings from new gcc version
just throw const at everything :blobthumbsup:
2026-02-11 17:48:16 +01:00
Alug 6cbb8a36cf Merge branch 'Saturn-Next' into netstuff 2026-01-21 20:48:47 +01:00
Gustaf Alhäll bf1aa47854 Simplify textcmd handling 2026-01-09 20:53:15 +01:00
Alug be423b2910 Merge branch 'Saturn-Next' into netstuff 2026-01-08 00:34:19 +01:00
Alug 3bf3bdf641 enable "Wzero-as-null-pointer-constant", fix cases of it
prevent ambiguity and bad practices, i like expressive and "correct" code
shoutout blankart for making me aware this exists
2026-01-08 00:34:15 +01:00
Alug e923777eb6 Acessability: add basic "reducevfx" toggle to disable/reduce certain effects
toggles certain effects, which may be troublesome to some players

-disabled hyudoro flashing, instead makes player translucent
- Makes rainbow colour effects, such as invul, change colours very slowly
- Disables underwater and heatwave screen effects
- Disables palette flashing
- Disables vhs effect

not the most pretty implementation, but im lazy and this works

feel free to suggest more things
2026-01-08 00:33:53 +01:00
Alug cf6eb0010e K_SpawnSparkleTrail: check for blend effect apply outside the loop
tiny optimization
2026-01-08 00:33:50 +01:00
Alug 5184115216 enable "Wzero-as-null-pointer-constant", fix cases of it
prevent ambiguity and bad practices, i like expressive and "correct" code
shoutout blankart for making me aware this exists
2026-01-08 00:33:43 +01:00
Alug 39a46e8f79 Revert "Remove tic provision (vanilla compat edition)"
This reverts commit 4a3c9ccfbb.
2025-12-30 01:09:14 +01:00
Alug d9712cf85e Merge branch 'Saturn-Next' into netstuff 2025-12-27 15:13:50 +01:00
Alug 0691e2d9e2 Merge branch 'Saturn-Next' into netstuff 2025-12-27 13:40:19 +01:00
PAS 08864e27b2 Fix double byte-swap in SV_MakeTic 2025-12-26 21:44:39 +01:00
Alug 4a3c9ccfbb Remove tic provision (vanilla compat edition)
based on https://codeberg.org/srb2classic/srb2classic/commit/7cf14fbe740998c3246dd190904f49a236b2ccec

seems to get rid of some jitter in localhost
2025-12-26 21:44:37 +01:00
Alug cedd789a27 Merge branch 'Saturn-Next' into netstuff 2025-12-26 21:44:34 +01:00
Alug 8f91707164 Merge branch 'Saturn-Next' into netstuff 2025-12-09 18:07:06 +01:00
Alug 37eba186f5 netcode: replace some stuff with memsets + add a little bounds safety in some places 2025-12-09 18:07:02 +01:00
Alug 7eb2ad1e35 slightly cleanup SV_AddWaitingPlayers 2025-12-02 23:23:41 +01:00
Alug f49e57a38c d_cliserv: Cleanup PT_ClientJoin
move refuse message handling into its own function
2025-12-02 23:23:38 +01:00
Alug 265f4a50ef readd check for node before SV_SendSaveGame
Apparently in some cases the server will connect to itself, in this case the server tries to send itself the savegame, leading to a crash in some cases. oops
2025-12-02 23:23:36 +01:00
Alug e83e2659a7 reorder packets again 2025-12-02 23:23:29 +01:00
Alug c680dd3222 fix some packet types not being correctly handled 2025-12-02 23:23:15 +01:00
Alug 96aaaf5261 merge SendNameAndColor & SendWeaponPref
TODO: make a bunch of player specific cvars arrays for splitscreen handling

- also cleanup some strlen usage
2025-12-02 23:23:07 +01:00
Alug efb29e6be5 d_cliserv: do some cleanups
- expose SAVEGAMESIZE
- pass node number to SV_AddWaitingPlayers (saves iterating through all 128 net nodes everytime a player joins) lifted from RR
- move all packet handling to the packet handlers
- Reorder packethandling switches a little, so common/important packets get checked first
- fix wrong clamp for realfirsttic that was too early
- add nowtime division by NEWTICRATERATIO (no change unless ticrate changes)
2025-12-02 23:23:02 +01:00
44 changed files with 769 additions and 1305 deletions

No files matched your search

+18 -42
View File
@@ -434,7 +434,7 @@ LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
lua_lock(L); lua_lock(L);
luaC_checkGC(L); luaC_checkGC(L);
setsvalue2s(L, L->top, (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len)); setsvalue2s(L, L->top, (len == 0) ? luaS_newlstr(L, "", 0) : luaS_newlstr(L, s, len));
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
} }
@@ -519,23 +519,6 @@ LUA_API int lua_pushthread (lua_State *L) {
** get functions (Lua -> stack) ** get functions (Lua -> stack)
*/ */
static void auxgetstr (lua_State *L, const TValue *t, const char *k) {
const TValue *slot;
TValue key;
TString *str = luaS_new(L, k);
api_checkvalidindex(L, t);
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
setobj2s(L, L->top, slot);
api_incr_top(L);
}
else {
setsvalue(L, &key, str);
luaV_finishget(L, t, L->top, L->top, slot);
api_incr_top(L);
}
lua_unlock(L);
}
LUA_API void lua_gettable (lua_State *L, int idx) { LUA_API void lua_gettable (lua_State *L, int idx) {
StkId t; StkId t;
@@ -548,8 +531,15 @@ LUA_API void lua_gettable (lua_State *L, int idx) {
LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
StkId t;
TValue key;
lua_lock(L); lua_lock(L);
auxgetstr(L, index2adr(L, idx), k); t = index2adr(L, idx);
api_checkvalidindex(L, t);
setsvalue(L, &key, luaS_new(L, k));
luaV_gettable(L, t, &key, L->top);
api_incr_top(L);
lua_unlock(L);
} }
@@ -640,26 +630,6 @@ LUA_API void lua_getfenv (lua_State *L, int idx) {
** set functions (stack -> Lua) ** set functions (stack -> Lua)
*/ */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
TValue key;
const TValue *slot;
TString *str = luaS_new(L, k);
api_checknelems(L, 1);
api_checkvalidindex(L, t);
if (luaV_fastset(L, t, str, slot, luaH_setstr, L->top)) {
setobj2t(L, cast(TValue *, slot), L->top - 1);
L->top--; /* pop value */
}
else {
setsvalue2s(L, &key, str);
luaV_finishset(L, t, &key, L->top - 1, slot);
L->top--; /* pop value */
}
lua_unlock(L);
}
LUA_API void lua_settable (lua_State *L, int idx) { LUA_API void lua_settable (lua_State *L, int idx) {
StkId t; StkId t;
@@ -672,12 +642,18 @@ LUA_API void lua_settable (lua_State *L, int idx) {
lua_unlock(L); lua_unlock(L);
} }
#pragma GCC diagnostic pop
LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
StkId t;
TValue key;
lua_lock(L); lua_lock(L);
auxsetstr(L, index2adr(L, idx), k); api_checknelems(L, 1);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
setsvalue(L, &key, luaS_new(L, k));
luaV_settable(L, t, &key, L->top - 1);
L->top--; /* pop value */
lua_unlock(L);
} }
+3 -15
View File
@@ -20,7 +20,6 @@
#define lauxlib_c #define lauxlib_c
#define LUA_LIB #define LUA_LIB
#include "ldebug.h"
#include "lua.h" #include "lua.h"
#include "lauxlib.h" #include "lauxlib.h"
@@ -469,19 +468,8 @@ LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
while (l) { while (l--)
size_t space = bufffree(B); luaL_addchar(B, *s++);
if (space == 0) {
luaL_prepbuffer(B);
lua_assert(bufffree(B) == LUAL_BUFFERSIZE);
space = LUAL_BUFFERSIZE;
}
if (space > l) space = l;
memcpy(B->p, s, space);
B->p += space;
s += space;
l -= space;
}
} }
@@ -698,6 +686,6 @@ static int panic (lua_State *L) {
LUALIB_API lua_State *luaL_newstate (void) { LUALIB_API lua_State *luaL_newstate (void) {
lua_State *L = lua_newstate(l_alloc, NULL); lua_State *L = lua_newstate(l_alloc, NULL);
if (l_likely(L)) lua_atpanic(L, &panic); if (L) lua_atpanic(L, &panic);
return L; return L;
} }
+12 -25
View File
@@ -626,20 +626,8 @@ static void codenot (FuncState *fs, expdesc *e) {
removevalues(fs, e->t); removevalues(fs, e->t);
} }
/*
** Check whether expression 'e' is a literal string
*/
static int isKstr (FuncState *fs, expdesc *e) {
return (e->k == VK && ttisstring(&fs->f->k[e->u.s.info]));
}
/*
** Create expression 't[k]'. 't' must have its final result already in a
** register or upvalue. Upvalues can only be indexed by literal strings.
*/
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non string? */
luaK_exp2anyreg(fs, t); /* put it in a register */
t->u.s.aux = luaK_exp2RK(fs, k); t->u.s.aux = luaK_exp2RK(fs, k);
t->k = VINDEXED; t->k = VINDEXED;
} }
@@ -802,19 +790,18 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
case OPR_BXOR: codearith(fs, OP_BXOR, e1, e2); break; case OPR_BXOR: codearith(fs, OP_BXOR, e1, e2); break;
case OPR_BSHL: codearith(fs, OP_BSHL, e1, e2); break; case OPR_BSHL: codearith(fs, OP_BSHL, e1, e2); break;
case OPR_BSHR: codearith(fs, OP_BSHR, e1, e2); break; case OPR_BSHR: codearith(fs, OP_BSHR, e1, e2); break;
case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
case OPR_MOD: case OPR_POW: { case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
codearith(fs, op - OPR_ADD + OP_ADD, e1, e2); case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
break; case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
} case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
case OPR_EQ: case OPR_LT: case OPR_LE: { case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
codecomp(fs, op - OPR_EQ + OP_EQ, 1, e1, e2); case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
break; case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
} case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
case OPR_NE: case OPR_GT: case OPR_GE: { case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
codecomp(fs, op - OPR_NE + OP_EQ, 0, e1, e2); case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
break; case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
}
default: lua_assert(0); default: lua_assert(0);
} }
} }
+3 -3
View File
@@ -21,13 +21,13 @@
/* /*
** grep "ORDER OPR" if you change these enums (ORDER OP) ** grep "ORDER OPR" if you change these enums
*/ */
typedef enum BinOpr { typedef enum BinOpr {
OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
OPR_CONCAT, OPR_CONCAT,
OPR_EQ, OPR_LT, OPR_LE, OPR_NE, OPR_EQ,
OPR_NE, OPR_GT, OPR_GE, OPR_LT, OPR_LE, OPR_GT, OPR_GE,
OPR_AND, OPR_OR, OPR_AND, OPR_OR,
OPR_BAND, OPR_BOR, OPR_BXOR, OPR_BAND, OPR_BOR, OPR_BXOR,
OPR_BSHL, OPR_BSHR, OPR_BSHL, OPR_BSHR,
+5 -28
View File
@@ -542,39 +542,16 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
TMS tm = 0;
Instruction i; Instruction i;
if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
return NULL; /* calling function is not Lua (or is unknown) */ return NULL; /* calling function is not Lua (or is unknown) */
ci--; /* calling function */ ci--; /* calling function */
i = ci_func(ci)->l.p->code[currentpc(L, ci)]; i = ci_func(ci)->l.p->code[currentpc(L, ci)];
switch (GET_OPCODE(i)) { if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
case OP_CALL: GET_OPCODE(i) == OP_TFORLOOP)
case OP_TAILCALL: return getobjname(L, ci, GETARG_A(i), name);
case OP_TFORLOOP: else
return getobjname(L, ci, GETARG_A(i), name); return NULL; /* no useful name can be found */
case OP_GETGLOBAL:
case OP_SELF:
case OP_GETTABLE: tm = TM_INDEX; break;
case OP_SETGLOBAL:
case OP_SETTABLE: tm = TM_NEWINDEX; break;
case OP_EQ: tm = TM_EQ; break;
case OP_ADD: tm = TM_ADD; break;
case OP_SUB: tm = TM_SUB; break;
case OP_MUL: tm = TM_MUL; break;
case OP_DIV: tm = TM_DIV; break;
case OP_MOD: tm = TM_MOD; break;
case OP_POW: tm = TM_POW; break;
case OP_UNM: tm = TM_UNM; break;
case OP_LEN: tm = TM_LEN; break;
case OP_LT: tm = TM_LT; break;
case OP_LE: tm = TM_LE; break;
case OP_CONCAT: tm = TM_CONCAT; break;
default:
return NULL; /* else no useful name can be found */
}
*name = getstr(G(L)->tmname[tm]);
return "metamethod";
} }
+2 -2
View File
@@ -164,7 +164,7 @@ void luaD_reallocCI (lua_State *L, int newsize) {
void luaD_growstack (lua_State *L, int n) { void luaD_growstack (lua_State *L, int n) {
if (n <= L->stacksize) /* double size is enough? */ if (l_likely(n <= L->stacksize)) /* double size is enough? */
luaD_reallocstack(L, 2*L->stacksize); luaD_reallocstack(L, 2*L->stacksize);
else else
luaD_reallocstack(L, L->stacksize + n); luaD_reallocstack(L, L->stacksize + n);
@@ -318,7 +318,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
ci->top = L->top + LUA_MINSTACK; ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last); lua_assert(ci->top <= L->stack_last);
ci->nresults = nresults; ci->nresults = nresults;
if (l_unlikely(L->hookmask & LUA_MASKCALL)) if (L->hookmask & LUA_MASKCALL)
luaD_callhook(L, LUA_HOOKCALL, -1); luaD_callhook(L, LUA_HOOKCALL, -1);
lua_unlock(L); lua_unlock(L);
n = (*curr_func(L)->c.f)(L); /* do the actual call */ n = (*curr_func(L)->c.f)(L); /* do the actual call */
+9 -10
View File
@@ -356,21 +356,20 @@ static int read_line (lua_State *L, FILE *f) {
static int read_chars (lua_State *L, FILE *f, size_t n) { static int read_chars (lua_State *L, FILE *f, size_t n) {
size_t tbr = n; /* number of chars to be read */ size_t rlen; /* how much to read */
size_t rlen; /* how much to read in each cycle */ size_t nr; /* number of chars actually read */
size_t nr; /* number of chars actually read in each cycle */
luaL_Buffer b; luaL_Buffer b;
luaL_buffinit(L, &b); luaL_buffinit(L, &b);
rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
do { do {
char *p = luaL_prepbuffer(&b); char *p = luaL_prepbuffer(&b);
if (rlen > tbr) rlen = tbr; /* cannot read more than asked */ if (rlen > n) rlen = n; /* cannot read more than asked */
nr = fread(p, sizeof(char), rlen, f); nr = fread(p, sizeof(char), rlen, f);
luaL_addsize(&b, nr); luaL_addsize(&b, nr);
tbr -= nr; /* still have to read 'tbr' chars */ n -= nr; /* still have to read `n' chars */
} while (tbr > 0 && nr == rlen); /* until end of count or eof */ } while (n > 0 && nr == rlen); /* until end of count or eof */
luaL_pushresult(&b); /* close buffer */ luaL_pushresult(&b); /* close buffer */
return (tbr == 0 || tbr < n); /* true iff read something */ return (n == 0 || lua_objlen(L, -1) > 0);
} }
@@ -433,13 +432,13 @@ static int f_read (lua_State *L) {
static int io_readline (lua_State *L) { static int io_readline (lua_State *L) {
FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
int success; int sucess;
if (f == NULL) /* file is already closed? */ if (f == NULL) /* file is already closed? */
luaL_error(L, "file is already closed"); luaL_error(L, "file is already closed");
success = read_line(L, f); sucess = read_line(L, f);
if (ferror(f)) if (ferror(f))
return luaL_error(L, "%s", strerror(errno)); return luaL_error(L, "%s", strerror(errno));
if (success) return 1; if (sucess) return 1;
else { /* EOF */ else { /* EOF */
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
lua_settop(L, 0); lua_settop(L, 0);
-2
View File
@@ -232,8 +232,6 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
(*) In OP_SETLIST, if (B == 0) then B = `top'; (*) In OP_SETLIST, if (B == 0) then B = `top';
if (C == 0) then next `instruction' is real C if (C == 0) then next `instruction' is real C
(*) In OP_SELF, the index must be a string.
(*) For comparisons, A specifies what condition the test should accept (*) For comparisons, A specifies what condition the test should accept
(true or false). (true or false).
+4 -4
View File
@@ -881,10 +881,10 @@ static const struct {
lu_byte right; /* right priority */ lu_byte right; /* right priority */
} priority[] = { /* ORDER OPR */ } priority[] = { /* ORDER OPR */
{6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
{10, 9}, {5, 4}, /* ^, .. (right associative) */ {10, 9}, {5, 4}, /* power and concat (right associative) */
{3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ {3, 3}, {3, 3}, /* equality and inequality */
{3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
{2, 2}, {1, 1} /* and, or */ {2, 2}, {1, 1} /* logical (and/or) */
,{6, 6}, {6, 6}, {6, 6}, /* bit-wise (band/bor/bxor) */ ,{6, 6}, {6, 6}, {6, 6}, /* bit-wise (band/bor/bxor) */
{7, 7}, {7, 7} /* shl/shr */ {7, 7}, {7, 7} /* shl/shr */
}; };
+4 -58
View File
@@ -51,7 +51,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
unsigned int h) { unsigned int h) {
TString *ts; TString *ts;
stringtable *tb; stringtable *tb;
if (l_unlikely(l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))) if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
luaM_toobig(L); luaM_toobig(L);
ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
ts->tsv.len = l; ts->tsv.len = l;
@@ -72,72 +72,18 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
} }
// string hash taken from luaJIT TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
GCObject *o;
/* Unaligned load of uint32_t. */
static inline __attribute__((always_inline)) uint32_t getu32(const void* ptr)
{
uint32_t result;
memcpy(&result, ptr, 4);
return result;
}
// smol macro to look a little less messy lul
#define getu8(p) *cast(const uint8_t *, p)
/* Keyed sparse ARX string hash. Constant time. */
static unsigned hash_sparse(const char *str, size_t len)
{
/* Constants taken from lookup3 hash by Bob Jenkins. */
unsigned int a, b, h = cast(unsigned int, len);
#define rol(x, n) (((x)<<(n)) | ((x)>>(-cast(int, n)&(8*sizeof(x)-1))))
if (len >= 4) { /* Caveat: unaligned access! */
a = getu32(str);
h ^= getu32(str+len-4);
b = getu32(str+(len>>1)-2);
h ^= b; h -= rol(b, 14);
b += getu32(str+(len>>2)-1);
} else if (len > 0) {
a = getu8(str);
h ^= getu8(str+len-1);
b = getu8(str+(len>>1));
h ^= b; h -= rol(b, 14);
} else {
return 0;
}
a ^= h; a -= rol(h, 11);
b ^= a; b -= rol(a, 25);
h ^= b; h -= rol(b, 16);
#undef rol
return h;
}
#undef getu8
static inline __attribute__((always_inline)) unsigned luaS_hash (const char *str, size_t l) {
#if 0
unsigned int h = cast(unsigned int, l); /* seed */ unsigned int h = cast(unsigned int, l); /* seed */
size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
size_t l1; size_t l1;
for (l1=l; l1>=step; l1-=step) /* compute hash */ for (l1=l; l1>=step; l1-=step) /* compute hash */
h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
return h;
#else
return hash_sparse(str, l);
#endif
}
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
GCObject *o;
unsigned int h = luaS_hash(str, l);
for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
o != NULL; o != NULL;
o = o->gch.next) { o = o->gch.next) {
TString *ts = rawgco2ts(o); TString *ts = rawgco2ts(o);
if (ts->tsv.hash == h && if (l_unlikely(ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0))) {
ts->tsv.len == l &&
(memcmp(str, getstr(ts), l) == 0)) {
/* string may be dead */ /* string may be dead */
if (isdead(G(L), o)) changewhite(o); if (isdead(G(L), o)) changewhite(o);
return ts; return ts;
+1 -1
View File
@@ -61,7 +61,7 @@ TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
} }
TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { TValue *luaT_gettmbyobj (lua_State *L, TValue *o, TMS event) {
Table *mt; Table *mt;
switch (ttype(o)) { switch (ttype(o)) {
case LUA_TTABLE: case LUA_TTABLE:
+1 -1
View File
@@ -55,7 +55,7 @@ LUAI_DATA const char *const luaT_typenames[];
LUAI_FUNC TValue *luaT_gettm (Table *events, TMS event, TString *ename); LUAI_FUNC TValue *luaT_gettm (Table *events, TMS event, TString *ename);
LUAI_FUNC TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event); LUAI_FUNC TValue *luaT_gettmbyobj (lua_State *L, TValue *o, TMS event);
LUAI_FUNC void luaT_init (lua_State *L); LUAI_FUNC void luaT_init (lua_State *L);
#endif #endif
+54 -145
View File
@@ -28,7 +28,7 @@
/* limit for table tag-method chains (to avoid infinite loops) */ /* limit for table tag-method chains (to avoid loops) */
#define MAXTAGLOOP 100 #define MAXTAGLOOP 100
@@ -105,94 +105,61 @@ static void callTM (lua_State *L, const TValue *f, const TValue *p1,
} }
/* void luaV_gettable (lua_State *L, TValue *t, TValue *key, StkId val) {
** Finish the table access 'val = t[key]'. int loop;
** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
** t[k] entry (which must be nil).
*/
void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
const TValue *slot) {
int loop; /* counter to avoid infinite loops */
const TValue *tm; /* metamethod */
for (loop = 0; loop < MAXTAGLOOP; loop++) { for (loop = 0; loop < MAXTAGLOOP; loop++) {
if (slot == NULL) { /* 't' is not a table? */ TValue *tm;
lua_assert(!ttistable(t)); if (ttistable(t)) { /* `t' is a table? */
tm = luaT_gettmbyobj(L, t, TM_INDEX); Table *h = hvalue(t);
if (l_unlikely(ttisnil(tm))) const TValue *res = luaH_get(h, key); /* do a primitive get */
luaG_typeerror(L, t, "index"); /* no metamethod */ if (!ttisnil(res) || /* result is no nil? */
/* else will try the metamethod */ (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
} setobj2s(L, val, res);
else { /* 't' is a table */
lua_assert(ttisnil(slot));
tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
if (tm == NULL) { /* no metamethod? */
setnilvalue(val); /* result is nil */
return; return;
} }
/* else will try the metamethod */ /* else will try the tag method */
} }
if (ttisfunction(tm)) { /* is metamethod a function? */ else if (l_unlikely(ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))))
callTMres(L, val, tm, t, key); /* call it */ luaG_typeerror(L, t, "index");
if (ttisfunction(tm)) {
callTMres(L, val, tm, t, key);
return; return;
} }
t = tm; /* else try to access 'tm[key]' */ t = tm; /* else repeat with `tm' */
if (luaV_fastget(L,t,key,slot,luaH_get)) { /* fast track? */
setobj2s(L, val, slot); /* done */
return;
}
/* else repeat (tail call 'luaV_finishget') */
} }
luaG_runerror(L, "'__index' chain too long; possible loop"); luaG_runerror(L, "loop in gettable");
} }
/*
** Finish a table assignment 't[key] = val'. void luaV_settable (lua_State *L, TValue *t, TValue *key, StkId val) {
** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points int loop;
** to the entry 't[key]', or to 'luaO_nilobject' if there is no such
** entry. (The value at 'slot' must be nil, otherwise 'luaV_fastset'
** would have done the job.)
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
StkId val, const TValue *slot) {
int loop; /* counter to avoid infinite loops */
for (loop = 0; loop < MAXTAGLOOP; loop++) { for (loop = 0; loop < MAXTAGLOOP; loop++) {
const TValue *tm; TValue *tm = NULL;
if (slot != NULL) { if (ttistable(t)) { /* `t' is a table? */
lua_assert(ttistable(t) && ttisnil(slot));
Table *h = hvalue(t); Table *h = hvalue(t);
/* must check the metamethod */ TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
/* slot is nil=> look for newindex, slot is not nil => look for usedindex */ /* oldval is nil=> look for newindex, oldval is not nil => look for usedindex */
if (!((ttisnil(slot) && ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) != NULL)) || if (!((ttisnil(oldval) && ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) != NULL)) ||
((!ttisnil(slot)) && ((tm = fasttm(L, h->metatable, TM_USEDINDEX)) != NULL)))) { ((!ttisnil(oldval)) && ((tm = fasttm(L, h->metatable, TM_USEDINDEX)) != NULL)))) {
/* no metamethod and (now) there is an entry with given key */ setobj2t(L, oldval, val);
setobj2t(L, cast(TValue *, slot), val);
luaC_barriert(L, h, val); luaC_barriert(L, h, val);
return; return;
} }
/* else will try the metamethod */ /* else will try the tag method */
} }
else { /* not a table; check metamethod */ else if (l_unlikely(ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))))
if (l_unlikely(ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))) luaG_typeerror(L, t, "index");
luaG_typeerror(L, t, "index");
}
/* try the metamethod */
if (ttisfunction(tm)) { if (ttisfunction(tm)) {
callTM(L, tm, t, key, val); callTM(L, tm, t, key, val);
return; return;
} }
t = tm; /* else repeat assignment over 'tm' */ t = tm; /* else repeat with `tm' */
if (luaV_fastset(L, t, key, slot, luaH_set, val))
return; /* done */
/* else loop */
} }
luaG_runerror(L, "settable chain too long; possible loop"); luaG_runerror(L, "loop in settable");
} }
#pragma GCC diagnostic pop
static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, static int call_binTM (lua_State *L, TValue *p1, TValue *p2,
StkId res, TMS event) { StkId res, TMS event) {
const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
if (ttisnil(tm)) if (ttisnil(tm))
@@ -217,7 +184,7 @@ static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
} }
static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, static int call_orderTM (lua_State *L, TValue *p1, TValue *p2,
TMS event) { TMS event) {
const TValue *tm1 = luaT_gettmbyobj(L, p1, event); const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
const TValue *tm2; const TValue *tm2;
@@ -399,7 +366,6 @@ static void Arith (lua_State *L, StkId ra, TValue *rb,
#define arith_op(op,tm) { \ #define arith_op(op,tm) { \
StkId ra = RA(i); \
TValue *rb = RKB(i); \ TValue *rb = RKB(i); \
TValue *rc = RKC(i); \ TValue *rc = RKC(i); \
if (ttisnumber(rb) && ttisnumber(rc)) { \ if (ttisnumber(rb) && ttisnumber(rc)) { \
@@ -411,24 +377,6 @@ static void Arith (lua_State *L, StkId ra, TValue *rb,
} }
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
/*
** copy of 'luaV_gettable', but protecting call to potential metamethod
** (which can reallocate the stack)
*/
#define gettableProtected(L,t,k,v) { const TValue *slot; \
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
else Protect(luaV_finishget(L,t,k,v,slot)); }
/* same for 'luaV_settable' */
#define settableProtected(L,t,k,v) { const TValue *slot; \
if (!luaV_fastset(L,t,k,slot,luaH_set,v)) \
Protect(luaV_finishset(L,t,k,v,slot)); }
void luaV_execute (lua_State *L, int nexeccalls) { void luaV_execute (lua_State *L, int nexeccalls) {
LClosure *cl; LClosure *cl;
@@ -438,12 +386,13 @@ void luaV_execute (lua_State *L, int nexeccalls) {
reentry: /* entry point */ reentry: /* entry point */
lua_assert(isLua(L->ci)); lua_assert(isLua(L->ci));
pc = L->savedpc; pc = L->savedpc;
cl = &clvalue(L->ci->func)->l; /* local reference to function's closure */ cl = &clvalue(L->ci->func)->l;
k = cl->p->k; /* local reference to function's constant table */ base = L->base;
base = L->base; /* local copy of function's base */ k = cl->p->k;
/* main loop of interpreter */ /* main loop of interpreter */
for (;;) { for (;;) {
const Instruction i = *pc++; const Instruction i = *pc++;
StkId ra;
if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
(--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
traceexec(L, pc); traceexec(L, pc);
@@ -453,28 +402,26 @@ void luaV_execute (lua_State *L, int nexeccalls) {
} }
base = L->base; base = L->base;
} }
/* warning!! several calls may realloc the stack and invalidate `ra' */
ra = RA(i);
lua_assert(base == L->base && L->base == L->ci->base); lua_assert(base == L->base && L->base == L->ci->base);
lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
switch (GET_OPCODE(i)) { switch (GET_OPCODE(i)) {
case OP_MOVE: { case OP_MOVE: {
StkId ra = RA(i);
setobjs2s(L, ra, RB(i)); setobjs2s(L, ra, RB(i));
continue; continue;
} }
case OP_LOADK: { case OP_LOADK: {
StkId ra = RA(i);
setobj2s(L, ra, KBx(i)); setobj2s(L, ra, KBx(i));
continue; continue;
} }
case OP_LOADBOOL: { case OP_LOADBOOL: {
StkId ra = RA(i);
setbvalue(ra, GETARG_B(i)); setbvalue(ra, GETARG_B(i));
if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
continue; continue;
} }
case OP_LOADNIL: { case OP_LOADNIL: {
StkId ra = RA(i);
TValue *rb = RB(i); TValue *rb = RB(i);
do { do {
setnilvalue(rb--); setnilvalue(rb--);
@@ -482,13 +429,11 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_GETUPVAL: { case OP_GETUPVAL: {
StkId ra = RA(i);
int b = GETARG_B(i); int b = GETARG_B(i);
setobj2s(L, ra, cl->upvals[b]->v); setobj2s(L, ra, cl->upvals[b]->v);
continue; continue;
} }
case OP_GETGLOBAL: { case OP_GETGLOBAL: {
StkId ra = RA(i);
TValue g; TValue g;
TValue *rb = KBx(i); TValue *rb = KBx(i);
sethvalue(L, &g, cl->env); sethvalue(L, &g, cl->env);
@@ -497,14 +442,10 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_GETTABLE: { case OP_GETTABLE: {
StkId ra = RA(i); Protect(luaV_gettable(L, RB(i), RKC(i), ra));
StkId rb = RB(i);
TValue *rc = RKC(i);
gettableProtected(L, rb, rc, ra);
continue; continue;
} }
case OP_SETGLOBAL: { case OP_SETGLOBAL: {
StkId ra = RA(i);
TValue g; TValue g;
sethvalue(L, &g, cl->env); sethvalue(L, &g, cl->env);
lua_assert(ttisstring(KBx(i))); lua_assert(ttisstring(KBx(i)));
@@ -512,21 +453,16 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_SETUPVAL: { case OP_SETUPVAL: {
StkId ra = RA(i);
UpVal *uv = cl->upvals[GETARG_B(i)]; UpVal *uv = cl->upvals[GETARG_B(i)];
setobj(L, uv->v, ra); setobj(L, uv->v, ra);
luaC_barrier(L, uv, ra); luaC_barrier(L, uv, ra);
continue; continue;
} }
case OP_SETTABLE: { case OP_SETTABLE: {
StkId ra = RA(i); Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
TValue *rb = RKB(i);
TValue *rc = RKC(i);
settableProtected(L, ra, rb, rc);
continue; continue;
} }
case OP_NEWTABLE: { case OP_NEWTABLE: {
StkId ra = RA(i);
int b = GETARG_B(i); int b = GETARG_B(i);
int c = GETARG_C(i); int c = GETARG_C(i);
sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
@@ -534,16 +470,9 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_SELF: { case OP_SELF: {
StkId ra = RA(i);
const TValue *slot;
StkId rb = RB(i); StkId rb = RB(i);
TValue *rc = RKC(i); setobjs2s(L, ra+1, rb);
TString *key = rawtsvalue(rc); /* key must be a string */ Protect(luaV_gettable(L, rb, RKC(i), ra));
setobjs2s(L, ra + 1, rb);
if (luaV_fastget(L, rb, key, slot, luaH_getstr)) {
setobj2s(L, ra, slot);
}
else Protect(luaV_finishget(L, rb, rc, ra, slot));
continue; continue;
} }
case OP_ADD: { case OP_ADD: {
@@ -559,7 +488,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_DIV: { case OP_DIV: {
StkId ra = RA(i);
TValue *rb = RKB(i); TValue *rb = RKB(i);
TValue *rc = RKC(i); TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) { if (ttisnumber(rb) && ttisnumber(rc)) {
@@ -575,7 +503,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_MOD: { case OP_MOD: {
StkId ra = RA(i);
TValue *rb = RKB(i); TValue *rb = RKB(i);
TValue *rc = RKC(i); TValue *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) { if (ttisnumber(rb) && ttisnumber(rc)) {
@@ -595,27 +522,26 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_BAND: { case OP_BAND: {
arith_op(luai_numand, TM_AND); arith_op(luai_numand, TM_AND);
continue; continue;
} }
case OP_BOR: { case OP_BOR: {
arith_op(luai_numor, TM_OR); arith_op(luai_numor, TM_OR);
continue; continue;
} }
case OP_BXOR: { case OP_BXOR: {
arith_op(luai_numxor, TM_XOR); arith_op(luai_numxor, TM_XOR);
continue; continue;
} }
case OP_BSHL: { case OP_BSHL: {
arith_op(luai_numshl, TM_SHL); arith_op(luai_numshl, TM_SHL);
continue; continue;
} }
case OP_BSHR: { case OP_BSHR: {
arith_op(luai_numshr, TM_SHR); arith_op(luai_numshr, TM_SHR);
continue; continue;
} }
case OP_BNOT: { case OP_BNOT: {
StkId ra = RA(i);
TValue *rb = RB(i); TValue *rb = RB(i);
if (ttisnumber(rb)) { if (ttisnumber(rb)) {
lua_Number nb = nvalue(rb); lua_Number nb = nvalue(rb);
@@ -627,7 +553,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_UNM: { case OP_UNM: {
StkId ra = RA(i);
TValue *rb = RB(i); TValue *rb = RB(i);
if (ttisnumber(rb)) { if (ttisnumber(rb)) {
lua_Number nb = nvalue(rb); lua_Number nb = nvalue(rb);
@@ -639,13 +564,11 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_NOT: { case OP_NOT: {
StkId ra = RA(i);
int res = l_isfalse(RB(i)); /* next assignment may change this value */ int res = l_isfalse(RB(i)); /* next assignment may change this value */
setbvalue(ra, res); setbvalue(ra, res);
continue; continue;
} }
case OP_LEN: { case OP_LEN: {
StkId ra = RA(i);
TValue *rb = RB(i); TValue *rb = RB(i);
switch (ttype(rb)) { switch (ttype(rb)) {
case LUA_TTABLE: { case LUA_TTABLE: {
@@ -703,14 +626,12 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_TEST: { case OP_TEST: {
StkId ra = RA(i);
if (l_isfalse(ra) != GETARG_C(i)) if (l_isfalse(ra) != GETARG_C(i))
dojump(L, pc, GETARG_sBx(*pc)); dojump(L, pc, GETARG_sBx(*pc));
pc++; pc++;
continue; continue;
} }
case OP_TESTSET: { case OP_TESTSET: {
StkId ra = RA(i);
TValue *rb = RB(i); TValue *rb = RB(i);
if (l_isfalse(rb) != GETARG_C(i)) { if (l_isfalse(rb) != GETARG_C(i)) {
setobjs2s(L, ra, rb); setobjs2s(L, ra, rb);
@@ -720,7 +641,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_CALL: { case OP_CALL: {
StkId ra = RA(i);
int b = GETARG_B(i); int b = GETARG_B(i);
int nresults = GETARG_C(i) - 1; int nresults = GETARG_C(i) - 1;
if (b != 0) L->top = ra+b; /* else previous instruction set top */ if (b != 0) L->top = ra+b; /* else previous instruction set top */
@@ -742,7 +662,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
} }
} }
case OP_TAILCALL: { case OP_TAILCALL: {
StkId ra = RA(i);
int b = GETARG_B(i); int b = GETARG_B(i);
if (b != 0) L->top = ra+b; /* else previous instruction set top */ if (b != 0) L->top = ra+b; /* else previous instruction set top */
L->savedpc = pc; L->savedpc = pc;
@@ -775,7 +694,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
} }
} }
case OP_RETURN: { case OP_RETURN: {
StkId ra = RA(i);
int b = GETARG_B(i); int b = GETARG_B(i);
if (b != 0) L->top = ra+b-1; if (b != 0) L->top = ra+b-1;
if (L->openupval) luaF_close(L, base); if (L->openupval) luaF_close(L, base);
@@ -791,7 +709,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
} }
} }
case OP_FORLOOP: { case OP_FORLOOP: {
StkId ra = RA(i);
lua_Number step = nvalue(ra+2); lua_Number step = nvalue(ra+2);
lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
lua_Number limit = nvalue(ra+1); lua_Number limit = nvalue(ra+1);
@@ -804,7 +721,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_FORPREP: { case OP_FORPREP: {
StkId ra = RA(i);
const TValue *init = ra; const TValue *init = ra;
const TValue *plimit = ra+1; const TValue *plimit = ra+1;
const TValue *pstep = ra+2; const TValue *pstep = ra+2;
@@ -821,7 +737,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_TFORLOOP: { case OP_TFORLOOP: {
StkId ra = RA(i);
StkId cb = ra + 3; /* call base */ StkId cb = ra + 3; /* call base */
setobjs2s(L, cb+2, ra+2); setobjs2s(L, cb+2, ra+2);
setobjs2s(L, cb+1, ra+1); setobjs2s(L, cb+1, ra+1);
@@ -838,7 +753,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_SETLIST: { case OP_SETLIST: {
StkId ra = RA(i);
int n = GETARG_B(i); int n = GETARG_B(i);
int c = GETARG_C(i); int c = GETARG_C(i);
int last; int last;
@@ -861,12 +775,10 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_CLOSE: { case OP_CLOSE: {
StkId ra = RA(i);
luaF_close(L, ra); luaF_close(L, ra);
continue; continue;
} }
case OP_CLOSURE: { case OP_CLOSURE: {
StkId ra = RA(i);
Proto *p; Proto *p;
Closure *ncl; Closure *ncl;
int nup, j; int nup, j;
@@ -887,7 +799,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue; continue;
} }
case OP_VARARG: { case OP_VARARG: {
StkId ra = RA(i);
int b = GETARG_B(i) - 1; int b = GETARG_B(i) - 1;
int j; int j;
CallInfo *ci = L->ci; CallInfo *ci = L->ci;
@@ -911,5 +822,3 @@ void luaV_execute (lua_State *L, int nexeccalls) {
} }
} }
} }
#pragma GCC diagnostic pop
+4 -51
View File
@@ -22,61 +22,14 @@
(ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
/*
** fast track for 'gettable': if 't' is a table and 't[k]' is not nil,
** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise,
** return 0 (meaning it will have to check metamethod) with 'slot'
** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise).
** 'f' is the raw get function to use.
*/
#define luaV_fastget(L,t,k,slot,f) \
(!ttistable(t) \
? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
: (slot = f(hvalue(t), k), /* else, do raw access */ \
!ttisnil(slot))) /* result not nil? */
/*
** standard implementation for 'gettable'
*/
#define luaV_gettable(L,t,k,v) { const TValue *slot; \
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
else luaV_finishget(L,t,k,v,slot); }
/*
** Fast track for set table. If 't' is a table and 't[k]' is not nil,
** call GC barrier, do a raw 't[k]=v', and return true; otherwise,
** return false with 'slot' equal to NULL (if 't' is not a table) or
** 'nil'. (This is needed by 'luaV_finishget'.) Note that, if the macro
** returns true, there is no need to 'invalidateTMcache', because the
** call is not creating a new entry.
*/
#define luaV_fastset(L,t,k,slot,f,v) \
(!ttistable(t) \
? (slot = NULL, 0) \
: (slot = f(L, hvalue(t), k), \
ttisnil(slot) ? 0 \
: (__extension__ ({ \
if (valiswhite(v) && isblack(obj2gco(hvalue(t)))) \
luaC_barrierback(L, hvalue(t)); \
setobj2t(L, cast(TValue *,slot), v); \
1; \
}))))
#define luaV_settable(L,t,k,v) { const TValue *slot; \
if (!luaV_fastset(L,t,k,slot,luaH_set,v)) \
luaV_finishset(L,t,k,v,slot); }
LUAI_FUNC int luaV_lessthan (lua_State *L, TValue *l, TValue *r); LUAI_FUNC int luaV_lessthan (lua_State *L, TValue *l, TValue *r);
LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, LUAI_FUNC void luaV_gettable (lua_State *L, TValue *t, TValue *key,
StkId val, const TValue *tm); StkId val);
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, LUAI_FUNC void luaV_settable (lua_State *L, TValue *t, TValue *key,
StkId val, const TValue *oldval); StkId val);
LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
+1 -1
View File
@@ -1178,7 +1178,7 @@ consvar_t *CV_FindVar(const char *name)
consvar_t *cvar; consvar_t *cvar;
for (cvar = consvar_vars; cvar; cvar = cvar->next) for (cvar = consvar_vars; cvar; cvar = cvar->next)
if (fasticmp(name,cvar->name)) if (fasticmp(name, cvar->name))
return cvar; return cvar;
return NULL; return NULL;
+5 -5
View File
@@ -46,16 +46,16 @@
#ifdef HAVE_THREADS #ifdef HAVE_THREADS
I_mutex con_mutex; I_mutex con_mutex;
// g_in_exiting_signal_handler is an evil hack // I_In_Exiting_Signal_Handler is an evil hack
// to avoid infinite SIGABRT recursion in the signal handler // to avoid infinite SIGABRT recursion in the signal handler
// due to poisoned locks or mach-o kernel not supporting locks in signals // due to poisoned locks or mach-o kernel not supporting locks in signals
// or something like that. idk // or something like that. idk
# define Lock_state() if (!g_in_exiting_signal_handler) { I_lock_mutex(&con_mutex); } # define Lock_state() if (!I_In_Exiting_Signal_Handler()) { I_LockMutex(&con_mutex); }
# define Unlock_state() if (!g_in_exiting_signal_handler) { I_unlock_mutex(con_mutex); } # define Unlock_state() if (!I_In_Exiting_Signal_Handler()) { I_UnlockMutex(con_mutex); }
#else/*HAVE_THREADS*/ #else /*HAVE_THREADS*/
# define Lock_state() # define Lock_state()
# define Unlock_state() # define Unlock_state()
#endif/*HAVE_THREADS*/ #endif /*HAVE_THREADS*/
static boolean con_started = false; // console has been initialised static boolean con_started = false; // console has been initialised
boolean con_startup = false; // true at game startup, screen need refreshing boolean con_startup = false; // true at game startup, screen need refreshing
+346 -316
View File
File diff suppressed because it is too large. Load diff
+3 -1
View File
@@ -660,9 +660,11 @@ extern UINT8 hu_redownloadinggamestate;
#endif #endif
extern boolean hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player extern boolean hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
#define SAVEGAMESIZE (768*1024)
typedef struct rewind_s typedef struct rewind_s
{ {
UINT8 savebuffer[(768*1024)]; UINT8 savebuffer[SAVEGAMESIZE];
tic_t leveltime; tic_t leveltime;
size_t demopos; size_t demopos;
+5
View File
@@ -697,6 +697,11 @@ void D_SRB2Loop(void)
for (;;) for (;;)
{ {
if (I_Interrupted())
{
I_Quit();
}
// capbudget is the minimum precise_t duration of a single loop iteration // capbudget is the minimum precise_t duration of a single loop iteration
precise_t capbudget; precise_t capbudget;
precise_t elapsed; precise_t elapsed;
+1 -5
View File
@@ -612,12 +612,8 @@ void Net_WaitAllAckReceived(UINT32 timeout)
static void InitNode(node_t *node) static void InitNode(node_t *node)
{ {
node->acktosend_head = node->acktosend_tail = 0; memset(node, 0, sizeof(node_t));
memset(node->acktosend, 0, sizeof(node->acktosend));
node->firstacktosend = 0;
node->nextacknum = 1; node->nextacknum = 1;
node->remotefirstack = 0;
node->flags = 0;
} }
static void InitAck(void) static void InitAck(void)
+144 -482
View File
@@ -1208,11 +1208,11 @@ static boolean AllowedPlayerNameChar(char ch)
static boolean EnsurePlayerNameIsGood(char *name, INT32 playernum) static boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
{ {
INT32 ix; size_t ix, len = strlen(name);
if (strlen(name) == 0 || strlen(name) > MAXPLAYERNAME) if (len == 0 || len > MAXPLAYERNAME)
return false; // Empty or too long. return false; // Empty or too long.
if (name[0] == ' ' || name[strlen(name)-1] == ' ') if (name[0] == ' ' || name[len-1] == ' ')
return false; // Starts or ends with a space. return false; // Starts or ends with a space.
if (isdigit(name[0])) if (isdigit(name[0]))
return false; // Starts with a digit. return false; // Starts with a digit.
@@ -1226,20 +1226,19 @@ static boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
// Also, anything over 0x80 is disallowed too, since compilers love to // Also, anything over 0x80 is disallowed too, since compilers love to
// differ on whether they're printable characters or not. // differ on whether they're printable characters or not.
for (ix = 0; name[ix] != '\0'; ix++) for (ix = 0; ix < len; ix++)
if (!AllowedPlayerNameChar(name[ix])) if (!AllowedPlayerNameChar(name[ix]))
return false; return false;
// Check if a player is currently using the name, case-insensitively. // Check if a player is currently using the name, case-insensitively.
for (ix = 0; ix < MAXPLAYERS; ix++) for (ix = 0; ix < MAXPLAYERS; ix++)
{ {
if (ix != playernum && playeringame[ix] if (ix != (size_t)playernum && playeringame[ix]
&& fasticmp(name, player_names[ix])) && fasticmp(name, player_names[ix]))
{ {
// We shouldn't kick people out just because // We shouldn't kick people out just because
// they joined the game with the same name // they joined the game with the same name
// as someone else -- modify the name instead. // as someone else -- modify the name instead.
size_t len = strlen(name);
// Recursion! // Recursion!
// Slowly strip characters off the end of the // Slowly strip characters off the end of the
@@ -1458,7 +1457,9 @@ UINT8 CanChangeSkin(INT32 playernum)
return true; return true;
} }
if (players[playernum].spectator || players[playernum].playerstate == PST_DEAD || players[playernum].playerstate == PST_REBORN) if (players[playernum].spectator ||
players[playernum].playerstate == PST_DEAD ||
players[playernum].playerstate == PST_REBORN)
return true; return true;
return false; return false;
@@ -1492,445 +1493,144 @@ static void ForceAllSkins(INT32 forcedskin)
} }
} }
static INT32 snacpending = 0, snac2pending = 0, snac3pending = 0, snac4pending = 0, chmappending = 0; static INT32 chmappending;
static INT32 snacpending[MAXSPLITSCREENPLAYERS];
// wonky compat, idk if anything uses this....
#define playerisbot (splitplayer == 1 && botingame)
// name, color, or skin has changed // name, color, or skin has changed
// //
static void SendNameAndColor(void) static void SendNameAndColor(UINT8 splitplayer)
{ {
char buf[MAXPLAYERNAME+2]; char buf[MAXPLAYERNAME+2];
char *p; char *p;
p = buf; p = buf;
// splitscreen
if (splitscreen < splitplayer && !playerisbot)
return;
const INT32 pnum = P_GetLocalPlayerNumForNum(splitplayer);
player_t *player = &players[pnum];
// TODO: make those cvars arrays
consvar_t *playercolor, *playername, *playerskin;
consvar_t *colorvars[] = {&cv_playercolor, &cv_playercolor2, &cv_playercolor3, &cv_playercolor4};
consvar_t *namevars[] = {&cv_playername, &cv_playername2, &cv_playername3, &cv_playername4};
consvar_t *skinvars[] = {&cv_skin, &cv_skin2, &cv_skin3, &cv_skin4};
playercolor = colorvars[splitplayer];
playername = namevars[splitplayer];
playerskin = skinvars[splitplayer];
// normal player colors // normal player colors
if (G_GametypeHasTeams()) if (G_GametypeHasTeams())
{ {
if (players[consoleplayer].ctfteam == 1 && cv_playercolor.value != skincolor_redteam) if (player->ctfteam == 1 && playercolor->value != skincolor_redteam)
CV_StealthSetValue(&cv_playercolor, skincolor_redteam); CV_StealthSetValue(playercolor, skincolor_redteam);
else if (players[consoleplayer].ctfteam == 2 && cv_playercolor.value != skincolor_blueteam) else if (player->ctfteam == 2 && playercolor->value != skincolor_blueteam)
CV_StealthSetValue(&cv_playercolor, skincolor_blueteam); CV_StealthSetValue(playercolor, skincolor_blueteam);
} }
// never allow the color "none" // never allow the color "none"
if (!cv_playercolor.value) if (!playercolor->value)
{ {
if (players[consoleplayer].skincolor) if (player->skincolor)
CV_StealthSetValue(&cv_playercolor, players[consoleplayer].skincolor); CV_StealthSetValue(playercolor, player->skincolor);
else if (skins[players[consoleplayer].skin].prefcolor) else if (skins[player->skin].prefcolor)
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor); CV_StealthSetValue(playercolor, skins[player->skin].prefcolor);
else else
CV_StealthSet(&cv_playercolor, cv_playercolor.defaultvalue); CV_StealthSet(playercolor, playercolor->defaultvalue);
} }
if (fastcmp(cv_playername.string, player_names[consoleplayer])
&& cv_playercolor.value == players[consoleplayer].skincolor
&& fastcmp(cv_skin.string, skins[players[consoleplayer].skin].name))
return;
// We'll handle it later if we're not playing. // We'll handle it later if we're not playing.
if (!Playing()) if (!Playing())
return; return;
if (fastcmp(playername->string, player_names[pnum])
&& playercolor->value == player->skincolor
&& fastcmp(playerskin->string, skins[player->skin].name))
return;
if (playerisbot)
{
players[pnum].skincolor = botcolor;
if (players[pnum].mo)
players[pnum].mo->color = players[pnum].skincolor;
SetPlayerSkinByNum(pnum, botskin-1);
return;
}
// If you're not in a netgame, merely update the skin, color, and name. // If you're not in a netgame, merely update the skin, color, and name.
if (!netgame) if (!netgame)
{ {
INT32 foundskin; INT32 foundskin;
CleanupPlayerName(consoleplayer, cv_playername.zstring); CleanupPlayerName(pnum, playername->zstring);
strcpy(player_names[consoleplayer], cv_playername.zstring); strcpy(player_names[pnum], playername->zstring);
players[consoleplayer].skincolor = cv_playercolor.value; player->skincolor = playercolor->value;
if (players[consoleplayer].mo) if (player->mo)
players[consoleplayer].mo->color = players[consoleplayer].skincolor; player->mo->color = player->skincolor;
if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1) if ((foundskin = R_SkinAvailable(playerskin->string)) != -1)
{ {
cv_skin.value = foundskin; playerskin->value = foundskin;
SetPlayerSkin(consoleplayer, cv_skin.string); SetPlayerSkin(pnum, playerskin->string);
CV_StealthSet(&cv_skin, skins[cv_skin.value].name); CV_StealthSet(playerskin, skins[playerskin->value].name);
} }
else else
{ {
cv_skin.value = players[consoleplayer].skin; playerskin->value = player->skin;
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name); CV_StealthSet(playerskin, skins[player->skin].name);
// will always be same as current // will always be same as current
SetPlayerSkin(consoleplayer, cv_skin.string); SetPlayerSkin(pnum, playerskin->string);
} }
return; return;
} }
snacpending++; snacpending[splitplayer]++;
// Don't change name if muted // Don't change name if muted
if (player_name_changes[consoleplayer] >= MAXNAMECHANGES) if (player_name_changes[pnum] >= MAXNAMECHANGES)
{ {
CV_StealthSet(&cv_playername, player_names[consoleplayer]); CV_StealthSet(playername, player_names[pnum]);
HU_AddChatText("\x85*You must wait to change your name again", false); HU_AddChatText("\x85*You must wait to change your name again", false);
} }
else if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) else if (cv_mute.value && !(server || IsPlayerAdmin(pnum)))
CV_StealthSet(&cv_playername, player_names[consoleplayer]); CV_StealthSet(playername, player_names[pnum]);
else // Cleanup name if changing it else // Cleanup name if changing it
CleanupPlayerName(consoleplayer, cv_playername.zstring); CleanupPlayerName(pnum, playername->zstring);
// Don't change skin if the server doesn't want you to. // Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(consoleplayer)) if (!CanChangeSkin(pnum))
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name); CV_StealthSet(playerskin, skins[player->skin].name);
// check if player has the skin loaded (cv_skin may have // check if player has the skin loaded (cv_skin may have
// the name of a skin that was available in the previous game) // the name of a skin that was available in the previous game)
cv_skin.value = R_SkinAvailable(cv_skin.string); playerskin->value = R_SkinAvailable(playerskin->string);
if (cv_skin.value < 0) if (playerskin->value < 0)
{ {
INT32 skinnum = players[consoleplayer].skin; INT32 skinnum = player->skin;
CV_StealthSet(&cv_skin, skins[skinnum].name); CV_StealthSet(playerskin, skins[skinnum].name);
cv_skin.value = skinnum; playerskin->value = skinnum;
} }
// Finally write out the complete packet and send it off. // Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME); WRITESTRINGN(p, playername->zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)cv_playercolor.value); WRITEUINT8(p, (UINT8)playercolor->value);
WRITEUINT8(p, (UINT8)cv_skin.value); WRITEUINT8(p, (UINT8)playerskin->value);
SendNetXCmdForPlayer(0, XD_NAMEANDCOLOR, buf, p - buf); SendNetXCmdForPlayer(splitplayer, XD_NAMEANDCOLOR, buf, p - buf);
}
// splitscreen
static void SendNameAndColor2(void)
{
INT32 secondplaya = -1;
char buf[MAXPLAYERNAME+2];
char *p;
if (splitscreen < 1 && !botingame)
return; // can happen if skin2/color2/name2 changed
if (displayplayers[1] != consoleplayer)
secondplaya = displayplayers[1];
else if (!netgame) // HACK
secondplaya = 1;
if (secondplaya == -1)
return;
p = buf;
// normal player colors
if (G_GametypeHasTeams())
{
if (players[secondplaya].ctfteam == 1 && cv_playercolor2.value != skincolor_redteam)
CV_StealthSetValue(&cv_playercolor2, skincolor_redteam);
else if (players[secondplaya].ctfteam == 2 && cv_playercolor2.value != skincolor_blueteam)
CV_StealthSetValue(&cv_playercolor2, skincolor_blueteam);
}
// never allow the color "none"
if (!cv_playercolor2.value)
{
if (players[secondplaya].skincolor)
CV_StealthSetValue(&cv_playercolor2, players[secondplaya].skincolor);
else if (skins[players[secondplaya].skin].prefcolor)
CV_StealthSetValue(&cv_playercolor2, skins[players[secondplaya].skin].prefcolor);
else
CV_StealthSet(&cv_playercolor2, cv_playercolor2.defaultvalue);
}
// We'll handle it later if we're not playing.
if (!Playing())
return;
// If you're not in a netgame, merely update the skin, color, and name.
if (botingame)
{
players[secondplaya].skincolor = botcolor;
if (players[secondplaya].mo)
players[secondplaya].mo->color = players[secondplaya].skincolor;
SetPlayerSkinByNum(secondplaya, botskin-1);
return;
}
else if (!netgame)
{
INT32 foundskin;
CleanupPlayerName(secondplaya, cv_playername2.zstring);
strcpy(player_names[secondplaya], cv_playername2.zstring);
// don't use displayplayers[1]: the second player must be 1
players[secondplaya].skincolor = cv_playercolor2.value;
if (players[secondplaya].mo)
players[secondplaya].mo->color = players[secondplaya].skincolor;
if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1)
{
cv_skin2.value = foundskin;
SetPlayerSkin(secondplaya, cv_skin2.string);
}
else
{
cv_skin2.value = players[secondplaya].skin;
CV_StealthSet(&cv_skin2, skins[players[secondplaya].skin].name);
// will always be same as current
SetPlayerSkin(secondplaya, cv_skin2.string);
}
return;
}
snac2pending++;
// Don't change name if muted
if (player_name_changes[displayplayers[1]] >= MAXNAMECHANGES)
{
CV_StealthSet(&cv_playername2, player_names[displayplayers[1]]);
HU_AddChatText("\x85*You must wait to change your name again", false);
}
else if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[1])))
CV_StealthSet(&cv_playername2, player_names[displayplayers[1]]);
else // Cleanup name if changing it
CleanupPlayerName(displayplayers[1], cv_playername2.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(displayplayers[1]))
CV_StealthSet(&cv_skin2, skins[players[displayplayers[1]].skin].name);
// check if player has the skin loaded (cv_skin2 may have
// the name of a skin that was available in the previous game)
cv_skin2.value = R_SkinAvailable(cv_skin2.string);
if (cv_skin2.value < 0)
{
INT32 skinnum = players[displayplayers[1]].skin;
CV_StealthSet(&cv_skin2, skins[skinnum].name);
cv_skin2.value = skinnum;
}
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername2.zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)cv_playercolor2.value);
WRITEUINT8(p, (UINT8)cv_skin2.value);
SendNetXCmdForPlayer(1, XD_NAMEANDCOLOR, buf, p - buf);
}
static void SendNameAndColor3(void)
{
INT32 thirdplaya = -1;
char buf[MAXPLAYERNAME+2];
char *p;
if (splitscreen < 2)
return; // can happen if skin3/color3/name3 changed
if (displayplayers[2] != consoleplayer)
thirdplaya = displayplayers[2];
else if (!netgame) // HACK
thirdplaya = 2;
if (thirdplaya == -1)
return;
p = buf;
// normal player colors
if (G_GametypeHasTeams())
{
if (players[thirdplaya].ctfteam == 1 && cv_playercolor3.value != skincolor_redteam)
CV_StealthSetValue(&cv_playercolor3, skincolor_redteam);
else if (players[thirdplaya].ctfteam == 2 && cv_playercolor3.value != skincolor_blueteam)
CV_StealthSetValue(&cv_playercolor3, skincolor_blueteam);
}
// never allow the color "none"
if (!cv_playercolor3.value)
{
if (players[thirdplaya].skincolor)
CV_StealthSetValue(&cv_playercolor3, players[thirdplaya].skincolor);
else if (skins[players[thirdplaya].skin].prefcolor)
CV_StealthSetValue(&cv_playercolor3, skins[players[thirdplaya].skin].prefcolor);
else
CV_StealthSet(&cv_playercolor3, cv_playercolor3.defaultvalue);
}
// We'll handle it later if we're not playing.
if (!Playing())
return;
// If you're not in a netgame, merely update the skin, color, and name.
if (!netgame)
{
INT32 foundskin;
CleanupPlayerName(thirdplaya, cv_playername3.zstring);
strcpy(player_names[thirdplaya], cv_playername3.zstring);
// don't use displayplayers[2]: the third player must be 2
players[thirdplaya].skincolor = cv_playercolor3.value;
if (players[thirdplaya].mo)
players[thirdplaya].mo->color = players[thirdplaya].skincolor;
if ((foundskin = R_SkinAvailable(cv_skin3.string)) != -1)
{
cv_skin3.value = foundskin;
SetPlayerSkin(thirdplaya, cv_skin3.string);
}
else
{
cv_skin3.value = players[thirdplaya].skin;
CV_StealthSet(&cv_skin3, skins[players[thirdplaya].skin].name);
// will always be same as current
SetPlayerSkin(thirdplaya, cv_skin3.string);
}
return;
}
snac3pending++;
// Don't change name if muted
if (player_name_changes[displayplayers[2]] >= MAXNAMECHANGES)
{
CV_StealthSet(&cv_playername3, player_names[displayplayers[2]]);
HU_AddChatText("\x85*You must wait to change your name again", false);
}
else if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[2])))
CV_StealthSet(&cv_playername3, player_names[displayplayers[2]]);
else // Cleanup name if changing it
CleanupPlayerName(displayplayers[2], cv_playername3.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(displayplayers[2]))
CV_StealthSet(&cv_skin3, skins[players[displayplayers[2]].skin].name);
// check if player has the skin loaded (cv_skin3 may have
// the name of a skin that was available in the previous game)
cv_skin3.value = R_SkinAvailable(cv_skin3.string);
if (cv_skin3.value < 0)
{
INT32 skinnum = players[displayplayers[2]].skin;
CV_StealthSet(&cv_skin3, skins[skinnum].name);
cv_skin3.value = skinnum;
}
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername3.zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)cv_playercolor3.value);
WRITEUINT8(p, (UINT8)cv_skin3.value);
SendNetXCmdForPlayer(2, XD_NAMEANDCOLOR, buf, p - buf);
}
static void SendNameAndColor4(void)
{
INT32 fourthplaya = -1;
char buf[MAXPLAYERNAME+2];
char *p;
if (splitscreen < 3)
return; // can happen if skin4/color4/name4 changed
if (displayplayers[3] != consoleplayer)
fourthplaya = displayplayers[3];
else if (!netgame) // HACK
fourthplaya = 3;
if (fourthplaya == -1)
return;
p = buf;
// normal player colors
if (G_GametypeHasTeams())
{
if (players[fourthplaya].ctfteam == 1 && cv_playercolor4.value != skincolor_redteam)
CV_StealthSetValue(&cv_playercolor4, skincolor_redteam);
else if (players[fourthplaya].ctfteam == 2 && cv_playercolor4.value != skincolor_blueteam)
CV_StealthSetValue(&cv_playercolor4, skincolor_blueteam);
}
// never allow the color "none"
if (!cv_playercolor4.value)
{
if (players[fourthplaya].skincolor)
CV_StealthSetValue(&cv_playercolor4, players[fourthplaya].skincolor);
else if (skins[players[fourthplaya].skin].prefcolor)
CV_StealthSetValue(&cv_playercolor4, skins[players[fourthplaya].skin].prefcolor);
else
CV_StealthSet(&cv_playercolor4, cv_playercolor4.defaultvalue);
}
// We'll handle it later if we're not playing.
if (!Playing())
return;
// If you're not in a netgame, merely update the skin, color, and name.
if (botingame)
{
players[fourthplaya].skincolor = botcolor;
if (players[fourthplaya].mo)
players[fourthplaya].mo->color = players[fourthplaya].skincolor;
SetPlayerSkinByNum(fourthplaya, botskin-1);
return;
}
else if (!netgame)
{
INT32 foundskin;
CleanupPlayerName(fourthplaya, cv_playername4.zstring);
strcpy(player_names[fourthplaya], cv_playername4.zstring);
// don't use displayplayers[3]: the second player must be 4
players[fourthplaya].skincolor = cv_playercolor4.value;
if (players[fourthplaya].mo)
players[fourthplaya].mo->color = players[fourthplaya].skincolor;
if ((foundskin = R_SkinAvailable(cv_skin4.string)) != -1)
{
cv_skin4.value = foundskin;
SetPlayerSkin(fourthplaya, cv_skin4.string);
}
else
{
cv_skin4.value = players[fourthplaya].skin;
CV_StealthSet(&cv_skin4, skins[players[fourthplaya].skin].name);
// will always be same as current
SetPlayerSkin(fourthplaya, cv_skin4.string);
}
return;
}
snac4pending++;
// Don't change name if muted
if (player_name_changes[displayplayers[3]] >= MAXNAMECHANGES)
{
CV_StealthSet(&cv_playername4, player_names[displayplayers[3]]);
HU_AddChatText("\x85*You must wait to change your name again", false);
}
else if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[3])))
CV_StealthSet(&cv_playername4, player_names[displayplayers[3]]);
else // Cleanup name if changing it
CleanupPlayerName(displayplayers[3], cv_playername4.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(displayplayers[3]))
CV_StealthSet(&cv_skin4, skins[players[displayplayers[3]].skin].name);
// check if player has the skin loaded (cv_skin4 may have
// the name of a skin that was available in the previous game)
cv_skin4.value = R_SkinAvailable(cv_skin4.string);
if (cv_skin4.value < 0)
{
INT32 skinnum = players[displayplayers[3]].skin;
CV_StealthSet(&cv_skin4, skins[skinnum].name);
cv_skin4.value = skinnum;
}
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername4.zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)cv_playercolor4.value);
WRITEUINT8(p, (UINT8)cv_skin4.value);
SendNetXCmdForPlayer(3, XD_NAMEANDCOLOR, buf, p - buf);
} }
static void Got_NameAndColor(const UINT8 **cp, INT32 playernum) static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
{ {
player_t *p = &players[playernum]; player_t *player = &players[playernum];
char name[MAXPLAYERNAME+1]; char name[MAXPLAYERNAME+1];
UINT8 color, skin; UINT8 color, skin;
@@ -1939,19 +1639,14 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
I_Error("There is no player %d!", playernum); I_Error("There is no player %d!", playernum);
#endif #endif
if (playernum == consoleplayer) if (P_IsLocalPlayer(player))
snacpending--; // TODO: make snacpending an array instead of 4 separate vars? {
else if (playernum == displayplayers[1]) snacpending[playernum]--;
snac2pending--;
else if (playernum == displayplayers[2])
snac3pending--;
else if (playernum == displayplayers[3])
snac4pending--;
#ifdef PARANOIA #ifdef PARANOIA
if (snacpending < 0 || snac2pending < 0 || snac3pending < 0 || snac4pending < 0) if (snacpending[playernum] < 0)
I_Error("snacpending negative!"); I_Error("snacpending negative!");
#endif #endif
}
READSTRINGN(*cp, name, MAXPLAYERNAME); READSTRINGN(*cp, name, MAXPLAYERNAME);
color = READUINT8(*cp); color = READUINT8(*cp);
@@ -1965,33 +1660,32 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
} }
// set color // set color
p->skincolor = color % MAXSKINCOLORS; player->skincolor = color % MAXSKINCOLORS;
if (p->mo) if (player->mo)
p->mo->color = (UINT8)p->skincolor; player->mo->color = (UINT8)player->skincolor;
demo_extradata[playernum] |= DXD_COLOR; demo_extradata[playernum] |= DXD_COLOR;
// normal player colors // normal player colors
if (server && (p != &players[consoleplayer] && p != &players[displayplayers[1]] if (server && !P_IsLocalPlayer(player))
&& p != &players[displayplayers[2]] && p != &players[displayplayers[3]]))
{ {
boolean kick = false; boolean kick = false;
// team colors // team colors
if (G_GametypeHasTeams()) if (G_GametypeHasTeams())
{ {
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam) if (player->ctfteam == 1 && player->skincolor != skincolor_redteam)
kick = true; kick = true;
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam) else if (player->ctfteam == 2 && player->skincolor != skincolor_blueteam)
kick = true; kick = true;
} }
// don't allow color "none" // don't allow color "none"
if (!p->skincolor) if (!player->skincolor)
kick = true; kick = true;
if (kick) if (kick)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal color change received from %s (team: %d), color: %d)\n"), player_names[playernum], p->ctfteam, p->skincolor); CONS_Alert(CONS_WARNING, M_GetText("Illegal color change received from %s (team: %d), color: %d)\n"), player_names[playernum], player->ctfteam, player->skincolor);
SendKick(playernum, KICK_MSG_CON_FAIL); SendKick(playernum, KICK_MSG_CON_FAIL);
return; return;
} }
@@ -2003,6 +1697,7 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
const INT32 forcedskin = cv_forceskin.value; const INT32 forcedskin = cv_forceskin.value;
SetPlayerSkinByNum(playernum, forcedskin); SetPlayerSkinByNum(playernum, forcedskin);
// TODO: make cv_skin an array
if (playernum == consoleplayer) if (playernum == consoleplayer)
CV_StealthSet(&cv_skin, skins[forcedskin].name); CV_StealthSet(&cv_skin, skins[forcedskin].name);
else if (playernum == displayplayers[1]) else if (playernum == displayplayers[1])
@@ -2016,44 +1711,16 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
SetPlayerSkinByNum(playernum, skin); SetPlayerSkinByNum(playernum, skin);
} }
void SendWeaponPref(void) void SendWeaponPref(UINT8 splitplayer)
{ {
UINT8 buf[1]; UINT8 buf[1];
buf[0] = 0; buf[0] = 0;
if (cv_flipcam[0].value)
if (cv_flipcam[splitplayer].value)
buf[0] |= 1; buf[0] |= 1;
SendNetXCmdForPlayer(0, XD_WEAPONPREF, buf, 1);
}
void SendWeaponPref2(void) SendNetXCmdForPlayer(splitplayer, XD_WEAPONPREF, buf, 1);
{
UINT8 buf[1];
buf[0] = 0;
if (cv_flipcam[1].value)
buf[0] |= 1;
SendNetXCmdForPlayer(1, XD_WEAPONPREF, buf, 1);
}
void SendWeaponPref3(void)
{
UINT8 buf[1];
buf[0] = 0;
if (cv_flipcam[2].value)
buf[0] |= 1;
SendNetXCmdForPlayer(2, XD_WEAPONPREF, buf, 1);
}
void SendWeaponPref4(void)
{
UINT8 buf[1];
buf[0] = 0;
if (cv_flipcam[3].value)
buf[0] |= 1;
SendNetXCmdForPlayer(3, XD_WEAPONPREF, buf, 1);
} }
static void Got_WeaponPref(const UINT8 **cp, INT32 playernum) static void Got_WeaponPref(const UINT8 **cp, INT32 playernum)
@@ -2069,23 +1736,10 @@ static void Got_WeaponPref(const UINT8 **cp, INT32 playernum)
player->pflags |= PF_ANALOGMODE; player->pflags |= PF_ANALOGMODE;
} }
void D_SendPlayerConfig(void) void D_SendPlayerConfig(UINT8 splitplayer)
{ {
SendNameAndColor(); SendNameAndColor(splitplayer);
if (splitscreen || botingame) SendWeaponPref(splitplayer);
SendNameAndColor2();
if (splitscreen > 1)
SendNameAndColor3();
if (splitscreen > 2)
SendNameAndColor4();
SendWeaponPref();
if (splitscreen)
SendWeaponPref2();
if (splitscreen > 1)
SendWeaponPref3();
if (splitscreen > 2)
SendWeaponPref4();
} }
// Only works for displayplayer, sorry! // Only works for displayplayer, sorry!
@@ -2108,10 +1762,12 @@ INT32 D_LookupPlayer(const char *s)
return playernum; return playernum;
} }
const size_t len = strlen(s);
for (playernum = 0; playernum < MAXPLAYERS; ++playernum) for (playernum = 0; playernum < MAXPLAYERS; ++playernum)
{ {
/* Match name case-insensitively: fully, or partially the start. */ /* Match name case-insensitively: fully, or partially the start. */
if (playeringame[playernum] && (strnicmp(player_names[playernum], s, strlen(s)) == 0)) if (playeringame[playernum] && (strnicmp(player_names[playernum], s, len) == 0))
{ {
return playernum; return playernum;
} }
@@ -2151,13 +1807,15 @@ static void GetViewablePlayerPlaceRange(INT32 *first, INT32 *last)
(*last) = 0; (*last) = 0;
for (i = 0; i < MAXPLAYERS; ++i) for (i = 0; i < MAXPLAYERS; ++i)
if (G_CouldView(i))
{ {
place = players[i].kartstuff[k_position]; if (G_CouldView(i))
if (place < (*first)) {
(*first) = place; place = players[i].kartstuff[k_position];
if (place > (*last)) if (place < (*first))
(*last) = place; (*first) = place;
if (place > (*last))
(*last) = place;
}
} }
} }
@@ -2491,7 +2149,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
displayplayers[1] = 1; displayplayers[1] = 1;
playeringame[1] = true; playeringame[1] = true;
players[1].bot = 1; players[1].bot = 1;
SendNameAndColor2(); SendNameAndColor(1);
} }
} }
@@ -5768,50 +5426,54 @@ static void ForceSkin_OnChange(void)
} }
} }
//Allows the player's name to be changed if cv_mute is off. // Allows the player's name to be changed if cv_mute is off.
static void Name_OnChange(void) static void Name_OnChange(void)
{ {
if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n")); CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername, player_names[consoleplayer]); CV_StealthSet(&cv_playername, player_names[consoleplayer]);
return;
} }
else
SendNameAndColor(); SendNameAndColor(0);
} }
static void Name2_OnChange(void) static void Name2_OnChange(void)
{ {
if (cv_mute.value) //Secondary player can't be admin. if (cv_mute.value) // Secondary player can't be admin.
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n")); CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername2, player_names[displayplayers[1]]); CV_StealthSet(&cv_playername2, player_names[displayplayers[1]]);
return;
} }
else
SendNameAndColor2(); SendNameAndColor(1);
} }
static void Name3_OnChange(void) static void Name3_OnChange(void)
{ {
if (cv_mute.value) //Third player can't be admin. if (cv_mute.value) // Third player can't be admin.
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n")); CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername3, player_names[displayplayers[2]]); CV_StealthSet(&cv_playername3, player_names[displayplayers[2]]);
return;
} }
else
SendNameAndColor3(); SendNameAndColor(2);
} }
static void Name4_OnChange(void) static void Name4_OnChange(void)
{ {
if (cv_mute.value) //Secondary player can't be admin. if (cv_mute.value) // Secondary player can't be admin.
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n")); CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername4, player_names[displayplayers[3]]); CV_StealthSet(&cv_playername4, player_names[displayplayers[3]]);
return;
} }
else
SendNameAndColor4(); SendNameAndColor(3);
} }
/** Sends a skin change for the console player, unless that player is moving. /** Sends a skin change for the console player, unless that player is moving.
@@ -5833,7 +5495,7 @@ static void Skin_OnChange(void)
} }
if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer)) if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer))
SendNameAndColor(); SendNameAndColor(0);
else else
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
@@ -5854,7 +5516,7 @@ static void Skin2_OnChange(void)
return; // do whatever you want return; // do whatever you want
if (CanChangeSkin(displayplayers[1]) && !P_PlayerMoving(displayplayers[1])) if (CanChangeSkin(displayplayers[1]) && !P_PlayerMoving(displayplayers[1]))
SendNameAndColor2(); SendNameAndColor(1);
else else
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
@@ -5870,7 +5532,7 @@ static void Skin3_OnChange(void)
return; // do whatever you want return; // do whatever you want
if (CanChangeSkin(displayplayers[2]) && !P_PlayerMoving(displayplayers[2])) if (CanChangeSkin(displayplayers[2]) && !P_PlayerMoving(displayplayers[2]))
SendNameAndColor3(); SendNameAndColor(2);
else else
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
@@ -5886,7 +5548,7 @@ static void Skin4_OnChange(void)
return; // do whatever you want return; // do whatever you want
if (CanChangeSkin(displayplayers[3]) && !P_PlayerMoving(displayplayers[3])) if (CanChangeSkin(displayplayers[3]) && !P_PlayerMoving(displayplayers[3]))
SendNameAndColor4(); SendNameAndColor(3);
else else
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
@@ -5999,7 +5661,7 @@ static void Color_OnChange(void)
if (!P_PlayerMoving(consoleplayer)) if (!P_PlayerMoving(consoleplayer))
{ {
// Color change menu scrolling fix is no longer necessary // Color change menu scrolling fix is no longer necessary
SendNameAndColor(); SendNameAndColor(0);
} }
else else
{ {
@@ -6021,7 +5683,7 @@ static void Color2_OnChange(void)
if (!P_PlayerMoving(displayplayers[1])) if (!P_PlayerMoving(displayplayers[1]))
{ {
// Color change menu scrolling fix is no longer necessary // Color change menu scrolling fix is no longer necessary
SendNameAndColor2(); SendNameAndColor(1);
} }
else else
{ {
@@ -6038,7 +5700,7 @@ static void Color3_OnChange(void)
if (!P_PlayerMoving(displayplayers[2])) if (!P_PlayerMoving(displayplayers[2]))
{ {
// Color change menu scrolling fix is no longer necessary // Color change menu scrolling fix is no longer necessary
SendNameAndColor3(); SendNameAndColor(2);
} }
else else
{ {
@@ -6055,7 +5717,7 @@ static void Color4_OnChange(void)
if (!P_PlayerMoving(displayplayers[3])) if (!P_PlayerMoving(displayplayers[3]))
{ {
// Color change menu scrolling fix is no longer necessary // Color change menu scrolling fix is no longer necessary
SendNameAndColor4(); SendNameAndColor(3);
} }
else else
{ {
+2 -5
View File
@@ -21,10 +21,7 @@ extern "C" {
#include "command.h" #include "command.h"
void SendWeaponPref(void); void SendWeaponPref(UINT8 splitplayer);
void SendWeaponPref2(void);
void SendWeaponPref3(void);
void SendWeaponPref4(void);
// console vars // console vars
extern consvar_t cv_playername; extern consvar_t cv_playername;
@@ -295,7 +292,7 @@ typedef union {
// add game commands, needs cleanup // add game commands, needs cleanup
void D_RegisterServerCommands(void); void D_RegisterServerCommands(void);
void D_RegisterClientCommands(void); void D_RegisterClientCommands(void);
void D_SendPlayerConfig(void); void D_SendPlayerConfig(UINT8 splitplayer);
void Command_ExitGame_f(void); void Command_ExitGame_f(void);
void Command_Retry_f(void); void Command_Retry_f(void);
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
+16 -16
View File
@@ -960,7 +960,7 @@ void Got_Filetxpak(void)
|| fastcmp(filename, "music.kart") || fastcmp(filename, "music.kart")
|| fastcmp(filename, "patch.kart") || fastcmp(filename, "patch.kart")
)) ))
I_Error("Tried to download \"%s\"", filename); I_Error("Tried to download base-game file: \"%s\"", filename);
if (filenum >= fileneedednum) if (filenum >= fileneedednum)
{ {
@@ -1019,21 +1019,21 @@ void Got_Filetxpak(void)
switch(file->status) switch(file->status)
{ {
case FS_NOTFOUND: case FS_NOTFOUND:
s = "FS_NOTFOUND"; s = "FS_NOTFOUND";
break; break;
case FS_FOUND: case FS_FOUND:
s = "FS_FOUND"; s = "FS_FOUND";
break; break;
case FS_OPEN: case FS_OPEN:
s = "FS_OPEN"; s = "FS_OPEN";
break; break;
case FS_MD5SUMBAD: case FS_MD5SUMBAD:
s = "FS_MD5SUMBAD"; s = "FS_MD5SUMBAD";
break; break;
default: default:
s = "unknown"; s = "unknown";
break; break;
} }
I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s); I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s);
+16 -5
View File
@@ -984,7 +984,7 @@ void I_SleepDuration(precise_t duration)
#endif #endif
} }
boolean g_in_exiting_signal_handler = false; static volatile sig_atomic_t g_in_exiting_signal_handler = false;
static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_msg) static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_msg)
{ {
@@ -1048,6 +1048,11 @@ static void I_ReportSignal(int num, int coredumped)
I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg); I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg);
} }
boolean I_In_Exiting_Signal_Handler(void)
{
return g_in_exiting_signal_handler;
}
#ifndef NEWSIGNALHANDLER #ifndef NEWSIGNALHANDLER
FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
{ {
@@ -1067,11 +1072,17 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
} }
#endif #endif
FUNCNORETURN static ATTRNORETURN void quit_handler(int num) static volatile sig_atomic_t interrupted = 0;
boolean I_Interrupted(void)
{ {
signal(num, SIG_DFL); //default signal action return interrupted;
raise(num); }
I_Quit();
static void quit_handler(int num)
{
(void)num;
interrupted = 1;
} }
#ifdef HAVE_LIBBACKTRACE #ifdef HAVE_LIBBACKTRACE
+2 -2
View File
@@ -173,7 +173,7 @@ FUNCPRINTF static void deh_warning(const char *first, ...)
vsnprintf(buf, 1000, first, argptr); // sizeof only returned 4 here. it didn't like that pointer. vsnprintf(buf, 1000, first, argptr); // sizeof only returned 4 here. it didn't like that pointer.
va_end(argptr); va_end(argptr);
if(dbg_line == -1) // Not in a SOC, line number unknown. if (dbg_line == -1) // Not in a SOC, line number unknown.
CONS_Alert(CONS_WARNING, "%s\n", buf); CONS_Alert(CONS_WARNING, "%s\n", buf);
else else
CONS_Alert(CONS_WARNING, "Line %u: %s\n", dbg_line, buf); CONS_Alert(CONS_WARNING, "Line %u: %s\n", dbg_line, buf);
@@ -8545,7 +8545,7 @@ static inline int lib_action(lua_State *L)
// Hardcoded A_Action name to call for super() or NULL if super() would be invalid. // Hardcoded A_Action name to call for super() or NULL if super() would be invalid.
// Set in lua_infolib. // Set in lua_infolib.
const char *superactions[MAXRECURSION]; const char *superactions[MAXRECURSION] = {};
UINT8 superstack = 0; UINT8 superstack = 0;
static int lib_dummysuper(lua_State *L) static int lib_dummysuper(lua_State *L)
+1 -4
View File
@@ -69,9 +69,6 @@ UINT8 botcolor = 0;
JoyType_t Joystick[MAXSPLITSCREENPLAYERS] = {}; JoyType_t Joystick[MAXSPLITSCREENPLAYERS] = {};
// 1024 bytes is plenty for a savegame
#define SAVEGAMESIZE (1024)
// SRB2kart // SRB2kart
char gamedatafilename[64] = "kartdata.dat"; char gamedatafilename[64] = "kartdata.dat";
char timeattackfolder[64] = "kart"; char timeattackfolder[64] = "kart";
@@ -3902,7 +3899,7 @@ void G_SaveGame(UINT32 savegameslot)
char name[VERSIONSIZE]; char name[VERSIONSIZE];
size_t length; size_t length;
save.p = save.buffer = (UINT8 *)Z_Malloc(SAVEGAMESIZE, PU_STATIC, NULL); save.p = save.buffer = (UINT8 *)Z_Malloc(1024, PU_STATIC, NULL); // 1024 bytes is plenty for a savegame
if (!save.p) if (!save.p)
{ {
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n")); CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n"));
+1
View File
@@ -318,6 +318,7 @@ static void
HMS_end (struct HMS_buffer *buffer) HMS_end (struct HMS_buffer *buffer)
{ {
curl_easy_cleanup(buffer->curl); curl_easy_cleanup(buffer->curl);
free(buffer->errbuf);
free(buffer->buffer); free(buffer->buffer);
free(buffer); free(buffer);
} }
+5 -1
View File
@@ -43,7 +43,7 @@ extern UINT8 graphics_started;
extern UINT8 keyboard_started; extern UINT8 keyboard_started;
/** \brief Set to true when inside a signal handler that will exit the program. */ /** \brief Set to true when inside a signal handler that will exit the program. */
extern boolean g_in_exiting_signal_handler; boolean I_In_Exiting_Signal_Handler(void);
/** \brief The I_GetFreeMem function /** \brief The I_GetFreeMem function
@@ -195,6 +195,10 @@ INT32 I_StartupSystem(void);
*/ */
void I_ShutdownSystem(void); void I_ShutdownSystem(void);
/** \brief To check if a Interrupt or Terminate Signal was fired
*/
boolean I_Interrupted(void);
/** \brief The I_GetDiskFreeSpace function /** \brief The I_GetDiskFreeSpace function
\param freespace a INT64 pointer to hold the free space amount \param freespace a INT64 pointer to hold the free space amount
+9 -7
View File
@@ -496,8 +496,10 @@ static void cleanupnodes(void)
// Why can't I start at zero? // Why can't I start at zero?
for (j = 1; j < MAXNETNODES; j++) for (j = 1; j < MAXNETNODES; j++)
{
if (!(nodeingame[j] || SV_SendingFile(j))) if (!(nodeingame[j] || SV_SendingFile(j)))
nodeconnected[j] = false; nodeconnected[j] = false;
}
} }
static SINT8 getfreenode(void) static SINT8 getfreenode(void)
@@ -507,11 +509,13 @@ static SINT8 getfreenode(void)
cleanupnodes(); cleanupnodes();
for (j = 0; j < MAXNETNODES; j++) for (j = 0; j < MAXNETNODES; j++)
{
if (!nodeconnected[j]) if (!nodeconnected[j])
{ {
nodeconnected[j] = true; nodeconnected[j] = true;
return j; return j;
} }
}
/** \warning No free node? Just in case a node might not have been freed properly, /** \warning No free node? Just in case a node might not have been freed properly,
* look if there are connected nodes that aren't in game, and forget them. * look if there are connected nodes that aren't in game, and forget them.
@@ -812,7 +816,7 @@ static void SOCK_Send(void)
static void SOCK_FreeNodenum(INT32 numnode) static void SOCK_FreeNodenum(INT32 numnode)
{ {
// can't disconnect from self :) // can't disconnect from self :)
if (!numnode || numnode > MAXNETNODES) if (numnode <= 0 || numnode > MAXNETNODES)
return; return;
DEBFILE(va("Free node %d (%s)\n", numnode, SOCK_GetNodeAddress(numnode))); DEBFILE(va("Free node %d (%s)\n", numnode, SOCK_GetNodeAddress(numnode)));
@@ -1432,14 +1436,12 @@ static void SOCK_RegisterHolePunch(void)
static boolean SOCK_OpenSocket(void) static boolean SOCK_OpenSocket(void)
{ {
size_t i; memset(clientaddress, 0, sizeof(clientaddress));
memset(clientaddress, 0, sizeof (clientaddress));
memset(nodeconnected, false, sizeof(nodeconnected));
nodeconnected[0] = true; // always connected to self nodeconnected[0] = true; // always connected to self
for (i = 1; i < MAXNETNODES; i++)
nodeconnected[i] = false;
nodeconnected[BROADCASTADDR] = true; nodeconnected[BROADCASTADDR] = true;
I_NetSend = SOCK_Send; I_NetSend = SOCK_Send;
I_NetGet = SOCK_Get; I_NetGet = SOCK_Get;
I_NetCloseSocket = SOCK_CloseSocket; I_NetCloseSocket = SOCK_CloseSocket;
@@ -1479,7 +1481,7 @@ static boolean SOCK_Ban(INT32 node)
{ {
INT32 ban; INT32 ban;
if (node > MAXNETNODES) if (node < 0 || node > MAXNETNODES)
return false; return false;
ban = numbans; ban = numbans;
+35 -18
View File
@@ -931,21 +931,21 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny)
//} //}
INT32 ITEM_X, ITEM_Y; // Item Window static INT32 ITEM_X, ITEM_Y; // Item Window
INT32 TIME_X, TIME_Y; // Time Sticker static INT32 TIME_X, TIME_Y; // Time Sticker
INT32 LAPS_X, LAPS_Y; // Lap Sticker static INT32 LAPS_X, LAPS_Y; // Lap Sticker
INT32 SPDM_X, SPDM_Y; // Speedometer static INT32 SPDM_X, SPDM_Y; // Speedometer
INT32 POSI_X, POSI_Y; // Position Number static INT32 POSI_X, POSI_Y; // Position Number
INT32 FACE_X, FACE_Y; // Top-four Faces static INT32 FACE_X, FACE_Y; // Top-four Faces
INT32 STCD_X, STCD_Y; // Starting countdown static INT32 STCD_X, STCD_Y; // Starting countdown
INT32 CHEK_Y; // CHECK graphic static INT32 CHEK_Y; // CHECK graphic
INT32 MINI_X, MINI_Y; // Minimap static INT32 MINI_X, MINI_Y; // Minimap
INT32 WANT_X, WANT_Y; // Battle WANTED poster static INT32 WANT_X, WANT_Y; // Battle WANTED poster
// This is for the P2 and P4 side of splitscreen. Then we'll flip P1's and P2's to the bottom with V_SPLITSCREEN. // This is for the P2 and P4 side of splitscreen. Then we'll flip P1's and P2's to the bottom with V_SPLITSCREEN.
INT32 ITEM2_X, ITEM2_Y; static INT32 ITEM2_X, ITEM2_Y;
INT32 LAPS2_X, LAPS2_Y; static INT32 LAPS2_X, LAPS2_Y;
INT32 POSI2_X, POSI2_Y; static INT32 POSI2_X, POSI2_Y;
static void K_initKartHUD(void) static void K_initKartHUD(void)
{ {
@@ -3816,7 +3816,7 @@ static void K_drawKartMinimap(void)
if (cv_showminimapangle.value && (minidoticon || minilighticon) && !playertimedout) if (cv_showminimapangle.value && (minidoticon || minilighticon) && !playertimedout)
{ {
UINT8 *colormap; UINT8 *colormap = NULL;
drawinfo_t dims; drawinfo_t dims;
fixed_t interpx, interpy; fixed_t interpx, interpy;
fixed_t xoff = 0, yoff = 0; fixed_t xoff = 0, yoff = 0;
@@ -3827,10 +3827,27 @@ static void K_drawKartMinimap(void)
if (encoremode) if (encoremode)
ang = ANGLE_180 - ang; ang = ANGLE_180 - ang;
if (mobj->colorized) if (mobj->color)
colormap = R_GetTranslationColormap(TC_RAINBOW, mobj->color, GTC_CACHE); {
else if (mobj->colorized)
colormap = R_GetLocalTranslationColormap(mobj->skin, mobj->localskin, mobj->color, GTC_CACHE, mobj->skinlocal); {
colormap = R_GetTranslationColormap(TC_RAINBOW, mobj->color, GTC_CACHE);
}
else
{
const INT32 skinnum = K_GetMobjLocalSkinNum(mobj->skin, mobj->localskin, mobj->skinlocal);
// special case if startcolor is not the default (160 / Green)
if (skinnum && skins[skinnum].starttranscolor != skins[0].starttranscolor)
{
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
}
else
{
colormap = R_GetLocalTranslationColormap(mobj->skin, mobj->localskin, mobj->color, GTC_CACHE, mobj->skinlocal);
}
}
}
interpx = lerp(mobj->old_x, mobj->x); interpx = lerp(mobj->old_x, mobj->x);
interpy = lerp(mobj->old_y, mobj->y); interpy = lerp(mobj->old_y, mobj->y);
+10 -1
View File
@@ -660,13 +660,22 @@ INT32 K_GetSkinNum(player_t *player)
// //
// returns the mobj skinnumber // returns the mobj skinnumber
// accounts for localskins // accounts for localskins ?
// //
INT32 K_GetMobjSkinNum(const skin_t *skin, boolean local) INT32 K_GetMobjSkinNum(const skin_t *skin, boolean local)
{ {
return skin - K_GetSkinArray(local); return skin - K_GetSkinArray(local);
} }
//
// returns the mobj skinnumber
// accounts for localskins
//
INT32 K_GetMobjLocalSkinNum(const skin_t *skin, const skin_t *localskin, boolean local)
{
return localskin ? (localskin - K_GetSkinArray(local)) : (skin - skins);
}
// //
// returns the players skinnumber // returns the players skinnumber
// accounts for localskins // accounts for localskins
+5 -5
View File
@@ -4016,16 +4016,16 @@ boolean replaynamesloaded = false;
#ifdef HAVE_THREADS #ifdef HAVE_THREADS
I_mutex replayquerymutex; I_mutex replayquerymutex;
// g_in_exiting_signal_handler is an evil hack // I_In_Exiting_Signal_Handler is an evil hack
// to avoid infinite SIGABRT recursion in the signal handler // to avoid infinite SIGABRT recursion in the signal handler
// due to poisoned locks or mach-o kernel not supporting locks in signals // due to poisoned locks or mach-o kernel not supporting locks in signals
// or something like that. idk // or something like that. idk
# define Lock_search_state() if (!g_in_exiting_signal_handler) { I_lock_mutex(&replayquerymutex); } # define Lock_search_state() if (!I_In_Exiting_Signal_Handler()) { I_LockMutex(&replayquerymutex); }
# define Unlock_search_state() if (!g_in_exiting_signal_handler) { I_unlock_mutex(replayquerymutex); } # define Unlock_search_state() if (!I_In_Exiting_Signal_Handler()) { I_UnlockMutex(replayquerymutex); }
#else/*HAVE_THREADS*/ #else /*HAVE_THREADS*/
# define Lock_search_state() # define Lock_search_state()
# define Unlock_search_state() # define Unlock_search_state()
#endif/*HAVE_THREADS*/ #endif /*HAVE_THREADS*/
#define MAXREPLAYQUERY 37 #define MAXREPLAYQUERY 37
+1
View File
@@ -262,6 +262,7 @@ Finish_registration (void)
{ {
CONS_Printf("\n"); CONS_Printf("\n");
CONS_Alert(CONS_NOTICE, "%s\n", rules); CONS_Alert(CONS_NOTICE, "%s\n", rules);
free(rules);
} }
if (registered) if (registered)
+2 -2
View File
@@ -831,7 +831,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{ {
S_StartSound(toucher, special->info->seesound); S_StartSound(toucher, special->info->seesound);
if (player->pflags & PF_NIGHTSMODE) if (UNLIKELY(player->pflags & PF_NIGHTSMODE))
{ {
player->bumpertime = TICRATE/2; player->bumpertime = TICRATE/2;
if (special->threshold > 0) if (special->threshold > 0)
@@ -1131,7 +1131,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
S_StartSound(toucher, special->info->painsound); S_StartSound(toucher, special->info->painsound);
return; return;
} }
else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) else if (UNLIKELY((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
{ {
// Shatter the shield! // Shatter the shield!
-6
View File
@@ -30,8 +30,6 @@ extern "C" {
#define FLOATSPEED (FRACUNIT*4) #define FLOATSPEED (FRACUNIT*4)
//#define VIEWHEIGHTS "41"
// Maximum player score. // Maximum player score.
#define MAXSCORE 999999990 #define MAXSCORE 999999990
@@ -239,14 +237,10 @@ void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move);
boolean P_LookForEnemies(player_t *player); boolean P_LookForEnemies(player_t *player);
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius);
void P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user void P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user
//boolean P_SuperReady(player_t *player);
boolean P_AnalogMove(player_t *player); boolean P_AnalogMove(player_t *player);
/*boolean P_TransferToNextMare(player_t *player);
UINT8 P_FindLowestMare(void);*/
UINT8 P_FindLowestLap(void); UINT8 P_FindLowestLap(void);
UINT8 P_FindHighestLap(void); UINT8 P_FindHighestLap(void);
void P_FindEmerald(void); void P_FindEmerald(void);
//void P_TransferToAxis(player_t *player, INT32 axisnum);
boolean P_PlayerMoving(INT32 pnum); boolean P_PlayerMoving(INT32 pnum);
void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range); void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range);
+9 -9
View File
@@ -919,12 +919,7 @@ static void P_PlayerFlip(mobj_t *mo)
G_GhostAddFlip((INT32) (mo->player - players)); G_GhostAddFlip((INT32) (mo->player - players));
// Flip aiming to match! // Flip aiming to match!
if (UNLIKELY(mo->player->pflags & PF_NIGHTSMODE)) // NiGHTS doesn't use flipcam if (mo->player->pflags & PF_FLIPCAM)
{
if (mo->tracer)
mo->tracer->eflags ^= MFE_VERTICALFLIP;
}
else if (mo->player->pflags & PF_FLIPCAM)
{ {
UINT8 i; UINT8 i;
@@ -946,6 +941,11 @@ static void P_PlayerFlip(mobj_t *mo)
camera[i].z += FixedMul(20*FRACUNIT, mo->scale); camera[i].z += FixedMul(20*FRACUNIT, mo->scale);
} }
} }
else if (UNLIKELY(mo->player->pflags & PF_NIGHTSMODE)) // NiGHTS doesn't use flipcam
{
if (mo->tracer)
mo->tracer->eflags ^= MFE_VERTICALFLIP;
}
} }
// //
@@ -3252,7 +3252,7 @@ void P_CalcChasePostImg(player_t *player, camera_t *thiscam)
player_flipcam = cv_flipcam[pnum].value; player_flipcam = cv_flipcam[pnum].value;
} }
const boolean flipcam = (player_flipcam && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP); const boolean flipcam = (player_flipcam && player->mo->eflags & MFE_VERTICALFLIP && LIKELY(!(player->pflags & PF_NIGHTSMODE)));
UINT8 postimgtype = 0; UINT8 postimgtype = 0;
if (encoremode) if (encoremode)
@@ -8553,7 +8553,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->tracer && mobj->tracer->player) if (mobj->tracer && mobj->tracer->player)
{ {
if (!(mobj->tracer->player->pflags & PF_NIGHTSMODE)) if (LIKELY(!(mobj->tracer->player->pflags & PF_NIGHTSMODE)))
{ {
mobj->flags &= ~MF_NOGRAVITY; mobj->flags &= ~MF_NOGRAVITY;
mobj->flags2 &= ~MF2_DONTDRAW; mobj->flags2 &= ~MF2_DONTDRAW;
@@ -8577,7 +8577,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_SetTarget(&mobj->target, NULL); P_SetTarget(&mobj->target, NULL);
} }
if (mobj->tracer->player->pflags & PF_NIGHTSMODE) if (UNLIKELY(mobj->tracer->player->pflags & PF_NIGHTSMODE))
{ {
if (mobj->tracer->player->bonustime) if (mobj->tracer->player->bonustime)
{ {
+3 -3
View File
@@ -4399,7 +4399,7 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
// The list of specials that activate without floor touch // The list of specials that activate without floor touch
// Check Section 1 // Check Section 1
switch(GETSECSPECIAL(sector->special, 1)) switch (GETSECSPECIAL(sector->special, 1))
{ {
//case 2: // Damage (water) //case 2: // Damage (water)
case 8: // Instant kill case 8: // Instant kill
@@ -4410,7 +4410,7 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
} }
// Check Section 2 // Check Section 2
switch(GETSECSPECIAL(sector->special, 2)) switch (GETSECSPECIAL(sector->special, 2))
{ {
case 2: // Linedef executor (All players needed) case 2: // Linedef executor (All players needed)
case 4: // Linedef executor case 4: // Linedef executor
@@ -4421,7 +4421,7 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
} }
// Check Section 4 // Check Section 4
switch(GETSECSPECIAL(sector->special, 4)) switch (GETSECSPECIAL(sector->special, 4))
{ {
case 2: // Level Exit / GOAL Sector / Flag Return case 2: // Level Exit / GOAL Sector / Flag Return
case 1: // Starpost activator case 1: // Starpost activator
+1 -1
View File
@@ -4109,7 +4109,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
angle -= (angle - thiscam->pitch)/2; angle -= (angle - thiscam->pitch)/2;
} }
if (player->playerstate != PST_DEAD && !((player->pflags & PF_NIGHTSMODE) && player->exiting)) if (player->playerstate != PST_DEAD && LIKELY(!((player->pflags & PF_NIGHTSMODE) && player->exiting)))
angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;' angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;'
if (!camstill && !timeover) // Keep the view still... if (!camstill && !timeover) // Keep the view still...
+1 -2
View File
@@ -437,8 +437,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags)
UINT8* R_GetLocalTranslationColormap(skin_t *skin, skin_t *localskin, skincolors_t color, UINT8 flags, boolean local) UINT8* R_GetLocalTranslationColormap(skin_t *skin, skin_t *localskin, skincolors_t color, UINT8 flags, boolean local)
{ {
const INT32 skinnum = localskin ? (localskin - K_GetSkinArray(local)) : (skin - skins); return RGetTranslationColormap(K_GetMobjLocalSkinNum(skin, localskin, local), color, flags, (localskin && local));
return RGetTranslationColormap(skinnum, color, flags, (localskin && local));
} }
patch_t* R_GetSkinFaceRank(player_t* ply) patch_t* R_GetSkinFaceRank(player_t* ply)
+4 -4
View File
@@ -280,22 +280,22 @@ static void Fov_OnChange(void)
static void FlipCam_OnChange(void) static void FlipCam_OnChange(void)
{ {
SendWeaponPref(); SendWeaponPref(0);
} }
static void FlipCam2_OnChange(void) static void FlipCam2_OnChange(void)
{ {
SendWeaponPref2(); SendWeaponPref(1);
} }
static void FlipCam3_OnChange(void) static void FlipCam3_OnChange(void)
{ {
SendWeaponPref3(); SendWeaponPref(2);
} }
static void FlipCam4_OnChange(void) static void FlipCam4_OnChange(void)
{ {
SendWeaponPref4(); SendWeaponPref(3);
} }
static void Precipstuff_OnChange(void) static void Precipstuff_OnChange(void)
+1
View File
@@ -92,6 +92,7 @@ INT32 R_LocalSkinAvailable(const char *name, boolean local);
// had to move those here Zzz... // had to move those here Zzz...
INT32 K_GetSkinNum(player_t *player); INT32 K_GetSkinNum(player_t *player);
INT32 K_GetMobjSkinNum(const skin_t *skin, boolean local); INT32 K_GetMobjSkinNum(const skin_t *skin, boolean local);
INT32 K_GetMobjLocalSkinNum(const skin_t *skin, const skin_t *localskin, boolean local);
skin_t *K_GetPlayerSkin(player_t *player); skin_t *K_GetPlayerSkin(player_t *player);
skin_t *K_GetMobjSkin(const mobj_t *mobj); skin_t *K_GetMobjSkin(const mobj_t *mobj);
patch_t *K_GetFacePrefix(player_t *player, INT32 skinnum); patch_t *K_GetFacePrefix(player_t *player, INT32 skinnum);
+16 -15
View File
@@ -1577,7 +1577,7 @@ static void write_backtrace(bt_crash_reason_t reason)
static std::thread::id g_main_thread_id; static std::thread::id g_main_thread_id;
#endif #endif
boolean g_in_exiting_signal_handler = false; static volatile sig_atomic_t g_in_exiting_signal_handler = false;
static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_msg, char *signal_name) static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_msg, char *signal_name)
{ {
@@ -1712,6 +1712,11 @@ static void I_ReportSignal(int num, int coredumped)
I_ShowErrorBox(sigttl, sigmsg); I_ShowErrorBox(sigttl, sigmsg);
} }
boolean I_In_Exiting_Signal_Handler(void)
{
return g_in_exiting_signal_handler;
}
#ifndef NEWSIGNALHANDLER #ifndef NEWSIGNALHANDLER
FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
{ {
@@ -1741,21 +1746,17 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
} }
#endif #endif
FUNCNORETURN static ATTRNORETURN void quit_handler(int num) static volatile sig_atomic_t interrupted = false;
{
#ifdef HAVE_THREADS
if (g_main_thread_id != std::this_thread::get_id())
{
// Do not attempt any sort of recovery if this signal triggers off the main thread
signal(num, SIG_DFL);
raise(num);
exit(-2);
}
#endif
signal(num, SIG_DFL); //default signal action boolean I_Interrupted(void)
raise(num); {
I_Quit(); return interrupted;
}
static void quit_handler(int num)
{
(void)num;
interrupted = true;
} }
static void I_RegisterSignals(void) static void I_RegisterSignals(void)
+2 -1
View File
@@ -2027,7 +2027,8 @@ void I_ShutdownGraphics(void)
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
window = NULL; window = NULL;
SDL_QuitSubSystem(SDL_INIT_VIDEO); if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO)
SDL_QuitSubSystem(SDL_INIT_VIDEO);
framebuffer = SDL_FALSE; framebuffer = SDL_FALSE;
} }
+2 -1
View File
@@ -237,7 +237,8 @@ void I_ShutdownSound(void)
Mix_Quit(); Mix_Quit();
#endif #endif
SDL_QuitSubSystem(SDL_INIT_AUDIO); if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO)
SDL_QuitSubSystem(SDL_INIT_AUDIO);
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
if (gme) if (gme)