1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

- pregame will use same resolution as main game

- disabled most of now unused code for changing resolution
- added missing spell effect sounds
- adventure map spells sounds
- remaining fixes for big endian systems
This commit is contained in:
Ivan Savenko 2012-05-18 17:35:46 +00:00
parent d491bc1c3a
commit 45c2809a40
21 changed files with 473 additions and 234 deletions

View File

@ -216,12 +216,6 @@ void CMinimapSurfacesRef::initMap(int level)
void CMinimapSurfacesRef::initFoW(int level)
{
/*for(int g=0; g<FoW.size(); ++g)
{
SDL_FreeSurface(FoW[g]);
}
FoW.clear();*/
const Rect &minimap_pos = adventureInt->minimap.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<mw; i++)
{
for (int j=0; j<mh; j++)
@ -261,7 +255,7 @@ void CMinimapSurfacesRef::initFlaggableObjs(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<mw; i++)
{
for (int j=0; j<mh; j++)
@ -1648,7 +1642,7 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
LOCPLINT->cb->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);

View File

@ -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

View File

@ -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());
}

View File

@ -75,7 +75,7 @@ std::queue<SDL_Event*> 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<std::string>());
}
@ -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<boost::recursive_mutex> 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);
}
*/

View File

@ -242,7 +242,10 @@ void CSoundHandler::initSpellsSounds(const std::vector< ConstTransitivePtr<CSpel
if (vstd::contains(spellSounds, s))
tlog1 << "Spell << " << spellid << " already has a sound" << std::endl;
spellSounds[s] = getSoundID(node["soundfile"].String());
soundBase::soundID sound = getSoundID(node["soundfile"].String());
if (sound == soundBase::invalid)
tlog0 << "Error: invalid sound for id "<< spellid << "\n";
spellSounds[s] = sound;
}
}
}

View File

@ -263,7 +263,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
if(makingTurn && ho->tempOwner == 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 */ )

View File

@ -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

View File

@ -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; y<to->h; y+=background->h)
{
for (int x=0; x<to->w; 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: "<<name<<"\n";
}
void CGPreGame::createIfNotPresent()
CGPreGame *CGPreGame::create()
{
if(!CGP)
CGP = new CGPreGame();
return CGP;
}
CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMultiMode MultiPlayer /*= CMenuScreen::SINGLE_PLAYER*/, const std::map<ui32, std::string> *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<std::string, std::string>(), bind(&CSelectionScreen::startCampaign, this), 411, 529, "SCNRLOD.DEF", SDLK_b);
start = new CAdventureMapButton(std::pair<std::string, std::string>(), 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<FileInfo> &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::function<void(
if (Type != CMenuScreen::campaignList)
{
bg = new CPicture(BitmapHandler::loadBitmap("SCSELBCK.bmp"), 0, 0, true);
pos.w = bg->pos.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::function<void(
FileInfo fi;
fi.inLod = cpm[g].loadFromLod;
fi.name = cpm[g].filename;
toParse.push_back(fi);
if (cpm[g].loadFromLod)
{
toParse.push_back(fi);
allItems.push_back(CMapInfo(false));
}
}
@ -1522,6 +1561,7 @@ InfoCard::InfoCard( bool Network )
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
pos.x += 393;
pos.y += 6;
used = RCLICK;
mapDescription = NULL;
@ -1535,7 +1575,7 @@ InfoCard::InfoCard( bool Network )
}
else
{
bg = new CPicture(BitmapHandler::loadBitmap("GSELPOP1.bmp"), 0, 0, true);
bg = new CPicture("GSELPOP1.bmp", 0, 0);
CGuiHandler::moveChild(bg, this, parent);
auto it = vstd::find(parent->children, 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<std::string> 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; b<ARRAY_COUNT(diffPics); ++b)
@ -2830,6 +2873,8 @@ void CBonusSelection::showAll(SDL_Surface * to)
CIntObject::showAll(to);
show(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 CBonusSelection::loadPositionsOfGraphics()
@ -2935,18 +2980,19 @@ void CBonusSelection::show(SDL_Surface * to)
for (std::map<int, PlayerSettings>::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);
}

View File

@ -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;

View File

@ -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) \

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;;
}
/*

View File

@ -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<int bpp>
SDL_Surface * CSDL_Ext::createSurfaceWithBpp(int width, int height)
{
int rMask = 0, gMask = 0, bMask = 0, aMask = 0;
Channels::px<bpp>::r.set((Uint8*)&rMask, 255);
Channels::px<bpp>::g.set((Uint8*)&gMask, 255);
Channels::px<bpp>::b.set((Uint8*)&bMask, 255);
Channels::px<bpp>::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 && x<rect->x+rect->w) && (y>rect->y && y<rect->y+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<int>(0, clipRect.y - dstY);
int lineEnd = std::min<int>(f->height, clipRect.y + clipRect.h - dstY - 1);
//for each line in symbol
for(int dy = lineBegin; dy <lineEnd; dy++)
{
px = (Uint8*)dst->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);

View File

@ -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<std::string> & 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<int bpp>
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<int bpp>

View File

@ -195,18 +195,16 @@ STRONG_INLINE void ColorPutter<bpp, incrementPtr>::PutColor(Uint8 *&ptr, const U
template<int bpp, int incrementPtr>
STRONG_INLINE void ColorPutter<bpp, incrementPtr>::PutColorRow(Uint8 *&ptr, const SDL_Color & Color, size_t count)
{
static_assert(incrementPtr >= -1 && incrementPtr <= +1, "Invalid incrementPtr value!");
Uint8 pixel[bpp];
Channels::px<bpp>::r.set(pixel, Color.r);
Channels::px<bpp>::g.set(pixel, Color.g);
Channels::px<bpp>::b.set(pixel, Color.b);
Channels::px<bpp>::a.set(pixel, 0);
for (size_t i=0; i<count; i++)
if (count)
{
memcpy(ptr, pixel, bpp);
ptr += bpp * incrementPtr;
Uint8 *pixel = ptr;
PutColor(ptr, Color.r, Color.g, Color.b);
for (size_t i=0; i<count-1; i++)
{
memcpy(ptr, pixel, bpp);
ptr += bpp * incrementPtr;
}
}
}

View File

@ -30,29 +30,13 @@
"video" : {
"type" : "object",
"properties" : {
"gameRes" : {
"type" : "object",
"properties" : {
"width" : { "type" : "number" },
"height" : { "type" : "number" }
},
"default": {"width" : 800, "height": 600 }
},
"menuRes" : {
"type" : "object",
"properties" : {
"width" : { "type" : "number" },
"height" : { "type" : "number" }
},
"default": {"width" : 800, "height": 600 }
},
"screenRes" : {
"type" : "object",
"properties" : {
"width" : { "type" : "number" },
"height" : { "type" : "number" }
},
"default": {"width" : 0, "height": 0 }
"default": {"width" : 800, "height": 600 }
},
"bitsPerPixel" : {
"type" : "number",

View File

@ -4,6 +4,76 @@
{
"spell_sounds":
[
{
"id": 0 ,
"name":"Summon boat",
"soundfile":"SUMMBOAT.wav"
},
{
"id": 1 ,
"name":"Scuttle boat",
"soundfile":"SCUTBOAT.wav"
},
{
"id": 2 ,
"name":"Visions",
"soundfile":"VISIONS.wav"
},
{
"id": 3 ,
"name":"View Earth",
"soundfile":"VIEW.wav"
},
{
"id": 4 ,
"name":"Disguise",
"soundfile":"DISGUISE.wav"
},
{
"id": 5 ,
"name":"View Air",
"soundfile":"VIEW.wav"
},
{
"id": 6 ,
"name":"Fly",
"soundfile":"FLYSPELL.wav"
},
{
"id": 7 ,
"name":"Water walking",
"soundfile":"WATRWALK.wav"
},
{
"id": 8 ,
"name":"Dimension doors",
"soundfile":"TELPTOUT.wav"
},
{
"id": 9 ,
"name":"Town Portal",
"soundfile":"TELPTOUT.wav"
},
{
"id": 10 ,
"name":"Quick sands",
"soundfile":"QUIKSAND.wav"
},
{
"id": 12 ,
"name":"Force field",
"soundfile":"FORCEFLD.wav"
},
{
"id": 13 ,
"name":"Fire wall",
"soundfile":"FIREWALL.wav"
},
{
"id": 14 ,
"name":"Earthquake",
"soundfile":"ERTHQUAK.wav"
},
{
"id": 15,
"soundfile": "MAGICBLT.wav",
@ -19,6 +89,16 @@
"soundfile": "LIGHTBLT.wav",
"name": "lightning bolt"
},
{
"id": 18 ,
"name":"Implosion",
"soundfile":"DECAY.wav"
},
{
"id": 19 ,
"name":"Chaon lighting",
"soundfile":"CHAINLTE.wav"
},
{
"id": 20,
"soundfile": "FROSTING.wav",
@ -29,6 +109,11 @@
"soundfile": "FIREBALL.wav",
"name": "fireball"
},
{
"id": 22 ,
"name":"Inferno",
"soundfile":"FIREBLST.wav"
},
{
"id": 23,
"soundfile": "METEOR.wav",
@ -39,6 +124,11 @@
"soundfile": "DEATHRIP.wav",
"name": "death ripple"
},
{
"id": 25 ,
"name":"Destroy undead",
"soundfile":"COLDRING.wav"
},
{
"id": 26,
"soundfile": "ARMGEDN.wav",
@ -54,6 +144,17 @@
"soundfile": "AIRSHELD.wav",
"name": "air shield"
},
{
"id": 29 ,
"name":"fireshield cast",
"soundfile":"FIRESHIE.wav"
},
// It looks that fireshield has two separate souds. Disabling one of them for now
// {
// "id": 29 ,
// "name":"fireshield effect",
// "soundfile":"FIRESHLD.wav"
// },
{
"id": 30,
"soundfile": "PROTECTA.wav",
@ -83,10 +184,30 @@
"soundfile": "DISPELL.wav",
"name": "dispell"
},
{
"id": 36 ,
"name":"Magic mirror",
"soundfile":"BACKLASH.wav"
},
{
"id": 37 ,
"name":"Cure",
"soundfile":"CURE.wav"
},
{
"id": 38 ,
"name":"Resurrect",
"soundfile":"RESURECT.wav"
},
{
"id": 39,
"soundfile": "ANIMDEAD.wav",
},
{
"id": 40 ,
"name":"Sacrifice",
"soundfile":"SACRIF1.wav"
},
{
"id": 41,
"soundfile": "BLESS.wav",
@ -167,6 +288,21 @@
"soundfile": "FRENZY.wav",
"name": "frenzy"
},
{
"id": 57 ,
"name":"Titan Bolt",
"soundfile":"LIGHTBLT.wav"
},
{
"id": 58 ,
"name":"Counterstrike",
"soundfile":"CNTRSTRK.wav"
},
{
"id": 59 ,
"name":"Berserk",
"soundfile":"BERSERK.wav"
},
{
"id": 60,
"soundfile": "HYPNOTIZ.wav",
@ -181,10 +317,45 @@
"id": 62,
"soundfile": "BLIND.wav",
},
{
"id": 63 ,
"name":"Teleport",
"soundfile":"TELPTOUT.wav"
},
{
"id": 64 ,
"name":"Remove obstacle",
"soundfile":"REMOVEOB.wav"
},
{
"id": 65 ,
"name":"Clone",
"soundfile":"CLONE.wav"
},
{
"id": 66 ,
"name":"Summon elementals",
"soundfile":"SUMNELM.wav"
},
{
"id": 67 ,
"name":"Summon elementals",
"soundfile":"SUMNELM.wav"
},
{
"id": 68 ,
"name":"Summon elementals",
"soundfile":"SUMNELM.wav"
},
{
"id": 69 ,
"name":"Summon elementals",
"soundfile":"SUMNELM.wav"
},
{
"id": 70,
"soundfile": "PARALYZE.wav",
"name": "stone gaze - not sure"
"name": "stone gaze and paralyze"
},
{
"id": 71,
@ -209,11 +380,11 @@
{
"id": 75,
"soundfile": "AGE.wav",
"name": "aging - already used (?)"
"name": "aging"
},
{
"id": 6,
"id": 76,
"soundfile": "DEATHCLD.wav",
"name": "death cloud"
},
@ -240,20 +411,15 @@
]
}
// Missing:
// 18 # implosion
// 22 # inferno
// 25 # destroy undead
// BLIND.wav
// CURE.wav
// HYPNOTIZ.wav
// DEATHBLO.wav
// DRAINLIF.wav
// DRGNSLAY.wav
// DISGUISE.wav
// QUIKSAND.wav
// FIRESHIE.wav fireshield when cast
// FIRESHLD.wav fireshield effect
// ANIMDEAD.wav
// ANTIMAGK.wav
// Several probably missing sounds of creature abilities
// ACID.WAV Acid breath Rust Dragons
// DEATHBLO.WAV Deathblow Death knigts
// DRAINLIF.WAV Drain life Vampires
// FEAR.WAV Fear Azure dragons
// MAGCHDRN.WAV Steal mana Imps
// MAGCHFIL.WAV Steal mana Either for upgrades or for receiving mana by hero
// MAGICRES.WAV Magic resist Dwarves
// MANADRAI.WAV Mana drain Ghosts
// REGENER.WAV Regeneration Ghosts, Trolls
// RESURECT.WAV Resurrection Both archangels and Demons
// SPONTCOMB.WAV Fireball Magogs

View File

@ -4844,7 +4844,7 @@ void CGBonusingObject::onHeroVisit( const CGHeroInstance * h ) const
bonusMove = 400;
break;
case 94: //Stables
sound = soundBase::horse20;
sound = soundBase::STORE;
bool someUpgradeDone = false;
for (TSlots::const_iterator i = h->Slots().begin(); i != h->Slots().end(); ++i)

View File

@ -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,