Compare commits

...
26 Commits
Author SHA1 Message Date
indev 33554dc14e Update bluajit to support non-gcc compilers 2025-08-15 20:13:15 +03:00
Alug c7d4c28f01 pass our compiler and ldflags to bluajit 2025-08-15 08:02:10 +02:00
Alug c8929b8c77 dont compile with bluajit by default
add HAVE_BLUAJIT=1 to compile with it
2025-08-05 23:21:44 +02:00
indev 7ee0fe1c1f Reapply lug's bluajit changes :3 2025-08-05 21:55:33 +03:00
indev ce11589f84 Change bluajit submodule branch to bluajit-install 2025-08-05 21:38:20 +03:00
indev c34ec52159 Convert libs/bluajit into git submodule 2025-08-05 21:31:20 +03:00
indev 50d9826e74 Always try to rebuild bluajit in case something is changed in it's sources 2025-08-05 16:04:30 +03:00
Alug 4444d35985 actually pass our compiler flags to jit
and supress all warnings for jit (idk how else to handle it lmao)
2025-08-04 20:23:36 +02:00
Alug 78a597543c readd ref system compat 2025-08-04 19:29:16 +02:00
Alug 78999ebcfa remove unused goto parse function 2025-08-04 19:29:16 +02:00
Alug b049475dd6 Remove goto stuff from bluajit
this wasnt in the main repo
but kart does not have goto so we dont allow modders to screw things up
2025-08-04 19:29:16 +02:00
Alug 477b6567e7 pass our main CFLAGS to bluajit
otherwise it would compile with O2 and stuff becoming super slow lol
no clue if we also should pass linker flags aswell
2025-08-04 19:29:16 +02:00
indev ba67d870a2 Automatically build bluajit 2025-08-04 19:42:11 +03:00
indev f4019ad5ea Move bluajit into libs 2025-08-04 19:10:37 +03:00
Alug 098779c924 fixup bluajit merge
this is the last state this had before wiping it
2025-08-04 15:15:32 +02:00
Alug 54b9c86d9d Merge remote-tracking branch 'origin/ljtest' into ljtest2 2025-08-04 15:06:23 +02:00
Alug e120907e0f make driftgauge stuff a bit more readable 2025-08-03 20:12:13 +02:00
Alug b0c217201e move flat cyan check into a function
and also limit it to software renderer only
we dont need this anywhere else, so can save a bit of work
2025-08-03 15:59:57 +02:00
Alug dac7026739 use R_GetFlat here
does the exact same thing
2025-08-03 15:59:23 +02:00
Alug 91a4646f19 dont PU_CACHE our planeflats 2025-08-03 15:51:52 +02:00
Alug eba5965220 move rainbow color calc into K_Rainbowcolor 2025-08-03 14:42:49 +02:00
GenericHeroGuy 744dc87c16 In rehashtab, do counthash before adding asize
Thanks alug!
2025-01-29 22:25:24 +01:00
GenericHeroGuy b400655f3c Add cleanjit target
Recompiling the whole game after changing a single flag is pretty tiring
2025-01-06 00:02:11 +01:00
GenericHeroGuy 314ab9e9f0 Fix some functions leaking doubles in INTONLY 2025-01-05 23:48:40 +01:00
GenericHeroGuy 0fbc448013 Use references instead of upvalues for original I/O functions
No more unrestricted I/O through debug.getupvalue
2025-01-03 22:16:11 +01:00
GenericHeroGuy eb9d1982fa Update to BLUAJIT 449b76f 2025-01-03 20:12:26 +01:00
21 changed files with 430 additions and 174 deletions

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
[submodule "libs/bluajit"]
path = libs/bluajit
url = https://github.com/Indev450/bluajit
[submodule "libs/bluajit/"]
branch = bluajit-install
Submodule
+1
Submodule libs/bluajit added at 14f5b60567.
+23 -1
View File
@@ -64,6 +64,10 @@
# DEBUGMODE=1 - Enable various debugging capabilities.
# Also disables optimizations.
#
# Potentially Unsafe
# ------------------
# HAVE_BLUAJIT=1 - Enable compiling with BluaJIT instead of blua, can have potential bugs
#
# Development flags:
#
# VALGRIND=1 - Enable Valgrind memory debugging support.
@@ -184,8 +188,14 @@ sources+=\
$(call List,Sourcefile)\
$(call List,core/Sourcefile)
ifndef HAVE_BLUAJIT
lualib:=
sources+=\
$(call List,blua/Sourcefile)
else
opts+=-DLUAJIT_INTONLY
lualib:=../libs/bluajit/src/libbluajit.a
endif
depends:=$(basename $(filter %.c %.cpp %.s,$(sources)))
objects:=$(basename $(filter %.c %.cpp %.s %.nas,$(sources)))
@@ -357,10 +367,15 @@ ifdef UPX
endif
# original executable with debugging symbols
$(dbg) : $(objects) | $$(@D)/
$(dbg) : $(objects) $(lualib) | $$(@D)/
$(call Echo,Linking $(@F)...)
$(.)$(LD) -o $@ $^ $(libs)
ifdef HAVE_BLUAJIT
$(lualib) ::
@$(MAKE) -C ../libs/bluajit $(MAKECMDGOALS) CC="$(CC)" CCOPT="$(opts)" LDFLAGS="$(LDFLAGS)"
endif
# disassembly of executable
$(dbg).txt : $(dbg)
$(call Echo,Dumping debugging info...)
@@ -423,6 +438,13 @@ clean :
distclean :
$(call _rm,../bin ../objs ../dep ../make comptime.h)
ifdef HAVE_BLUAJIT
$(call _rm,$(objdir)/buildvm* $(objdir)/minilua* $(objdir)/lj_vm*)
cleanjit:
$(call _rm,$(objdir)/buildvm* $(objdir)/minilua* $(objdir)/lj_vm* $(ALL_HDRGEN) $(LJVMCORE_O) $(ALL_GEN))
endif
info:
ifdef WINDOWSHELL
@REM
+2 -1
View File
@@ -6,7 +6,8 @@ passthru_opts+=\
NOHW NOMD5 NOPOSTPROCESSING\
MOBJCONSISTANCY PACKETDROP ZDEBUG\
HAVE_MINIUPNPC\
HAVE_DISCORDRPC DEVELOP
HAVE_DISCORDRPC DEVELOP\
HAVE_BLUAJIT
# build with debugging information
ifdef DEBUGMODE
+5
View File
@@ -26,6 +26,11 @@ ifeq (${DEDICATED},1)
EXENAME?=lsrb2kartd
endif
ifdef HAVE_BLUAJIT
libs+=-L../libs/bluajit/src/ -l:libbluajit.a
opts+=-I../libs/bluajit/src/
endif
# In common usage.
ifdef LINUX
libs+=-lrt
+5
View File
@@ -69,6 +69,11 @@ LIBOPENMPT_opts:=-I$(lib)/inc
LIBOPENMPT_libs:=-L$(lib)/lib/$(x86) -lopenmpt
$(eval $(call _set,LIBOPENMPT))
lib:=../libs/bluajit
BLUAJIT_opts:=-I$(lib)/src
BLUAJIT_libs:=-L$(lib)/lib/$(x86) -lbluajit
$(eval $(call _set,BLUAJIT))
lib:=../libs/SDL2_mixer/$(mingw)
ifdef SDL
+5 -70
View File
@@ -17,27 +17,14 @@
#include "lauxlib.h"
#include "lualib.h"
#include "../i_system.h"
#include "../doomdef.h"
#include "../d_main.h"
#include "../m_misc.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
#define FILELIMIT 1024*1024 // Size limit for reading/writing files
static const char *const fnames[] = {"input", "output"};
static const char *whitelist[] = { // Allow scripters to write files of these types to SRB2's folder
".txt",
".sav2",
".cfg",
".png",
".bmp"
};
static int pushresult (lua_State *L, int i, const char *filename) {
@@ -159,59 +146,12 @@ static int io_tostring (lua_State *L) {
return 1;
}
static int StartsWith(const char *a, const char *b) // this is wolfs being lazy yet again
{
if(strncmp(a, b, strlen(b)) == 0) return 1;
return 0;
}
static int io_open (lua_State *L) {
FILE **pf;
const char *filename = luaL_checkstring(L, 1);
int pass = 0;
size_t i;
int length = strlen(filename);
char *splitter, *forward, *backward;
char *destFilename;
const char *mode = luaL_optstring(L, 2, "r");
for (i = 0; i < (sizeof (whitelist) / sizeof(const char *)); i++)
{
if (!stricmp(&filename[length - strlen(whitelist[i])], whitelist[i]))
{
pass = 1;
break;
}
}
if (l_unlikely(strstr(filename, "..") || strchr(filename, ':') || StartsWith(filename, "\\")
|| StartsWith(filename, "/") || !pass))
{
luaL_error(L,"access denied to %s", filename);
return pushresult(L,0,filename);
}
destFilename = va("%s"PATHSEP"luafiles"PATHSEP"%s", srb2home, filename);
// Make directories as needed
splitter = destFilename;
forward = strchr(splitter, '/');
backward = strchr(splitter, '\\');
while ((splitter = (forward && backward) ? min(forward, backward) : (forward ?: backward)))
{
*splitter = 0;
I_mkdir(destFilename, 0755);
*splitter = '/';
splitter++;
forward = strchr(splitter, '/');
backward = strchr(splitter, '\\');
}
pf = newfile(L);
*pf = fopen(destFilename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
FILE **pf = newfile(L);
*pf = fopen(filename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
}
@@ -454,11 +394,6 @@ static int g_write (lua_State *L, FILE *f, int arg) {
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
if (l_unlikely(ftell(f) + l > FILELIMIT))
{
luaL_error(L,"write limit bypassed in file. Changes have been discarded.");
break;
}
status = status && (fwrite(s, sizeof(char), l, f) == l);
}
}
+4
View File
@@ -777,6 +777,10 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_netdemosyncquality);
CV_RegisterVar(&cv_maxdemosize);
CV_RegisterVar(&cv_demochangemap);
#ifdef HAVE_BLUAJIT
CV_RegisterVar(&cv_luajit);
#endif
}
// =========================================================================
+72 -36
View File
@@ -1138,6 +1138,33 @@ static boolean K_UseColorSpeedo(int speedostyle)
}
}
enum
{
GAUGE_DEFAULT = 1,
GAUGE_SMALL,
GAUGE_BIGNUM,
GAUGE_NUMONLY,
GAUGE_EXTRA,
};
static SINT8 K_GetDriftgaugeStyle(void)
{
if (driftgaugegfx)
{
if (cv_driftgaugestyle.value == 1)
return GAUGE_DEFAULT;
else if (cv_driftgaugestyle.value == 2)
return GAUGE_SMALL;
else if (cv_driftgaugestyle.value == 3)
return GAUGE_BIGNUM;
else if (cv_driftgaugestyle.value == 5 && xtra_speedo3)
return GAUGE_EXTRA;
}
// Fallback
return GAUGE_NUMONLY; // (cv_driftgaugestyle.value == 4)
}
static boolean K_IsHighResolution(void)
{
return (vid.width >= 640 && vid.height >= 400);
@@ -1699,7 +1726,7 @@ static void K_drawKartItem(void)
switch (stplyr->kartstuff[k_itemblinkmode])
{
case 2:
localcolor = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
localcolor = K_RainbowColor();
break;
case 1:
localcolor = SKINCOLOR_RED;
@@ -3149,7 +3176,7 @@ static void K_drawDriftGauge(void)
fixed_t basex, basey;
const int dup = vid.dupx;
int i;
UINT8 *cmap;
UINT8 *colormap = NULL;
static const UINT8 driftcolors[3][4] = {
{0, 0, 10, 16}, // no drift
@@ -3195,23 +3222,21 @@ skipcrap:
const INT32 driftcharge = min(driftval*4, stplyr->kartstuff[k_driftcharge]);
const INT32 driftlevel = min(driftcharge / driftval, 2);
const INT32 drifttrans = ((cv_driftgaugetrans.value) ? V_LocalTransFlag() : 0);
const SINT8 gaugestyle = K_GetDriftgaugeStyle();
basex = pos.x>>FRACBITS;
basey = pos.y>>FRACBITS;
switch (cv_driftgaugestyle.value)
switch (gaugestyle)
{
case 1:
case 2:
case 3:
case 5:
case GAUGE_DEFAULT:
case GAUGE_SMALL:
case GAUGE_EXTRA:
case GAUGE_BIGNUM:
{
if (!driftgaugegfx)
break;
patch_t *driftpatch = NULL;
const boolean usescaledpatch = (cv_driftgaugestyle.value == 5 && xtra_speedo3);
if (cv_driftgaugestyle.value == 1 || cv_driftgaugestyle.value == 3 || usescaledpatch)
if (gaugestyle == GAUGE_DEFAULT || gaugestyle == GAUGE_BIGNUM || gaugestyle == GAUGE_EXTRA)
{
barx = basex - dup*23;
BAR_WIDTH = dup*47;
@@ -3224,40 +3249,44 @@ skipcrap:
bary = basey - dup*2;
if (usescaledpatch) // i hate hud code i hate hud code i hate hud code i hate hud code i hate hud code.....
if (gaugestyle == GAUGE_EXTRA) // i hate hud code i hate hud code i hate hud code i hate hud code i hate hud code.....
{
if (K_UseColorSpeedo(SPEEDO_EXTRA3)) // Colourized hud
if (K_UseColorSpeedo(SPEEDO_EXTRA3)) // We reuse the extra speedometer patch hence this check
{
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
V_DrawStretchyFixedPatch((basex - dup*30)<<FRACBITS, ((basey<<FRACBITS) - FixedMul(dup<<FRACBITS, 21*FRACUNIT/10)), XTRA3PSCALE, XTRA3VSCALE, V_NOSCALESTART|V_OFFSET|drifttrans, skp_smallstickerclr3, colormap, 0);
colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
driftpatch = skp_smallstickerclr3;
}
else
V_DrawStretchyFixedPatch((basex - dup*30)<<FRACBITS, ((basey<<FRACBITS) - FixedMul(dup<<FRACBITS, 21*FRACUNIT/10)), XTRA3PSCALE, XTRA3VSCALE, V_NOSCALESTART|V_OFFSET|drifttrans, skp_smallsticker3, NULL, 0);
driftpatch = skp_smallsticker3;
V_DrawStretchyFixedPatch((basex - dup*30)<<FRACBITS, ((basey<<FRACBITS) - FixedMul(dup<<FRACBITS, 21*FRACUNIT/10)), XTRA3PSCALE, XTRA3VSCALE, V_NOSCALESTART|V_OFFSET|drifttrans, driftpatch, colormap, 0);
}
else
{
if (K_UseColorHud()) // Colourized hud
{
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
V_DrawMappedPatch(cv_driftgaugestyle.value == 2 ? basex + dup*11 : basex, basey, V_NOSCALESTART|V_OFFSET|drifttrans, cv_driftgaugestyle.value == 2 ? driftgaugesmallcolor : driftgaugecolor, colormap);
colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
driftpatch = (gaugestyle == GAUGE_SMALL ? driftgaugesmallcolor : driftgaugecolor);
}
else
V_DrawMappedPatch(cv_driftgaugestyle.value == 2 ? basex + dup*11 : basex, basey, V_NOSCALESTART|V_OFFSET|drifttrans, cv_driftgaugestyle.value == 2 ? driftgaugesmall : driftgauge, NULL);
driftpatch = (gaugestyle == GAUGE_SMALL ? driftgaugesmall : driftgauge);
V_DrawMappedPatch(gaugestyle == GAUGE_SMALL ? basex + dup*11 : basex, basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftpatch, colormap);
}
if (driftcharge >= driftval*4) // rainbow sparks
{
cmap = R_GetTranslationColormap(TC_RAINBOW, 1 + leveltime % (MAXSKINCOLORS-1),GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(), GTC_CACHE);
for (i = 0; i < 4; i++)
V_DrawFill(barx, bary+dup*1+dup*i, BAR_WIDTH, dup, (driftrainbow[min((leveltime % 18) + 1, 18 - 1)] + i*2) | V_NOSCALESTART|drifttrans);
V_DrawFill(barx, bary+dup*1+dup*i, BAR_WIDTH, dup, (driftrainbow[min((leveltime % 18) + 1, 17)] + i*2) | V_NOSCALESTART|drifttrans);
}
else // none/blue/red
{
const INT32 limit = (driftval * (driftcharge >= driftval*2 ? 2 : 1));
const INT32 width = ((driftcharge - (driftcharge >= driftval ? limit : 0)) * BAR_WIDTH) / limit;
cmap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel],GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel], GTC_CACHE);
for (i = 0; i < 4; i++)
{
@@ -3269,20 +3298,20 @@ skipcrap:
}
// right, also draw a cool number
if (cv_driftgaugestyle.value == 3)
V_DrawPaddedTallColorNum(basex + (dup*32), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, cmap);
if (gaugestyle == GAUGE_BIGNUM)
V_DrawPaddedTallColorNum(basex + (dup*32), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, colormap);
else
V_DrawPingNum(cv_driftgaugestyle.value == 2 ? basex + (dup*22) : basex + (dup*32), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, cmap);
V_DrawPingNum((gaugestyle == GAUGE_SMALL ? basex + (dup*22) : basex + (dup*32)), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, colormap);
}
break;
case 4:
case GAUGE_NUMONLY:
{
if (driftcharge >= driftval*4)
cmap = R_GetTranslationColormap(TC_RAINBOW, 1 + leveltime % (MAXSKINCOLORS-1),GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(), GTC_CACHE);
else
cmap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel],GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel], GTC_CACHE);
V_DrawPaddedTallColorNum(basex + (dup*16), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, cmap);
V_DrawPaddedTallColorNum(basex + (dup*16), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, colormap);
}
break;
default:
@@ -3343,6 +3372,7 @@ static void K_drawKartWanted(void)
{
basex = WANT_X;
basey = WANT_Y;
if (splitscreen == 2)
{
basey += 16; // slight adjust for 3P
@@ -4092,17 +4122,23 @@ static void K_drawKartFirstPerson(void)
x -= xoffs;
else
x += xoffs;
if (!splitscreen)
y += yoffs;
}
const INT32 driftcharge = stplyr->kartstuff[k_driftcharge];
// drift sparks!
if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsthree))
colmap = R_GetTranslationColormap(TC_RAINBOW, (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))), GTC_CACHE);
else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dstwo))
colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_KETCHUP, GTC_CACHE);
else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsone))
colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SAPPHIRE, GTC_CACHE);
if ((leveltime & 1) && driftcharge)
{
if (driftcharge >= dsthree)
colmap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(), GTC_CACHE);
else if (driftcharge >= dstwo)
colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_KETCHUP, GTC_CACHE);
else if (driftcharge >= dsone)
colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SAPPHIRE, GTC_CACHE);
}
else
#endif
// invincibility/grow/shrink!
+21 -2
View File
@@ -484,6 +484,15 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = {
{120, 120, 96, 96, 97, 98, 98, 99, 81, 81, 69, 71, 73, 75, 77, 79}, // SKINCOLOR_CSUPER5
};
//
// Gives you a color to use for rainbow effects (like invincibility).
// Return: Skincolor value.
//
UINT8 K_RainbowColor(void)
{
return (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
}
// Define for getting accurate color brightness readings according to how the human eye sees them.
// https://en.wikipedia.org/wiki/Relative_luminance
// 0.2126 to red
@@ -645,36 +654,46 @@ UINT8 K_GetKartColorByName(const char *name)
return 0;
}
//
// returns the players skinnumber
// accounts for localskins
//
INT32 K_GetSkinNum(player_t *player)
{
return player->localskin ? (player->localskin - 1) : player->skin;
}
//
// returns the mobj skinnumber
// accounts for localskins
//
INT32 K_GetMobjSkinNum(const skin_t *skin, boolean local)
{
return skin - K_GetSkinArray(local);
}
//
// returns the players skinnumber
// accounts for localskins
//
skin_t *K_GetMobjSkin(const mobj_t *mobj)
{
return mobj->localskin ? mobj->localskin : mobj->skin;
}
//
// returns the skin array to use
// accounts for localskins
//
skin_t *K_GetSkinArray(boolean local)
{
return local ? localskins : skins;
}
//
// returns the players skin
// accounts for localskins
//
skin_t *K_GetPlayerSkin(player_t *player)
{
return &K_GetSkinArray(player->skinlocal)[K_GetSkinNum(player)];
@@ -3084,7 +3103,7 @@ static UINT16 K_DriftSparkColor(player_t *player, INT32 charge)
if (charge >= K_GetKartDriftSparkValue(player)*4)
{
color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
color = K_RainbowColor();
}
else if (charge >= K_GetKartDriftSparkValue(player)*2)
{
@@ -5371,7 +5390,7 @@ static UINT8 K_GetSpeedLineColor(player_t *player, boolean colorSpeed)
else if (player->kartstuff[k_driftboost] <= 50)
speedcolor = SKINCOLOR_RASPBERRY;
else if (player->kartstuff[k_driftboost] <= 125)
speedcolor = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
speedcolor = K_RainbowColor();
if (cv_coloredspeedlines.value == 2)
speedcolor = (leveltime & 1) ? playercolor : speedcolor;
+1
View File
@@ -19,6 +19,7 @@ extern "C" {
extern UINT8 colortranslations[MAXTRANSLATIONS][16];
extern const char *KartColor_Names[MAXSKINCOLORS];
extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2];
UINT8 K_RainbowColor(void);
void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor);
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color, boolean local);
UINT8 K_GetKartColorByName(const char *name);
+139
View File
@@ -42,6 +42,123 @@ boolean luaL_checkboolean(lua_State *L, int narg) {
return lua_toboolean(L, narg);
}
static int ref_open, ref_iowrite, ref_fwrite; // original versions of io functions
#define FILELIMIT 1024*1024 // Size limit for reading/writing files
static const char *whitelist[] = { // Allow scripters to write files of these types to SRB2's folder
".txt",
".sav2",
".cfg",
".png",
".bmp"
};
static int StartsWith(const char *a, const char *b) // this is wolfs being lazy yet again
{
if(strncmp(a, b, strlen(b)) == 0) return 1;
return 0;
};
// Wrapper for opening files
static int lib_open(lua_State *L)
{
const char *filename = luaL_checkstring(L, 1);
int pass = 0;
size_t i;
int length = strlen(filename);
char *splitter, *forward, *backward;
char *destFilename;
for (i = 0; i < (sizeof (whitelist) / sizeof(const char *)); i++)
{
if (!stricmp(&filename[length - strlen(whitelist[i])], whitelist[i]))
{
pass = 1;
break;
}
}
if (strstr(filename, "..") || strchr(filename, ':') || StartsWith(filename, "\\")
|| StartsWith(filename, "/") || !pass)
{
return luaL_error(L,"access denied to %s", filename);
}
destFilename = va("%s"PATHSEP"luafiles"PATHSEP"%s", srb2home, filename);
// Make directories as needed
splitter = destFilename;
forward = strchr(splitter, '/');
backward = strchr(splitter, '\\');
while ((splitter = (forward && backward) ? min(forward, backward) : (forward ?: backward)))
{
*splitter = 0;
I_mkdir(destFilename, 0755);
*splitter = '/';
splitter++;
forward = strchr(splitter, '/');
backward = strchr(splitter, '\\');
}
// replace the filename string
lua_pushstring(L, destFilename);
lua_replace(L, 1);
// now call the real io.open
lua_rawgeti(L, LUA_REGISTRYINDEX, ref_open);
lua_insert(L, 1);
lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
return lua_gettop(L);
}
// Wrapper for writing to files
static int lib_write(lua_State *L, int arg)
{
int top = lua_gettop(L);
boolean error = true;
size_t len, size = 0;
int ogref = ref_iowrite;
if (arg != 1) {
ogref = ref_fwrite;
FILE *fp = *(FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE);
if (fp == NULL) goto call; // real file:write will throw
size = ftell(fp);
}
// check the size of each argument. if there's too much data,
// cut off the stack and print an error
for (; arg <= top; arg++) {
if (lua_tolstring(L, arg, &len) == NULL) goto call;
if ((size += len) > FILELIMIT) {
// oops! too many bytes!
lua_settop(L, arg-1);
goto call;
}
}
error = false;
call:
lua_rawgeti(L, LUA_REGISTRYINDEX, ogref);
lua_insert(L, 1);
lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
if (error)
return luaL_error(L,"write limit bypassed in file. Changes have been discarded.");
return lua_gettop(L);
}
static int lib_write_f(lua_State *L)
{
return lib_write(L, 2);
}
static int lib_write_io(lua_State *L)
{
return lib_write(L, 1);
}
// String concatination
static int lib_concat(lua_State *L)
{
@@ -3348,6 +3465,28 @@ int LUA_BaseLib(lua_State *L)
lua_setfield(L,-2,"__add"); // ... store it as mathematical addition
lua_pop(L, 2); // pop metatable and dummy string
// replaces an existing function with another,
// saving the original as a reference
#define REPLACE(name, func, ref) \
lua_pushliteral(L, name); \
lua_rawget(L, -2); \
ref = luaL_ref(L, LUA_REGISTRYINDEX); \
lua_pushliteral(L, name); \
lua_pushcclosure(L, &func, 0); \
lua_rawset(L, -3);
// replace io.open
lua_getglobal(L, "io");
REPLACE("open", lib_open, ref_open)
REPLACE("write", lib_write_io, ref_iowrite)
lua_pop(L, 1);
// replace file:write
luaL_getmetatable(L, LUA_FILEHANDLE);
REPLACE("write", lib_write_f, ref_fwrite)
lua_pop(L, 1);
#undef REPLACE
lua_newtable(L);
lua_setfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
+41 -27
View File
@@ -324,13 +324,14 @@ static int lib_cvRegisterVar(lua_State *L)
const char* category = NULL;
const char* menu_name = NULL;
boolean hasfunc = false;
int funcref = 0;
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one.
NOHUD
cvar = lua_newuserdata(L, sizeof(consvar_t));
luaL_getmetatable(L, META_CVAR);
lua_setmetatable(L, -2);
cvar = ZZ_Calloc(sizeof(consvar_t));
LUA_PushUserdata(L, cvar, META_CVAR);
#define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to " LUA_QL("CV_RegisterVar") " (%s)", e);
#define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1)))
@@ -404,27 +405,38 @@ static int lib_cvRegisterVar(lua_State *L)
cvpv[i].value = 0;
cvpv[i].strvalue = NULL;
cvar->PossibleValue = cvpv;
// MIN and MAX are expected to be at hardcoded indices apparently
// so, sigh, here goes...
#define SWAP(from, to) \
INT32 val = cvpv[from].value; \
const char *strval = cvpv[from].strvalue; \
cvpv[from].value = cvpv[to].value; \
cvpv[from].strvalue = cvpv[to].strvalue; \
cvpv[to].value = val; \
cvpv[to].strvalue = strval;
for (int j = 0; j < i; j++) {
if (!strcmp(cvpv[j].strvalue, "MIN") && j != 0) {
SWAP(j, 0)
} else if (!strcmp(cvpv[j].strvalue, "MAX") && j != 1) {
SWAP(j, 1)
}
}
} else
FIELDERROR("PossibleValue", va("%s or CV_PossibleValue_t expected, got %s", lua_typename(L, LUA_TTABLE), luaL_typename(L, -1)))
} else if (i == 5 || (k && fasticmp(k, "func"))) {
if (!lua_isfunction(L, 4))
TYPEERROR("func", LUA_TFUNCTION)
lua_getfield(L, LUA_REGISTRYINDEX, "CV_OnChange");
I_Assert(lua_istable(L, 5));
lua_pushvalue(L, 4);
lua_setfield(L, 5, cvar->name);
lua_pop(L, 1);
cvar->func = Lua_OnChange;
if (hasfunc)
luaL_unref(L, LUA_REGISTRYINDEX, funcref); // real clever, huh?
funcref = luaL_ref(L, LUA_REGISTRYINDEX);
hasfunc = true;
continue;
}
else if (((i == 5 && !(cvar->flags & CV_CALL))
|| (cvar->flags & CV_CALL && i == 6))
|| (k && fasticmp(k, "category")))
else if (i == 6 || (k && fasticmp(k, "category")))
{
category = lua_isnoneornil(L, 4) ? NULL : lua_tostring(L, 4);
}
else if (((i == 6 && !(cvar->flags & CV_CALL))
|| (cvar->flags & CV_CALL && i == 7))
|| (k && fasticmp(k, "menuname")))
else if (i == 7 || (k && fasticmp(k, "menuname")))
{
menu_name = lua_isnoneornil(L, 4) ? NULL : lua_tostring(L, 4);
}
@@ -434,6 +446,16 @@ static int lib_cvRegisterVar(lua_State *L)
#undef TYPEERROR
// stack: cvar table, cvar userdata
if (hasfunc) {
lua_getfield(L, LUA_REGISTRYINDEX, "CV_OnChange");
I_Assert(lua_istable(L, 3));
lua_rawgeti(L, LUA_REGISTRYINDEX, funcref);
lua_setfield(L, 3, cvar->name);
lua_pop(L, 1);
cvar->func = Lua_OnChange;
luaL_unref(L, LUA_REGISTRYINDEX, funcref);
}
lua_getfield(L, LUA_REGISTRYINDEX, "CV_Vars");
I_Assert(lua_istable(L, 3));
@@ -479,15 +501,7 @@ static int lib_cvFindVar(lua_State *L)
consvar_t *cv;
if (( cv = CV_FindVar(luaL_checkstring(L,1)) ))
{
lua_settop(L,1);/* We only want one argument in the stack. */
lua_pushlightuserdata(L, cv);/* Now the second value on stack. */
luaL_getmetatable(L, META_CVAR);
/*
The metatable is the last value on the stack, so this
applies it to the second value, which is the cvar.
*/
lua_setmetatable(L,2);
lua_pushvalue(L,2);
LUA_PushUserdata(L, cv, META_CVAR);
return 1;
}
else
@@ -500,7 +514,7 @@ static int CVarSetFunction
void (*Set)(consvar_t *, const char *),
void (*SetValue)(consvar_t *, INT32)
){
consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR);
consvar_t *cvar = *((consvar_t **)luaL_checkudata(L, 1, META_CVAR));
switch (lua_type(L, 2))
{
@@ -529,7 +543,7 @@ static int lib_cvStealthSet(lua_State *L)
static int lib_cvAddValue(lua_State *L)
{
consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR);
consvar_t *cvar = *((consvar_t **)luaL_checkudata(L, 1, META_CVAR));
CV_AddValue(cvar, (INT32)luaL_checknumber(L, 2));
return 0;
}
@@ -604,7 +618,7 @@ static int cvar_fields_ref = LUA_NOREF;
static int cvar_get(lua_State *L)
{
consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR);
consvar_t *cvar = *((consvar_t **)luaL_checkudata(L, 1, META_CVAR));
enum cvar_e field = Lua_optoption(L, 2, -1, cvar_fields_ref);
switch (field)
+12 -1
View File
@@ -12,7 +12,11 @@
#include "lua_hudlib_drawlist.h"
#include "lua_hud.h"
#ifndef HAVE_BLUAJIT
#include "blua/lstate.h" // shhhhhh
#else
#include "lua_script.h"
#endif
#include "lua_libs.h"
#include <string.h>
@@ -328,8 +332,15 @@ static UINT64 GetItemId(void)
if (!hud_interpolate)
return 0;
#ifndef HAVE_BLUAJIT
UINT64 id = (uintptr_t)gL->savedpc;
#else
// he who controls the JIT controls the API
const void *p = lua_getpc(gL, 1);
UINT64 id = (uintptr_t)p;
#endif
// leave bits 0 and 1 free for the string mode
UINT64 id = ((UINT64)(uintptr_t)gL->savedpc << 32) | (hud_interpcounter << 10) | (hud_interptag << 2);
id = (id << 32) | (hud_interpcounter << 10) | (hud_interptag << 2);
if (hud_interplatch)
{
+5
View File
@@ -11,7 +11,12 @@
/// \brief libraries for Lua scripting
#include "doomtype.h"
#ifndef HAVE_BLUAJIT
#include "blua/lua.h"
#else
#include <lua.h>
#endif
extern lua_State *gL;
+50
View File
@@ -35,6 +35,14 @@
#include "doomstat.h"
#ifdef HAVE_BLUAJIT
#include "d_main.h"
#include "i_system.h"
static void LuaJit_OnChange(void);
static void print_jit_status(boolean verbose);
consvar_t cv_luajit = {"luajit", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, LuaJit_OnChange, 0, NULL, NULL, 0, 0, NULL};
#endif
lua_State *gL = NULL;
// Mathlib global state
@@ -61,6 +69,21 @@ static lua_CFunction liblist[] = {
NULL
};
#ifdef HAVE_BLUAJIT
static void LuaJit_OnChange(void)
{
if (!gL)
LUA_ClearState();
lua_getfield(gL, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(gL, -1, "jit");
lua_remove(gL, -2);
lua_getfield(gL, -1, cv_luajit.value ? "on" : "off");
lua_remove(gL, -2);
lua_call(gL, 0, 0);
print_jit_status(false);
}
#endif
// Lua asks for memory using this.
static void *LUA_Alloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
@@ -185,6 +208,29 @@ static int noglobals(lua_State *L)
return luaL_error(L, "Implicit global " LUA_QS " prevented. Create a local variable instead.", csname);
}
#ifdef HAVE_BLUAJIT
// print all the ISA extensions because it looks cool!
// absolutely not stolen from luajit.c
static void print_jit_status(boolean verbose)
{
int n;
const char *s;
lua_getfield(gL, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(gL, -1, "jit"); /* Get jit.* module table. */
lua_remove(gL, -2);
lua_getfield(gL, -1, "status");
lua_remove(gL, -2);
n = lua_gettop(gL);
lua_call(gL, 0, LUA_MULTRET);
CONS_Printf(lua_toboolean(gL, n) ? "JIT: ON" : "JIT: OFF");
if (verbose)
for (n++; (s = lua_tostring(gL, n)); n++)
CONS_Printf(" %s", s);
CONS_Printf("\n");
lua_settop(gL, 0); /* clear stack */
}
#endif
// Clear and create a new Lua state, laddo!
// There's SCRIPTIN to be had!
void LUA_ClearState(void)
@@ -227,6 +273,10 @@ void LUA_ClearState(void)
// lua state is ready!
gL = L;
#ifdef HAVE_BLUAJIT
print_jit_status(true);
#endif
}
#ifdef _DEBUG
+10
View File
@@ -18,9 +18,19 @@
#include "d_player.h"
#include "p_saveg.h"
#ifndef HAVE_BLUAJIT
#include "blua/lua.h"
#include "blua/lualib.h"
#include "blua/lauxlib.h"
#else
#include "command.h"
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
lua_gettop(L) + (i) + 1)
extern consvar_t cv_luajit;
#endif
#define lua_optboolean(L, i) (!lua_isnoneornil(L, i) && lua_toboolean(L, i))
#define lua_opttrueboolean(L, i) (lua_isnoneornil(L, i) || lua_toboolean(L, i))
+3 -3
View File
@@ -6964,7 +6964,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
if (mobj->flags2 & MF2_AMBUSH)
{
mobj->colorized = true;
mobj->color = (1 + (leveltime % (MAXSKINCOLORS-1)));
mobj->color = K_RainbowColor();
mobj->frame |= FF_FULLBRIGHT;
}
else
@@ -7806,7 +7806,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_SetScale(mobj, (mobj->destscale = mobj->target->scale));
if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player)*4)
mobj->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
mobj->color = K_RainbowColor();
else if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player)*2)
mobj->color = SKINCOLOR_KETCHUP;
else if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player))
@@ -8505,7 +8505,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->flags2 & MF2_AMBUSH)
{
mobj->colorized = true;
mobj->color = (1 + (leveltime % (MAXSKINCOLORS-1)));
mobj->color = K_RainbowColor();
mobj->frame |= FF_FULLBRIGHT;
}
else
+24 -29
View File
@@ -650,6 +650,27 @@ size_t P_PrecacheLevelFlats(void)
return flatmem;
}
// check if our flat contains cyan pixels
// not sure if this is the best way to do it but it works
static void P_CheckCyanFlat(levelflat_t *levelflat)
{
// only need this for software
if (rendermode != render_soft)
return;
const UINT8 *flat = R_GetFlat(levelflat->lumpnum);
const size_t size = W_LumpLength(levelflat->lumpnum);
for (size_t steppy = 0; steppy < size; steppy++)
{
if (flat[steppy] == TRANSPARENTPIXEL)
{
levelflat->cyan = true;
break;
}
}
}
// help function for P_LoadSectors, find a flat in the active wad files,
// allocate an id for it, and set the levelflat (to speedup search)
//
@@ -661,7 +682,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
// first scan through the already found flats
//
for (i = 0; i < numlevelflats; i++, levelflat++)
if (strnicmp(levelflat->name,flatname,8) == 0)
if (strnicmp(levelflat->name, flatname, 8) == 0)
break;
// that flat was already found in the level, return the id
@@ -675,20 +696,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
levelflat->lumpnum = R_GetFlatNumForName(flatname);
levelflat->baselumpnum = LUMPERROR;
// check if our flat contains cyan pixels
// not sure if this is the best way to do it but it works
{
const UINT8 *flat = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_LEVEL);
size_t size = W_LumpLength(levelflat->lumpnum);
for (size_t steppy = 0; steppy < size; steppy++)
{
if (flat[steppy] == TRANSPARENTPIXEL)
{
levelflat->cyan = true;
break;
}
}
}
P_CheckCyanFlat(levelflat);
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
@@ -735,20 +743,7 @@ INT32 P_AddLevelFlatRuntime(const char *flatname)
levelflat->lumpnum = R_GetFlatNumForName(flatname);
levelflat->baselumpnum = LUMPERROR;
// check if our flat contains cyan pixels
// not sure if this is the best way to do it but it works
{
const UINT8 *flat = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_LEVEL);
size_t size = W_LumpLength(levelflat->lumpnum);
for (size_t steppy = 0; steppy < size; steppy++)
{
if (flat[steppy] == TRANSPARENTPIXEL)
{
levelflat->cyan = true;
break;
}
}
}
P_CheckCyanFlat(levelflat);
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
+1 -1
View File
@@ -1641,7 +1641,7 @@ static void P_CheckInvincibilityTimer(player_t *player)
if (!player->powers[pw_invulnerability] && !player->kartstuff[k_invincibilitytimer])
return;
player->mo->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
player->mo->color = K_RainbowColor();
// Resume normal music stuff.
if (player->powers[pw_invulnerability] == 1 || player->kartstuff[k_invincibilitytimer] == 1)
+1 -3
View File
@@ -1182,7 +1182,7 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
levelflat = &levelflats[pl->picnum];
// Get the texture
ds->source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag
ds->source = R_GetFlat(levelflat->lumpnum);
if (ds->source == NULL)
return;
@@ -1387,8 +1387,6 @@ using the palette colors.
}
}
#endif
Z_ChangeTag(ds->source, PU_CACHE);
}
void R_PlaneBounds(visplane_t *plane)