Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions code/fog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,11 @@ void Draw_Fogged_Objects(Rect const & rect)
return;
}

Rect cliprect = Intersect(rect, TacticalRect);
if (!cliprect.Is_Valid()) {
return;
}

for (int index = 0; index < FoggedObjectClass::FoggedObjectIndex.Count(); index++) {

FoggedObjectClass * data = FoggedObjectClass::FoggedObjectIndex.Fetch_By_Position(index);
Expand All @@ -303,7 +308,7 @@ void Draw_Fogged_Objects(Rect const & rect)
rectangle.Y = rectangle.Y - TacticalMap->TacPixelY + TacticalRect.Y;
rectangle.X += TacticalRect.X;

Rect clipped = Intersect(rect, rectangle);
Rect clipped = Intersect(cliprect, rectangle);
if (!clipped.Is_Valid()) {
continue;
}
Expand All @@ -327,8 +332,8 @@ void Draw_Fogged_Objects(Rect const & rect)
TacticalMap->Coord_To_Pixel(coord, point);
point.X += ISO_TILE_PIXEL_W / -2;

cellptr->Draw_Overlay(point, rect);
cellptr->Draw_Overlay_Shadow(point, rect);
cellptr->Draw_Overlay(point, cliprect);
cellptr->Draw_Overlay_Shadow(point, cliprect);

cellptr->Overlay = saveoverlay;
cellptr->OverlayData = saveoverlaydata;
Expand All @@ -347,18 +352,18 @@ void Draw_Fogged_Objects(Rect const & rect)

Point2D xy;
TacticalMap->Coord_To_Pixel((Coord)*position, xy);
xy += Point2D(TacticalRect.X - rect.X, TacticalRect.Y - rect.Y);
xy += Point2D(TacticalRect.X - cliprect.X, TacticalRect.Y - cliprect.Y);

int zadjust = -TacticalMap->Z_Lepton_To_Pixel(((Coord)*position).Z);

if (cellptr->Drawer == NULL) {
cellptr->Init_Drawer(NULL, 0x10000, 0, NORMAL_LIGHT, NORMAL_LIGHT, NORMAL_LIGHT);
}

Draw_Shape(*LogicalSurface, *cellptr->Drawer, shape, shapenum, xy, rect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zadjust - 4, ZGRAD_90DEG, cellptr->TileBrightness);
Draw_Shape(*LogicalSurface, *cellptr->Drawer, shape, shapenum, xy, cliprect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zadjust - 4, ZGRAD_90DEG, cellptr->TileBrightness);

if (DrawShapeShadows) {
Draw_Shape(*LogicalSurface, *cellptr->Drawer, shape, shapenum + shape->Get_Count() / 2, xy, rect, ShapeFlags_Type(SHAPE_DARKEN|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ZWRITE), NULL, zadjust - 2, ZGRAD_GROUND, NORMAL_LIGHT);
Draw_Shape(*LogicalSurface, *cellptr->Drawer, shape, shapenum + shape->Get_Count() / 2, xy, cliprect, ShapeFlags_Type(SHAPE_DARKEN|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ZWRITE), NULL, zadjust - 2, ZGRAD_GROUND, NORMAL_LIGHT);
}
break;
}
Expand All @@ -385,7 +390,7 @@ void Draw_Fogged_Objects(Rect const & rect)
Point2D drawpoint;
TacticalMap->Coord_To_Pixel(*position - Coord(CELL_LEPTON_W / 2, CELL_LEPTON_H / 2, 0), drawpoint);
CellClass * cellptr = &Map[(Coord)*position];
drawpoint += Point2D(TacticalRect.X - rect.X, TacticalRect.Y - rect.Y);
drawpoint += Point2D(TacticalRect.X - cliprect.X, TacticalRect.Y - cliprect.Y);

if (type->IsInvisibleInGame) {
break;
Expand All @@ -395,9 +400,9 @@ void Draw_Fogged_Objects(Rect const & rect)

Point2D shapepoint = drawpoint;
int height = drawpoint.Y + shape->Get_Height() / 2;
Rect cliprect = rect;
if (cliprect.Height > height) {
cliprect.Height = height;
Rect shapeclip = cliprect;
if (shapeclip.Height > height) {
shapeclip.Height = height;
}

Point2D zdrawpoint(144, 172);
Expand All @@ -413,23 +418,23 @@ void Draw_Fogged_Objects(Rect const & rect)
if (cellptr->Drawer == NULL) {
cellptr->Init_Drawer(NULL, 0x10000, 0, NORMAL_LIGHT, NORMAL_LIGHT, NORMAL_LIGHT);
}
ConvertClass * drawconvert = type->IsTerrainPalette ? (ConvertClass *)cellptr->Drawer : (ConvertClass *)cellptr;
ConvertClass * drawconvert = type->IsTerrainPalette ? cellptr->Drawer : converter;

if (cliprect.Height > 0) {
if (shapeclip.Height > 0) {
if (heightadjust) {
Draw_Shape(*LogicalSurface, *drawconvert, shape, shapenum, shapepoint, cliprect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zlepton - 2, ZGRAD_GROUND, brightness);
Draw_Shape(*LogicalSurface, *drawconvert, shape, shapenum + shape->Get_Count() / 2, shapepoint, cliprect, ShapeFlags_Type(SHAPE_DARKEN|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zlepton - 2, ZGRAD_GROUND, NORMAL_LIGHT);
Draw_Shape(*LogicalSurface, *drawconvert, shape, shapenum, shapepoint, shapeclip, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zlepton - 2, ZGRAD_GROUND, brightness);
Draw_Shape(*LogicalSurface, *drawconvert, shape, shapenum + shape->Get_Count() / 2, shapepoint, shapeclip, ShapeFlags_Type(SHAPE_DARKEN|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zlepton - 2, ZGRAD_GROUND, NORMAL_LIGHT);
} else {
Draw_Shape(*LogicalSurface, *drawconvert, shape, shapenum, shapepoint, cliprect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zlepton + zadjust - 2, ZGRAD_90DEG, brightness, zshapefile, 0, zdrawpoint);
Draw_Shape(*LogicalSurface, *drawconvert, shape, shapenum + shape->Get_Count() / 2, shapepoint, cliprect, ShapeFlags_Type(SHAPE_DARKEN|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zlepton - 2, ZGRAD_GROUND, NORMAL_LIGHT);
Draw_Shape(*LogicalSurface, *drawconvert, shape, shapenum, shapepoint, shapeclip, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zlepton + zadjust - 2, ZGRAD_90DEG, brightness, zshapefile, 0, zdrawpoint);
Draw_Shape(*LogicalSurface, *drawconvert, shape, shapenum + shape->Get_Count() / 2, shapepoint, shapeclip, ShapeFlags_Type(SHAPE_DARKEN|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zlepton - 2, ZGRAD_GROUND, NORMAL_LIGHT);
}
}

/*
* Draw the building's bib graphic.
*/
if (type->BibShape != NULL) {
Draw_Shape(*LogicalSurface, *drawconvert, type->BibShape, shapenum, drawpoint, rect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zlepton - 3, ZGRAD_GROUND, brightness);
Draw_Shape(*LogicalSurface, *drawconvert, type->BibShape, shapenum, drawpoint, cliprect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZWRITE), NULL, zlepton - 3, ZGRAD_GROUND, brightness);
}

} else {
Expand All @@ -446,7 +451,7 @@ void Draw_Fogged_Objects(Rect const & rect)
Coord * position = &data->Position;
Point2D drawpoint;
TacticalMap->Coord_To_Pixel(*position - Coord(CELL_LEPTON_W / 2, CELL_LEPTON_H / 2, 0), drawpoint);
drawpoint += Point2D(TacticalRect.X - rect.X, TacticalRect.Y - rect.Y);
drawpoint += Point2D(TacticalRect.X - cliprect.X, TacticalRect.Y - cliprect.Y);

int brightness = NORMAL_LIGHT;
if (!anim->IsUseNormalLight) {
Expand All @@ -463,9 +468,9 @@ void Draw_Fogged_Objects(Rect const & rect)
int zadjust = data->Records[record].ZAdjust;

if (anim->IsFlat) {
Draw_Shape(*LogicalSurface, *animconvert, shape, shapenum, drawpoint, rect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZGRAD), NULL, zadjust - TacticalMap->Z_Lepton_To_Pixel(((Coord)*position).Z) - 2, ZGRAD_GROUND, brightness);
Draw_Shape(*LogicalSurface, *animconvert, shape, shapenum, drawpoint, cliprect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZGRAD), NULL, zadjust - TacticalMap->Z_Lepton_To_Pixel(((Coord)*position).Z) - 2, ZGRAD_GROUND, brightness);
} else {
Draw_Shape(*LogicalSurface, *animconvert, shape, shapenum, drawpoint, rect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZGRAD), NULL, zadjust - TacticalMap->Z_Lepton_To_Pixel(((Coord)*position).Z) - 2, ZGRAD_90DEG, brightness);
Draw_Shape(*LogicalSurface, *animconvert, shape, shapenum, drawpoint, cliprect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA|SHAPE_ZGRAD), NULL, zadjust - TacticalMap->Z_Lepton_To_Pixel(((Coord)*position).Z) - 2, ZGRAD_90DEG, brightness);
}
}
}
Expand All @@ -477,14 +482,14 @@ void Draw_Fogged_Objects(Rect const & rect)
*/
case RTTI_SMUDGE: {
Point2D point;
point.X = data->BoundingRect.X - TacticalMap->TacPixelX + TacticalRect.X + ISO_TILE_PIXEL_W / 2 - rect.X;
point.Y = data->BoundingRect.Y - TacticalMap->TacPixelY + TacticalRect.Y - rect.Y;
point.X = data->BoundingRect.X - TacticalMap->TacPixelX + TacticalRect.X + ISO_TILE_PIXEL_W / 2 - cliprect.X;
point.Y = data->BoundingRect.Y - TacticalMap->TacPixelY + TacticalRect.Y - cliprect.Y;

ShapeSet const * shape = (ShapeSet const *)SmudgeTypes[data->Smudge]->Get_Image_Data();
if (shape != NULL) {
Coord * position = &data->Position;
CellClass * cellptr = &Map[(Coord)*position];
Draw_Shape(*LogicalSurface, *cellptr->Drawer, shape, data->SmudgeData, point, rect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA), NULL, -TacticalMap->Z_Lepton_To_Pixel(((Coord)*position).Z), ZGRAD_90DEG, cellptr->TileBrightness);
Draw_Shape(*LogicalSurface, *cellptr->Drawer, shape, data->SmudgeData, point, cliprect, ShapeFlags_Type(SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_ALPHA), NULL, -TacticalMap->Z_Lepton_To_Pixel(((Coord)*position).Z), ZGRAD_90DEG, cellptr->TileBrightness);
}
break;
}
Expand Down
21 changes: 21 additions & 0 deletions manual/changes/fogged-object-edge-redraw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: Keep fogged object redraws inside safe bounds
category: fix
release: 0.2.0
credit: [Krisztiaan]
targets:
- type: system
id: map-visibility
effect: changed
---
Comment thread
ZivDero marked this conversation as resolved.

Fogged structures, terrain, overlays and smudges are now clipped to the tactical view
when a cell at its edge asks to be redrawn. A cell's redraw area extends beyond its own
diamond, and one along the top, bottom or sides could therefore pass an out-of-frame
clipping window into the shape renderer. The renderer then addressed pixels outside the
frame and could stop the game while loading or playing a fog-of-war scenario.

Fogged buildings that use their owner's palette now also reuse that owner's color
converter, matching visible buildings. They previously treated the map cell as a color
converter, which could overwrite the cell with rendering state and stop the game during
a later terrain-overlay redraw.
Loading