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

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
  • Jisk/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
117 results
Select Git revision
Show changes
Commits on Source (101)
......@@ -266,6 +266,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
blua/lfunc.c
blua/lgc.c
blua/linit.c
blua/liolib.c
blua/llex.c
blua/lmem.c
blua/lobject.c
......
......@@ -18,6 +18,7 @@ OBJS:=$(OBJS) \
$(OBJDIR)/ldo.o \
$(OBJDIR)/lfunc.o \
$(OBJDIR)/linit.o \
$(OBJDIR)/liolib.o \
$(OBJDIR)/llex.o \
$(OBJDIR)/lmem.o \
$(OBJDIR)/lobject.o \
......
......@@ -17,6 +17,7 @@
static const luaL_Reg lualibs[] = {
{"", luaopen_base},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_STRLIBNAME, luaopen_string},
{NULL, NULL}
};
......
/*
** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define liolib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "../i_system.h"
#include "../doomdef.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) {
int en = errno; /* calls to Lua API may change this value */
if (i) {
lua_pushboolean(L, 1);
return 1;
}
else {
lua_pushnil(L);
if (filename)
lua_pushfstring(L, "%s: %s", filename, strerror(en));
else
lua_pushfstring(L, "%s", strerror(en));
lua_pushinteger(L, en);
return 3;
}
}
static void fileerror (lua_State *L, int arg, const char *filename) {
lua_pushfstring(L, "%s: %s", filename, strerror(errno));
luaL_argerror(L, arg, lua_tostring(L, -1));
}
#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
static int io_type (lua_State *L) {
void *ud;
luaL_checkany(L, 1);
ud = lua_touserdata(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
lua_pushnil(L); /* not a file */
else if (*((FILE **)ud) == NULL)
lua_pushliteral(L, "closed file");
else
lua_pushliteral(L, "file");
return 1;
}
static FILE *tofile (lua_State *L) {
FILE **f = tofilep(L);
if (*f == NULL)
luaL_error(L, "attempt to use a closed file");
return *f;
}
/*
** When creating file handles, always creates a `closed' file handle
** before opening the actual file; so, if there is a memory error, the
** file is not left opened.
*/
static FILE **newfile (lua_State *L) {
FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
*pf = NULL; /* file handle is currently `closed' */
luaL_getmetatable(L, LUA_FILEHANDLE);
lua_setmetatable(L, -2);
return pf;
}
/*
** function to (not) close the standard files stdin, stdout, and stderr
*/
static int io_noclose (lua_State *L) {
lua_pushnil(L);
lua_pushliteral(L, "cannot close standard file");
return 2;
}
/*
** function to close regular files
*/
static int io_fclose (lua_State *L) {
FILE **p = tofilep(L);
int ok = (fclose(*p) == 0);
*p = NULL;
return pushresult(L, ok, NULL);
}
static int aux_close (lua_State *L) {
lua_getfenv(L, 1);
lua_getfield(L, -1, "__close");
return (lua_tocfunction(L, -1))(L);
}
static int io_close (lua_State *L) {
if (lua_isnone(L, 1))
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
tofile(L); /* make sure argument is a file */
return aux_close(L);
}
static int io_gc (lua_State *L) {
FILE *f = *tofilep(L);
/* ignore closed files */
if (f != NULL)
aux_close(L);
return 0;
}
static int io_tostring (lua_State *L) {
FILE *f = *tofilep(L);
if (f == NULL)
lua_pushliteral(L, "file (closed)");
else
lua_pushfstring(L, "file (%p)", f);
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) {
const char *Cfilename = luaL_checkstring(L, 1);
char *filename = strdup(Cfilename);
int pass = 0;
size_t i;
int length = strlen(filename) - 1;
char *splitter, *splitter2;
char* destFilename;
const char *mode;
FILE **pf;
for (i = 0; i < (sizeof (whitelist) / sizeof(const char *)); i++)
{
if (!stricmp(&filename[length - (strlen(whitelist[i]) - 1)], whitelist[i]))
{
pass = 1;
break;
}
}
if (strstr(filename, "..") || strchr(filename, ':') || StartsWith(filename, "\\")
|| StartsWith(filename, "/") || strchr(filename, '%') || !pass)
{
luaL_error(L,"access denied to %s", filename);
return pushresult(L,0,filename);
}
I_mkdir("luafiles", 0755);
splitter = strdup(filename);
while ((splitter = strchr(splitter, '/')))
{
*splitter = 0;
I_mkdir(va("luafiles"PATHSEP"%s", filename), 0755);
*splitter = '/';
splitter++;
}
splitter2 = strdup(filename);
while ((splitter2 = strchr(splitter2, '\\')))
{
*splitter2 = 0;
I_mkdir(va("luafiles"PATHSEP"%s", filename), 0755);
*splitter2 = '\\';
splitter2++;
}
destFilename = va("luafiles"PATHSEP"%s", filename);
filename = destFilename;
mode = luaL_optstring(L, 2, "r");
pf = newfile(L);
*pf = fopen(filename, mode);
free(splitter);
free(splitter2);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
}
static int io_tmpfile (lua_State *L) {
FILE **pf = newfile(L);
*pf = tmpfile();
return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
}
static FILE *getiofile (lua_State *L, int findex) {
FILE *f;
lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
f = *(FILE **)lua_touserdata(L, -1);
if (f == NULL)
luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
return f;
}
static int g_iofile (lua_State *L, int f, const char *mode) {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
if (filename) {
FILE **pf = newfile(L);
*pf = fopen(filename, mode);
if (*pf == NULL)
fileerror(L, 1, filename);
}
else {
tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1);
}
lua_rawseti(L, LUA_ENVIRONINDEX, f);
}
/* return current value */
lua_rawgeti(L, LUA_ENVIRONINDEX, f);
return 1;
}
static int io_input (lua_State *L) {
return g_iofile(L, IO_INPUT, "r");
}
static int io_output (lua_State *L) {
return g_iofile(L, IO_OUTPUT, "w");
}
static int io_readline (lua_State *L);
static void aux_lines (lua_State *L, int idx, int toclose) {
lua_pushvalue(L, idx);
lua_pushboolean(L, toclose); /* close/not close file when finished */
lua_pushcclosure(L, io_readline, 2);
}
static int f_lines (lua_State *L) {
tofile(L); /* check that it's a valid file handle */
aux_lines(L, 1, 0);
return 1;
}
static int io_lines (lua_State *L) {
if (lua_isnoneornil(L, 1)) { /* no arguments? */
/* will iterate over default input */
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
return f_lines(L);
}
else {
const char *filename = luaL_checkstring(L, 1);
FILE **pf = newfile(L);
*pf = fopen(filename, "r");
if (*pf == NULL)
fileerror(L, 1, filename);
aux_lines(L, lua_gettop(L), 1);
return 1;
}
}
/*
** {======================================================
** READ
** =======================================================
*/
static int read_number (lua_State *L, FILE *f) {
lua_Number d;
if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
lua_pushnumber(L, d);
return 1;
}
else return 0; /* read fails */
}
static int test_eof (lua_State *L, FILE *f) {
int c = getc(f);
ungetc(c, f);
lua_pushlstring(L, NULL, 0);
return (c != EOF);
}
static int read_line (lua_State *L, FILE *f) {
luaL_Buffer b;
luaL_buffinit(L, &b);
for (;;) {
size_t l;
char *p = luaL_prepbuffer(&b);
if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
luaL_pushresult(&b); /* close buffer */
return (lua_objlen(L, -1) > 0); /* check whether read something */
}
l = strlen(p);
if (l == 0 || p[l-1] != '\n')
luaL_addsize(&b, l);
else {
luaL_addsize(&b, l - 1); /* do not include `eol' */
luaL_pushresult(&b); /* close buffer */
return 1; /* read at least an `eol' */
}
}
}
static int read_chars (lua_State *L, FILE *f, size_t n) {
size_t rlen; /* how much to read */
size_t nr; /* number of chars actually read */
luaL_Buffer b;
luaL_buffinit(L, &b);
rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
do {
char *p = luaL_prepbuffer(&b);
if (rlen > n) rlen = n; /* cannot read more than asked */
nr = fread(p, sizeof(char), rlen, f);
luaL_addsize(&b, nr);
n -= nr; /* still have to read `n' chars */
} while (n > 0 && nr == rlen); /* until end of count or eof */
luaL_pushresult(&b); /* close buffer */
return (n == 0 || lua_objlen(L, -1) > 0);
}
static int g_read (lua_State *L, FILE *f, int first) {
int nargs = lua_gettop(L) - 1;
int success;
int n;
clearerr(f);
if (nargs == 0) { /* no arguments? */
success = read_line(L, f);
n = first+1; /* to return 1 result */
}
else { /* ensure stack space for all results and for auxlib's buffer */
luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
success = 1;
for (n = first; nargs-- && success; n++) {
if (lua_type(L, n) == LUA_TNUMBER) {
size_t l = (size_t)lua_tointeger(L, n);
success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
}
else {
const char *p = lua_tostring(L, n);
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) {
case 'n': /* number */
success = read_number(L, f);
break;
case 'l': /* line */
success = read_line(L, f);
break;
case 'a': /* file */
read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
success = 1; /* always success */
break;
default:
return luaL_argerror(L, n, "invalid format");
}
}
}
}
if (ferror(f))
return pushresult(L, 0, NULL);
if (!success) {
lua_pop(L, 1); /* remove last result */
lua_pushnil(L); /* push nil instead */
}
return n - first;
}
static int io_read (lua_State *L) {
return g_read(L, getiofile(L, IO_INPUT), 1);
}
static int f_read (lua_State *L) {
return g_read(L, tofile(L), 2);
}
static int io_readline (lua_State *L) {
FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
int sucess;
if (f == NULL) /* file is already closed? */
luaL_error(L, "file is already closed");
sucess = read_line(L, f);
if (ferror(f))
return luaL_error(L, "%s", strerror(errno));
if (sucess) return 1;
else { /* EOF */
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
lua_settop(L, 0);
lua_pushvalue(L, lua_upvalueindex(1));
aux_close(L); /* close it */
}
return 0;
}
}
/* }====================================================== */
static int g_write (lua_State *L, FILE *f, int arg) {
int nargs = lua_gettop(L) - 1;
int status = 1;
size_t count = 0;
for (; nargs--; arg++) {
if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */
status = status &&
fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
}
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
count += l;
if (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);
}
}
return pushresult(L, status, NULL);
}
static int io_write (lua_State *L) {
return g_write(L, getiofile(L, IO_OUTPUT), 1);
}
static int f_write (lua_State *L) {
return g_write(L, tofile(L), 2);
}
static int f_seek (lua_State *L) {
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = {"set", "cur", "end", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, "cur", modenames);
long offset = luaL_optlong(L, 3, 0);
op = fseek(f, offset, mode[op]);
if (op)
return pushresult(L, 0, NULL); /* error */
else {
lua_pushinteger(L, ftell(f));
return 1;
}
}
static int f_setvbuf (lua_State *L) {
static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
static const char *const modenames[] = {"no", "full", "line", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, NULL, modenames);
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
int res = setvbuf(f, NULL, mode[op], sz);
return pushresult(L, res == 0, NULL);
}
static int io_flush (lua_State *L) {
return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
}
static int f_flush (lua_State *L) {
return pushresult(L, fflush(tofile(L)) == 0, NULL);
}
static const luaL_Reg iolib[] = {
{"close", io_close},
{"flush", io_flush},
{"input", io_input},
{"lines", io_lines},
{"open", io_open},
{"output", io_output},
{"read", io_read},
{"tmpfile", io_tmpfile},
{"type", io_type},
{"write", io_write},
{NULL, NULL}
};
static const luaL_Reg flib[] = {
{"close", io_close},
{"flush", f_flush},
{"lines", f_lines},
{"read", f_read},
{"seek", f_seek},
{"setvbuf", f_setvbuf},
{"write", f_write},
{"__gc", io_gc},
{"__tostring", io_tostring},
{NULL, NULL}
};
static void createmeta (lua_State *L) {
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_register(L, NULL, flib); /* file methods */
}
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
*newfile(L) = f;
if (k > 0) {
lua_pushvalue(L, -1);
lua_rawseti(L, LUA_ENVIRONINDEX, k);
}
lua_pushvalue(L, -2); /* copy environment */
lua_setfenv(L, -2); /* set it */
lua_setfield(L, -3, fname);
}
static void newfenv (lua_State *L, lua_CFunction cls) {
lua_createtable(L, 0, 1);
lua_pushcfunction(L, cls);
lua_setfield(L, -2, "__close");
}
LUALIB_API int luaopen_io (lua_State *L) {
createmeta(L);
/* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
newfenv(L, io_fclose);
lua_replace(L, LUA_ENVIRONINDEX);
/* open library */
luaL_register(L, LUA_IOLIBNAME, iolib);
/* create (and set) default files */
newfenv(L, io_noclose); /* close function for default files */
createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, stderr, 0, "stderr");
lua_pop(L, 1); /* pop environment for default files */
return 1;
}
......@@ -21,6 +21,9 @@ LUALIB_API int (luaopen_base) (lua_State *L);
#define LUA_TABLIBNAME "table"
LUALIB_API int (luaopen_table) (lua_State *L);
#define LUA_IOLIBNAME "io"
LUALIB_API int (luaopen_io) (lua_State *L);
#define LUA_STRLIBNAME "string"
LUALIB_API int (luaopen_string) (lua_State *L);
......
......@@ -2222,7 +2222,8 @@ static void Command_connect(void)
CONS_Printf(M_GetText(
"Connect <serveraddress> (port): connect to a server\n"
"Connect ANY: connect to the first lan server found\n"
"Connect SELF: connect to your own server.\n"));
"Connect SELF: connect to your own server.\n"
"Connect HOST <map> <gametype>: "));
return;
}
......@@ -2237,7 +2238,79 @@ static void Command_connect(void)
server = false;
if (!stricmp(COM_Argv(1), "self"))
// mirmiru RedEnchilada: host a game from connect
if (!stricmp(COM_Argv(1), "HOST"))
{
const char *mapname;
INT32 newmapnum;
INT32 j, newgametype = INT32_MAX;
if (COM_Argc() != 4)
{
CONS_Printf("Command must be of form \"Connect"
" HOST <MAPxx> <gametype>\".\n");
return;
}
// Get map number from name
mapname = COM_Argv(2);
// internal wad lump always: map command doesn't support external files as in doom legacy
if (W_CheckNumForName(mapname) == LUMPERROR)
{
CONS_Alert(CONS_ERROR, M_GetText("Internal game level '%s' not found\n"), mapname);
return;
}
if (strlen(mapname) != 5
|| (newmapnum = M_MapNumber(mapname[3], mapname[4])) == 0)
{
CONS_Alert(CONS_ERROR, M_GetText("Invalid level name %s\n"), mapname);
return;
}
// Get gametype
for (j = 0; gametype_cons_t[j].strvalue; j++)
if (!strcasecmp(gametype_cons_t[j].strvalue, COM_Argv(3)))
{
// Don't do any variable setting here. Wait until you get your
// map packet first to avoid sending the same info twice!
newgametype = gametype_cons_t[j].value;
break;
}
if (!gametype_cons_t[j].strvalue) // reached end of the list with no match
{
// assume they gave us a gametype number, which is okay too
for (j = 0; gametype_cons_t[j].strvalue != NULL; j++)
{
if (atoi(COM_Argv(3)) == gametype_cons_t[j].value)
{
newgametype = gametype_cons_t[j].value;
break;
}
}
}
#if 0 // gametype will never equal INT32_MAX
if (gametype == INT32_MAX)
{
CONS_Alert(CONS_ERROR, M_GetText("Invalid gametype %s\n"), COM_Argv(3));
return;
}
#endif
// Goodbye, we're off to host a server
CV_SetValue(&cv_nextmap, newmapnum);
CV_SetValue(&cv_newgametype, newgametype);
server = true;
M_StartServer(0);
return;
}
else if (!stricmp(COM_Argv(1), "self"))
{
servernode = 0;
server = true;
......
......@@ -302,7 +302,7 @@ static void D_Display(void)
if (rendermode != render_none)
{
// Fade to black first
if (gamestate != GS_LEVEL // fades to black on its own timing, always
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) // fades to black on its own timing, always
&& wipedefs[wipedefindex] != UINT8_MAX)
{
F_WipeStartScreen();
......@@ -318,6 +318,12 @@ static void D_Display(void)
// do buffered drawing
switch (gamestate)
{
case GS_TITLESCREEN:
if (!titlemapinaction) {
F_TitleScreenDrawer();
break;
}
// Intentional fall-through
case GS_LEVEL:
if (!gametic)
break;
......@@ -366,10 +372,6 @@ static void D_Display(void)
HU_Drawer();
break;
case GS_TITLESCREEN:
F_TitleScreenDrawer();
break;
case GS_WAITINGPLAYERS:
// The clientconnect drawer is independent...
case GS_DEDICATEDSERVER:
......@@ -379,9 +381,10 @@ static void D_Display(void)
// clean up border stuff
// see if the border needs to be initially drawn
if (gamestate == GS_LEVEL)
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))
{
// draw the view directly
if (!automapactive && !dedicated && cv_renderview.value)
{
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
......@@ -436,9 +439,13 @@ static void D_Display(void)
lastdraw = false;
}
ST_Drawer();
HU_Drawer();
if (gamestate == GS_LEVEL)
{
ST_Drawer();
HU_Drawer();
}
else
F_TitleScreenDrawer();
}
// change gamma if needed
......@@ -482,8 +489,19 @@ static void D_Display(void)
if (rendermode != render_none)
{
F_WipeEndScreen();
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
// miru: we can use the mapheaderinfo to change the forced wipe the instant the map loads
if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->postlevelwipe && mapheaderinfo[gamemap-1]->postlevelwipe < 100)
{
F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, mapheaderinfo[gamemap-1]->wipecolor);
F_WipeEndScreen();
F_RunWipe(mapheaderinfo[gamemap-1]->postlevelwipe, gamestate != GS_TIMEATTACK);
}
else
{
F_WipeEndScreen();
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
}
}
}
......@@ -1323,6 +1341,22 @@ void D_SRB2Main(void)
ultimatemode = true;
}
// rei/miru: bootmap (Idea: starts the game on a predefined map)
if (bootmap && !(M_CheckParm("-warp") && M_IsNextParm()))
{
pstartmap = bootmap;
if (pstartmap < 1 || pstartmap > NUMMAPS)
I_Error("Cannot warp to map %d (out of range)\n", pstartmap);
else
{
//if (!M_CheckParm("-server"))
//G_SetGameModified(true);
autostart = true;
}
}
//CONS_Printf("BOOT_MAP: %d\n", bootmap);
if (autostart || netgame || M_CheckParm("+connect") || M_CheckParm("-connect"))
{
gameaction = ga_nothing;
......
......@@ -3816,6 +3816,8 @@ static void Command_Displayplayer_f(void)
CONS_Printf(M_GetText("Displayplayer is %d\n"), displayplayer);
}
#include "dehacked.h"
#include "fastcmp.h"
static void Command_Tunes_f(void)
{
const char *tunearg;
......
......@@ -427,6 +427,9 @@ typedef struct player_s
INT32 awayviewtics;
angle_t awayviewaiming; // Used for cut-away view
// miru: let's add stuff to player struct!
angle_t viewrollangle; // Roll angle (software)
boolean spectator;
UINT8 bot;
......
......@@ -1321,6 +1321,20 @@ static void readlevelheader(MYFILE *f, INT32 num)
else
mapheaderinfo[num-1]->menuflags &= ~LF2_NOVISITNEEDED;
}
// miru: we can build custom map header words here
else if (fastcmp(word, "LEVELWIPE"))
{
mapheaderinfo[num-1]->levelwipe = (UINT8)i;
}
else if (fastcmp(word, "POSTLEVELWIPE"))
{
mapheaderinfo[num-1]->postlevelwipe = (UINT8)i;
}
else if (fastcmp(word, "WIPECOLOR"))
{
mapheaderinfo[num-1]->wipecolor = (UINT8)i;
}
else
deh_warning("Level header %d: unknown word '%s'", num, word);
}
......@@ -3004,6 +3018,25 @@ static void readmaincfg(MYFILE *f)
DEH_WriteUndoline(word, va("%d", looptitle), UNDO_NONE);
looptitle = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "TITLEMAP"))
{
// Support using the actual map name,
// i.e., Level AB, Level FZ, etc.
// Convert to map number
if (word2[0] >= 'A' && word2[0] <= 'Z')
value = M_MapNumber(word2[0], word2[1]);
else
value = get_number(word2);
DEH_WriteUndoline(word, va("%d", titlemap), UNDO_NONE);
titlemap = (INT16)value;
}
else if (fastcmp(word, "HIDETITLEPICS"))
{
DEH_WriteUndoline(word, va("%d", hidetitlepics), UNDO_NONE);
hidetitlepics = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "TITLESCROLLSPEED"))
{
DEH_WriteUndoline(word, va("%d", titlescrollspeed), UNDO_NONE);
......@@ -3083,6 +3116,22 @@ static void readmaincfg(MYFILE *f)
DEH_WriteUndoline(word, customversionstring, UNDO_NONE);
strlcpy(customversionstring, word2, sizeof (customversionstring));
}
else if (fastcmp(word, "BOOTMAP"))
{
// rei/miru: bootmap definition for maincfg
// Support using the actual map name,
// i.e., Level AB, Level FZ, etc.
// Convert to map number
if (word2[0] >= 'A' && word2[0] <= 'Z')
value = M_MapNumber(word2[0], word2[1]);
else
value = get_number(word2);
DEH_WriteUndoline(word, va("%d", bootmap), UNDO_NONE);
bootmap = (INT16)value;
}
else
deh_warning("Maincfg: unknown word '%s'", word);
}
......@@ -6642,7 +6691,7 @@ static const char *const MOBJFLAG_LIST[] = {
"SHOOTABLE",
"NOSECTOR",
"NOBLOCKMAP",
"AMBUSH",
"PAPERCOLLISION",
"PUSHABLE",
"BOSS",
"SPAWNCEILING",
......@@ -6700,6 +6749,7 @@ static const char *const MOBJFLAG2_LIST[] = {
"BOSSNOTRAP", // No Egg Trap after boss
"BOSSFLEE", // Boss is fleeing!
"BOSSDEAD", // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.)
"AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH
NULL
};
......@@ -6992,6 +7042,7 @@ struct {
// Frame settings
{"FF_FRAMEMASK",FF_FRAMEMASK},
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
{"FF_ANIMATE",FF_ANIMATE},
{"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_TRANSMASK",FF_TRANSMASK},
......
......@@ -149,10 +149,10 @@ extern FILE *logstream;
// most interface strings are ignored in development mode.
// we use comprevision and compbranch instead.
#else
#define VERSION 201 // Game version
#define SUBVERSION 17 // more precise version number
#define VERSIONSTRING "v2.1.17"
#define VERSIONSTRINGW L"v2.1.17"
#define VERSION 100 // Game version
#define SUBVERSION 0 // more precise version number
#define VERSIONSTRING "PlusC v1.0"
#define VERSIONSTRINGW L"PlusC v1.0"
// Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates!
#endif
......@@ -208,13 +208,13 @@ extern FILE *logstream;
// The Modification ID; must be obtained from Inuyasha ( http://mb.srb2.org/private.php?do=newpm&u=2604 ).
// DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server.
// "12" is the default mod ID for version 2.1
#define MODID 12
#define MODID 15
// The Modification Version, starting from 1. Do not follow your version string for this,
// it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 22
#define MODVERSION 1
// =========================================================================
......
......@@ -124,6 +124,12 @@ extern INT16 spstage_start;
extern INT16 sstage_start;
extern INT16 sstage_end;
extern INT16 bootmap; // rei/miru: bootmap for loading a map on startup (skips intro+title)
//extern INT16 returnTobootmap; // rei/miru: return to bootmap when attempting to go to the REAL title?
extern INT16 titlemap;
extern boolean hidetitlepics;
extern boolean looptitle;
extern boolean useNightsSS;
......@@ -245,6 +251,11 @@ typedef struct
UINT8 numGradedMares; ///< Internal. For grade support.
nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful.
// miru: to use custom mapheaderinfo options, we need to add them to the struct first
UINT8 levelwipe;
UINT8 postlevelwipe;
UINT8 wipecolor;
// Lua stuff.
// (This is not ifdeffed so the map header structure can stay identical, just in case.)
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
......
......@@ -259,7 +259,10 @@ typedef enum
postimg_water,
postimg_motion,
postimg_flip,
postimg_heat
postimg_heat,
// miru: more postimg definitions
postimg_roll
} postimg_t;
typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)
......
......@@ -31,11 +31,14 @@
#include "m_random.h"
#include "y_inter.h"
#include "m_cond.h"
#include "p_local.h"
#include "p_setup.h"
// Stage of animation:
// 0 = text, 1 = art screen
static INT32 finalecount;
INT32 titlescrollspeed = 80;
boolean titlemapinaction = false;
static INT32 timetonext; // Delay between screen changes
static INT32 continuetime; // Short delay when continuing
......@@ -999,7 +1002,7 @@ static const char *credits[] = {
"",
"\1Sprite Artists",
"Odi \"Iceman404\" Atunzu",
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Arajo -- sorry for our limited font! D:
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
"Jim \"MotorRoach\" DeMello",
"Desmond \"Blade\" DesJardins",
"Sherman \"CoatRack\" DesJardins",
......@@ -1421,13 +1424,32 @@ void F_StartTitleScreen(void)
finalecount = 0;
else
wipegamestate = GS_TITLESCREEN;
if (titlemap)
{
titlemapinaction = true;
gamemap = titlemap;
if (!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1);
G_DoLoadLevel(true);
players[displayplayer].playerstate = PST_DEAD; // Don't spawn the player in dummy (I'm still a filthy cheater)
camera.subsector = NULL; // toast is filthy too
//CON_ClearHUD();
}
else
{
titlemapinaction = false;
gamemap = 1; // g_game.c
CON_ClearHUD();
}
G_SetGamestate(GS_TITLESCREEN);
CON_ClearHUD();
// IWAD dependent stuff.
S_ChangeMusicInternal("titles", looptitle);
animtimer = 0;
demoDelayLeft = demoDelayTime;
......@@ -1457,12 +1479,17 @@ void F_TitleScreenDrawer(void)
return; // We likely came here from retrying. Don't do a damn thing.
// Draw that sky!
F_SkyScroll(titlescrollspeed);
if (!titlemapinaction)
F_SkyScroll(titlescrollspeed);
// Don't draw outside of the title screewn, or if the patch isn't there.
if (!ttwing || (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS))
return;
// rei|miru: use title pics?
if (hidetitlepics)
return;
V_DrawScaledPatch(30, 14, 0, ttwing);
if (finalecount < 57)
......@@ -1511,6 +1538,13 @@ void F_TitleScreenTicker(boolean run)
if (gameaction != ga_nothing || gamestate != GS_TITLESCREEN)
return;
// Do a lil' camera spin if a title map is loaded.
if (titlemapinaction) {
camera.x = camera.y = camera.height = camera.aiming = 0;
camera.z = 128*FRACUNIT;
camera.angle += titlescrollspeed;
}
// no demos to play? or, are they disabled?
if (!cv_rollingdemos.value || !numDemos)
return;
......
......@@ -61,6 +61,7 @@ void F_ContinueTicker(void);
void F_ContinueDrawer(void);
extern INT32 titlescrollspeed;
extern boolean titlemapinaction;
//
// WIPE
......
......@@ -119,6 +119,12 @@ INT16 spstage_start;
INT16 sstage_start;
INT16 sstage_end;
INT16 bootmap; // rei/miru: bootmap for loading a map on startup (skips intro+title)
//INT16 returnTobootmap; // rei/miru: return to bootmap when attempting to go to the REAL title?
INT16 titlemap = 0;
boolean hidetitlepics = false;
boolean looptitle = false;
boolean useNightsSS = false;
......@@ -1984,6 +1990,7 @@ void G_Ticker(boolean run)
break;
case GS_TITLESCREEN:
if (titlemapinaction) P_Ticker(run); // then intentionally fall through
case GS_WAITINGPLAYERS:
F_TitleScreenTicker(run);
break;
......@@ -5674,3 +5681,48 @@ INT32 G_TicsToMilliseconds(tic_t tics)
return (INT32)((tics%TICRATE) * (1000.00f/TICRATE));
}
//miru: change the displayed player
// player - player to forward the function to
// displayNumber - the player number (node) to view
// setAllDisplays - set all displays to the player number/node specified
void G_SetDisplayPlayer(player_t *player, INT32 displayNumber, boolean setAllDisplays)
{
//TODO: fix black flashes when touching controls (this has to do with
//((cmd->forwardmove || cmd->sidemove || cmd->buttons) && displayplayer != consoleplayer) )
//TODO: proper implementation for using player node instead of -1 (unsure how)
if (gamestate == GS_LEVEL)
{
// no, not for non-sp
if (!netgame)
displayplayer = consoleplayer;
else
{
// the player has to exist or you just get a bleeding display
if (playeringame[displayNumber] || (players[displayplayer].spectator && player == &players[displayplayer]))
{
// switch the display number locally
if (P_IsLocalPlayer(player) && displayplayer == consoleplayer)
{
displayplayer = displayNumber;
}
// or force all
else if (setAllDisplays == true)
{
displayplayer = displayNumber;
}
// tell who's the view
//CONS_Printf(M_GetText("Viewpoint: %s\n"), player_names[displayplayer]);
}
// Setting as -1 resets your view to normal
else if (displayNumber == -1 && P_IsLocalPlayer(player)
&& displayplayer != consoleplayer)
displayplayer = consoleplayer;
else
{
// or do...nothing
//CONS_Printf("Player doesn't exist (or viewing self).\n");
}
}
}
}
......@@ -216,4 +216,6 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics);
// Don't split up TOL handling
INT16 G_TOLFlag(INT32 pgametype);
void G_SetDisplayPlayer(player_t *player, INT32 displayNumber, boolean setAllDisplays);
#endif
......@@ -762,8 +762,10 @@ void HWR_WallLighting(FOutVector *wlVerts)
#ifdef DL_HIGH_QUALITY
Surf.FlatColor.s.alpha = (UINT8)((1-dist_p2d/DL_SQRRADIUS(j))*Surf.FlatColor.s.alpha);
#endif
if ((!dynlights->mo[j]) || (dynlights->mo[j]->thinker.function.acp1 != (actionf_p1)P_MobjThinker))
continue;
if (!dynlights->mo[j]->state)
return;
continue;
// next state is null so fade out with alpha
if (dynlights->mo[j]->state->nextstate == S_NULL)
Surf.FlatColor.s.alpha = (UINT8)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha);
......@@ -825,8 +827,10 @@ void HWR_PlaneLighting(FOutVector *clVerts, int nrClipVerts)
#ifdef DL_HIGH_QUALITY
Surf.FlatColor.s.alpha = (unsigned char)((1 - dist_p2d/DL_SQRRADIUS(j))*Surf.FlatColor.s.alpha);
#endif
if ((!dynlights->mo[j]) || (dynlights->mo[j]->thinker.function.acp1 != (actionf_p1)P_MobjThinker))
continue;
if (!dynlights->mo[j]->state)
return;
continue;
// next state is null so fade out with alpha
if ((dynlights->mo[j]->state->nextstate == S_NULL))
Surf.FlatColor.s.alpha = (unsigned char)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha);
......@@ -1232,12 +1236,37 @@ static void HWR_CheckSubsector(size_t num, fixed_t *bbox)
}
//Hurdler: The goal of this function is to walk through all the bsp starting
// on the top.
// We need to do that to know all the lights in the map and all the walls
static void HWR_ComputeLightMapsInBSPNode(int bspnum, fixed_t *bbox)
{
if (bspnum & NF_SUBSECTOR) // Found a subsector?
{
if (bspnum == -1)
HWR_CheckSubsector(0, bbox); // probably unecessary: see boris' comment in hw_bsp
else
HWR_CheckSubsector(bspnum&(~NF_SUBSECTOR), bbox);
return;
}
HWR_ComputeLightMapsInBSPNode(nodes[bspnum].children[0], nodes[bspnum].bbox[0]);
HWR_ComputeLightMapsInBSPNode(nodes[bspnum].children[1], nodes[bspnum].bbox[1]);
}
#endif
// --------------------------------------------------------------------------
// Hurdler: this adds lights by mobj.
// --------------------------------------------------------------------------
static void HWR_AddMobjLights(mobj_t *thing)
{
if (t_lspr[thing->sprite]->type & CORONA_SPR)
if (!cv_drawdist.value || P_AproxDistance(thing->x-viewx, thing->y-viewy) < cv_drawdist.value*FRACUNIT)
if (!(thing->flags2 & MF2_DEBRIS) && (thing->sprite != SPR_PLAY ||
(thing->player && thing->player->powers[pw_super])))
if ((t_lspr[thing->sprite]->type&DYNLIGHT_SPR)
&& ((t_lspr[thing->sprite]->type != LIGHT_SPR) || cv_grstaticlighting.value)
&& (dynlights->nb < DL_MAX_LIGHT)
&& thing->state)
{
LIGHT_POS(dynlights->nb).x = FIXED_TO_FLOAT(thing->x);
LIGHT_POS(dynlights->nb).y = FIXED_TO_FLOAT(thing->z) + t_lspr[thing->sprite]->light_yoffset;
......@@ -1245,30 +1274,15 @@ static void HWR_AddMobjLights(mobj_t *thing)
dynlights->p_lspr[dynlights->nb] = t_lspr[thing->sprite];
P_SetTarget(&dynlights->mo[dynlights->nb], thing);
dynlights->nb++;
if (dynlights->nb > DL_MAX_LIGHT)
dynlights->nb = DL_MAX_LIGHT;
}
}
//Hurdler: The goal of this function is to walk through all the bsp starting
// on the top.
// We need to do that to know all the lights in the map and all the walls
static void HWR_ComputeLightMapsInBSPNode(int bspnum, fixed_t *bbox)
{
if (bspnum & NF_SUBSECTOR) // Found a subsector?
{
if (bspnum == -1)
HWR_CheckSubsector(0, bbox); // probably unecessary: see boris' comment in hw_bsp
else
HWR_CheckSubsector(bspnum&(~NF_SUBSECTOR), bbox);
return;
}
HWR_ComputeLightMapsInBSPNode(nodes[bspnum].children[0], nodes[bspnum].bbox[0]);
HWR_ComputeLightMapsInBSPNode(nodes[bspnum].children[1], nodes[bspnum].bbox[1]);
}
static void HWR_SearchLightsInMobjs(void)
void HWR_SearchLightsInMobjs(void)
{
thinker_t * th;
//mobj_t * mobj;
......@@ -1279,9 +1293,15 @@ static void HWR_SearchLightsInMobjs(void)
// a mobj ?
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
HWR_AddMobjLights((mobj_t *)th);
if (dynlights->nb == DL_MAX_LIGHT)
{
CONS_Printf("light limit exceeded\n");
return;
}
}
}
#endif
//
// HWR_CreateStaticLightmaps()
......
......@@ -36,6 +36,8 @@ void HWR_WallLighting(FOutVector *wlVerts);
void HWR_ResetLights(void);
void HWR_SetLights(int viewnumber);
void HWR_SearchLightsInMobjs(void);
#ifdef NEWCORONAS
void HWR_DrawCoronas(void);
#else
......
......@@ -4246,7 +4246,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
#ifdef ALAM_LIGHTING
#if 0 //#ifdef ALAM_LIGHTING
if (!(spr->mobj->flags2 & MF2_DEBRIS) && (spr->mobj->sprite != SPR_PLAY ||
(spr->mobj->player && spr->mobj->player->powers[pw_super])))
HWR_DL_AddLight(spr, gpatch);
......@@ -5107,6 +5107,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
rot = thing->frame&FF_FRAMEMASK;
thing->state->sprite = thing->sprite;
thing->state->frame = thing->frame;
sprdef = &sprites[thing->sprite]; //Yellow: sprdef now updates rotations to fix the crash
}
sprframe = &sprdef->spriteframes[rot];
......@@ -5116,22 +5117,29 @@ static void HWR_ProjectSprite(mobj_t *thing)
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
#endif
if (sprframe->rotate)
{
// choose a different rotation based on player view
ang = R_PointToAngle(thing->x, thing->y); // uses viewx,viewy
rot = (ang-thing->angle+ANGLE_202h)>>29;
//Fab: lumpid is the index for spritewidth,spriteoffset... tables
lumpoff = sprframe->lumpid[rot];
flip = sprframe->flip & (1<<rot);
}
else
if (sprframe->rotate == SRF_SINGLE)
{
// use single rotation for all views
rot = 0; //Fab: for vis->patch below
lumpoff = sprframe->lumpid[0]; //Fab: see note above
flip = sprframe->flip; // Will only be 0x00 or 0xFF
}
else
{
// choose a different rotation based on player view
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right
rot = 6; // F7 slot
else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left
rot = 2; // F3 slot
else // Normal behaviour
rot = (ang+ANGLE_202h)>>29;
//Fab: lumpid is the index for spritewidth,spriteoffset... tables
lumpoff = sprframe->lumpid[rot];
flip = sprframe->flip & (1<<rot);
}
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale);
......@@ -5599,6 +5607,12 @@ if (0)
validcount++;
#ifdef ALAM_LIGHTING
//14/11/99: Hurdler: moved here because it doesn't work with
// subsector, see other comments;
HWR_ResetLights();
HWR_SearchLightsInMobjs();
#endif
HWR_RenderBSPNode((INT32)numnodes-1);
// Make a viewangle int so we can render things based on mouselook
......@@ -5634,7 +5648,7 @@ if (0)
#ifdef ALAM_LIGHTING
//14/11/99: Hurdler: moved here because it doesn't work with
// subsector, see other comments;
HWR_ResetLights();
//HWR_ResetLights();
#endif
// Draw MD2 and sprites
......@@ -5829,6 +5843,13 @@ if (0)
validcount++;
#ifdef ALAM_LIGHTING
//14/11/99: Hurdler: moved here because it doesn't work with
// subsector, see other comments;
HWR_ResetLights();
HWR_SearchLightsInMobjs();
#endif
HWR_RenderBSPNode((INT32)numnodes-1);
// Make a viewangle int so we can render things based on mouselook
......@@ -5861,12 +5882,6 @@ if (0)
// Check for new console commands.
NetUpdate();
#ifdef ALAM_LIGHTING
//14/11/99: Hurdler: moved here because it doesn't work with
// subsector, see other comments;
HWR_ResetLights();
#endif
// Draw MD2 and sprites
#ifdef SORTING
HWR_SortVisSprites();
......