Exemplo n.º 1
0
/// default value load routine
bool scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size)
{
	char			*pPos;
	DROID			*psCDroid;
	SDWORD			index, members, savedMembers;
	UDWORD			id;
	LEVEL_DATASET	*psLevel;
	DROID_GROUP		*psGroup = NULL;
	const char              *pName;
	bool			bObjectDefined;

	switch ((unsigned)psVal->type)  // Unsigned cast to suppress compiler warnings due to enum abuse.
	{
	case ST_INTMESSAGE:
		if ((size == 1) &&
			(*pBuffer == 0))
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)getViewData(pBuffer);
			if (psVal->v.oval == NULL)
			{
				return false;
			}
		}
		break;
	case ST_BASEOBJECT:
	case ST_DROID:
	case ST_STRUCTURE:
	case ST_FEATURE:
		id = *((UDWORD *)pBuffer);
		endian_udword(&id);

		if (id == UDWORD_MAX)
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)getBaseObjFromId(id);
			if (!psVal->v.oval)
			{
				debug(LOG_ERROR, "Could not find object id %d", id);
			}
		}
		break;
	case ST_BASESTATS:
	case ST_COMPONENT:
		break;
	case ST_STRUCTURESTAT:
		index = getStructStatFromName(pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find structure stat %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_FEATURESTAT:
		index = getFeatureStatFromName(pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find feature stat %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_BODY:
		index = getCompFromResName(COMP_BODY, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find body component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_PROPULSION:
		index = getCompFromResName(COMP_PROPULSION, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find propulsion component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_ECM:
		index = getCompFromResName(COMP_ECM, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find ECM component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_SENSOR:
		index = getCompFromResName(COMP_SENSOR, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find sensor component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_CONSTRUCT:
		index = getCompFromResName(COMP_CONSTRUCT, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find constructor component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_WEAPON:
		index = getCompFromResName(COMP_WEAPON, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find weapon %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_REPAIR:
		index = getCompFromResName(COMP_REPAIRUNIT, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find repair component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_BRAIN:
		index = getCompFromResName(COMP_BRAIN, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find repair brain %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_TEMPLATE:
		id = *((UDWORD *)pBuffer);
		endian_udword(&id);

		if (id == UDWORD_MAX)
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)IdToTemplate(id, ANYPLAYER);
			if ((DROID_TEMPLATE*)(psVal->v.oval) == NULL)
			{
				debug( LOG_FATAL, "scrValDefLoad: couldn't find template id %d", id );
				abort();
			}
		}
		break;
	case ST_TEXTSTRING:
		{
			const char* str;
			char* idStr;
			uint16_t len;

			if (size < sizeof(len))
			{
				debug(LOG_ERROR, "Data size is too small, %u is expected, but %u is provided", (unsigned int)(sizeof(len)), (unsigned int)size);
				return false;
			}

			len = *((uint16_t*)pBuffer);
			endian_uword(&len);

			if (size < sizeof(len) + len)
			{
				debug(LOG_ERROR, "Data size is too small, %u is expected, but %u is provided", (unsigned int)(sizeof(len) + len), (unsigned int)size);
				return false;
			}

			if (len == 0)
			{
				psVal->v.sval = NULL;
				return true;
			}

			idStr = (char *)malloc(len);
			if (!idStr)
			{
				debug(LOG_ERROR, "Out of memory (tried to allocate %u bytes)", (unsigned int)len);
				// Don't abort() here, as this might be the result from a bad "len" field in the data
				return false;
			}

			memcpy(idStr, pBuffer + sizeof(len), len);

			if (idStr[len - 1] != '\0')
			{
				debug(LOG_WARNING, "Non-NUL terminated string encountered!");
			}
			idStr[len - 1] = '\0';

			str = strresGetString(psStringRes, idStr);
			if (!str)
			{
				debug(LOG_ERROR, "Couldn't find string with id \"%s\"", idStr);
				free(idStr);
				return false;
			}
			free(idStr);

			psVal->v.sval = strdup(str);
			if (!psVal->v.sval)
			{
				debug(LOG_FATAL, "Out of memory");
				abort();
				return false;
			}
		}
		break;
	case ST_LEVEL:
		if ((size == 1) &&
			(*pBuffer == 0))
		{
			psVal->v.sval = '\0';
		}
		else
		{
			psLevel = levFindDataSet(pBuffer);
			if (psLevel == NULL)
			{
				debug( LOG_FATAL, "scrValDefLoad: couldn't find level dataset %s", pBuffer );
				abort();
			}
			psVal->v.sval = psLevel->pName;
		}
		break;
	case ST_RESEARCH:
		if ((size == 1) &&
			(*pBuffer == 0))
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)getResearch(pBuffer);
			if (psVal->v.oval == NULL)
			{
				debug( LOG_FATAL, "scrValDefLoad: couldn't find research %s", pBuffer );
				abort();
			}
		}
		break;
	case ST_GROUP:
		bObjectDefined = true;

		if (psVal->v.oval == NULL)
		{
			DROID_GROUP *tmp = grpCreate();
			tmp->add(NULL);
			psVal->v.oval = tmp;
		}

		pPos = pBuffer;

		if (version < 2)
		{
			members = size / sizeof(UDWORD);
		}
		else if (version < 3)
		{
			members = (size - sizeof(SDWORD)*4) / sizeof(UDWORD);
		}
		else
		{
			members = (size - sizeof(SDWORD)*6) / sizeof(UDWORD);

			// get saved group member count/nullpointer flag
			endian_sdword((SDWORD*)pPos);
			bObjectDefined = ( *((SDWORD *)pPos) != UNALLOCATED_OBJECT );

			if(bObjectDefined)
			{
				savedMembers = *((SDWORD *)pPos);	// get number of saved group members

				ASSERT(savedMembers == members, "scrValDefLoad: calculated and saved group member count did not match." );
			}
			pPos += sizeof(SDWORD);
		}

		// make sure group was allocated when it was saved (relevant starting from version 3)
		if( version < 3 || bObjectDefined )
		{
			if (version >= 2)
			{
				// load the retreat data
				psGroup = (DROID_GROUP*)(psVal->v.oval);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.sPos.x = *((SDWORD *)pPos);
				pPos += sizeof(SDWORD);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.sPos.y = *((SDWORD *)pPos);
				pPos += sizeof(SDWORD);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.forceLevel = (UBYTE)(*((SDWORD *)pPos));
				pPos += sizeof(SDWORD);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.leadership = (UBYTE)(*((SDWORD *)pPos));
				pPos += sizeof(SDWORD);
			}
			if (version >= 3)
			{
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.healthLevel = (UBYTE)(*((SDWORD *)pPos));
				pPos += sizeof(SDWORD);
			}

			// load the droids
			while (members > 0)
			{
				endian_udword((UDWORD*)pPos);
				id = *((UDWORD *) pPos);
				psCDroid = (DROID *)getBaseObjFromId(id);
				if (!psCDroid)
				{
					debug(LOG_ERROR, "Could not find object id %d", id);
				}
				else
				{
					((DROID_GROUP*)(psVal->v.oval))->add(psCDroid);
				}

				pPos += sizeof(UDWORD);
				members -= 1;
			}
		}
		else		// a group var was unallocated during saving
		{
			pPos += sizeof(UWORD);
		}
		break;
	case ST_SOUND:
		// find audio id

		// don't use sound if it's disabled
		if (audio_Disabled())
		{
			psVal->v.ival = NO_SOUND;
			break;
		}

		pName = pBuffer;
		index = audio_GetTrackID( pName );
		if (index == SAMPLE_NOT_FOUND)
		{
			// find empty id and set track vals
			index = audio_SetTrackVals(pName, false, 100, 1800);
			if (!index)			//this is a NON fatal error.
			{
				// We can't find filename of the sound for some reason.
				debug(LOG_ERROR, "Sound ID not available %s not found", pName);
				break;
			}
		}
		psVal->v.ival = index;
		break;
	case ST_STRUCTUREID:
	case ST_DROIDID:
	default:
		// just set the contents directly
		psVal->v.ival = *((SDWORD *)pBuffer);
		endian_sdword(&psVal->v.ival);
		break;
	}

	return true;
}
Exemplo n.º 2
0
// ////////////////////////////////////////////////////
static BOOL _addLoadSave(BOOL bLoad,CHAR *sSearchPath,CHAR *sExtension, CHAR *title)
{
	W_FORMINIT		sFormInit;
	W_BUTINIT		sButInit;
	W_LABINIT		sLabInit;
	UDWORD			slotCount;
	static STRING	sSlots[10][64];
	STRING			sTemp[255];

	WIN32_FIND_DATA	found;	
	HANDLE			dir;
	mode = bLoad;

	if(GetCurrentDirectory(255,(char*)&sTemp) == 0)
	{
		return FALSE;										// failed, directory probably didn't exist.
	}
	
	if ((bLoadSaveMode == LOAD_INGAME) || (bLoadSaveMode == SAVE_INGAME))
	{
		if (!bMultiPlayer || (NetPlay.bComms ==0))
		{
			gameTimeStop();
			if(GetGameMode() == GS_NORMAL)
			{	
				BOOL radOnScreen = radarOnScreen;				// Only do this in main game.
					
				bRender3DOnly = TRUE;
				radarOnScreen = FALSE;
		
				displayWorld();									// Just display the 3d, no interface
		
				pie_UploadDisplayBuffer(DisplayBuffer);			// Upload the current display back buffer into system memory.
			
				iV_ScaleBitmapRGB(DisplayBuffer,iV_GetDisplayWidth(),
								 iV_GetDisplayHeight(),2,2,2);	// Make it darker.
			
				radarOnScreen = radOnScreen;
				bRender3DOnly = FALSE;
			}

			setGamePauseStatus( TRUE );
			setGameUpdatePause(TRUE);
			setScriptPause(TRUE);
			setScrollPause(TRUE);
			setConsolePause(TRUE);

		}

		forceHidePowerBar();
		intRemoveReticule();
	}

	CreateDirectory(sSearchPath,NULL);			// create the directory required... fails if already there, so no problem.
	widgCreateScreen(&psRequestScreen);			// init the screen.
	widgSetTipFont(psRequestScreen,WFont);

	/* add a form to place the tabbed form on */
	memset(&sFormInit, 0, sizeof(W_FORMINIT));
	sFormInit.formID = 0;
	sFormInit.id = LOADSAVE_FORM;
	sFormInit.style = WFORM_PLAIN;
	sFormInit.x = (SWORD)(LOADSAVE_X);
	sFormInit.y = (SWORD)(LOADSAVE_Y);
	sFormInit.width = LOADSAVE_W;
	sFormInit.height = LOADSAVE_H;
	sFormInit.disableChildren = TRUE;
	sFormInit.pDisplay = intOpenPlainForm;
	widgAddForm(psRequestScreen, &sFormInit);

	// Add Banner
	sFormInit.formID = LOADSAVE_FORM;
	sFormInit.id = LOADSAVE_BANNER;
	sFormInit.x = LOADSAVE_HGAP;
	sFormInit.y = LOADSAVE_VGAP;
	sFormInit.width = LOADSAVE_W-(2*LOADSAVE_HGAP);
	sFormInit.height = LOADSAVE_BANNER_DEPTH;
	sFormInit.disableChildren = FALSE;
	sFormInit.pDisplay = displayLoadBanner;
	sFormInit.pUserData = (VOID *)bLoad;
	widgAddForm(psRequestScreen, &sFormInit);

	// Add Banner Label
	memset(&sLabInit, 0, sizeof(W_LABINIT));
	sLabInit.formID = LOADSAVE_BANNER;
	sLabInit.id		= LOADSAVE_LABEL;
	sLabInit.style	= WLAB_ALIGNCENTRE;
	sLabInit.x		= 0;
	sLabInit.y		= 4;
	sLabInit.width	= LOADSAVE_W-(2*LOADSAVE_HGAP);	//LOADSAVE_W;
	sLabInit.height = 20;
	sLabInit.pText	= title;
	sLabInit.FontID = WFont;
	widgAddLabel(psRequestScreen, &sLabInit);


	// add cancel.
	memset(&sButInit, 0, sizeof(W_BUTINIT));
	sButInit.formID = LOADSAVE_BANNER;
	sButInit.x = 4;
	sButInit.y = 3;
	sButInit.width		= iV_GetImageWidth(IntImages,IMAGE_NRUTER);
	sButInit.height		= iV_GetImageHeight(IntImages,IMAGE_NRUTER);
	sButInit.pUserData	= (void*)PACKDWORD_TRI(0,IMAGE_NRUTER , IMAGE_NRUTER);
	sButInit.id = LOADSAVE_CANCEL;
	sButInit.style = WBUT_PLAIN;
	sButInit.pTip = strresGetString(psStringRes, STR_MISC_CLOSE);
	sButInit.FontID = WFont;
	sButInit.pDisplay = intDisplayImageHilight;
	widgAddButton(psRequestScreen, &sButInit);

	// add slots
	memset(&sButInit, 0, sizeof(W_BUTINIT));
	sButInit.formID		= LOADSAVE_FORM;
	sButInit.style		= WBUT_PLAIN;
	sButInit.width		= LOADENTRY_W;
	sButInit.height		= LOADENTRY_H;
	sButInit.pDisplay	= displayLoadSlot;
	sButInit.FontID		= WFont;

	for(slotCount = 0; slotCount< 10 ; slotCount++)
	{
		sButInit.id		= slotCount+LOADENTRY_START;
		
		if(slotCount<5)
		{
			sButInit.x	= LOADSAVE_HGAP;
			sButInit.y	= (SWORD)((LOADSAVE_BANNER_DEPTH +(2*LOADSAVE_VGAP)) + (
                slotCount*(LOADSAVE_VGAP+LOADENTRY_H)));
		}
		else
		{
			sButInit.x	= (2*LOADSAVE_HGAP)+LOADENTRY_W;
			sButInit.y	= (SWORD)((LOADSAVE_BANNER_DEPTH +(2* LOADSAVE_VGAP)) + (
                (slotCount-5) *(LOADSAVE_VGAP+LOADENTRY_H)));
		}
		widgAddButton(psRequestScreen, &sButInit);
	}


	// fill slots.
	slotCount = 0;

	sprintf(sTemp,"%s*.%s",sSearchPath,sExtension);		// form search string.
	strcpy(sPath,sSearchPath);							// setup locals.
	strcpy(sExt,sExtension);
	dir =FindFirstFile(sTemp,&found);
	if(dir != INVALID_HANDLE_VALUE)
	{
		while( TRUE ) 
		{
			/* Set the tip and add the button */		
			found.cFileName[strlen(found.cFileName) -4 ] = '\0';			// chop extension

			strcpy(sSlots[slotCount],found.cFileName);		//store it!
			
			((W_BUTTON *)widgGetFromID(psRequestScreen,LOADENTRY_START+slotCount))->pTip		= sSlots[slotCount];
			((W_BUTTON *)widgGetFromID(psRequestScreen,LOADENTRY_START+slotCount))->pText		= sSlots[slotCount];
				
			slotCount++;		// goto next but.
	
			if(!FindNextFile(dir,&found ) || slotCount == 10 )// only show upto 10 entrys.
			{
				break;
			}
		}
	}
	FindClose(dir);
	bLoadSaveUp = TRUE;
	return TRUE;
}
Exemplo n.º 3
0
// ////////////////////////////////////////////////////////////////////////////
BOOL startKeyMapEditor(BOOL first)
{
	W_BUTINIT	sButInit;
	W_FORMINIT	sFormInit;
	KEY_MAPPING	*psMapping;
	UDWORD		i,mapcount =0;
	UDWORD		bubbleCount;
	BOOL		bAtEnd,bGotOne;
	KEY_MAPPING	*psPresent,*psNext;
	char		test[255];
	addBackdrop();
	addSideText	(FRONTEND_SIDETEXT ,KM_X-2,KM_Y,strresGetString(psStringRes, STR_KM_KEYMAP_SIDE));

	if(first)
	{
		loadKeyMap();									// get the current mappings.
	}
	memset(&sFormInit, 0, sizeof(W_FORMINIT));			// draw blue form...
	sFormInit.formID	= FRONTEND_BACKDROP;
	sFormInit.id		= KM_FORM;
	sFormInit.style		= WFORM_PLAIN;
	sFormInit.x			= KM_X;
	sFormInit.y			= KM_Y;
	sFormInit.width		= KM_W;
	sFormInit.height	= KM_H;
	sFormInit.pDisplay	= intDisplayPlainForm;
	widgAddForm(psWScreen, &sFormInit);	


	addMultiBut(psWScreen,KM_FORM,KM_RETURN,			// return button.
					8,5,
					iV_GetImageWidth(FrontImages,IMAGE_RETURN),
					iV_GetImageHeight(FrontImages,IMAGE_RETURN),
					STR_MUL_CANCEL,IMAGE_RETURN,IMAGE_RETURN_HI,TRUE);

	addMultiBut(psWScreen,KM_FORM,KM_DEFAULT,
				11,45,
				56,38,
				STR_MUL_DEFAULT,
				IMAGE_KEYMAP_DEFAULT,IMAGE_KEYMAP_DEFAULT,TRUE);	// default.


	/* Better be none that come after this...! */
	strcpy(test,"zzzzzzzzzzzzzzzzzzzzz");
	psMapping = NULL;

	//count mappings required.
	for(psMapping = keyMappings; psMapping; psMapping = psMapping->psNext)
	{
		if( (psMapping->status!=KEYMAP__DEBUG)&&(psMapping->status!=KEYMAP___HIDE))		// if it's not a debug mapping..
		{
			mapcount++;
			if(strcmp(psMapping->pName,test) < 0)
			{
				/* Best one found so far */
				strcpy(test,psMapping->pName);
				psPresent = psMapping;
			}
		}
	}

	// add tab form..
	memset(&sFormInit, 0, sizeof(W_FORMINIT));
	sFormInit.formID			= KM_FORM;	
	sFormInit.id				= KM_FORM_TABS;
	sFormInit.style				= WFORM_TABBED;
	sFormInit.x					= 50;
	sFormInit.y					= 10;
	sFormInit.width				= KM_W- 100;	
	sFormInit.height			= KM_H- 4;	
	sFormInit.numMajor			= numForms(mapcount, BUTTONSPERKEYMAPPAGE);
	sFormInit.majorPos			= WFORM_TABTOP;
	sFormInit.minorPos			= WFORM_TABNONE;
	sFormInit.majorSize			= OBJ_TABWIDTH+3; 
	sFormInit.majorOffset		= OBJ_TABOFFSET;
	sFormInit.tabVertOffset		= (OBJ_TABHEIGHT/2);
	sFormInit.tabMajorThickness = OBJ_TABHEIGHT;
	sFormInit.pFormDisplay		= intDisplayObjectForm;	
	sFormInit.pUserData			= (void*)&StandardTab;
	sFormInit.pTabDisplay		= intDisplayTab;
	for (i=0; i< sFormInit.numMajor; i++)
	{
		sFormInit.aNumMinors[i] = 1;
	}
	widgAddForm(psWScreen, &sFormInit);

	//Put the buttons on it 
	memset(&sButInit, 0, sizeof(W_BUTINIT));		
	sButInit.formID   = KM_FORM_TABS;
	sButInit.style	  = WFORM_PLAIN;
	sButInit.width    = KM_ENTRYW;
	sButInit.height	  = KM_ENTRYH;
	sButInit.pDisplay = displayKeyMap;
	sButInit.x		  = 2;
	sButInit.y		  = 16;
	sButInit.id	 	  = KM_START;


	/* Add our first mapping to the form */
	sButInit.pUserData= (VOID*)psPresent;
	widgAddButton(psWScreen, &sButInit);
	sButInit.id++;

	/* Now add the others... */
	bubbleCount = 0;
	bAtEnd = FALSE;
	/* Stop when the right number or when aphabetically last - not sure...! */
	while(bubbleCount<mapcount-1 AND !bAtEnd)
	{
		/* Same test as before for upper limit */
	 	strcpy(test,"zzzzzzzzzzzzzzzzzzzzz");
		for(psMapping = keyMappings,psNext = NULL,bGotOne = FALSE; psMapping; psMapping = psMapping->psNext)
		{
			/* Only certain mappings get displayed */
			if( (psMapping->status!=KEYMAP__DEBUG)&&(psMapping->status!=KEYMAP___HIDE))		// if it's not a debug mapping..
			{
				/* If it's alphabetically good but better then next one */
				if(strcmp(psMapping->pName,test) < 0 AND strcmp(psMapping->pName,psPresent->pName) > 0)
				{
					/* Keep a record of it */
					strcpy(test,psMapping->pName);
				   	psNext = psMapping;	
					bGotOne = TRUE;
				}
			}
		}
		/* We found one matching criteria */
		if(bGotOne)
		{
			psPresent = psNext;
			bubbleCount++;
	 		sButInit.pUserData= (VOID*)psNext;
	 		widgAddButton(psWScreen, &sButInit);
			 					// move on..
	 		sButInit.id++;
		  	/* Might be no more room on the page */
			if (  (sButInit.y + KM_ENTRYH+5 ) > (3+ (BUTTONSPERKEYMAPPAGE*(KM_ENTRYH+3))))
			{
				sButInit.y = 16;
				sButInit.majorID += 1;
			}
			else
			{
				sButInit.y +=  KM_ENTRYH +3;
			}
		}
		else
		{
			/* The previous one we found was alphabetically last - time to stop */
			bAtEnd = TRUE;
		}
	}

	/* Go home... */
	return TRUE;
}