458 lines
11 KiB
C
458 lines
11 KiB
C
/*
|
|
This file is part of Warzone 2100.
|
|
Copyright (C) 1999-2004 Eidos Interactive
|
|
Copyright (C) 2005-2007 Warzone Resurrection Project
|
|
|
|
Warzone 2100 is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Warzone 2100 is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Warzone 2100; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/*
|
|
* multilimit.c
|
|
*
|
|
* interface for setting limits to the game, bots, structlimits etc...
|
|
*/
|
|
#include "lib/framework/frame.h"
|
|
#include "lib/framework/frameresource.h"
|
|
#include "lib/framework/strres.h"
|
|
#include "lib/widget/widget.h"
|
|
#include "hci.h"
|
|
#include "intimage.h"
|
|
#include "intdisplay.h"
|
|
#include "init.h" // for gameheap
|
|
#include "frend.h"
|
|
#include "stats.h"
|
|
#include "frontend.h"
|
|
#include "component.h"
|
|
#include "loadsave.h"
|
|
#include "wrappers.h" // for loading screen
|
|
#include "lib/gamelib/gtime.h"
|
|
#include "console.h"
|
|
#include "lib/ivis_common/bitimage.h" // GFX incs
|
|
#include "lib/ivis_common/textdraw.h"
|
|
// FIXME Direct iVis implementation include!
|
|
#include "lib/ivis_opengl/piematrix.h"
|
|
#include "lib/ivis_common/piestate.h"
|
|
#include "lib/netplay/netplay.h"
|
|
#include "multiplay.h"
|
|
#include "multirecv.h"
|
|
#include "multiint.h"
|
|
#include "multilimit.h"
|
|
#include "lib/ivis_common/piemode.h"
|
|
#include "lib/script/script.h"
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
// externs
|
|
extern void intDisplayPlainForm (WIDGET *psWidget, UDWORD xOffset,
|
|
UDWORD yOffset, PIELIGHT *pColours);
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
// defines
|
|
#define IDLIMITS 22000
|
|
#define IDLIMITS_RETURN (IDLIMITS+1)
|
|
#define IDLIMITS_OK (IDLIMITS+2)
|
|
#define IDLIMITS_TABS (IDLIMITS+3)
|
|
#define IDLIMITS_ENTRIES_START (IDLIMITS+4)
|
|
#define IDLIMITS_ENTRIES_END (IDLIMITS+99)
|
|
|
|
#define LIMITSX 25
|
|
#define LIMITSY 30
|
|
#define LIMITSW 580
|
|
#define LIMITSH 430
|
|
|
|
#define LIMITS_OKX (LIMITSW-90)
|
|
#define LIMITS_OKY (LIMITSH-42)
|
|
|
|
#define BARWIDTH 480
|
|
#define BARHEIGHT 40
|
|
#define BUTPERFORM 8
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
// protos.
|
|
|
|
static void displayStructureBar(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGHT *pColours);
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
static BOOL useStruct(UDWORD count,UDWORD i)
|
|
{
|
|
// STRUCTURE_STATS *pStat = asStructureStats+i;
|
|
|
|
if(count >= (4*BUTPERFORM))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// now see if we loaded that stat..
|
|
if(asStructLimits[0][i].globalLimit ==LOTS_OF)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
BOOL startLimitScreen(void)
|
|
{
|
|
W_FORMINIT sButInit;
|
|
W_FORMINIT sFormInit;
|
|
UDWORD numButtons = 0;
|
|
UDWORD i;
|
|
|
|
addBackdrop();//background
|
|
|
|
// load stats...
|
|
if(!bForceEditorLoaded)
|
|
{
|
|
initLoadingScreen( TRUE );//changed by jeremy mar8
|
|
|
|
if (!resLoad("wrf/piestats.wrf", 501))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (!resLoad("wrf/forcedit2.wrf", 502))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
bForceEditorLoaded = TRUE;
|
|
closeLoadingScreen();
|
|
}
|
|
|
|
addSideText(FRONTEND_SIDETEXT1,LIMITSX-2,LIMITSY,"LIMITS"); // draw sidetext...
|
|
|
|
memset(&sFormInit, 0, sizeof(W_FORMINIT)); // draw blue form...
|
|
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,
|
|
// 8,5,
|
|
// iV_GetImageWidth(FrontImages,IMAGE_RETURN),
|
|
// iV_GetImageHeight(FrontImages,IMAGE_RETURN),
|
|
// _("Return To Previous Screen"),IMAGE_RETURN,IMAGE_RETURN_HI,TRUE);
|
|
|
|
|
|
// ok button
|
|
// addMultiBut(psWScreen,IDLIMITS,IDLIMITS_OK,
|
|
// LIMITS_OKX,LIMITS_OKY,
|
|
// iV_GetImageWidth(FrontImages,IMAGE_BIGOK),
|
|
// iV_GetImageHeight(FrontImages,IMAGE_BIGOK),
|
|
// _("Accept Settings"),IMAGE_BIGOK,IMAGE_BIGOK,TRUE);
|
|
|
|
addMultiBut(psWScreen,IDLIMITS,IDLIMITS_RETURN,
|
|
LIMITS_OKX-40,LIMITS_OKY,
|
|
iV_GetImageWidth(FrontImages,IMAGE_RETURN),
|
|
iV_GetImageHeight(FrontImages,IMAGE_RETURN),
|
|
_("Return To Previous Screen"),IMAGE_NO,IMAGE_NO,TRUE);
|
|
|
|
|
|
// ok button
|
|
addMultiBut(psWScreen,IDLIMITS,IDLIMITS_OK,
|
|
LIMITS_OKX,LIMITS_OKY,
|
|
iV_GetImageWidth(FrontImages,IMAGE_BIGOK),
|
|
iV_GetImageHeight(FrontImages,IMAGE_BIGOK),
|
|
_("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..
|
|
memset(&sFormInit, 0, sizeof(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.pFormDisplay = intDisplayObjectForm;
|
|
sFormInit.pUserData = &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 = 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, 0);
|
|
sButInit.id ++;
|
|
|
|
|
|
if (sButInit.y + BARHEIGHT + 2 > (BUTPERFORM*(BARHEIGHT+2) - 4) )
|
|
{
|
|
sButInit.y = 5;
|
|
sButInit.majorID += 1;
|
|
}
|
|
else
|
|
{
|
|
sButInit.y += BARHEIGHT +5;
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
void runLimitScreen(void)
|
|
{
|
|
UDWORD id,statid;
|
|
|
|
frontendMultiMessages(); // network stuff.
|
|
|
|
id = widgRunScreen(psWScreen); // Run the current set of widgets
|
|
|
|
// sliders
|
|
if((id > IDLIMITS_ENTRIES_START) && (id< IDLIMITS_ENTRIES_END))
|
|
{
|
|
statid = widgGetFromID(psWScreen,id-1)->UserData ;
|
|
if(statid)
|
|
{
|
|
asStructLimits[0][statid].limit = (UBYTE) ((W_SLIDER*)(widgGetFromID(psWScreen,id)))->pos;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// icons that are always about.
|
|
switch(id)
|
|
{
|
|
case IDLIMITS_RETURN:
|
|
// reset the sliders..
|
|
eventReset();
|
|
// resReleaseBlockData(500);
|
|
resReleaseBlockData(501);
|
|
resReleaseBlockData(502);
|
|
// eventReset();
|
|
bForceEditorLoaded = FALSE;
|
|
changeTitleMode(MULTIOPTION);
|
|
|
|
|
|
// make some noize.
|
|
if(!ingame.localOptionsReceived)
|
|
{
|
|
addConsoleMessage("Limits Reset To Default Values",DEFAULT_JUSTIFY);
|
|
}
|
|
else
|
|
{
|
|
sendTextMessage("Limits Reset To Default Values",TRUE);
|
|
}
|
|
|
|
|
|
break;
|
|
case IDLIMITS_OK:
|
|
createLimitSet();
|
|
changeTitleMode(MULTIOPTION);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
widgDisplayScreen(psWScreen); // show the widgets currently running
|
|
}
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
void createLimitSet(void)
|
|
{
|
|
UDWORD i,numchanges;
|
|
UBYTE *pChanges;
|
|
UBYTE *pEntry;
|
|
|
|
if(ingame.numStructureLimits) // free the old set if required.
|
|
{
|
|
ingame.numStructureLimits = 0;
|
|
free(ingame.pStructureLimits);
|
|
ingame.pStructureLimits = NULL;
|
|
}
|
|
|
|
numchanges =0; // count number of changes
|
|
for(i=0;i<numStructureStats;i++)
|
|
{
|
|
if(asStructLimits[0][i].limit != LOTS_OF)
|
|
{
|
|
numchanges++;
|
|
}
|
|
}
|
|
|
|
//close your eyes now
|
|
pChanges = (UBYTE*)malloc(numchanges*(sizeof(UDWORD)+sizeof(UBYTE))); // allocate some mem for this.
|
|
pEntry = pChanges;
|
|
|
|
for(i=0;i<numStructureStats;i++) // prepare chunk.
|
|
{
|
|
if(asStructLimits[0][i].limit != LOTS_OF)
|
|
{
|
|
memcpy(pEntry, &i,sizeof(UDWORD));
|
|
pEntry += sizeof(UDWORD);
|
|
memcpy(pEntry, &asStructLimits[0][i].limit,sizeof(UBYTE));
|
|
pEntry += sizeof(UBYTE);
|
|
}
|
|
}
|
|
// you can open them again.
|
|
|
|
ingame.numStructureLimits = numchanges;
|
|
ingame.pStructureLimits = pChanges;
|
|
|
|
sendOptions(0,0);
|
|
|
|
return;
|
|
}
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
void applyLimitSet(void)
|
|
{
|
|
UBYTE *pEntry;
|
|
UDWORD i;
|
|
UBYTE val;
|
|
UDWORD id;
|
|
|
|
if(ingame.numStructureLimits == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// get the limits
|
|
// decode and apply
|
|
pEntry = ingame.pStructureLimits;
|
|
for(i=0;i<ingame.numStructureLimits;i++) // prepare chunk.
|
|
{
|
|
memcpy(&id,pEntry,sizeof(UDWORD));
|
|
pEntry += sizeof(UDWORD);
|
|
memcpy(&val,pEntry,sizeof(UBYTE));
|
|
pEntry += sizeof(UBYTE);
|
|
|
|
if(id <numStructureStats)
|
|
{
|
|
asStructLimits[0][id].limit=val;
|
|
asStructLimits[1][id].limit=val;
|
|
asStructLimits[2][id].limit=val;
|
|
asStructLimits[3][id].limit=val;
|
|
asStructLimits[4][id].limit=val;
|
|
asStructLimits[5][id].limit=val;
|
|
asStructLimits[6][id].limit=val;
|
|
asStructLimits[7][id].limit=val;
|
|
}
|
|
}
|
|
|
|
// free.
|
|
if( ingame.numStructureLimits )
|
|
{
|
|
free(ingame.pStructureLimits);
|
|
ingame.numStructureLimits = 0;
|
|
ingame.pStructureLimits = NULL;
|
|
}
|
|
}
|
|
|
|
// ////////////////////////////////////////////////////////////////////////////
|
|
|
|
static void displayStructureBar(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGHT *pColours)
|
|
{
|
|
UDWORD x = xOffset+psWidget->x;
|
|
UDWORD y = yOffset+psWidget->y;
|
|
UDWORD w = psWidget->width;
|
|
UDWORD h = psWidget->height;
|
|
STRUCTURE_STATS *stat = asStructureStats + psWidget->UserData;
|
|
Vector3i Rotation, Position;
|
|
char str[3];
|
|
|
|
UDWORD scale,Radius;
|
|
|
|
drawBlueBox(x,y,w,h);
|
|
|
|
// draw image
|
|
pie_SetGeometricOffset( x+35 ,y+(psWidget->height/2)+9);
|
|
Rotation.x = -15;
|
|
Rotation.y = ((gameTime2/45)%360) ; //45
|
|
Rotation.z = 0;
|
|
Position.x = 0;
|
|
Position.y = 0;
|
|
Position.z = BUTTON_DEPTH*2;//getStructureStatSize(stat) * 38 * OBJECT_RADIUS;
|
|
|
|
Radius = getStructureStatSize(stat);
|
|
if(Radius <= 128) {
|
|
scale = SMALL_STRUCT_SCALE;
|
|
} else if(Radius <= 256) {
|
|
scale = MED_STRUCT_SCALE;
|
|
} else {
|
|
scale = LARGE_STRUCT_SCALE;
|
|
}
|
|
|
|
pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON);
|
|
displayStructureStatButton(stat ,0, &Rotation,&Position,TRUE, scale);
|
|
pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_ON);
|
|
|
|
// draw name
|
|
iV_SetFont(font_regular); // font
|
|
iV_SetTextColour(WZCOL_TEXT_BRIGHT);
|
|
iV_DrawText(getName(stat->pName), x+80, y+(psWidget->height/2)+3);
|
|
|
|
// draw limit
|
|
sprintf(str,"%d",((W_SLIDER*)(widgGetFromID(psWScreen,psWidget->id+1)))->pos);
|
|
iV_DrawText(str, x+270, y+(psWidget->height/2)+3);
|
|
|
|
return;
|
|
}
|