Exemple #1
0
CEx2 &CEx2::FmtRc(int ID, ...)
{
	va_list vargs;
	va_start( vargs, ID );

	Msg.Grow(QEX_MAXMSG);

	char data[QEX_MAXMSG];
	long len = resLoad(ghRes, ID, data, QEX_MAXMSG);

	if (len <= 0)
		Msg = "Unknown error.";
	else {
		Msg = CStr(data, len);
	}

	return FmtV(ID, Msg, vargs);
}
Exemple #2
0
// load up a single wrf file
static bool levLoadSingleWRF(const char* name)
{
	// free the old data
	if (!levReleaseAll())
	{
		return false;
	}

	// create the dummy level data
	if (sSingleWRF.pName)
	{
		free(sSingleWRF.pName);
	}

	memset(&sSingleWRF, 0, sizeof(LEVEL_DATASET));
	sSingleWRF.pName = strdup(name);

	// load up the WRF
	if (!stageOneInitialise())
	{
		return false;
	}

	// load the data
	debug(LOG_WZ, "Loading %s ...", name);
	if (!resLoad(name, 0))
	{
		return false;
	}

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

	psCurrLevel = &sSingleWRF;

	return true;
}
Exemple #3
0
CEx2 &CEx2::FmtRcF(int ID, ...)
{
	va_list vargs;
	va_start( vargs, ID );

	Msg=gEx2Prefix;

	Msg.Grow(QEX_MAXMSG);
	
	char data[QEX_MAXMSG];
	long len = resLoad(ghRes, ID, data, QEX_MAXMSG);

	if (len <= 0) {
		strcpy(Msg + gEx2PrefixLen, "Unknown error.");
	} else {
		strncpy(Msg + gEx2PrefixLen, data, QEX_MAXMSG - gEx2PrefixLen);
		Msg[QEX_MAXMSG - gEx2PrefixLen - 1] = 0;
	}

	Msg.Shrink();

	return FmtV(ID, Msg, ((char *)vargs)-sizeof(int));
}
Exemple #4
0
bool frontendInitialise(const char *ResourceFile)
{
	debug(LOG_MAIN, "Initialising frontend : %s", ResourceFile);

	if(!InitialiseGlobals())				// Initialise all globals and statics everywhere.
	{
		return false;
	}

	iV_Reset();								// Reset the IV library.

	if (!scrTabInitialise())				// Initialise the script system
	{
		return false;
	}

	if (!stringsInitialise())				// Initialise the string system
	{
		return false;
	}

	if (!objInitialise())					// Initialise the object system
	{
		return false;
	}

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

	if ( !animObj_Init( init_ObjectDead ) )
	{
		return false;
	}

	if (!allocPlayerPower())	 //set up the PlayerPower for each player - this should only be done ONCE now
	{
		return false;
	}

	debug(LOG_MAIN, "frontEndInitialise: loading resource file .....");
	if (!resLoad(ResourceFile, 0))
	{
		//need the object heaps to have been set up before loading in the save game
		return false;
	}

	if (!dispInitialise())					// Initialise the display system
	{
		return false;
	}

	FrontImages = (IMAGEFILE*)resGetData("IMG", "frontend.img");
   	/* Shift the interface initialisation here temporarily so that it
   		can pick up the stats after they have been loaded */
	if (!intInitialise())
	{
		return false;
	}

	// keymappings
	// clear out any existing mappings
	keyClearMappings();
	keyInitMappings(false);

	// Set the default uncoloured cursor here, since it looks slightly
	// better for menus and such.
	wzSetCursor(CURSOR_DEFAULT);

	SetFormAudioIDs(-1,ID_SOUND_WINDOWCLOSE);			// disable the open noise since distorted in 3dfx builds.

	initMiscVars();

	gameTimeInit();

	// hit me with some funky beats....
	cdAudio_PlayTrack(SONG_FRONTEND);

	return true;
}
Exemple #5
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;
}
Exemple #6
0
// ////////////////////////////////////////////////////////////////////////////
bool startLimitScreen(void)
{
	addBackdrop();//background

	// load stats...
	if(!bLimiterLoaded)
	{
		initLoadingScreen(true);
		
		if (!resLoad("wrf/limiter_tex.wrf", 501))
		{
			return false;
		}

		if (!resLoad("wrf/piestats.wrf", 502))
		{
			return false;
		}

		if (!resLoad("wrf/limiter_data.wrf", 503))
		{
			return false;
		}

		bLimiterLoaded = true;

		closeLoadingScreen();		
	}

	if (challengeActive)
	{
		// reset the sliders..
		// it's a HACK since the actual limiter structure was cleared in the startMultiOptions function 
		for (unsigned i = 0; i < numStructureStats; ++i)
		{
			asStructLimits[0][i].limit = asStructLimits[0][i].globalLimit;
		}
		
		// turn off the sliders
		sliderEnableDrag(false);
	}
	else
	{
		//enable the sliders
		sliderEnableDrag(true);
	}

	addSideText(FRONTEND_SIDETEXT1,LIMITSX-2,LIMITSY,"LIMITS");	// draw sidetext...

	WIDGET *parent = widgGetFromID(psWScreen, FRONTEND_BACKDROP);

	IntFormAnimated *limitsForm = new IntFormAnimated(parent, false);
	limitsForm->id = IDLIMITS;
	limitsForm->setGeometry(LIMITSX, LIMITSY, LIMITSW, LIMITSH);

	// return button.
	addMultiBut(psWScreen,IDLIMITS,IDLIMITS_RETURN,
					LIMITS_OKX-40,LIMITS_OKY,
	            iV_GetImageWidth(FrontImages, IMAGE_NO),
	            iV_GetImageHeight(FrontImages, IMAGE_NO),
					_("Apply Defaults and Return To Previous Screen"),IMAGE_NO,IMAGE_NO,true);

	// ok button
	addMultiBut(psWScreen,IDLIMITS,IDLIMITS_OK,
					LIMITS_OKX,LIMITS_OKY,
					iV_GetImageWidth(FrontImages,IMAGE_OK),
					iV_GetImageHeight(FrontImages,IMAGE_OK),
					_("Accept Settings"),IMAGE_OK,IMAGE_OK,true);

	// add tab form..
	IntListTabWidget *limitsList = new IntListTabWidget(limitsForm);
	limitsList->setChildSize(BARWIDTH, BARHEIGHT);
	limitsList->setChildSpacing(5, 5);
	limitsList->setGeometry(50, 10, BARWIDTH, 370);

	//Put the buttons on it
	int limitsButtonId = IDLIMITS_ENTRIES_START;

	for (unsigned i = 0; i < numStructureStats; ++i)
	{
		if (asStructLimits[0][i].globalLimit != LOTS_OF)
		{
			W_FORM *button = new W_FORM(limitsList);
			button->id = limitsButtonId;
			button->displayFunction = displayStructureBar;
			button->UserData = i;
			limitsList->addWidgetToLayout(button);
			++limitsButtonId;

			addFESlider(limitsButtonId, limitsButtonId - 1, 290, 11,
						asStructLimits[0][i].globalLimit,
						asStructLimits[0][i].limit);
			++limitsButtonId;
		}
	}

	return true;
}
Exemple #7
0
tMenuOption playAnimation(int id) {

	/* Declare variables */
	int imgCount,         objCount,              sndCount,               i;
	animImage*  img;      animObject* obj;       animSound* snd;
	titleImage* imgArray; titleObject* objArray; /*animSound* sndArray;*/
	int imgsActive=0;     int objsActive=0;      /*int sndsActive=0;*/
	int imgTotal,         objTotal,              sndTotal;

	tKey key=inputCreateKey();
	tKey nullKey=inputCreateKey();

	/* Initialize animation and allocate memory */
	animStart(id,&imgTotal,&objTotal,&sndTotal);
	imgArray=(titleImage*)malloc(imgTotal*sizeof(titleImage));
	objArray=(titleObject*)malloc(objTotal*sizeof(titleObject));
	/*sndArray=(animSound*)malloc(sndTotal*sizeof(animSound));*/

	/* main animation kernel loop */
	while (animGetFrame(&imgCount,&objCount,&sndCount,&img,&obj,&snd)) {
		int reprocessInput=1;

		while(reprocessInput) {
		if (!inputGetEvent(&key)) {
			/* key pressed */
		 	/*  if there is an action      and  the action wasn't control key */
			if (key.actionPerformed!=none  &&   !(inputGetCtrl(key.status)&&key.actionPerformed==other))
				return getAction(key);
		} else {
			reprocessInput=0;
			/* create new images/objects/sounds */
			for (i=0;i<imgCount;i++) { /*images*/
				imgArray[imgsActive].img=resLoad(img[i].res);
				if (!imgArray[imgsActive].img) {
					fprintf(stderr,"resource coudn't be loaded.");
					return menuQuit;
				}
				imgArray[imgsActive].y=img[i].y;
				imgArray[imgsActive].x=img[i].x;
				imgArray[imgsActive].layer=img[i].layer;
				imgArray[imgsActive].duration=img[i].duration;
				imgsActive++;
			}
			for (i=0;i<objCount;i++) { /*objects*/
				objArray[objsActive].obj=objectCreate(obj[i].location,obj[i].floor,DIR_LEFT,obj[i].state,obj[i].res,obj[i].cacheMirror,oGeneric);
				objArray[objsActive].active=1;
				objArray[objsActive].duration=obj[i].duration;
				objsActive++;
			}
/*		TODO: code sounds	
 *		for (i=0;i<sndCount;i++) {
				sndArray[sndsActive]=snd[i];
				sndsActive++;
			}*/

			outputClearScreen();

			/* The bottom layer */
			for (i=0;i<imgsActive;i++) {
				if (imgArray[i].layer==ANIMS_LAYERTYPE_BOTTOM)
					outputDrawBitmap(imgArray[i].img->pFrames[0], imgArray[i].x, imgArray[i].y);
			}
			
			/* move objects */
			for (i=0;i<objsActive;i++) {
				/*TODO: detect exits */
				if (objArray[i].active) {
					int exitCode;
		  		exitCode=objectMove(&(objArray[i].obj),nullKey,NULL);
					if (objArray[i].duration) objArray[i].duration--;

					/* detect exited states and destroy them */

					/* if the time is over or exit code detected */
					if ((objArray[i].duration==1)||(exitCode<0)) {
						/*printf("exit Code detected: i=%d exit=%d \n",i,exitCode);*/
						objectFree(&objArray[i].obj);
						objArray[i].active=0; /* remember it is destroyed */
					} else {
		  			objectDraw(&objArray[i].obj);
					}
				}
			}
			
			/* The top layer */
			for (i=0;i<imgsActive;i++) {
				if (imgArray[i].layer==ANIMS_LAYERTYPE_TOP) {
					outputDrawBitmap(imgArray[i].img->pFrames[0], imgArray[i].x, imgArray[i].y);
				}
			}
			outputUpdateScreen();

			/* caducied backgrounds destruction */
			i=imgsActive;
			while(i) {
				i--;
				if (imgArray[i].duration) { /* if not 0 (infinite) */
					imgArray[i].duration--;
					if (!imgArray[i].duration) { /* time is over for this images */
						imgsActive--;
						resFree(imgArray[i].img);
						imgArray[i]=imgArray[imgsActive];
					}
				}
			}	}
		}
	}

	for (i=0;i<objsActive;i++) if (objArray[i].active) objectFree(&objArray[i].obj);
	for (i=0;i<imgsActive;i++) resFree(imgArray[i].img);
	free(imgArray);
	free(objArray);
	/*free(sndArray);*/
	return menuQuit;
}
// ////////////////////////////////////////////////////////////////////////////
bool startLimitScreen(void)
{
    UDWORD			numButtons = 0;
    UDWORD			i;

    addBackdrop();//background

    // load stats...
    if(!bLimiterLoaded)
    {
        initLoadingScreen(true);

        if (!resLoad("wrf/limiter_tex.wrf", 501))
        {
            return false;
        }

        if (!resLoad("wrf/piestats.wrf", 502))
        {
            return false;
        }

        if (!resLoad("wrf/limiter_data.wrf", 503))
        {
            return false;
        }

        bLimiterLoaded = true;

        closeLoadingScreen();
    }

    if (challengeActive)
    {
        // reset the sliders..
        // it's a HACK since the actual limiter structure was cleared in the startMultiOptions function
        for (i = 0; i < numStructureStats ; ++i)
        {
            asStructLimits[0][i].limit = asStructLimits[0][i].globalLimit;
        }

        // turn off the sliders
        sliderEnableDrag(false);
    }
    else
    {
        //enable the sliders
        sliderEnableDrag(true);
    }

    addSideText(FRONTEND_SIDETEXT1,LIMITSX-2,LIMITSY,"LIMITS");	// draw sidetext...

    W_FORMINIT sFormInit;
    sFormInit.formID	= FRONTEND_BACKDROP;
    sFormInit.id		= IDLIMITS;
    sFormInit.style		= WFORM_PLAIN;
    sFormInit.x			= LIMITSX;
    sFormInit.y			= LIMITSY;
    sFormInit.width		= LIMITSW;
    sFormInit.height	= LIMITSH;
    sFormInit.pDisplay	= intDisplayPlainForm;
    widgAddForm(psWScreen, &sFormInit);

    // return button.
    addMultiBut(psWScreen,IDLIMITS,IDLIMITS_RETURN,
                LIMITS_OKX-40,LIMITS_OKY,
                iV_GetImageWidth(FrontImages,IMAGE_RETURN),
                iV_GetImageHeight(FrontImages,IMAGE_RETURN),
                _("Apply Defaults and Return To Previous Screen"),IMAGE_NO,IMAGE_NO,true);

    // ok button
    addMultiBut(psWScreen,IDLIMITS,IDLIMITS_OK,
                LIMITS_OKX,LIMITS_OKY,
                iV_GetImageWidth(FrontImages,IMAGE_OK),
                iV_GetImageHeight(FrontImages,IMAGE_OK),
                _("Accept Settings"),IMAGE_OK,IMAGE_OK,true);

    // Count the number of minor tabs needed
    numButtons = 0;

    for(i=0; i<numStructureStats; i++ )
    {
        if(useStruct(numButtons,i))
        {
            numButtons++;
        }
    }

    if(numButtons >(4*BUTPERFORM)) numButtons =(4*BUTPERFORM);

    // add tab form..
    sFormInit = W_FORMINIT();
    sFormInit.formID = IDLIMITS;
    sFormInit.id = IDLIMITS_TABS;
    sFormInit.style = WFORM_TABBED;
    sFormInit.x = 50;
    sFormInit.y = 10;
    sFormInit.width = LIMITSW - 100;
    sFormInit.height =LIMITSH - 4;
    sFormInit.numMajor = numForms(numButtons, BUTPERFORM);
    sFormInit.majorPos = WFORM_TABTOP;
    sFormInit.minorPos = WFORM_TABNONE;
    sFormInit.majorSize = OBJ_TABWIDTH+3; //!!
    sFormInit.majorOffset = OBJ_TABOFFSET;
    sFormInit.tabVertOffset = (OBJ_TABHEIGHT/2);			//(DES_TAB_HEIGHT/2)+2;
    sFormInit.tabMajorThickness = OBJ_TABHEIGHT;
    sFormInit.pUserData = &StandardTab;
    sFormInit.pTabDisplay = intDisplayTab;

    // TABFIXME --unsure if needs fixing yet.
    for (i=0; i< sFormInit.numMajor; i++)
    {
        sFormInit.aNumMinors[i] = 1;
    }
    widgAddForm(psWScreen, &sFormInit);

    //Put the buttons on it
    W_FORMINIT sButInit;
    sButInit.formID   = IDLIMITS_TABS;//IDLIMITS;
    sButInit.style	  = WFORM_PLAIN;
    sButInit.width    = BARWIDTH;
    sButInit.height	  = BARHEIGHT;
    sButInit.pDisplay = displayStructureBar;
    sButInit.x		  = 2;
    sButInit.y		  = 5;
    sButInit.id	 	  = IDLIMITS_ENTRIES_START;

    numButtons =0;
    for(i=0; i<numStructureStats ; i++)
    {
        if(useStruct(numButtons,i))
        {
            numButtons++;
            sButInit.UserData= i;

            widgAddForm(psWScreen, &sButInit);
            sButInit.id	++;

            addFESlider(sButInit.id,sButInit.id-1, 290,11,
                        asStructLimits[0][i].globalLimit,
                        asStructLimits[0][i].limit);
            sButInit.id	++;

            if (sButInit.y + BARHEIGHT + 2 > (BUTPERFORM*(BARHEIGHT+2) - 4) )
            {
                sButInit.y = 5;
                sButInit.majorID += 1;
            }
            else
            {
                sButInit.y +=  BARHEIGHT +5;
            }
        }
    }

    return true;
}