1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-30 08:57:00 +02:00
vcmi/CMT.cpp
Michał W. Urbańczyk 985b4930e4 Major changes to the GUI. Introduced list of interfaces (listInt) containing pointers to all shown interfaces / windows. Only top layer is active and regularly updated.
Windows should be shown using pushInt and closed with popInt or PopIntTotally (if interface needs to be also deleted).
Some things are not working yet properly, I'll try to fix them ASAP.
2009-04-14 12:47:09 +00:00

339 lines
11 KiB
C++

// CMT.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <boost/algorithm/string.hpp>
#include "boost/filesystem/operations.hpp"
#include <boost/thread.hpp>
#include <SDL_ttf.h>
#include <SDL_mixer.h>
#include "SDL_Extensions.h"
#include "SDL_framerate.h"
#include "CGameInfo.h"
#include "mapHandler.h"
#include "global.h"
#include "CPreGame.h"
#include "CCastleInterface.h"
#include "CConsoleHandler.h"
#include "CCursorHandler.h"
#include "CGameState.h"
#include "CCallback.h"
#include "CPlayerInterface.h"
#include "CAdvmapInterface.h"
#include "hch/CBuildingHandler.h"
#include "hch/CVideoHandler.h"
#include "hch/CHeroHandler.h"
#include "hch/CCreatureHandler.h"
#include "hch/CSpellHandler.h"
#include "hch/CMusicHandler.h"
#include "hch/CLodHandler.h"
#include "hch/CDefHandler.h"
#include "hch/CAmbarCendamo.h"
#include "hch/CGeneralTextHandler.h"
#include "client/Graphics.h"
#include "client/Client.h"
#include "client/CConfigHandler.h"
#include "lib/Connection.h"
#include "lib/VCMI_Lib.h"
#include <cstdlib>
#include "lib/NetPacks.h"
#if __MINGW32__
#undef main
#endif
std::string NAME = NAME_VER + std::string(" (client)"); //application name
SDL_Surface *screen = NULL, *screen2 = NULL; //main screen surface and hlp surface (used to store not-active interfaces layer)
std::queue<SDL_Event*> events;
boost::mutex eventsM;
TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16;
void processCommand(const std::string &message, CClient *&client);
void setScreenRes(int w, int h, int bpp, bool fullscreen);
#ifndef __GNUC__
int _tmain(int argc, _TCHAR* argv[])
#else
int main(int argc, char** argv)
#endif
{
tlog0 << "Starting... " << std::endl;
THC timeHandler tmh, total, pomtime;
CClient *client = NULL;
boost::thread *console = NULL;
std::cout.flags(std::ios::unitbuf);
logfile = new std::ofstream("VCMI_Client_log.txt");
::console = new CConsoleHandler;
*::console->cb = boost::bind(processCommand,_1,boost::ref(client));
console = new boost::thread(boost::bind(&CConsoleHandler::run,::console));
tlog0 <<"Creating console and logfile: "<<pomtime.getDif() << std::endl;
conf.init();
tlog0 <<"Loading settings: "<<pomtime.getDif() << std::endl;
tlog0 << NAME << std::endl;
srand ( time(NULL) );
CPG=NULL;
atexit(SDL_Quit);
CGameInfo * cgi = CGI = new CGameInfo; //contains all global informations about game (texts, lodHandlers, map handler itp.)
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO)==0)
{
setScreenRes(800,600,conf.cc.bpp,conf.cc.fullscreen);
tlog0 <<"\tInitializing screen: "<<pomtime.getDif() << std::endl;
#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.getDif() << std::endl;
TTF_Init();
TNRB16 = TTF_OpenFont("Fonts" PATHSEPARATOR "tnrb.ttf",16);
GEOR13 = TTF_OpenFont("Fonts" PATHSEPARATOR "georgia.ttf",13);
GEOR16 = TTF_OpenFont("Fonts" PATHSEPARATOR "georgia.ttf",16);
GEORXX = TTF_OpenFont("Fonts" PATHSEPARATOR "tnrb.ttf",22);
GEORM = TTF_OpenFont("Fonts" PATHSEPARATOR "georgia.ttf",10);
if(! (TNRB16 && GEOR16 && GEORXX && GEORM))
{
tlog1 << "One of the fonts couldn't be loaded!\n";
throw "One of the fonts couldn't be loaded!\n";
}
atexit(TTF_Quit);
THC tlog0<<"\tInitializing fonts: "<<pomtime.getDif()<<std::endl;
CMusicHandler * mush = new CMusicHandler; //initializing audio
mush->initMusics();
//audio initialized
cgi->mush = mush;
tlog0<<"\tInitializing sound: "<<pomtime.getDif()<<std::endl;
tlog0<<"Initializing screen, fonts and sound handling: "<<tmh.getDif()<<std::endl;
CDefHandler::Spriteh = cgi->spriteh = new CLodHandler();
cgi->spriteh->init("Data" PATHSEPARATOR "H3sprite.lod","Sprites");
BitmapHandler::bitmaph = cgi->bitmaph = new CLodHandler;
cgi->bitmaph->init("Data" PATHSEPARATOR "H3bitmap.lod","Data");
tlog0<<"Loading .lod files: "<<tmh.getDif()<<std::endl;
initDLL(cgi->bitmaph,::console,logfile);
CGI->setFromLib();
tlog0<<"Initializing VCMI_Lib: "<<tmh.getDif()<<std::endl;
pomtime.getDif();
cgi->curh = new CCursorHandler;
cgi->curh->initCursor();
cgi->curh->show();
tlog0<<"Screen handler: "<<pomtime.getDif()<<std::endl;
pomtime.getDif();
graphics = new Graphics();
graphics->loadHeroAnim();
tlog0<<"\tMain graphics: "<<tmh.getDif()<<std::endl;
tlog0<<"Initializing game graphics: "<<tmh.getDif()<<std::endl;
CMessage::init();
tlog0<<"Message handler: "<<tmh.getDif()<<std::endl;
CPreGame * cpg = new CPreGame(); //main menu and submenus
tlog0<<"Initialization CPreGame (together): "<<tmh.getDif()<<std::endl;
tlog0<<"Initialization of VCMI (together): "<<total.getDif()<<std::endl;
cpg->mush = mush;
StartInfo *options = new StartInfo(cpg->runLoop());
if(screen->w != conf.cc.resx || screen->h != conf.cc.resy)
{
setScreenRes(conf.cc.resx,conf.cc.resy,conf.cc.bpp,conf.cc.fullscreen);
}
CClient cl;
if(options->mode == 0) //new game
{
tmh.getDif();
char portc[10];
SDL_itoa(conf.cc.port,portc,10);
CClient::runServer(portc);
tlog0<<"Preparing shared memory and starting server: "<<tmh.getDif()<<std::endl;
tmh.getDif();pomtime.getDif();//reset timers
CConnection *c=NULL;
//wait until server is ready
tlog0<<"Waiting for server... ";
cl.waitForServer();
tlog0 << tmh.getDif()<<std::endl;
while(!c)
{
try
{
tlog0 << "Establishing connection...\n";
c = new CConnection(conf.cc.server,portc,NAME);
}
catch(...)
{
tlog1 << "\nCannot establish connection! Retrying within 2 seconds" <<std::endl;
SDL_Delay(2000);
}
}
THC tlog0<<"\tConnecting to the server: "<<tmh.getDif()<<std::endl;
cl.newGame(c,options);
client = &cl;
boost::thread t(boost::bind(&CClient::run,&cl));
}
else //load game
{
std::string fname = options->mapname;
boost::algorithm::erase_last(fname,".vlgm1");
cl.load(fname);
client = &cl;
boost::thread t(boost::bind(&CClient::run,&cl));
}
SDL_Event *ev = NULL;
while(1) //main SDL events loop
{
ev = new SDL_Event();
int ret = SDL_WaitEvent(ev);
if(ret == 0 || (ev->type==SDL_QUIT) || (ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4 && (ev->key.keysym.mod & KMOD_ALT)))
{
LOCPLINT->pim->lock();
cl.close();
#ifndef __unix__
::console->killConsole(console->native_handle());
#endif
SDL_Delay(750);
tlog0 << "Ending...\n";
exit(EXIT_SUCCESS);
}
else if(ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4)
{
boost::unique_lock<boost::recursive_mutex> lock(*LOCPLINT->pim);
bool full = !(screen->flags&SDL_FULLSCREEN);
setScreenRes(conf.cc.resx,conf.cc.resy,conf.cc.bpp,full);
LOCPLINT->totalRedraw();
}
eventsM.lock();
events.push(ev);
eventsM.unlock();
}
}
else
{
tlog1<<"Something was wrong: "<<SDL_GetError()<<std::endl;
return -1;
}
}
void processCommand(const std::string &message, CClient *&client)
{
std::istringstream readed;
readed.str(message);
std::string cn; //command name
readed >> cn;
int3 src, dst;
// int heronum;//TODO use me
int3 dest;
if(LOCPLINT && LOCPLINT->cingconsole)
LOCPLINT->cingconsole->print(message);
if(message==std::string("die, fool"))
exit(EXIT_SUCCESS);
else if(cn==std::string("activate"))
{
int what;
readed >> what;
switch (what)
{
case 0:
LOCPLINT->topInt()->activate();
break;
case 1:
LOCPLINT->adventureInt->activate();
break;
case 2:
LOCPLINT->castleInt->activate();
break;
}
}
else if(cn=="save")
{
std::string fname;
readed >> fname;
client->save(fname);
}
else if(cn=="load")
{
std::string fname;
readed >> fname;
client->load(fname);
}
else if(cn=="resolution")
{
std::map<std::pair<int,int>, config::GUIOptions >::iterator j;
int i=1, hlp=1;
tlog4 << "Available screen resolutions:\n";
for(j=conf.guiOptions.begin(); j!=conf.guiOptions.end(); j++)
tlog4 << i++ <<". " << j->first.first << " x " << j->first.second << std::endl;
tlog4 << "Type number from 1 to " << i-1 << " to set appropriate resolution or 0 to cancel.\n";
std::cin >> i;
if(!i)
return;
else if(i < 0 || i > conf.guiOptions.size())
{
tlog1 << "Invalid resolution ID! Not a number between 0 and " << conf.guiOptions.size() << ". No settings changed.\n";
}
else
{
for(j=conf.guiOptions.begin(); j!=conf.guiOptions.end() && hlp++<i; j++); //move j to the i-th resolution info
conf.cc.resx = j->first.first;
conf.cc.resy = j->first.second;
tlog0 << "Screen resolution set to " << conf.cc.resx << " x " << conf.cc.resy <<". It will be aplied when the game starts.\n";
}
}
else if(message=="get txt")
{
boost::filesystem::create_directory("Extracted_txts");
tlog0<<"Command accepted. Opening .lod file...\t";
CLodHandler * txth = new CLodHandler;
txth->init(std::string(DATA_DIR "Data" PATHSEPARATOR "H3bitmap.lod"),"");
tlog0<<"done.\nScanning .lod file\n";
int curp=0;
std::string pattern = ".TXT", pom;
for(int i=0;i<txth->entries.size(); i++)
{
pom = txth->entries[i].nameStr;
if(boost::algorithm::find_last(pom,pattern))
{
txth->extractFile(std::string("Extracted_txts\\")+pom,pom);
}
if(i%8) continue;
int p2 = ((float)i/(float)txth->entries.size())*(float)100;
if(p2!=curp)
{
curp = p2;
tlog0<<"\r"<<curp<<"%";
}
}
tlog0<<"\rExtracting done :)\n";
}
else if(client && client->serv && client->serv->connected) //send to server
{
PlayerMessage pm(LOCPLINT->playerID,message);
*client->serv << &pm;
}
}
void setScreenRes(int w, int h, int bpp, bool fullscreen)
{
if(screen) //screen has been already inited
SDL_QuitSubSystem(SDL_INIT_VIDEO);
SDL_InitSubSystem(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(conf.cc.resx,conf.cc.resy,conf.cc.bpp,SDL_SWSURFACE|SDL_DOUBLEBUF|(conf.cc.fullscreen?SDL_FULLSCREEN:0)); //initializing important global surface
if(screen2)
SDL_FreeSurface(screen2);
screen2 = CSDL_Ext::copySurface(screen);
SDL_EnableUNICODE(1);
SDL_WM_SetCaption(NAME.c_str(),""); //set window title
SDL_ShowCursor(SDL_DISABLE);
}