Browse Source

- shadows for CWindowObject-based windows
- better error messages on read error
- fixed crash on level-up window

Ivan Savenko 13 years ago
parent
commit
8c6965c5ee

+ 1 - 1
client/CAnimation.cpp

@@ -942,7 +942,7 @@ void CAnimation::init(CDefFile * file)
 		ui8 * configFile = spriteh->giveFile(name, FILE_TEXT, &size);
 
 		const JsonNode config((char*)configFile, size);
-		delete configFile;
+		delete[] configFile;
 
 		std::string basepath;
 		basepath = config["basepath"].String();

+ 2 - 1
client/CCastleInterface.cpp

@@ -923,6 +923,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
 	pos.w = panel->pos.w;
 	pos.h = builds->pos.h + panel->pos.h;
 	center();
+	updateShadow();
 
 	garr = new CGarrisonInt(305, 387, 4, Point(0,96), panel->bg, Point(62,374), town->getUpperArmy(), town->visitingHero);
 	heroes = new HeroSlots(town, Point(241, 387), Point(241, 483), garr, true);
@@ -1755,7 +1756,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, i
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 
-	statusBar = new CGStatusBar(164, 370);
+	statusBar = new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
 	
 	animBG = new CPicture("TPSMITBK", 64, 50);
 	animBG->needRefresh = true;

+ 0 - 1
client/CCastleInterface.h

@@ -15,7 +15,6 @@ class CMinorResDataBar;
 class CPicture;
 class CResDataBar;
 class CSpell;
-class CStatusBar;
 class CTextBox;
 class CTownList;
 struct Structure;

+ 22 - 26
client/GUIClasses.cpp

@@ -1127,6 +1127,13 @@ void CRecruitmentWindow::clickRight(tribool down, bool previousState)
 void CRecruitmentWindow::showAll(SDL_Surface * to)
 {
 	CWindowObject::showAll(to);
+	drawBorder(to, pos.x + 172, pos.y + 222, 67, 42, int3(239,215,123));
+	drawBorder(to, pos.x + 246, pos.y + 222, 67, 42, int3(239,215,123));
+	drawBorder(to, pos.x + 64,  pos.y + 222, 99, 76, int3(239,215,123));
+	drawBorder(to, pos.x + 322, pos.y + 222, 99, 76, int3(239,215,123));
+	drawBorder(to, pos.x + 133, pos.y + 312, 66, 34, int3(173,142,66));
+	drawBorder(to, pos.x + 211, pos.y + 312, 66, 34, int3(173,142,66));
+	drawBorder(to, pos.x + 289, pos.y + 312, 66, 34, int3(173,142,66));
 
 	char pom[15];
 	SDL_itoa(creatures[which].amount-slider->value,pom,10); //available
@@ -1167,7 +1174,7 @@ CRecruitmentWindow::CRecruitmentWindow(const CGDwelling *Dwelling, int Level, co
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 
 	which = 0;
-	bar = new CGStatusBar(8, 370, "APHLFTRT.bmp", 471);
+	bar = new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
 	max = new CAdventureMapButton(CGI->generaltexth->zelp[553],boost::bind(&CRecruitmentWindow::Max,this),134,313,"IRCBTNS.DEF",SDLK_m);
 	buy = new CAdventureMapButton(CGI->generaltexth->zelp[554],boost::bind(&CRecruitmentWindow::Buy,this),212,313,"IBY6432.DEF",SDLK_RETURN);
 	cancel = new CAdventureMapButton(CGI->generaltexth->zelp[555],boost::bind(&CRecruitmentWindow::Cancel,this),290,313,"ICN6432.DEF",SDLK_ESCAPE);
@@ -1180,14 +1187,7 @@ CRecruitmentWindow::CRecruitmentWindow(const CGDwelling *Dwelling, int Level, co
 	new CLabel(205, 233, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[465]); //available t
 	new CLabel(279, 233, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[16]); //recruit t
 	new CLabel(371, 232, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[466]); //total cost t
-	/*drawBorder(*background,172,222,67,42,int3(239,215,123));
-	drawBorder(*background,246,222,67,42,int3(239,215,123));
-	drawBorder(*background,64,222,99,76,int3(239,215,123));
-	drawBorder(*background,322,222,99,76,int3(239,215,123));
-	drawBorder(*background,133,312,66,34,int3(173,142,66));
-	drawBorder(*background,211,312,66,34,int3(173,142,66));
-	drawBorder(*background,289,312,66,34,int3(173,142,66));
-*/
+
 	//border for creatures
 	int curx = 192 + 50 - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2);
 	for(int i=0;i<creatures.size();i++)
@@ -1331,6 +1331,7 @@ CLevelWindow::CLevelWindow(const CGHeroInstance *hero, int pskill, std::vector<u
 		comps.back()->assignedKeys.insert(SDLK_1 + i);
 	}
 
+	new CAnimImage("PortraitsLarge", hero->portrait, 0, 170, 66);
 	new CAdventureMapButton("", "", boost::bind(&CLevelWindow::close, this), 297, 413, "IOKAY", SDLK_RETURN);
 
 	//%s has gained a level.
@@ -1339,9 +1340,9 @@ CLevelWindow::CLevelWindow(const CGHeroInstance *hero, int pskill, std::vector<u
 
 	//%s is now a level %d %s.
 	new CLabel(192, 162, FONT_MEDIUM, CENTER, Colors::Cornsilk,
-	           boost::str(boost::format(CGI->generaltexth->allTexts[444]) % hero->name % hero->type->heroClass->name));
+	           boost::str(boost::format(CGI->generaltexth->allTexts[445]) % hero->name % hero->level % hero->type->heroClass->name));
 
-	new CAnimImage("PSKILL42", pskill, 0, 174, 190);
+	new CAnimImage("PSKIL42", pskill, 0, 174, 190);
 
 	new CLabel(192, 253, FONT_MEDIUM, CENTER, Colors::Cornsilk,
 	           CGI->generaltexth->primarySkillNames[pskill] + " +1");
@@ -2143,7 +2144,7 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket *Market, const CGHeroInstan
 	madeTransaction = false;
 	bool sliderNeeded = true;
 
-	new CGStatusBar(302, 576);
+	new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
 
 	std::string title;
 
@@ -2620,7 +2621,8 @@ CAltarWindow::CAltarWindow(const IMarket *Market, const CGHeroInstance *Hero /*=
 	//Total experience on the Altar
 	new CTextBox(CGI->generaltexth->allTexts[476], Rect(15, 495, 125, 40), 0, FONT_SMALL, CENTER, Colors::Jasmine);
 
-	new CGStatusBar(302, 576);
+	new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
+
 	ok = new CAdventureMapButton(CGI->generaltexth->zelp[568],boost::bind(&CGuiHandler::popIntTotally,&GH,this),516,520,"IOK6432.DEF",SDLK_RETURN);
 	ok->assignedKeys.insert(SDLK_ESCAPE);
 
@@ -3221,7 +3223,7 @@ CTavernWindow::CTavernWindow(const CGObjectInstance *TavernObj):
 	new CLabel(320, 328, FONT_SMALL, CENTER, Colors::Cornsilk, "2500");
 	new CTextBox(LOCPLINT->cb->getTavernGossip(tavernObj), Rect(32, 190, 330, 68), 0, FONT_SMALL, CENTER, Colors::Cornsilk);
 
-	bar = new CGStatusBar(8, 478, "APHLFTRT.bmp", 380);
+	new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
 	cancel = new CAdventureMapButton(CGI->generaltexth->tavernInfo[7],"", boost::bind(&CTavernWindow::close, this), 310, 428, "ICANCEL.DEF", SDLK_ESCAPE);
 	recruit = new CAdventureMapButton("", "", boost::bind(&CTavernWindow::recruitb, this), 272, 355, "TPTAV01.DEF", SDLK_RETURN);
 	thiefGuild = new CAdventureMapButton(CGI->generaltexth->tavernInfo[5],"", boost::bind(&CTavernWindow::thievesguildb, this), 22, 428, "TPTAV02.DEF", SDLK_t);
@@ -4576,12 +4578,6 @@ void CExchangeWindow::prepareBackground()
 		//mana points
 		new CAnimImage("PSKIL32", 5, 0, 139 + 490*b, 45);
 		new CLabel(155 + 490*b, 71, FONT_SMALL, CENTER, Colors::Cornsilk, makeNumberShort(heroInst[b]->mana));
-
-		//setting morale
-		//blitAt(graphics->morale30->ourImages[heroWArt.MoraleVal()+3].bitmap, 177 + 490*b, 45, bg);
-
-		//setting luck
-		//blitAt(graphics->luck30->ourImages[heroWArt.LuckVal()+3].bitmap, 213 + 490*b, 45, bg);
 	}
 
 	//printing portraits
@@ -4731,7 +4727,7 @@ CShipyardWindow::CShipyardWindow(const std::vector<si32> &cost, int state, int b
 		}
 	}
 
-	statusBar = new CGStatusBar(pos.w/2, pos.h-16);
+	statusBar = new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
 
 	title =     new CLabel(164, 27,  FONT_BIG,    CENTER, Colors::Jasmine, CGI->generaltexth->jktexts[13]);
 	costLabel = new CLabel(164, 220, FONT_MEDIUM, CENTER, Colors::Cornsilk,   CGI->generaltexth->jktexts[14]);
@@ -4886,7 +4882,7 @@ CTransformerWindow::CTransformerWindow(const CGHeroInstance * _hero, const CGTow
 	all    = new CAdventureMapButton(CGI->generaltexth->zelp[590],boost::bind(&CTransformerWindow::addAll,this),     146,416,"ALTARMY.DEF",SDLK_a);
 	convert= new CAdventureMapButton(CGI->generaltexth->zelp[591],boost::bind(&CTransformerWindow::makeDeal,this),   269,416,"ALTSACR.DEF",SDLK_RETURN);
 	cancel = new CAdventureMapButton(CGI->generaltexth->zelp[592],boost::bind(&CTransformerWindow::close, this),392,416,"ICANCEL.DEF",SDLK_ESCAPE);
-	bar    = new CGStatusBar(304, 469);
+	bar    = new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
 }
 
 void CUniversityWindow::CItem::clickLeft(tribool down, bool previousState)
@@ -5014,7 +5010,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
 	cancel = new CAdventureMapButton(CGI->generaltexth->zelp[632],
 		boost::bind(&CUniversityWindow::close, this),200,313,"IOKAY.DEF",SDLK_RETURN);
 
-	bar = new CGStatusBar(232, 371);
+	bar = new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
 }
 
 CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * PARENT, int SKILL, bool available ):
@@ -5051,7 +5047,7 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * PARENT, int SKILL, bo
 
 	cancel = new CAdventureMapButton(CGI->generaltexth->zelp[631],boost::bind(&CUnivConfirmWindow::close, this),
 	         252,299,"ICANCEL.DEF",SDLK_ESCAPE);
-	bar = new CGStatusBar(232, 371);
+	bar = new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
 }
 
 void CUnivConfirmWindow::makeDeal(int skill)
@@ -5092,7 +5088,7 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance *visitor, const CGObjectIn
 	upgradeAll = new CAdventureMapButton(CGI->generaltexth->allTexts[432],"",boost::bind(&CHillFortWindow::makeDeal, this, slotsCount),
 	                                    30, 231, "", SDLK_0, &files);
 	quit = new CAdventureMapButton("","",boost::bind(&CHillFortWindow::close, this), 294, 275, "IOKAY.DEF", SDLK_RETURN);
-	bar = new CGStatusBar(327, 332);
+	bar = new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
 
 	garr = new CGarrisonInt(108, 60, 18, Point(),background->bg,Point(108,60),hero,NULL);
 	updateGarrisons();
@@ -5265,7 +5261,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
 	LOCPLINT->cb->getThievesGuildInfo(tgi, owner);
 
 	exitb = new CAdventureMapButton (CGI->generaltexth->allTexts[600], "", boost::bind(&CThievesGuildWindow::close,this), 748, 556, "TPMAGE1", SDLK_RETURN);
-	statusBar = new CGStatusBar(3, 555, "TStatBar", 742);
+	statusBar = new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
 
 	resdatabar = new CMinorResDataBar();
 	resdatabar->pos.x += pos.x;

+ 132 - 5
client/UIFramework/CIntObjectClasses.cpp

@@ -2,6 +2,7 @@
 #include "CIntObjectClasses.h"
 
 #include "../CBitmapHandler.h"
+#include "SDL_Pixels.h"
 #include "SDL_Extensions.h"
 #include "../Graphics.h"
 #include "../CAnimation.h"
@@ -1341,11 +1342,11 @@ std::string CGStatusBar::getCurrent()
 	return text;
 }
 
-CGStatusBar::CGStatusBar(int x, int y, EFonts Font /*= FONT_SMALL*/, EAlignment Align, const SDL_Color &Color /*= Colors::Cornsilk*/, const std::string &Text /*= ""*/)
-: CLabel(x, y, Font, Align, Color, Text)
-{
-	init();
-}
+//CGStatusBar::CGStatusBar(int x, int y, EFonts Font /*= FONT_SMALL*/, EAlignment Align, const SDL_Color &Color /*= Colors::Cornsilk*/, const std::string &Text /*= ""*/)
+//: CLabel(x, y, Font, Align, Color, Text)
+//{
+//	init();
+//}
 
 CGStatusBar::CGStatusBar(CPicture *BG, EFonts Font /*= FONT_SMALL*/, EAlignment Align /*= CENTER*/, const SDL_Color &Color /*= Colors::Cornsilk*/)
 : CLabel(BG->pos.x, BG->pos.y, Font, Align, Color, "")
@@ -1597,6 +1598,7 @@ void CFocusable::moveFocus()
 
 CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt):
     CIntObject(getUsedEvents(options_), Point()),
+    shadow(nullptr),
     options(options_),
     background(createBg(imageName, options & PLAYER_COLORED))
 {
@@ -1609,10 +1611,14 @@ CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt
 		pos = background->center(centerAt);
 	else
 		center(centerAt);
+
+	if (!(options & SHADOW_DISABLED))
+		setShadow(true);
 }
 
 CWindowObject::CWindowObject(int options_, std::string imageName):
     CIntObject(getUsedEvents(options_), Point()),
+    shadow(nullptr),
     options(options_),
     background(createBg(imageName, options & PLAYER_COLORED))
 {
@@ -1625,6 +1631,14 @@ CWindowObject::CWindowObject(int options_, std::string imageName):
 		pos = background->center();
 	else
 		center(Point(screen->w/2, screen->h/2));
+
+	if (!(options & SHADOW_DISABLED))
+		setShadow(true);
+}
+
+CWindowObject::~CWindowObject()
+{
+	setShadow(false);
 }
 
 CPicture * CWindowObject::createBg(std::string imageName, bool playerColored)
@@ -1649,6 +1663,8 @@ void CWindowObject::setBackground(std::string filename)
 
 	if (background)
 		pos = background->center(Point(pos.w/2 + pos.x, pos.h/2 + pos.y));
+
+	updateShadow();
 }
 
 int CWindowObject::getUsedEvents(int options)
@@ -1658,6 +1674,117 @@ int CWindowObject::getUsedEvents(int options)
 	return 0;
 }
 
+void CWindowObject::updateShadow()
+{
+	setShadow(false);
+	if (!(options & SHADOW_DISABLED))
+		setShadow(true);
+}
+
+void CWindowObject::setShadow(bool on)
+{
+	vstd::clear_pointer(shadow);
+
+	//size of shadow
+	static const int size = 8;
+
+	if (on == bool(shadow))
+		return;
+
+	//object too small to cast shadow
+	if (pos.h <= size || pos.w <= size)
+		return;
+
+	if (on)
+	{
+
+		//helper to set last row
+		auto blitAlphaRow = [](SDL_Surface *surf, size_t row)
+		{
+			Uint8 * ptr = (Uint8*)surf->pixels + surf->pitch * (row);
+
+			for (size_t i=0; i< surf->w; i++)
+			{
+				Channels::px<4>::a.set(ptr, 128);
+				ptr+=4;
+			}
+		};
+
+		// helper to set last column
+		auto blitAlphaCol = [](SDL_Surface *surf, size_t col)
+		{
+			Uint8 * ptr = (Uint8*)surf->pixels + 4 * (col);
+
+			for (size_t i=0; i< surf->h; i++)
+			{
+				Channels::px<4>::a.set(ptr, 128);
+				ptr+= surf->pitch;
+			}
+		};
+
+		static SDL_Surface * shadowCornerTempl = nullptr;
+		static SDL_Surface * shadowBottomTempl = nullptr;
+		static SDL_Surface * shadowRightTempl = nullptr;
+
+		//one-time initialization
+		if (!shadowCornerTempl)
+		{
+			//create "template" surfaces
+			shadowCornerTempl = CSDL_Ext::createSurfaceWithBpp<4>(size, size);
+			shadowBottomTempl = CSDL_Ext::createSurfaceWithBpp<4>(1, size);
+			shadowRightTempl  = CSDL_Ext::createSurfaceWithBpp<4>(size, 1);
+
+			Uint32 shadowColor = SDL_MapRGBA(shadowCornerTempl->format, 0, 0, 0, 192);
+
+			//fill with shadow body color
+			SDL_FillRect(shadowCornerTempl, NULL, shadowColor);
+			SDL_FillRect(shadowBottomTempl, NULL, shadowColor);
+			SDL_FillRect(shadowRightTempl,  NULL, shadowColor);
+
+			//fill last row and column with more transparent color
+			blitAlphaCol(shadowRightTempl , size-1);
+			blitAlphaCol(shadowCornerTempl, size-1);
+			blitAlphaRow(shadowBottomTempl, size-1);
+			blitAlphaRow(shadowCornerTempl, size-1);
+		}
+
+		OBJ_CONSTRUCTION_CAPTURING_ALL;
+
+		//FIXME: do something with this points
+		Point shadowStart;
+		if (options & BORDERED)
+			shadowStart = Point(size - 14, size - 14);
+		else
+			shadowStart = Point(size, size);
+
+		Point shadowPos;
+		if (options & BORDERED)
+			shadowPos = Point(pos.w + 14, pos.h + 14);
+		else
+			shadowPos = Point(pos.w, pos.h);
+
+		Point fullsize;
+		if (options & BORDERED)
+			fullsize = Point(pos.w + 28, pos.h + 29);
+		else
+			fullsize = Point(pos.w, pos.h);
+
+		//create base 8x8 piece of shadow
+		SDL_Surface * shadowCorner = CSDL_Ext::copySurface(shadowCornerTempl);
+		SDL_Surface * shadowBottom = CSDL_Ext::scaleSurfaceFast(shadowBottomTempl, fullsize.x - size, size);
+		SDL_Surface * shadowRight  = CSDL_Ext::scaleSurfaceFast(shadowRightTempl,  size, fullsize.y - size);
+
+		blitAlphaCol(shadowBottom, 0);
+		blitAlphaRow(shadowRight, 0);
+
+		//generate "shadow" object with these 3 pieces in it
+		shadow = new CIntObject;
+		shadow->addChild(new CPicture(shadowCorner, shadowPos.x, shadowPos.y));
+		shadow->addChild(new CPicture(shadowRight,  shadowPos.x, shadowStart.y));
+		shadow->addChild(new CPicture(shadowBottom, shadowStart.x, shadowPos.y));
+	}
+}
+
 void CWindowObject::showAll(SDL_Surface *to)
 {
 	CIntObject::showAll(to);

+ 9 - 4
client/UIFramework/CIntObjectClasses.h

@@ -376,8 +376,7 @@ public:
 };
 
 /// Status bar which is shown at the bottom of the in-game screens
-class CGStatusBar
-	: public CLabel, public IStatusBar
+class CGStatusBar : public CLabel, public IStatusBar
 {
 	void init();
 public:
@@ -389,7 +388,7 @@ public:
 	std::string getCurrent(); //returns currently displayed text
 	void show(SDL_Surface * to); //shows statusbar (with current text)
 
-	CGStatusBar(int x, int y, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color &Color = Colors::Cornsilk, const std::string &Text =  "");
+	//CGStatusBar(int x, int y, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color &Color = Colors::Cornsilk, const std::string &Text =  "");
 	CGStatusBar(CPicture *BG, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color &Color = Colors::Cornsilk); //given CPicture will be captured by created sbar and it's pos will be used as pos for sbar
 	CGStatusBar(int x, int y, std::string name, int maxw=-1); 
 
@@ -472,6 +471,9 @@ class CWindowObject : public CIntObject
 	CPicture * createBg(std::string imageName, bool playerColored);
 	int getUsedEvents(int options);
 
+	CIntObject *shadow;
+	void setShadow(bool on);
+
 	int options;
 
 protected:
@@ -485,12 +487,14 @@ protected:
 	void showAll(SDL_Surface *to);
 	//change or set background image
 	void setBackground(std::string filename);
+	void updateShadow();
 public:
 	enum EOptions
 	{
 		PLAYER_COLORED=1, //background will be player-colored
 		RCLICK_POPUP=2, // window will behave as right-click popup
-		BORDERED=4 // window will have border if current resolution is bigger than size of window
+		BORDERED=4, // window will have border if current resolution is bigger than size of window
+		SHADOW_DISABLED=8 //this window won't display any shadow
 	};
 
 	/*
@@ -500,4 +504,5 @@ public:
 	*/
 	CWindowObject(int options, std::string imageName, Point centerAt);
 	CWindowObject(int options, std::string imageName = "");
+	~CWindowObject();
 };

+ 2 - 1
lib/CLodHandler.cpp

@@ -78,7 +78,8 @@ ui8 * CLodHandler::giveFile(std::string fname, LodFileType type, int * length)
 			result = -1;
 		if(result<0)
 		{
-			tlog1<<"Error in file reading: " << myDir << "/" << ourEntry.realName << std::endl;
+			tlog1<<"Error in file reading: " << ourEntry.realName << std::endl;
+			perror("Last error was: ");//print system error message
 			delete[] outp;
 			return NULL;
 		}

+ 4 - 0
lib/JsonNode.cpp

@@ -21,7 +21,11 @@ JsonNode::JsonNode(std::string filename):
 {
 	FILE * file = fopen(filename.c_str(), "rb");
 	if (!file)
+	{
+		tlog1 << "Failed to open file " << filename << "\n";
+		perror("Last system error was ");
 		return;
+	}
 
 	fseek(file, 0, SEEK_END);
 	size_t datasize = ftell(file);