From 96a34c30f071b93b51e695a051635231193dc35a Mon Sep 17 00:00:00 2001 From: Frank Zago Date: Sun, 14 Jun 2009 07:02:06 +0000 Subject: [PATCH] Center active hero on map. Added map grid. Fixed a visual artefact. --- client/CAdvmapInterface.cpp | 41 ++-- client/CPlayerInterface.cpp | 16 +- mapHandler.cpp | 474 +++++++++++++++++++++--------------- mapHandler.h | 27 +- 4 files changed, 321 insertions(+), 237 deletions(-) diff --git a/client/CAdvmapInterface.cpp b/client/CAdvmapInterface.cpp index 1d7777867..8ca43fe7e 100644 --- a/client/CAdvmapInterface.cpp +++ b/client/CAdvmapInterface.cpp @@ -608,8 +608,9 @@ void CTerrainRect::showPath(const SDL_Rect * extRect) int pn=-1;//number of picture if (i==0) //last tile { - int x = 32*(currentPath->nodes[i].coord.x-LOCPLINT->adventureInt->position.x)+7, - y = 32*(currentPath->nodes[i].coord.y-LOCPLINT->adventureInt->position.y)+6; + // TODO: use right variable instead of (7,6). Twice in this function. + int x = 32*(currentPath->nodes[i].coord.x-LOCPLINT->adventureInt->position.x)+CGI->mh->offsetX + 7, + y = 32*(currentPath->nodes[i].coord.y-LOCPLINT->adventureInt->position.y)+CGI->mh->offsetY + 6; if (x<0 || y<0 || x>pos.w || y>pos.h) continue; pn=0; @@ -870,8 +871,8 @@ void CTerrainRect::showPath(const SDL_Rect * extRect) pn+=25; if (pn>=0) { - int x = 32*(currentPath->nodes[i].coord.x-LOCPLINT->adventureInt->position.x)+7, - y = 32*(currentPath->nodes[i].coord.y-LOCPLINT->adventureInt->position.y)+6; + int x = 32*(currentPath->nodes[i].coord.x-LOCPLINT->adventureInt->position.x)+CGI->mh->offsetX + 7, + y = 32*(currentPath->nodes[i].coord.y-LOCPLINT->adventureInt->position.y)+CGI->mh->offsetY + 6; if (x<0 || y<0 || x>pos.w || y>pos.h) continue; int hvx = (x+arrows->ourImages[pn].bitmap->w)-(pos.x+pos.w), @@ -939,11 +940,9 @@ void CTerrainRect::showPath(const SDL_Rect * extRect) void CTerrainRect::show(SDL_Surface * to) { CGI->mh->terrainRect - (LOCPLINT->adventureInt->position.x,LOCPLINT->adventureInt->position.y, - tilesw,tilesh,LOCPLINT->adventureInt->position.z,LOCPLINT->adventureInt->anim, - &LOCPLINT->cb->getVisibilityMap(), true, LOCPLINT->adventureInt->heroAnim, - to, &genRect(pos.h, pos.w, pos.x, pos.y), moveX, moveY, ADVOPT.smoothMove && (moveX != 0 || moveY != 0) - ); + (LOCPLINT->adventureInt->position, LOCPLINT->adventureInt->anim, + &LOCPLINT->cb->getVisibilityMap(), true, LOCPLINT->adventureInt->heroAnim, + to, &genRect(pos.h, pos.w, pos.x, pos.y), moveX, moveY); //SDL_BlitSurface(teren,&genRect(pos.h,pos.w,0,0),screen,&genRect(547,594,7,6)); //SDL_FreeSurface(teren); @@ -956,8 +955,8 @@ void CTerrainRect::show(SDL_Surface * to) int3 CTerrainRect::whichTileIsIt(const int & x, const int & y) { int3 ret; - ret.x = LOCPLINT->adventureInt->position.x + ((LOCPLINT->current->motion.x-pos.x)/32); - ret.y = LOCPLINT->adventureInt->position.y + ((LOCPLINT->current->motion.y-pos.y)/32); + ret.x = LOCPLINT->adventureInt->position.x + ((LOCPLINT->current->motion.x-CGI->mh->offsetX-pos.x)/32); + ret.y = LOCPLINT->adventureInt->position.y + ((LOCPLINT->current->motion.y-CGI->mh->offsetY-pos.y)/32); ret.z = LOCPLINT->adventureInt->position.z; return ret; } @@ -1461,16 +1460,16 @@ void CAdvMapInt::show(SDL_Surface *to) || SDL_GetKeyState(NULL)[SDLK_RCTRL] ) { - if( (scrollingDir & LEFT) && (position.x>-CGI->mh->frame.left) ) + if( (scrollingDir & LEFT) && (position.x>-CGI->mh->frameW) ) position.x--; - if( (scrollingDir & RIGHT) && (position.x < CGI->mh->map->width - terrain.tilesw + CGI->mh->frame.right) ) + if( (scrollingDir & RIGHT) && (position.x < CGI->mh->map->width - CGI->mh->tilesW + CGI->mh->frameW) ) position.x++; - if( (scrollingDir & UP) && (position.y>-CGI->mh->frame.top) ) + if( (scrollingDir & UP) && (position.y>-CGI->mh->frameH) ) position.y--; - if( (scrollingDir & DOWN) && (position.y < CGI->mh->map->height - terrain.tilesh + CGI->mh->frame.bottom) ) + if( (scrollingDir & DOWN) && (position.y < CGI->mh->map->height - CGI->mh->tilesH + CGI->mh->frameH) ) position.y++; if(scrollingDir) @@ -1501,14 +1500,16 @@ void CAdvMapInt::selectionChanged() } void CAdvMapInt::centerOn(int3 on) { - on.x -= (LOCPLINT->adventureInt->terrain.tilesw/2); - on.y -= (LOCPLINT->adventureInt->terrain.tilesh/2); + // TODO:convertPosition should not belong to CGHeroInstance, and it + // should be split in 2 methods. + on = CGHeroInstance::convertPosition(on, false); + on.x -= CGI->mh->frameW; + on.y -= CGI->mh->frameH; + on = LOCPLINT->repairScreenPos(on); - LOCPLINT->adventureInt->position.x=on.x; - LOCPLINT->adventureInt->position.y=on.y; - LOCPLINT->adventureInt->position.z=on.z; + LOCPLINT->adventureInt->position = on; LOCPLINT->adventureInt->updateScreen=true; updateMinimap=true; } diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 9baa93f53..d56ca2e45 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1024,14 +1024,14 @@ void CPlayerInterface::handleEvent(SDL_Event *sEvent) int3 CPlayerInterface::repairScreenPos(int3 pos) { - if(pos.x<=-CGI->mh->frame.left) - pos.x = -CGI->mh->frame.left+1; - if(pos.y<=-CGI->mh->frame.top) - pos.y = -CGI->mh->frame.top+1; - if(pos.x>CGI->mh->map->width - this->adventureInt->terrain.tilesw + CGI->mh->frame.right) - pos.x = CGI->mh->map->width - this->adventureInt->terrain.tilesw + CGI->mh->frame.right; - if(pos.y>CGI->mh->map->height - this->adventureInt->terrain.tilesh + CGI->mh->frame.bottom) - pos.y = CGI->mh->map->height - this->adventureInt->terrain.tilesh + CGI->mh->frame.bottom; + if(pos.x<-CGI->mh->frameW) + pos.x = -CGI->mh->frameW; + if(pos.y<-CGI->mh->frameH) + pos.y = -CGI->mh->frameH; + if(pos.x>CGI->mh->map->width - this->adventureInt->terrain.tilesw + CGI->mh->frameW) + pos.x = CGI->mh->map->width - this->adventureInt->terrain.tilesw + CGI->mh->frameW; + if(pos.y>CGI->mh->map->height - this->adventureInt->terrain.tilesh + CGI->mh->frameH) + pos.y = CGI->mh->map->height - this->adventureInt->terrain.tilesh + CGI->mh->frameH; return pos; } void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) diff --git a/mapHandler.cpp b/mapHandler.cpp index 305f7873c..47525c25c 100644 --- a/mapHandler.cpp +++ b/mapHandler.cpp @@ -207,14 +207,14 @@ void CMapHandler::roadsRiverTerrainInit() sizes.z = CGI->mh->map->twoLevel+1; // Create enough room for the whole map and its frame - ttiles.resize(CGI->mh->map->width, frame.left, frame.right); - for (int i=0-frame.left;imh->map->width, frameW, frameW); + for (int i=0-frameW;imh->map->height, frame.top, frame.bottom); + ttiles[i].resize(CGI->mh->map->height, frameH, frameH); } - for (int i=0-frame.left;imh->map->height+frame.bottom;j++) + for (int j=0-frameH;j<(int)CGI->mh->map->height+frameH;j++) ttiles[i][j].resize(CGI->mh->map->twoLevel+1, 0, 0); } @@ -315,9 +315,9 @@ void CMapHandler::borderAndTerrainBitmapInit() delete hlp; } - for (int i=0-frame.left; iwidth+frame.right; i++) //jest po szeroko�ci + for (int i=0-frameW; iwidth+frameW; i++) //jest po szeroko�ci { - for (int j=0-frame.top; jheight+frame.bottom;j++) //po wysoko�ci + for (int j=0-frameH; jheight+frameH;j++) //po wysoko�ci { for(int k=0; k<=map->twoLevel; ++k) { @@ -402,9 +402,9 @@ void CMapHandler::initObjectRects() std::pair toAdd = std::make_pair(map->objects[f],cr); if( (map->objects[f]->pos.x + fx - bitmap->w/32+1) >= 0 - && (map->objects[f]->pos.x + fx - bitmap->w/32+1) < ttiles.size() - frame.right + && (map->objects[f]->pos.x + fx - bitmap->w/32+1) < ttiles.size() - frameW && (map->objects[f]->pos.y + fy - bitmap->h/32+1) >= 0 - && (map->objects[f]->pos.y + fy - bitmap->h/32+1) < ttiles[0].size() - frame.bottom + && (map->objects[f]->pos.y + fy - bitmap->h/32+1) < ttiles[0].size() - frameH ) { //TerrainTile2 & curt = @@ -418,9 +418,9 @@ void CMapHandler::initObjectRects() } //for(int fx=0; fxw/32; ++fx) }//if curd } // for(int f=0; fobjects.size(); ++f) - for(int ix=0; ixac.tilesW * 32 - conf.go()->ac.advmapTrimX; + mapH = conf.go()->ac.tilesH * 32 - conf.go()->ac.advmapTrimY; + + // Total number of visible tiles. Substract the center tile, then + // compute the number of tiles on each side, and reassemble. + int t1, t2; + t1 = (mapW-32)/2; + t2 = mapW - 32 - t1; + tilesW = 1 + (t1+31)/32 + (t2+31)/32; + + t1 = (mapH-32)/2; + t2 = mapH - 32 - t1; + tilesH = 1 + (t1+31)/32 + (t2+31)/32; + // Size of the frame around the map. In extremes positions, the // frame must not be on the center of the map, but right on the - // edge of the center tile. Consequently, frame.left + 1 + - // frame.right = size of the window map on the screen. Same for - // top/bottom. And the sizes will be different on opposite sides - // if the length of the window map is even. - frame.left = (conf.go()->ac.tilesW-1) / 2; - frame.right = (conf.go()->ac.tilesW) / 2; - frame.top = (conf.go()->ac.tilesH-1) / 2; - frame.bottom = (conf.go()->ac.tilesH) / 2; + // edge of the center tile. + frameW = (mapW+31) /32 / 2; + frameH = (mapH+31) /32 / 2; + + offsetX = (mapW - (2*frameW+1)*32)/2; + offsetY = (mapH - (2*frameH+1)*32)/2; std::ifstream ifs("config/townsDefs.txt"); int ccc; @@ -543,162 +558,175 @@ void CMapHandler::init() tlog0<<"\tMaking object rects: "< > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, SDL_Rect * extRect, int moveX, int moveY, bool smooth) +// Update map window screen +// top_tile top left tile to draw. Not necessarily visible. +// extRect, extRect = map window on screen +// moveX, moveY: when a hero is in movement indicates how to shift the map. Range is -31 to + 31. +void CMapHandler::terrainRect(int3 top_tile, unsigned char anim, std::vector< std::vector< std::vector > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, SDL_Rect * extRect, int moveX, int moveY) { - int srx, sry; + // Width and height of the portion of the map to process. Units in tiles. + unsigned int dx = tilesW; + unsigned int dy = tilesH; - // Temporarily disable smoothing as it is source of crashes - smooth = false; + // Basic rectangle for a tile. Should be a const but conflicts with SDL headers + SDL_Rect rtile = { 0, 0, 32, 32 }; + + // Absolute coords of the first pixel in the top left corner + int srx_init = offsetX + extRect->x; + int sry_init = offsetY + extRect->y; + int srx, sry; // absolute screen coordinates in pixels + + // If moving, we need to add an extra column/line + if (moveX != 0) { + dx++; + srx_init += moveX; + if (moveX < 0) { + // Moving left, so adjust our referential + top_tile.x --; + srx_init -= 32; + } + } + + if (moveY != 0) { + dy++; + sry_init += moveY; + if (moveY < 0) { + // Moving up, so adjust our referential + top_tile.y --; + sry_init -= 32; + } + } + + // Reduce sizes if we go out of the full map. + if (top_tile.x < -frameW) + top_tile.x = -frameW; + if (top_tile.y < -frameH) + top_tile.y = -frameH; + if (top_tile.x + dx > map->width + frameW) + dx = map->width + frameW - top_tile.x; + if (top_tile.y + dy > map->height + frameH) + dy = map->height + frameH - top_tile.y; + if(!otherHeroAnim) heroAnim = anim; //the same, as it should be - //setting surface to blit at - SDL_Surface * su = NULL; //blitting surface CSDL_Ext::newSurface(dx*32, dy*32, CSDL_Ext::std32bppSurface); - if(extSurf) - { - su = extSurf; - } - else - { - su = CSDL_Ext::newSurface(dx*32, dy*32, CSDL_Ext::std32bppSurface); - } + SDL_Rect prevClip; - SDL_GetClipRect(su, &prevClip); - if(extRect) SDL_SetClipRect(su, extRect); //preventing blitting outside of that rect + SDL_GetClipRect(extSurf, &prevClip); + SDL_SetClipRect(extSurf, extRect); //preventing blitting outside of that rect - dx += smooth?1:0; - dy += smooth?1:0; + // Temp surface for rotating tile and then properly blit. The + // problem is that blitWithRotate1clip & co do not respect the + // previous SDL_SetClipRect. + // TODO: optimize by pre-rotating those surfaces + SDL_Surface *rSurf = CSDL_Ext::newSurface(32, 32, extSurf); - // Sanity check - TODO: fails if smooth mode - if (dx+x > map->width+frame.right || - dy+y > map->height+frame.bottom || - x<-frame.left || - y<-frame.right) - throw std::string("terrainRect: out of range"); + // printing terrain + srx = srx_init; - ////printing terrain - srx = (moveX <= 0 ? 0 : -1) * 32; - if (smooth) - srx += moveX + extRect->x; - - for (int bx= (moveX <= 0 ? 0 : -1); bxy; + // Skip column if not in map + if (top_tile.x+bx < 0 || top_tile.x+bx >= map->width) + continue; - for (int by=(moveY <= 0 ? 0 : -1); by= map->height) + continue; + + const TerrainTile2 & tile = ttiles[top_tile.x+bx][top_tile.y+by][top_tile.z]; SDL_Rect sr; sr.x=srx; sr.y=sry; sr.h=sr.w=32; - if (!smooth) - validateRectTerr(&sr, extRect); - if(tile.terbitmap) { - SDL_BlitSurface(tile.terbitmap, &genRect(sr.h, sr.w, 0, 0), su, &sr); + SDL_BlitSurface(tile.terbitmap, &genRect(sr.h, sr.w, 0, 0), extSurf, &sr); } else { - if(smooth) + switch(tile.tileInfo->siodmyTajemniczyBajt%4) { - switch(tile.tileInfo->siodmyTajemniczyBajt%4) - { - case 0: - SDL_BlitSurface(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], - &genRect(sr.h, sr.w, 0, 0),su,&sr); - break; - case 1: - CSDL_Ext::blitWithRotate1clip(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], - &genRect(sr.h, sr.w, 0, 0),su,&sr); - break; - case 2: - CSDL_Ext::blitWithRotate2clip(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], - &genRect(sr.h, sr.w, 0, 0),su,&sr); - break; - default: - CSDL_Ext::blitWithRotate3clip(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], - &genRect(sr.h, sr.w, 0, 0),su,&sr); - break; - } - } - else - { - switch(tile.tileInfo->siodmyTajemniczyBajt%4) - { - case 0: - SDL_BlitSurface(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], - &genRect(sr.h, sr.w, 0, 0),su,&sr); - break; - case 1: - CSDL_Ext::blitWithRotate1(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], - &genRect(sr.h, sr.w, 0, 0),su,&sr); - break; - case 2: - CSDL_Ext::blitWithRotate2(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], - &genRect(sr.h, sr.w, 0, 0),su,&sr); - break; - default: - CSDL_Ext::blitWithRotate3(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], - &genRect(sr.h, sr.w, 0, 0),su,&sr); - break; - } + case 0: + SDL_BlitSurface(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], + &rtile, extSurf, &sr); + break; + + case 1: + CSDL_Ext::blitWithRotate1clip(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], + &rtile, rSurf, &rtile); + SDL_BlitSurface(rSurf, &rtile, extSurf, &sr); + break; + + case 2: + CSDL_Ext::blitWithRotate2clip(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], + &rtile, rSurf, &rtile); + SDL_BlitSurface(rSurf, &rtile, extSurf, &sr); + break; + default: + CSDL_Ext::blitWithRotate3clip(terrainGraphics[tile.tileInfo->tertype][tile.tileInfo->terview], + &rtile, rSurf, &rtile); + SDL_BlitSurface(rSurf, &rtile, extSurf, &sr); + break; } } } } - ////terrain printed + // terrain printed - ////printing rivers - srx = (moveX <= 0 ? 0 : -1) * 32; - if (smooth) - srx += moveX + extRect->x; + // printing rivers + srx = srx_init; - for (int bx= (moveX <= 0 ? 0 : -1); bxy; + // Skip column if not in map + if (top_tile.x+bx < 0 || top_tile.x+bx >= map->width) + continue; - for (int by=(moveY <= 0 ? 0 : -1); by= map->height) + continue; + SDL_Rect sr; sr.x=srx; sr.y=sry; sr.h=sr.w=32; - if (!smooth) - validateRectTerr(&sr, extRect); - - const std::vector &rivbitmap = ttiles[x+bx][y+by][level].rivbitmap; + const std::vector &rivbitmap = ttiles[top_tile.x+bx][top_tile.y+by][top_tile.z].rivbitmap; if(rivbitmap.size()) { - CSDL_Ext::blit8bppAlphaTo24bpp(rivbitmap[anim%rivbitmap.size()],&genRect(sr.h, sr.w, 0, 0),su,&sr); + CSDL_Ext::blit8bppAlphaTo24bpp(rivbitmap[anim%rivbitmap.size()],&genRect(sr.h, sr.w, 0, 0),extSurf,&sr); } } } - ////rivers printed + // rivers printed - ////printing roads - srx = (moveX <= 0 ? 0 : -1) * 32; - if (smooth) - srx += moveX + extRect->x; + // printing roads + srx = srx_init; - for (int bx= (moveX <= 0 ? 0 : -1); bxy; + // Skip column if not in map + if (top_tile.x+bx < 0 || top_tile.x+bx >= map->width) + continue; - for (int by=(moveY <= 0 ? 0 : -1) - 1; by= map->height) continue; SDL_Rect sr; @@ -707,32 +735,36 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level, sr.y = sry; sr.h=sr.w=32; - if (!smooth) - validateRectTerr(&sr, extRect); - - const std::vector &roadbitmap = ttiles[x+bx][y+by][level].roadbitmap; + const std::vector &roadbitmap = ttiles[top_tile.x+bx][top_tile.y+by][top_tile.z].roadbitmap; if(roadbitmap.size()) { - CSDL_Ext::blit8bppAlphaTo24bpp(roadbitmap[anim%roadbitmap.size()], &genRect(sr.h, sr.w, 0, (by==-1 && moveY == 0 ? 16 : 0)),su,&sr); + CSDL_Ext::blit8bppAlphaTo24bpp(roadbitmap[anim%roadbitmap.size()], &genRect(sr.h, sr.w, 0, (by==-1 && moveY == 0 ? 16 : 0)),extSurf,&sr); } } } - ////roads printed + // roads printed - ////printing objects - srx = (moveX <= 0 ? 0 : -1) * 32; - if (smooth) - srx += moveX + extRect->x; + // printing objects + srx = srx_init; - for (int bx= (moveX <= 0 ? 0 : -1); bxy; + // Skip column if not in map + if (top_tile.x+bx < 0 || top_tile.x+bx >= map->width) + continue; - for (int by=(moveY <= 0 ? 0 : -1); by= map->height) + continue; + + std::vector < std::pair > &objects = + ttiles[top_tile.x+bx][top_tile.y+by][top_tile.z].objects; + + for(int h=0; h < objects.size(); ++h) { SDL_Rect sr; @@ -740,13 +772,10 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level, sr.y = sry; sr.w = sr.h = 32; - if (!smooth) - validateRectTerr(&sr, extRect); - - SDL_Rect pp = ttiles[x+bx][y+by][level].objects[h].second; + SDL_Rect pp = objects[h].second; pp.h = sr.h; pp.w = sr.w; - const CGHeroInstance * themp = (dynamic_cast(ttiles[x+bx][y+by][level].objects[h].first)); + const CGHeroInstance * themp = (dynamic_cast(objects[h].first)); if(themp && themp->moveDir && !themp->isStanding && themp->ID!=62) //last condition - this is not prison { @@ -766,10 +795,10 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level, break; } } - CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,su,&sr); + CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr); pp.y+=imgVal*2-32; sr.y-=16; - SDL_BlitSurface(graphics->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, su, &sr); + SDL_BlitSurface(graphics->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, extSurf, &sr); } else if(themp && themp->moveDir && themp->isStanding && themp->ID!=62) //last condition - this is not prison) { @@ -789,8 +818,9 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level, break; } } - CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,su,&sr); - if(themp->pos.x==x+bx && themp->pos.y==y+by) + CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr); + + if(themp->pos.x==top_tile.x+bx && themp->pos.y==top_tile.y+by) { SDL_Rect bufr = sr; bufr.x-=2*32; @@ -798,12 +828,12 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level, bufr.h = 64; bufr.w = 96; if(bufr.x-extRect->x>-64) - SDL_BlitSurface(graphics->flags4[themp->getOwner()]->ourImages[ getHeroFrameNum(themp->moveDir, !themp->isStanding) *8+(heroAnim/4)%imgVal].bitmap, NULL, su, &bufr); + SDL_BlitSurface(graphics->flags4[themp->getOwner()]->ourImages[ getHeroFrameNum(themp->moveDir, !themp->isStanding) *8+(heroAnim/4)%imgVal].bitmap, NULL, extSurf, &bufr); } } else { - const CGObjectInstance *obj = ttiles[x+bx][y+by][level].objects[h].first; + const CGObjectInstance *obj = objects[h].first; const std::vector &ourImages = obj->defInfo->handler->ourImages; SDL_Surface *bitmap = ourImages[(anim+obj->animPhaseShift)%ourImages.size()].bitmap; @@ -811,69 +841,71 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level, if(obj->tempOwner<8 || obj->tempOwner==255) CSDL_Ext::setPlayerColor(bitmap, obj->tempOwner); - CSDL_Ext::blit8bppAlphaTo24bpp(bitmap,&pp,su,&sr); + CSDL_Ext::blit8bppAlphaTo24bpp(bitmap,&pp,extSurf,&sr); } } } } - ////objects printed + // objects printed - ////printing shadow - srx = (moveX <= 0 ? 0 : -1) * 32; - if (smooth) - srx += moveX + extRect->x; + // printing shadow + srx = srx_init; - for (int bx= (moveX <= 0 ? 0 : -1); bxy; + // Skip column if not in map + if (top_tile.x+bx < 0 || top_tile.x+bx >= map->width) + continue; - for (int by=(moveY <= 0 ? 0 : -1); by= map->height) + continue; + SDL_Rect sr; sr.x = srx; sr.y = sry; sr.h = sr.w = 32; - if(!smooth) - validateRectTerr(&sr, extRect); - - if(bx+x>=0 && by+y>=0 && bx+xmh->map->width && by+ymh->map->height && !(*visibilityMap)[bx+x][by+y][level]) + if (top_tile.x+bx >= 0 && + top_tile.y+by >= 0 && + top_tile.x+bx < CGI->mh->map->width && + top_tile.y+by < CGI->mh->map->height && + !(*visibilityMap)[top_tile.x+bx][top_tile.y+by][top_tile.z]) { - SDL_Surface * hide = getVisBitmap(bx+x, by+y, *visibilityMap, level); - CSDL_Ext::blit8bppAlphaTo24bpp(hide, &genRect(sr.h, sr.w, 0, 0), su, &sr); + SDL_Surface * hide = getVisBitmap(top_tile.x+bx, top_tile.y+by, *visibilityMap, top_tile.z); + CSDL_Ext::blit8bppAlphaTo24bpp(hide, &rtile, extSurf, &sr); } } } - ////shadow printed + // shadow printed - //printing borders - for (int bx= (moveX <= 0 ? 0 : -1); bxmap->width+(-1) || by+y>map->height+(-1)) - { + if (top_tile.x+bx < 0 || top_tile.x+bx >= map->width || + top_tile.y+by < 0 || top_tile.y+by >= map->height) { + SDL_Rect sr; - if(smooth) - { - sr.y=by*32 + moveY + extRect->y; - sr.x=bx*32 + moveX + extRect->x; - sr.h=sr.w=32; - } - else - { - sr.y=by*32; - sr.x=bx*32; - sr.h=sr.w=32; - validateRectTerr(&sr, extRect); - } - SDL_BlitSurface(ttiles[x+bx][y+by][level].terbitmap,&genRect(sr.h, sr.w, 0, 0),su,&sr); - } - else - { + + sr.x=srx; + sr.y=sry; + sr.h=sr.w=32; + + SDL_BlitSurface(ttiles[top_tile.x+bx][top_tile.y+by][top_tile.z].terbitmap, + &genRect(sr.h, sr.w, 0, 0),extSurf,&sr); + } else { + // TODO: these should be activable by the console #ifdef MARK_BLOCKED_POSITIONS if(ttiles[x+bx][y+by][level].tileInfo->blocked) //temporary hiding blocked positions { @@ -898,7 +930,7 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level, *((unsigned char*)(ns->pixels) + f) = 128; } - SDL_BlitSurface(ns,&genRect(sr.h, sr.w, 0, 0),su,&sr); + SDL_BlitSurface(ns,&genRect(sr.h, sr.w, 0, 0),extSurf,&sr); SDL_FreeSurface(ns); } @@ -927,7 +959,7 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level, *((unsigned char*)(ns->pixels) + f) = 128; } - SDL_BlitSurface(ns,&genRect(sr.h, sr.w, 0, 0),su,&sr); + SDL_BlitSurface(ns,&genRect(sr.h, sr.w, 0, 0),extSurf,&sr); SDL_FreeSurface(ns); } @@ -935,10 +967,49 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level, } } } - SDL_SetClipRect(su, &prevClip); //restoring clip_rect - //borders printed + // borders printed - return su; +#if 1 + // print grid + // TODO: This option should be activated by the console. + srx = srx_init; + + for (int bx = 0; bx < dx; bx++, srx+=32) + { + sry = sry_init; + + for (int by = 0; by= extRect->y && + sr.y < extRect->y+extRect->h) + for(int i=0;i= extRect->x && + sr.x+i < extRect->x+extRect->w) + CSDL_Ext::SDL_PutPixelWithoutRefresh(extSurf,sr.x+i,sr.y,color.x,color.y,color.z); + + if (sr.x >= extRect->x && + sr.x < extRect->x+extRect->w) + for(int i=0; i= extRect->y && + sr.y+i < extRect->y+extRect->h) + CSDL_Ext::SDL_PutPixelWithoutRefresh(extSurf,sr.x,sr.y+i,color.x,color.y,color.z); + } + } + + // grid +#endif + + SDL_SetClipRect(extSurf, &prevClip); //restoring clip_rect + + delete rSurf; } SDL_Surface * CMapHandler::getVisBitmap(int x, int y, const std::vector< std::vector< std::vector > > & visibilityMap, int lvl) @@ -1253,7 +1324,7 @@ bool CMapHandler::printObject(const CGObjectInstance *obj) cr.x = fx*32; cr.y = fy*32; std::pair toAdd = std::make_pair(obj, cr); - if((obj->pos.x + fx - bitmap->w/32+1)>=0 && (obj->pos.x + fx - bitmap->w/32+1)pos.y + fy - bitmap->h/32+1)>=0 && (obj->pos.y + fy - bitmap->h/32+1)pos.x + fx - bitmap->w/32+1)>=0 && (obj->pos.x + fx - bitmap->w/32+1)pos.y + fy - bitmap->h/32+1)>=0 && (obj->pos.y + fy - bitmap->h/32+1)h/32; ++fy) { - if((obj->pos.x + fx - bitmap->w/32+1)>=0 && (obj->pos.x + fx - bitmap->w/32+1)pos.y + fy - bitmap->h/32+1)>=0 && (obj->pos.y + fy - bitmap->h/32+1)pos.x + fx - bitmap->w/32+1)>=0 && (obj->pos.x + fx - bitmap->w/32+1)pos.y + fy - bitmap->h/32+1)>=0 && (obj->pos.y + fy - bitmap->h/32+1) > & ctile = ttiles[obj->pos.x + fx - bitmap->w/32+1][obj->pos.y + fy - bitmap->h/32+1][obj->pos.z].objects; for(size_t dd=0; dd < ctile.size(); ++dd) @@ -1467,7 +1538,8 @@ CMapHandler::~CMapHandler() CMapHandler::CMapHandler() { - frame.left = frame.right = frame.top = frame.bottom = 0; + mapW = mapH = 0; + frameW = frameH = 0; fullHide = NULL; partialHide = NULL; } diff --git a/mapHandler.h b/mapHandler.h index f5cc72ed9..6c3bd9ab4 100644 --- a/mapHandler.h +++ b/mapHandler.h @@ -81,13 +81,24 @@ public: int3 sizes; //map size (x = width, y = height, z = number of levels) Mapa * map; - // size of each side of the frame around the whole map - struct { - int left; - int right; - int top; - int bottom; - } frame; + // Size of the map window in pixels. This doesn't have to be a multiple of tiles. + int mapW; + int mapH; + + // Max number of tiles that will fit in the map screen. Tiles + // can be partial on each edges. + int tilesW; + int tilesH; + + // size of each side of the frame around the whole map, in tiles + int frameH; + int frameW; + + // Coord in pixels of the top left corner of the top left tile to + // draw. Values range is [-31..0]. A negative value + // implies that part of the tile won't be displayed. + int offsetX; + int offsetY; std::set usedHeroes; CDefHandler * fullHide; //for Fog of War @@ -124,7 +135,7 @@ public: void roadsRiverTerrainInit(); void prepareFOWDefs(); - SDL_Surface * terrainRect(int x, int y, int dx, int dy, int level, unsigned char anim, std::vector< std::vector< std::vector > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, SDL_Rect * extRect, int moveX, int moveY, bool smooth); + void terrainRect(int3 top_tile, unsigned char anim, std::vector< std::vector< std::vector > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, SDL_Rect * extRect, int moveX, int moveY); void updateWater(); unsigned char getHeroFrameNum(const unsigned char & dir, const bool & isMoving) const; //terrainRect helper function void validateRectTerr(SDL_Rect * val, const SDL_Rect * ext); //terrainRect helper