Add option to render minimap to a fixed-size canvas.

This commit is contained in:
Mari the Deer 2023-01-16 13:28:10 +01:00
commit ddbc59939b
8 changed files with 91 additions and 31 deletions

View file

@ -1,7 +1,13 @@
// title stuff
canvastexture LOGOFADE 4 4
// ammo leds
canvastexture PLASBLED 64 64
canvastexture PLASBFAD 4 4
canvastexture SHEENLED 128 128
canvastexture QUADRLED 64 64
canvastexture MORTLED1 256 128
canvastexture MORTLED2 64 16
// minimap
canvastexture MMCANVAS 80 80

View file

@ -85,6 +85,7 @@ nosave bool swwm_mm_enable = true; // show a minimap below the score counter
nosave noarchive float swwm_mm_zoom = 1; // zoom level of minimap
nosave bool swwm_mm_missiles = true; // show projectiles (how revolutionary)
nosave int swwm_mm_colorset = 0; // 0: Demolitionist, 1: GZDoom, 2: Doom, 3: Strife, 4: Raven
nosave bool swwm_mm_usecanvas = false; // use a canvas to draw the minimap, so its pixel density is consistent with the rest of the HUD
server noarchive bool swwm_iseriouslywanttoplaythiswithbd = false; // self-explanatory

View file

@ -191,6 +191,7 @@ SWWM_GZDOOMCOLORS = "GZDoom Custom";
SWWM_DOOMCOLORS = "Vanilla Doom";
SWWM_STRIFECOLORS = "Vanilla Strife";
SWWM_RAVENCOLORS = "Vanilla Raven";
SWWM_MM_USECANVAS = "Fixed Scale Minimap";
SWWM_AC_UNLOCKED = "Unlocked: ";
SWWM_AC_INCOMPLETE = "Incomplete: ";
SWWM_AC_UNDISCOVERED = "Undiscovered: ";
@ -277,6 +278,7 @@ TOOLTIP_SWWMACHIEVEMENTMENU = "View your achievements.";
TOOLTIP_SWWM_MM_ENABLE = "Displays a minimap on the top right corner of the screen.";
TOOLTIP_SWWM_MM_MISSILES = "Displays projectiles in the minimap. Can be toggled if this clutters too much.";
TOOLTIP_SWWM_MM_COLORSET = "Choose what palette to use for the minimap.";
TOOLTIP_SWWM_MM_USECANVAS = "Rather than being drawn directly on-screen, the minimap will be drawn to a texture, maintaining the same pixel density as the rest of the HUD. Due to engine quirks, this causes the map to have a one-frame delay.";
TOOLTIP_SWWMDEBUGMENU = "Don't touch this unless you know what you're doing.";
TOOLTIP_SWWM_DEBUGBLAST = "Shows radii of DoExplosion calls. Damaging explosions are green, with yellow for the hotspot. Non-damaging explosions are blue, with magenta for the hotspot.";
TOOLTIP_SWWM_DEBUGVIEW = "Shows collision, orientation and velocity of actors, as well as relationship lines to their target/tracer/master pointers (gold/orange/purple respectively).";

View file

@ -188,6 +188,7 @@ SWWM_GZDOOMCOLORS = "Personalizado de GZDoom";
SWWM_DOOMCOLORS = "Doom Vanilla";
SWWM_STRIFECOLORS = "Strife Vanilla";
SWWM_RAVENCOLORS = "Raven Vanilla";
SWWM_MM_USECANVAS = "Minimapa a Escala Fija";
SWWM_AC_UNLOCKED = "Desbloqueados: ";
SWWM_AC_INCOMPLETE = "Incompletos: ";
SWWM_AC_UNDISCOVERED = "Sin descubrir: ";
@ -275,6 +276,7 @@ TOOLTIP_SWWMACHIEVEMENTMENU = "Revisa tus logros.";
TOOLTIP_SWWM_MM_ENABLE = "Muestra un minimapa en la esquina superior derecha de la pantalla.";
TOOLTIP_SWWM_MM_MISSILES = "Muestra proyectiles en el minimapa. Puede ser desactivado si causa problemas de visibilidad.";
TOOLTIP_SWWM_MM_COLORSET = "Selecciona que paleta usar para el minimapa.";
TOOLTIP_SWWM_MM_USECANVAS = "En vez de dibujarse directamente a la pantalla, el mapa se dibujará en una texture, mantentiendo la misma densidad de píxel que el resto del HUD. Debido a peculiaridades del motor, esto causa que el mapa tenga un frame de retardo.";
TOOLTIP_SWWMDEBUGMENU = "No toques esto a menos que sepas lo que estás haciendo.";
TOOLTIP_SWWM_DEBUGBLAST = "Muestra el radio de funciones DoExplosion. Las explosiones con daño son verdes, con amarillo para su punto caliente. Las explosiones sin daño son azules, con magenta para su punto caliente.";
TOOLTIP_SWWM_DEBUGVIEW = "Muestra la colisión, orientación y velocidad de actores, junto con lineas de relación hacia sus punteros de objetivo/trazador/maestro (dorado/naranja/púrpura respectivamente).";

View file

@ -1,3 +1,3 @@
[default]
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r736 \cu(Mon 16 Jan 13:27:25 CET 2023)\c-";
SWWM_SHORTVER="\cw1.3pre r736 \cu(2023-01-16 13:27:25)\c-";
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r737 \cu(Mon 16 Jan 13:28:10 CET 2023)\c-";
SWWM_SHORTVER="\cw1.3pre r737 \cu(2023-01-16 13:28:10)\c-";

View file

@ -153,6 +153,7 @@ OptionMenu "SWWMOptionMenu"
Option "$SWWM_MM_ENABLE", "swwm_mm_enable", "YesNo"
Option "$SWWM_MM_MISSILES", "swwm_mm_missiles", "YesNo"
Option "$SWWM_MM_COLORSET", "swwm_mm_colorset", "SWWMMinimapColorset"
Option "$SWWM_MM_USECANVAS", "swwm_mm_usecanvas", "YesNo"
Option "$SWWM_TARGET", "swwm_targeter", "SWWMTarget"
ScaleSliderFix "$SWWM_BARDIST", "swwm_bardist", 0, 4000, 100, "$SWWM_UNLIMITED"
Option "$SWWM_TARGETTAG", "swwm_targettags", "YesNo"

View file

@ -154,6 +154,9 @@ Class SWWMStatusBar : BaseStatusBar
int mm_colorset;
Color mm_backcolor, mm_cdwallcolor, mm_efwallcolor, mm_fdwallcolor, mm_interlevelcolor, mm_intralevelcolor, mm_lockedcolor, mm_notseencolor, mm_portalcolor, mm_secretsectorcolor, mm_secretwallcolor, mm_specialwallcolor, mm_thingcolor, mm_thingcolor_citem, mm_thingcolor_friend, mm_thingcolor_item, mm_thingcolor_monster, mm_thingcolor_ncmonster, mm_thingcolor_shootable, mm_thingcolor_vipitem, mm_thingcolor_missile, mm_tswallcolor, mm_unexploredsecretcolor, mm_wallcolor, mm_yourcolor;
bool mm_displaylocks;
transient bool mm_cvfirstdraw;
transient Canvas mm_canvas;
transient TextureID mm_canvastex;
// deathmatch stuff
int playercount, rank, lead;

View file

@ -436,7 +436,7 @@ extend Class SWWMStatusBar
return false;
}
private void DrawMapLines( Vector2 basepos )
private void DrawMapLines( Vector2 basepos, bool bUseCanvas = false )
{
double zoomlevel = SWWMUtility.Lerp(oldminimapzoom,minimapzoom,FracTic);
double zoomview = MAPVIEWDIST*zoomlevel, zoomclip = CLIPDIST*zoomlevel;
@ -482,8 +482,13 @@ extend Class SWWMStatusBar
[visible, rv1, rv2] = SWWMUtility.LiangBarsky((-1,-1)*zoomclip,(1,1)*zoomclip,rv1,rv2);
if ( !visible ) continue;
// scale to minimap frame
rv1 *= (HALFMAPSIZE/zoomclip)*hs;
rv2 *= (HALFMAPSIZE/zoomclip)*hs;
rv1 *= HALFMAPSIZE/zoomclip;
rv2 *= HALFMAPSIZE/zoomclip;
if ( !bUseCanvas )
{
rv1 *= hs;
rv2 *= hs;
}
// offset to minimap center
rv1 += basepos;
rv2 += basepos;
@ -562,13 +567,18 @@ extend Class SWWMStatusBar
if ( isportal )
{
col = Color((col.r+mm_portalcolor.r*7)/8,(col.g+mm_portalcolor.g*7)/8,(col.b+mm_portalcolor.b*7)/8);
Screen.DrawThickLine(int(rv1.x),int(rv1.y),int(rv2.x),int(rv2.y),max(1.,hs*.25),col);
if ( bUseCanvas ) mm_canvas.DrawLine(int(rv1.x),int(rv1.y),int(rv2.x),int(rv2.y),col);
else Screen.DrawThickLine(int(rv1.x),int(rv1.y),int(rv2.x),int(rv2.y),max(1.,hs*.25),col);
}
else
{
if ( bUseCanvas ) mm_canvas.DrawLine(int(rv1.x),int(rv1.y),int(rv2.x),int(rv2.y),col);
else Screen.DrawThickLine(int(rv1.x),int(rv1.y),int(rv2.x),int(rv2.y),max(1.,hs*.5),col);
}
else Screen.DrawThickLine(int(rv1.x),int(rv1.y),int(rv2.x),int(rv2.y),max(1.,hs*.5),col);
}
}
}
private void DrawMapMarkers( Vector2 basepos )
private void DrawMapMarkers( Vector2 basepos, bool bUseCanvas = false )
{
double zoomlevel = SWWMUtility.Lerp(oldminimapzoom,minimapzoom,FracTic);
double zoomview = MAPVIEWDIST*zoomlevel, zoomclip = CLIPDIST*zoomlevel;
@ -615,11 +625,13 @@ extend Class SWWMStatusBar
// rotate by view
rv = Actor.RotateVector(rv,ViewRot.x-90);
// scale to minimap frame
rv *= (HALFMAPSIZE/zoomclip)*hs;
rv *= HALFMAPSIZE/zoomclip;
if ( !bUseCanvas ) rv *= hs;
// offset to minimap center
rv += basepos;
// draw
Screen.DrawTexture(tx,false,rv.x,rv.y,DTA_ColorOverlay,isportal?Color(128,mm_portalcolor.r,mm_portalcolor.g,mm_portalcolor.b):Color(0,0,0,0),DTA_ScaleX,hs*scl.x,DTA_ScaleY,hs*scl.y,DTA_LegacyRenderStyle,m.GetRenderStyle(),DTA_Alpha,m.Alpha,DTA_FillColor,m.FillColor,DTA_TranslationIndex,m.Translation);
if ( bUseCanvas ) mm_canvas.DrawTexture(tx,false,rv.x,rv.y,DTA_ColorOverlay,isportal?Color(128,mm_portalcolor.r,mm_portalcolor.g,mm_portalcolor.b):Color(0,0,0,0),DTA_ScaleX,scl.x,DTA_ScaleY,scl.y,DTA_LegacyRenderStyle,m.GetRenderStyle(),DTA_Alpha,m.Alpha,DTA_FillColor,m.FillColor,DTA_TranslationIndex,m.Translation);
else Screen.DrawTexture(tx,false,rv.x,rv.y,DTA_ColorOverlay,isportal?Color(128,mm_portalcolor.r,mm_portalcolor.g,mm_portalcolor.b):Color(0,0,0,0),DTA_ScaleX,hs*scl.x,DTA_ScaleY,hs*scl.y,DTA_LegacyRenderStyle,m.GetRenderStyle(),DTA_Alpha,m.Alpha,DTA_FillColor,m.FillColor,DTA_TranslationIndex,m.Translation);
}
ai.Destroy();
continue;
@ -640,14 +652,16 @@ extend Class SWWMStatusBar
// rotate by view
rv = Actor.RotateVector(rv,ViewRot.x-90);
// scale to minimap frame
rv *= (HALFMAPSIZE/zoomclip)*hs;
rv *= HALFMAPSIZE/zoomclip;
if ( !bUseCanvas ) rv *= hs;
// offset to minimap center
rv += basepos;
// draw
Screen.DrawTexture(tx,false,rv.x,rv.y,DTA_ColorOverlay,isportal?Color(128,mm_portalcolor.r,mm_portalcolor.g,mm_portalcolor.b):Color(0,0,0,0),DTA_ScaleX,hs*scl.x,DTA_ScaleY,hs*scl.y,DTA_LegacyRenderStyle,m.GetRenderStyle(),DTA_Alpha,m.Alpha,DTA_FillColor,m.FillColor,DTA_TranslationIndex,m.Translation);
if ( bUseCanvas ) mm_canvas.DrawTexture(tx,false,rv.x,rv.y,DTA_ColorOverlay,isportal?Color(128,mm_portalcolor.r,mm_portalcolor.g,mm_portalcolor.b):Color(0,0,0,0),DTA_ScaleX,scl.x,DTA_ScaleY,scl.y,DTA_LegacyRenderStyle,m.GetRenderStyle(),DTA_Alpha,m.Alpha,DTA_FillColor,m.FillColor,DTA_TranslationIndex,m.Translation);
else Screen.DrawTexture(tx,false,rv.x,rv.y,DTA_ColorOverlay,isportal?Color(128,mm_portalcolor.r,mm_portalcolor.g,mm_portalcolor.b):Color(0,0,0,0),DTA_ScaleX,hs*scl.x,DTA_ScaleY,hs*scl.y,DTA_LegacyRenderStyle,m.GetRenderStyle(),DTA_Alpha,m.Alpha,DTA_FillColor,m.FillColor,DTA_TranslationIndex,m.Translation);
}
}
private void DrawMapThings( Vector2 basepos )
private void DrawMapThings( Vector2 basepos, bool bUseCanvas = false )
{
double zoomlevel = SWWMUtility.Lerp(oldminimapzoom,minimapzoom,FracTic);
double zoomview = MAPVIEWDIST*zoomlevel, zoomclip = CLIPDIST*zoomlevel;
@ -756,13 +770,19 @@ extend Class SWWMStatusBar
if ( visible )
{
// scale to minimap frame
x0 *= (HALFMAPSIZE/zoomclip)*hs;
x1 *= (HALFMAPSIZE/zoomclip)*hs;
x0 *= HALFMAPSIZE/zoomclip;
x1 *= HALFMAPSIZE/zoomclip;
if ( !bUseCanvas )
{
x0 *= hs;
x1 *= hs;
}
// offset to minimap center
x0 += basepos;
x1 += basepos;
// draw the line
if ( isportal ) Screen.DrawThickLine(int(x0.x),int(x0.y),int(x1.x),int(x1.y),max(1.,hs*.25),col,int(t.smoothalpha*255));
if ( bUseCanvas ) mm_canvas.DrawLine(int(x0.x),int(x0.y),int(x1.x),int(x1.y),col,int(t.smoothalpha*255));
else if ( isportal ) Screen.DrawThickLine(int(x0.x),int(x0.y),int(x1.x),int(x1.y),max(1.,hs*.25),col,int(t.smoothalpha*255));
else Screen.DrawThickLine(int(x0.x),int(x0.y),int(x1.x),int(x1.y),max(1.,hs*.5),col,int(t.smoothalpha*255));
drawn = true;
}
@ -786,6 +806,45 @@ extend Class SWWMStatusBar
return StringTable.Localize("$SWWM_PLACE"..val);
}
private void DrawMinimap( int xx, int yy )
{
// experiment: use canvas
if ( swwm_mm_usecanvas )
{
if ( !mm_canvas ) mm_canvas = TexMan.GetCanvas("MMCANVAS");
if ( !mm_canvastex ) mm_canvastex = TexMan.CheckForTexture("MMCANVAS");
mm_canvas.Clear(0,0,HALFMAPSIZE*2,HALFMAPSIZE*2,mm_backcolor);
Vector2 basemappos = (HALFMAPSIZE,HALFMAPSIZE);
// draw dat stuff
DrawMapLines(basemappos,true);
DrawMapThings(basemappos,true);
DrawMapMarkers(basemappos,true);
// finally, draw the player arrow
Vector2 tv[] = {(0,-4),(-3,2),(3,2)};
for ( int i=0; i<3; i++ ) mm_canvas.DrawLine(int(tv[i].x+HALFMAPSIZE),int(tv[i].y+HALFMAPSIZE),int(tv[(i+1)%3].x+HALFMAPSIZE),int(tv[(i+1)%3].y+HALFMAPSIZE),mm_yourcolor);
// HACK: don't draw before the first refresh of the canvas
// there is a one-frame delay for its contents to get updated when drawing in the HUD
if ( (level.maptime > 1) && mm_cvfirstdraw )
Screen.DrawTexture(mm_canvastex,false,xx+2,yy+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
else Screen.Dim(mm_backcolor,1.,int((xx+2)*hs),int((yy+2)*hs),int(HALFMAPSIZE*2*hs),int(HALFMAPSIZE*2*hs));
mm_cvfirstdraw = true;
return;
}
mm_cvfirstdraw = false;
Vector2 basemappos = (xx+HALFMAPSIZE+2,yy+HALFMAPSIZE+2);
Screen.Dim(mm_backcolor,1.,int((basemappos.x-HALFMAPSIZE)*hs),int((basemappos.y-HALFMAPSIZE)*hs),int(HALFMAPSIZE*2*hs),int(HALFMAPSIZE*2*hs));
Screen.SetClipRect(int((basemappos.x-HALFMAPSIZE)*hs),int((basemappos.y-HALFMAPSIZE)*hs),int(HALFMAPSIZE*2*hs),int(HALFMAPSIZE*2*hs));
// draw dat stuff
DrawMapLines(basemappos*hs);
DrawMapThings(basemappos*hs);
DrawMapMarkers(basemappos*hs);
// finally, draw the player arrow
Vector2 tv[] = {(0,-4),(-3,2),(3,2)};
for ( int i=0; i<3; i++ ) tv[i] = (tv[i]+basemappos)*hs;
for ( int i=0; i<3; i++ ) Screen.DrawThickLine(int(tv[i].x),int(tv[i].y),int(tv[(i+1)%3].x),int(tv[(i+1)%3].y),max(1.,hs*.5),mm_yourcolor);
Screen.ClearClipRect();
}
private void DrawTopStuff()
{
int xx, yy = margin;
@ -795,21 +854,7 @@ extend Class SWWMStatusBar
GetMinimapColors();
xx = int(ss.x-(margin+(HALFMAPSIZE+2)*2));
Screen.DrawTexture(MiniBox,false,xx,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
Vector2 basemappos = (xx+HALFMAPSIZE+2,yy+HALFMAPSIZE+2);
Screen.Dim(mm_backcolor,1.,int((basemappos.x-HALFMAPSIZE)*hs),int((basemappos.y-HALFMAPSIZE)*hs),int(HALFMAPSIZE*2*hs),int(HALFMAPSIZE*2*hs));
Screen.SetClipRect(int((basemappos.x-HALFMAPSIZE)*hs),int((basemappos.y-HALFMAPSIZE)*hs),int(HALFMAPSIZE*2*hs),int(HALFMAPSIZE*2*hs));
// draw dat stuff
DrawMapLines(basemappos*hs);
DrawMapThings(basemappos*hs);
DrawMapMarkers(basemappos*hs);
// finally, draw the player arrow
Vector2 tv[3];
tv[0] = (0,-4);
tv[1] = (-3,2);
tv[2] = (3,2);
for ( int i=0; i<3; i++ ) tv[i] = (tv[i]+basemappos)*hs;
for ( int i=0; i<3; i++ ) Screen.DrawThickLine(int(tv[i].x),int(tv[i].y),int(tv[(i+1)%3].x),int(tv[(i+1)%3].y),max(1.,hs*.5),mm_yourcolor);
Screen.ClearClipRect();
DrawMinimap(xx,yy);
yy += ((HALFMAPSIZE+2)*2)+5;
}
// draw stats and timer when automap is open