Rework automap/minigen colours

- All pre-existing colours are now actually what the code says they should be for the 2.2 palette
- RR-specific colour changes.
    - Remove all noclimb-specific line colours
    - Render areas that can't be stepped up/down onto as walls
    - Add colours for
        - Tripwire (cyan, but not 0xff cyan)
        - Finish Line (grey)
        - FOF info (blue)
    - Use a low-intensity colour to signal possible offroad/hazard sector or stairjank step
- Rework to support drawing in multiple passes, so that information that is strictly more important (solid walls, finish line) will not be obscured at minimap resolution by nearby lines signalling offroad/stairjank

Related:
- Added K_TerrainHasAffect
    - Returns true if terrain has any properties which would affect the player's gameplay, false if not.
This commit is contained in:
toaster 2023-01-23 18:38:52 +00:00
parent dafd6d5dfa
commit da639fe65f
3 changed files with 274 additions and 57 deletions

View file

@ -26,43 +26,39 @@
#endif #endif
// For use if I do walls with outsides/insides // For use if I do walls with outsides/insides
static const UINT8 REDS = (8*16); static const UINT8 REDS = (2*16);
static const UINT8 REDRANGE = 16; static const UINT8 REDRANGE = 16;
static const UINT8 GRAYS = (1*16); static const UINT8 GRAYS = (1*16);
static const UINT8 GRAYSRANGE = 16; static const UINT8 GRAYSRANGE = 16;
static const UINT8 BROWNS = (3*16); static const UINT8 BROWNS = (15*16);
static const UINT8 YELLOWS = (7*16); static const UINT8 YELLOWS = (5*16)+8;
static const UINT8 GREENS = (10*16); static const UINT8 GREENS = (6*16);
static const UINT8 CYANS = (8*16);
static const UINT8 BLUES = (9*16);
static const UINT8 DBLACK = 31; static const UINT8 DBLACK = 31;
static const UINT8 DWHITE = 0; static const UINT8 DWHITE = 0;
static const UINT8 NOCLIMBREDS = 248;
static const UINT8 NOCLIMBREDRANGE = 8;
static const UINT8 NOCLIMBGRAYS = 204;
static const UINT8 NOCLIMBBROWNS = (2*16);
static const UINT8 NOCLIMBYELLOWS = (11*16);
// Automap colors // Automap colors
#define BACKGROUND DBLACK #define BACKGROUND DBLACK
#define WALLCOLORS (REDS + REDRANGE/2) #define WALLCOLORS (REDS + REDRANGE/2)
#define WALLRANGE (REDRANGE/2) #define WALLRANGE (REDRANGE/2)
#define NOCLIMBWALLCOLORS (NOCLIMBREDS + NOCLIMBREDRANGE/2)
#define NOCLIMBWALLRANGE (NOCLIMBREDRANGE/2)
#define THOKWALLCOLORS REDS #define THOKWALLCOLORS REDS
#define THOKWALLRANGE REDRANGE #define THOKWALLRANGE REDRANGE
#define NOCLIMBTHOKWALLCOLORS NOCLIMBREDS #define TSWALLCOLORS DWHITE
#define NOCLIMBTHOKWALLRANGE NOCLIMBREDRANGE #define TSFINISHLINE GRAYS
#define TSWALLCOLORS GRAYS #define TSTRIPWIRE (CYANS + 4)
#define TSWALLRANGE GRAYSRANGE #define TSFOFINFO (BLUES + 4)
#define NOCLIMBTSWALLCOLORS NOCLIMBGRAYS
#define FDWALLCOLORS BROWNS #define FDWALLCOLORS BROWNS
#define NOCLIMBFDWALLCOLORS NOCLIMBBROWNS
#define CDWALLCOLORS YELLOWS #define CDWALLCOLORS YELLOWS
#define NOCLIMBCDWALLCOLORS NOCLIMBYELLOWS
#define THINGCOLORS GREENS #define THINGCOLORS GREENS
#define GRIDCOLORS (GRAYS + GRAYSRANGE/2) #define GRIDCOLORS (GRAYS + GRAYSRANGE/2)
#define XHAIRCOLORS DWHITE #define XHAIRCOLORS GRAYS
// Automap passes
#define PASS_SOLID 1
#define PASS_INTANGIBLE 2
#define PASS_FOF 4
// controls // controls
#define AM_PANUPKEY KEY_UPARROW #define AM_PANUPKEY KEY_UPARROW
@ -932,14 +928,93 @@ static void AM_drawGrid(INT32 color)
} }
} }
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
end1 = (P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y, normalheight) + FRACUNIT/2) >> FRACBITS; \
end2 = (P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y, normalheight) + FRACUNIT/2) >> FRACBITS;
static ffloor_t *AM_CompareFOFs(size_t i, ffloor_t *rover, ffloor_t *secondarystore)
{
ffloor_t *secondaryrover = NULL;
for (; rover; rover = rover->next)
{
fixed_t rovt1, rovt2;
fixed_t rovb1, rovb2;
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->fofflags & FOF_BLOCKPLAYER))
continue;
SLOPEPARAMS(*rover->t_slope, rovt1, rovt2, *rover->topheight)
SLOPEPARAMS(*rover->b_slope, rovb1, rovb2, *rover->bottomheight)
for (secondaryrover = secondarystore; secondaryrover; secondaryrover = secondaryrover->next)
{
fixed_t sect1, sect2;
fixed_t secb1, secb2;
terrain_t *terrain1 = NULL;
terrain_t *terrain2 = NULL;
if (!(secondaryrover->fofflags & FOF_EXISTS))
continue;
if (!(secondaryrover->fofflags & FOF_BLOCKPLAYER))
continue;
if (secondaryrover->secnum == rover->secnum)
break;
SLOPEPARAMS(*secondaryrover->t_slope, sect1, sect2, *secondaryrover->topheight)
SLOPEPARAMS(*secondaryrover->b_slope, secb1, secb2, *secondaryrover->bottomheight)
if (rovt1 != sect1)
continue;
if (rovt2 != sect2)
continue;
if (rovb1 != secb1)
continue;
if (rovb2 != secb2)
continue;
if (sectors[rover->secnum].damagetype != sectors[secondaryrover->secnum].damagetype
|| sectors[rover->secnum].friction != sectors[secondaryrover->secnum].friction
|| sectors[rover->secnum].offroad != sectors[secondaryrover->secnum].offroad)
continue;
if (*rover->toppic != *secondaryrover->toppic)
{
terrain1 = K_GetTerrainForFlatNum(*rover->toppic);
terrain2 = K_GetTerrainForFlatNum(*secondaryrover->toppic);
}
else if (*rover->bottompic != *secondaryrover->bottompic)
{
terrain1 = K_GetTerrainForFlatNum(*rover->bottompic);
terrain2 = K_GetTerrainForFlatNum(*secondaryrover->bottompic);
}
if ((terrain1 && K_TerrainHasAffect(terrain1))
|| (terrain2 && K_TerrainHasAffect(terrain2)))
continue;
break;
}
if (secondaryrover == NULL)
break;
}
return rover;
}
// //
// Determines visible lines, draws them. // Determines visible lines, draws them.
// This is LineDef based, not LineSeg based. // This is LineDef based, not LineSeg based.
// //
static void AM_drawWalls(void) static void AM_drawWalls(UINT8 pass)
{ {
size_t i; size_t i;
static mline_t l; static mline_t l;
const fixed_t maxstep = P_BaseStepUp()>>FRACBITS;
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1 = 0, backf2 = 0, backc1 = 0, backc2 = 0; // back floor ceiling ends fixed_t backf1 = 0, backf2 = 0, backc1 = 0, backc2 = 0; // back floor ceiling ends
@ -950,71 +1025,180 @@ static void AM_drawWalls(void)
l.b.x = lines[i].v2->x >> FRACTOMAPBITS; l.b.x = lines[i].v2->x >> FRACTOMAPBITS;
l.b.y = lines[i].v2->y >> FRACTOMAPBITS; l.b.y = lines[i].v2->y >> FRACTOMAPBITS;
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
end1 = P_GetZAt(slope, lines[i].v1->x, lines[i].v1->y, normalheight); \
end2 = P_GetZAt(slope, lines[i].v2->x, lines[i].v2->y, normalheight);
SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight) SLOPEPARAMS(lines[i].frontsector->f_slope, frontf1, frontf2, lines[i].frontsector->floorheight)
SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight) SLOPEPARAMS(lines[i].frontsector->c_slope, frontc1, frontc2, lines[i].frontsector->ceilingheight)
if (lines[i].backsector) {
SLOPEPARAMS(lines[i].backsector->f_slope, backf1, backf2, lines[i].backsector->floorheight)
SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight)
}
#undef SLOPEPARAMS
if (!lines[i].backsector) // 1-sided if (!lines[i].backsector) // 1-sided
{ {
if (lines[i].flags & ML_NOCLIMB) if (!(pass & PASS_SOLID))
AM_drawMline(&l, NOCLIMBWALLCOLORS); ;
else else if (frontf1 != frontc1 || frontf2 != frontc2 || lines[i].frontsector->f_slope)
{
AM_drawMline(&l, TSWALLCOLORS);
}
else if (!am_minigen)
{
AM_drawMline(&l, WALLCOLORS); AM_drawMline(&l, WALLCOLORS);
}
continue;
} }
else if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier
SLOPEPARAMS(lines[i].backsector->f_slope, backf1, backf2, lines[i].backsector->floorheight)
SLOPEPARAMS(lines[i].backsector->c_slope, backc1, backc2, lines[i].backsector->ceilingheight)
if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier
|| (frontf1 == frontc1 && frontf2 == frontc2)) // Front is thok barrier || (frontf1 == frontc1 && frontf2 == frontc2)) // Front is thok barrier
{ {
if (backf1 == backc1 && backf2 == backc2 if (backf1 == backc1 && backf2 == backc2
&& frontf1 == frontc1 && frontf2 == frontc2) // BOTH are thok barriers && frontf1 == frontc1 && frontf2 == frontc2) // BOTH are thok barriers
{ {
if (lines[i].flags & ML_NOCLIMB) if (!am_minigen && (pass & PASS_INTANGIBLE))
AM_drawMline(&l, NOCLIMBTSWALLCOLORS); {
else AM_drawMline(&l, GRIDCOLORS);
AM_drawMline(&l, TSWALLCOLORS); }
} }
else else if (pass & PASS_SOLID)
{ {
if (lines[i].flags & ML_NOCLIMB) AM_drawMline(&l, TSWALLCOLORS);
AM_drawMline(&l, NOCLIMBTHOKWALLCOLORS);
else
AM_drawMline(&l, THOKWALLCOLORS);
} }
} }
else else
{ {
if (lines[i].flags & ML_NOCLIMB) { if (lines[i].flags & (ML_IMPASSABLE|ML_BLOCKPLAYERS))
if (backf1 != frontf1 || backf2 != frontf2) { {
AM_drawMline(&l, NOCLIMBFDWALLCOLORS); // floor level change if (pass & PASS_SOLID)
} AM_drawMline(&l, TSWALLCOLORS); // Completely solid course boundary
else if (backc1 != frontc1 || backc2 != frontc2) { }
AM_drawMline(&l, NOCLIMBCDWALLCOLORS); // ceiling level change else if ((lines[i].flags & ML_MIDSOLID)
&& sides[lines->sidenum[0]].midtexture)
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSWALLCOLORS); // solid midtexture, likely a course boundary
}
if ((backf1 != frontf1 && abs(backf1 - frontf1) > maxstep)
|| (backf2 != frontf2 && abs(backf2 - frontf2) > maxstep))
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSWALLCOLORS); // floor-wall, likely a course boundary
}
else if (lines[i].special == 2001)
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSFINISHLINE); // finish line
}
else if (P_IsLineTripWire(&lines[i]))
{
if (pass & PASS_SOLID)
AM_drawMline(&l, TSTRIPWIRE); // tripwire shortcut
}
else if (backf1 != frontf1 || backf2 != frontf2)
{
if (pass & PASS_INTANGIBLE)
AM_drawMline(&l, FDWALLCOLORS); // floorlevel change
}
else if (backc1 != frontc1 || backc2 != frontc2)
{
if (!(pass & PASS_INTANGIBLE))
;
else if (abs(backc1 - frontc1) < maxstep
|| abs(backc2 - frontc2) < maxstep)
{
AM_drawMline(&l, CDWALLCOLORS); // ceilinglevel change
} }
else else
AM_drawMline(&l, NOCLIMBTSWALLCOLORS); {
AM_drawMline(&l, GRIDCOLORS); // ceiling-wall, not likely to be a course boundary but flagged up just in case
}
}
else if (lines[i].frontsector->damagetype != lines[i].backsector->damagetype
|| lines[i].frontsector->friction != lines[i].backsector->friction
|| lines[i].frontsector->offroad != lines[i].backsector->offroad)
{
if (pass & PASS_INTANGIBLE)
AM_drawMline(&l, FDWALLCOLORS); // Functionality boundary
} }
else else
{ {
if (backf1 != frontf1 || backf2 != frontf2) { terrain_t *terrain1 = NULL;
AM_drawMline(&l, FDWALLCOLORS); // floor level change terrain_t *terrain2 = NULL;
UINT8 defercol = GRIDCOLORS;
if (lines[i].frontsector->floorpic != lines[i].backsector->floorpic)
{
terrain1 = K_GetTerrainForFlatNum(lines[i].frontsector->floorpic);
terrain2 = K_GetTerrainForFlatNum(lines[i].backsector->ceilingpic);
defercol = FDWALLCOLORS; // possible floor offroad boundary
} }
else if (backc1 != frontc1 || backc2 != frontc2) { else if (lines[i].frontsector->ceilingpic != lines[i].backsector->ceilingpic)
AM_drawMline(&l, CDWALLCOLORS); // ceiling level change {
terrain1 = K_GetTerrainForFlatNum(lines[i].frontsector->floorpic);
terrain2 = K_GetTerrainForFlatNum(lines[i].backsector->ceilingpic);
defercol = CDWALLCOLORS; // possible ceiling offroad boundary
}
if ((terrain1 && K_TerrainHasAffect(terrain1))
|| (terrain2 && K_TerrainHasAffect(terrain2)))
{
if (pass & PASS_INTANGIBLE)
AM_drawMline(&l, defercol); // Yep, definitely a functionality boundary
} }
else else
AM_drawMline(&l, TSWALLCOLORS); {
ffloor_t *rover = NULL;
if (lines[i].frontsector->ffloors || lines[i].backsector->ffloors)
{
if (lines[i].backsector->ffloors == NULL)
{
// Check frontside for one solid
for (rover = lines[i].frontsector->ffloors; rover; rover = rover->next)
{
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->fofflags & FOF_BLOCKPLAYER))
continue;
break;
}
}
else if (lines[i].frontsector->ffloors == NULL)
{
// Check backside for one solid
for (rover = lines[i].backsector->ffloors; rover; rover = rover->next)
{
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->fofflags & FOF_BLOCKPLAYER))
continue;
break;
}
}
else
{
// Check to see if any secnums exist in one but not the other.
rover = AM_CompareFOFs(i, lines[i].frontsector->ffloors, lines[i].backsector->ffloors);
if (rover == NULL)
rover = AM_CompareFOFs(i, lines[i].backsector->ffloors, lines[i].frontsector->ffloors);
}
}
if (rover != NULL)
{
if (pass & PASS_FOF)
AM_drawMline(&l, TSFOFINFO); // a FOF is here but we don't know how to distinguish them yet
}
else if (!am_minigen)
{
if (pass & PASS_INTANGIBLE)
AM_drawMline(&l, GRIDCOLORS); // likely low-relevance line
}
}
} }
} }
} }
} }
#undef SLOPEPARAMS
// //
// Rotation in 2D. // Rotation in 2D.
// Used to rotate player arrow line character. // Used to rotate player arrow line character.
@ -1162,7 +1346,7 @@ void AM_Drawer(void)
AM_clearFB(BACKGROUND); AM_clearFB(BACKGROUND);
if (draw_grid) AM_drawGrid(GRIDCOLORS); if (draw_grid) AM_drawGrid(GRIDCOLORS);
AM_drawWalls(); AM_drawWalls(PASS_FOF|PASS_INTANGIBLE|PASS_SOLID);
AM_drawPlayers(); AM_drawPlayers();
AM_drawThings(THINGCOLORS); AM_drawThings(THINGCOLORS);
@ -1218,7 +1402,9 @@ UINT8 *AM_MinimapGenerate(INT32 wh)
//AM_clearFB(BACKGROUND); //AM_clearFB(BACKGROUND);
memset(am_buf, 0xff, (f_w*f_h)); memset(am_buf, 0xff, (f_w*f_h));
AM_drawWalls(); AM_drawWalls(PASS_FOF);
AM_drawWalls(PASS_INTANGIBLE);
AM_drawWalls(PASS_SOLID);
am_buf = NULL; am_buf = NULL;
am_recalc = true; am_recalc = true;

View file

@ -1536,6 +1536,23 @@ static void K_TerrainDefaults(terrain_t *terrain)
terrain->flags = 0; terrain->flags = 0;
} }
/*--------------------------------------------------
boolean K_TerrainHasAffect(terrain_t *terrain)
See header file for description.
--------------------------------------------------*/
boolean K_TerrainHasAffect(terrain_t *terrain)
{
return (terrain->friction != 0
|| terrain->offroad != 0
|| terrain->damageType != -1
|| terrain->trickPanel != 0
|| terrain->speedPad != 0
|| terrain->springStrength != 0
|| terrain->flags != 0);
}
/*-------------------------------------------------- /*--------------------------------------------------
static void K_NewTerrainDefs(void) static void K_NewTerrainDefs(void)

View file

@ -569,6 +569,20 @@ void K_UpdateTerrainOverlay(mobj_t *mo);
void K_InitTerrain(UINT16 wadNum); void K_InitTerrain(UINT16 wadNum);
/*--------------------------------------------------
boolean K_TerrainHasAffect(terrain_t *terrain)
Checks if Terrain block has a gameplay-affecting property.
Input Arguments:-
terrain - Terrain structure to default.
Return:-
false if functionally default, otherwise true.
--------------------------------------------------*/
boolean K_TerrainHasAffect(terrain_t *terrain);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif