Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Hanicef/SRB2Classic
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Jisk/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
118 results
Show changes
Commits on Source (90)
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "m_menu.h" #include "m_menu.h"
#include "filesrch.h" #include "filesrch.h"
#include "m_misc.h" #include "m_misc.h"
#include "lua_libs.h"
#ifdef _WINDOWS #ifdef _WINDOWS
#include "win32/win_main.h" #include "win32/win_main.h"
...@@ -918,6 +919,22 @@ static void CON_InputDelChar(void) ...@@ -918,6 +919,22 @@ static void CON_InputDelChar(void)
// ---- // ----
// //
//
// Same as CON_Responder, but is process before everything else, so it cannot be blocked.
//
boolean CON_PreResponder(event_t *ev)
{
if (ev->type == ev_keydown && shiftdown == 1 && ev->key == KEY_ESCAPE)
{
I_SetTextInputMode(con_destlines == 0 ? true : textinputmodeenabledbylua); // inverse, since this is changed next tic.
consoletoggle = true;
return true;
}
return false;
}
//
// Handles console key input // Handles console key input
// //
boolean CON_Responder(event_t *ev) boolean CON_Responder(event_t *ev)
...@@ -957,7 +974,7 @@ boolean CON_Responder(event_t *ev) ...@@ -957,7 +974,7 @@ boolean CON_Responder(event_t *ev)
if (con_destlines == 0 && I_GetTextInputMode()) if (con_destlines == 0 && I_GetTextInputMode())
return false; // some other component is holding keyboard input, don't hijack it! return false; // some other component is holding keyboard input, don't hijack it!
I_SetTextInputMode(con_destlines == 0); // inverse, since this is changed next tic. I_SetTextInputMode(con_destlines == 0 ? true : textinputmodeenabledbylua); // inverse, since this is changed next tic.
consoletoggle = true; consoletoggle = true;
return true; return true;
} }
...@@ -977,7 +994,7 @@ boolean CON_Responder(event_t *ev) ...@@ -977,7 +994,7 @@ boolean CON_Responder(event_t *ev)
// escape key toggle off console // escape key toggle off console
if (key == KEY_ESCAPE) if (key == KEY_ESCAPE)
{ {
I_SetTextInputMode(false); I_SetTextInputMode(textinputmodeenabledbylua);
consoletoggle = true; consoletoggle = true;
return true; return true;
} }
......
...@@ -19,6 +19,7 @@ void CON_Init(void); ...@@ -19,6 +19,7 @@ void CON_Init(void);
void CON_StartRefresh(void); void CON_StartRefresh(void);
void CON_StopRefresh(void); void CON_StopRefresh(void);
boolean CON_PreResponder(event_t *ev);
boolean CON_Responder(event_t *ev); boolean CON_Responder(event_t *ev);
#ifdef HAVE_THREADS #ifdef HAVE_THREADS
......
...@@ -227,6 +227,9 @@ void D_ProcessEvents(void) ...@@ -227,6 +227,9 @@ void D_ProcessEvents(void)
} }
} }
if (CON_PreResponder(ev))
continue;
// Screenshots over everything so that they can be taken anywhere. // Screenshots over everything so that they can be taken anywhere.
if (M_ScreenshotResponder(ev)) if (M_ScreenshotResponder(ev))
continue; // ate the event continue; // ate the event
......
...@@ -598,43 +598,76 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, ...@@ -598,43 +598,76 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Fills a box of pixels using a flat texture as a pattern // Fills a box of pixels using a flat texture as a pattern
// Fixed to properly align like the other draw functions -luigi budd
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum) void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum)
{ {
FOutVector v[4]; FOutVector v[4];
const size_t len = W_LumpLength(flatlumpnum); const size_t len = W_LumpLength(flatlumpnum);
UINT16 flatflag = R_GetFlatSize(len) - 1; UINT16 flatflag = R_GetFlatSize(len);
double dflatsize = (double)(flatflag + 1); double dflatsize = (double)(flatflag);
// compilers are COOL!
float dup = (float)vid.dup;
float fx = (float)x * dup;
float fy = (float)y * dup;
float fw = (float)w * dup;
float fh = (float)h * dup;
/*
fx *= dup;
fy *= dup;
fw *= dup;
fh *= dup;
*/
if (fw <= 0 || fh <= 0)
return;
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * vid.dup) > 1.0E-36f)
{
fx += ((float)vid.width - ((float)BASEVIDWIDTH * vid.dup)) / 2;
}
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * vid.dup) > 1.0E-36f)
{
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * vid.dup)) / 2;
}
if (fx >= vid.width || fy >= vid.height)
return;
fx = -1.0f + (fx / (vid.width / 2.0f));
fy = 1.0f - (fy / (vid.height / 2.0f));
fw /= vid.width / 2;
fh /= vid.height / 2;
// 3--2 // 3--2
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
// position vertices
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
v[0].x = v[3].x = (x - 160.0f)/160.0f; v[0].y = v[1].y = fy;
v[2].x = v[1].x = ((x+w) - 160.0f)/160.0f; v[2].y = v[3].y = fy - fh;
v[0].y = v[1].y = -(y - 100.0f)/100.0f;
v[2].y = v[3].y = -((y+h) - 100.0f)/100.0f;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].s = v[3].s = (float)((x & flatflag)/dflatsize); // sides
v[2].s = v[1].s = (float)(v[0].s + w/dflatsize); v[0].s = v[3].s = (float)(flatflag/dflatsize) * 2;
v[0].t = v[1].t = (float)((y & flatflag)/dflatsize); v[2].s = v[1].s = (float)(v[0].s + w/dflatsize) * 2;
v[2].t = v[3].t = (float)(v[0].t + h/dflatsize);
HWR_GetRawFlat(flatlumpnum); // top/bottom
v[0].t = v[1].t = (float)(flatflag/dflatsize) * 2;
v[2].t = v[3].t = (float)(v[0].t + h/dflatsize) * 2;
//Hurdler: Boris, the same comment as above... but maybe for pics // needed to texture the poly
// it not a problem since they don't have any transparent pixel HWR_GetRawFlat(flatlumpnum);
// if I'm right !?
// BTW, I see we put 0 for PFs, and If I'm right, that
// means we take the previous PFs as default
// how can we be sure they are ok?
HWD.pfnDrawPolygon(NULL, v, 4, PF_NoDepthTest); //PF_Translucent); HWD.pfnDrawPolygon(NULL, v, 4, PF_NoDepthTest); //PF_Translucent);
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Fade down the screen so that the menu drawn on top of it looks brighter // Fade down the screen so that the menu drawn on top of it looks brighter
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include "lua_hud.h" #include "lua_hud.h"
#include "lua_hudlib_drawlist.h" #include "lua_hudlib_drawlist.h"
#include "lua_hook.h" #include "lua_hook.h"
#include "lua_libs.h"
// coords are scaled // coords are scaled
#define HU_INPUTX 0 #define HU_INPUTX 0
...@@ -395,8 +396,11 @@ void HU_AddChatText(const char *text, boolean playsound) ...@@ -395,8 +396,11 @@ void HU_AddChatText(const char *text, boolean playsound)
if (OLDCHAT) // if we're using oldchat, print directly in console if (OLDCHAT) // if we're using oldchat, print directly in console
CONS_Printf("%s\n", text); CONS_Printf("%s\n", text);
else // if we aren't, still save the message to log.txt else // if we aren't, still save the message to log.txt
CON_LogMessage(va("%s\n", text)); {
CON_LogMessage(text);
CON_LogMessage("\n"); // Add newline. Don't use va for that, since `text` might be refering to va's buffer itself
}
} }
/** Runs a say command, sending an ::XD_SAY message. /** Runs a say command, sending an ::XD_SAY message.
...@@ -1013,7 +1017,7 @@ static void HU_sendChatMessage(void) ...@@ -1013,7 +1017,7 @@ static void HU_sendChatMessage(void)
void HU_clearChatChars(void) void HU_clearChatChars(void)
{ {
memset(w_chat, '\0', sizeof(w_chat)); memset(w_chat, '\0', sizeof(w_chat));
I_SetTextInputMode(false); I_SetTextInputMode(textinputmodeenabledbylua);
chat_on = false; chat_on = false;
c_input = 0; c_input = 0;
...@@ -1150,7 +1154,7 @@ boolean HU_Responder(event_t *ev) ...@@ -1150,7 +1154,7 @@ boolean HU_Responder(event_t *ev)
if (!CHAT_MUTE) if (!CHAT_MUTE)
HU_sendChatMessage(); HU_sendChatMessage();
I_SetTextInputMode(false); I_SetTextInputMode(textinputmodeenabledbylua);
chat_on = false; chat_on = false;
c_input = 0; // reset input cursor c_input = 0; // reset input cursor
chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :) chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :)
...@@ -1161,7 +1165,7 @@ boolean HU_Responder(event_t *ev) ...@@ -1161,7 +1165,7 @@ boolean HU_Responder(event_t *ev)
|| c == gamecontrol[GC_TEAMKEY][0] || c == gamecontrol[GC_TEAMKEY][1]) || c == gamecontrol[GC_TEAMKEY][0] || c == gamecontrol[GC_TEAMKEY][1])
&& c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle. && c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle.
{ {
I_SetTextInputMode(false); I_SetTextInputMode(textinputmodeenabledbylua);
chat_on = false; chat_on = false;
c_input = 0; // reset input cursor c_input = 0; // reset input cursor
I_UpdateMouseGrab(); I_UpdateMouseGrab();
......
...@@ -461,15 +461,29 @@ static int camera_set(lua_State *L) ...@@ -461,15 +461,29 @@ static int camera_set(lua_State *L)
static int libd_patchExists(lua_State *L) static int libd_patchExists(lua_State *L)
{ {
HUDONLY
lua_pushboolean(L, W_LumpExists(luaL_checkstring(L, 1))); lua_pushboolean(L, W_LumpExists(luaL_checkstring(L, 1)));
return 1; return 1;
} }
static int libd_cachePatch(lua_State *L) static int libd_cachePatch(lua_State *L)
{ {
HUDONLY const char *name = luaL_checkstring(L, 1);
LUA_PushUserdata(L, W_CachePatchLongName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH); patch_t *patch = W_CachePatchLongName(name, PU_PATCH);
#ifdef ROTSPRITE
if (lua_isnumber(L, 2))
{
angle_t rollangle = luaL_checkangle(L, 2);
INT32 rot = R_GetRollAngle(rollangle);
if (rot) {
patch_t *rotpatch = Patch_GetRotated(patch, rot, false);
LUA_PushUserdata(L, rotpatch, META_PATCH);
return 1;
}
}
#endif
LUA_PushUserdata(L, patch, META_PATCH);
return 1; return 1;
} }
...@@ -481,7 +495,6 @@ static int libd_getSpritePatch(lua_State *L) ...@@ -481,7 +495,6 @@ static int libd_getSpritePatch(lua_State *L)
UINT8 angle = 0; UINT8 angle = 0;
spritedef_t *sprdef; spritedef_t *sprdef;
spriteframe_t *sprframe; spriteframe_t *sprframe;
HUDONLY
if (lua_isnumber(L, 1)) // sprite number given, e.g. SPR_THOK if (lua_isnumber(L, 1)) // sprite number given, e.g. SPR_THOK
{ {
...@@ -555,7 +568,6 @@ static int libd_getSprite2Patch(lua_State *L) ...@@ -555,7 +568,6 @@ static int libd_getSprite2Patch(lua_State *L)
spritedef_t *sprdef; spritedef_t *sprdef;
spriteframe_t *sprframe; spriteframe_t *sprframe;
boolean super = false; // add SPR2F_SUPER to sprite2 if true boolean super = false; // add SPR2F_SUPER to sprite2 if true
HUDONLY
// get skin first! // get skin first!
if (lua_isnumber(L, 1)) // find skin by number if (lua_isnumber(L, 1)) // find skin by number
...@@ -1130,13 +1142,12 @@ static int libd_levelTitleHeight(lua_State *L) ...@@ -1130,13 +1142,12 @@ static int libd_levelTitleHeight(lua_State *L)
static int libd_getColormap(lua_State *L) static int libd_getColormap(lua_State *L)
{ {
HUDONLY
INT32 skinnum = TC_DEFAULT; INT32 skinnum = TC_DEFAULT;
skincolornum_t color = luaL_optinteger(L, 2, 0); skincolornum_t color = luaL_optinteger(L, 2, 0);
UINT8* colormap = NULL; UINT8* colormap = NULL;
int translation_id = -1; int translation_id = -1;
HUDONLY
if (lua_isnoneornil(L, 1)) if (lua_isnoneornil(L, 1))
; // defaults to TC_DEFAULT ; // defaults to TC_DEFAULT
else if (lua_type(L, 1) == LUA_TNUMBER) // skin number else if (lua_type(L, 1) == LUA_TNUMBER) // skin number
...@@ -1176,9 +1187,10 @@ static int libd_getColormap(lua_State *L) ...@@ -1176,9 +1187,10 @@ static int libd_getColormap(lua_State *L)
static int libd_getStringColormap(lua_State *L) static int libd_getStringColormap(lua_State *L)
{ {
HUDONLY
INT32 flags = luaL_checkinteger(L, 1); INT32 flags = luaL_checkinteger(L, 1);
UINT8* colormap = NULL; UINT8* colormap = NULL;
HUDONLY
colormap = V_GetStringColormap(flags & V_CHARCOLORMASK); colormap = V_GetStringColormap(flags & V_CHARCOLORMASK);
if (colormap) { if (colormap) {
LUA_PushUserdata(L, colormap, META_COLORMAP); // push as META_COLORMAP userdata, specifically for patches to use! LUA_PushUserdata(L, colormap, META_COLORMAP); // push as META_COLORMAP userdata, specifically for patches to use!
...@@ -1189,6 +1201,7 @@ static int libd_getStringColormap(lua_State *L) ...@@ -1189,6 +1201,7 @@ static int libd_getStringColormap(lua_State *L)
static int libd_getSectorColormap(lua_State *L) static int libd_getSectorColormap(lua_State *L)
{ {
HUDONLY
boolean has_sector = false; boolean has_sector = false;
sector_t *sector = NULL; sector_t *sector = NULL;
if (!lua_isnoneornil(L, 1)) if (!lua_isnoneornil(L, 1))
...@@ -1264,21 +1277,18 @@ static int libd_fadeScreen(lua_State *L) ...@@ -1264,21 +1277,18 @@ static int libd_fadeScreen(lua_State *L)
static int libd_width(lua_State *L) static int libd_width(lua_State *L)
{ {
HUDONLY
lua_pushinteger(L, vid.width); // push screen width lua_pushinteger(L, vid.width); // push screen width
return 1; return 1;
} }
static int libd_height(lua_State *L) static int libd_height(lua_State *L)
{ {
HUDONLY
lua_pushinteger(L, vid.height); // push screen height lua_pushinteger(L, vid.height); // push screen height
return 1; return 1;
} }
static int libd_dup(lua_State *L) static int libd_dup(lua_State *L)
{ {
HUDONLY
lua_pushinteger(L, vid.dup); // push integral scale (patch scale) lua_pushinteger(L, vid.dup); // push integral scale (patch scale)
lua_pushfixed(L, vid.fdup); // push fixed point scale (position scale) lua_pushfixed(L, vid.fdup); // push fixed point scale (position scale)
return 2; return 2;
...@@ -1286,7 +1296,6 @@ static int libd_dup(lua_State *L) ...@@ -1286,7 +1296,6 @@ static int libd_dup(lua_State *L)
static int libd_renderer(lua_State *L) static int libd_renderer(lua_State *L)
{ {
HUDONLY
switch (rendermode) { switch (rendermode) {
case render_opengl: lua_pushliteral(L, "opengl"); break; // OpenGL renderer case render_opengl: lua_pushliteral(L, "opengl"); break; // OpenGL renderer
case render_soft: lua_pushliteral(L, "software"); break; // Software renderer case render_soft: lua_pushliteral(L, "software"); break; // Software renderer
...@@ -1300,14 +1309,12 @@ static int libd_renderer(lua_State *L) ...@@ -1300,14 +1309,12 @@ static int libd_renderer(lua_State *L)
static int libd_RandomFixed(lua_State *L) static int libd_RandomFixed(lua_State *L)
{ {
HUDONLY
lua_pushfixed(L, M_RandomFixed()); lua_pushfixed(L, M_RandomFixed());
return 1; return 1;
} }
static int libd_RandomByte(lua_State *L) static int libd_RandomByte(lua_State *L)
{ {
HUDONLY
lua_pushinteger(L, M_RandomByte()); lua_pushinteger(L, M_RandomByte());
return 1; return 1;
} }
...@@ -1316,7 +1323,6 @@ static int libd_RandomKey(lua_State *L) ...@@ -1316,7 +1323,6 @@ static int libd_RandomKey(lua_State *L)
{ {
INT32 a = (INT32)luaL_checkinteger(L, 1); INT32 a = (INT32)luaL_checkinteger(L, 1);
HUDONLY
lua_pushinteger(L, M_RandomKey(a)); lua_pushinteger(L, M_RandomKey(a));
return 1; return 1;
} }
...@@ -1326,7 +1332,6 @@ static int libd_RandomRange(lua_State *L) ...@@ -1326,7 +1332,6 @@ static int libd_RandomRange(lua_State *L)
INT32 a = (INT32)luaL_checkinteger(L, 1); INT32 a = (INT32)luaL_checkinteger(L, 1);
INT32 b = (INT32)luaL_checkinteger(L, 2); INT32 b = (INT32)luaL_checkinteger(L, 2);
HUDONLY
lua_pushinteger(L, M_RandomRange(a, b)); lua_pushinteger(L, M_RandomRange(a, b));
return 1; return 1;
} }
...@@ -1334,7 +1339,6 @@ static int libd_RandomRange(lua_State *L) ...@@ -1334,7 +1339,6 @@ static int libd_RandomRange(lua_State *L)
// Macros. // Macros.
static int libd_SignedRandom(lua_State *L) static int libd_SignedRandom(lua_State *L)
{ {
HUDONLY
lua_pushinteger(L, M_SignedRandom()); lua_pushinteger(L, M_SignedRandom());
return 1; return 1;
} }
...@@ -1342,7 +1346,6 @@ static int libd_SignedRandom(lua_State *L) ...@@ -1342,7 +1346,6 @@ static int libd_SignedRandom(lua_State *L)
static int libd_RandomChance(lua_State *L) static int libd_RandomChance(lua_State *L)
{ {
fixed_t p = luaL_checkfixed(L, 1); fixed_t p = luaL_checkfixed(L, 1);
HUDONLY
lua_pushboolean(L, M_RandomChance(p)); lua_pushboolean(L, M_RandomChance(p));
return 1; return 1;
} }
...@@ -1351,7 +1354,6 @@ static int libd_RandomChance(lua_State *L) ...@@ -1351,7 +1354,6 @@ static int libd_RandomChance(lua_State *L)
// Could as well be thrown in global vars for ease of access but I guess it makes sense for it to be a HUD fn // Could as well be thrown in global vars for ease of access but I guess it makes sense for it to be a HUD fn
static int libd_getlocaltransflag(lua_State *L) static int libd_getlocaltransflag(lua_State *L)
{ {
HUDONLY
lua_pushinteger(L, (10-st_translucency)*V_10TRANS); lua_pushinteger(L, (10-st_translucency)*V_10TRANS);
return 1; return 1;
} }
...@@ -1359,7 +1361,6 @@ static int libd_getlocaltransflag(lua_State *L) ...@@ -1359,7 +1361,6 @@ static int libd_getlocaltransflag(lua_State *L)
// Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int // Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int
static int libd_getusertransflag(lua_State *L) static int libd_getusertransflag(lua_State *L)
{ {
HUDONLY
lua_pushinteger(L, (10-cv_translucenthud.value)*V_10TRANS); // A bit weird that it's called "translucenthud" yet 10 is fully opaque :V lua_pushinteger(L, (10-cv_translucenthud.value)*V_10TRANS); // A bit weird that it's called "translucenthud" yet 10 is fully opaque :V
return 1; return 1;
} }
...@@ -1452,6 +1453,26 @@ static luaL_Reg lib_hud[] = { ...@@ -1452,6 +1453,26 @@ static luaL_Reg lib_hud[] = {
{"disable", lib_huddisable}, {"disable", lib_huddisable},
{"enabled", lib_hudenabled}, {"enabled", lib_hudenabled},
{"add", lib_hudadd}, {"add", lib_hudadd},
{"patchExists", libd_patchExists},
{"cachePatch", libd_cachePatch},
{"getSpritePatch", libd_getSpritePatch},
{"getSprite2Patch", libd_getSprite2Patch},
{"width", libd_width},
{"height", libd_height},
{"scale", libd_dup},
{"renderer", libd_renderer},
{NULL, NULL}
};
// globalized client_side random functions.
static luaL_Reg lib_randomclient[] = {
// m_random
{"localFixed",libd_RandomFixed},
{"localByte",libd_RandomByte},
{"localKey",libd_RandomKey},
{"localRange",libd_RandomRange},
{"localSignedRandom",libd_SignedRandom}, // MACRO
{"localChance",libd_RandomChance}, // MACRO
{NULL, NULL} {NULL, NULL}
}; };
...@@ -1478,6 +1499,7 @@ int LUA_HudLib(lua_State *L) ...@@ -1478,6 +1499,7 @@ int LUA_HudLib(lua_State *L)
LUA_RegisterGlobalUserdata(L, "hudinfo", lib_getHudInfo, NULL, lib_hudinfolen); LUA_RegisterGlobalUserdata(L, "hudinfo", lib_getHudInfo, NULL, lib_hudinfolen);
luaL_register(L, "hud", lib_hud); luaL_register(L, "hud", lib_hud);
luaL_register(L, "random", lib_randomclient);
return 0; return 0;
} }
......
...@@ -10,16 +10,19 @@ ...@@ -10,16 +10,19 @@
/// \brief input library for Lua scripting /// \brief input library for Lua scripting
#include "doomdef.h" #include "doomdef.h"
#include "doomstat.h"
#include "fastcmp.h" #include "fastcmp.h"
#include "g_input.h" #include "g_input.h"
#include "g_game.h" #include "g_game.h"
#include "hu_stuff.h" #include "hu_stuff.h"
#include "i_system.h" #include "i_system.h"
#include "console.h"
#include "lua_script.h" #include "lua_script.h"
#include "lua_libs.h" #include "lua_libs.h"
boolean mousegrabbedbylua = true; boolean mousegrabbedbylua = true;
boolean textinputmodeenabledbylua = false;
boolean ignoregameinputs = false; boolean ignoregameinputs = false;
/////////////// ///////////////
...@@ -131,13 +134,15 @@ static int lib_getCursorPosition(lua_State *L) ...@@ -131,13 +134,15 @@ static int lib_getCursorPosition(lua_State *L)
static int lib_setTextInputMode(lua_State *L) static int lib_setTextInputMode(lua_State *L)
{ {
I_SetTextInputMode(luaL_checkboolean(L, 1)); textinputmodeenabledbylua = luaL_checkboolean(L, 1);
if (!(menuactive || CON_Ready() || chat_on))
I_SetTextInputMode(textinputmodeenabledbylua);
return 0; return 0;
} }
static int lib_getTextInputMode(lua_State *L) static int lib_getTextInputMode(lua_State *L)
{ {
lua_pushinteger(L, I_GetTextInputMode()); lua_pushinteger(L, textinputmodeenabledbylua);
return 1; return 1;
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
extern lua_State *gL; extern lua_State *gL;
extern boolean mousegrabbedbylua; extern boolean mousegrabbedbylua;
extern boolean textinputmodeenabledbylua;
extern boolean ignoregameinputs; extern boolean ignoregameinputs;
#define MUTABLE_TAGS #define MUTABLE_TAGS
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "p_setup.h" #include "p_setup.h"
#include "f_finale.h" #include "f_finale.h"
#include "lua_hook.h" #include "lua_hook.h"
#include "lua_libs.h"
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
...@@ -3793,6 +3794,7 @@ void M_ClearMenus(boolean callexitmenufunc) ...@@ -3793,6 +3794,7 @@ void M_ClearMenus(boolean callexitmenufunc)
hidetitlemap = false; hidetitlemap = false;
I_UpdateMouseGrab(); I_UpdateMouseGrab();
I_SetTextInputMode(textinputmodeenabledbylua);
} }
// //
......
...@@ -1720,7 +1720,7 @@ char *va(const char *format, ...) ...@@ -1720,7 +1720,7 @@ char *va(const char *format, ...)
static char string[1024]; static char string[1024];
va_start(argptr, format); va_start(argptr, format);
vsprintf(string, format, argptr); vsnprintf(string, 1024, format, argptr);
va_end(argptr); va_end(argptr);
return string; return string;
......
...@@ -127,8 +127,8 @@ perfstatrow_t commoncounter_rows[] = { ...@@ -127,8 +127,8 @@ perfstatrow_t commoncounter_rows[] = {
}; };
perfstatrow_t interpolation_rows[] = { perfstatrow_t interpolation_rows[] = {
{"intpfrc", "Interp frac: ", &ps_interp_frac, PS_TIME}, {"intpfrc", "Interp frac: ", &ps_interp_frac, 0}, // PS_TIME is not applicable here, as it is meant for I_GetPreciseTime
{"intplag", "Interp lag: ", &ps_interp_lag, PS_TIME}, {"intplag", "Interp lag: ", &ps_interp_lag, 0},
{0} {0}
}; };
......
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 2013-2024 by Sonic Team Junior. // Copyright (C) 2013-2025 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -28,6 +28,7 @@ tokenizer_t *Tokenizer_Open(const char *inputString, size_t len, unsigned numTok ...@@ -28,6 +28,7 @@ tokenizer_t *Tokenizer_Open(const char *inputString, size_t len, unsigned numTok
tokenizer->endPos = 0; tokenizer->endPos = 0;
tokenizer->inputLength = 0; tokenizer->inputLength = 0;
tokenizer->inComment = 0; tokenizer->inComment = 0;
tokenizer->stringNeedsEscaping = false;
tokenizer->inString = 0; tokenizer->inString = 0;
tokenizer->get = Tokenizer_Read; tokenizer->get = Tokenizer_Read;
...@@ -92,6 +93,124 @@ static void DetectComment(tokenizer_t *tokenizer, UINT32 *pos) ...@@ -92,6 +93,124 @@ static void DetectComment(tokenizer_t *tokenizer, UINT32 *pos)
tokenizer->inComment = 2; tokenizer->inComment = 2;
} }
// This function detects escape sequences in a string and attempts to convert them.
static size_t EscapeString(char *output, const char *input, size_t inputLength)
{
const char *end = input + inputLength;
size_t i = 0;
while (input < end)
{
char chr = *input++;
if (chr == '\\')
{
chr = *input++;
switch (chr)
{
case 'n':
output[i] = '\n';
i++;
break;
case 't':
output[i] = '\t';
i++;
break;
case '\\':
output[i] = '\\';
i++;
break;
case '"':
output[i] = '\"';
i++;
break;
case 'x': {
int out = 0, c;
int j = 0;
chr = *input++;
for (j = 0; j < 5 && isxdigit(chr); j++)
{
c = ((chr <= '9') ? (chr - '0') : (tolower(chr) - 'a' + 10));
out = (out << 4) | c;
chr = *input++;
}
input--;
switch (j)
{
case 4:
output[i] = (out >> 8) & 0xFF;
i++;
/* FALLTHRU */
case 2:
output[i] = out & 0xFF;
i++;
break;
default:
// TODO: Displaying parsing errors properly will require
// some refactoring of the tokenizer itself. For now,
// this function will silently return an empty string
// if it encounters a malformed escape sequence.
// This situation cannot happen for i.e. UDMF comments,
// so it's okay to do this right now.
// CONS_Alert(CONS_WARNING, "Escape sequence has wrong size\n");
i = 0;
goto done;
}
break;
}
default:
if (isdigit(chr))
{
int out = 0;
int j = 0;
do
{
out = 10*out + (chr - '0');
chr = *input++;
} while (++j < 3 && isdigit(chr));
input--;
if (out > 255)
{
// CONS_Alert(CONS_WARNING, "Escape sequence is too large\n");
i = 0;
goto done;
}
output[i] = out;
i++;
}
else
{
// CONS_Alert(CONS_WARNING, "Unknown escape sequence '\\%c'\n", chr);
i = 0;
goto done;
}
break;
}
}
else
{
output[i] = chr;
i++;
}
}
done:
output[i] = '\0';
i++;
return i;
}
static void Tokenizer_ReadTokenString(tokenizer_t *tokenizer, UINT32 i) static void Tokenizer_ReadTokenString(tokenizer_t *tokenizer, UINT32 i)
{ {
UINT32 tokenLength = tokenizer->endPos - tokenizer->startPos; UINT32 tokenLength = tokenizer->endPos - tokenizer->startPos;
...@@ -101,10 +220,46 @@ static void Tokenizer_ReadTokenString(tokenizer_t *tokenizer, UINT32 i) ...@@ -101,10 +220,46 @@ static void Tokenizer_ReadTokenString(tokenizer_t *tokenizer, UINT32 i)
// Assign the memory. Don't forget an extra byte for the end of the string! // Assign the memory. Don't forget an extra byte for the end of the string!
tokenizer->token[i] = (char *)Z_Malloc(tokenizer->capacity[i] * sizeof(char), PU_STATIC, NULL); tokenizer->token[i] = (char *)Z_Malloc(tokenizer->capacity[i] * sizeof(char), PU_STATIC, NULL);
} }
// Copy the string. // Copy the string.
M_Memcpy(tokenizer->token[i], tokenizer->input + tokenizer->startPos, (size_t)tokenLength); if (tokenizer->stringNeedsEscaping)
// Make the final character NUL. {
tokenizer->token[i][tokenLength] = '\0'; EscapeString(tokenizer->token[i], tokenizer->input + tokenizer->startPos, (size_t)tokenLength);
}
else
{
M_Memcpy(tokenizer->token[i], tokenizer->input + tokenizer->startPos, (size_t)tokenLength);
// Make the final character NUL.
tokenizer->token[i][tokenLength] = '\0';
}
}
static void ScanString(tokenizer_t *tokenizer)
{
tokenizer->stringNeedsEscaping = false;
while (tokenizer->input[tokenizer->endPos] != '"' && tokenizer->endPos < tokenizer->inputLength)
{
if (!DetectLineBreak(tokenizer, tokenizer->endPos))
{
// Skip one character ahead if this looks like an escape sequence
if (tokenizer->input[tokenizer->endPos] == '\\')
{
tokenizer->stringNeedsEscaping = true;
tokenizer->endPos++;
// Oh. Naughty. We hit the end of the input.
// Stop scanning, then.
if (tokenizer->endPos == tokenizer->inputLength)
return;
DetectLineBreak(tokenizer, tokenizer->endPos);
}
}
tokenizer->endPos++;
}
} }
const char *Tokenizer_Read(tokenizer_t *tokenizer, UINT32 i) const char *Tokenizer_Read(tokenizer_t *tokenizer, UINT32 i)
...@@ -117,11 +272,7 @@ const char *Tokenizer_Read(tokenizer_t *tokenizer, UINT32 i) ...@@ -117,11 +272,7 @@ const char *Tokenizer_Read(tokenizer_t *tokenizer, UINT32 i)
// If in a string, return the entire string within quotes, except without the quotes. // If in a string, return the entire string within quotes, except without the quotes.
if (tokenizer->inString == 1) if (tokenizer->inString == 1)
{ {
while (tokenizer->input[tokenizer->endPos] != '"' && tokenizer->endPos < tokenizer->inputLength) ScanString(tokenizer);
{
DetectLineBreak(tokenizer, tokenizer->endPos);
tokenizer->endPos++;
}
Tokenizer_ReadTokenString(tokenizer, i); Tokenizer_ReadTokenString(tokenizer, i);
tokenizer->inString = 2; tokenizer->inString = 2;
...@@ -134,6 +285,7 @@ const char *Tokenizer_Read(tokenizer_t *tokenizer, UINT32 i) ...@@ -134,6 +285,7 @@ const char *Tokenizer_Read(tokenizer_t *tokenizer, UINT32 i)
tokenizer->token[i][0] = tokenizer->input[tokenizer->startPos]; tokenizer->token[i][0] = tokenizer->input[tokenizer->startPos];
tokenizer->token[i][1] = '\0'; tokenizer->token[i][1] = '\0';
tokenizer->inString = 0; tokenizer->inString = 0;
tokenizer->stringNeedsEscaping = false;
return tokenizer->token[i]; return tokenizer->token[i];
} }
...@@ -281,11 +433,7 @@ const char *Tokenizer_SRB2Read(tokenizer_t *tokenizer, UINT32 i) ...@@ -281,11 +433,7 @@ const char *Tokenizer_SRB2Read(tokenizer_t *tokenizer, UINT32 i)
else if (tokenizer->input[tokenizer->startPos] == '"') else if (tokenizer->input[tokenizer->startPos] == '"')
{ {
tokenizer->endPos = ++tokenizer->startPos; tokenizer->endPos = ++tokenizer->startPos;
while (tokenizer->input[tokenizer->endPos] != '"' && tokenizer->endPos < tokenizer->inputLength) ScanString(tokenizer);
{
DetectLineBreak(tokenizer, tokenizer->endPos);
tokenizer->endPos++;
}
Tokenizer_ReadTokenString(tokenizer, i); Tokenizer_ReadTokenString(tokenizer, i);
tokenizer->endPos++; tokenizer->endPos++;
......
// SONIC ROBO BLAST 2 // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 2013-2024 by Sonic Team Junior. // Copyright (C) 2013-2025 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
...@@ -26,6 +26,7 @@ typedef struct Tokenizer ...@@ -26,6 +26,7 @@ typedef struct Tokenizer
UINT32 inputLength; UINT32 inputLength;
UINT8 inComment; // 0 = not in comment, 1 = // Single-line, 2 = /* Multi-line */ UINT8 inComment; // 0 = not in comment, 1 = // Single-line, 2 = /* Multi-line */
UINT8 inString; // 0 = not in string, 1 = in string, 2 = just left string UINT8 inString; // 0 = not in string, 1 = in string, 2 = just left string
boolean stringNeedsEscaping;
int line; int line;
const char *(*get)(struct Tokenizer*, UINT32); const char *(*get)(struct Tokenizer*, UINT32);
} tokenizer_t; } tokenizer_t;
......
...@@ -54,6 +54,8 @@ static boolean IsDownloadingFile(void) ...@@ -54,6 +54,8 @@ static boolean IsDownloadingFile(void)
static void DrawConnectionStatusBox(void) static void DrawConnectionStatusBox(void)
{ {
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1); M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1);
if (cl_mode != CL_DOWNLOADSAVEGAME && filedownload.current != -1)
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-46-8, 32, 1);
if (cl_mode == CL_CONFIRMCONNECT || IsDownloadingFile()) if (cl_mode == CL_CONFIRMCONNECT || IsDownloadingFile())
return; return;
...@@ -84,6 +86,33 @@ static void DrawFileProgress(fileneeded_t *file, int y) ...@@ -84,6 +86,33 @@ static void DrawFileProgress(fileneeded_t *file, int y)
V_DrawRightAlignedString(BASEVIDWIDTH/2+128, y, V_20TRANS|V_MONOSPACE, va("%3.1fK/s ", ((double)getbps)/1024)); V_DrawRightAlignedString(BASEVIDWIDTH/2+128, y, V_20TRANS|V_MONOSPACE, va("%3.1fK/s ", ((double)getbps)/1024));
} }
static void DrawOverallProgress(int y)
{
UINT32 totalsize = filedownload.totalsize;
INT32 downloadedfiles = filedownload.completednum;
INT32 totalfiles = filedownload.remaining + filedownload.completednum;
INT32 downloaded = filedownload.completedsize;
if (fileneeded[filedownload.current].currentsize != fileneeded[filedownload.current].totalsize)
downloaded = filedownload.completedsize + fileneeded[filedownload.current].currentsize;
INT32 dldlength = (INT32)((downloaded/(double)totalsize) * 256);
if (dldlength > 256)
dldlength = 256;
V_DrawFill(BASEVIDWIDTH/2-128, y, 256, 8, 111);
V_DrawFill(BASEVIDWIDTH/2-128, y, dldlength, 8, 96);
const char *progress_str;
if (totalsize >= 1024*1024)
progress_str = va(" %.2fMiB/%.2fMiB", (double)downloaded / (1024*1024), (double)totalsize / (1024*1024));
else if (totalsize < 1024)
progress_str = va(" %4uB/%4uB", downloaded, totalsize);
else
progress_str = va(" %.2fKiB/%.2fKiB", (double)downloaded / 1024, (double)totalsize / 1024);
V_DrawString(BASEVIDWIDTH/2-128, y, V_20TRANS|V_ALLOWLOWERCASE, progress_str);
V_DrawRightAlignedString(BASEVIDWIDTH/2+128, y, V_20TRANS|V_ALLOWLOWERCASE, va("%2u/%2u Files ", downloadedfiles+1, totalfiles));
}
// //
// CL_DrawConnectionStatus // CL_DrawConnectionStatus
// //
...@@ -96,7 +125,7 @@ static void CL_DrawConnectionStatus(void) ...@@ -96,7 +125,7 @@ static void CL_DrawConnectionStatus(void)
// Draw background fade // Draw background fade
V_DrawFadeScreen(0xFF00, 16); // force default V_DrawFadeScreen(0xFF00, 16); // force default
if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_DOWNLOADHTTPFILES && cl_mode != CL_LOADFILES) if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_DOWNLOADHTTPFILES && cl_mode != CL_LOADFILES && cl_mode != CL_CHECKFILES && cl_mode != CL_ASKFULLFILELIST)
{ {
INT32 animtime = ((ccstime / 4) & 15) + 16; INT32 animtime = ((ccstime / 4) & 15) + 16;
UINT8 palstart; UINT8 palstart;
...@@ -179,6 +208,31 @@ static void CL_DrawConnectionStatus(void) ...@@ -179,6 +208,31 @@ static void CL_DrawConnectionStatus(void)
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE,
va(" %2u/%2u files",loadcompletednum,fileneedednum)); va(" %2u/%2u files",loadcompletednum,fileneedednum));
} }
else if ((cl_mode == CL_CHECKFILES) || (cl_mode == CL_ASKFULLFILELIST))
{
INT32 totalfileslength;
INT32 checkcompletednum = 0;
INT32 i;
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_YELLOWMAP, "Press ESC to abort");
//ima just count files here
if (fileneeded)
{
for (i = 0; i < fileneedednum; i++)
if (fileneeded[i].status != FS_NOTCHECKED)
checkcompletednum++;
}
// Check progress
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, "Checking server addon list...");
totalfileslength = (INT32)((checkcompletednum/(double)(fileneedednum)) * 256);
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1);
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, 256, 8, 111);
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, totalfileslength, 8, 96);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE,
va(" %2u/%2u Files",checkcompletednum,fileneedednum));
}
else if (filedownload.current != -1) else if (filedownload.current != -1)
{ {
char tempname[28]; char tempname[28];
...@@ -224,7 +278,7 @@ static void CL_DrawConnectionStatus(void) ...@@ -224,7 +278,7 @@ static void CL_DrawConnectionStatus(void)
const char *download_str = M_GetText("Downloading \"%s\""); const char *download_str = M_GetText("Downloading \"%s\"");
#endif #endif
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_ALLOWLOWERCASE|V_YELLOWMAP, V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-46-24, V_ALLOWLOWERCASE|V_YELLOWMAP,
va(download_str, tempname)); va(download_str, tempname));
// Rusty: actually lets do this instead // Rusty: actually lets do this instead
...@@ -244,16 +298,18 @@ static void CL_DrawConnectionStatus(void) ...@@ -244,16 +298,18 @@ static void CL_DrawConnectionStatus(void)
strlcpy(tempname, http_source, sizeof(tempname)); strlcpy(tempname, http_source, sizeof(tempname));
} }
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_ALLOWLOWERCASE|V_YELLOWMAP, V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-46-16, V_ALLOWLOWERCASE|V_YELLOWMAP,
va(M_GetText("from %s"), tempname)); va(M_GetText("from %s"), tempname));
} }
else else
{ {
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_ALLOWLOWERCASE|V_YELLOWMAP, V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-46-16, V_ALLOWLOWERCASE|V_YELLOWMAP,
M_GetText("from the server")); M_GetText("from the server"));
} }
DrawFileProgress(file, BASEVIDHEIGHT-46);
DrawFileProgress(file, BASEVIDHEIGHT-16); V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-14, V_ALLOWLOWERCASE|V_YELLOWMAP, "Total Progress");
DrawOverallProgress(BASEVIDHEIGHT-16);
} }
else else
{ {
...@@ -657,6 +713,7 @@ static void ShowDownloadConsentMessage(void) ...@@ -657,6 +713,7 @@ static void ShowDownloadConsentMessage(void)
if (IsFileDownloadable(&fileneeded[i])) if (IsFileDownloadable(&fileneeded[i]))
totalsize += fileneeded[i].totalsize; totalsize += fileneeded[i].totalsize;
} }
filedownload.totalsize = totalsize;
const char *downloadsize = GetPrintableFileSize(totalsize); const char *downloadsize = GetPrintableFileSize(totalsize);
...@@ -1214,7 +1271,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic ...@@ -1214,7 +1271,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
void CL_ConnectToServer(void) void CL_ConnectToServer(void)
{ {
INT32 pnumnodes, nodewaited = doomcom->numnodes, i; INT32 pnumnodes, nodewaited = numnetnodes, i;
tic_t oldtic; tic_t oldtic;
tic_t asksent; tic_t asksent;
char tmpsave[256]; char tmpsave[256];
...@@ -1240,7 +1297,7 @@ void CL_ConnectToServer(void) ...@@ -1240,7 +1297,7 @@ void CL_ConnectToServer(void)
if (gamestate == GS_INTERMISSION) if (gamestate == GS_INTERMISSION)
Y_EndIntermission(); // clean up intermission graphics etc Y_EndIntermission(); // clean up intermission graphics etc
DEBFILE(va("waiting %d nodes\n", doomcom->numnodes)); DEBFILE(va("waiting %d nodes\n", numnetnodes));
G_SetGamestate(GS_WAITINGPLAYERS); G_SetGamestate(GS_WAITINGPLAYERS);
wipegamestate = GS_WAITINGPLAYERS; wipegamestate = GS_WAITINGPLAYERS;
...@@ -1401,7 +1458,7 @@ void PT_ServerCFG(SINT8 node) ...@@ -1401,7 +1458,7 @@ void PT_ServerCFG(SINT8 node)
netnodes[(UINT8)servernode].ingame = true; netnodes[(UINT8)servernode].ingame = true;
serverplayer = netbuffer->u.servercfg.serverplayer; serverplayer = netbuffer->u.servercfg.serverplayer;
doomcom->numslots = SHORT(netbuffer->u.servercfg.totalslotnum); numslots = SHORT(netbuffer->u.servercfg.totalslotnum);
mynode = netbuffer->u.servercfg.clientnode; mynode = netbuffer->u.servercfg.clientnode;
if (serverplayer >= 0) if (serverplayer >= 0)
playernode[(UINT8)serverplayer] = servernode; playernode[(UINT8)serverplayer] = servernode;
......
...@@ -149,8 +149,8 @@ void CL_Reset(void) ...@@ -149,8 +149,8 @@ void CL_Reset(void)
multiplayer = false; multiplayer = false;
servernode = 0; servernode = 0;
server = true; server = true;
doomcom->numnodes = 1; numnetnodes = 1;
doomcom->numslots = 1; numslots = 1;
SV_StopServer(); SV_StopServer();
SV_ResetServer(); SV_ResetServer();
...@@ -215,8 +215,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) ...@@ -215,8 +215,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
CL_ClearPlayer(newplayernum); CL_ClearPlayer(newplayernum);
playeringame[newplayernum] = true; playeringame[newplayernum] = true;
G_AddPlayer(newplayernum); G_AddPlayer(newplayernum);
if (newplayernum+1 > doomcom->numslots) if (newplayernum+1 > numslots)
doomcom->numslots = (INT16)(newplayernum+1); numslots = (INT16)(newplayernum+1);
if (server && I_GetNodeAddress) if (server && I_GetNodeAddress)
{ {
...@@ -612,8 +612,8 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) ...@@ -612,8 +612,8 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
// remove avatar of player // remove avatar of player
playeringame[playernum] = false; playeringame[playernum] = false;
while (!playeringame[doomcom->numslots-1] && doomcom->numslots > 1) while (!playeringame[numslots-1] && numslots > 1)
doomcom->numslots--; numslots--;
// Reset the name // Reset the name
sprintf(player_names[playernum], "Player %d", playernum+1); sprintf(player_names[playernum], "Player %d", playernum+1);
...@@ -641,6 +641,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) ...@@ -641,6 +641,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
void D_QuitNetGame(void) void D_QuitNetGame(void)
{ {
mousegrabbedbylua = true; mousegrabbedbylua = true;
textinputmodeenabledbylua = false;
I_UpdateMouseGrab(); I_UpdateMouseGrab();
if (!netgame || !netbuffer) if (!netgame || !netbuffer)
...@@ -754,7 +755,7 @@ void SV_ResetServer(void) ...@@ -754,7 +755,7 @@ void SV_ResetServer(void)
if (server) if (server)
servernode = 0; servernode = 0;
doomcom->numslots = 0; numslots = 0;
// clear server_context // clear server_context
memset(server_context, '-', 8); memset(server_context, '-', 8);
...@@ -806,7 +807,7 @@ void SV_SpawnServer(void) ...@@ -806,7 +807,7 @@ void SV_SpawnServer(void)
// non dedicated server just connect to itself // non dedicated server just connect to itself
if (!dedicated) if (!dedicated)
CL_ConnectToServer(); CL_ConnectToServer();
else doomcom->numslots = 1; else numslots = 1;
} }
} }
......
...@@ -48,6 +48,10 @@ ...@@ -48,6 +48,10 @@
#define FORCECLOSE 0x8000 #define FORCECLOSE 0x8000
tic_t connectiontimeout = (10*TICRATE); tic_t connectiontimeout = (10*TICRATE);
INT16 numnetnodes;
INT16 numslots;
INT16 extratics;
/// \brief network packet /// \brief network packet
doomcom_t *doomcom = NULL; doomcom_t *doomcom = NULL;
/// \brief network packet data, points inside doomcom /// \brief network packet data, points inside doomcom
...@@ -182,13 +186,9 @@ static node_t nodes[MAXNETNODES]; ...@@ -182,13 +186,9 @@ static node_t nodes[MAXNETNODES];
// 0 if a = n (mod 256) // 0 if a = n (mod 256)
// >0 if a > b (mod 256) // >0 if a > b (mod 256)
// mnemonic: to use it compare to 0: cmpack(a,b)<0 is "a < b" ... // mnemonic: to use it compare to 0: cmpack(a,b)<0 is "a < b" ...
FUNCMATH static INT32 cmpack(UINT8 a, UINT8 b) FUNCMATH static inline INT32 cmpack(UINT8 a, UINT8 b)
{ {
register INT32 d = a - b; return (SINT8)(a - b);
if (d >= 127 || d < -128)
return -d;
return d;
} }
/** Sets freeack to a free acknum and copies the netbuffer in the ackpak table /** Sets freeack to a free acknum and copies the netbuffer in the ackpak table
...@@ -999,8 +999,8 @@ void D_SetDoomcom(void) ...@@ -999,8 +999,8 @@ void D_SetDoomcom(void)
{ {
if (doomcom) return; if (doomcom) return;
doomcom = Z_Calloc(sizeof (doomcom_t), PU_STATIC, NULL); doomcom = Z_Calloc(sizeof (doomcom_t), PU_STATIC, NULL);
doomcom->numslots = doomcom->numnodes = 1; numslots = numnetnodes = 1;
doomcom->extratics = 0; extratics = 0;
} }
// //
...@@ -1046,10 +1046,10 @@ boolean D_CheckNetGame(void) ...@@ -1046,10 +1046,10 @@ boolean D_CheckNetGame(void)
if (M_CheckParm("-extratic")) if (M_CheckParm("-extratic"))
{ {
if (M_IsNextParm()) if (M_IsNextParm())
doomcom->extratics = (INT16)atoi(M_GetNextParm()); extratics = (INT16)atoi(M_GetNextParm());
else else
doomcom->extratics = 1; extratics = 1;
CONS_Printf(M_GetText("Set extratics to %d\n"), doomcom->extratics); CONS_Printf(M_GetText("Set extratics to %d\n"), extratics);
} }
software_MAXPACKETLENGTH = hardware_MAXPACKETLENGTH; software_MAXPACKETLENGTH = hardware_MAXPACKETLENGTH;
...@@ -1071,8 +1071,8 @@ boolean D_CheckNetGame(void) ...@@ -1071,8 +1071,8 @@ boolean D_CheckNetGame(void)
if (netgame) if (netgame)
multiplayer = true; multiplayer = true;
if (doomcom->numnodes > MAXNETNODES) if (numnetnodes > MAXNETNODES)
I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES); I_Error("Too many nodes (%d), max:%d", numnetnodes, MAXNETNODES);
netbuffer = (doomdata_t *)(void *)&doomcom->data; netbuffer = (doomdata_t *)(void *)&doomcom->data;
......
...@@ -129,7 +129,7 @@ boolean waitingforluafilecommand = false; ...@@ -129,7 +129,7 @@ boolean waitingforluafilecommand = false;
char luafiledir[256 + 16] = "luafiles"; char luafiledir[256 + 16] = "luafiles";
// max file size to send to a player (in kilobytes) // max file size to send to a player (in kilobytes)
static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {204800, "MAX"}, {0, NULL}}; static CV_PossibleValue_t maxsend_cons_t[] = {{-1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
consvar_t cv_maxsend = CVAR_INIT ("maxsend", "4096", CV_SAVE|CV_NETVAR, maxsend_cons_t, NULL); consvar_t cv_maxsend = CVAR_INIT ("maxsend", "4096", CV_SAVE|CV_NETVAR, maxsend_cons_t, NULL);
consvar_t cv_noticedownload = CVAR_INIT ("noticedownload", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); consvar_t cv_noticedownload = CVAR_INIT ("noticedownload", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
...@@ -206,7 +206,7 @@ UINT8 *PutFileNeeded(UINT16 firstfile) ...@@ -206,7 +206,7 @@ UINT8 *PutFileNeeded(UINT16 firstfile)
// Store in the upper four bits // Store in the upper four bits
if (!cv_downloading.value) if (!cv_downloading.value)
filestatus += (WILLSEND_NO << 4); // Won't send filestatus += (WILLSEND_NO << 4); // Won't send
else if (wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024) else if (cv_maxsend.value == -1 || wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024)
filestatus += (WILLSEND_YES << 4); // Will send if requested filestatus += (WILLSEND_YES << 4); // Will send if requested
else else
filestatus += (WILLSEND_TOOLARGE << 4); // Won't send, too big filestatus += (WILLSEND_TOOLARGE << 4); // Won't send, too big
...@@ -849,7 +849,7 @@ static boolean AddFileToSendQueue(INT32 node, UINT8 fileid) ...@@ -849,7 +849,7 @@ static boolean AddFileToSendQueue(INT32 node, UINT8 fileid)
strlcpy(p->id.filename, wadfiles[wadnum]->filename, MAX_WADPATH); strlcpy(p->id.filename, wadfiles[wadnum]->filename, MAX_WADPATH);
// Handle huge file requests (i.e. bigger than cv_maxsend.value KB) // Handle huge file requests (i.e. bigger than cv_maxsend.value KB)
if (wadfiles[wadnum]->filesize > (UINT32)cv_maxsend.value * 1024) if (cv_maxsend.value != -1 && wadfiles[wadnum]->filesize > (UINT32)cv_maxsend.value * 1024)
{ {
// Too big // Too big
// Don't inform client (client sucks, man) // Don't inform client (client sucks, man)
......
...@@ -95,6 +95,7 @@ typedef struct ...@@ -95,6 +95,7 @@ typedef struct
INT32 remaining; INT32 remaining;
INT32 completednum; INT32 completednum;
UINT32 completedsize; UINT32 completedsize;
UINT64 totalsize;
boolean http_failed; boolean http_failed;
boolean http_running; boolean http_running;
......
...@@ -44,15 +44,6 @@ typedef struct ...@@ -44,15 +44,6 @@ typedef struct
/// Number of bytes in doomdata to be sent /// Number of bytes in doomdata to be sent
INT16 datalength; INT16 datalength;
/// Info common to all nodes.
/// Console is always node 0.
INT16 numnodes;
/// Flag: 1 = send a backup tic in every packet.
INT16 extratics;
/// Number of "slots": the highest player number in use plus one.
INT16 numslots;
/// The packet data to be sent. /// The packet data to be sent.
char data[MAXPACKETLENGTH]; char data[MAXPACKETLENGTH];
} ATTRPACK doomcom_t; } ATTRPACK doomcom_t;
...@@ -61,6 +52,18 @@ typedef struct ...@@ -61,6 +52,18 @@ typedef struct
#pragma pack() #pragma pack()
#endif #endif
/** \brief Number of connected nodes.
*/
extern INT16 numnetnodes;
/** \brief Number of "slots": the highest player number in use plus one.
*/
extern INT16 numslots;
/** \brief Flag: 1 = send a backup tic in every packet.
*/
extern INT16 extratics;
extern doomcom_t *doomcom; extern doomcom_t *doomcom;
/** \brief return packet in doomcom struct /** \brief return packet in doomcom struct
......
...@@ -1105,7 +1105,7 @@ static boolean UDP_Socket(void) ...@@ -1105,7 +1105,7 @@ static boolean UDP_Socket(void)
broadcastaddresses = s; broadcastaddresses = s;
doomcom->extratics = 1; // internet is very high ping extratics = 1; // internet is very high ping
return true; return true;
} }
...@@ -1393,18 +1393,18 @@ boolean I_InitTcpNetwork(void) ...@@ -1393,18 +1393,18 @@ boolean I_InitTcpNetwork(void)
// in-game. // in-game.
// Since Boris has implemented join in-game, there is no actual need for specifying a // Since Boris has implemented join in-game, there is no actual need for specifying a
// particular number here. // particular number here.
// FIXME: for dedicated server, numnodes needs to be set to 0 upon start // FIXME: for dedicated server, numnetnodes needs to be set to 0 upon start
if (dedicated) if (dedicated)
doomcom->numnodes = 0; numnetnodes = 0;
/* else if (M_IsNextParm()) /* else if (M_IsNextParm())
doomcom->numnodes = (INT16)atoi(M_GetNextParm());*/ numnetnodes = (INT16)atoi(M_GetNextParm());*/
else else
doomcom->numnodes = 1; numnetnodes = 1;
if (doomcom->numnodes < 0) if (numnetnodes < 0)
doomcom->numnodes = 0; numnetnodes = 0;
if (doomcom->numnodes > MAXNETNODES) if (numnetnodes > MAXNETNODES)
doomcom->numnodes = MAXNETNODES; numnetnodes = MAXNETNODES;
// server // server
servernode = 0; servernode = 0;
......