void TileOverlay::Draw(Region viewport, std::vector< TileOverlay*> &overlays) { Video* vid = core->GetVideoDriver(); Region vp = vid->GetViewport(); // if the video's viewport is partially outside of the map, bump it back BumpViewport(viewport, vp); // determine which tiles are visible int sx = vp.x / 64; int sy = vp.y / 64; int dx = ( vp.x + vp.w + 63 ) / 64; int dy = ( vp.y + vp.h + 63 ) / 64; for (int y = sy; y < dy && y < h; y++) { for (int x = sx; x < dx && x < w; x++) { Tile* tile = tiles[( y* w ) + x]; //draw door tiles if there are any Animation* anim = tile->anim[tile->tileIndex]; if (!anim && tile->tileIndex) { anim = tile->anim[0]; } vid->BlitTile( anim->NextFrame(), 0, viewport.x + ( x * 64 ), viewport.y + ( y * 64 ), &viewport, false ); if (!tile->om || tile->tileIndex) { continue; } //draw overlay tiles, they should be half transparent int mask = 2; for (size_t z = 1;z<overlays.size();z++) { TileOverlay * ov = overlays[z]; if (ov && ov->count > 0) { Tile *ovtile = ov->tiles[0]; //allow only 1x1 tiles now if (tile->om & mask) { if (RedrawTile) { vid->BlitTile( ovtile->anim[0]->NextFrame(), tile->anim[0]->NextFrame(), viewport.x + ( x * 64 ), viewport.y + ( y * 64 ), &viewport, false ); } else { Sprite2D* mask = 0; if (tile->anim[1]) mask = tile->anim[1]->NextFrame(); vid->BlitTile( ovtile->anim[0]->NextFrame(), mask, viewport.x + ( x * 64 ), viewport.y + ( y * 64 ), &viewport, true ); } } } mask<<=1; } } } }
/** Draws the Control on the Output Display */ void MapControl::Draw(unsigned short XWin, unsigned short YWin) { if (!Width || !Height) { return; } if (Owner->Visible!=WINDOW_VISIBLE) { return; } if (Changed) { Realize(); Changed = false; } // we're going to paint over labels/etc, so they need to repaint! bool seen_this = false; unsigned int i; for (i = 0; i < Owner->GetControlCount(); i++) { Control *ctrl = Owner->GetControl(i); if (!ctrl) continue; // we could try working out which controls overlap, // but the later controls are cheap to paint.. if (ctrl == this) { seen_this = true; continue; } if (!seen_this) continue; ctrl->Changed = true; } Video* video = core->GetVideoDriver(); Region r( XWin + XPos, YWin + YPos, Width, Height ); if (MapMOS) { video->BlitSprite( MapMOS, MAP_TO_SCREENX(0), MAP_TO_SCREENY(0), true, &r ); } if (core->FogOfWar&FOG_DRAWFOG) DrawFog(XWin, YWin); Region vp = video->GetViewport(); vp.x = GAME_TO_SCREENX(vp.x); vp.y = GAME_TO_SCREENY(vp.y); vp.w = ViewWidth; vp.h = ViewHeight; if ((vp.x + vp.w) >= MAP_TO_SCREENX( Width )) vp.w = MAP_TO_SCREENX( Width ) - vp.x; if ((vp.y + vp.h) >= MAP_TO_SCREENY( Height )) vp.h = MAP_TO_SCREENY( Height ) - vp.y; video->DrawRect( vp, colors[green], false, false ); // Draw PCs' ellipses Game *game = core->GetGame(); i = game->GetPartySize(true); while (i--) { Actor* actor = game->GetPC( i, true ); if (MyMap->HasActor(actor) ) { video->DrawEllipse( (short) GAME_TO_SCREENX(actor->Pos.x), (short) GAME_TO_SCREENY(actor->Pos.y), 3, 2, actor->Selected ? colors[green] : colors[darkgreen], false ); } } // Draw Map notes, could be turned off in bg2 // we use the common control value to handle it, because then we // don't need another interface if (Value!=MAP_NO_NOTES) { i = MyMap -> GetMapNoteCount(); while (i--) { MapNote * mn = MyMap -> GetMapNote(i); Sprite2D *anim = Flag[mn->color&7]; Point pos = mn->Pos; if (convertToGame) { vp.x = GAME_TO_SCREENX(mn->Pos.x); vp.y = GAME_TO_SCREENY(mn->Pos.y); } else { //pst style vp.x = MAP_TO_SCREENX(mn->Pos.x); vp.y = MAP_TO_SCREENY(mn->Pos.y); pos.x = pos.x * MAP_MULT / MAP_DIV; pos.y = pos.y * MAP_MULT / MAP_DIV; } //Skip unexplored map notes bool visible = MyMap->IsVisible( pos, true ); if (!visible) continue; if (anim) { video->BlitSprite( anim, vp.x - anim->Width/2, vp.y - anim->Height/2, true, &r ); } else { video->DrawEllipse( (short) vp.x, (short) vp.y, 6, 5, colors[mn->color&7], false ); } } } }
void TileMap::DrawFogOfWar(ieByte* explored_mask, ieByte* visible_mask, Region viewport) { // viewport - pos & size of the control int w = XCellCount * CELL_RATIO; int h = YCellCount * CELL_RATIO; if (LargeMap) { w++; h++; } Color black = { 0, 0, 0, 255 }; Video* vid = core->GetVideoDriver(); Region vp = vid->GetViewport(); vp.w = viewport.w; vp.h = viewport.h; if (( vp.x + vp.w ) > w * CELL_SIZE) { vp.x = ( w * CELL_SIZE - vp.w ); } if (vp.x < 0) { vp.x = 0; } if (( vp.y + vp.h ) > h * CELL_SIZE) { vp.y = ( h * CELL_SIZE - vp.h ); } if (vp.y < 0) { vp.y = 0; } int sx = ( vp.x ) / CELL_SIZE; int sy = ( vp.y ) / CELL_SIZE; int dx = sx + vp.w / CELL_SIZE + 2; int dy = sy + vp.h / CELL_SIZE + 2; int x0 = sx * CELL_SIZE - vp.x; int y0 = sy * CELL_SIZE - vp.y; if (LargeMap) { x0 -= CELL_SIZE / 2; y0 -= CELL_SIZE / 2; dx++; dy++; } for (int y = sy; y < dy && y < h; y++) { for (int x = sx; x < dx && x < w; x++) { Region r = Region(x0 + viewport.x + ( (x - sx) * CELL_SIZE ), y0 + viewport.y + ( (y - sy) * CELL_SIZE ), CELL_SIZE, CELL_SIZE); if (! IS_EXPLORED( x, y )) { // Unexplored tiles are all black vid->DrawRect(r, black, true, true); continue; // Don't draw 'invisible' fog } else { // If an explored tile is adjacent to an // unexplored one, we draw border sprite // (gradient black <-> transparent) // Tiles in four cardinal directions have these // values. // // 1 // 2 8 // 4 // // Values of those unexplored are // added together, the resulting number being // an index of shadow sprite to use. For now, // some tiles are made 'on the fly' by // drawing two or more tiles int e = ! IS_EXPLORED( x, y - 1); if (! IS_EXPLORED( x - 1, y )) e |= 2; if (! IS_EXPLORED( x, y + 1 )) e |= 4; if (! IS_EXPLORED( x + 1, y )) e |= 8; switch (e) { case 1: case 2: case 3: case 4: case 6: case 8: case 9: case 12: FOG( e ); break; case 5: FOG( 1 ); FOG( 4 ); break; case 7: FOG( 3 ); FOG( 6 ); break; case 10: FOG( 2 ); FOG( 8 ); break; case 11: FOG( 3 ); FOG( 9 ); break; case 13: FOG( 9 ); FOG( 12 ); break; case 14: FOG( 6 ); FOG( 12 ); break; case 15: //this is black too vid->DrawRect(r, black, true, true); break; } } if (! IS_VISIBLE( x, y )) { // Invisible tiles are all gray FOG( 16 ); continue; // Don't draw 'invisible' fog } else { // If a visible tile is adjacent to an // invisible one, we draw border sprite // (gradient gray <-> transparent) // Tiles in four cardinal directions have these // values. // // 1 // 2 8 // 4 // // Values of those invisible are // added together, the resulting number being // an index of shadow sprite to use. For now, // some tiles are made 'on the fly' by // drawing two or more tiles int e = ! IS_VISIBLE( x, y - 1); if (! IS_VISIBLE( x - 1, y )) e |= 2; if (! IS_VISIBLE( x, y + 1 )) e |= 4; if (! IS_VISIBLE( x + 1, y )) e |= 8; switch (e) { case 1: case 2: case 3: case 4: case 6: case 8: case 9: case 12: FOG( 16 + e ); break; case 5: FOG( 16 + 1 ); FOG( 16 + 4 ); break; case 7: FOG( 16 + 3 ); FOG( 16 + 6 ); break; case 10: FOG( 16 + 2 ); FOG( 16 + 8 ); break; case 11: FOG( 16 + 3 ); FOG( 16 + 9 ); break; case 13: FOG( 16 + 9 ); FOG( 16 + 12 ); break; case 14: FOG( 16 + 6 ); FOG( 16 + 12 ); break; case 15: //this is unseen too FOG( 16 ); break; } } } } }