mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-24 10:40:46 +00:00
A bunch of mutually unrelated updates.
First, there's a new script for the generation of highpalookup images. Python 2.6, NumPy and PIL are required. Next, the map corruption checker has been ported to C. This is so that Mapster32 will be able to take decisions more cleverly based on the corruptness of the map. It also catches a few more issues like inconsistent nextwall/nextsector tags now. Finally, link the executables with --large-address-aware on Windows. This gives a gig more private virtual memory on XP when booting with /3GB. YMMV, but I can play IW2 with Polymer now. git-svn-id: https://svn.eduke32.com/eduke32@1751 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
79a52e1bc5
commit
e745f3abf9
10 changed files with 459 additions and 64 deletions
|
@ -167,11 +167,14 @@ OURCFLAGS+= $(BUILDCFLAGS)
|
|||
OURCXXFLAGS+= $(BUILDCFLAGS)
|
||||
|
||||
MISCLINKOPTS=
|
||||
ifeq($(PLATFORM),WINDOWS)
|
||||
MISCLINKOPTS+= -Wl,--large-address-aware
|
||||
endif
|
||||
ifneq (0,$(KRANDDEBUG))
|
||||
MISCLINKOPTS=-Wl,-Map=$@.memmap
|
||||
MISCLINKOPTS+=-Wl,-Map=$@.memmap
|
||||
endif
|
||||
ifneq (0,$(PROFILER))
|
||||
MISCLINKOPTS=-pg
|
||||
MISCLINKOPTS+=-pg
|
||||
endif
|
||||
|
||||
ifeq ($(PRETTY_OUTPUT),1)
|
||||
|
|
|
@ -106,6 +106,9 @@ extern void ExtEditWallData(int16_t wallnum);
|
|||
extern void ExtEditSpriteData(int16_t spritenum);
|
||||
extern const char *ExtGetSectorType(int32_t lotag);
|
||||
|
||||
extern int32_t autocorruptcheck;
|
||||
extern int32_t CheckMapCorruption(int32_t printfromlev);
|
||||
|
||||
extern void showsectordata(int16_t sectnum, int16_t small);
|
||||
extern void showwalldata(int16_t wallnum, int16_t small);
|
||||
extern void showspritedata(int16_t spritenum, int16_t small);
|
||||
|
|
|
@ -152,7 +152,7 @@ void OSD_ShowDisplay(int32_t onf);
|
|||
void OSD_Draw(void);
|
||||
|
||||
// just like printf
|
||||
void OSD_Printf(const char *fmt, ...);
|
||||
void OSD_Printf(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));
|
||||
|
||||
// executes buffered commands
|
||||
void OSD_DispatchQueued(void);
|
||||
|
|
|
@ -6244,6 +6244,7 @@ static int32_t menuselect(void)
|
|||
if (keystatus[0xc8]) ch = 72; // up arr
|
||||
if (keystatus[0xd0]) ch = 80; // down arr
|
||||
}
|
||||
|
||||
if (ch == 'f' || ch == 'F')
|
||||
{
|
||||
currentlist = 0;
|
||||
|
@ -6323,9 +6324,11 @@ static int32_t menuselect(void)
|
|||
enddrawing();
|
||||
showframe(1);
|
||||
}
|
||||
|
||||
if (ch == 13 && !findfileshigh) ch = 0;
|
||||
}
|
||||
while ((ch != 13) && (ch != 27));
|
||||
|
||||
if (ch == 13)
|
||||
{
|
||||
Bstrcat(selectedboardfilename, findfileshigh->name);
|
||||
|
@ -6333,7 +6336,9 @@ static int32_t menuselect(void)
|
|||
|
||||
return(0);
|
||||
}
|
||||
|
||||
pathsearchmode = bakpathsearchmode;
|
||||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
@ -7130,6 +7135,8 @@ void AutoAlignWalls(int32_t nWall0, int32_t ply)
|
|||
}
|
||||
}
|
||||
|
||||
#define PLAYTEST_MAPNAME "autosave_playtest.map"
|
||||
|
||||
void test_map(int32_t mode)
|
||||
{
|
||||
if (!mode)
|
||||
|
@ -7139,7 +7146,7 @@ void test_map(int32_t mode)
|
|||
|
||||
if ((!mode && cursectnum >= 0) || (mode && startsectnum >= 0))
|
||||
{
|
||||
char *param = " -map autosave.map -noinstancechecking";
|
||||
char *param = " -map " PLAYTEST_MAPNAME " -noinstancechecking";
|
||||
char *fullparam;
|
||||
char current_cwd[BMAX_PATH];
|
||||
int32_t slen = 0;
|
||||
|
@ -7194,11 +7201,11 @@ void test_map(int32_t mode)
|
|||
fixspritesectors(); //Do this before saving!
|
||||
ExtPreSaveMap();
|
||||
if (mode)
|
||||
saveboard("autosave.map",&startposx,&startposy,&startposz,&startang,&startsectnum);
|
||||
saveboard(PLAYTEST_MAPNAME,&startposx,&startposy,&startposz,&startang,&startsectnum);
|
||||
else
|
||||
saveboard("autosave.map",&pos.x,&pos.y,&pos.z,&ang,&cursectnum);
|
||||
saveboard(PLAYTEST_MAPNAME,&pos.x,&pos.y,&pos.z,&ang,&cursectnum);
|
||||
|
||||
message("Board saved to AUTOSAVE.MAP. Starting the game...");
|
||||
message("Board saved to " PLAYTEST_MAPNAME ". Starting the game...");
|
||||
OSD_Printf("...as `%s'\n", fullparam);
|
||||
|
||||
showframe(1);
|
||||
|
|
|
@ -220,7 +220,7 @@ int32_t loadsetup(const char *fn)
|
|||
|
||||
if (readconfig(fp, "mousenavigationaccel", val, VL) > 0) pk_uedaccel = Batoi(val);
|
||||
|
||||
if (readconfig(fp, "quickmapcycling", val, VL) > 0) quickmapcycling = Batoi(val);
|
||||
if (readconfig(fp, "quickmapcycling", val, VL) > 0) quickmapcycling = !!Batoi(val);
|
||||
|
||||
if (readconfig(fp, "sideview_reversehorizrot", val, VL) > 0) sideview_reversehrot = !!Batoi(val);
|
||||
if (readconfig(fp, "revertCTRL", val, VL) > 0) revertCTRL = !!Batoi(val);
|
||||
|
@ -231,8 +231,9 @@ int32_t loadsetup(const char *fn)
|
|||
|
||||
if (readconfig(fp, "turndecel", val, VL) > 0) pk_turndecel = Batoi(val);
|
||||
|
||||
if (readconfig(fp, "autosave", val, VL) > 0) autosave = Batoi(val)*60;
|
||||
if (readconfig(fp, "autosavesec", val, VL) > 0) autosave = Batoi(val);
|
||||
// if (readconfig(fp, "autosave", val, VL) > 0) autosave = Batoi(val)*60;
|
||||
if (readconfig(fp, "autosavesec", val, VL) > 0) autosave = max(0, Batoi(val));
|
||||
if (readconfig(fp, "autocorruptchecksec", val, VL) > 0) autocorruptcheck = max(0, Batoi(val));
|
||||
|
||||
if (readconfig(fp, "showheightindicators", val, VL) > 0)
|
||||
showheightindicators = min(max(Batoi(val),0),2);
|
||||
|
@ -420,6 +421,9 @@ int32_t writesetup(const char *fn)
|
|||
"; Autosave map interval (seconds)\n"
|
||||
"autosavesec = %d\n"
|
||||
"\n"
|
||||
"; Auto corruption check interval (seconds)\n"
|
||||
"autocorruptchecksec = %d\n"
|
||||
"\n"
|
||||
"; Height indicators (0:none, 1:only 2-sided&different, 2:all)\n"
|
||||
"showheightindicators = %d\n"
|
||||
"\n"
|
||||
|
@ -510,7 +514,7 @@ int32_t writesetup(const char *fn)
|
|||
#endif
|
||||
option[3], msens, unrealedlook, pk_uedaccel, quickmapcycling,
|
||||
sideview_reversehrot,
|
||||
revertCTRL,scrollamount,pk_turnaccel,pk_turndecel,autosave,
|
||||
revertCTRL,scrollamount,pk_turnaccel,pk_turndecel,autosave,autocorruptcheck,
|
||||
showheightindicators,showambiencesounds,graphicsmode,
|
||||
MixRate,AmbienceToggle,ParentalLock, !!m32_osd_tryscript,
|
||||
#if 1
|
||||
|
|
|
@ -1432,12 +1432,10 @@ static int32_t defsparser(scriptfile *script)
|
|||
case T_HIGHPALOOKUP:
|
||||
{
|
||||
char *highpaltokptr = script->ltextptr;
|
||||
int32_t pal=-1, oldpathsearchmode, fd, datasize, dataread;
|
||||
int32_t pal=-1, oldpathsearchmode, fd;
|
||||
char *fn = NULL, *tfn = NULL;
|
||||
char *highpalend;
|
||||
char *highpaldata;
|
||||
static const uint8_t pngheaderref[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
|
||||
uint8_t pngheader[8];
|
||||
|
||||
static const tokenlist highpaltokens[] =
|
||||
{
|
||||
|
@ -1488,35 +1486,13 @@ static int32_t defsparser(scriptfile *script)
|
|||
else Bfree(tfn);
|
||||
pathsearchmode = oldpathsearchmode;
|
||||
|
||||
// load the highpalookup and send it to polymer
|
||||
datasize = PR_HIGHPALOOKUP_DATA_SIZE;
|
||||
|
||||
fd = kopen4load(fn, 0);
|
||||
|
||||
if (kread(fd, pngheader, sizeof(pngheader))!=sizeof(pngheader))
|
||||
break;
|
||||
// load the highpalookup and send it to polymer
|
||||
highpaldata = Bmalloc(PR_HIGHPALOOKUP_DATA_SIZE);
|
||||
|
||||
highpaldata = Bmalloc(datasize);
|
||||
|
||||
if (Bmemcmp(pngheader, pngheaderref, sizeof(pngheader))) // blindly assume TGA
|
||||
{
|
||||
// skip the TGA header
|
||||
klseek(fd, 18, SEEK_SET);
|
||||
|
||||
dataread = 0;
|
||||
|
||||
while (1) {
|
||||
dataread += kread(fd, highpaldata + dataread, datasize - dataread);
|
||||
if (dataread == datasize)
|
||||
break;
|
||||
}
|
||||
|
||||
// ignore whatever image editors might have put after the interesting stuff
|
||||
kclose(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *filebuf, *tmpbuf;
|
||||
char *filebuf;
|
||||
int32_t xsiz, ysiz, filesize, i;
|
||||
|
||||
filesize = kfilelength(fd);
|
||||
|
@ -1531,10 +1507,10 @@ static int32_t defsparser(scriptfile *script)
|
|||
kclose(fd);
|
||||
kpgetdim(filebuf, filesize, &xsiz, &ysiz);
|
||||
|
||||
if (xsiz*ysiz != PR_HIGHPALOOKUP_DATA_SIZE/4)
|
||||
if (xsiz != PR_HIGHPALOOKUP_DIM*PR_HIGHPALOOKUP_DIM || ysiz != PR_HIGHPALOOKUP_DIM)
|
||||
{
|
||||
initprintf("Error: product of image dimensions of '%s' must equal %d.\n",
|
||||
fn, PR_HIGHPALOOKUP_DATA_SIZE/4);
|
||||
initprintf("Error: image dimensions of '%s' must be %dx%d.\n",
|
||||
fn, PR_HIGHPALOOKUP_DIM*PR_HIGHPALOOKUP_DIM, PR_HIGHPALOOKUP_DIM);
|
||||
Bfree(filebuf); Bfree(highpaldata);
|
||||
break;
|
||||
}
|
||||
|
@ -1542,15 +1518,7 @@ static int32_t defsparser(scriptfile *script)
|
|||
i = kprender(filebuf, filesize, (intptr_t)highpaldata, xsiz*sizeof(coltype), xsiz, ysiz, 0, 0);
|
||||
Bfree(filebuf);
|
||||
if (i)
|
||||
{ Bfree(highpaldata); initprintf("Error: failed rendering '%s': code %d.\n", fn, i); break; }
|
||||
|
||||
#if 0
|
||||
for (i=0; i<PR_HIGHPALOOKUP_DATA_SIZE/4; i++)
|
||||
{
|
||||
char *col = &highpaldata[i*4];
|
||||
swapchar(&col[0], &col[2]);
|
||||
}
|
||||
#endif
|
||||
{ Bfree(highpaldata); initprintf("Error: failed rendering '%s'.\n", fn); break; }
|
||||
}
|
||||
|
||||
polymer_definehighpalookup(pal, highpaldata);
|
||||
|
|
|
@ -1014,7 +1014,9 @@ defstate jumptosec // (tmp)
|
|||
ends
|
||||
|
||||
// Map corruption checker
|
||||
// now included in Mapster32 natively
|
||||
|
||||
/*
|
||||
defstate corruptchk
|
||||
var ewall
|
||||
var endwall
|
||||
|
@ -1114,7 +1116,7 @@ defstate corruptchk
|
|||
ife ok 0
|
||||
print "--"
|
||||
ends
|
||||
|
||||
*/
|
||||
|
||||
gamevar d2d_lastcheck 0 0
|
||||
onevent EVENT_DRAW2DSCREEN
|
||||
|
@ -1134,7 +1136,7 @@ onevent EVENT_DRAW2DSCREEN
|
|||
ifl d2d_lastcheck tmp
|
||||
{
|
||||
set d2d_lastcheck totalclock
|
||||
state corruptchk
|
||||
// state corruptchk
|
||||
}
|
||||
|
||||
ifn showpal 0
|
||||
|
|
|
@ -99,6 +99,9 @@ int32_t scripthistend = 0;
|
|||
|
||||
int32_t showambiencesounds=2;
|
||||
|
||||
int32_t autocorruptcheck = 0;
|
||||
static int32_t corruptchecktimer;
|
||||
|
||||
static uint32_t templenrepquot;
|
||||
static void fixxrepeat(int16_t i, uint32_t lenrepquot)
|
||||
{
|
||||
|
@ -2682,14 +2685,14 @@ static int32_t DrawTiles(int32_t iTopLeft, int32_t iSelected, int32_t nXTiles, i
|
|||
} while (0)
|
||||
|
||||
#define TMPERRMSG_PRINT(Msg, ...) do { \
|
||||
Bsprintf(tilesel_errmsg, Msg, __VA_ARGS__); \
|
||||
Bsprintf(tilesel_errmsg, Msg, ## __VA_ARGS__); \
|
||||
TMPERRMSG_SHOW(1); \
|
||||
tilesel_showerr = 1; \
|
||||
} while (0)
|
||||
|
||||
#define TMPERRMSG_RETURN(Msg, ...) do \
|
||||
{ \
|
||||
TMPERRMSG_PRINT(Msg, __VA_ARGS__); \
|
||||
TMPERRMSG_PRINT(Msg, ## __VA_ARGS__); \
|
||||
return 1; \
|
||||
} while (0)
|
||||
|
||||
|
@ -3158,7 +3161,7 @@ static int32_t m32gettile(int32_t idInitialTile)
|
|||
if (noTilesMarked)
|
||||
{
|
||||
noTilesMarked = 0;
|
||||
TMPERRMSG_PRINT("%s", "Beginning marking tiles. To group, press Ctrl-G. To reset, press LCtrl-RShift-SPACE.");
|
||||
TMPERRMSG_PRINT("Beginning marking tiles. To group, press Ctrl-G. To reset, press LCtrl-RShift-SPACE.");
|
||||
}
|
||||
|
||||
if (mark_lastk>=0 && eitherCTRL)
|
||||
|
@ -3239,7 +3242,7 @@ static int32_t OnSaveTileGroup()
|
|||
n += !!(tilemarked[i>>3]&(1<<(i&7)));
|
||||
|
||||
if (n==0)
|
||||
TMPERRMSG_RETURN("%s", "Cannot save tile group: no tiles marked.");
|
||||
TMPERRMSG_RETURN("Cannot save tile group: no tiles marked.");
|
||||
else if (n > MAX_TILE_GROUP_ENTRIES)
|
||||
TMPERRMSG_RETURN("Cannot save tile group: too many tiles in group. Have %d, max is %d.",
|
||||
n, MAX_TILE_GROUP_ENTRIES);
|
||||
|
@ -3250,7 +3253,7 @@ static int32_t OnSaveTileGroup()
|
|||
|
||||
hotkey = Btoupper(cp[0]);
|
||||
if (!isalpha(hotkey))
|
||||
TMPERRMSG_RETURN("%s", "Hotkey must be alphabetic.");
|
||||
TMPERRMSG_RETURN("Hotkey must be alphabetic.");
|
||||
|
||||
for (i=0; i<tile_groups; i++)
|
||||
if (s_TileGroups[i].key1==hotkey || s_TileGroups[i].key2==Btolower(hotkey))
|
||||
|
@ -3262,7 +3265,7 @@ static int32_t OnSaveTileGroup()
|
|||
|
||||
for (i=0; name[i]; i++)
|
||||
if (!(isalnum(name[i]) || name[i]==' ' || name[i]==','))
|
||||
TMPERRMSG_RETURN("%s", "Name may only consist of alphabetic, numeric and space characters.");
|
||||
TMPERRMSG_RETURN("Name may only consist of alphabetic, numeric and space characters.");
|
||||
|
||||
{
|
||||
int32_t lasti=-1, col=0, j, k, opathsearchmode=pathsearchmode;
|
||||
|
@ -3283,7 +3286,7 @@ static int32_t OnSaveTileGroup()
|
|||
Bfprintf(fp, TTAB "hotkey \"%c\"\n\n", hotkey);
|
||||
|
||||
if (!(s_TileGroups[tile_groups].pIds = Bmalloc(n * sizeof(s_TileGroups[tile_groups].pIds[0]))))
|
||||
TMPERRMSG_RETURN("%s", "Out of memory.");
|
||||
TMPERRMSG_RETURN("Out of memory.");
|
||||
|
||||
j = 0;
|
||||
// tileranges for consecutive runs of 3 or more tiles
|
||||
|
@ -3359,7 +3362,7 @@ static int32_t OnSaveTileGroup()
|
|||
if (!(s_TileGroups[tile_groups].szText = Bstrdup(name)))
|
||||
{
|
||||
Bfree(s_TileGroups[tile_groups].pIds);
|
||||
TMPERRMSG_RETURN("%s", "Out of memory.");
|
||||
TMPERRMSG_RETURN("Out of memory.");
|
||||
}
|
||||
|
||||
s_TileGroups[tile_groups].nIds = n;
|
||||
|
@ -3368,7 +3371,7 @@ static int32_t OnSaveTileGroup()
|
|||
s_TileGroups[tile_groups].color1 = s_TileGroups[tile_groups].color2 = 0;
|
||||
tile_groups++;
|
||||
|
||||
TMPERRMSG_PRINT("%s", "Wrote and installed new tile group.");
|
||||
TMPERRMSG_PRINT("Wrote and installed new tile group.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -7795,6 +7798,25 @@ static int32_t osdcmd_vars_pk(const osdfuncparm_t *parm)
|
|||
else
|
||||
return OSDCMD_SHOWHELP;
|
||||
}
|
||||
else if (!Bstrcasecmp(parm->name, "autocorruptcheck"))
|
||||
{
|
||||
if (parm->numparms == 1)
|
||||
{
|
||||
autocorruptcheck = clamp(atoi(parm->parms[0]), 0, 3600);
|
||||
corruptchecktimer = 0; // force checking now
|
||||
}
|
||||
|
||||
if (parm->numparms <= 1)
|
||||
{
|
||||
if (autocorruptcheck)
|
||||
OSD_Printf("auto corruption check: %d seconds\n", autocorruptcheck);
|
||||
else
|
||||
OSD_Printf("auto corruption check: off\n");
|
||||
}
|
||||
else
|
||||
return OSDCMD_SHOWHELP;
|
||||
}
|
||||
|
||||
return OSDCMD_OK;
|
||||
}
|
||||
|
||||
|
@ -8072,6 +8094,7 @@ static int32_t registerosdcommands(void)
|
|||
OSD_RegisterFunction("testplay_addparam", "testplay_addparam \"string\": sets additional parameters for test playing", osdcmd_testplay_addparam);
|
||||
OSD_RegisterFunction("show_heightindicators", "show_heightindicators <0, 1 or 2>: sets display of height indicators in 2D mode", osdcmd_vars_pk);
|
||||
OSD_RegisterFunction("show_ambiencesounds", "show_ambiencesounds <0, 1 or 2>: sets display of MUSICANDSFX circles in 2D mode", osdcmd_vars_pk);
|
||||
OSD_RegisterFunction("autocorruptcheck", "autocorruptcheck <seconds>: sets auto corruption check interval", osdcmd_vars_pk);
|
||||
#ifdef POLYMOST
|
||||
OSD_RegisterFunction("tint", "tint <pal> <r> <g> <b> <flags>: queries or sets hightile tinting", osdcmd_tint);
|
||||
#endif
|
||||
|
@ -9888,7 +9911,16 @@ void ExtCheckKeys(void)
|
|||
if (infobox&2)
|
||||
m32_showmouse();
|
||||
}
|
||||
else Keys2d();
|
||||
else
|
||||
{
|
||||
Keys2d();
|
||||
|
||||
if (autocorruptcheck>0 && totalclock > corruptchecktimer)
|
||||
{
|
||||
CheckMapCorruption(0);
|
||||
corruptchecktimer = totalclock + 120*autocorruptcheck;
|
||||
}
|
||||
}
|
||||
|
||||
if (asksave == 1 && (bstatus + lastbstatus) == 0 && mapstate)
|
||||
{
|
||||
|
@ -9920,6 +9952,130 @@ void ExtCheckKeys(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//// port of a.m32's corruptchk ////
|
||||
// returns value from 0 (all OK) to 5 (panic!)
|
||||
#define CORRUPTCHK_PRINT(errlev, fmt, ...) do \
|
||||
{ \
|
||||
bad = max(bad, errlev); \
|
||||
if (errlev >= printfromlev) \
|
||||
{ \
|
||||
OSD_Printf(fmt "\n", ## __VA_ARGS__); \
|
||||
if (qsetmode!=200) printmessage16(fmt, ## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int32_t CheckMapCorruption(int32_t printfromlev)
|
||||
{
|
||||
int32_t i, j, w0, numw, endwall, ns, nw;
|
||||
int32_t ewall=0; // expected wall index
|
||||
|
||||
int32_t errlevel=0, bad=0;
|
||||
|
||||
if (numsectors>MAXSECTORS)
|
||||
CORRUPTCHK_PRINT(5, "PANIC!!! SECTOR LIMIT EXCEEDED (MAXSECTORS=%d)!!!", MAXSECTORS);
|
||||
|
||||
if (numwalls>MAXWALLS)
|
||||
CORRUPTCHK_PRINT(5, "PANIC!!! WALL LIMIT EXCEEDED (MAXWALLS=%d)!!!", MAXWALLS);
|
||||
|
||||
if (numsectors>MAXSECTORS || numwalls>MAXWALLS)
|
||||
return bad;
|
||||
|
||||
for (i=0; i<numsectors; i++)
|
||||
{
|
||||
bad = 0;
|
||||
|
||||
w0 = sector[i].wallptr;
|
||||
numw = sector[i].wallnum;
|
||||
|
||||
if (w0 < 0 || w0 > numwalls)
|
||||
CORRUPTCHK_PRINT(4, "SECTOR[%d].WALLPTR=%d out of range (numwalls=%d)", i, w0, numw);
|
||||
|
||||
if (w0 != ewall)
|
||||
CORRUPTCHK_PRINT(4, "SECTOR[%d].WALLPTR=%d inconsistent, expected %d", i, w0, ewall);
|
||||
|
||||
if (numw <= 1)
|
||||
CORRUPTCHK_PRINT(5, "PANIC!!! SECTOR[%d].WALLNUM=%d INVALID!!!", i, numw);
|
||||
else if (numw==2)
|
||||
CORRUPTCHK_PRINT(3, "SECTOR[%d].WALLNUM=2, expected at least 3", i);
|
||||
|
||||
ewall += numw;
|
||||
|
||||
endwall = w0 + numw;
|
||||
if (endwall > numwalls)
|
||||
CORRUPTCHK_PRINT(4, "SECTOR[%d]: wallptr+wallnum=%d out of range: numwalls=%d", i, endwall, numwalls);
|
||||
|
||||
if (bad)
|
||||
errlevel = max(errlevel, bad);
|
||||
else
|
||||
{
|
||||
endwall--;
|
||||
|
||||
for (j=w0; j<=endwall; j++)
|
||||
{
|
||||
bad = 0;
|
||||
|
||||
if (wall[j].point2 < w0 || wall[j].point2 > endwall)
|
||||
CORRUPTCHK_PRINT(4, "WALL[%d].POINT2=%d out of range [%d, %d]",
|
||||
j, wall[j].point2, w0, endwall);
|
||||
|
||||
nw = wall[j].nextwall;
|
||||
ns = wall[j].nextsector;
|
||||
|
||||
if (nw >= numwalls)
|
||||
CORRUPTCHK_PRINT(4, "WALL[%d].NEXTWALL=%d out of range: numwalls=%d",
|
||||
j, nw, numwalls);
|
||||
|
||||
if (ns >= numsectors)
|
||||
CORRUPTCHK_PRINT(4, "WALL[%d].NEXTSECTOR=%d out of range: numsectors=%d",
|
||||
j, ns, numsectors);
|
||||
|
||||
if (ns == i)
|
||||
CORRUPTCHK_PRINT(4, "WALL[%d].NEXTSECTOR is its own sector", j);
|
||||
|
||||
if (nw>=w0 && nw<=endwall)
|
||||
CORRUPTCHK_PRINT(4, "WALL[%d].NEXTWALL is its own sector's wall", j);
|
||||
|
||||
if (bad)
|
||||
errlevel = max(errlevel, bad);
|
||||
else
|
||||
{
|
||||
if (ns>=0 || (ns^nw)<0)
|
||||
{
|
||||
if ((ns^nw)<0 || nw<sector[ns].wallptr || nw>=sector[ns].wallptr+sector[ns].wallnum)
|
||||
CORRUPTCHK_PRINT(4, "WALL[%d].NEXTSECTOR=%d and .NEXTWALL=%d inconsistent",
|
||||
j, ns, nw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bad = 0;
|
||||
for (i=0; i<MAXSPRITES; i++)
|
||||
{
|
||||
if (sprite[i].statnum==MAXSTATUS)
|
||||
continue;
|
||||
|
||||
if (sprite[i].sectnum<0 || sprite[i].sectnum>=numsectors)
|
||||
CORRUPTCHK_PRINT(2, "SPRITE[%d].SECTNUM=%d. Expect problems!", i, sprite[i].sectnum);
|
||||
|
||||
if (sprite[i].picnum<0 || sprite[i].picnum>=MAXTILES)
|
||||
{
|
||||
sprite[i].picnum = 0;
|
||||
CORRUPTCHK_PRINT(0, "SPRITE[%d].PICNUM=%d out of range, resetting to 0", i, sprite[i].picnum);
|
||||
}
|
||||
}
|
||||
|
||||
errlevel = max(errlevel, bad);
|
||||
|
||||
if (errlevel)
|
||||
OSD_Printf("--\n");
|
||||
|
||||
return errlevel;
|
||||
}
|
||||
////
|
||||
|
||||
void faketimerhandler(void)
|
||||
{
|
||||
sampletimer();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
def makehighpalookuppixel(pal, rgb):
|
||||
hsv = list(colorsys.rgb_to_hsv(*rgb))
|
||||
if pal == 0:
|
||||
|
@ -78,4 +80,4 @@ for k in range(zdim):
|
|||
fo.writelines(pixels)
|
||||
fo.close()
|
||||
|
||||
print "\n"
|
||||
print "\n"
|
||||
|
|
250
polymer/prhighpal.py
Executable file
250
polymer/prhighpal.py
Executable file
|
@ -0,0 +1,250 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys;
|
||||
|
||||
from numpy import array, zeros, ones, arange
|
||||
from numpy import vstack, hstack, hsplit, dstack, dsplit
|
||||
|
||||
from PIL.Image import frombuffer
|
||||
|
||||
|
||||
NBITS = 7;
|
||||
RESIDBITS = 8-NBITS;
|
||||
DIM = 1<<NBITS;
|
||||
|
||||
CONVFACT = 256;
|
||||
|
||||
### target hues
|
||||
green = .39; # 11, 22
|
||||
yellow = .17; # 23
|
||||
red = .04; # 21
|
||||
|
||||
|
||||
def genbasepal():
|
||||
"Generate base palette for highpalookup system. \
|
||||
All other palettes must be based on this one."
|
||||
imint = zeros([DIM, DIM, DIM], 'uint32');
|
||||
for i in range(DIM):
|
||||
for j in range(DIM):
|
||||
for k in range(DIM):
|
||||
imint[i,j,k] = ((i<<16)|(k<<8)|j)<<RESIDBITS;
|
||||
|
||||
imint = hstack(dsplit(imint, DIM));
|
||||
|
||||
imbyte = zeros([DIM, DIM*DIM, 3], 'uint8');
|
||||
|
||||
for i in range(3):
|
||||
imbyte[:,:,i] = (imint[:,:,0]>>(i*8))&255;
|
||||
|
||||
return imbyte;
|
||||
|
||||
|
||||
def getdispimg(im):
|
||||
"Get a reshaped version of the palette image IM suitable for viewing."
|
||||
# 2^NBITS x 2^NBITS*2^NBITS --> 2^(NBITS + NBITS/2) x 2^NBITS*2^(NBITS - NBITS/2)
|
||||
|
||||
if (im.shape != (DIM, DIM*DIM, 3)):
|
||||
raise ValueError("image must have shape (DIM, DIM*DIM, 3)");
|
||||
|
||||
dimfactor = 1<<(NBITS/2);
|
||||
return vstack(hsplit(im, dimfactor));
|
||||
|
||||
|
||||
def getPILimg(im):
|
||||
sz = im.shape;
|
||||
return frombuffer("RGB", [sz[1], sz[0]], im, "raw", "RGB", 0, 1);
|
||||
|
||||
|
||||
def saveimage(im, filename):
|
||||
getPILimg(im).save(filename);
|
||||
|
||||
def showpalimg(im):
|
||||
getPILimg(getdispimg(im)).show();
|
||||
|
||||
|
||||
### utility functions
|
||||
|
||||
## port of Octave's rbg2hsv
|
||||
def rgb2hsv(im):
|
||||
im = imitof(im);
|
||||
|
||||
r, g, b = im[..., 0], im[..., 1], im[..., 2];
|
||||
s, v = im.min(2), im.max(2);
|
||||
dif = v-s;
|
||||
|
||||
colored = (s != v);
|
||||
|
||||
h = zeros(r.shape, im.dtype);
|
||||
|
||||
# blue hue
|
||||
idx = ((v==b) & colored);
|
||||
h[idx] = 2./3 + 1./6*(r[idx]-g[idx])/dif[idx];
|
||||
|
||||
# green hue
|
||||
idx = ((v==g) & colored);
|
||||
h[idx] = 1./3 + 1./6*(b[idx]-r[idx])/dif[idx];
|
||||
|
||||
# red hue
|
||||
idx = ((v==r) & colored);
|
||||
h[idx] = 1./6*(g[idx]-b[idx])/dif[idx];
|
||||
h[idx] %= 1;
|
||||
|
||||
s[~colored] = 0;
|
||||
s[colored] = 1.0 - s[colored]/v[colored];
|
||||
|
||||
return dstack((h,s,v));
|
||||
|
||||
|
||||
## port of Octave's hsv2rbg
|
||||
def hsv2rgb(imh):
|
||||
imh[imh<0] = 0;
|
||||
imh[imh>1] = 1;
|
||||
|
||||
h, s, v = imh[..., 0], imh[..., 1], imh[..., 2];
|
||||
|
||||
rgb = v*(1.0-s);
|
||||
rgb = dstack((rgb, rgb, rgb));
|
||||
|
||||
hue = dstack((h-2./3, h, h-1./3))%1;
|
||||
f = s*v;
|
||||
f = dstack((f, f, f));
|
||||
|
||||
rgb += f * (6.0 * (hue < 1./6)*hue
|
||||
+ ((hue >= 1./6) & (hue < 1./2))
|
||||
+ ((hue >= 1./2) & (hue < 2./3))*(4.0 - 6.0*hue));
|
||||
|
||||
return imftoi(rgb);
|
||||
|
||||
|
||||
def imftoi(im):
|
||||
im *= CONVFACT;
|
||||
im[im>255] = 255;
|
||||
return im.astype('uint8');
|
||||
|
||||
def imitof(im):
|
||||
return im.astype('float32')/CONVFACT;
|
||||
|
||||
|
||||
###
|
||||
def genpal(basepal, basepalhsv, pal):
|
||||
"Generate a highpalookup image for palette number PAL. \
|
||||
BASEPALHSV should the precomputed HSV representation of BASEPAL."
|
||||
|
||||
if (basepal.dtype != 'uint8'):
|
||||
raise TypeError('BASEPAL should be uint8.');
|
||||
|
||||
if (pal==0):
|
||||
return basepal;
|
||||
|
||||
bph = basepalhsv;
|
||||
h,s,v = bph[..., 0], bph[..., 1], bph[..., 2];
|
||||
|
||||
bluemask = (h>0.52) & (h<0.8) & (s>0.2);
|
||||
|
||||
# all true mask will be used unless overridden
|
||||
mask = ones(h.shape, 'bool');
|
||||
|
||||
# plagman:
|
||||
if (pal==1):
|
||||
h[:] = 0.66;
|
||||
|
||||
elif (pal==6):
|
||||
h[:] = 0.33;
|
||||
v = 1.0 - v;
|
||||
|
||||
elif (pal==20):
|
||||
m1 = ((h>0.6) & (h<0.7));
|
||||
m2 = ((h>0.04) & (h<0.13));
|
||||
m3 = ((h>0.7) & (h<0.9));
|
||||
m4 = ((h>0.3) & (h<0.36));
|
||||
mask = m1 | m2 | m3 | m4;
|
||||
|
||||
# blue to gray by removing all saturation
|
||||
h[m1] = 0.0;
|
||||
# orange and brown to blue
|
||||
h[m2] = 0.66;
|
||||
# purple and reddish to blue
|
||||
h[m3] = 0.66
|
||||
# green to blue
|
||||
h[m4] = 0.66;
|
||||
|
||||
# helixhorned:
|
||||
elif (pal==11):
|
||||
mask = bluemask;
|
||||
h[:] = green;
|
||||
s += 0.1;
|
||||
|
||||
elif (pal==12):
|
||||
mask = bluemask;
|
||||
h[:] = 0.0;
|
||||
s[:] = 0.0;
|
||||
|
||||
elif (pal==13):
|
||||
mask = bluemask;
|
||||
h[:] = 0.0;
|
||||
s[:] = 0.0;
|
||||
v *= 0.7;
|
||||
|
||||
elif (pal==16):
|
||||
mask = bluemask;
|
||||
s += 0.1;
|
||||
v -= 0.1;
|
||||
|
||||
elif (pal==21):
|
||||
mask = bluemask;
|
||||
h[:] = red;
|
||||
s += 0.3;
|
||||
|
||||
elif (pal==23):
|
||||
mask = bluemask;
|
||||
h[:] = yellow;
|
||||
s += 0.12;
|
||||
v *= 1.15;
|
||||
|
||||
# user:
|
||||
# ...
|
||||
|
||||
else:
|
||||
raise ValueError("unknown pal {0}!".format(pal));
|
||||
|
||||
# ---
|
||||
newrgb = hsv2rgb(dstack((h, s, v)));
|
||||
|
||||
r = mask*newrgb[:,:,0] + (~mask)*basepal[:,:,0];
|
||||
g = mask*newrgb[:,:,1] + (~mask)*basepal[:,:,1];
|
||||
b = mask*newrgb[:,:,2] + (~mask)*basepal[:,:,2];
|
||||
|
||||
# PIL doesn't seem to like views/shallow copies
|
||||
return dstack((r, g, b)).copy();
|
||||
|
||||
|
||||
## main
|
||||
if (__name__ == "__main__"):
|
||||
|
||||
argc = len(sys.argv);
|
||||
if (argc == 1):
|
||||
print "Usage: python prhighpal.py <palnum>"
|
||||
sys.exit();
|
||||
elif (argc > 2):
|
||||
print "There's a weird bug when passing more than one palnum; \
|
||||
processing only the first one.\n"
|
||||
|
||||
print "Generating base palette..."
|
||||
bp = genbasepal();
|
||||
bph = rgb2hsv(bp);
|
||||
|
||||
for i in [1]: #xrange(1, argc):
|
||||
palnum = int(sys.argv[i]);
|
||||
filename = "hipal{0}_gen.png".format(palnum);
|
||||
print "Generating palnum", palnum, "image ...";
|
||||
palimg = genpal(bp, bph, palnum);
|
||||
print "Writing", filename, "...";
|
||||
saveimage(palimg, filename);
|
||||
|
||||
print "\nDEF code:\n"
|
||||
for i in xrange(1, argc):
|
||||
palnum = int(sys.argv[i]);
|
||||
if (palnum==0):
|
||||
continue;
|
||||
filename = "hipal{0}_gen.png".format(palnum);
|
||||
print "highpalookup { pal", palnum, "file", filename, "}";
|
Loading…
Reference in a new issue