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

@ -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