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
Select Git revision
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2214-pre1
  • 2214-pre2
  • 2214-pre3
  • 2214-pre4
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-parameter-crash
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • just-in-case
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.15
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
142 results

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
  • 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
  • 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
  • Jisk/srb-2-beef-jerky
117 results
Select Git revision
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • better-player-states
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • camera-think-hook
  • cleanup-opengl
  • cleanupmusic
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • expose-player-muted
  • few-kart-lua-changes
  • ffloorclip
  • fix-1215
  • fix-167
  • fix-cvar-conflicts
  • fix-equation-slopes-near-edges
  • fix-opengl-shear-roll
  • fix-player-ping-being-writeable
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • gitlab-ci
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-conditions
  • lua-debug-library
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
141 results
Show changes
Showing with 675 additions and 98 deletions
...@@ -42,6 +42,10 @@ static const char *const hud_disable_options[] = { ...@@ -42,6 +42,10 @@ static const char *const hud_disable_options[] = {
"textspectator", "textspectator",
"crosshair", "crosshair",
"powerups", "powerups",
"gameover",
"pause",
"cecho",
"chat",
"score", "score",
"time", "time",
...@@ -52,6 +56,7 @@ static const char *const hud_disable_options[] = { ...@@ -52,6 +56,7 @@ static const char *const hud_disable_options[] = {
"weaponrings", "weaponrings",
"powerstones", "powerstones",
"teamscores", "teamscores",
"itemhunt",
"nightslink", "nightslink",
"nightsdrill", "nightsdrill",
...@@ -461,15 +466,29 @@ static int camera_set(lua_State *L) ...@@ -461,15 +466,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 +500,6 @@ static int libd_getSpritePatch(lua_State *L) ...@@ -481,7 +500,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 +573,6 @@ static int libd_getSprite2Patch(lua_State *L) ...@@ -555,7 +573,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
...@@ -875,6 +892,28 @@ static int libd_drawFill(lua_State *L) ...@@ -875,6 +892,28 @@ static int libd_drawFill(lua_State *L)
return 0; return 0;
} }
static int libd_drawFixedFill(lua_State *L)
{
huddrawlist_h list;
INT32 x = luaL_optinteger(L, 1, 0);
INT32 y = luaL_optinteger(L, 2, 0);
INT32 w = luaL_optinteger(L, 3, BASEVIDWIDTH << FRACBITS);
INT32 h = luaL_optinteger(L, 4, BASEVIDHEIGHT << FRACBITS);
INT32 c = luaL_optinteger(L, 5, 31);
HUDONLY
lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
list = (huddrawlist_h) lua_touserdata(L, -1);
lua_pop(L, 1);
if (LUA_HUD_IsDrawListValid(list))
LUA_HUD_AddDrawFixedFill(list, x, y, w, h, c);
else
V_DrawFixedFill(x, y, w, h, c);
return 0;
}
static int libd_drawString(lua_State *L) static int libd_drawString(lua_State *L)
{ {
huddrawlist_h list; huddrawlist_h list;
...@@ -1130,13 +1169,12 @@ static int libd_levelTitleHeight(lua_State *L) ...@@ -1130,13 +1169,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 +1214,10 @@ static int libd_getColormap(lua_State *L) ...@@ -1176,9 +1214,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 +1228,7 @@ static int libd_getStringColormap(lua_State *L) ...@@ -1189,6 +1228,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 +1304,18 @@ static int libd_fadeScreen(lua_State *L) ...@@ -1264,21 +1304,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 +1323,6 @@ static int libd_dup(lua_State *L) ...@@ -1286,7 +1323,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 +1336,12 @@ static int libd_renderer(lua_State *L) ...@@ -1300,14 +1336,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 +1350,6 @@ static int libd_RandomKey(lua_State *L) ...@@ -1316,7 +1350,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 +1359,6 @@ static int libd_RandomRange(lua_State *L) ...@@ -1326,7 +1359,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 +1366,6 @@ static int libd_RandomRange(lua_State *L) ...@@ -1334,7 +1366,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 +1373,6 @@ static int libd_SignedRandom(lua_State *L) ...@@ -1342,7 +1373,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 +1381,6 @@ static int libd_RandomChance(lua_State *L) ...@@ -1351,7 +1381,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 +1388,6 @@ static int libd_getlocaltransflag(lua_State *L) ...@@ -1359,7 +1388,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;
} }
...@@ -1381,6 +1409,7 @@ static luaL_Reg lib_draw[] = { ...@@ -1381,6 +1409,7 @@ static luaL_Reg lib_draw[] = {
{"drawNum", libd_drawNum}, {"drawNum", libd_drawNum},
{"drawPaddedNum", libd_drawPaddedNum}, {"drawPaddedNum", libd_drawPaddedNum},
{"drawFill", libd_drawFill}, {"drawFill", libd_drawFill},
{"drawFixedFill", libd_drawFixedFill},
{"drawString", libd_drawString}, {"drawString", libd_drawString},
{"drawNameTag", libd_drawNameTag}, {"drawNameTag", libd_drawNameTag},
{"drawScaledNameTag", libd_drawScaledNameTag}, {"drawScaledNameTag", libd_drawScaledNameTag},
...@@ -1452,6 +1481,26 @@ static luaL_Reg lib_hud[] = { ...@@ -1452,6 +1481,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 +1527,7 @@ int LUA_HudLib(lua_State *L) ...@@ -1478,6 +1527,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;
} }
......
...@@ -25,6 +25,7 @@ enum drawitem_e { ...@@ -25,6 +25,7 @@ enum drawitem_e {
DI_DrawNum, DI_DrawNum,
DI_DrawPaddedNum, DI_DrawPaddedNum,
DI_DrawFill, DI_DrawFill,
DI_DrawFixedFill,
DI_DrawString, DI_DrawString,
DI_DrawNameTag, DI_DrawNameTag,
DI_DrawScaledNameTag, DI_DrawScaledNameTag,
...@@ -346,6 +347,25 @@ void LUA_HUD_AddDrawFill( ...@@ -346,6 +347,25 @@ void LUA_HUD_AddDrawFill(
item->c = c; item->c = c;
} }
void LUA_HUD_AddDrawFixedFill(
huddrawlist_h list,
fixed_t x,
fixed_t y,
fixed_t w,
fixed_t h,
INT32 c
)
{
size_t i = AllocateDrawItem(list);
drawitem_t *item = &list->items[i];
item->type = DI_DrawFixedFill;
item->x = x;
item->y = y;
item->w = w;
item->h = h;
item->c = c;
}
void LUA_HUD_AddDrawString( void LUA_HUD_AddDrawString(
huddrawlist_h list, huddrawlist_h list,
fixed_t x, fixed_t x,
...@@ -482,6 +502,9 @@ void LUA_HUD_DrawList(huddrawlist_h list) ...@@ -482,6 +502,9 @@ void LUA_HUD_DrawList(huddrawlist_h list)
case DI_DrawFill: case DI_DrawFill:
V_DrawFill(item->x, item->y, item->w, item->h, item->c); V_DrawFill(item->x, item->y, item->w, item->h, item->c);
break; break;
case DI_DrawFixedFill:
V_DrawFixedFill(item->x, item->y, item->w, item->h, item->c);
break;
case DI_DrawString: case DI_DrawString:
switch(item->align) switch(item->align)
{ {
......
...@@ -98,6 +98,14 @@ void LUA_HUD_AddDrawFill( ...@@ -98,6 +98,14 @@ void LUA_HUD_AddDrawFill(
INT32 h, INT32 h,
INT32 c INT32 c
); );
void LUA_HUD_AddDrawFixedFill(
huddrawlist_h list,
fixed_t x,
fixed_t y,
fixed_t w,
fixed_t h,
INT32 c
);
void LUA_HUD_AddDrawString( void LUA_HUD_AddDrawString(
huddrawlist_h list, huddrawlist_h list,
fixed_t x, fixed_t x,
......
...@@ -1158,6 +1158,7 @@ enum mobjinfo_e ...@@ -1158,6 +1158,7 @@ enum mobjinfo_e
mobjinfo_activesound, mobjinfo_activesound,
mobjinfo_flags, mobjinfo_flags,
mobjinfo_raisestate, mobjinfo_raisestate,
mobjinfo_name,
}; };
const char *const mobjinfo_opt[] = { const char *const mobjinfo_opt[] = {
...@@ -1185,6 +1186,7 @@ const char *const mobjinfo_opt[] = { ...@@ -1185,6 +1186,7 @@ const char *const mobjinfo_opt[] = {
"activesound", "activesound",
"flags", "flags",
"raisestate", "raisestate",
"name",
NULL, NULL,
}; };
...@@ -1199,6 +1201,8 @@ static int mobjinfo_get(lua_State *L) ...@@ -1199,6 +1201,8 @@ static int mobjinfo_get(lua_State *L)
I_Assert(info != NULL); I_Assert(info != NULL);
I_Assert(info >= mobjinfo); I_Assert(info >= mobjinfo);
mobjtype_t id = info-mobjinfo;
switch (field) switch (field)
{ {
case mobjinfo_doomednum: case mobjinfo_doomednum:
...@@ -1273,6 +1277,21 @@ static int mobjinfo_get(lua_State *L) ...@@ -1273,6 +1277,21 @@ static int mobjinfo_get(lua_State *L)
case mobjinfo_raisestate: case mobjinfo_raisestate:
lua_pushinteger(L, info->raisestate); lua_pushinteger(L, info->raisestate);
break; break;
case mobjinfo_name:
if (id < MT_FIRSTFREESLOT)
{
lua_pushstring(L, MOBJTYPE_LIST[id]+3);
return 1;
}
id -= MT_FIRSTFREESLOT;
if (id < NUMMOBJFREESLOTS && FREE_MOBJS[id])
{
lua_pushstring(L, FREE_MOBJS[id]);
return 1;
}
return 0;
default: default:
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1)); I_Assert(lua_istable(L, -1));
......
...@@ -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;
/////////////// ///////////////
...@@ -129,6 +132,20 @@ static int lib_getCursorPosition(lua_State *L) ...@@ -129,6 +132,20 @@ static int lib_getCursorPosition(lua_State *L)
return 2; return 2;
} }
static int lib_setTextInputMode(lua_State *L)
{
textinputmodeenabledbylua = luaL_checkboolean(L, 1);
if (!(menuactive || CON_Ready() || chat_on))
I_SetTextInputMode(textinputmodeenabledbylua);
return 0;
}
static int lib_getTextInputMode(lua_State *L)
{
lua_pushinteger(L, textinputmodeenabledbylua);
return 1;
}
static luaL_Reg lib[] = { static luaL_Reg lib[] = {
{"gameControlDown", lib_gameControlDown}, {"gameControlDown", lib_gameControlDown},
{"gameControl2Down", lib_gameControl2Down}, {"gameControl2Down", lib_gameControl2Down},
...@@ -143,6 +160,8 @@ static luaL_Reg lib[] = { ...@@ -143,6 +160,8 @@ static luaL_Reg lib[] = {
{"getMouseGrab", lib_getMouseGrab}, {"getMouseGrab", lib_getMouseGrab},
{"setMouseGrab", lib_setMouseGrab}, {"setMouseGrab", lib_setMouseGrab},
{"getCursorPosition", lib_getCursorPosition}, {"getCursorPosition", lib_getCursorPosition},
{"setTextInputMode", lib_setTextInputMode},
{"getTextInputMode", lib_getTextInputMode},
{NULL, NULL} {NULL, NULL}
}; };
...@@ -220,6 +239,28 @@ static int lib_lenGameKeyDown(lua_State *L) ...@@ -220,6 +239,28 @@ static int lib_lenGameKeyDown(lua_State *L)
return 1; return 1;
} }
////////////////
// TEXT EVENT //
////////////////
static int textevent_get(lua_State *L)
{
event_t *event = *((event_t **)luaL_checkudata(L, 1, META_TEXTEVENT));
const char *field = luaL_checkstring(L, 2);
I_Assert(event != NULL);
if (fastcmp(field,"text"))
{
char s[2] = { event->key, 0 };
lua_pushstring(L, s);
}
else
return luaL_error(L, "textevent_t has no field named %s", field);
return 1;
}
/////////////// ///////////////
// KEY EVENT // // KEY EVENT //
/////////////// ///////////////
...@@ -285,6 +326,7 @@ static int mouse_num(lua_State *L) ...@@ -285,6 +326,7 @@ static int mouse_num(lua_State *L)
int LUA_InputLib(lua_State *L) int LUA_InputLib(lua_State *L)
{ {
LUA_RegisterUserdataMetatable(L, META_TEXTEVENT, textevent_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_KEYEVENT, keyevent_get, NULL, NULL); LUA_RegisterUserdataMetatable(L, META_KEYEVENT, keyevent_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_MOUSE, mouse_get, NULL, mouse_num); LUA_RegisterUserdataMetatable(L, META_MOUSE, mouse_get, NULL, mouse_num);
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2024-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_interceptlib.c
/// \brief intercept library for Lua scripting
#include "doomdef.h"
#include "fastcmp.h"
#include "p_local.h"
#include "lua_script.h"
#include "lua_libs.h"
#include "lua_hud.h" // hud_running errors
#define NOHUD if (hud_running)\
return luaL_error(L, "HUD rendering code should not call this function!");
enum intercept_e {
intercept_valid = 0,
intercept_frac,
intercept_thing,
intercept_line
};
static const char *const intercept_opt[] = {
"valid",
"frac",
"thing",
"line",
NULL};
static int intercept_fields_ref = LUA_NOREF;
static boolean Lua_PathTraverser(intercept_t *in)
{
boolean traverse = false;
I_Assert(in != NULL);
lua_settop(gL, 6);
lua_pushcfunction(gL, LUA_GetErrorMessage);
I_Assert(lua_isfunction(gL, -2));
lua_pushvalue(gL, -2);
LUA_PushUserdata(gL, in, META_INTERCEPT);
LUA_Call(gL, 1, 1, -3);
traverse = lua_toboolean(gL, -1);
lua_pop(gL, 1);
return !traverse; // Stay consistent with the MobjMoveCollide hook
}
static int intercept_get(lua_State *L)
{
intercept_t *in = *((intercept_t **)luaL_checkudata(L, 1, META_INTERCEPT));
enum intercept_e field = Lua_optoption(L, 2, intercept_valid, intercept_fields_ref);
if (!in)
{
if (field == intercept_valid) {
lua_pushboolean(L, 0);
return 1;
}
return luaL_error(L, "accessed intercept_t doesn't exist anymore.");
}
switch(field)
{
case intercept_valid: // valid
lua_pushboolean(L, 1);
return 1;
case intercept_frac:
lua_pushfixed(L, in->frac);
return 1;
case intercept_thing:
if (in->isaline)
return 0;
LUA_PushUserdata(L, in->d.thing, META_MOBJ);
return 1;
case intercept_line:
if (!in->isaline)
return 0;
LUA_PushUserdata(L, in->d.line, META_LINE);
return 1;
}
return 0;
}
static int lib_pPathTraverse(lua_State *L)
{
fixed_t px1 = luaL_checkfixed(L, 1);
fixed_t py1 = luaL_checkfixed(L, 2);
fixed_t px2 = luaL_checkfixed(L, 3);
fixed_t py2 = luaL_checkfixed(L, 4);
INT32 flags = (INT32)luaL_checkinteger(L, 5);
luaL_checktype(L, 6, LUA_TFUNCTION);
NOHUD
INLEVEL
lua_pushboolean(L, P_PathTraverse(px1, py1, px2, py2, flags, Lua_PathTraverser));
return 1;
}
int LUA_InterceptLib(lua_State *L)
{
LUA_RegisterUserdataMetatable(L, META_INTERCEPT, intercept_get, NULL, NULL);
intercept_fields_ref = Lua_CreateFieldTable(L, intercept_opt);
lua_register(L, "P_PathTraverse", lib_pPathTraverse);
return 0;
}
...@@ -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
...@@ -46,6 +47,8 @@ extern boolean ignoregameinputs; ...@@ -46,6 +47,8 @@ extern boolean ignoregameinputs;
#define META_SKINSPRITESLIST "SKIN_T*SKINSPRITES[]" #define META_SKINSPRITESLIST "SKIN_T*SKINSPRITES[]"
#define META_SKINSPRITESCOMPAT "SKIN_T*SPRITES" // TODO: 2.3: Delete #define META_SKINSPRITESCOMPAT "SKIN_T*SPRITES" // TODO: 2.3: Delete
#define META_MUSICDEF "MUSICDEF_T*"
#define META_VERTEX "VERTEX_T*" #define META_VERTEX "VERTEX_T*"
#define META_LINE "LINE_T*" #define META_LINE "LINE_T*"
#define META_SIDE "SIDE_T*" #define META_SIDE "SIDE_T*"
...@@ -69,11 +72,15 @@ extern boolean ignoregameinputs; ...@@ -69,11 +72,15 @@ extern boolean ignoregameinputs;
#ifdef MUTABLE_TAGS #ifdef MUTABLE_TAGS
#define META_SECTORTAGLIST "sector_t.taglist" #define META_SECTORTAGLIST "sector_t.taglist"
#endif #endif
#define META_SECTORCUSTOMARGS "SECTOR_T*CUSTOMARGS"
#define META_SIDENUM "LINE_T*SIDENUM" #define META_SIDENUM "LINE_T*SIDENUM"
#define META_LINEARGS "LINE_T*ARGS" #define META_LINEARGS "LINE_T*ARGS"
#define META_LINESTRINGARGS "LINE_T*STRINGARGS" #define META_LINESTRINGARGS "LINE_T*STRINGARGS"
#define META_LINECUSTOMARGS "LINE_T*CUSTOMARGS"
#define META_SIDECUSTOMARGS "SIDE_T*CUSTOMARGS"
#define META_THINGARGS "MAPTHING_T*ARGS" #define META_THINGARGS "MAPTHING_T*ARGS"
#define META_THINGSTRINGARGS "MAPTHING_T*STRINGARGS" #define META_THINGSTRINGARGS "MAPTHING_T*STRINGARGS"
#define META_THINGCUSTOMARGS "MAPTHING_T*CUSTOMARGS"
#define META_POLYOBJVERTICES "POLYOBJ_T*VERTICES" #define META_POLYOBJVERTICES "POLYOBJ_T*VERTICES"
#define META_POLYOBJLINES "POLYOBJ_T*LINES" #define META_POLYOBJLINES "POLYOBJ_T*LINES"
#ifdef HAVE_LUA_SEGS #ifdef HAVE_LUA_SEGS
...@@ -93,9 +100,12 @@ extern boolean ignoregameinputs; ...@@ -93,9 +100,12 @@ extern boolean ignoregameinputs;
#define META_LUABANKS "LUABANKS[]*" #define META_LUABANKS "LUABANKS[]*"
#define META_TEXTEVENT "TEXTEVENT_T*"
#define META_KEYEVENT "KEYEVENT_T*" #define META_KEYEVENT "KEYEVENT_T*"
#define META_MOUSE "MOUSE_T*" #define META_MOUSE "MOUSE_T*"
#define META_INTERCEPT "INTERCEPT_T*"
boolean luaL_checkboolean(lua_State *L, int narg); boolean luaL_checkboolean(lua_State *L, int narg);
int LUA_EnumLib(lua_State *L); int LUA_EnumLib(lua_State *L);
...@@ -116,3 +126,4 @@ int LUA_BlockmapLib(lua_State *L); ...@@ -116,3 +126,4 @@ int LUA_BlockmapLib(lua_State *L);
int LUA_HudLib(lua_State *L); int LUA_HudLib(lua_State *L);
int LUA_ColorLib(lua_State *L); int LUA_ColorLib(lua_State *L);
int LUA_InputLib(lua_State *L); int LUA_InputLib(lua_State *L);
int LUA_InterceptLib(lua_State *L);
...@@ -69,6 +69,7 @@ enum sector_e { ...@@ -69,6 +69,7 @@ enum sector_e {
sector_triggerer, sector_triggerer,
sector_friction, sector_friction,
sector_gravity, sector_gravity,
sector_customargs
}; };
static const char *const sector_opt[] = { static const char *const sector_opt[] = {
...@@ -112,6 +113,7 @@ static const char *const sector_opt[] = { ...@@ -112,6 +113,7 @@ static const char *const sector_opt[] = {
"triggerer", "triggerer",
"friction", "friction",
"gravity", "gravity",
"customargs",
NULL}; NULL};
static int sector_fields_ref = LUA_NOREF; static int sector_fields_ref = LUA_NOREF;
...@@ -147,6 +149,7 @@ enum line_e { ...@@ -147,6 +149,7 @@ enum line_e {
line_taglist, line_taglist,
line_args, line_args,
line_stringargs, line_stringargs,
line_customargs,
line_sidenum, line_sidenum,
line_frontside, line_frontside,
line_backside, line_backside,
...@@ -173,6 +176,7 @@ static const char *const line_opt[] = { ...@@ -173,6 +176,7 @@ static const char *const line_opt[] = {
"taglist", "taglist",
"args", "args",
"stringargs", "stringargs",
"customargs",
"sidenum", "sidenum",
"frontside", "frontside",
"backside", "backside",
...@@ -221,7 +225,8 @@ enum side_e { ...@@ -221,7 +225,8 @@ enum side_e {
side_lightabsolute_top, side_lightabsolute_top,
side_lightabsolute_mid, side_lightabsolute_mid,
side_lightabsolute_bottom, side_lightabsolute_bottom,
side_text side_text,
side_customargs
}; };
static const char *const side_opt[] = { static const char *const side_opt[] = {
...@@ -258,6 +263,7 @@ static const char *const side_opt[] = { ...@@ -258,6 +263,7 @@ static const char *const side_opt[] = {
"lightabsolute_mid", "lightabsolute_mid",
"lightabsolute_bottom", "lightabsolute_bottom",
"text", "text",
"customargs",
NULL}; NULL};
static int side_fields_ref = LUA_NOREF; static int side_fields_ref = LUA_NOREF;
...@@ -674,6 +680,73 @@ static int sectorlines_num(lua_State *L) ...@@ -674,6 +680,73 @@ static int sectorlines_num(lua_State *L)
return 1; return 1;
} }
//////////////////
// customargs_t //
//////////////////
FUNCINLINE static ATTRINLINE int customargs_get(lua_State* L, const char* meta)
{
customargs_t *args = *((customargs_t**)luaL_checkudata(L, 1, meta));
const char* field = luaL_checkstring(L, 2);
if (args == NULL) {
lua_pushnil(L);
return 1;
}
customargs_t* current = args;
while (current != NULL)
{
if (!strcmp(current->name, field))
{
switch (current->type)
{
case UDMF_TYPE_STRING:
lua_pushstring(L, current->value.vstring);
break;
case UDMF_TYPE_NUMERIC:
lua_pushinteger(L, current->value.vint);
break;
case UDMF_TYPE_FIXED:
lua_pushfixed(L, current->value.vfloat);
break;
case UDMF_TYPE_BOOLEAN:
lua_pushboolean(L, current->value.vbool);
break;
default:
lua_pushnil(L);
}
return 1;
}
current = current->next;
}
lua_pushnil(L);
return 1;
}
static int sectorcustomargs_get(lua_State* L)
{
return customargs_get(L, META_SECTORCUSTOMARGS);
}
static int sidecustomargs_get(lua_State* L)
{
return customargs_get(L, META_SIDECUSTOMARGS);
}
static int linecustomargs_get(lua_State* L)
{
return customargs_get(L, META_LINECUSTOMARGS);
}
static int thingcustomargs_get(lua_State* L)
{
return customargs_get(L, META_THINGCUSTOMARGS);
}
////////////// //////////////
// sector_t // // sector_t //
////////////// //////////////
...@@ -835,6 +908,9 @@ static int sector_get(lua_State *L) ...@@ -835,6 +908,9 @@ static int sector_get(lua_State *L)
case sector_gravity: // gravity case sector_gravity: // gravity
lua_pushfixed(L, sector->gravity); lua_pushfixed(L, sector->gravity);
return 1; return 1;
case sector_customargs:
LUA_PushUserdata(L, sector->customargs, META_SECTORCUSTOMARGS);
return 1;
} }
return 0; return 0;
} }
...@@ -1130,6 +1206,9 @@ static int line_get(lua_State *L) ...@@ -1130,6 +1206,9 @@ static int line_get(lua_State *L)
case line_stringargs: case line_stringargs:
LUA_PushUserdata(L, line->stringargs, META_LINESTRINGARGS); LUA_PushUserdata(L, line->stringargs, META_LINESTRINGARGS);
return 1; return 1;
case line_customargs:
LUA_PushUserdata(L, line->customargs, META_LINECUSTOMARGS);
return 1;
case line_sidenum: case line_sidenum:
LUA_PushUserdata(L, line->sidenum, META_SIDENUM); LUA_PushUserdata(L, line->sidenum, META_SIDENUM);
return 1; return 1;
...@@ -1351,6 +1430,9 @@ static int side_get(lua_State *L) ...@@ -1351,6 +1430,9 @@ static int side_get(lua_State *L)
case side_lightabsolute_bottom: case side_lightabsolute_bottom:
lua_pushboolean(L, side->lightabsolute_bottom); lua_pushboolean(L, side->lightabsolute_bottom);
return 1; return 1;
case side_customargs:
LUA_PushUserdata(L, side->customargs, META_SIDECUSTOMARGS);
return 1;
// TODO: 2.3: Delete // TODO: 2.3: Delete
case side_text: case side_text:
{ {
...@@ -1370,6 +1452,7 @@ static int side_get(lua_State *L) ...@@ -1370,6 +1452,7 @@ static int side_get(lua_State *L)
return 1; return 1;
} }
} }
return 0; return 0;
} }
...@@ -3061,9 +3144,12 @@ int LUA_MapLib(lua_State *L) ...@@ -3061,9 +3144,12 @@ int LUA_MapLib(lua_State *L)
LUA_RegisterUserdataMetatable(L, META_SECTORLINES, sectorlines_get, NULL, sectorlines_num); LUA_RegisterUserdataMetatable(L, META_SECTORLINES, sectorlines_get, NULL, sectorlines_num);
LUA_RegisterUserdataMetatable(L, META_SECTOR, sector_get, sector_set, sector_num); LUA_RegisterUserdataMetatable(L, META_SECTOR, sector_get, sector_set, sector_num);
LUA_RegisterUserdataMetatable(L, META_SUBSECTOR, subsector_get, NULL, subsector_num); LUA_RegisterUserdataMetatable(L, META_SUBSECTOR, subsector_get, NULL, subsector_num);
LUA_RegisterUserdataMetatable(L, META_SECTORCUSTOMARGS, sectorcustomargs_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_LINE, line_get, NULL, line_num); LUA_RegisterUserdataMetatable(L, META_LINE, line_get, NULL, line_num);
LUA_RegisterUserdataMetatable(L, META_LINEARGS, lineargs_get, NULL, lineargs_len); LUA_RegisterUserdataMetatable(L, META_LINEARGS, lineargs_get, NULL, lineargs_len);
LUA_RegisterUserdataMetatable(L, META_LINESTRINGARGS, linestringargs_get, NULL, linestringargs_len); LUA_RegisterUserdataMetatable(L, META_LINESTRINGARGS, linestringargs_get, NULL, linestringargs_len);
LUA_RegisterUserdataMetatable(L, META_LINECUSTOMARGS, linecustomargs_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_SIDECUSTOMARGS, sidecustomargs_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_SIDENUM, sidenum_get, NULL, NULL); LUA_RegisterUserdataMetatable(L, META_SIDENUM, sidenum_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_SIDE, side_get, side_set, side_num); LUA_RegisterUserdataMetatable(L, META_SIDE, side_get, side_set, side_num);
LUA_RegisterUserdataMetatable(L, META_VERTEX, vertex_get, NULL, vertex_num); LUA_RegisterUserdataMetatable(L, META_VERTEX, vertex_get, NULL, vertex_num);
...@@ -3073,6 +3159,7 @@ int LUA_MapLib(lua_State *L) ...@@ -3073,6 +3159,7 @@ int LUA_MapLib(lua_State *L)
LUA_RegisterUserdataMetatable(L, META_VECTOR2, vector2_get, NULL, NULL); LUA_RegisterUserdataMetatable(L, META_VECTOR2, vector2_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_VECTOR3, vector3_get, NULL, NULL); LUA_RegisterUserdataMetatable(L, META_VECTOR3, vector3_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_MAPHEADER, mapheaderinfo_get, NULL, NULL); LUA_RegisterUserdataMetatable(L, META_MAPHEADER, mapheaderinfo_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_THINGCUSTOMARGS, thingcustomargs_get, NULL, NULL);
sector_fields_ref = Lua_CreateFieldTable(L, sector_opt); sector_fields_ref = Lua_CreateFieldTable(L, sector_opt);
subsector_fields_ref = Lua_CreateFieldTable(L, subsector_opt); subsector_fields_ref = Lua_CreateFieldTable(L, subsector_opt);
......
...@@ -973,6 +973,7 @@ enum mapthing_e { ...@@ -973,6 +973,7 @@ enum mapthing_e {
mapthing_taglist, mapthing_taglist,
mapthing_args, mapthing_args,
mapthing_stringargs, mapthing_stringargs,
mapthing_customargs,
mapthing_mobj, mapthing_mobj,
}; };
...@@ -994,6 +995,7 @@ const char *const mapthing_opt[] = { ...@@ -994,6 +995,7 @@ const char *const mapthing_opt[] = {
"taglist", "taglist",
"args", "args",
"stringargs", "stringargs",
"customargs",
"mobj", "mobj",
NULL, NULL,
}; };
...@@ -1072,6 +1074,9 @@ static int mapthing_get(lua_State *L) ...@@ -1072,6 +1074,9 @@ static int mapthing_get(lua_State *L)
case mapthing_stringargs: case mapthing_stringargs:
LUA_PushUserdata(L, mt->stringargs, META_THINGSTRINGARGS); LUA_PushUserdata(L, mt->stringargs, META_THINGSTRINGARGS);
break; break;
case mapthing_customargs:
LUA_PushUserdata(L, mt->customargs, META_THINGCUSTOMARGS);
break;
case mapthing_mobj: case mapthing_mobj:
LUA_PushUserdata(L, mt->mobj, META_MOBJ); LUA_PushUserdata(L, mt->mobj, META_MOBJ);
break; break;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "r_state.h" #include "r_state.h"
#include "r_sky.h" #include "r_sky.h"
#include "g_game.h" #include "g_game.h"
#include "g_demo.h"
#include "g_input.h" #include "g_input.h"
#include "f_finale.h" #include "f_finale.h"
#include "byteptr.h" #include "byteptr.h"
...@@ -62,6 +63,7 @@ static lua_CFunction liblist[] = { ...@@ -62,6 +63,7 @@ static lua_CFunction liblist[] = {
LUA_HudLib, // HUD stuff LUA_HudLib, // HUD stuff
LUA_ColorLib, // general color functions LUA_ColorLib, // general color functions
LUA_InputLib, // inputs LUA_InputLib, // inputs
LUA_InterceptLib, // intercept_t
NULL NULL
}; };
...@@ -394,6 +396,22 @@ int LUA_PushGlobals(lua_State *L, const char *word) ...@@ -394,6 +396,22 @@ int LUA_PushGlobals(lua_State *L, const char *word)
return 0; return 0;
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
return 1; return 1;
// demos booleans
} else if (fastcmp(word, "demoplayback")) {
lua_pushboolean(L, demoplayback);
return 1;
} else if (fastcmp(word, "titledemo")) {
lua_pushboolean(L, titledemo);
return 1;
} else if (fastcmp(word, "demorecording")) {
lua_pushboolean(L, demorecording);
return 1;
} else if (fastcmp(word, "timingdemo")) {
lua_pushboolean(L, timingdemo);
return 1;
} else if (fastcmp(word, "demosynced")) {
lua_pushboolean(L, demosynced);
return 1;
} else if (fastcmp(word,"emeralds")) { } else if (fastcmp(word,"emeralds")) {
lua_pushinteger(L, emeralds); lua_pushinteger(L, emeralds);
return 1; return 1;
...@@ -412,6 +430,9 @@ int LUA_PushGlobals(lua_State *L, const char *word) ...@@ -412,6 +430,9 @@ int LUA_PushGlobals(lua_State *L, const char *word)
} else if (fastcmp(word, "token")) { } else if (fastcmp(word, "token")) {
lua_pushinteger(L, token); lua_pushinteger(L, token);
return 1; return 1;
} else if (fastcmp(word, "nummaprings")) {
lua_pushinteger(L, nummaprings);
return 1;
} else if (fastcmp(word, "gamestate")) { } else if (fastcmp(word, "gamestate")) {
lua_pushinteger(L, gamestate); lua_pushinteger(L, gamestate);
return 1; return 1;
...@@ -437,6 +458,14 @@ int LUA_PushGlobals(lua_State *L, const char *word) ...@@ -437,6 +458,14 @@ int LUA_PushGlobals(lua_State *L, const char *word)
} else if (fastcmp(word, "chatactive")) { } else if (fastcmp(word, "chatactive")) {
lua_pushboolean(L, chat_on); lua_pushboolean(L, chat_on);
return 1; return 1;
} else if (fastcmp(word, "currentsaveslot")) {
if (multiplayer)
return 0;
lua_pushinteger(L, cursaveslot);
return 1;
} else if (fastcmp(word, "gamedatafilename")) {
lua_pushstring(L, strcmp(timeattackfolder, "main") ? timeattackfolder : "gamedata");
return 1;
} }
return 0; return 0;
} }
...@@ -460,6 +489,8 @@ int LUA_CheckGlobals(lua_State *L, const char *word) ...@@ -460,6 +489,8 @@ int LUA_CheckGlobals(lua_State *L, const char *word)
emeralds = (UINT16)luaL_checkinteger(L, 2); emeralds = (UINT16)luaL_checkinteger(L, 2);
else if (fastcmp(word, "token")) else if (fastcmp(word, "token"))
token = (UINT32)luaL_checkinteger(L, 2); token = (UINT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "nummaprings"))
nummaprings = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "gravity")) else if (fastcmp(word, "gravity"))
gravity = (fixed_t)luaL_checkinteger(L, 2); gravity = (fixed_t)luaL_checkinteger(L, 2);
else if (fastcmp(word, "stoppedclock")) else if (fastcmp(word, "stoppedclock"))
......
...@@ -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);
} }
// //
...@@ -11141,37 +11143,11 @@ static INT32 menuRoomIndex = 0; ...@@ -11141,37 +11143,11 @@ static INT32 menuRoomIndex = 0;
static void M_DrawRoomMenu(void) static void M_DrawRoomMenu(void)
{ {
static fixed_t frame = -(12 << FRACBITS);
int dot_frame;
char text[4];
const char *rmotd; const char *rmotd;
const char *waiting_message; const char *waiting_message;
int dots;
if (m_waiting_mode) if (m_waiting_mode)
{ currentMenu->menuitems[0].text = "...";
dot_frame = (int)(frame >> FRACBITS) / 4;
dots = dot_frame + 3;
strcpy(text, " ");
if (dots > 0)
{
if (dot_frame < 0)
dot_frame = 0;
if (dot_frame != 3)
strncpy(&text[dot_frame], "...", min(dots, 3 - dot_frame));
}
frame += renderdeltatics;
while (frame >= (12 << FRACBITS))
frame -= 12 << FRACBITS;
currentMenu->menuitems[0].text = text;
}
// use generic drawer for cursor, items and title // use generic drawer for cursor, items and title
M_DrawGenericMenu(); M_DrawGenericMenu();
......
...@@ -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,9 @@ void SV_SpawnServer(void) ...@@ -806,7 +807,9 @@ 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;
LUA_HookVoid(HOOK(GameStart));
} }
} }
......
...@@ -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;
......