diff --git a/client/CAdvmapInterface.cpp b/client/CAdvmapInterface.cpp index 7e5900273..4fce0824b 100644 --- a/client/CAdvmapInterface.cpp +++ b/client/CAdvmapInterface.cpp @@ -216,12 +216,6 @@ void CMinimapSurfacesRef::initMap(int level) void CMinimapSurfacesRef::initFoW(int level) { - /*for(int g=0; gminimap.pos; int3 mapSizes = LOCPLINT->cb->getMapSize(); int mw = map_[0]->w, mh = map_[0]->h;//, @@ -230,7 +224,7 @@ void CMinimapSurfacesRef::initFoW(int level) { if(level>=0 && d!=level) continue; - SDL_Surface * pt = CSDL_Ext::newSurface(minimap_pos.w, minimap_pos.h, CSDL_Ext::std32bppSurface); + SDL_Surface * pt = CSDL_Ext::createSurfaceWithBpp<4>(minimap_pos.w, minimap_pos.h); for (int i=0; i=0 && d!=level) continue; - SDL_Surface * pt = CSDL_Ext::newSurface(minimap_pos.w, minimap_pos.h, CSDL_Ext::std32bppSurface); + SDL_Surface * pt = CSDL_Ext::createSurfaceWithBpp<4>(minimap_pos.w, minimap_pos.h); for (int i=0; icb->setSelection(sel); selection = sel; if (LOCPLINT->battleInt == NULL) - CCS->musich->playMusic(CCS->musich->terrainMusics[LOCPLINT->cb->getTile(sel->visitablePos())->tertype]); + CCS->musich->playMusic(CCS->musich->terrainMusics[LOCPLINT->cb->getTile(sel->visitablePos())->tertype], -1); if(centerView) centerOn(sel); diff --git a/client/CAdvmapInterface.h b/client/CAdvmapInterface.h index d447e910c..167db2c82 100644 --- a/client/CAdvmapInterface.h +++ b/client/CAdvmapInterface.h @@ -40,13 +40,16 @@ public: static void showScenarioInfo(); }; -class CMinimapSurfacesRef { +//Player-specific minimaps +class CMinimapSurfacesRef +{ public: - CMinimapSurfacesRef(); - std::vector< SDL_Surface* > &map(); - std::vector< SDL_Surface* > &FoW(); - std::vector< SDL_Surface* > &flObjs(); - void free(); + CMinimapSurfacesRef(); + // see private members descriptions + std::vector< SDL_Surface* > &map(); + std::vector< SDL_Surface* > &FoW(); + std::vector< SDL_Surface* > &flObjs(); + void free(); private: void redraw(int level=-1);// (level==-1) => redraw all levels void initMap(int level=-1);// (level==-1) => redraw all levels @@ -54,8 +57,8 @@ private: void initFlaggableObjs(int level=-1);// (level==-1) => redraw all levels void showVisibleTiles(int level=-1);// (level==-1) => redraw all levels private: - std::vector< SDL_Surface* > map_, FoW_, flObjs_; //one bitmap for each level (terrain, Fog of War, flaggable objects) (one for underworld, one for surface) - bool ready; + std::vector< SDL_Surface* > map_, FoW_, flObjs_; //one bitmap for each level (terrain, Fog of War, flaggable objects) (one for underworld, one for surface) + bool ready; }; /// Minimap which is displayed at the right upper corner of adventure map diff --git a/client/CConfigHandler.cpp b/client/CConfigHandler.cpp index d9ad91599..4ceed67b6 100644 --- a/client/CConfigHandler.cpp +++ b/client/CConfigHandler.cpp @@ -270,15 +270,6 @@ void config::CConfigHandler::init() } const JsonNode& screenRes = settings["video"]["screenRes"]; - const JsonNode& gameRes = settings["video"]["gameRes"]; - //fixing screenx / screeny - if (screenRes["width"].Float() != gameRes["width"].Float() - || screenRes["height"].Float() != gameRes["height"].Float()) - { - Settings screen = settings.write["video"]["screenRes"]; - screen["width"].Float() = gameRes["width"].Float(); - screen["height"].Float() = gameRes["height"].Float(); - } - SetResolution(gameRes["width"].Float(), gameRes["height"].Float()); + SetResolution(screenRes["width"].Float(), screenRes["height"].Float()); } diff --git a/client/CMT.cpp b/client/CMT.cpp index 82f097b34..d18da752a 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -75,7 +75,7 @@ std::queue events; boost::mutex eventsM; static bool gOnlyAI = false; -static bool setResolution = false; //set by event handling thread after resolution is adjusted +//static bool setResolution = false; //set by event handling thread after resolution is adjusted static bool ermInteractiveMode = false; //structurize when time is right void processCommand(const std::string &message); @@ -83,7 +83,7 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo void dispose(); void playIntro(); static void listenForEvents(); -void requestChangingResolution(); +//void requestChangingResolution(); void startGame(StartInfo * options, CConnection *serv = NULL); #ifndef _WIN32 @@ -102,7 +102,7 @@ void startGameFromFile(const std::string &fname) if(!out.sfile || !*out.sfile) { tlog1 << "Failed to open startfile, falling back to the main menu!\n"; - GH.curInt = new CGPreGame; + GH.curInt = CGPreGame::create(); return; } out >> si; @@ -116,12 +116,6 @@ void startGameFromFile(const std::string &fname) void init() { CStopWatch tmh, pomtime; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - int rmask = 0xff000000;int gmask = 0x00ff0000;int bmask = 0x0000ff00;int amask = 0x000000ff; -#else - int rmask = 0x000000ff; int gmask = 0x0000ff00; int bmask = 0x00ff0000; int amask = 0xff000000; -#endif - CSDL_Ext::std32bppSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 1, 32, rmask, gmask, bmask, amask); tlog0 << "\tInitializing minors: " << pomtime.getDiff() << std::endl; //initializing audio @@ -256,7 +250,7 @@ int main(int argc, char** argv) atexit(SDL_Quit); const JsonNode& video = settings["video"]; - const JsonNode& res = video["menuRes"]; + const JsonNode& res = video["screenRes"]; setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["fullscreen"].Bool()); @@ -294,7 +288,7 @@ int main(int argc, char** argv) if(!vm.count("start")) - GH.curInt = new CGPreGame; //will set CGP pointer to itself + GH.curInt = CGPreGame::create(); //will set CGP pointer to itself else startGameFromFile(vm["start"].as()); } @@ -332,7 +326,6 @@ void processCommand(const std::string &message) std::string cn; //command name readed >> cn; - if(LOCPLINT && LOCPLINT->cingconsole) LOCPLINT->cingconsole->print(message); @@ -408,7 +401,7 @@ void processCommand(const std::string &message) std::string fname; readed >> fname; client->loadGame(fname); - } + }/* else if(cn=="resolution" || cn == "r") { if(LOCPLINT) @@ -437,15 +430,14 @@ void processCommand(const std::string &message) auto j = conf.guiOptions.begin(); std::advance(j, i - 1); //move j to the i-th resolution info const int w = j->first.first, h = j->first.second; - Settings res = settings.write["video"]["gameRes"]; Settings screen = settings.write["video"]["screenRes"]; - res["width"].Float() = screen["width"].Float() = w; - res["height"].Float() = screen["height"].Float() = h; + screen["width"].Float() = w; + screen["height"].Float() = h; conf.SetResolution(screen["width"].Float(), screen["height"].Float()); tlog0 << "Screen resolution set to " << (int)screen["width"].Float() << " x " - << (int)screen["height"].Float() <<". It will be applied when the game starts.\n"; + << (int)screen["height"].Float() <<". It will be applied afters game restart.\n"; } - } + }*/ else if(message=="get txt") { boost::filesystem::create_directory("Extracted_txts"); @@ -578,6 +570,7 @@ void dispose() delete logfile; } +//used only once during initialization static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo) { // VCMI will only work with 2, 3 or 4 bytes per pixel @@ -596,7 +589,7 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo if(suggestedBpp != bpp) { - tlog2 << "Warning: SDL says that " << bpp << "bpp is wrong and suggests " << suggestedBpp << std::endl; + tlog2 << "Note: SDL suggests to use " << suggestedBpp << " bpp instead of" << bpp << " bpp " << std::endl; } //For some reason changing fullscreen via config window checkbox result in SDL_Quit event @@ -647,15 +640,24 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo //TODO: centering game window on other platforms (or does the environment do their job correctly there?) screenBuf = bufOnScreen ? screen : screen2; - setResolution = true; + //setResolution = true; } static void fullScreenChanged(const JsonNode &newState) { boost::unique_lock lock(*LOCPLINT->pim); - const JsonNode& video = settings["video"]; - const JsonNode& res = video["screenRes"]; - setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), newState.Bool(), false); + + bool fullscreen = newState.Bool(); + int bitsPerPixel = screen->format->BitsPerPixel; + + bitsPerPixel = SDL_VideoModeOK(screen->w, screen->h, bitsPerPixel, SDL_SWSURFACE|(fullscreen?SDL_FULLSCREEN:0)); + if(bitsPerPixel == 0) + { + tlog1 << "Error: SDL says that " << screen->w << "x" << screen->h << " resolution is not available!\n"; + return; + } + + screen = SDL_SetVideoMode(screen->w, screen->h, bitsPerPixel, SDL_SWSURFACE|(fullscreen?SDL_FULLSCREEN:0)); GH.totalRedraw(); } @@ -711,17 +713,17 @@ static void listenForEvents() switch(ev->user.code) { - case CHANGE_SCREEN_RESOLUTION: + /* case CHANGE_SCREEN_RESOLUTION: { tlog0 << "Changing resolution has been requested\n"; const JsonNode& video = settings["video"]; const JsonNode& res = video["gameRes"]; setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["fullscreen"].Bool()); break; - } + }*/ case RETURN_TO_MAIN_MENU: endGame(); - CGPreGame::createIfNotPresent(); + CGPreGame::create(); GH.curInt = CGP; GH.defActionsDef = 63; break; @@ -737,7 +739,7 @@ static void listenForEvents() break; case RETURN_TO_MENU_LOAD: endGame(); - CGPreGame::createIfNotPresent(); + CGPreGame::create(); GH.defActionsDef = 63; CGP->update(); CGP->menu->switchToTab(vstd::find_pos(CGP->menu->menuNameToEntry, "load")); @@ -773,7 +775,7 @@ void startGame(StartInfo * options, CConnection *serv/* = NULL*/) it->second.human = false; } } - const JsonNode& res = settings["video"]["screenRes"]; +/* const JsonNode& res = settings["video"]["screenRes"]; if(screen->w != res["width"].Float() || screen->h != res["height"].Float()) { @@ -784,7 +786,7 @@ void startGame(StartInfo * options, CConnection *serv/* = NULL*/) while(!setResolution) boost::this_thread::sleep(boost::posix_time::milliseconds(50)); } else - setResolution = true; + setResolution = true;*/ client = new CClient; @@ -805,7 +807,7 @@ void startGame(StartInfo * options, CConnection *serv/* = NULL*/) client->connectionHandler = new boost::thread(&CClient::run, client); } - +/* void requestChangingResolution() { //mark that we are going to change resolution @@ -817,3 +819,4 @@ void requestChangingResolution() ev.user.code = CHANGE_SCREEN_RESOLUTION; SDL_PushEvent(&ev); } +*/ \ No newline at end of file diff --git a/client/CMusicHandler.cpp b/client/CMusicHandler.cpp index d5d48e86a..14e512195 100644 --- a/client/CMusicHandler.cpp +++ b/client/CMusicHandler.cpp @@ -242,7 +242,10 @@ void CSoundHandler::initSpellsSounds(const std::vector< ConstTransitivePtrtempOwner == playerID) //we are moving our hero - we may need to update assigned path { //We may need to change music - select new track, music handler will change it if needed - CCS->musich->playMusic(CCS->musich->terrainMusics[LOCPLINT->cb->getTile(ho->visitablePos())->tertype]); + CCS->musich->playMusic(CCS->musich->terrainMusics[LOCPLINT->cb->getTile(ho->visitablePos())->tertype], -1); if(details.result == TryMoveHero::TELEPORTATION) { @@ -2073,6 +2073,9 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI { eraseCurrentPathOf(caster, false); } + const CSpell * spell = CGI->spellh->spells[spellID]; + if (vstd::contains(CCS->soundh->spellSounds, spell)) + CCS->soundh->playSound(CCS->soundh->spellSounds[spell]); } void CPlayerInterface::eraseCurrentPathOf( const CGHeroInstance * ho, bool checkForExistanceOfPath /*= true */ ) diff --git a/client/CPlayerInterface.h b/client/CPlayerInterface.h index d58e788ca..1c07dcb86 100644 --- a/client/CPlayerInterface.h +++ b/client/CPlayerInterface.h @@ -71,7 +71,11 @@ namespace boost class recursive_mutex; }; -enum {CHANGE_SCREEN_RESOLUTION = 1, RETURN_TO_MAIN_MENU = 2, STOP_CLIENT = 3, RESTART_GAME, +enum { + /*CHANGE_SCREEN_RESOLUTION = 1,*/ + RETURN_TO_MAIN_MENU = 2, + STOP_CLIENT = 3, + RESTART_GAME, RETURN_TO_MENU_LOAD}; /// Central class for managing user interface logic diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index a33639893..df8a35f7f 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -61,7 +61,7 @@ using boost::ref; void startGame(StartInfo * options, CConnection *serv = NULL); -CGPreGame * CGP; +CGPreGame * CGP = nullptr; ISelectionScreenInfo *SEL; static int playerColor; //if more than one player - applies to the first @@ -215,6 +215,9 @@ CMenuScreen::CMenuScreen(const JsonNode& configNode): BOOST_FOREACH(const JsonNode& node, config["images"].Vector()) images.push_back(createPicture(node)); + if (!images.empty()) + pos = images[0]->center(); + //Hardcoded entry menuNameToEntry.push_back("credits"); @@ -230,10 +233,19 @@ CIntObject * CMenuScreen::createTab(size_t index) return new CMenuEntry(this, config["items"].Vector()[index]); } +void CMenuScreen::showAll(SDL_Surface * to) +{ + CIntObject::showAll(to); + + if (pos.h != to->h || pos.w != to->w) + CMessage::drawBorder(1, to, pos.w+28, pos.h+30, pos.x-14, pos.y-15); + +} + void CMenuScreen::show(SDL_Surface * to) { if (!config["video"].isNull()) - CCS->videoh->update(config["video"]["x"].Float(), config["video"]["y"].Float(), to, true, false); + CCS->videoh->update(config["video"]["x"].Float() + pos.x, config["video"]["y"].Float() + pos.y, to, true, false); CIntObject::show(to); } @@ -355,15 +367,20 @@ CreditsScreen::CreditsScreen() used |= LCLICK | RCLICK; type |= REDRAW_PARENT; OBJ_CONSTRUCTION_CAPTURING_ALL; - pos.w = 800; - pos.h = 600; + pos.w = CGP->menu->pos.w; + pos.h = CGP->menu->pos.h; std::string text = bitmaph->getTextFile("CREDITS"); size_t firstQuote = text.find('\"')+1; text = text.substr(firstQuote, text.find('\"', firstQuote) - firstQuote ); - credits = new CTextBox(text, Rect(450, 600, 350, 32000), 0, FONT_CREDITS, CENTER, Colors::Cornsilk); + credits = new CTextBox(text, Rect(pos.w - 350, 600, 350, 32000), 0, FONT_CREDITS, CENTER, Colors::Cornsilk); credits->pos.h = credits->maxH; } +void CreditsScreen::showAll(SDL_Surface * to) +{ + //Do not draw anything +} + void CreditsScreen::show(SDL_Surface * to) { static int count = 0; @@ -373,9 +390,13 @@ void CreditsScreen::show(SDL_Surface * to) credits->pos.y--; count = 0; } - SDL_SetClipRect(screen, &credits->pos); + Rect creditsArea = credits->pos & pos; + SDL_SetClipRect(screenBuf, &creditsArea); + SDL_SetClipRect(screen, &creditsArea); redraw(); + CIntObject::showAll(to); SDL_SetClipRect(screen, NULL); + SDL_SetClipRect(screenBuf, NULL); //end of credits, close this screen if (credits->pos.y + credits->pos.h < 0) @@ -416,6 +437,7 @@ void CGPreGame::openSel(CMenuScreen::EState screenType, CMenuScreen::EMultiMode void CGPreGame::loadGraphics() { + background = BitmapHandler::loadBitmap("DIBOXBCK"); victory = CDefHandler::giveDef("SCNRVICT.DEF"); loss = CDefHandler::giveDef("SCNRLOSS.DEF"); bonuses = CDefHandler::giveDef("SCNRSTAR.DEF"); @@ -429,6 +451,7 @@ void CGPreGame::disposeGraphics() { delete victory; delete loss; + SDL_FreeSurface(background); SDL_FreeSurface(rHero); SDL_FreeSurface(nHero); SDL_FreeSurface(rTown); @@ -439,6 +462,7 @@ void CGPreGame::update() { if (GH.listInt.empty()) { + GH.pushInt(this); GH.pushInt(menu); menu->switchToTab(0); } @@ -464,6 +488,18 @@ void CGPreGame::update() CCS->curh->draw2(); } +void CGPreGame::showAll(SDL_Surface *to) +{ + //fill screen with background texture + for (int y=0; yh; y+=background->h) + { + for (int x=0; xw; x+=background->w) + { + blitAt(background, x, y, to); + } + } +} + void CGPreGame::openCampaignScreen(std::string name) { BOOST_FOREACH(const JsonNode& node, (*pregameConfig)["campaignsset"].Vector()) @@ -477,17 +513,18 @@ void CGPreGame::openCampaignScreen(std::string name) tlog1<<"Unknown campaign set: "< *Names /*= NULL*/) : ISelectionScreenInfo(Names), serverHandlingThread(NULL), mx(new boost::recursive_mutex), serv(NULL), ongoingClosing(false), myNameID(255) { - CGPreGame::createIfNotPresent(); //we depend on its graphics + CGPreGame::create(); //we depend on its graphics screenType = Type; multiPlayer = MultiPlayer; @@ -507,20 +544,20 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti pos.h = 584; if(Type == CMenuScreen::saveGame) { + bordered = false; center(pos); } else if(Type == CMenuScreen::campaignList) { + bordered = false; bg = new CPicture(BitmapHandler::loadBitmap("CamCust.bmp"), 0, 0, true); - - pos.x = 3; - pos.y = 6; + pos = bg->center(); } else { - pos.x = 3; - pos.y = 6; - bg = new CPicture(BitmapHandler::loadBitmap(rand()%2 ? "ZPIC1000.bmp" : "ZPIC1001.bmp"), -3, -6, true); + bordered = true; + bg = new CPicture(BitmapHandler::loadBitmap(rand()%2 ? "ZPIC1000.bmp" : "ZPIC1001.bmp"), 0, 0, true); + pos = bg->center(); } sInfo.difficulty = 1; @@ -549,20 +586,20 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti { card->difficulty->onChange = bind(&CSelectionScreen::difficultyChange, this, _1); card->difficulty->select(1, 0); - CAdventureMapButton *select = new CAdventureMapButton(CGI->generaltexth->zelp[45], bind(&CSelectionScreen::toggleTab, this, sel), 411, 75, "GSPBUTT.DEF", SDLK_s); + CAdventureMapButton *select = new CAdventureMapButton(CGI->generaltexth->zelp[45], bind(&CSelectionScreen::toggleTab, this, sel), 411, 80, "GSPBUTT.DEF", SDLK_s); select->addTextOverlay(CGI->generaltexth->allTexts[500], FONT_SMALL); - CAdventureMapButton *opts = new CAdventureMapButton(CGI->generaltexth->zelp[46], bind(&CSelectionScreen::toggleTab, this, opt), 411, 503, "GSPBUTT.DEF", SDLK_a); + CAdventureMapButton *opts = new CAdventureMapButton(CGI->generaltexth->zelp[46], bind(&CSelectionScreen::toggleTab, this, opt), 411, 510, "GSPBUTT.DEF", SDLK_a); opts->addTextOverlay(CGI->generaltexth->allTexts[501], FONT_SMALL); - CAdventureMapButton *random = new CAdventureMapButton(CGI->generaltexth->zelp[47], bind(&CSelectionScreen::toggleTab, this, sel), 411, 99, "GSPBUTT.DEF", SDLK_r); + CAdventureMapButton *random = new CAdventureMapButton(CGI->generaltexth->zelp[47], bind(&CSelectionScreen::toggleTab, this, sel), 411, 105, "GSPBUTT.DEF", SDLK_r); random->addTextOverlay(CGI->generaltexth->allTexts[740], FONT_SMALL); - start = new CAdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 411, 529, "SCNRBEG.DEF", SDLK_b); + start = new CAdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 411, 535, "SCNRBEG.DEF", SDLK_b); if(network) { - CAdventureMapButton *hideChat = new CAdventureMapButton(CGI->generaltexth->zelp[48], bind(&InfoCard::toggleChat, card), 619, 75, "GSPBUT2.DEF", SDLK_h); + CAdventureMapButton *hideChat = new CAdventureMapButton(CGI->generaltexth->zelp[48], bind(&InfoCard::toggleChat, card), 619, 83, "GSPBUT2.DEF", SDLK_h); hideChat->addTextOverlay(CGI->generaltexth->allTexts[531], FONT_SMALL); if(multiPlayer == CMenuScreen::MULTI_NETWORK_GUEST) @@ -579,19 +616,18 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti break; case CMenuScreen::loadGame: sel->recActions = 255; - start = new CAdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 411, 529, "SCNRLOD.DEF", SDLK_l); + start = new CAdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 411, 535, "SCNRLOD.DEF", SDLK_l); break; case CMenuScreen::saveGame: sel->recActions = 255; - start = new CAdventureMapButton("", CGI->generaltexth->zelp[103].second, bind(&CSelectionScreen::startGame, this), 411, 529, "SCNRSAV.DEF"); + start = new CAdventureMapButton("", CGI->generaltexth->zelp[103].second, bind(&CSelectionScreen::startGame, this), 411, 535, "SCNRSAV.DEF"); break; case CMenuScreen::campaignList: sel->recActions = 255; - start = new CAdventureMapButton(std::pair(), bind(&CSelectionScreen::startCampaign, this), 411, 529, "SCNRLOD.DEF", SDLK_b); + start = new CAdventureMapButton(std::pair(), bind(&CSelectionScreen::startCampaign, this), 411, 535, "SCNRLOD.DEF", SDLK_b); break; } - start->assignedKeys.insert(SDLK_RETURN); std::string backName; @@ -604,7 +640,7 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti backName = "SCNRBACK.DEF"; } - back = new CAdventureMapButton("", CGI->generaltexth->zelp[105].second, bind(&CGuiHandler::popIntTotally, &GH, this), 581, 529, backName, SDLK_ESCAPE); + back = new CAdventureMapButton("", CGI->generaltexth->zelp[105].second, bind(&CGuiHandler::popIntTotally, &GH, this), 581, 535, backName, SDLK_ESCAPE); if(network) { @@ -780,6 +816,8 @@ void CSelectionScreen::startGame() StartInfo *si = new StartInfo(sInfo); GH.popIntTotally(this); //delete me GH.popInt(GH.topInt()); //only deactivate main menu screen + GH.totalRedraw(); + GH.popInt(GH.topInt()); //and pregame background //SEL->current = NULL; //curOpts = NULL; ::startGame(si); @@ -927,6 +965,13 @@ void CSelectionScreen::propagateNames() *serv << &pn; } +void CSelectionScreen::showAll(SDL_Surface *to) +{ + CIntObject::showAll(to); + if (bordered && (pos.h != to->h || pos.w != to->w)) + CMessage::drawBorder(1, to, pos.w+28, pos.h+30, pos.x-14, pos.y-15); +} + // A new size filter (Small, Medium, ...) has been selected. Populate // selMaps with the relevant data. void SelectionTab::filter( int size, bool selectFirst ) @@ -964,7 +1009,6 @@ void SelectionTab::filter( int size, bool selectFirst ) } } - void SelectionTab::getFiles(std::vector &out, const std::string &dirname, const std::string &ext) { CFileUtility::getFilesWithExt(out, dirname, ext); @@ -1046,20 +1090,15 @@ SelectionTab::SelectionTab(CMenuScreen::EState Type, const boost::functionpos.w; - pos.h = bg->pos.h; + bg = new CPicture("SCSELBCK.bmp", 0, 6); + pos = bg->pos; } else { - SDL_Surface * tmp1 = BitmapHandler::loadBitmap("CAMCUST.bmp"); - SDL_Surface * tmp = CSDL_Ext::newSurface(400, tmp1->h); - blitAt(tmp1, 0, 0, tmp); - SDL_FreeSurface(tmp1); - bg = new CPicture(tmp, 0, 0, true); - pos.w = bg->pos.w; - pos.h = bg->pos.h; - bg->pos.x = bg->pos.y = 0; + bg = nullptr; //use background from parent + pos.w = parent->pos.w; + pos.h = parent->pos.h; + pos.x += 3; pos.y += 6; } if(MultiPlayer == CMenuScreen::MULTI_NETWORK_GUEST) @@ -1111,9 +1150,9 @@ SelectionTab::SelectionTab(CMenuScreen::EState Type, const boost::functionchildren, this); //our position among parent children parent->children.insert(it, bg); //put BG before us @@ -1825,7 +1865,7 @@ OptionsTab::OptionsTab(): turnDuration(NULL) { OBJ_CONSTRUCTION; - bg = new CPicture(BitmapHandler::loadBitmap("ADVOPTBK.bmp"), 0, 0, true); + bg = new CPicture("ADVOPTBK", 0, 6); pos = bg->pos; if(SEL->screenType == CMenuScreen::newGame) @@ -2715,6 +2755,9 @@ CBonusSelection::CBonusSelection( CCampaignState * _ourCampaign ) loadPositionsOfGraphics(); background = BitmapHandler::loadBitmap(bgNames[ourCampaign->camp->header.mapVersion]); + pos.h = background->h; + pos.w = background->w; + center(); SDL_Surface * panel = BitmapHandler::loadBitmap("CAMPBRF.BMP"); @@ -2726,25 +2769,25 @@ CBonusSelection::CBonusSelection( CCampaignState * _ourCampaign ) //campaign name if (ourCampaign->camp->header.name.length()) - printAtLoc(ourCampaign->camp->header.name, 481, 28, FONT_BIG, Colors::Jasmine, background); + CSDL_Ext::printAt(ourCampaign->camp->header.name, 481, 28, FONT_BIG, Colors::Jasmine, background); else - printAtLoc("Unnamed", 481, 28, FONT_BIG, Colors::Jasmine, background); + CSDL_Ext::printAt("Unnamed", 481, 28, FONT_BIG, Colors::Jasmine, background); //map size icon sizes = CDefHandler::giveDef("SCNRMPSZ.DEF"); //campaign description - printAtLoc(CGI->generaltexth->allTexts[38], 481, 63, FONT_SMALL, Colors::Jasmine, background); + CSDL_Ext::printAt(CGI->generaltexth->allTexts[38], 481, 63, FONT_SMALL, Colors::Jasmine, background); cmpgDesc = new CTextBox(ourCampaign->camp->header.description, Rect(480, 86, 286, 117), 1); - cmpgDesc->showAll(background); + //cmpgDesc->showAll(background); //map description mapDesc = new CTextBox("", Rect(480, 280, 286, 117), 1); //bonus choosing - printAtLoc(CGI->generaltexth->allTexts[71], 511, 432, FONT_MEDIUM, Colors::Cornsilk, background); //Choose a bonus: + CSDL_Ext::printAt(CGI->generaltexth->allTexts[71], 511, 432, FONT_MEDIUM, Colors::Cornsilk, background); //Choose a bonus: bonuses = new CHighlightableButtonsGroup(bind(&CBonusSelection::selectBonus, this, _1)); //set left part of window @@ -2774,15 +2817,15 @@ CBonusSelection::CBonusSelection( CCampaignState * _ourCampaign ) } //allies / enemies - printAtLoc(CGI->generaltexth->allTexts[390] + ":", 486, 407, FONT_SMALL, Colors::Cornsilk, background); //Allies - printAtLoc(CGI->generaltexth->allTexts[391] + ":", 619, 407, FONT_SMALL, Colors::Cornsilk, background); //Enemies + CSDL_Ext::printAt(CGI->generaltexth->allTexts[390] + ":", 486, 407, FONT_SMALL, Colors::Cornsilk, background); //Allies + CSDL_Ext::printAt(CGI->generaltexth->allTexts[391] + ":", 619, 407, FONT_SMALL, Colors::Cornsilk, background); //Enemies SDL_FreeSurface(panel); //difficulty std::vector difficulty; boost::split(difficulty, CGI->generaltexth->allTexts[492], boost::is_any_of(" ")); - printAtLoc(difficulty.back(), 689, 432, FONT_MEDIUM, Colors::Cornsilk, background); //Difficulty + CSDL_Ext::printAt(difficulty.back(), 689, 432, FONT_MEDIUM, Colors::Cornsilk, background); //Difficulty //difficulty pics for (int b=0; bh || pos.w != to->w) + CMessage::drawBorder(1, to, pos.w+28, pos.h+30, pos.x-14, pos.y-15); } void CBonusSelection::loadPositionsOfGraphics() @@ -2935,18 +2980,19 @@ void CBonusSelection::show(SDL_Surface * to) for (std::map::const_iterator i = sInfo.playerInfos.begin(); i != sInfo.playerInfos.end(); i++) { int *myx = ((i->first == playerColor || ourHeader->players[i->first].team == myT) ? &fx : &ex); - blitAtLoc(sFlags->ourImages[i->first].bitmap, *myx, 405, to); + blitAtLoc(sFlags->ourImages[i->first].bitmap, pos.x + *myx, pos.y + 405, to); *myx += sFlags->ourImages[i->first].bitmap->w; } //difficulty - blitAt(diffPics[sInfo.difficulty], 709, 455, to); + blitAtLoc(diffPics[sInfo.difficulty], 709, 455, to); CIntObject::show(to); } void CBonusSelection::updateBonusSelection() { + OBJ_CONSTRUCTION_CAPTURING_ALL; //graphics: //spell - SPELLBON.DEF //monster - TWCRPORT.DEF @@ -3198,8 +3244,8 @@ CBonusSelection::CRegion::CRegion( CBonusSelection * _owner, bool _accessible, b const SCampPositions & campDsc = owner->campDescriptions[owner->ourCampaign->camp->header.mapVersion]; const SCampPositions::SRegionDesc & desc = campDsc.regions[myNumber]; - pos.x = desc.xpos; - pos.y = desc.ypos; + pos.x += desc.xpos; + pos.y += desc.ypos; //loading of graphics @@ -3255,17 +3301,17 @@ void CBonusSelection::CRegion::show(SDL_Surface * to) if (!accessible) { //show as striped - blitAt(graphics[2], pos.x, pos.y, to); + blitAtLoc(graphics[2], 0, 0, to); } else if (this == owner->highlightedRegion) { //show as selected - blitAt(graphics[1], pos.x, pos.y, to); + blitAtLoc(graphics[1], 0, 0, to); } else { //show as not selected selected - blitAt(graphics[0], pos.x, pos.y, to); + blitAtLoc(graphics[0], 0, 0, to); } } @@ -3573,6 +3619,14 @@ CCampaignScreen::CCampaignScreen(const JsonNode &config) BOOST_FOREACH(const JsonNode& node, config["images"].Vector()) images.push_back(createPicture(node)); + if (!images.empty()) + { + images[0]->center(); // move background to center + moveTo(images[0]->pos.topLeft()); // move everything else to center + images[0]->moveTo(pos.topLeft()); // restore moved twice background + pos = images[0]->pos; // fix height\width of this window + } + if (!config["exitbutton"].isNull()) { back = createExitButton(config["exitbutton"]); @@ -3582,3 +3636,10 @@ CCampaignScreen::CCampaignScreen(const JsonNode &config) BOOST_FOREACH(const JsonNode& node, config["items"].Vector()) campButtons.push_back(new CCampaignButton(node)); } + +void CCampaignScreen::showAll(SDL_Surface *to) +{ + CIntObject::showAll(to); + if (pos.h != to->h || pos.w != to->w) + CMessage::drawBorder(1, to, pos.w+28, pos.h+30, pos.x-14, pos.y-15); +} diff --git a/client/CPreGame.h b/client/CPreGame.h index 2cf12f0df..89d51c922 100644 --- a/client/CPreGame.h +++ b/client/CPreGame.h @@ -66,6 +66,7 @@ public: }; CMenuScreen(const JsonNode& configNode); + void showAll(SDL_Surface * to); void show(SDL_Surface * to); void activate(); void deactivate(); @@ -90,6 +91,7 @@ public: CreditsScreen(); void show(SDL_Surface * to); + void showAll(SDL_Surface * to); void clickLeft(tribool down, bool previousState); void clickRight(tribool down, bool previousState); @@ -274,6 +276,7 @@ public: /// The actual map selection screen which consists of the options and selection tab class CSelectionScreen : public CIntObject, public ISelectionScreenInfo { + bool bordered; public: CPicture *bg; //general bg image InfoCard *card; @@ -308,6 +311,7 @@ public: void postRequest(ui8 what, ui8 dir) OVERRIDE; void postChatMessage(const std::string &txt) OVERRIDE; void propagateNames(); + void showAll(SDL_Surface *to); }; /// Save game screen @@ -479,30 +483,35 @@ public: enum CampaignSet {ROE, AB, SOD, WOG}; CCampaignScreen(const JsonNode &config); + void showAll(SDL_Surface *to); }; /// Handles background screen, loads graphics for victory/loss condition and random town or hero selection class CGPreGame : public CIntObject, public IUpdateable { const JsonNode * const pregameConfig; -public: - CMenuScreen* menu; - - SDL_Surface *nHero, *rHero, *nTown, *rTown; // none/random hero/town imgs - CDefHandler *bonuses; - CDefHandler *victory, *loss; - - CGPreGame(); - ~CGPreGame(); - void update(); - void openSel(CMenuScreen::EState type, CMenuScreen::EMultiMode multi = CMenuScreen::SINGLE_PLAYER); void loadGraphics(); void disposeGraphics(); + CGPreGame(); //Use createIfNotPresent + +public: + CMenuScreen* menu; + + SDL_Surface *background; + SDL_Surface *nHero, *rHero, *nTown, *rTown; // none/random hero/town imgs + CDefHandler *bonuses; + CDefHandler *victory, *loss; + + ~CGPreGame(); + void update(); + void openSel(CMenuScreen::EState type, CMenuScreen::EMultiMode multi = CMenuScreen::SINGLE_PLAYER); + + void showAll(SDL_Surface *to); void openCampaignScreen(std::string name); - static void createIfNotPresent(); + static CGPreGame * create(); }; extern ISelectionScreenInfo *SEL; diff --git a/client/CSoundBase.h b/client/CSoundBase.h index 2f4d44cfb..f06f2d0e1 100644 --- a/client/CSoundBase.h +++ b/client/CSoundBase.h @@ -476,15 +476,15 @@ VCMI_SOUND_NAME(horseLava) VCMI_SOUND_FILE(HORSE07.wav) \ VCMI_SOUND_NAME(horseWater) VCMI_SOUND_FILE(HORSE08.wav) \ VCMI_SOUND_NAME(horseRock) VCMI_SOUND_FILE(HORSE09.wav) \ VCMI_SOUND_NAME(horseFly) VCMI_SOUND_FILE(HORSE10.wav) \ -VCMI_SOUND_NAME(horse20) VCMI_SOUND_FILE(HORSE20.wav) \ -VCMI_SOUND_NAME(horse21) VCMI_SOUND_FILE(HORSE21.wav) \ -VCMI_SOUND_NAME(horse22) VCMI_SOUND_FILE(HORSE22.wav) \ -VCMI_SOUND_NAME(horse23) VCMI_SOUND_FILE(HORSE23.wav) \ -VCMI_SOUND_NAME(horse24) VCMI_SOUND_FILE(HORSE24.wav) \ -VCMI_SOUND_NAME(horse25) VCMI_SOUND_FILE(HORSE25.wav) \ -VCMI_SOUND_NAME(horse26) VCMI_SOUND_FILE(HORSE26.wav) \ -VCMI_SOUND_NAME(horse27) VCMI_SOUND_FILE(HORSE27.wav) \ -VCMI_SOUND_NAME(horse29) VCMI_SOUND_FILE(HORSE29.wav) \ +VCMI_SOUND_NAME(horsePenaltyDirt) VCMI_SOUND_FILE(HORSE20.wav) \ +VCMI_SOUND_NAME(horsePenaltySand) VCMI_SOUND_FILE(HORSE21.wav) \ +VCMI_SOUND_NAME(horsePenaltyGrass) VCMI_SOUND_FILE(HORSE22.wav) \ +VCMI_SOUND_NAME(horsePenaltySnow) VCMI_SOUND_FILE(HORSE23.wav) \ +VCMI_SOUND_NAME(horsePenaltySwamp) VCMI_SOUND_FILE(HORSE24.wav) \ +VCMI_SOUND_NAME(horsePenaltyRough) VCMI_SOUND_FILE(HORSE25.wav) \ +VCMI_SOUND_NAME(horsePenaltySubterranean) VCMI_SOUND_FILE(HORSE26.wav) \ +VCMI_SOUND_NAME(horsePenaltyLava) VCMI_SOUND_FILE(HORSE27.wav) \ +VCMI_SOUND_NAME(horsePenaltyRock) VCMI_SOUND_FILE(HORSE29.wav) \ VCMI_SOUND_NAME(hydraAttack) VCMI_SOUND_FILE(HYDRATTK.wav) \ VCMI_SOUND_NAME(hydraDefend) VCMI_SOUND_FILE(HYDRDFND.wav) \ VCMI_SOUND_NAME(hydraKill) VCMI_SOUND_FILE(HYDRKILL.wav) \ diff --git a/client/FontBase.h b/client/FontBase.h index 7c18bba43..e730dbb29 100644 --- a/client/FontBase.h +++ b/client/FontBase.h @@ -15,12 +15,11 @@ enum EFonts FONT_BIG, FONT_CALLI, FONT_CREDITS, FONT_HIGH_SCORE, FONT_MEDIUM, FONT_SMALL, FONT_TIMES, FONT_TINY, FONT_VERD }; - struct Font { struct Char { - si32 unknown1, width, unknown2, offset; + si32 leftOffset, width, rightOffset; ui8 *pixels; }; @@ -29,7 +28,6 @@ struct Font ui8 *data; - Font(ui8 *Data); ~Font(); int getWidth(const char *text) const; diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index 38f5b2afb..9eed8825c 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -3720,13 +3720,11 @@ CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &Pos, CPlayerInterface newCreatureWin->select(settings["general"]["classicCreatureWindow"].Bool()); fullscreen->select(settings["video"]["fullscreen"].Bool()); - gameResButton = new CAdventureMapButton("", rsHelp, boost::bind(&CSystemOptionsWindow::selectGameRes, this, false), 28, 275,"SYSOB12", SDLK_g); + gameResButton = new CAdventureMapButton("", rsHelp, boost::bind(&CSystemOptionsWindow::selectGameRes, this), 28, 275,"SYSOB12", SDLK_g); } -void CSystemOptionsWindow::selectGameRes(bool pregame) +void CSystemOptionsWindow::selectGameRes() { - assert(pregame == false);//TODO - //TODO: translation and\or config file static const std::string rsLabel = "Select resolution"; static const std::string rsHelp = "Change in-game screen resolution."; @@ -3741,16 +3739,16 @@ void CSystemOptionsWindow::selectGameRes(bool pregame) } GH.pushInt(new CObjectListWindow(items, NULL, rsLabel, rsHelp, - boost::bind(&CSystemOptionsWindow::setGameRes, this, pregame, _1))); + boost::bind(&CSystemOptionsWindow::setGameRes, this, _1))); } -void CSystemOptionsWindow::setGameRes(bool pregame, int index) +void CSystemOptionsWindow::setGameRes(int index) { config::CConfigHandler::GuiOptionsMap::const_iterator iter = conf.guiOptions.begin(); while (index--) iter++; - Settings gameRes = settings.write["video"]["gameRes"]; + Settings gameRes = settings.write["video"]["screenRes"]; gameRes["width"].Float() = iter->first.first; gameRes["height"].Float() = iter->first.second; } diff --git a/client/GUIClasses.h b/client/GUIClasses.h index 0a2fa5f37..8931e2ba9 100644 --- a/client/GUIClasses.h +++ b/client/GUIClasses.h @@ -689,8 +689,8 @@ private: void toggleCreatureWin(bool on); void toggleFullscreen(bool on); - void selectGameRes(bool pregame); - void setGameRes(bool pregame, int index); + void selectGameRes(); + void setGameRes(int index); void pushSDLEvent(int type, int usercode); diff --git a/client/Graphics.cpp b/client/Graphics.cpp index e94126fcf..9bcfd5f9a 100644 --- a/client/Graphics.cpp +++ b/client/Graphics.cpp @@ -730,17 +730,17 @@ Font::Font(ui8 *Data) i = 32; for(int ci = 0; ci < 256; ci++) { - chars[ci].unknown1 = read_le_u32(data + i); i+=4; + chars[ci].leftOffset = read_le_u32(data + i); i+=4; chars[ci].width = read_le_u32(data + i); i+=4; - chars[ci].unknown2 = read_le_u32(data + i); i+=4; + chars[ci].rightOffset = read_le_u32(data + i); i+=4; //if(ci>=30) // tlog0 << ci << ". (" << (char)ci << "). Width: " << chars[ci].width << " U1/U2:" << chars[ci].unknown1 << "/" << chars[ci].unknown2 << std::endl; } for(int ci = 0; ci < 256; ci++) { - chars[ci].offset = read_le_u32(data + i); i+=4; - chars[ci].pixels = data + 4128 + chars[ci].offset; + int offset = read_le_u32(data + i); i+=4; + chars[ci].pixels = data + 4128 + offset; } } @@ -757,7 +757,7 @@ int Font::getWidth(const char *text ) const for(int i = 0; i < length; i++) { ui8 c = text[i]; - ret += chars[c].width + chars[c].unknown1 + chars[c].unknown2; + ret += chars[c].width + chars[c].leftOffset + chars[c].rightOffset; } return ret; @@ -766,7 +766,7 @@ int Font::getWidth(const char *text ) const int Font::getCharWidth( char c ) const { const Char &C = chars[(ui8)c]; - return C.width + C.unknown1 + C.unknown2;; + return C.width + C.leftOffset + C.rightOffset;; } /* diff --git a/client/UIFramework/SDL_Extensions.cpp b/client/UIFramework/SDL_Extensions.cpp index 307bf79ef..3a156515e 100644 --- a/client/UIFramework/SDL_Extensions.cpp +++ b/client/UIFramework/SDL_Extensions.cpp @@ -35,6 +35,19 @@ SDL_Surface * CSDL_Ext::copySurface(SDL_Surface * mod) //returns copy of given s return SDL_ConvertSurface(mod, mod->format, mod->flags); } +template +SDL_Surface * CSDL_Ext::createSurfaceWithBpp(int width, int height) +{ + int rMask = 0, gMask = 0, bMask = 0, aMask = 0; + + Channels::px::r.set((Uint8*)&rMask, 255); + Channels::px::g.set((Uint8*)&gMask, 255); + Channels::px::b.set((Uint8*)&bMask, 255); + Channels::px::a.set((Uint8*)&aMask, 255); + + return SDL_CreateRGBSurface( SDL_SWSURFACE | SDL_SRCALPHA, width, height, bpp * 8, rMask, gMask, bMask, aMask); +} + bool isItIn(const SDL_Rect * rect, int x, int y) { return (x>rect->x && xx+rect->w) && (y>rect->y && yy+rect->h); @@ -230,68 +243,74 @@ void printAt(const std::string & text, int x, int y, TTF_Font * font, SDL_Color SDL_FreeSurface(temp); } - - -void CSDL_Ext::printAt( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=Colors::Cornsilk*/, SDL_Surface * dst/*=screen*/ ) +void CSDL_Ext::printAt( const std::string & text, int dstX, int dstY, EFonts font, SDL_Color color, SDL_Surface * dst) { if(!text.size()) return; if (graphics->fontsTrueType[font]) { - printAt(text,x, y, graphics->fontsTrueType[font], kolor, dst); + printAt(text,dstX, dstY, graphics->fontsTrueType[font], color, dst); return; } assert(dst); assert(font < Graphics::FONTS_NUMBER); - //assume BGR dst surface, TODO - make it general in a tidy way - assert(dst->format->Rshift > dst->format->Gshift); - assert(dst->format->Gshift > dst->format->Bshift); + Rect clipRect; + SDL_GetClipRect(dst, &clipRect); const Font *f = graphics->fonts[font]; const Uint8 bpp = dst->format->BytesPerPixel; - Uint8 *px = NULL; - Uint8 *src = NULL; - TColorPutter colorPutter = getPutterFor(dst, false); + TColorPutter colorPutter = getPutterFor(dst, 0); //if text is in {} braces, we'll ommit them - const int first = (text[0] == '{' ? 1 : 0); - const int beyondEnd = (text[text.size()-1] == '}' ? text.size()-1 : text.size()); + const int textBegin = (text[0] == '{' ? 1 : 0); + const int textEnd = (text[text.size()-1] == '}' ? text.size()-1 : text.size()); - for(int txti = first; txti < beyondEnd; txti++) + SDL_LockSurface(dst); + // for each symbol + for(int index = textBegin; index < textEnd; index++) { - const ui8 c = text[txti]; - x += f->chars[c].unknown1; + const ui8 symbol = text[index]; + dstX += f->chars[symbol].leftOffset; - for(int i = std::max(0, -y); i < f->height && (y + i) < (dst->h - 1); i++) + int lineBegin = std::max(0, clipRect.y - dstY); + int lineEnd = std::min(f->height, clipRect.y + clipRect.h - dstY - 1); + + //for each line in symbol + for(int dy = lineBegin; dy pixels; - px += (y+i) * dst->pitch + x * bpp; - src = f->chars[c].pixels; - src += i * f->chars[c].width;//if we have reached end of surface in previous line + Uint8 *dstLine = (Uint8*)dst->pixels; + Uint8 *srcLine = f->chars[symbol].pixels; - for(int j = std::max(0, -x); j < f->chars[c].width && (j + x) < (dst->w - 1); j++) + dstLine += (dstY+dy) * dst->pitch + dstX * bpp; + srcLine += dy * f->chars[symbol].width; + + int rowBegin = std::max(0, clipRect.x - dstX); + int rowEnd = std::min(f->chars[symbol].width, clipRect.x + clipRect.w - dstX - 1); + + //for each column in line + for(int dx = rowBegin; dx < rowEnd; dx++) { - switch(*src) + Uint8* dstPixel = dstLine + dx*bpp; + switch(*(srcLine + dx)) { case 1: //black "shadow" - memset(px, 0, bpp); + memset(dstPixel, 0, bpp); break; case 255: //text colour - colorPutter(px, kolor.r, kolor.g, kolor.b); + colorPutter(dstPixel, color.r, color.g, color.b); break; } - src++; - px += bpp; } } - x += f->chars[c].width; - x += f->chars[c].unknown2; + dstX += f->chars[symbol].width; + dstX += f->chars[symbol].rightOffset; } + SDL_UnlockSurface(dst); } void printTo(const std::string & text, int x, int y, TTF_Font * font, SDL_Color kolor, SDL_Surface * dst, ui8 quality=2) @@ -483,9 +502,10 @@ Uint32 CSDL_Ext::SDL_GetPixel(SDL_Surface *surface, const int & x, const int & y void CSDL_Ext::alphaTransform(SDL_Surface *src) { + //NOTE: colors #7 & #8 used in some of WoG objects. Don't know how they're handled by H3 assert(src->format->BitsPerPixel == 8); SDL_Color colors[] = {{0,0,0,255}, {0,0,0,214}, {0,0,0,164}, {0,0,0,82}, {0,0,0,128}, - {255,0,0,0}, {255,0,0,0}, {255,0,0,0}, {0,0,0,192}, {0,0,0,192}}; + {255,255,255,0}, {255,255,255,0}, {255,255,255,0}, {0,0,0,192}, {0,0,0,192}}; SDL_SetColors(src, colors, 0, ARRAY_COUNT(colors)); SDL_SetColorKey(src, SDL_SRCCOLORKEY, SDL_MapRGBA(src->format, 0, 0, 0, 255)); @@ -1135,4 +1155,6 @@ std::string CSDL_Ext::trimToFit(std::string text, int widthLimit, EFonts font) return text; } -SDL_Surface * CSDL_Ext::std32bppSurface = NULL; +template SDL_Surface * CSDL_Ext::createSurfaceWithBpp<2>(int, int); +template SDL_Surface * CSDL_Ext::createSurfaceWithBpp<3>(int, int); +template SDL_Surface * CSDL_Ext::createSurfaceWithBpp<4>(int, int); \ No newline at end of file diff --git a/client/UIFramework/SDL_Extensions.h b/client/UIFramework/SDL_Extensions.h index b42b553d4..e02e717ad 100644 --- a/client/UIFramework/SDL_Extensions.h +++ b/client/UIFramework/SDL_Extensions.h @@ -117,7 +117,6 @@ namespace CSDL_Ext { void blitSurface(SDL_Surface * src, SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect); void fillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color); - extern SDL_Surface * std32bppSurface; void SDL_PutPixelWithoutRefresh(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255); void SDL_PutPixelWithoutRefreshIfInSurf(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255); @@ -171,6 +170,8 @@ namespace CSDL_Ext std::string processStr(std::string str, std::vector & tor); //replaces %s in string SDL_Surface * newSurface(int w, int h, SDL_Surface * mod=screen); //creates new surface, with flags/format same as in surface given SDL_Surface * copySurface(SDL_Surface * mod); //returns copy of given surface + template + SDL_Surface * createSurfaceWithBpp(int width, int height); //create surface with give bits per pixels value void VflipSurf(SDL_Surface * surf); //fluipis given surface by vertical axis template diff --git a/client/UIFramework/SDL_Pixels.h b/client/UIFramework/SDL_Pixels.h index ee8790879..1848f6125 100644 --- a/client/UIFramework/SDL_Pixels.h +++ b/client/UIFramework/SDL_Pixels.h @@ -195,18 +195,16 @@ STRONG_INLINE void ColorPutter::PutColor(Uint8 *&ptr, const U template STRONG_INLINE void ColorPutter::PutColorRow(Uint8 *&ptr, const SDL_Color & Color, size_t count) { - static_assert(incrementPtr >= -1 && incrementPtr <= +1, "Invalid incrementPtr value!"); - - Uint8 pixel[bpp]; - Channels::px::r.set(pixel, Color.r); - Channels::px::g.set(pixel, Color.g); - Channels::px::b.set(pixel, Color.b); - Channels::px::a.set(pixel, 0); - - for (size_t i=0; iSlots().begin(); i != h->Slots().end(); ++i) diff --git a/lib/CSpellHandler.h b/lib/CSpellHandler.h index 80b5f5ad8..5d8f9cc5c 100644 --- a/lib/CSpellHandler.h +++ b/lib/CSpellHandler.h @@ -57,7 +57,8 @@ namespace Spells { enum { - SUMMON_BOAT=0, SCUTTLE_BOAT=1, VISIONS=2, VIEW_EARTH=3, DISGUISE=4, VIEW_AIR=5, FLY=6, WATER_WALK=7, DIMENSION_DOOR=8, TOWN_PORTAL=9, + SUMMON_BOAT=0, SCUTTLE_BOAT=1, VISIONS=2, VIEW_EARTH=3, DISGUISE=4, VIEW_AIR=5, + FLY=6, WATER_WALK=7, DIMENSION_DOOR=8, TOWN_PORTAL=9, QUICKSAND=10, LAND_MINE=11, FORCE_FIELD=12, FIRE_WALL=13, EARTHQUAKE=14, MAGIC_ARROW=15, ICE_BOLT=16, LIGHTNING_BOLT=17, IMPLOSION=18,