Example #1
0
void iV_saveImage_JPEG(const char *fileName, const iV_Image *image)
{
	unsigned char *buffer = NULL;
	unsigned char *jpeg = NULL;
	char newfilename[PATH_MAX];
	unsigned int currentRow;
	const unsigned int row_stride = image->width * 3; // 3 bytes per pixel
	PHYSFS_file* fileHandle;
	unsigned char *jpeg_end;

	sstrcpy(newfilename, fileName);
	memcpy(newfilename + strlen(newfilename) - 4, ".jpg", 4);
	fileHandle = PHYSFS_openWrite(newfilename);
	if (fileHandle == NULL)
	{
		debug(LOG_ERROR, "pie_JPEGSaveFile: PHYSFS_openWrite failed (while opening file %s) with error: %s\n", fileName, PHYSFS_getLastError());
		return;
	}

	buffer = (unsigned char *)malloc(sizeof(const char*) * image->height * image->width);  // Suspect it should be sizeof(unsigned char)*3 == 3 here, not sizeof(const char *) == 8.
	if (buffer == NULL)
	{
		debug(LOG_ERROR, "pie_JPEGSaveFile: Couldn't allocate memory\n");
		return;
	}

	// Create an array of scanlines
	for (currentRow = 0; currentRow < image->height; ++currentRow)
	{
		// We're filling the scanline from the bottom up here,
		// otherwise we'd have a vertically mirrored image.
		memcpy(buffer + row_stride * currentRow, &image->bmp[row_stride * (image->height - currentRow - 1)], row_stride);
	}

	jpeg = (unsigned char *)malloc(sizeof(const char*) * image->height * image->width);  // Suspect it should be something else here, but sizeof(const char *) == 8 is hopefully big enough...
	if (jpeg == NULL)
	{
		debug(LOG_ERROR, "pie_JPEGSaveFile: Couldn't allocate memory\n");
		free(buffer);
		return;
	}

	jpeg_end = jpeg_encode_image(buffer, jpeg, 1, JPEG_FORMAT_RGB, image->width, image->height);
	PHYSFS_write(fileHandle, jpeg, jpeg_end - jpeg, 1);

	free(buffer);
	free(jpeg);
	PHYSFS_close(fileHandle);
}
Example #2
0
const char *objInfo(const BASE_OBJECT *psObj)
{
	static char	info[PATH_MAX];

	switch (psObj->type)
	{
	case OBJ_DROID:
	{
		const DROID *psDroid = (const DROID *)psObj;

		return droidGetName(psDroid);
	}
	case OBJ_STRUCTURE:
	{
		const STRUCTURE *psStruct = (const STRUCTURE *)psObj;

		return getName(psStruct->pStructureType->pName);
	}
	case OBJ_FEATURE:
	{
		const FEATURE *psFeat = (const FEATURE *)psObj;

		return getName(psFeat->psStats->pName);
	}
	case OBJ_PROJECTILE:
		sstrcpy(info, "Projectile");	// TODO
		break;
	case OBJ_TARGET:
		sstrcpy(info, "Target");	// TODO
		break;
	default:
		sstrcpy(info, "Unknown object type");
		break;
	}
	return info;
}
Example #3
0
const char* version_getVcsDate()
{
#if (VCS_NUM == 0)
	return "";
#else
	static char vcs_date[sizeof(vcs_date_cstr) - 9] = { '\0' };

	if (vcs_date[0] == '\0')
	{
		sstrcpy(vcs_date, vcs_date_cstr);
	}

	return vcs_date;
#endif
}
Example #4
0
void pie_LoadBackDrop(SCREENTYPE screenType)
{
	char backd[128];

	//randomly load in a backdrop piccy.
	srand( (unsigned)time(NULL) + 17 ); // Use offset since time alone doesn't work very well

	switch (screenType)
	{
		case SCREEN_RANDOMBDROP:
			snprintf(backd, sizeof(backd), "texpages/bdrops/backdrop%i.png", rand() % NUM_BACKDROPS); // Range: 0 to (NUM_BACKDROPS-1)
			break;
		case SCREEN_MISSIONEND:
			sstrcpy(backd, "texpages/bdrops/missionend.png");
			break;

		case SCREEN_CREDITS:
		default:
			sstrcpy(backd, "texpages/bdrops/credits.png");
			break;
	}

	screen_SetBackDropFromFile(backd);
}
Example #5
0
const char* version_getSvnDate()
{
#if (SVN_REV == 0)
	return "";
#else
	static char svn_date[sizeof(svn_date_cstr) - 9] = { '\0' };

	if (svn_date[0] == '\0')
	{
		sstrcpy(svn_date, svn_date_cstr);
	}

	return svn_date;
#endif
}
Example #6
0
/**
 * Safe strcat
 */
static void sstrcat(char *dest,const char*source,size_t size)
{
	size_t length = strlen(dest);

	if (length < size)
	{
		sstrcpy(dest+length,source,size - length);
	}
	else
	{
		LWIP_DEBUGF(GPRS_DEBUG,("gprs: sstrcat() String overflow short size=%u length=%u",size,length));
		LWIP_ASSERT("gprs: sstrcat()",length < size);

	}
}
Example #7
0
// ////////////////////////////////////////////////////////////////////////////
// Host Campaign.
bool hostCampaign(char *sGame, char *sPlayer)
{
	PLAYERSTATS playerStats;
	UDWORD		i;

	debug(LOG_WZ, "Hosting campaign: '%s', player: '%s'", sGame, sPlayer);

	freeMessages();

	// If we had a single player (i.e. campaign) game before this value will
	// have been set to 0. So revert back to the default value.
	if (game.maxPlayers == 0)
	{
		game.maxPlayers = 4;
	}

	if (!NEThostGame(sGame, sPlayer, game.type, 0, 0, 0, game.maxPlayers))
	{
		return false;
	}

	for (i = 0; i < MAX_PLAYERS; i++)
	{
		if (NetPlay.bComms)
		{
			game.skDiff[i] = 0;     	// disable AI
		}
		setPlayerName(i, ""); //Clear custom names (use default ones instead)
	}

	NetPlay.players[selectedPlayer].ready = false;

	ingame.localJoiningInProgress = true;
	ingame.JoiningInProgress[selectedPlayer] = true;
	bMultiPlayer = true;
	bMultiMessages = true; // enable messages

	loadMultiStats(sPlayer, &playerStats);				// stats stuff
	setMultiStats(selectedPlayer, playerStats, false);
	setMultiStats(selectedPlayer, playerStats, true);

	if (!NetPlay.bComms)
	{
		sstrcpy(NetPlay.players[0].name, sPlayer);
	}

	return true;
}
Example #8
0
void initI18n(void)
{
	const char *textdomainDirectory = NULL;

	if (!setLanguage("")) // set to system default
	{
		// no system default?
		debug(LOG_ERROR, "initI18n: No system language found");
	}
#if defined(WZ_OS_WIN)
	{
		// Retrieve an absolute path to the locale directory
		char localeDir[PATH_MAX];
		sstrcpy(localeDir, PHYSFS_getBaseDir());
		sstrcat(localeDir, "\\" LOCALEDIR);

		// Set locale directory and translation domain name
		textdomainDirectory = bindtextdomain(PACKAGE, localeDir);
	}
#else
	#ifdef WZ_OS_MAC
	{
		char resourcePath[PATH_MAX];
		CFURLRef resourceURL = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
		if( CFURLGetFileSystemRepresentation( resourceURL, true, (UInt8 *) resourcePath, PATH_MAX) )
		{
			sstrcat(resourcePath, "/locale");
			textdomainDirectory = bindtextdomain(PACKAGE, resourcePath);
		}
		else
		{
			debug( LOG_ERROR, "Could not change to resources directory." );
		}

		debug(LOG_INFO, "resourcePath is %s", resourcePath);
	}
	#else
	textdomainDirectory = bindtextdomain(PACKAGE, LOCALEDIR);
	#endif
#endif
	if (!textdomainDirectory)
	{
		debug(LOG_ERROR, "initI18n: bindtextdomain failed!");
	}

	(void)bind_textdomain_codeset(PACKAGE, "UTF-8");
	(void)textdomain(PACKAGE);
}
Example #9
0
W_LABEL::W_LABEL(W_LABINIT const *init)
	: WIDGET(init, WIDG_LABEL)
	, FontID(init->FontID)
	, pTip(init->pTip)
{
	if (display == NULL)
	{
		display = labelDisplay;
	}

	aText[0] = '\0';
	if (init->pText)
	{
		sstrcpy(aText, init->pText);
	}
}
Example #10
0
// Generate a new texture page both in the texture page table, and on the graphics card
static int newPage(const char *name, int level, int width, int height, int count)
{
	int texPage = firstPage + ((count + 1) / TILES_IN_PAGE);

	// debug(LOG_TEXTURE, "newPage: texPage=%d firstPage=%d %s %d (%d,%d) (count %d + 1) / %d _TEX_INDEX=%u",
	//      texPage, firstPage, name, level, width, height, count, TILES_IN_PAGE, _TEX_INDEX);
	if (texPage == _TEX_INDEX)
	{
		// We need to create a new texture page; create it and increase texture table to store it
		glGenTextures(1, &_TEX_PAGE[texPage].id);
		_TEX_INDEX++;
	}
	terrainPage = texPage;

	ASSERT(_TEX_INDEX > texPage, "newPage: Index too low (%d > %d)", _TEX_INDEX, texPage);
	ASSERT(_TEX_INDEX < iV_TEX_MAX, "Too many texture pages used");

	sstrcpy(_TEX_PAGE[texPage].name, name);

	pie_SetTexturePage(texPage);

	// Specify first and last mipmap level to be used
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmap_levels - 1);

	// debug(LOG_TEXTURE, "newPage: glTexImage2D(page=%d, level=%d) opengl id=%u", texPage, level, _TEX_PAGE[texPage].id);
	glTexImage2D(GL_TEXTURE_2D, level, wz_texture_compression, width, height, 0,
	             GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	// Use anisotropic filtering, if available, but only max 4.0 to reduce processor burden
	if (GLEW_EXT_texture_filter_anisotropic)
	{
		GLfloat max;

		glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, MIN(4.0f, max));
	}

	return texPage;
}
Example #11
0
/**
 * Send the command to initialize the gprs of the modem.
 */
static void do_modem_init(gprs_t * gprs)
{
	UNTIMEOUT();

    gprs_set_state(gprs,GPRS_STATE_MODEM_INIT);
    sstrcpy(gprs->replyBuffer,"AT+CGDCONT=1,\"IP\",\"",sizeof(gprs->replyBuffer));

#if	GPRS_RUNTIME_APN
    sstrcat(gprs->replyBuffer,gprs->apn,sizeof(gprs->replyBuffer));
#else
    sstrcat(gprs->replyBuffer,GPRS_APN,sizeof(gprs->replyBuffer));
#endif

    sstrcat(gprs->replyBuffer,"\"",sizeof(gprs->replyBuffer));

    gprs_command(gprs,gprs->replyBuffer,'\r');

}
Example #12
0
/* Allocate a RES_TYPE structure */
static RES_TYPE* resAlloc(const char *pType)
{
	RES_TYPE	*psT;

#ifdef DEBUG
	// Check for a duplicate type
	for(psT = psResTypes; psT; psT = psT->psNext)
	{
		ASSERT(strcmp(psT->aType, pType) != 0, "Duplicate function for type: %s", pType);
	}
#endif

	// setup the structure
	psT = (RES_TYPE *)malloc(sizeof(RES_TYPE));
	sstrcpy(psT->aType, pType);
	psT->HashedType = HashString(psT->aType); // store a hased version for super speed !
	psT->psRes = NULL;

	return psT;
}
Example #13
0
static bool recvBeacon(NETQUEUE queue)
{
	int32_t sender, receiver,locX, locY;
	char    msg[MAX_CONSOLE_STRING_LENGTH];

	NETbeginDecode(queue, NET_BEACONMSG);
	    NETint32_t(&sender);            // the actual sender
	    NETint32_t(&receiver);          // the actual receiver (might not be the same as the one we are actually sending to, in case of AIs)
	    NETint32_t(&locX);
	    NETint32_t(&locY);
	    NETstring(msg, sizeof(msg));    // Receive the actual message
	NETend();

	debug(LOG_WZ, "Received beacon for player: %d, from: %d",receiver, sender);

	sstrcat(msg, NetPlay.players[sender].name);    // name
	sstrcpy(beaconReceiveMsg[sender], msg);

	return addBeaconBlip(locX, locY, receiver, sender, beaconReceiveMsg[sender]);
}
Example #14
0
/*!
 * Register searchPath above the path with next lower priority
 * For information about what can be a search path, refer to PhysFS documentation
 */
void registerSearchPath( const char path[], unsigned int priority )
{
	wzSearchPath * curSearchPath = searchPathRegistry, * tmpSearchPath = NULL;

	tmpSearchPath = (wzSearchPath*)malloc(sizeof(*tmpSearchPath));
	sstrcpy(tmpSearchPath->path, path);
	if (path[strlen(path)-1] != *PHYSFS_getDirSeparator())
		sstrcat(tmpSearchPath->path, PHYSFS_getDirSeparator());
	tmpSearchPath->priority = priority;

	debug( LOG_WZ, "registerSearchPath: Registering %s at priority %i", path, priority );
	if ( !curSearchPath )
	{
		searchPathRegistry = tmpSearchPath;
		searchPathRegistry->lowerPriority = NULL;
		searchPathRegistry->higherPriority = NULL;
		return;
	}

	while( curSearchPath->higherPriority && priority > curSearchPath->priority )
		curSearchPath = curSearchPath->higherPriority;
	while( curSearchPath->lowerPriority && priority < curSearchPath->priority )
		curSearchPath = curSearchPath->lowerPriority;

	if ( priority < curSearchPath->priority )
	{
	        tmpSearchPath->lowerPriority = curSearchPath->lowerPriority;
        	tmpSearchPath->higherPriority = curSearchPath;
	}
	else
	{
		tmpSearchPath->lowerPriority = curSearchPath;
		tmpSearchPath->higherPriority = curSearchPath->higherPriority;
	}

	if( tmpSearchPath->lowerPriority )
		tmpSearchPath->lowerPriority->higherPriority = tmpSearchPath;
	if( tmpSearchPath->higherPriority )
		tmpSearchPath->higherPriority->lowerPriority = tmpSearchPath;
}
Example #15
0
bool OverrideRPTDirectory(char *newPath)
{
# if defined(WZ_CC_MINGW)
	wchar_t buf[MAX_PATH];

	if (!MultiByteToWideChar(CP_UTF8, 0, newPath, -1, buf, MAX_PATH))
	{
		//conversion failed-- we won't use the user's directory.

		LPVOID lpMsgBuf;
		DWORD dw = GetLastError();
		TCHAR szBuffer[4196];

		FormatMessage(
		    FORMAT_MESSAGE_ALLOCATE_BUFFER |
		    FORMAT_MESSAGE_FROM_SYSTEM |
		    FORMAT_MESSAGE_IGNORE_INSERTS,
		    NULL,
		    dw,
		    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		    (LPTSTR) &lpMsgBuf,
		    0, NULL);

		wsprintf(szBuffer, _T("Exception handler failed setting new directory with error %d: %s\n"), dw, lpMsgBuf);
		MessageBox((HWND)MB_ICONEXCLAMATION, szBuffer, _T("Error"), MB_OK);

		LocalFree(lpMsgBuf);

		return false;
	}
	PathRemoveFileSpecW(buf);
	wcscat(buf, L"\\logs\\"); // stuff it in the logs directory
	wcscat(buf, L"Warzone2100.RPT");
	ResetRPTDirectory(buf);
#elif defined(WZ_OS_UNIX) && !defined(WZ_OS_MAC)
	sstrcpy(WritePath, newPath);
#endif
	return true;
}
Example #16
0
//add a sequence to the list to be played
void seq_AddSeqToList(const char *pSeqName, const char *pAudioName, const char *pTextName, BOOL bLoop)
{
	currentSeq++;

	ASSERT(currentSeq < MAX_SEQ_LIST, "too many sequences");
	if (currentSeq >=  MAX_SEQ_LIST)
	{
		return;
	}

	//OK so add it to the list
	aSeqList[currentSeq].pSeq = pSeqName;
	aSeqList[currentSeq].pAudio = pAudioName;
	aSeqList[currentSeq].bSeqLoop = bLoop;
	if (pTextName != NULL)
	{
		// Ordinary text shouldn't be justified
		seq_AddTextFromFile(pTextName, SEQ_TEXT_POSITION);
	}

	if (bSeqSubtitles)
	{
		char aSubtitleName[MAX_STR_LENGTH];
		size_t check_len = sstrcpy(aSubtitleName, pSeqName);
		char* extension;

		ASSERT(check_len < sizeof(aSubtitleName), "given sequence name (%s) longer (%lu) than buffer (%lu)", pSeqName, (unsigned long) check_len, (unsigned long) sizeof(aSubtitleName));

		// check for a subtitle file
		extension = strrchr(aSubtitleName, '.');
		if (extension)
			*extension = '\0';
		check_len = sstrcat(aSubtitleName, ".txt");
		ASSERT(check_len < sizeof(aSubtitleName), "sequence name to long to attach an extension too");

		// Subtitles should be center justified
		seq_AddTextFromFile(aSubtitleName, SEQ_TEXT_JUSTIFY);
	}
}
Example #17
0
// ////////////////////////////////////////////////////////////////////////////
static void displayLoadSlot(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset)
{
	int x = xOffset + psWidget->x();
	int y = yOffset + psWidget->y();
	char  butString[64];

	drawBlueBox(x, y, psWidget->width(), psWidget->height());  //draw box

	if (!((W_BUTTON *)psWidget)->pText.isEmpty())
	{
		sstrcpy(butString, ((W_BUTTON *)psWidget)->pText.toUtf8().constData());

		iV_SetFont(font_regular);									// font
		iV_SetTextColour(WZCOL_FORM_TEXT);

		while(iV_GetTextWidth(butString) > psWidget->width())
		{
			butString[strlen(butString)-1]='\0';
		}

		//draw text
		iV_DrawText( butString, x+4, y+17);
	}
}
/**
 * Setup the exception handler responsible for target OS.
 *
 * \param programCommand Command used to launch this program. Only used for POSIX handler.
 */
void setupExceptionHandler(int argc, const char ** argv)
{
#if defined(WZ_OS_UNIX) && !defined(WZ_OS_MAC)
	const char *programCommand;
	time_t currentTime;
#endif
#if !defined(WZ_OS_MAC)
	// Initialize info required for the debug dumper
	dbgDumpInit(argc, argv);
#endif

#if defined(WZ_OS_WIN)
# if defined(WZ_CC_MINGW)
	ExchndlSetup();
# else
	prevExceptionHandler = SetUnhandledExceptionFilter(windowsExceptionHandler);
# endif // !defined(WZ_CC_MINGW)
#elif defined(WZ_OS_UNIX) && !defined(WZ_OS_MAC)
	programCommand = argv[0];

	// Get full path to this program. Needed for gdb to find the binary.
	programIsAvailable = fetchProgramPath(programPath, sizeof(programPath), programCommand);

	// Get full path to 'gdb'
	gdbIsAvailable = fetchProgramPath(gdbPath, sizeof(gdbPath), "gdb");

	sysInfoValid = (uname(&sysInfo) == 0);

	currentTime = time(NULL);
	sstrcpy(executionDate, ctime(&currentTime));

	snprintf(programPID, sizeof(programPID), "%i", getpid());

	setFatalSignalHandler(posixExceptionHandler);
#endif // WZ_OS_*
}
Example #19
0
//AI multiplayer message - received message from AI (from scripts)
bool recvTextMessageAI(NETQUEUE queue)
{
	UDWORD	sender, receiver;
	char	msg[MAX_CONSOLE_STRING_LENGTH];
	char	newmsg[MAX_CONSOLE_STRING_LENGTH];

	NETbeginDecode(queue, NET_AITEXTMSG);
		NETuint32_t(&sender);			//in-game player index ('normal' one)
		NETuint32_t(&receiver);			//in-game player index
		NETstring(newmsg,MAX_CONSOLE_STRING_LENGTH);
	NETend();

	if (whosResponsible(sender) != queue.index)
	{
		sender = queue.index;  // Fix corrupted sender.
	}

	//sstrcpy(msg, getPlayerName(sender));  // name
	//sstrcat(msg, " : ");                  // seperator
	sstrcpy(msg, newmsg);
	triggerEventChat(sender, receiver, newmsg);

	//Display the message and make the script callback
	displayAIMessage(msg, sender, receiver);

	//Received a console message from a player callback
	//store and call later
	//-------------------------------------------------
	if(!msgStackPush(CALL_AI_MSG,sender,receiver,msg,-1,-1,NULL))
	{
		debug(LOG_ERROR, "recvTextMessageAI() - msgStackPush - stack failed");
		return false;
	}

	return true;
}
VOID SetWinTitle(HWND hwnd, PATTMAN pam) {
   CHAR buf[LPATH + 32];

   dprintf("Settaggio titolo finestra\n");
   DlgLboxQueryItemText(hwnd, LB_FILE, pam->fsp.psSel[1], buf, LPATH + 32);
   // se Å  una dir ed Å  attiva opzione Selez All files in directory legge
   // attr primo file selezionato e titolo = nomedir\*.*
   if (pam->pro.sel.extsel && pam->pro.sel.dir &&
       pam->fsp.pszFile[0] == '\\' && pam->fsp.psSel[0]) {
      sstrcpy(pam->fsp.pszFile, buf); //copia in pszFile nome Iø file selez
      sprintf(buf, "%s%s%s & *.*", pam->fsp.pszPath,
              (pam->fsp.pszPath[3]? "\\": ""), pam->fsp.pszFile);
   // se Å  una dir con opzione SelectAll non attiva o non ci sono file selez
   // legge attr dir corrente e titolo = nomedir\.
   } else if (pam->fsp.pszFile[0] == '\\' || !pam->fsp.psSel[0]) {
      if (!pam->fsp.psSel[0]) MyDlgLboxSelectItem(hwnd, LB_FILE, 0);
      pam->fsp.pszFile[0] = '.'; pam->fsp.pszFile[1] = 0;
      sstrcpy(buf, pam->fsp.pszPath);
      sstrcat(buf, pam->fsp.pszPath[3]? "\\.": ".");
   // se Å  un file specificato con una mask di wildchar e ci sono + file
   // selez legge attr primo file e titolo = nomefile & mask
   } else if (isWildCh(pam->fsp.pszFile) && pam->fsp.psSel[0] > 1) {
      char tmp[256];
      sstrcpy(tmp, buf);
      sprintf(buf, "%s%s%s & %s", pam->fsp.pszPath,
              (pam->fsp.pszPath[3]? "\\": ""), tmp, pam->fsp.pszFile);
      sstrcpy(pam->fsp.pszFile, tmp);
   // pi— file selezionati non secondo una mask di wildchars
   } else if (pam->fsp.psSel[0] > 1) {
      sstrcpy(pam->fsp.pszFile, buf);
      sprintf(buf, "%s%s%s & ...", pam->fsp.pszPath,
              (pam->fsp.pszPath[3]? "\\": ""), pam->fsp.pszFile);
   // un solo file selezionato
   } else {
      sstrcpy(pam->fsp.pszFile, buf);
      sprintf(buf, "%s%s%s", pam->fsp.pszPath,
              (pam->fsp.pszPath[3]? "\\": ""), pam->fsp.pszFile);
   } // endif   ---  se Å  autoimport e subject e comment sono vuoti
   WinSetWindowText(hwnd, buf);
}
Example #21
0
/*!
 * \brief Rebuilds the PHYSFS searchPath with mode specific subdirs
 *
 * Priority:
 * maps > mods > base > base.wz
 */
bool rebuildSearchPath( searchPathMode mode, bool force )
{
	static searchPathMode current_mode = mod_clean;
	static std::string current_current_map;
	wzSearchPath * curSearchPath = searchPathRegistry;
	char tmpstr[PATH_MAX] = "\0";

	if (mode != current_mode || (current_map != NULL? current_map : "") != current_current_map || force ||
	    (use_override_mods && strcmp(override_mod_list, getModList())))
	{
		if (mode != mod_clean)
		{
			rebuildSearchPath( mod_clean, false );
		}

		current_mode = mode;
		current_current_map = current_map != NULL? current_map : "";

		// Start at the lowest priority
		while( curSearchPath->lowerPriority )
			curSearchPath = curSearchPath->lowerPriority;

		switch ( mode )
		{
			case mod_clean:
				debug(LOG_WZ, "Cleaning up");
				clearLoadedMods();

				while( curSearchPath )
				{
#ifdef DEBUG
					debug(LOG_WZ, "Removing [%s] from search path", curSearchPath->path);
#endif // DEBUG
					// Remove maps and mods
					removeSubdirs( curSearchPath->path, "maps", NULL );
					removeSubdirs( curSearchPath->path, "mods/music", NULL );
					removeSubdirs( curSearchPath->path, "mods/global", NULL );
					removeSubdirs( curSearchPath->path, "mods/campaign", NULL );
					removeSubdirs( curSearchPath->path, "mods/multiplay", NULL );
					removeSubdirs( curSearchPath->path, "mods/autoload", NULL );

					// Remove multiplay patches
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "mp");
					PHYSFS_removeFromSearchPath( tmpstr );
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "mp.wz");
					PHYSFS_removeFromSearchPath( tmpstr );

					// Remove plain dir
					PHYSFS_removeFromSearchPath( curSearchPath->path );

					// Remove base files
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base");
					PHYSFS_removeFromSearchPath( tmpstr );
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base.wz");
					PHYSFS_removeFromSearchPath( tmpstr );

					// remove video search path as well
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "sequences.wz");
					PHYSFS_removeFromSearchPath( tmpstr );
					curSearchPath = curSearchPath->higherPriority;
				}
				break;
			case mod_campaign:
				debug(LOG_WZ, "*** Switching to campaign mods ***");
				clearLoadedMods();

				while (curSearchPath)
				{
					// make sure videos override included files
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "sequences.wz");
					PHYSFS_addToSearchPath(tmpstr, PHYSFS_APPEND);
					curSearchPath = curSearchPath->higherPriority;
				}
				curSearchPath = searchPathRegistry;
				while (curSearchPath->lowerPriority)
					curSearchPath = curSearchPath->lowerPriority;
				while( curSearchPath )
				{
#ifdef DEBUG
					debug(LOG_WZ, "Adding [%s] to search path", curSearchPath->path);
#endif // DEBUG
					// Add global and campaign mods
					PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND );

					addSubdirs( curSearchPath->path, "mods/music", PHYSFS_APPEND, NULL, false );
					addSubdirs( curSearchPath->path, "mods/global", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true );
					addSubdirs( curSearchPath->path, "mods", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true );
					addSubdirs( curSearchPath->path, "mods/autoload", PHYSFS_APPEND, use_override_mods?override_mods:NULL, true );
					addSubdirs( curSearchPath->path, "mods/campaign", PHYSFS_APPEND, use_override_mods?override_mods:campaign_mods, true );
					if (!PHYSFS_removeFromSearchPath( curSearchPath->path ))
					{
						debug(LOG_WZ, "* Failed to remove path %s again", curSearchPath->path);
					}

					// Add plain dir
					PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND );

					// Add base files
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base.wz");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );

					curSearchPath = curSearchPath->higherPriority;
				}
				break;
			case mod_multiplay:
				debug(LOG_WZ, "*** Switching to multiplay mods ***");
				clearLoadedMods();

				while (curSearchPath)
				{
					// make sure videos override included files
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "sequences.wz");
					PHYSFS_addToSearchPath(tmpstr, PHYSFS_APPEND);
					curSearchPath = curSearchPath->higherPriority;
				}
				// Add the selected map first, for mapmod support
				if (current_map != NULL)
				{
					std::string realPathAndDir = std::string(PHYSFS_getRealDir(current_map)) + current_map;
					PHYSFS_addToSearchPath(realPathAndDir.c_str(), PHYSFS_APPEND);
				}
				curSearchPath = searchPathRegistry;
				while (curSearchPath->lowerPriority)
					curSearchPath = curSearchPath->lowerPriority;
				while( curSearchPath )
				{
#ifdef DEBUG
					debug(LOG_WZ, "Adding [%s] to search path", curSearchPath->path);
#endif // DEBUG
					// Add global and multiplay mods
					PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND );
					addSubdirs( curSearchPath->path, "mods/music", PHYSFS_APPEND, NULL, false );
					addSubdirs( curSearchPath->path, "mods/global", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true );
					addSubdirs( curSearchPath->path, "mods", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true );
					addSubdirs( curSearchPath->path, "mods/autoload", PHYSFS_APPEND, use_override_mods?override_mods:NULL, true );
					addSubdirs( curSearchPath->path, "mods/multiplay", PHYSFS_APPEND, use_override_mods?override_mods:multiplay_mods, true );
					PHYSFS_removeFromSearchPath( curSearchPath->path );

					// Add multiplay patches
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "mp");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "mp.wz");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );

					// Add plain dir
					PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND );

					// Add base files
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base.wz");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );

					curSearchPath = curSearchPath->higherPriority;
				}
				break;
			default:
				debug(LOG_ERROR, "Can't switch to unknown mods %i", mode);
				return false;
		}
		if (use_override_mods && mode != mod_clean)
		{
			if (strcmp(getModList(),override_mod_list))
			{
				debug(LOG_POPUP, _("The required mod could not be loaded: %s\n\nWarzone will try to load the game without it."), override_mod_list);
			}
			clearOverrideMods();
			current_mode = mod_override;
		}

		// User's home dir must be first so we allways see what we write
		PHYSFS_removeFromSearchPath(PHYSFS_getWriteDir());
		PHYSFS_addToSearchPath( PHYSFS_getWriteDir(), PHYSFS_PREPEND );

#ifdef DEBUG
		printSearchPath();
#endif // DEBUG
	}
	else if (use_override_mods)
	{
		// override mods are already the same as current mods, so no need to do anything
		clearOverrideMods();
	}
	return true;
}
Example #22
0
// load up the data for a level
bool levLoadData(const char* name, char *pSaveName, GAME_TYPE saveType)
{
	LEVEL_DATASET	*psNewLevel, *psBaseData, *psChangeLevel;
	SDWORD			i;
	bool            bCamChangeSaveGame;

	debug(LOG_WZ, "Loading level %s (%s, type %d)", name, pSaveName, (int)saveType);
	if (saveType == GTYPE_SAVE_START || saveType == GTYPE_SAVE_MIDMISSION)
	{
		if (!levReleaseAll())
		{
			debug(LOG_ERROR, "Failed to unload old data");
			return false;
		}
	}

	levelLoadType = saveType;

	// find the level dataset
	psNewLevel = levFindDataSet(name);
	if (psNewLevel == NULL)
	{
		debug(LOG_WZ, "Dataset %s not found - trying to load as WRF", name);
		return levLoadSingleWRF(name);
	}
	debug(LOG_WZ, "** Data set found is %s type %d", psNewLevel->pName, (int)psNewLevel->type);

	/* Keep a copy of the present level name */
	sstrcpy(currentLevelName, name);

	bCamChangeSaveGame = false;
	if (pSaveName && saveType == GTYPE_SAVE_START)
	{
		if (psNewLevel->psChange != NULL)
		{
			bCamChangeSaveGame = true;
			debug(LOG_WZ, "** CAMCHANGE FOUND");
		}
	}

	// select the change dataset if there is one
	psChangeLevel = NULL;
	if (((psNewLevel->psChange != NULL) && (psCurrLevel != NULL)) || bCamChangeSaveGame)
	{
		//store the level name
		debug(LOG_WZ, "Found CAMCHANGE dataset");
		psChangeLevel = psNewLevel;
		psNewLevel = psNewLevel->psChange;
	}

	// ensure the correct dataset is loaded
	if (psNewLevel->type == LDS_CAMPAIGN)
	{
		debug(LOG_ERROR, "Cannot load a campaign dataset (%s)", psNewLevel->pName);
		return false;
	}
	else
	{
		if (psCurrLevel != NULL)
		{
			if ((psCurrLevel->psBaseData != psNewLevel->psBaseData) ||
				(psCurrLevel->type < LDS_NONE && psNewLevel->type  >= LDS_NONE) ||
				(psCurrLevel->type >= LDS_NONE && psNewLevel->type  < LDS_NONE))
			{
				// there is a dataset loaded but it isn't the correct one
				debug(LOG_WZ, "Incorrect base dataset loaded (%p != %p, %d - %d)",
				      psCurrLevel->psBaseData, psNewLevel->psBaseData, (int)psCurrLevel->type, (int)psNewLevel->type);
				if (!levReleaseAll())	// this sets psCurrLevel to NULL
				{
					return false;
				}
			}
			else
			{
				debug(LOG_WZ, "Correct base dataset already loaded.");
			}
		}

		// setup the correct dataset to load if necessary
		if (psCurrLevel == NULL)
		{
			if (psNewLevel->psBaseData != NULL)
			{
				debug(LOG_WZ, "Setting base dataset to load: %s", psNewLevel->psBaseData->pName);
			}
			psBaseData = psNewLevel->psBaseData;
		}
		else
		{
			debug(LOG_WZ, "No base dataset to load");
			psBaseData = NULL;
		}
	}

	setCurrentMap(psNewLevel->pName, psNewLevel->players);
	if (!rebuildSearchPath(psNewLevel->dataDir, true))
	{
		return false;
	}

	// reset the old mission data if necessary
	if (psCurrLevel != NULL)
	{
		debug(LOG_WZ, "Reseting old mission data");
		if (!levReleaseMissionData())
		{
			return false;
		}
	}

	// need to free the current map and droids etc for a save game
	if ((psBaseData == NULL) &&
		(pSaveName != NULL))
	{
		if (!saveGameReset())
		{
			return false;
		}
	}

	// initialise if necessary
	if (psNewLevel->type == LDS_COMPLETE || //psNewLevel->type >= LDS_MULTI_TYPE_START ||
		psBaseData != NULL)
	{
		debug(LOG_WZ, "Calling stageOneInitialise!");
		if (!stageOneInitialise())
		{
			return false;
		}
	}

	// load up a base dataset if necessary
	if (psBaseData != NULL)
	{
		debug(LOG_WZ, "Loading base dataset %s", psBaseData->pName);
		for(i=0; i<LEVEL_MAXFILES; i++)
		{
			if (psBaseData->apDataFiles[i])
			{
				// load the data
				debug(LOG_WZ, "Loading [directory: %s] %s ...", PHYSFS_getRealDir(psBaseData->apDataFiles[i]), psBaseData->apDataFiles[i]);
				if (!resLoad(psBaseData->apDataFiles[i], i))
				{
					return false;
				}
			}
		}
	}
	if (psNewLevel->type == LDS_CAMCHANGE)
	{
		if (!campaignReset())
		{
			return false;
		}
	}
	if (psNewLevel->game == -1)  //no .gam file to load - BETWEEN missions (for Editor games only)
	{
		ASSERT( psNewLevel->type == LDS_BETWEEN,
			"levLoadData: only BETWEEN missions do not need a .gam file" );
		debug(LOG_WZ, "No .gam file for level: BETWEEN mission");
		if (pSaveName != NULL)
		{
			if (psBaseData != NULL)
			{
				if (!stageTwoInitialise())
				{
					return false;
				}
			}

			//set the mission type before the saveGame data is loaded
			if (saveType == GTYPE_SAVE_MIDMISSION)
			{
				debug(LOG_WZ, "Init mission stuff");
				if (!startMissionSave(psNewLevel->type))
				{
					return false;
				}

				debug(LOG_NEVER, "dataSetSaveFlag");
				dataSetSaveFlag();
			}

			debug(LOG_NEVER, "Loading savegame: %s", pSaveName);
			if (!loadGame(pSaveName, false, true,true))
			{
				return false;
			}
		}

		if ((pSaveName == NULL) ||
			(saveType == GTYPE_SAVE_START))
		{
			debug(LOG_NEVER, "Start mission - no .gam");
			if (!startMission((LEVEL_TYPE)psNewLevel->type, NULL))
			{
				return false;
			}
		}
	}

	//we need to load up the save game data here for a camchange
	if (bCamChangeSaveGame)
	{
		if (pSaveName != NULL)
		{
			if (psBaseData != NULL)
			{
				if (!stageTwoInitialise())
				{
					return false;
				}
			}

			debug(LOG_NEVER, "loading savegame: %s", pSaveName);
			if (!loadGame(pSaveName, false, true,true))
			{
				return false;
			}

			if (!campaignReset())
			{
				return false;
			}
		}
	}


	// load the new data
	debug(LOG_NEVER, "Loading mission dataset: %s", psNewLevel->pName);
	for(i=0; i < LEVEL_MAXFILES; i++)
	{
		if (psNewLevel->game == i)
		{
			// do some more initialising if necessary
			if (psNewLevel->type == LDS_COMPLETE || psNewLevel->type >= LDS_MULTI_TYPE_START || (psBaseData != NULL && !bCamChangeSaveGame))
			{
				if (!stageTwoInitialise())
				{
					return false;
				}
			}

			// load a savegame if there is one - but not if already done so
			if (pSaveName != NULL && !bCamChangeSaveGame)
			{
				//set the mission type before the saveGame data is loaded
				if (saveType == GTYPE_SAVE_MIDMISSION)
				{
					debug(LOG_WZ, "Init mission stuff");
					if (!startMissionSave(psNewLevel->type))
					{
						return false;
					}

					debug(LOG_NEVER, "dataSetSaveFlag");
					dataSetSaveFlag();
				}

				debug(LOG_NEVER, "Loading save game %s", pSaveName);
				if (!loadGame(pSaveName, false, true,true))
				{
					return false;
				}
			}

			if ((pSaveName == NULL) ||
				(saveType == GTYPE_SAVE_START))
			{
				// load the game
				debug(LOG_WZ, "Loading scenario file %s", psNewLevel->apDataFiles[i]);
				switch (psNewLevel->type)
				{
				case LDS_COMPLETE:
				case LDS_CAMSTART:
					debug(LOG_WZ, "LDS_COMPLETE / LDS_CAMSTART");
					if (!startMission(LDS_CAMSTART, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				case LDS_BETWEEN:
					debug(LOG_WZ, "LDS_BETWEEN");
					if (!startMission(LDS_BETWEEN, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;

				case LDS_MKEEP:
					debug(LOG_WZ, "LDS_MKEEP");
					if (!startMission(LDS_MKEEP, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				case LDS_CAMCHANGE:
					debug(LOG_WZ, "LDS_CAMCHANGE");
					if (!startMission(LDS_CAMCHANGE, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;

				case LDS_EXPAND:
					debug(LOG_WZ, "LDS_EXPAND");
					if (!startMission(LDS_EXPAND, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				case LDS_EXPAND_LIMBO:
					debug(LOG_WZ, "LDS_LIMBO");
					if (!startMission(LDS_EXPAND_LIMBO, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;

				case LDS_MCLEAR:
					debug(LOG_WZ, "LDS_MCLEAR");
					if (!startMission(LDS_MCLEAR, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				case LDS_MKEEP_LIMBO:
					debug(LOG_WZ, "LDS_MKEEP_LIMBO");
					if (!startMission(LDS_MKEEP_LIMBO, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				default:
					ASSERT( psNewLevel->type >= LDS_MULTI_TYPE_START,
						"levLoadData: Unexpected mission type" );
					debug(LOG_WZ, "default (MULTIPLAYER)");
					if (!startMission(LDS_CAMSTART, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				}
			}
		}
		else if (psNewLevel->apDataFiles[i])
		{
			// load the data
			debug(LOG_WZ, "Loading %s", psNewLevel->apDataFiles[i]);
			if (!resLoad(psNewLevel->apDataFiles[i], i + CURRENT_DATAID))
			{
				return false;
			}
		}
	}

	if (pSaveName != NULL)
	{
		//load MidMission Extras
		if (!loadMissionExtras(pSaveName, psNewLevel->type))
		{
			return false;
		}
	}

	if (bMultiPlayer)
	{
		loadMultiScripts();
	}
	if (pSaveName != NULL && saveType == GTYPE_SAVE_MIDMISSION)
	{
		//load script stuff
		// load the event system state here for a save game
		debug(LOG_SAVE, "Loading script system state");
		if (!loadScriptState(pSaveName))
		{
			return false;
		}
	}

	if (!stageThreeInitialise())
	{
		return false;
	}

	dataClearSaveFlag();

	//this enables us to to start cam2/cam3 without going via a save game and get the extra droids
	//in from the script-controlled Transporters
	if (!pSaveName && psNewLevel->type == LDS_CAMSTART)
	{
		eventFireCallbackTrigger((TRIGGER_TYPE)CALL_NO_REINFORCEMENTS_LEFT);
	}

	//restore the level name for comparisons on next mission load up
	if (psChangeLevel == NULL)
	{
		psCurrLevel = psNewLevel;
	}
	else
	{
		psCurrLevel = psChangeLevel;
	}

	{
		// Copy this info to be used by the crash handler for the dump file
		char buf[256];

		ssprintf(buf, "Current Level/map is %s", psCurrLevel->pName);
		addDumpInfo(buf);
	}


	return true;
}
Example #23
0
/**
 * Second half of command line parsing. See ParseCommandLineEarly() for
 * the first half. Note that render mode must come before resolution flag.
 * \param argc number of arguments given
 * \param argv string array of the arguments
 * \return Returns true on success, false on error */
bool ParseCommandLine(int argc, const char **argv)
{
	poptContext poptCon = poptGetContext(NULL, argc, argv, getOptionsTable(), 0);
	int iOption;

	/* loop through command line */
	while ((iOption = poptGetNextOpt(poptCon)) > 0)
	{
		const char *token;
		CLI_OPTIONS option = (CLI_OPTIONS)iOption;

		switch (option)
		{
		case CLI_DEBUG:
		case CLI_DEBUGFILE:
		case CLI_FLUSHDEBUGSTDERR:
		case CLI_CONFIGDIR:
		case CLI_HELP:
		case CLI_VERSION:
			// These options are parsed in ParseCommandLineEarly() already, so ignore them
			break;

		case CLI_NOASSERT:
			kf_NoAssert();
			break;

		// NOTE: The sole purpose of this is to test the crash handler.
		case CLI_CRASH:
			CauseCrash = true;
			NetPlay.bComms = false;
			sstrcpy(aLevelName, "CAM_3A");
			SetGameMode(GS_NORMAL);
			break;

		case CLI_DATADIR:
			// retrieve the quoted path name
			token = poptGetOptArg(poptCon);
			if (token == NULL)
			{
				qFatal("Unrecognised datadir");
			}
			sstrcpy(datadir, token);
			break;

		case CLI_FULLSCREEN:
			war_setFullscreen(true);
			break;
		case CLI_CONNECTTOIP:
			//get the ip we want to connect with, and go directly to join screen.
			token = poptGetOptArg(poptCon);
			if (token == NULL)
			{
				qFatal("No IP/hostname given");
			}
			sstrcpy(iptoconnect, token);
			break;
		case CLI_HOSTLAUNCH:
			// go directly to host screen, bypass all others.
			hostlaunch = true;
			break;
		case CLI_GAME:
			// retrieve the game name
			token = poptGetOptArg(poptCon);
			if (token == NULL
			    || (strcmp(token, "CAM_1A") && strcmp(token, "CAM_2A") && strcmp(token, "CAM_3A")
			        && strcmp(token, "TUTORIAL3") && strcmp(token, "FASTPLAY")))
			{
				qFatal("The game parameter requires one of the following keywords:"
				       "CAM_1A, CAM_2A, CAM_3A, TUTORIAL3, or FASTPLAY.");
			}
			NetPlay.bComms = false;
			bMultiPlayer = false;
			bMultiMessages = false;
			NetPlay.players[0].allocated = true;
			if (!strcmp(token, "CAM_1A") || !strcmp(token, "CAM_2A") || !strcmp(token, "CAM_3A"))
			{
				game.type = CAMPAIGN;
			}
			else
			{
				game.type = SKIRMISH; // tutorial is skirmish for some reason
			}
			sstrcpy(aLevelName, token);
			SetGameMode(GS_NORMAL);
			break;
		case CLI_MOD_GLOB:
			{
				unsigned int i;

				// retrieve the file name
				token = poptGetOptArg(poptCon);
				if (token == NULL)
				{
					qFatal("Missing mod name?");
				}

				// Find an empty place in the global_mods list
				for (i = 0; i < 100 && global_mods[i] != NULL; ++i) {}
				if (i >= 100 || global_mods[i] != NULL)
				{
					qFatal("Too many mods registered! Aborting!");
				}
				global_mods[i] = strdup(token);
				break;
			}
		case CLI_MOD_CA:
			{
				unsigned int i;

				// retrieve the file name
				token = poptGetOptArg(poptCon);
				if (token == NULL)
				{
					qFatal("Missing mod name?");
				}

				// Find an empty place in the campaign_mods list
				for (i = 0; i < 100 && campaign_mods[i] != NULL; ++i) {}
				if (i >= 100 || campaign_mods[i] != NULL)
				{
					qFatal("Too many mods registered! Aborting!");
				}
				campaign_mods[i] = strdup(token);
				break;
			}
		case CLI_MOD_MP:
			{
				unsigned int i;

				// retrieve the file name
				token = poptGetOptArg(poptCon);
				if (token == NULL)
				{
					qFatal("Missing mod name?");
				}

				for (i = 0; i < 100 && multiplay_mods[i] != NULL; ++i) {}
				if (i >= 100 || multiplay_mods[i] != NULL)
				{
					qFatal("Too many mods registered! Aborting!");
				}
				multiplay_mods[i] = strdup(token);
				break;
			}
		case CLI_RESOLUTION:
			{
				unsigned int width, height;

				token = poptGetOptArg(poptCon);
				if (sscanf(token, "%ix%i", &width, &height) != 2)
				{
					qFatal("Invalid parameter specified (format is WIDTHxHEIGHT, e.g. 800x600)");
				}
				if (width < 640)
				{
					debug(LOG_ERROR, "Screen width < 640 unsupported, using 640");
					width = 640;
				}
				if (height < 480)
				{
					debug(LOG_ERROR, "Screen height < 480 unsupported, using 480");
					height = 480;
				}
				// tell the display system of the desired resolution
				pie_SetVideoBufferWidth(width);
				pie_SetVideoBufferHeight(height);
				// and update the configuration
				war_SetWidth(width);
				war_SetHeight(height);
				break;
			}
		case CLI_SAVEGAME:
			// retrieve the game name
			token = poptGetOptArg(poptCon);
			if (token == NULL)
			{
				qFatal("Unrecognised savegame name");
			}
			snprintf(saveGameName, sizeof(saveGameName), "%s/%s", SaveGamePath, token);
			SetGameMode(GS_SAVEGAMELOAD);
			break;

		case CLI_WINDOW:
			war_setFullscreen(false);
			break;

		case CLI_SHADOWS:
			setDrawShadows(true);
			break;

		case CLI_NOSHADOWS:
			setDrawShadows(false);
			break;

		case CLI_SOUND:
			war_setSoundEnabled(true);
			break;

		case CLI_NOSOUND:
			war_setSoundEnabled(false);
			break;

		case CLI_TEXTURECOMPRESSION:
			wz_texture_compression = GL_COMPRESSED_RGBA_ARB;
			break;

		case CLI_NOTEXTURECOMPRESSION:
			wz_texture_compression = GL_RGBA;
			break;
		};
	}

	return true;
}
Example #24
0
static void getPlatformUserDir(char * const tmpstr, size_t const size)
{
#if defined(WZ_OS_WIN)
//  When WZ_PORTABLE is passed, that means we want the config directory at the same location as the program file
	DWORD dwRet;
	wchar_t tmpWStr[MAX_PATH];
#ifndef WZ_PORTABLE
	if ( SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, tmpWStr ) ) )
	{
#else
	if (dwRet = GetCurrentDirectoryW(MAX_PATH, tmpWStr))
	{
		if(dwRet > MAX_PATH)
		{
			debug(LOG_FATAL, "Buffer exceeds maximum path to create directory. Exiting.");
			exit(1);
		}
#endif
		if (WideCharToMultiByte(CP_UTF8, 0, tmpWStr, -1, tmpstr, size, NULL, NULL) == 0)
		{
			debug(LOG_FATAL, "Config directory encoding conversion error.");
			exit(1);
		}
		strlcat(tmpstr, PHYSFS_getDirSeparator(), size);
	}
	else
#elif defined(WZ_OS_MAC)
	FSRef fsref;
	OSErr error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, false, &fsref);
	if (!error)
		error = FSRefMakePath(&fsref, (UInt8 *) tmpstr, size);
	if (!error)
		strlcat(tmpstr, PHYSFS_getDirSeparator(), size);
	else
#endif
	if (PHYSFS_getUserDir())
	{
		strlcpy(tmpstr, PHYSFS_getUserDir(), size); // Use PhysFS supplied UserDir (As fallback on Windows / Mac, default on Linux)
	}
	// If PhysicsFS fails (might happen if environment variable HOME is unset or wrong) then use the current working directory
	else if (getCurrentDir(tmpstr, size))
	{
		strlcat(tmpstr, PHYSFS_getDirSeparator(), size);
	}
	else
	{
		debug(LOG_FATAL, "Can't get UserDir?");
		abort();
	}
}


static void initialize_ConfigDir(void)
{
	char tmpstr[PATH_MAX] = { '\0' };

	if (strlen(configdir) == 0)
	{
		getPlatformUserDir(tmpstr, sizeof(tmpstr));

		if (!PHYSFS_setWriteDir(tmpstr)) // Workaround for PhysFS not creating the writedir as expected.
		{
			debug(LOG_FATAL, "Error setting write directory to \"%s\": %s",
			      tmpstr, PHYSFS_getLastError());
			exit(1);
		}

		if (!PHYSFS_mkdir(WZ_WRITEDIR)) // s.a.
		{
			debug(LOG_FATAL, "Error creating directory \"%s\": %s",
			      WZ_WRITEDIR, PHYSFS_getLastError());
			exit(1);
		}

		// Append the Warzone subdir
		sstrcat(tmpstr, WZ_WRITEDIR);
		sstrcat(tmpstr, PHYSFS_getDirSeparator());

		if (!PHYSFS_setWriteDir(tmpstr))
		{
			debug( LOG_FATAL, "Error setting write directory to \"%s\": %s",
			tmpstr, PHYSFS_getLastError() );
			exit(1);
		}
	}
	else
	{
		sstrcpy(tmpstr, configdir);

		// Make sure that we have a directory separator at the end of the string
		if (tmpstr[strlen(tmpstr) - 1] != PHYSFS_getDirSeparator()[0])
			sstrcat(tmpstr, PHYSFS_getDirSeparator());

		debug(LOG_WZ, "Using custom configuration directory: %s", tmpstr);

		if (!PHYSFS_setWriteDir(tmpstr)) // Workaround for PhysFS not creating the writedir as expected.
		{
			debug(LOG_FATAL, "Error setting write directory to \"%s\": %s",
			      tmpstr, PHYSFS_getLastError());
			exit(1);
		}

		// NOTE: This is currently only used for mingw builds for now.
#if defined (WZ_CC_MINGW)
		if (!OverrideRPTDirectory(tmpstr))
		{
			// since it failed, we just use our default path, and not the user supplied one.
			debug(LOG_ERROR, "Error setting exception hanlder to use directory %s", tmpstr);
		}
#endif
	}

	// User's home dir first so we allways see what we write
	PHYSFS_addToSearchPath( PHYSFS_getWriteDir(), PHYSFS_PREPEND );

	PHYSFS_permitSymbolicLinks(1);

	debug(LOG_WZ, "Write dir: %s", PHYSFS_getWriteDir());
	debug(LOG_WZ, "Base dir: %s", PHYSFS_getBaseDir());
}
Example #25
0
/*!
 * \brief Adds default data dirs
 *
 * Priority:
 * Lower loads first. Current:
 * -datadir > User's home dir > source tree data > AutoPackage > BaseDir > DEFAULT_DATADIR
 *
 * Only -datadir and home dir are allways examined. Others only if data still not found.
 *
 * We need ParseCommandLine, before we can add any mods...
 *
 * \sa rebuildSearchPath
 */
static void scanDataDirs( void )
{
	char tmpstr[PATH_MAX], prefix[PATH_MAX];
	char* separator;

#if defined(WZ_OS_MAC)
	// version-independent location for video files
	registerSearchPath("/Library/Application Support/Warzone 2100/", 1);
#endif

	// Find out which PREFIX we are in...
	sstrcpy(prefix, PHYSFS_getBaseDir());

	separator = strrchr(prefix, *PHYSFS_getDirSeparator());
	if (separator)
	{
		*separator = '\0'; // Trim ending '/', which getBaseDir always provides

		separator = strrchr(prefix, *PHYSFS_getDirSeparator());
		if (separator)
		{
			*separator = '\0'; // Skip the last dir from base dir
		}
	}

	// Commandline supplied datadir
	if( strlen( datadir ) != 0 )
		registerSearchPath( datadir, 1 );

	// User's home dir
	registerSearchPath( PHYSFS_getWriteDir(), 2 );
	rebuildSearchPath( mod_multiplay, true );

	if( !PHYSFS_exists("gamedesc.lev") )
	{
		// Data in source tree
		sstrcpy(tmpstr, prefix);
		sstrcat(tmpstr, "/data/");
		registerSearchPath( tmpstr, 3 );
		rebuildSearchPath( mod_multiplay, true );

		if( !PHYSFS_exists("gamedesc.lev") )
		{
			// Relocation for AutoPackage
			sstrcpy(tmpstr, prefix);
			sstrcat(tmpstr, "/share/warzone2100/");
			registerSearchPath( tmpstr, 4 );
			rebuildSearchPath( mod_multiplay, true );

			if( !PHYSFS_exists("gamedesc.lev") )
			{
				// Program dir
				registerSearchPath( PHYSFS_getBaseDir(), 5 );
				rebuildSearchPath( mod_multiplay, true );

				if( !PHYSFS_exists("gamedesc.lev") )
				{
					// Guessed fallback default datadir on Unix
					registerSearchPath( WZ_DATADIR, 6 );
					rebuildSearchPath( mod_multiplay, true );
				}
			}
		}
	}

#ifdef WZ_OS_MAC
	if( !PHYSFS_exists("gamedesc.lev") ) {
		CFURLRef resourceURL = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
		char resourcePath[PATH_MAX];
		if( CFURLGetFileSystemRepresentation( resourceURL, true,
							(UInt8 *) resourcePath,
							PATH_MAX) ) {
			chdir( resourcePath );
			registerSearchPath( "data", 7 );
			rebuildSearchPath( mod_multiplay, true );
		} else {
			debug( LOG_ERROR, "Could not change to resources directory." );
		}

		if( resourceURL != NULL ) {
			CFRelease( resourceURL );
		}
	}
#endif

	/** Debugging and sanity checks **/

	printSearchPath();

	if( PHYSFS_exists("gamedesc.lev") )
	{
		debug( LOG_WZ, "gamedesc.lev found at %s", PHYSFS_getRealDir( "gamedesc.lev" ) );
	}
	else
	{
		debug( LOG_FATAL, "Could not find game data. Aborting." );
		exit(1);
	}
}
Example #26
0
int realmain(int argc, char *argv[])
{
	// The libcrypto startup stuff... May or may not actually be needed for anything at all.
	ERR_load_crypto_strings();  // This is needed for descriptive error messages.
	OpenSSL_add_all_algorithms();  // Don't actually use the EVP functions, so probably not needed.
	OPENSSL_config(nullptr);  // What does this actually do?
#ifdef WZ_OS_WIN
	RAND_screen();  // Uses a screenshot as a random seed, on systems lacking /dev/random.
#endif

	wzMain(argc, argv);
	int utfargc = argc;
	const char** utfargv = (const char**)argv;

#ifdef WZ_OS_MAC
	cocoaInit();
#endif

	debug_init();
	debug_register_callback( debug_callback_stderr, NULL, NULL, NULL );
#if defined(WZ_OS_WIN) && defined(DEBUG_INSANE)
	debug_register_callback( debug_callback_win32debug, NULL, NULL, NULL );
#endif // WZ_OS_WIN && DEBUG_INSANE

	// *****
	// NOTE: Try *NOT* to use debug() output routines without some other method of informing the user.  All this output is sent to /dev/nul at this point on some platforms!
	// *****
	if (!getUTF8CmdLine(&utfargc, &utfargv))
	{
		return EXIT_FAILURE;
	}
	QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));	// make Qt treat all C strings in Warzone as UTF-8

	setupExceptionHandler(utfargc, utfargv, version_getFormattedVersionString());

	/*** Initialize PhysicsFS ***/
	initialize_PhysicsFS(utfargv[0]);

	/*** Initialize translations ***/
	initI18n();

	// find early boot info
	if (!ParseCommandLineEarly(utfargc, utfargv))
	{
		return EXIT_FAILURE;
	}

	/* Initialize the write/config directory for PhysicsFS.
	 * This needs to be done __after__ the early commandline parsing,
	 * because the user might tell us to use an alternative configuration
	 * directory.
	 */
	initialize_ConfigDir();

	/*** Initialize directory structure ***/
	make_dir(ScreenDumpPath, "screenshots", NULL);
	make_dir(SaveGamePath, "savegames", NULL);
	PHYSFS_mkdir("savegames/campaign");
	PHYSFS_mkdir("savegames/skirmish");
	make_dir(MultiCustomMapsPath, "maps", NULL); // MUST have this to prevent crashes when getting map
	PHYSFS_mkdir("music");
	PHYSFS_mkdir("logs");		// a place to hold our netplay, mingw crash reports & WZ logs
	PHYSFS_mkdir("userdata");	// a place to store per-mod data user generated data
	memset(rulesettag, 0, sizeof(rulesettag)); // tag to add to userdata to find user generated stuff
	make_dir(MultiPlayersPath, "multiplay", NULL);
	make_dir(MultiPlayersPath, "multiplay", "players");

	if (!customDebugfile)
	{
		// there was no custom debug file specified  (--debug-file=blah)
		// so we use our write directory to store our logs.
		time_t aclock;
		struct tm *newtime;
		char buf[PATH_MAX];

		time( &aclock );					// Get time in seconds
		newtime = localtime( &aclock );		// Convert time to struct
		// Note: We are using fopen(), and not physfs routines to open the file
		// log name is logs/(or \)WZlog-MMDD_HHMMSS.txt
		snprintf(buf, sizeof(buf), "%slogs%sWZlog-%02d%02d_%02d%02d%02d.txt", PHYSFS_getWriteDir(), PHYSFS_getDirSeparator(),
			newtime->tm_mon + 1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec );
		debug_register_callback( debug_callback_file, debug_callback_file_init, debug_callback_file_exit, buf );

		// FIXME: Change this to LOG_WZ on next release
		debug(LOG_INFO, "Using %s debug file", buf);
	}

	// NOTE: it is now safe to use debug() calls to make sure output gets captured.
	check_Physfs();
	debug(LOG_WZ, "Warzone 2100 - %s", version_getFormattedVersionString());
	debug(LOG_WZ, "Using language: %s", getLanguage());
	debug(LOG_WZ, "Backend: %s", BACKEND);
	debug(LOG_MEMORY, "sizeof: SIMPLE_OBJECT=%ld, BASE_OBJECT=%ld, DROID=%ld, STRUCTURE=%ld, FEATURE=%ld, PROJECTILE=%ld",
	      (long)sizeof(SIMPLE_OBJECT), (long)sizeof(BASE_OBJECT), (long)sizeof(DROID), (long)sizeof(STRUCTURE), (long)sizeof(FEATURE), (long)sizeof(PROJECTILE));


	/* Put in the writedir root */
	sstrcpy(KeyMapPath, "keymap.map");

	// initialise all the command line states
	war_SetDefaultStates();

	debug(LOG_MAIN, "initializing");

	PhysicsEngineHandler engine;	// register abstract physfs filesystem

	loadConfig();

	// parse the command line
	if (!ParseCommandLine(utfargc, utfargv))
	{
		return EXIT_FAILURE;
	}

	// Save new (commandline) settings
	saveConfig();

	// Find out where to find the data
	scanDataDirs();

	// Now we check the mods to see if they exist or not (specified on the command line)
	// They are all capped at 100 mods max(see clparse.c)
	// FIX ME: I know this is a bit hackish, but better than nothing for now?
	{
		char *modname;
		char modtocheck[256];
		int i = 0;
		int result = 0;

		// check global mods
		for(i=0; i < 100; i++)
		{
			modname = global_mods[i];
			if (modname == NULL)
			{
				break;
			}
			ssprintf(modtocheck, "mods/global/%s", modname);
			result = PHYSFS_exists(modtocheck);
			result |= PHYSFS_isDirectory(modtocheck);
			if (!result)
			{
				debug(LOG_ERROR, "The (global) mod (%s) you have specified doesn't exist!", modname);
			}
			else
			{
				info("(global) mod (%s) is enabled", modname);
			}
		}
		// check campaign mods
		for(i=0; i < 100; i++)
		{
			modname = campaign_mods[i];
			if (modname == NULL)
			{
				break;
			}
			ssprintf(modtocheck, "mods/campaign/%s", modname);
			result = PHYSFS_exists(modtocheck);
			result |= PHYSFS_isDirectory(modtocheck);
			if (!result)
			{
				debug(LOG_ERROR, "The mod_ca (%s) you have specified doesn't exist!", modname);
			}
			else
			{
				info("mod_ca (%s) is enabled", modname);
			}
		}
		// check multiplay mods
		for(i=0; i < 100; i++)
		{
			modname = multiplay_mods[i];
			if (modname == NULL)
			{
				break;
			}
			ssprintf(modtocheck, "mods/multiplay/%s", modname);
			result = PHYSFS_exists(modtocheck);
			result |= PHYSFS_isDirectory(modtocheck);
			if (!result)
			{
				debug(LOG_ERROR, "The mod_mp (%s) you have specified doesn't exist!", modname);
			}
			else
			{
				info("mod_mp (%s) is enabled", modname);
			}
		}
	}

	if (!wzMain2(war_getFSAA(), war_getFullscreen(), war_GetVsync()))
	{
		return EXIT_FAILURE;
	}
	int w = pie_GetVideoBufferWidth();
	int h = pie_GetVideoBufferHeight();

	char buf[256];
	ssprintf(buf, "Video Mode %d x %d (%s)", w, h, war_getFullscreen() ? "fullscreen" : "window");
	addDumpInfo(buf);

	debug(LOG_MAIN, "Final initialization");
	if (!frameInitialise())
	{
		return EXIT_FAILURE;
	}
	if (!screenInitialise())
	{
		return EXIT_FAILURE;
	}
	if (!pie_LoadShaders())
	{
		return EXIT_FAILURE;
	}
	war_SetWidth(pie_GetVideoBufferWidth());
	war_SetHeight(pie_GetVideoBufferHeight());

	pie_SetFogStatus(false);
	pie_ScreenFlip(CLEAR_BLACK);

	pal_Init();

	pie_LoadBackDrop(SCREEN_RANDOMBDROP);
	pie_SetFogStatus(false);
	pie_ScreenFlip(CLEAR_BLACK);

	if (!systemInitialise())
	{
		return EXIT_FAILURE;
	}

	//set all the pause states to false
	setAllPauseStates(false);

	// Copy this info to be used by the crash handler for the dump file
	ssprintf(buf,"Using Backend: %s", BACKEND);
	addDumpInfo(buf);
	ssprintf(buf,"Using language: %s", getLanguageName());
	addDumpInfo(buf);

	// Do the game mode specific initialisation.
	switch(GetGameMode())
	{
		case GS_TITLE_SCREEN:
			startTitleLoop();
			break;
		case GS_SAVEGAMELOAD:
			initSaveGameLoad();
			break;
		case GS_NORMAL:
			startGameLoop();
			break;
		default:
			debug(LOG_ERROR, "Weirdy game status, I'm afraid!!");
			break;
	}

#if defined(WZ_CC_MSVC) && defined(DEBUG)
	debug_MEMSTATS();
#endif
	debug(LOG_MAIN, "Entering main loop");
	wzMain3();
	saveConfig();
	systemShutdown();
#ifdef WZ_OS_WIN	// clean up the memory allocated for the command line conversion
	for (int i=0; i<argc; i++)
	{
		const char*** const utfargvF = &utfargv;
		free((void *)(*utfargvF)[i]);
	}
	free(utfargv);
#endif
	wzShutdown();
	debug(LOG_MAIN, "Completed shutting down Warzone 2100");
	return EXIT_SUCCESS;
}
Example #27
0
//****************************************************************************************
// Challenge menu
//*****************************************************************************************
bool addChallenges()
{
    char			sPath[PATH_MAX];
    const char *sSearchPath	= "challenges";
    UDWORD			slotCount;
    static char		sSlotCaps[totalslots][totalslotspace];
    static char		sSlotTips[totalslots][totalslotspace];
    static char		sSlotFile[totalslots][totalslotspace];
    char **i, **files;

    (void) PHYSFS_mkdir(sSearchPath); // just in case

    psRequestScreen = widgCreateScreen(); // init the screen
    widgSetTipFont(psRequestScreen, font_regular);

    /* add a form to place the tabbed form on */
    W_FORMINIT sFormInit;
    sFormInit.formID = 0;				//this adds the blue background, and the "box" behind the buttons -Q
    sFormInit.id = CHALLENGE_FORM;
    sFormInit.style = WFORM_PLAIN;
    sFormInit.x = (SWORD) CHALLENGE_X;
    sFormInit.y = (SWORD) CHALLENGE_Y;
    sFormInit.width = CHALLENGE_W;
    // we need the form to be long enough for all resolutions, so we take the total number of items * height
    // and * the gaps, add the banner, and finally, the fudge factor ;)
    sFormInit.height = (slotsInColumn * CHALLENGE_ENTRY_H + CHALLENGE_HGAP * slotsInColumn) + CHALLENGE_BANNER_DEPTH + 20;
    sFormInit.disableChildren = true;
    sFormInit.pDisplay = intOpenPlainForm;
    widgAddForm(psRequestScreen, &sFormInit);

    // Add Banner
    sFormInit.formID = CHALLENGE_FORM;
    sFormInit.id = CHALLENGE_BANNER;
    sFormInit.x = CHALLENGE_HGAP;
    sFormInit.y = CHALLENGE_VGAP;
    sFormInit.width = CHALLENGE_W - (2 * CHALLENGE_HGAP);
    sFormInit.height = CHALLENGE_BANNER_DEPTH;
    sFormInit.disableChildren = false;
    sFormInit.pDisplay = displayLoadBanner;
    sFormInit.UserData = 0;
    widgAddForm(psRequestScreen, &sFormInit);

    // Add Banner Label
    W_LABINIT sLabInit;
    sLabInit.formID		= CHALLENGE_BANNER;
    sLabInit.id		= CHALLENGE_LABEL;
    sLabInit.style		= WLAB_ALIGNCENTRE;
    sLabInit.x		= 0;
    sLabInit.y		= 3;
    sLabInit.width		= CHALLENGE_W - (2 * CHALLENGE_HGAP);	//CHALLENGE_W;
    sLabInit.height		= CHALLENGE_BANNER_DEPTH;		//This looks right -Q
    sLabInit.pText		= "Challenge";
    widgAddLabel(psRequestScreen, &sLabInit);

    // add cancel.
    W_BUTINIT sButInit;
    sButInit.formID = CHALLENGE_BANNER;
    sButInit.x = 8;
    sButInit.y = 8;
    sButInit.width		= iV_GetImageWidth(IntImages, IMAGE_NRUTER);
    sButInit.height		= iV_GetImageHeight(IntImages, IMAGE_NRUTER);
    sButInit.UserData	= PACKDWORD_TRI(0, IMAGE_NRUTER , IMAGE_NRUTER);

    sButInit.id = CHALLENGE_CANCEL;
    sButInit.pTip = _("Close");
    sButInit.pDisplay = intDisplayImageHilight;
    widgAddButton(psRequestScreen, &sButInit);

    // add slots
    sButInit = W_BUTINIT();
    sButInit.formID		= CHALLENGE_FORM;
    sButInit.width		= CHALLENGE_ENTRY_W;
    sButInit.height		= CHALLENGE_ENTRY_H;
    sButInit.pDisplay	= displayLoadSlot;

    for (slotCount = 0; slotCount < totalslots; slotCount++)
    {
        sButInit.id		= slotCount + CHALLENGE_ENTRY_START;

        if (slotCount < slotsInColumn)
        {
            sButInit.x	= 22 + CHALLENGE_HGAP;
            sButInit.y	= (SWORD)((CHALLENGE_BANNER_DEPTH + (2 * CHALLENGE_VGAP)) + (
                                      slotCount * (CHALLENGE_VGAP + CHALLENGE_ENTRY_H)));
        }
        else if (slotCount >= slotsInColumn && (slotCount < (slotsInColumn *2)))
        {
            sButInit.x	= 22 + (2 * CHALLENGE_HGAP + CHALLENGE_ENTRY_W);
            sButInit.y	= (SWORD)((CHALLENGE_BANNER_DEPTH + (2 * CHALLENGE_VGAP)) + (
                                      (slotCount % slotsInColumn) * (CHALLENGE_VGAP + CHALLENGE_ENTRY_H)));
        }
        else
        {
            sButInit.x	= 22 + (3 * CHALLENGE_HGAP + (2 * CHALLENGE_ENTRY_W));
            sButInit.y	= (SWORD)((CHALLENGE_BANNER_DEPTH + (2 * CHALLENGE_VGAP)) + (
                                      (slotCount % slotsInColumn) * (CHALLENGE_VGAP + CHALLENGE_ENTRY_H)));
        }
        widgAddButton(psRequestScreen, &sButInit);
    }

    // fill slots.
    slotCount = 0;

    sstrcpy(sPath, sSearchPath);
    sstrcat(sPath, "/*.ini");

    debug(LOG_SAVE, "Searching \"%s\" for challenges", sPath);

    // add challenges to buttons
    files = PHYSFS_enumerateFiles(sSearchPath);
    for (i = files; *i != NULL; ++i)
    {
        W_BUTTON *button;
        char description[totalslotspace];
        char highscore[totalslotspace];
        const char *name, *difficulty, *map, *givendescription;
        inifile *inif;

        // See if this filename contains the extension we're looking for
        if (!strstr(*i, ".ini"))
        {
            // If it doesn't, move on to the next filename
            continue;
        }

        /* First grab any high score associated with this challenge */
        inif = inifile_load(CHALLENGE_SCORES);
        sstrcpy(sPath, *i);
        sPath[strlen(sPath) - 4] = '\0';	// remove .ini
        sstrcpy(highscore, "no score");
        if (inif)
        {
            char key[64];
            bool victory;
            int seconds;

            ssprintf(key, "%s:Player", sPath);
            name = inifile_get(inif, key, "NO NAME");
            ssprintf(key, "%s:Victory", sPath);
            victory = inifile_get_as_bool(inif, key, false);
            ssprintf(key, "%s:Seconds", sPath);
            seconds = inifile_get_as_int(inif, key, -1);
            if (seconds > 0)
            {
                getAsciiTime(key, seconds * GAME_TICKS_PER_SEC);
                ssprintf(highscore, "%s by %s (%s)", key, name, victory ? "Victory" : "Survived");
            }
            inifile_delete(inif);
        }

        ssprintf(sPath, "%s/%s", sSearchPath, *i);
        inif = inifile_load(sPath);
        inifile_set_current_section(inif, "challenge");
        if (!inif)
        {
            debug(LOG_ERROR, "Could not open \"%s\"", sPath);
            continue;
        }
        name = inifile_get(inif, "Name", "BAD NAME");
        map = inifile_get(inif, "Map", "BAD MAP");
        difficulty = inifile_get(inif, "difficulty", "BAD DIFFICULTY");
        givendescription = inifile_get(inif, "description", "");
        ssprintf(description, "%s, %s, %s. %s", map, difficulty, highscore, givendescription);

        button = (W_BUTTON*)widgGetFromID(psRequestScreen, CHALLENGE_ENTRY_START + slotCount);

        debug(LOG_SAVE, "We found [%s]", *i);

        /* Set the button-text */
        sstrcpy(sSlotCaps[slotCount], name);		// store it!
        sstrcpy(sSlotTips[slotCount], description);	// store it, too!
        sstrcpy(sSlotFile[slotCount], sPath);		// store filename
        inifile_delete(inif);

        /* Add button */
        button->pTip = sSlotTips[slotCount];
        button->pText = sSlotCaps[slotCount];
        button->pUserData = (void *)sSlotFile[slotCount];
        slotCount++;		// go to next button...
        if (slotCount == totalslots)
        {
            break;
        }
    }
    PHYSFS_freeList(files);

    challengesUp = true;

    return true;
}
Example #28
0
// Saves and loads the relevant part of the config files for MP games
// Ensures that others' games don't change our own configuration settings
bool reloadMPConfig(void)
{
	QSettings ini(PHYSFS_getWriteDir() + QString("/") + fileName, QSettings::IniFormat);
	if (ini.status() != QSettings::NoError)
	{
		debug(LOG_ERROR, "Could not open configuration file \"%s\"", fileName);
		return false;
	}
	debug(LOG_WZ, "Reloading prefs prefs to registry");

	// If we're in-game, we already have our own configuration set, so no need to reload it.
	if (NetPlay.isHost && !ingame.localJoiningInProgress)
	{
		if (bMultiPlayer && !NetPlay.bComms)
		{
			// one-player skirmish mode sets game name to "One Player Skirmish", so
			// reset the name
			if (ini.contains("gameName"))
			{
				sstrcpy(game.name, ini.value("gameName").toString().toUtf8().constData());
			}
		}
		return true;
	}

	// If we're host and not in-game, we can safely save our settings and return.
	if (NetPlay.isHost && ingame.localJoiningInProgress)
	{
		if (bMultiPlayer && NetPlay.bComms)
		{
			ini.setValue("gameName", game.name);			//  last hosted game
		}
		else
		{
			// One-player skirmish mode sets game name to "One Player Skirmish", so
			// reset the name
			if (ini.contains("gameName"))
			{
				sstrcpy(game.name, ini.value("gameName").toString().toUtf8().constData());
			}
		}

		// Set a default map to prevent hosting games without a map.
		sstrcpy(game.map, "Sk-Rush");
		game.hash.setZero();
		game.maxPlayers = 4;

		ini.setValue("power", game.power);				// power
		ini.setValue("base", game.base);				// size of base
		ini.setValue("alliance", game.alliance);		// allow alliances
		return true;
	}

	// We're not host, so let's get rid of the host's game settings and restore our own.

	// game name
	if (ini.contains("gameName"))
	{
		sstrcpy(game.name, ini.value("gameName").toString().toUtf8().constData());
	}

	// Set a default map to prevent hosting games without a map.
	sstrcpy(game.map, "Sk-Rush");
	game.hash.setZero();
	game.maxPlayers = 4;

	game.power = ini.value("power", LEV_MED).toInt();
	game.base = ini.value("base", CAMP_BASE).toInt();
	game.alliance = ini.value("alliance", NO_ALLIANCES).toInt();

	return true;
}
Example #29
0
// ////////////////////////////////////////////////////////////////////////////
// options for a game. (usually recvd in frontend)
void recvOptions(NETQUEUE queue)
{
	unsigned int i;

	debug(LOG_NET, "Receiving options from host");
	NETbeginDecode(queue, NET_OPTIONS);

	// Get general information about the game
	NETuint8_t(&game.type);
	NETstring(game.map, 128);
	NETbin(game.hash.bytes, game.hash.Bytes);
	uint32_t modHashesSize;
	NETuint32_t(&modHashesSize);
	ASSERT_OR_RETURN(, modHashesSize < 1000000, "Way too many mods %u", modHashesSize);
	game.modHashes.resize(modHashesSize);
	for (auto &hash : game.modHashes)
	{
		NETbin(hash.bytes, hash.Bytes);
	}
	NETuint8_t(&game.maxPlayers);
	NETstring(game.name, 128);
	NETuint32_t(&game.power);
	NETuint8_t(&game.base);
	NETuint8_t(&game.alliance);
	NETbool(&game.scavengers);
	NETbool(&game.isMapMod);

	for (i = 0; i < MAX_PLAYERS; i++)
	{
		NETuint8_t(&game.skDiff[i]);
	}

	// Send the list of who is still joining
	for (i = 0; i < MAX_PLAYERS; i++)
	{
		NETbool(&ingame.JoiningInProgress[i]);
	}

	// Alliances
	for (i = 0; i < MAX_PLAYERS; i++)
	{
		unsigned int j;

		for (j = 0; j < MAX_PLAYERS; j++)
		{
			NETuint8_t(&alliances[i][j]);
		}
	}
	netPlayersUpdated = true;

	// Free any structure limits we may have in-place
	if (ingame.numStructureLimits)
	{
		ingame.numStructureLimits = 0;
		free(ingame.pStructureLimits);
		ingame.pStructureLimits = NULL;
	}

	// Get the number of structure limits to expect
	NETuint32_t(&ingame.numStructureLimits);
	debug(LOG_NET, "Host is sending us %u structure limits", ingame.numStructureLimits);
	// If there were any changes allocate memory for them
	if (ingame.numStructureLimits)
	{
		ingame.pStructureLimits = (MULTISTRUCTLIMITS *)malloc(ingame.numStructureLimits * sizeof(MULTISTRUCTLIMITS));
	}

	for (i = 0; i < ingame.numStructureLimits; i++)
	{
		NETuint32_t(&ingame.pStructureLimits[i].id);
		NETuint32_t(&ingame.pStructureLimits[i].limit);
	}
	NETuint8_t(&ingame.flags);

	NETend();

	// Do the skirmish slider settings if they are up
	for (i = 0; i < MAX_PLAYERS; i++)
	{
		if (widgGetFromID(psWScreen, MULTIOP_SKSLIDE + i))
		{
			widgSetSliderPos(psWScreen, MULTIOP_SKSLIDE + i, game.skDiff[i]);
		}
	}
	debug(LOG_INFO, "Rebuilding map list");
	// clear out the old level list.
	levShutDown();
	levInitialise();
	rebuildSearchPath(mod_multiplay, true);	// MUST rebuild search path for the new maps we just got!
	buildMapList();

	bool haveData = true;
	auto requestFile = [&haveData](Sha256 &hash, char const *filename) {
		if (std::any_of(NetPlay.wzFiles.begin(), NetPlay.wzFiles.end(), [&hash](WZFile const &file) { return file.hash == hash; }))
		{
			debug(LOG_INFO, "Already requested file, continue waiting.");
			haveData = false;
			return false;  // Downloading the file already
		}

		if (!PHYSFS_exists(filename))
		{
			debug(LOG_INFO, "Creating new file %s", filename);
		}
		else if (findHashOfFile(filename) != hash)
		{
			debug(LOG_INFO, "Overwriting old incomplete or corrupt file %s", filename);
		}
		else
		{
			return false;  // Have the file already.
		}

		NetPlay.wzFiles.emplace_back(PHYSFS_openWrite(filename), hash);

		// Request the map/mod from the host
		NETbeginEncode(NETnetQueue(NET_HOST_ONLY), NET_FILE_REQUESTED);
		NETbin(hash.bytes, hash.Bytes);
		NETend();

		haveData = false;
		return true;  // Starting download now.
	};

	LEVEL_DATASET *mapData = levFindDataSet(game.map, &game.hash);
	// See if we have the map or not
	if (mapData == nullptr)
	{
		char mapName[256];
		sstrcpy(mapName, game.map);
		removeWildcards(mapName);

		if (strlen(mapName) >= 3 && mapName[strlen(mapName) - 3] == '-' && mapName[strlen(mapName) - 2] == 'T' && unsigned(mapName[strlen(mapName) - 1] - '1') < 3)
		{
			mapName[strlen(mapName) - 3] = '\0';  // Cut off "-T1", "-T2" or "-T3".
		}
		char filename[256];
		ssprintf(filename, "maps/%dc-%s-%s.wz", game.maxPlayers, mapName, game.hash.toString().c_str());  // Wonder whether game.maxPlayers is initialised already?

		if (requestFile(game.hash, filename))
		{
			debug(LOG_INFO, "Map was not found, requesting map %s from host, type %d", game.map, game.isMapMod);
			addConsoleMessage("MAP REQUESTED!", DEFAULT_JUSTIFY, SYSTEM_MESSAGE);
		}
		else
		{
			debug(LOG_FATAL, "Can't load map %s, even though we downloaded %s", game.map, filename);
			abort();
		}
	}

	for (Sha256 &hash : game.modHashes)
	{
		char filename[256];
		ssprintf(filename, "mods/downloads/%s", hash.toString().c_str());

		if (requestFile(hash, filename))
		{
			debug(LOG_INFO, "Mod was not found, requesting mod %s from host", hash.toString().c_str());
			addConsoleMessage("MOD REQUESTED!", DEFAULT_JUSTIFY, SYSTEM_MESSAGE);
		}
	}

	if (mapData && CheckForMod(mapData->realFileName))
	{
		char const *str = game.isMapMod ?
			_("Warning, this is a map-mod, it could alter normal gameplay.") :
			_("Warning, HOST has altered the game code, and can't be trusted!");
		addConsoleMessage(str, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);
		game.isMapMod = true;
	}

	if (mapData)
	{
		loadMapPreview(false);
	}
}
Example #30
0
// ////////////////////////////////////////////////////////////////////////////
bool loadConfig()
{
	QSettings ini(PHYSFS_getWriteDir() + QString("/") + fileName, QSettings::IniFormat);
	if (ini.status() != QSettings::NoError)
	{
		debug(LOG_ERROR, "Could not open configuration file \"%s\"", fileName);
		return false;
	}
	debug(LOG_WZ, "Reading configuration from %s", ini.fileName().toUtf8().constData());
	if (ini.contains("voicevol")) sound_SetUIVolume(ini.value("voicevol").toDouble() / 100.0);
	if (ini.contains("fxvol")) sound_SetEffectsVolume(ini.value("fxvol").toDouble() / 100.0);
	if (ini.contains("cdvol")) sound_SetMusicVolume(ini.value("cdvol").toDouble() / 100.0);
	if (ini.contains("music_enabled")) war_SetMusicEnabled(ini.value("music_enabled").toBool());
	if (ini.contains("language")) setLanguage(ini.value("language").toString().toUtf8().constData());
	if (ini.contains("nomousewarp")) setMouseWarp(ini.value("nomousewarp").toBool());
	if (ini.contains("notexturecompression")) wz_texture_compression = GL_RGBA;
	showFPS = ini.value("showFPS", false).toBool();
	scroll_speed_accel = ini.value("scroll", DEFAULTSCROLL).toInt();
	setShakeStatus(ini.value("shake", false).toBool());
	setDrawShadows(ini.value("shadows", true).toBool());
	war_setSoundEnabled(ini.value("sound", true).toBool());
	setInvertMouseStatus(ini.value("mouseflip", true).toBool());
	setRightClickOrders(ini.value("RightClickOrders", false).toBool());
	setMiddleClickRotate(ini.value("MiddleClickRotate", false).toBool());
	rotateRadar = ini.value("rotateRadar", true).toBool();
	war_SetPauseOnFocusLoss(ini.value("PauseOnFocusLoss", false).toBool());
	NETsetMasterserverName(ini.value("masterserver_name", "lobby.wz2100.net").toString().toUtf8().constData());
	iV_font(ini.value("fontname", "DejaVu Sans").toString().toUtf8().constData(),
		ini.value("fontface", "Book").toString().toUtf8().constData(),
		ini.value("fontfacebold", "Bold").toString().toUtf8().constData());
	NETsetMasterserverPort(ini.value("masterserver_port", MASTERSERVERPORT).toInt());
	NETsetGameserverPort(ini.value("gameserver_port", GAMESERVERPORT).toInt());
	war_SetFMVmode((FMV_MODE)ini.value("FMVmode", FMV_FULLSCREEN).toInt());
	war_setScanlineMode((SCANLINE_MODE)ini.value("scanlines", SCANLINES_OFF).toInt());
	seq_SetSubtitles(ini.value("subtitles", true).toBool());
	setDifficultyLevel((DIFFICULTY_LEVEL)ini.value("difficulty", DL_NORMAL).toInt());
	war_SetSPcolor(ini.value("colour", 0).toInt());	// default is green (0)
	war_setMPcolour(ini.value("colourMP", -1).toInt());  // default is random (-1)
	sstrcpy(game.name, ini.value("gameName", _("My Game")).toString().toUtf8().constData());
	sstrcpy(sPlayer, ini.value("playerName", _("Player")).toString().toUtf8().constData());

	// Set a default map to prevent hosting games without a map.
	sstrcpy(game.map, "Sk-Rush");
	game.hash.setZero();
	game.maxPlayers = 4;

	game.power = ini.value("power", LEV_MED).toInt();
	game.base = ini.value("base", CAMP_BASE).toInt();
	game.alliance = ini.value("alliance", NO_ALLIANCES).toInt();
	game.scavengers = ini.value("scavengers", false).toBool();
	memset(&ingame.phrases, 0, sizeof(ingame.phrases));
	for (int i = 1; i < 5; i++)
	{
		QString key("phrase" + QString::number(i));
		if (ini.contains(key)) sstrcpy(ingame.phrases[i], ini.value(key).toString().toUtf8().constData());
	}
	bEnemyAllyRadarColor = ini.value("radarObjectMode").toBool();
	radarDrawMode = (RADAR_DRAW_MODE)ini.value("radarTerrainMode", RADAR_MODE_DEFAULT).toInt();
	radarDrawMode = (RADAR_DRAW_MODE)MIN(NUM_RADAR_MODES - 1, radarDrawMode); // restrict to allowed values
	if (ini.contains("textureSize")) setTextureSize(ini.value("textureSize").toInt());
	NetPlay.isUPNP = ini.value("UPnP", true).toBool();
	if (ini.contains("FSAA")) war_setFSAA(ini.value("FSAA").toInt());
	// Leave this to false, some system will fail and they can't see the system popup dialog!
	war_setFullscreen(ini.value("fullscreen", false).toBool());
	war_SetTrapCursor(ini.value("trapCursor", false).toBool());
	// this should be enabled on all systems by default
	war_SetVsync(ini.value("vsync", true).toBool());
	// 640x480 is minimum that we will support
	int width = ini.value("width", 640).toInt();
	int height = ini.value("height", 480).toInt();
	if (width < 640 || height < 480)	// sanity check
	{
		width = 640;
		height = 480;
	}
	pie_SetVideoBufferWidth(width);
	pie_SetVideoBufferHeight(height);
	war_SetWidth(width);
	war_SetHeight(height);

	if (ini.contains("bpp")) pie_SetVideoBufferDepth(ini.value("bpp").toInt());
	return true;
}