diff --git a/docs/rh-log.txt b/docs/rh-log.txt index fd50a226c..86d725d6a 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,16 @@ October 19, 2006 +- Added a new MapMarker actor. Instead of appearing in the 3D view, it appears + on the automap instead. If its first argument is zero, the map marker itself + appears on the automap, otherwise it is drawn on top of any actor with a TID + matching that argument. If the second argument is one, then the map marker + will only be appear if the player has previously seen the sector it is one. + You can use Thing_Activate and Thing_Deactivate on markers to turn them on + and off. And if you subclass MapMarker with DECORATE, you can easily make + your own custom markers. +- Fixed: Map markers could not be drawn partially off the map. They were + drawn either fully or not at all. +- Fixed: Map markers appeared in the wrong place on a rotated overlay map if + screenblocks < 10. - Added the MF2_PASSMOBJ for P_Thing_Spawn() from January 4, 2003, to DLevelScript::DoSpawn(). - Changed VectorNormalize() (and VectorNormalize2) to use doubles for storing diff --git a/src/actor.h b/src/actor.h index d5066de1b..02188d7d3 100644 --- a/src/actor.h +++ b/src/actor.h @@ -331,7 +331,9 @@ enum ERenderStyle STYLE_Translucent=64, // Draw translucent STYLE_Add, // Draw additive STYLE_Shaded, // Treat patch data as alpha values for alphacolor - STYLE_TranslucentStencil + STYLE_TranslucentStencil, + + STYLE_Count }; #define TRANSLUC25 (FRACUNIT/4) diff --git a/src/am_map.cpp b/src/am_map.cpp index 26de065bc..8d0804816 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -31,6 +31,8 @@ #include "p_local.h" #include "p_lnspec.h" #include "w_wad.h" +#include "a_sharedglobal.h" +#include "statnums.h" #include "m_cheat.h" #include "i_system.h" @@ -2098,31 +2100,100 @@ void AM_drawThings (int _color) } } +static void DrawMarker (FTexture *tex, fixed_t x, fixed_t y, int yadjust, + INTBOOL flip, int xscale, int yscale, int translation, fixed_t alpha, DWORD alphacolor, int renderstyle) +{ + if (tex == NULL || tex->UseType == FTexture::TEX_Null) + { + return; + } + if (am_rotate == 1 || (am_rotate == 2 && viewactive)) + { + AM_rotatePoint (&x, &y); + } + screen->DrawTexture (tex, CXMTOF(x) + f_x, CYMTOF(y) + yadjust + f_y, + DTA_DestWidth, MulScale6 (tex->GetScaledWidth() * CleanXfac, xscale), + DTA_DestHeight, MulScale6 (tex->GetScaledHeight() * CleanYfac, yscale), + DTA_ClipTop, f_y, + DTA_ClipBottom, f_y + f_h, + DTA_ClipLeft, f_x, + DTA_ClipRight, f_x + f_w, + DTA_FlipX, flip, + DTA_Translation, translation != 0 ? translationtables[(translation&0xff00)>>8] + (translation&0x00ff)*256 : NULL, + DTA_Alpha, alpha, + DTA_FillColor, alphacolor, + DTA_RenderStyle, renderstyle, + TAG_DONE); +} + void AM_drawMarks () { - int i, fx, fy, w, h; - mpoint_t pt; - - for (i = 0; i < AM_NUMMARKPOINTS; i++) + for (int i = 0; i < AM_NUMMARKPOINTS; i++) { if (markpoints[i].x != -1) { - // w = TileSizes[i].width; - // h = TileSizes[i].height; - w = 5; // because something's wrong with the wad, i guess - h = 6; // because something's wrong with the wad, i guess + DrawMarker (TexMan(marknums[i]), markpoints[i].x, markpoints[i].y, -3, 0, 64, 64, 0, FRACUNIT, 0, STYLE_Normal); + } + } +} - pt.x = markpoints[i].x; - pt.y = markpoints[i].y; +void AM_drawAuthorMarkers () +{ + // [RH] Draw any actors derived from AMapMarker on the automap. + // If args[0] is 0, then the actor's sprite is drawn at its own location. + // Otherwise, its sprite is drawn at the location of any actors whose TIDs match args[0]. + TThinkerIterator it (STAT_MAPMARKER); + AMapMarker *mark; - if (am_rotate == 1 || (am_rotate == 2 && viewactive)) - AM_rotatePoint (&pt.x, &pt.y); + while ((mark = it.Next()) != NULL) + { + if (mark->flags2 & MF2_DORMANT) + { + continue; + } - fx = CXMTOF(pt.x); - fy = CYMTOF(pt.y) - 3; + int picnum; + FTexture *tex; + WORD flip = 0; - if (fx >= f_x && fx <= f_w - w && fy >= f_y && fy <= f_h - h && marknums[i] != -1) - screen->DrawTexture (TexMan(marknums[i]), fx, fy, DTA_CleanNoMove, true, TAG_DONE); + if (mark->picnum != 0xFFFF) + { + tex = TexMan(mark->picnum); + if (tex->Rotations != 0xFFFF) + { + spriteframe_t *sprframe = &SpriteFrames[tex->Rotations]; + picnum = sprframe->Texture[0]; + flip = sprframe->Flip & 1; + tex = TexMan[picnum]; + } + } + else + { + spritedef_t *sprdef = &sprites[mark->sprite]; + if (mark->frame >= sprdef->numframes) + { + continue; + } + else + { + spriteframe_t *sprframe = &SpriteFrames[sprdef->spriteframes + mark->frame]; + picnum = sprframe->Texture[0]; + flip = sprframe->Flip & 1; + tex = TexMan[picnum]; + } + } + FActorIterator it (mark->args[0]); + AActor *marked = mark->args[0] == 0 ? mark : it.Next(); + + while (marked != NULL) + { + if (mark->args[1] == 0 || (mark->args[1] == 1 && marked->Sector->MoreFlags & SECF_DRAWN)) + { + DrawMarker (tex, marked->x >> FRACTOMAPBITS, marked->y >> FRACTOMAPBITS, 0, + flip, mark->xscale+1, mark->yscale+1, mark->Translation, + mark->alpha, mark->alphacolor, mark->RenderStyle); + } + marked = mark->args[0] != 0 ? it.Next() : NULL; } } } @@ -2177,6 +2248,7 @@ void AM_Drawer () AM_drawPlayers(); if (am_cheat >= 2 || allthings) AM_drawThings(ThingColor); + AM_drawAuthorMarkers(); if (!viewactive) AM_drawCrosshair(XHairColor); diff --git a/src/g_shared/a_mapmarker.cpp b/src/g_shared/a_mapmarker.cpp new file mode 100644 index 000000000..fee38520a --- /dev/null +++ b/src/g_shared/a_mapmarker.cpp @@ -0,0 +1,80 @@ +/* +** a_mapmarker.cpp +** An actor that appears on the automap instead of in the 3D view. +** +**--------------------------------------------------------------------------- +** Copyright 2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "a_sharedglobal.h" +#include "statnums.h" + +// Map Marker -------------------------------------------------------------- +// +// This class uses the following argument: +// args[0] == 0, shows the sprite at this actor +// != 0, shows the sprite for all actors whose TIDs match instead +// +// args[1] == 0, show the sprite always +// == 1, show the sprite only after its sector has been drawn +// +// To enable display of the sprite, activate it. To turn off the sprite, +// deactivate it. +// +// All the code to display it is in am_map.cpp. +// +//-------------------------------------------------------------------------- + +FState AMapMarker::States[] = +{ + S_NORMAL (AMRK, 'A', -1, NULL, NULL) +}; + +IMPLEMENT_ACTOR(AMapMarker, Any, 9040, 0) + PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY) + PROP_RenderFlags (RF_INVISIBLE) + PROP_SpawnState (0) + PROP_XScale (31) + PROP_YScale (31) +END_DEFAULTS + +void AMapMarker::BeginPlay () +{ + ChangeStatNum (STAT_MAPMARKER); +} + +void AMapMarker::Activate (AActor *activator) +{ + flags2 |= MF2_DORMANT; +} + +void AMapMarker::Deactivate (AActor *activator) +{ + flags2 &= ~MF2_DORMANT; +} diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 67d5dd4ff..30190dda1 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -229,4 +229,13 @@ public: DWORD FlagsSave; }; +class AMapMarker : public AActor +{ + DECLARE_ACTOR(AMapMarker, AActor) +public: + void BeginPlay (); + void Activate (AActor *activator); + void Deactivate (AActor *activator); +}; + #endif //__A_SHAREDGLOBAL_H__ diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 3f53b8cb3..2cbc77d5f 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -1041,7 +1041,7 @@ void FBaseStatusBar::DrawCrosshair () DTA_DestWidth, w, DTA_DestHeight, h, DTA_AlphaChannel, true, - DTA_FillColor, palettecolor, + DTA_FillColor, (palettecolor << 24) | (color & 0xFFFFFF), TAG_DONE); } diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 9d5ad0c21..e751666fd 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -1052,6 +1052,7 @@ void R_Subsector (subsector_t *sub) #endif frontsector = sub->sector; + frontsector->MoreFlags |= SECF_DRAWN; count = sub->numlines; line = &segs[sub->firstline]; diff --git a/src/r_defs.h b/src/r_defs.h index 466794123..908475516 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -227,7 +227,8 @@ enum SECF_IGNOREHEIGHTSEC= 16, // heightsec is only for triggering sector actions SECF_UNDERWATER = 32, // sector is underwater SECF_FORCEDUNDERWATER= 64, // sector is forced to be underwater - SECF_UNDERWATERMASK = 32+64 + SECF_UNDERWATERMASK = 32+64, + SECF_DRAWN = 128, // sector has been drawn at least once }; struct FDynamicColormap; diff --git a/src/r_things.cpp b/src/r_things.cpp index 1ac898969..b655155f2 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1236,26 +1236,23 @@ void R_ProjectSprite (AActor *thing, int fakeside) } flip = 0; - if (thing->picnum != 0xFFFF) + if (tex->Rotations != 0xFFFF) { - if (tex->Rotations != 0xFFFF) + // choose a different rotation based on player view + spriteframe_t *sprframe = &SpriteFrames[tex->Rotations]; + angle_t ang = R_PointToAngle (fx, fy); + angle_t rot; + if (sprframe->Texture[0] == sprframe->Texture[1]) { - // choose a different rotation based on player view - spriteframe_t *sprframe = &SpriteFrames[tex->Rotations]; - angle_t ang = R_PointToAngle (fx, fy); - angle_t rot; - if (sprframe->Texture[0] == sprframe->Texture[1]) - { - rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9) >> 28; - } - else - { - rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; - } - picnum = sprframe->Texture[rot]; - flip = sprframe->Flip & (1 << rot); - tex = TexMan[picnum]; // Do not animate the rotation + rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9) >> 28; } + else + { + rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; + } + picnum = sprframe->Texture[rot]; + flip = sprframe->Flip & (1 << rot); + tex = TexMan[picnum]; // Do not animate the rotation } } else diff --git a/src/statnums.h b/src/statnums.h index b42d52cc1..fd6831dc8 100644 --- a/src/statnums.h +++ b/src/statnums.h @@ -55,4 +55,5 @@ enum STAT_LIGHT, // A sector light effect STAT_LIGHTTRANSFER, // A sector light transfer. These must be ticked after the light effects!!! STAT_EARTHQUAKE, // Earthquake actors + STAT_MAPMARKER, // Map marker actors }; diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 4f9035a41..0dd7f613a 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -94,6 +94,7 @@ void STACK_ARGS DCanvas::DrawTexture (FTexture *img, int x0, int y0, DWORD tags_ int virtWidth = this->GetWidth(); int virtHeight = this->GetHeight(); INTBOOL keepratio = false; + ERenderStyle style = STYLE_Count; x0 <<= FRACBITS; y0 <<= FRACBITS; @@ -322,6 +323,10 @@ void STACK_ARGS DCanvas::DrawTexture (FTexture *img, int x0, int y0, DWORD tags_ case DTA_KeepRatio: keepratio = va_arg (tags, INTBOOL); break; + + case DTA_RenderStyle: + style = ERenderStyle(va_arg (tags, int)); + break; } tag = va_arg (tags, DWORD); } @@ -354,34 +359,35 @@ void STACK_ARGS DCanvas::DrawTexture (FTexture *img, int x0, int y0, DWORD tags_ return; } - ERenderStyle style; - - if (fillcolor >= 0) + if (style == STYLE_Count) { - if (alphaChannel) + if (fillcolor != -1) { - style = STYLE_Shaded; + if (alphaChannel) + { + style = STYLE_Shaded; + } + else if (alpha < FRACUNIT) + { + style = STYLE_TranslucentStencil; + } + else + { + style = STYLE_Stencil; + } } else if (alpha < FRACUNIT) { - style = STYLE_TranslucentStencil; + style = STYLE_Translucent; } else { - style = STYLE_Stencil; + style = STYLE_Normal; } } - else if (alpha < FRACUNIT) - { - style = STYLE_Translucent; - } - else - { - style = STYLE_Normal; - } fixedcolormap = identitymap; - ESPSResult mode = R_SetPatchStyle (style, alpha, 0, fillcolor<<24); + ESPSResult mode = R_SetPatchStyle (style, alpha, 0, fillcolor); if (style != STYLE_Shaded) { diff --git a/src/v_video.h b/src/v_video.h index 660b3087d..3dc1e9c08 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -101,6 +101,7 @@ enum DTA_HUDRules, // use fullscreen HUD rules to position and size textures DTA_KeepRatio, // doesn't adjust screen size for DTA_Virtual* if the aspect ratio is not 4:3 DTA_TextLen, // for DrawText: stop after this many characters, even if \0 not hit + DTA_RenderStyle, // same as render style for actors }; enum diff --git a/wadsrc/amrka0.png b/wadsrc/amrka0.png new file mode 100644 index 000000000..c95d00afe Binary files /dev/null and b/wadsrc/amrka0.png differ diff --git a/wadsrc/zdoom.lst b/wadsrc/zdoom.lst index 498bc831d..fbbf01ddc 100644 --- a/wadsrc/zdoom.lst +++ b/wadsrc/zdoom.lst @@ -134,6 +134,7 @@ sprites/iceca0.png iceca0.png sprites/icecb0.png icecb0.png sprites/icecc0.png icecc0.png sprites/icecd0.png icecd0.png +sprites/amrka0.png amrka0.png # crouching DoomPlayer sprites/plyca1.lmp crouch/plyca1.lmp diff --git a/zdoom.vcproj b/zdoom.vcproj index 19d3ac1b0..726a1870e 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -5758,6 +5758,10 @@ RelativePath=".\src\g_shared\a_lightning.h" > + +