12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252 |
- #ifdef PRECOMPILEDHEADERS
- #include "Tactical All.h"
- #else
- #include "math.h"
- #include <stdio.h>
- #include <errno.h>
- #include "worlddef.h"
- #include "renderworld.h"
- #include "vsurface.h"
- #include "Render Dirty.h"
- #include "sysutil.h"
- #include "container.h"
- #include "wcheck.h"
- #include "video.h"
- #include "vobject_blitters.h"
- #include "faces.h"
- #include "utilities.h"
- #include "overhead.h"
- #include "gap.h"
- #include "Soldier Profile.h"
- #include "sound control.h"
- #include "teamturns.h"
- #include "soldier macros.h"
- #include "dialogue control.h"
- #include "font control.h"
- #include "Assignments.h"
- #include "Random.h"
- #include "line.h"
- #include "GameSettings.h"
- #include "squads.h"
- #include "interface.h"
- #include "Quests.h"
- #include "animation control.h"
- #endif
- // Defines
- #define NUM_FACE_SLOTS 50
- #define END_FACE_OVERLAY_DELAY 2000
- // GLOBAL FOR FACES LISTING
- FACETYPE gFacesData[ NUM_FACE_SLOTS ];
- UINT32 guiNumFaces = 0;
- // LOCAL FUNCTIONS
- void NewEye( FACETYPE *pFace );
- void NewMouth( FACETYPE *pFace );
- INT32 GetFreeFace(void);
- void RecountFaces(void);
- void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLEAN fUseExternBuffer, UINT32 uiBuffer, INT16 sFaceX, INT16 sFaceY, UINT16 usEyesX, UINT16 usEyesY );
- extern BOOLEAN gfInItemPickupMenu;
- typedef struct
- {
- INT8 bEyesX;
- INT8 bEyesY;
- INT8 bMouthX;
- INT8 bMouthY;
- } RPC_SMALL_FACE_VALUES;
- RPC_SMALL_FACE_VALUES gRPCSmallFaceValues[ ] =
- {
- 9, 8, 8, 24, // MIGUEL ( 57 )
- 8, 8, 7, 24, // CARLOS ( 58 )
- 10, 8, 8, 26, // IRA ( 59 )
- 7, 8, 7, 26, // DIMITRI ( 60 )
- 6, 7, 7, 23, // DEVIN ( 61 )
- 0, 0, 0, 0, // THE RAT ( 62 )
- 8, 7, 8, 23, // ( 63 )
- 8, 8, 8, 22, // SLAY ( 64 )
- 0, 0, 0, 0, // ( 65 )
- 9, 4, 7, 22, // DYNAMO ( 66 )
- 8, 8, 8, 25, // SHANK ( 67 )
- 4, 6, 5, 22, // IGGY ( 68 )
- 8, 9, 7, 25, // VINCE ( 69 )
- 4, 7, 5, 25, // CONRAD ( 70 )
- 9, 7, 8, 22, // CARL ( 71 )
- 9, 7, 9, 25, // MADDOG ( 72 )
- 0, 0, 0, 0, // ( 73 )
- 0, 0, 0, 0, // ( 74 )
-
- 9, 3, 8, 23, // MARIA ( 88 )
- 9, 3, 8, 25, // JOEY ( 90 )
-
- 11, 7, 9, 24, // SKYRIDER ( 97 )
- 9, 5, 7, 23, // Miner ( 106 )
- 6, 4, 6, 24, // JOHN ( 118 )
- 12,4, 10, 24, // ( 119 )
- 8, 6, 8, 23, // Miner ( 148 )
- 6, 5, 6, 23, // Miner ( 156 )
- 13, 7, 11, 24, // Miner ( 157 )
- 9, 7, 8, 22, // Miner ( 158 )
- };
- UINT8 gubRPCSmallFaceProfileNum[] =
- {
- 57, // entry 0
- 58,
- 59,
- 60,
- 61,
- 62,
- 63,
- 64,
- 65,
- 66, // entry 9
- 67,
- 68,
- 69,
- 70,
- 71,
- 72,
- 73,
- 74,
- 88,
- 90, // entry 19
- 97,
- 106,
- 118,
- 119,
- 148, // entry 24
- 156,
- 157,
- 158,
-
- };
- UINT8 ubRPCNumSmallFaceValues = 28;
- extern BOOLEAN gfSMDisableForItems;
- extern INT16 gsCurInterfacePanel;
- extern UINT16 gusSMCurrentMerc;
- extern BOOLEAN gfRerenderInterfaceFromHelpText;
- extern BOOLEAN gfInItemPickupMenu;
-
- BOOLEAN FaceRestoreSavedBackgroundRect( INT32 iFaceIndex, INT16 sDestLeft, INT16 sDestTop, INT16 sSrcLeft, INT16 sSrcTop, INT16 sWidth, INT16 sHeight );
- void SetupFinalTalkingDelay( FACETYPE *pFace );
- INT32 GetFreeFace(void)
- {
- UINT32 uiCount;
- for(uiCount=0; uiCount < guiNumFaces; uiCount++)
- {
- if((gFacesData[uiCount].fAllocated==FALSE) )
- return((INT32)uiCount);
- }
- if(guiNumFaces < NUM_FACE_SLOTS )
- return((INT32)guiNumFaces++);
- return(-1);
- }
- void RecountFaces(void)
- {
- INT32 uiCount;
- for(uiCount=guiNumFaces-1; (uiCount >=0) ; uiCount--)
- {
- if( ( gFacesData[uiCount].fAllocated ) )
- {
- guiNumFaces=(UINT32)(uiCount+1);
- break;
- }
- }
- }
- INT32 InitSoldierFace( SOLDIERTYPE *pSoldier )
- {
- INT32 iFaceIndex;
- // Check if we have a face init already
- iFaceIndex = pSoldier->iFaceIndex;
-
- if ( iFaceIndex != -1 )
- {
- return( iFaceIndex );
- }
- return( InitFace( pSoldier->ubProfile, pSoldier->ubID, 0) );
- }
- INT32 InitFace( UINT8 usMercProfileID, UINT8 ubSoldierID, UINT32 uiInitFlags )
- {
- UINT32 uiBlinkFrequency;
- UINT32 uiExpressionFrequency;
- if ( usMercProfileID == NO_PROFILE )
- {
- return( -1 );
- }
- uiBlinkFrequency = gMercProfiles[ usMercProfileID ].uiBlinkFrequency;
- uiExpressionFrequency = gMercProfiles[ usMercProfileID ].uiExpressionFrequency;
- if ( Random( 2 ) )
- {
- uiBlinkFrequency += Random( 2000 );
- }
- else
- {
- uiBlinkFrequency -= Random( 2000 );
- }
- return( InternalInitFace( usMercProfileID, ubSoldierID, uiInitFlags, gMercProfiles[ usMercProfileID ].ubFaceIndex, uiBlinkFrequency, uiExpressionFrequency ) );
- }
- INT32 InternalInitFace( UINT8 usMercProfileID, UINT8 ubSoldierID, UINT32 uiInitFlags, INT32 iFaceFileID, UINT32 uiBlinkFrequency, UINT32 uiExpressionFrequency )
- {
- FACETYPE *pFace;
- VOBJECT_DESC VObjectDesc;
- UINT32 uiVideoObject;
- INT32 iFaceIndex;
- ETRLEObject ETRLEObject;
- HVOBJECT hVObject;
- UINT32 uiCount;
- SGPPaletteEntry Pal[256];
- if( ( iFaceIndex = GetFreeFace() )==(-1) )
- return(-1);
- // Load face file
- VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
- // ATE: If we are merc profile ID #151-154, all use 151's protrait....
- if ( usMercProfileID >= 151 && usMercProfileID <= 154 )
- {
- iFaceFileID = 151;
- }
- // Check if we are a big-face....
- if ( uiInitFlags & FACE_BIGFACE )
- {
- // The filename is the profile ID!
- if( iFaceFileID < 100 )
- {
- sprintf( VObjectDesc.ImageFile, "FACES\\b%02d.sti", iFaceFileID );
- }
- else
- {
- sprintf( VObjectDesc.ImageFile, "FACES\\b%03d.sti", iFaceFileID );
- }
- // ATE: Check for profile - if elliot , use special face :)
- if ( usMercProfileID == ELLIOT )
- {
- if ( gMercProfiles[ ELLIOT ].bNPCData > 3 && gMercProfiles[ ELLIOT ].bNPCData < 7 )
- {
- sprintf( VObjectDesc.ImageFile, "FACES\\b%02da.sti", iFaceFileID );
- }
- else if ( gMercProfiles[ ELLIOT ].bNPCData > 6 && gMercProfiles[ ELLIOT ].bNPCData < 10 )
- {
- sprintf( VObjectDesc.ImageFile, "FACES\\b%02db.sti", iFaceFileID );
- }
- else if ( gMercProfiles[ ELLIOT ].bNPCData > 9 && gMercProfiles[ ELLIOT ].bNPCData < 13 )
- {
- sprintf( VObjectDesc.ImageFile, "FACES\\b%02dc.sti", iFaceFileID );
- }
- else if ( gMercProfiles[ ELLIOT ].bNPCData > 12 && gMercProfiles[ ELLIOT ].bNPCData < 16 )
- {
- sprintf( VObjectDesc.ImageFile, "FACES\\b%02dd.sti", iFaceFileID );
- }
- else if ( gMercProfiles[ ELLIOT ].bNPCData == 17 )
- {
- sprintf( VObjectDesc.ImageFile, "FACES\\b%02de.sti", iFaceFileID );
- }
- }
- }
- else
- {
- if( iFaceFileID < 100 )
- {
- // The filename is the profile ID!
- sprintf( VObjectDesc.ImageFile, "FACES\\%02d.sti", iFaceFileID );
- }
- else
- {
- sprintf( VObjectDesc.ImageFile, "FACES\\%03d.sti", iFaceFileID );
- }
- }
- // Load
- if( AddVideoObject( &VObjectDesc, &uiVideoObject ) == FALSE )
- {
- // If we are a big face, use placeholder...
- if ( uiInitFlags & FACE_BIGFACE )
- {
- sprintf( VObjectDesc.ImageFile, "FACES\\placeholder.sti" );
- if( AddVideoObject( &VObjectDesc, &uiVideoObject ) == FALSE )
- {
- return( -1 );
- }
- }
- else
- {
- return( -1 );
- }
- }
- memset(&gFacesData[ iFaceIndex ], 0, sizeof( FACETYPE ) );
- pFace = &gFacesData[ iFaceIndex ];
- // Get profile data and set into face data
- pFace->ubSoldierID = ubSoldierID;
- pFace->iID = iFaceIndex;
- pFace->fAllocated = TRUE;
- //Default to off!
- pFace->fDisabled = TRUE;
- pFace->iVideoOverlay = -1;
- //pFace->uiEyeDelay = gMercProfiles[ usMercProfileID ].uiEyeDelay;
- //pFace->uiMouthDelay = gMercProfiles[ usMercProfileID ].uiMouthDelay;
- pFace->uiEyeDelay = 50 + Random( 30 );
- pFace->uiMouthDelay = 120;
- pFace->ubCharacterNum = usMercProfileID;
- pFace->uiBlinkFrequency = uiBlinkFrequency;
- pFace->uiExpressionFrequency = uiExpressionFrequency;
- pFace->sEyeFrame = 0;
- pFace->sMouthFrame = 0;
- pFace->uiFlags = uiInitFlags;
- // Set palette
- if( GetVideoObject( &hVObject, uiVideoObject ) )
- {
- // Build a grayscale palette! ( for testing different looks )
- for(uiCount=0; uiCount < 256; uiCount++)
- {
- Pal[uiCount].peRed=255;
- Pal[uiCount].peGreen=255;
- Pal[uiCount].peBlue=255;
- }
- hVObject->pShades[ FLASH_PORTRAIT_NOSHADE ] = Create16BPPPaletteShaded( hVObject->pPaletteEntry, 255, 255, 255, FALSE );
- hVObject->pShades[ FLASH_PORTRAIT_STARTSHADE ] = Create16BPPPaletteShaded( Pal, 255, 255, 255, FALSE );
- hVObject->pShades[ FLASH_PORTRAIT_ENDSHADE ] = Create16BPPPaletteShaded( hVObject->pPaletteEntry, 250, 25, 25, TRUE );
- hVObject->pShades[ FLASH_PORTRAIT_DARKSHADE ] = Create16BPPPaletteShaded( hVObject->pPaletteEntry, 100, 100, 100, TRUE );
- hVObject->pShades[ FLASH_PORTRAIT_LITESHADE ] = Create16BPPPaletteShaded( hVObject->pPaletteEntry, 100, 100, 100, FALSE );
- for(uiCount=0; uiCount < 256; uiCount++)
- {
- Pal[uiCount].peRed=(UINT8)(uiCount%128)+128;
- Pal[uiCount].peGreen=(UINT8)(uiCount%128)+128;
- Pal[uiCount].peBlue=(UINT8)(uiCount%128)+128;
- }
- hVObject->pShades[ FLASH_PORTRAIT_GRAYSHADE ] = Create16BPPPaletteShaded( Pal, 255, 255, 255, FALSE );
- }
- // Get FACE height, width
- if( GetVideoObjectETRLEPropertiesFromIndex( uiVideoObject, &ETRLEObject, 0 ) == FALSE )
- {
- return( -1 );
- }
- pFace->usFaceWidth = ETRLEObject.usWidth;
- pFace->usFaceHeight = ETRLEObject.usHeight;
- // OK, check # of items
- if ( hVObject->usNumberOfObjects == 8 )
- {
- pFace->fInvalidAnim = FALSE;
- // Get EYE height, width
- if( GetVideoObjectETRLEPropertiesFromIndex( uiVideoObject, &ETRLEObject, 1 ) == FALSE )
- {
- return( -1 );
- }
- pFace->usEyesWidth = ETRLEObject.usWidth;
- pFace->usEyesHeight = ETRLEObject.usHeight;
- // Get Mouth height, width
- if( GetVideoObjectETRLEPropertiesFromIndex( uiVideoObject, &ETRLEObject, 5 ) == FALSE )
- {
- return( -1 );
- }
- pFace->usMouthWidth = ETRLEObject.usWidth;
- pFace->usMouthHeight = ETRLEObject.usHeight;
- }
- else
- {
- pFace->fInvalidAnim = TRUE;
- }
- // Set id
- pFace->uiVideoObject = uiVideoObject;
- return( iFaceIndex );
- }
- void DeleteSoldierFace( SOLDIERTYPE *pSoldier )
- {
- DeleteFace( pSoldier->iFaceIndex );
- pSoldier->iFaceIndex = -1;
- }
- void DeleteFace( INT32 iFaceIndex )
- {
- FACETYPE *pFace;
- // Check face index
- CHECKV( iFaceIndex != -1 );
- pFace = &gFacesData[ iFaceIndex ];
- // Check for a valid slot!
- CHECKV( pFace->fAllocated != FALSE );
- pFace->fCanHandleInactiveNow = TRUE;
- if ( !pFace->fDisabled )
- {
- SetAutoFaceInActive( iFaceIndex );
- }
- // If we are still talking, stop!
- if ( pFace->fTalking )
- {
- // Call dialogue handler function
- pFace->fTalking = FALSE;
- HandleDialogueEnd( pFace );
- }
- // Delete vo
- DeleteVideoObjectFromIndex( pFace->uiVideoObject );
-
- // Set uncallocated
- pFace->fAllocated = FALSE;
- RecountFaces( );
- }
- void SetAutoFaceActiveFromSoldier( UINT32 uiDisplayBuffer, UINT32 uiRestoreBuffer, UINT8 ubSoldierID , UINT16 usFaceX, UINT16 usFaceY )
- {
- if( ubSoldierID == NOBODY )
- {
- return;
- }
- SetAutoFaceActive( uiDisplayBuffer, uiRestoreBuffer, MercPtrs[ ubSoldierID ]->iFaceIndex, usFaceX, usFaceY );
- }
- void GetFaceRelativeCoordinates( FACETYPE *pFace, UINT16 *pusEyesX, UINT16 *pusEyesY, UINT16 *pusMouthX, UINT16 *pusMouthY )
- {
- UINT16 usMercProfileID;
- UINT16 usEyesX;
- UINT16 usEyesY;
- UINT16 usMouthX;
- UINT16 usMouthY;
- INT32 cnt;
- usMercProfileID = pFace->ubCharacterNum;
- //Take eyes x,y from profile unless we are an RPC and we are small faced.....
- usEyesX = gMercProfiles[ usMercProfileID ].usEyesX;
- usEyesY = gMercProfiles[ usMercProfileID ].usEyesY;
- usMouthY = gMercProfiles[ usMercProfileID ].usMouthY;
- usMouthX = gMercProfiles[ usMercProfileID ].usMouthX;
- // Use some other values for x,y, base on if we are a RPC!
- if ( !( pFace->uiFlags & FACE_BIGFACE ) ||( pFace->uiFlags & FACE_FORCE_SMALL ))
- {
- // Are we a recruited merc? .. or small?
- if( ( gMercProfiles[ usMercProfileID ].ubMiscFlags & ( PROFILE_MISC_FLAG_RECRUITED | PROFILE_MISC_FLAG_EPCACTIVE ) ) ||( pFace->uiFlags & FACE_FORCE_SMALL ) )
- {
- // Loop through all values of availible merc IDs to find ours!
- for ( cnt = 0; cnt < ubRPCNumSmallFaceValues; cnt++ )
- {
- // We've found one!
- if ( gubRPCSmallFaceProfileNum[ cnt ] == usMercProfileID )
- {
- usEyesX = gRPCSmallFaceValues[ cnt ].bEyesX;
- usEyesY = gRPCSmallFaceValues[ cnt ].bEyesY;
- usMouthY = gRPCSmallFaceValues[ cnt ].bMouthY;
- usMouthX = gRPCSmallFaceValues[ cnt ].bMouthX;
- }
- }
- }
- }
- (*pusEyesX) = usEyesX;
- (*pusEyesY) = usEyesY;
- (*pusMouthX) = usMouthX;
- (*pusMouthY) = usMouthY;
- }
- void SetAutoFaceActive( UINT32 uiDisplayBuffer, UINT32 uiRestoreBuffer, INT32 iFaceIndex , UINT16 usFaceX, UINT16 usFaceY )
- {
- UINT16 usEyesX;
- UINT16 usEyesY;
- UINT16 usMouthX;
- UINT16 usMouthY;
- FACETYPE *pFace;
- // Check face index
- CHECKV( iFaceIndex != -1 );
- pFace = &gFacesData[ iFaceIndex ];
- GetFaceRelativeCoordinates( pFace, &usEyesX, &usEyesY, &usMouthX, &usMouthY );
- InternalSetAutoFaceActive( uiDisplayBuffer, uiRestoreBuffer, iFaceIndex , usFaceX, usFaceY, usEyesX, usEyesY, usMouthX, usMouthY );
- }
- void InternalSetAutoFaceActive( UINT32 uiDisplayBuffer, UINT32 uiRestoreBuffer, INT32 iFaceIndex , UINT16 usFaceX, UINT16 usFaceY, UINT16 usEyesX, UINT16 usEyesY, UINT16 usMouthX, UINT16 usMouthY )
- {
- UINT16 usMercProfileID;
- FACETYPE *pFace;
- VSURFACE_DESC vs_desc;
- UINT16 usWidth;
- UINT16 usHeight;
- UINT8 ubBitDepth;
- // Check face index
- CHECKV( iFaceIndex != -1 );
- pFace = &gFacesData[ iFaceIndex ];
- // IF we are already being contained elsewhere, return without doing anything!
- // ATE: Don't allow another activity from setting active....
- if ( pFace->uiFlags & FACE_INACTIVE_HANDLED_ELSEWHERE )
- {
- return;
- }
- // Check if we are active already, remove if so!
- if ( pFace->fDisabled )
- {
- SetAutoFaceInActive( iFaceIndex );
- }
- if ( uiRestoreBuffer == FACE_AUTO_RESTORE_BUFFER )
- {
- // BUILD A BUFFER
- GetCurrentVideoSettings( &usWidth, &usHeight, &ubBitDepth );
- // OK, ignore screen widths, height, only use BPP
- vs_desc.fCreateFlags = VSURFACE_CREATE_DEFAULT | VSURFACE_SYSTEM_MEM_USAGE;
- vs_desc.usWidth = pFace->usFaceWidth;
- vs_desc.usHeight = pFace->usFaceHeight;
- vs_desc.ubBitDepth = ubBitDepth;
- pFace->fAutoRestoreBuffer = TRUE;
- CHECKV( AddVideoSurface( &vs_desc, &(pFace->uiAutoRestoreBuffer) ) );
- }
- else
- {
- pFace->fAutoRestoreBuffer = FALSE;
- pFace->uiAutoRestoreBuffer = uiRestoreBuffer;
- }
- if ( uiDisplayBuffer == FACE_AUTO_DISPLAY_BUFFER )
- {
- // BUILD A BUFFER
- GetCurrentVideoSettings( &usWidth, &usHeight, &ubBitDepth );
- // OK, ignore screen widths, height, only use BPP
- vs_desc.fCreateFlags = VSURFACE_CREATE_DEFAULT | VSURFACE_SYSTEM_MEM_USAGE;
- vs_desc.usWidth = pFace->usFaceWidth;
- vs_desc.usHeight = pFace->usFaceHeight;
- vs_desc.ubBitDepth = ubBitDepth;
- pFace->fAutoDisplayBuffer = TRUE;
- CHECKV( AddVideoSurface( &vs_desc, &(pFace->uiAutoDisplayBuffer) ) );
- }
- else
- {
- pFace->fAutoDisplayBuffer = FALSE;
- pFace->uiAutoDisplayBuffer = uiDisplayBuffer;
- }
- usMercProfileID = pFace->ubCharacterNum;
- pFace->usFaceX = usFaceX;
- pFace->usFaceY = usFaceY;
- pFace->fCanHandleInactiveNow = FALSE;
- //Take eyes x,y from profile unless we are an RPC and we are small faced.....
- pFace->usEyesX = usEyesX + usFaceX;
- pFace->usEyesY = usEyesY + usFaceY;
- pFace->usMouthY = usMouthY + usFaceY;
- pFace->usMouthX = usMouthX + usFaceX;
- // Save offset values
- pFace->usEyesOffsetX = usEyesX;
- pFace->usEyesOffsetY = usEyesY;
- pFace->usMouthOffsetY = usMouthY;
- pFace->usMouthOffsetX = usMouthX;
-
- if ( pFace->usEyesY == usFaceY || pFace->usMouthY == usFaceY )
- {
- pFace->fInvalidAnim = TRUE;
- }
- pFace->fDisabled = FALSE;
- pFace->uiLastBlink = GetJA2Clock();
- pFace->uiLastExpression = GetJA2Clock();
- pFace->uiEyelast = GetJA2Clock();
- pFace->fStartFrame = TRUE;
- // Are we a soldier?
- if ( pFace->ubSoldierID != NOBODY )
- {
- pFace->bOldSoldierLife = MercPtrs[ pFace->ubSoldierID ]->bLife;
- }
- }
- void SetAutoFaceInActiveFromSoldier( UINT8 ubSoldierID )
- {
- // Check for valid soldier
- CHECKV( ubSoldierID != NOBODY );
- SetAutoFaceInActive( MercPtrs[ ubSoldierID ]->iFaceIndex );
- }
- void SetAutoFaceInActive(INT32 iFaceIndex )
- {
- FACETYPE *pFace;
- SOLDIERTYPE *pSoldier;
- // Check face index
- CHECKV( iFaceIndex != -1 );
- pFace = &gFacesData[ iFaceIndex ];
- // Check for a valid slot!
- CHECKV( pFace->fAllocated != FALSE );
- // Turn off some flags
- if ( pFace->uiFlags & FACE_INACTIVE_HANDLED_ELSEWHERE )
- {
- if ( !pFace->fCanHandleInactiveNow )
- {
- return;
- }
- }
- if ( pFace->uiFlags & FACE_MAKEACTIVE_ONCE_DONE )
- {
- //
- if ( pFace->ubSoldierID != NOBODY )
- {
- pSoldier = MercPtrs[ pFace->ubSoldierID ];
- // IF we are in tactical
- if ( pSoldier->bAssignment == iCurrentTacticalSquad && guiCurrentScreen == GAME_SCREEN )
- {
- // Make the interfac panel dirty..
- // This will dirty the panel next frame...
- gfRerenderInterfaceFromHelpText = TRUE;
- }
- }
- }
- if ( pFace->fAutoRestoreBuffer )
- {
- DeleteVideoSurfaceFromIndex( pFace->uiAutoRestoreBuffer );
- }
- if ( pFace->fAutoDisplayBuffer )
- {
- DeleteVideoSurfaceFromIndex( pFace->uiAutoDisplayBuffer );
- }
- if ( pFace->iVideoOverlay != -1 )
- {
- RemoveVideoOverlay( pFace->iVideoOverlay );
- pFace->iVideoOverlay = -1;
- }
- // Turn off some flags
- pFace->uiFlags &= ( ~FACE_INACTIVE_HANDLED_ELSEWHERE );
-
- // Disable!
- pFace->fDisabled = TRUE;
-
- }
- void SetAllAutoFacesInactive( )
- {
- UINT32 uiCount;
- FACETYPE *pFace;
- for ( uiCount = 0; uiCount < guiNumFaces; uiCount++ )
- {
- if ( gFacesData[ uiCount ].fAllocated )
- {
- pFace = &gFacesData[ uiCount ];
- SetAutoFaceInActive( uiCount );
- }
- }
- }
- void BlinkAutoFace( INT32 iFaceIndex )
- {
- FACETYPE *pFace;
- INT16 sFrame;
- BOOLEAN fDoBlink = FALSE;
- if ( gFacesData[ iFaceIndex ].fAllocated && !gFacesData[ iFaceIndex ].fDisabled && !gFacesData[ iFaceIndex ].fInvalidAnim )
- {
- pFace = &gFacesData[ iFaceIndex ];
- // CHECK IF BUDDY IS DEAD, UNCONSCIOUS, ASLEEP, OR POW!
- if ( pFace->ubSoldierID != NOBODY )
- {
- if ( ( MercPtrs[ pFace->ubSoldierID ]->bLife < OKLIFE ) ||
- ( MercPtrs[ pFace->ubSoldierID ]->fMercAsleep == TRUE ) ||
- ( MercPtrs[ pFace->ubSoldierID ]->bAssignment == ASSIGNMENT_POW ) )
- {
- return;
- }
- }
- if ( pFace->ubExpression == NO_EXPRESSION )
- {
- // Get Delay time, if the first frame, use a different delay
- if ( ( GetJA2Clock() - pFace->uiLastBlink ) > pFace->uiBlinkFrequency )
- {
- pFace->uiLastBlink = GetJA2Clock();
- pFace->ubExpression = BLINKING;
- pFace->uiEyelast = GetJA2Clock();
- }
- if ( pFace->fAnimatingTalking )
- {
- if ( ( GetJA2Clock() - pFace->uiLastExpression ) > pFace->uiExpressionFrequency )
- {
- pFace->uiLastExpression = GetJA2Clock();
- if ( Random( 2 ) == 0 )
- {
- pFace->ubExpression = ANGRY;
- }
- else
- {
- pFace->ubExpression = SURPRISED;
- }
- }
- }
- }
- if ( pFace->ubExpression != NO_EXPRESSION )
- {
- if ( pFace->fStartFrame )
- {
- if ( ( GetJA2Clock() - pFace->uiEyelast ) > pFace->uiEyeDelay ) //> Random( 10000 ) )
- {
- fDoBlink = TRUE;
- pFace->fStartFrame = FALSE;
- }
- }
- else
- {
- if ( ( GetJA2Clock() - pFace->uiEyelast ) > pFace->uiEyeDelay )
- {
- fDoBlink = TRUE;
- }
- }
- // Are we going to blink?
- if ( fDoBlink )
- {
- pFace->uiEyelast = GetJA2Clock();
- // Adjust
- NewEye( pFace );
-
- sFrame = pFace->sEyeFrame;
- if ( sFrame >= 5 )
- {
- sFrame = 4;
- }
- if ( sFrame > 0 )
- {
- // Blit Accordingly!
- BltVideoObjectFromIndex( pFace->uiAutoDisplayBuffer, pFace->uiVideoObject, (INT16)( sFrame ), pFace->usEyesX, pFace->usEyesY, VO_BLT_SRCTRANSPARENCY, NULL );
- if ( pFace->uiAutoDisplayBuffer == FRAME_BUFFER )
- {
- InvalidateRegion( pFace->usEyesX, pFace->usEyesY, pFace->usEyesX + pFace->usEyesWidth, pFace->usEyesY + pFace->usEyesHeight );
- }
- }
- else
- {
- //RenderFace( uiDestBuffer , uiCount );
- pFace->ubExpression = NO_EXPRESSION;
- // Update rects just for eyes
-
- if ( pFace->uiAutoRestoreBuffer == guiSAVEBUFFER )
- {
- FaceRestoreSavedBackgroundRect( iFaceIndex, pFace->usEyesX, pFace->usEyesY, pFace->usEyesX, pFace->usEyesY, pFace->usEyesWidth, pFace->usEyesHeight );
- }
- else
- {
- FaceRestoreSavedBackgroundRect( iFaceIndex, pFace->usEyesX, pFace->usEyesY, pFace->usEyesOffsetX, pFace->usEyesOffsetY, pFace->usEyesWidth, pFace->usEyesHeight );
- }
- }
- HandleRenderFaceAdjustments( pFace, TRUE, FALSE, 0, pFace->usFaceX, pFace->usFaceY, pFace->usEyesX, pFace->usEyesY );
- }
- }
- }
- }
- void HandleFaceHilights( FACETYPE *pFace, UINT32 uiBuffer, INT16 sFaceX, INT16 sFaceY )
- {
- UINT32 uiDestPitchBYTES;
- UINT8 *pDestBuf;
- UINT16 usLineColor;
- INT32 iFaceIndex;
- iFaceIndex = pFace->iID;
- if ( !gFacesData[ iFaceIndex ].fDisabled )
- {
- if ( pFace->uiAutoDisplayBuffer == FRAME_BUFFER && guiCurrentScreen == GAME_SCREEN )
- {
- // If we are highlighted, do this now!
- if ( ( pFace->uiFlags & FACE_SHOW_WHITE_HILIGHT ) )
- {
- // Lock buffer
- pDestBuf = LockVideoSurface( uiBuffer, &uiDestPitchBYTES );
- SetClippingRegionAndImageWidth( uiDestPitchBYTES, sFaceX-2, sFaceY-1, sFaceX + pFace->usFaceWidth + 4, sFaceY + pFace->usFaceHeight + 4 );
- usLineColor = Get16BPPColor( FROMRGB( 255, 255, 255 ) );
- RectangleDraw( TRUE, (sFaceX - 2 ), (sFaceY - 1),sFaceX + pFace->usFaceWidth + 1, sFaceY + pFace->usFaceHeight , usLineColor, pDestBuf );
- SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, 640, 480 );
- UnLockVideoSurface( uiBuffer );
- }
- else if ( ( pFace->uiFlags & FACE_SHOW_MOVING_HILIGHT ) )
- {
- if ( pFace->ubSoldierID != NOBODY )
- {
- if ( MercPtrs[ pFace->ubSoldierID ]->bLife >= OKLIFE )
- {
- // Lock buffer
- pDestBuf = LockVideoSurface( uiBuffer, &uiDestPitchBYTES );
- SetClippingRegionAndImageWidth( uiDestPitchBYTES, sFaceX-2, sFaceY-1, sFaceX + pFace->usFaceWidth + 4, sFaceY + pFace->usFaceHeight + 4 );
-
- if ( MercPtrs[ pFace->ubSoldierID ]->bStealthMode )
- {
- usLineColor = Get16BPPColor( FROMRGB( 158, 158, 12 ) );
- }
- else
- {
- usLineColor = Get16BPPColor( FROMRGB( 8, 12, 118 ) );
- }
- RectangleDraw( TRUE, (sFaceX - 2 ), (sFaceY - 1),sFaceX + pFace->usFaceWidth + 1, sFaceY + pFace->usFaceHeight , usLineColor, pDestBuf );
- SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, 640, 480 );
- UnLockVideoSurface( uiBuffer );
- }
- }
- }
- else
- {
- // ATE: Zero out any highlight boxzes....
- // Lock buffer
- pDestBuf = LockVideoSurface( pFace->uiAutoDisplayBuffer, &uiDestPitchBYTES );
- SetClippingRegionAndImageWidth( uiDestPitchBYTES, pFace->usFaceX-2, pFace->usFaceY-1, pFace->usFaceX + pFace->usFaceWidth + 4, pFace->usFaceY + pFace->usFaceHeight + 4 );
- usLineColor = Get16BPPColor( FROMRGB( 0, 0, 0 ) );
- RectangleDraw( TRUE, (pFace->usFaceX - 2 ), (pFace->usFaceY - 1), pFace->usFaceX + pFace->usFaceWidth + 1, pFace->usFaceY + pFace->usFaceHeight , usLineColor, pDestBuf );
- SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, 640, 480 );
- UnLockVideoSurface( pFace->uiAutoDisplayBuffer );
- }
- }
- }
- if ( ( pFace->fCompatibleItems && !gFacesData[ iFaceIndex ].fDisabled ) )
- {
- // Lock buffer
- pDestBuf = LockVideoSurface( uiBuffer, &uiDestPitchBYTES );
- SetClippingRegionAndImageWidth( uiDestPitchBYTES, sFaceX-2, sFaceY-1, sFaceX + pFace->usFaceWidth+ 4, sFaceY + pFace->usFaceHeight + 4 );
- usLineColor = Get16BPPColor( FROMRGB( 255, 0, 0 ) );
- RectangleDraw( TRUE, (sFaceX - 2), (sFaceY - 1), sFaceX + pFace->usFaceWidth + 1, sFaceY + pFace->usFaceHeight , usLineColor, pDestBuf );
- SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, 640, 480 );
- UnLockVideoSurface( uiBuffer );
- }
- }
- void MouthAutoFace( INT32 iFaceIndex )
- {
- FACETYPE *pFace;
- INT16 sFrame;
- if ( gFacesData[ iFaceIndex ].fAllocated )
- {
- pFace = &gFacesData[ iFaceIndex ];
- // Remove video overlay is present....
- if ( pFace->uiFlags & FACE_DESTROY_OVERLAY )
- {
- //if ( pFace->iVideoOverlay != -1 )
- //{
- // if ( pFace->uiStopOverlayTimer != 0 )
- // {
- // if ( ( GetJA2Clock( ) - pFace->uiStopOverlayTimer ) > END_FACE_OVERLAY_DELAY )
- // {
- // RemoveVideoOverlay( pFace->iVideoOverlay );
- // pFace->iVideoOverlay = -1;
- // }
- // }
- //}
- }
- if ( pFace->fTalking )
- {
- if ( !gFacesData[ iFaceIndex ].fDisabled && !gFacesData[ iFaceIndex ].fInvalidAnim )
- {
- if ( pFace->fAnimatingTalking )
- {
- PollAudioGap( pFace->uiSoundID, &(pFace->GapList ) );
- // Check if we have an audio gap
- if ( pFace->GapList.audio_gap_active )
- {
- pFace->sMouthFrame = 0;
- if ( pFace->uiAutoRestoreBuffer == guiSAVEBUFFER )
- {
- FaceRestoreSavedBackgroundRect( iFaceIndex, pFace->usMouthX, pFace->usMouthY, pFace->usMouthX, pFace->usMouthY, pFace->usMouthWidth, pFace->usMouthHeight );
- }
- else
- {
- FaceRestoreSavedBackgroundRect( iFaceIndex, pFace->usMouthX, pFace->usMouthY, pFace->usMouthOffsetX, pFace->usMouthOffsetY, pFace->usMouthWidth, pFace->usMouthHeight );
- }
- }
- else
- {
- // Get Delay time
- if ( ( GetJA2Clock() - pFace->uiMouthlast ) > pFace->uiMouthDelay )
- {
- pFace->uiMouthlast = GetJA2Clock();
- // Adjust
- NewMouth( pFace );
-
- sFrame = pFace->sMouthFrame;
- if ( sFrame > 0 )
- {
- // Blit Accordingly!
- BltVideoObjectFromIndex( pFace->uiAutoDisplayBuffer, pFace->uiVideoObject, (INT16)( sFrame + 4 ), pFace->usMouthX, pFace->usMouthY, VO_BLT_SRCTRANSPARENCY, NULL );
- // Update rects
- if ( pFace->uiAutoDisplayBuffer == FRAME_BUFFER )
- {
- InvalidateRegion( pFace->usMouthX, pFace->usMouthY, pFace->usMouthX + pFace->usMouthWidth, pFace->usMouthY + pFace->usMouthHeight );
- }
- }
- else
- {
- //RenderFace( uiDestBuffer , uiCount );
- //pFace->fTaking = FALSE;
- // Update rects just for Mouth
- if ( pFace->uiAutoRestoreBuffer == guiSAVEBUFFER )
- {
- FaceRestoreSavedBackgroundRect( iFaceIndex, pFace->usMouthX, pFace->usMouthY, pFace->usMouthX, pFace->usMouthY, pFace->usMouthWidth, pFace->usMouthHeight );
- }
- else
- {
- FaceRestoreSavedBackgroundRect( iFaceIndex, pFace->usMouthX, pFace->usMouthY, pFace->usMouthOffsetX, pFace->usMouthOffsetY, pFace->usMouthWidth, pFace->usMouthHeight );
- }
- }
- HandleRenderFaceAdjustments( pFace, TRUE, FALSE, 0, pFace->usFaceX, pFace->usFaceY, pFace->usEyesX, pFace->usEyesY );
- }
- }
- }
- }
- }
- if ( !( pFace->uiFlags & FACE_INACTIVE_HANDLED_ELSEWHERE ) )
- {
- HandleFaceHilights( pFace, pFace->uiAutoDisplayBuffer, pFace->usFaceX, pFace->usFaceY );
- }
- }
- }
- void HandleTalkingAutoFace( INT32 iFaceIndex )
- {
- FACETYPE *pFace;
- if ( gFacesData[ iFaceIndex ].fAllocated )
- {
- pFace = &gFacesData[ iFaceIndex ];
- if ( pFace->fTalking )
- {
- // Check if we are done! ( Check this first! )
- if ( pFace->fValidSpeech )
- {
- // Check if we have finished, set some flags for the final delay down if so!
- if ( !SoundIsPlaying( pFace->uiSoundID ) && !pFace->fFinishTalking )
- {
- SetupFinalTalkingDelay( pFace );
- }
- }
- else
- {
- // Check if our delay is over
- if ( !pFace->fFinishTalking )
- {
- if ( ( GetJA2Clock() - pFace->uiTalkingTimer ) > pFace->uiTalkingDuration )
- {
- // If here, setup for last delay!
- SetupFinalTalkingDelay( pFace );
- }
- }
- }
- // Now check for end of talking
- if ( pFace->fFinishTalking )
- {
- if ( ( GetJA2Clock() - pFace->uiTalkingTimer ) > pFace->uiTalkingDuration )
- {
- pFace->fTalking = FALSE;
- pFace->fAnimatingTalking = FALSE;
-
- // Remove gap info
- AudioGapListDone( &(pFace->GapList) );
- // Remove video overlay is present....
- if ( pFace->iVideoOverlay != -1 )
- {
- //if ( pFace->uiStopOverlayTimer == 0 )
- //{
- // pFace->uiStopOverlayTimer = GetJA2Clock();
- //}
- }
- // Call dialogue handler function
- HandleDialogueEnd( pFace );
- }
- }
- }
- }
- }
- // Local function - uses these variables because they have already been validated
- void SetFaceShade( SOLDIERTYPE *pSoldier, FACETYPE *pFace, BOOLEAN fExternBlit )
- {
- // Set to default
- SetObjectHandleShade( pFace->uiVideoObject, FLASH_PORTRAIT_NOSHADE );
- if ( pFace->iVideoOverlay == -1 && !fExternBlit )
- {
- if ( ( pSoldier->bActionPoints == 0 ) && !( gTacticalStatus.uiFlags & REALTIME ) && (gTacticalStatus.uiFlags & INCOMBAT ) )
- {
- SetObjectHandleShade( pFace->uiVideoObject, FLASH_PORTRAIT_LITESHADE );
- }
- }
- if ( pSoldier->bLife < OKLIFE )
- {
- SetObjectHandleShade( pFace->uiVideoObject, FLASH_PORTRAIT_DARKSHADE );
- }
- // ATE: Don't shade for damage if blitting extern face...
- if ( !fExternBlit )
- {
- if ( pSoldier->fFlashPortrait == FLASH_PORTRAIT_START )
- {
- SetObjectHandleShade( pFace->uiVideoObject, pSoldier->bFlashPortraitFrame );
- }
- }
- }
- BOOLEAN RenderAutoFaceFromSoldier( UINT8 ubSoldierID )
- {
- // Check for valid soldier
- CHECKF( ubSoldierID != NOBODY );
- return( RenderAutoFace( MercPtrs[ ubSoldierID ]->iFaceIndex ) );
- }
- void GetXYForIconPlacement( FACETYPE *pFace, UINT16 ubIndex, INT16 sFaceX, INT16 sFaceY, INT16 *psX, INT16 *psY )
- {
- INT16 sX, sY;
- UINT16 usWidth, usHeight;
- ETRLEObject *pTrav;
- HVOBJECT hVObject;
- // Get height, width of icon...
- GetVideoObject( &hVObject, guiPORTRAITICONS );
- pTrav = &(hVObject->pETRLEObject[ ubIndex ] );
- usHeight = pTrav->usHeight;
- usWidth = pTrav->usWidth;
- sX = sFaceX + pFace->usFaceWidth - usWidth - 1;
- sY = sFaceY + pFace->usFaceHeight - usHeight - 1;
- *psX = sX;
- *psY = sY;
- }
- void GetXYForRightIconPlacement( FACETYPE *pFace, UINT16 ubIndex, INT16 sFaceX, INT16 sFaceY, INT16 *psX, INT16 *psY, INT8 bNumIcons )
- {
- INT16 sX, sY;
- UINT16 usWidth, usHeight;
- ETRLEObject *pTrav;
- HVOBJECT hVObject;
- // Get height, width of icon...
- GetVideoObject( &hVObject, guiPORTRAITICONS );
- pTrav = &(hVObject->pETRLEObject[ ubIndex ] );
- usHeight = pTrav->usHeight;
- usWidth = pTrav->usWidth;
- sX = sFaceX + ( usWidth * bNumIcons ) + 1;
- sY = sFaceY + pFace->usFaceHeight - usHeight - 1;
- *psX = sX;
- *psY = sY;
- }
- void DoRightIcon( UINT32 uiRenderBuffer, FACETYPE *pFace, INT16 sFaceX, INT16 sFaceY, INT8 bNumIcons, INT8 sIconIndex )
- {
- INT16 sIconX, sIconY;
- // Find X, y for placement
- GetXYForRightIconPlacement( pFace, sIconIndex, sFaceX, sFaceY, &sIconX, &sIconY, bNumIcons );
- BltVideoObjectFromIndex( uiRenderBuffer, guiPORTRAITICONS, sIconIndex, sIconX, sIconY, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLEAN fUseExternBuffer, UINT32 uiBuffer, INT16 sFaceX, INT16 sFaceY, UINT16 usEyesX, UINT16 usEyesY )
- {
- INT16 sIconX, sIconY;
- INT16 sIconIndex=-1;
- BOOLEAN fDoIcon = FALSE;
- UINT32 uiRenderBuffer;
- INT16 sPtsAvailable = 0;
- UINT16 usMaximumPts = 0;
- CHAR16 sString[ 32 ];
- UINT16 usTextWidth;
- BOOLEAN fAtGunRange = FALSE;
- BOOLEAN fShowNumber = FALSE;
- BOOLEAN fShowMaximum = FALSE;
- SOLDIERTYPE *pSoldier;
- INT16 sFontX, sFontY;
- INT16 sX1, sY1, sY2, sX2;
- UINT32 uiDestPitchBYTES;
- UINT8 *pDestBuf;
- UINT16 usLineColor;
- INT8 bNumRightIcons = 0;
- // If we are using an extern buffer...
- if ( fUseExternBuffer )
- {
- uiRenderBuffer = uiBuffer;
- }
- else
- {
- if ( fDisplayBuffer )
- {
- uiRenderBuffer = pFace->uiAutoDisplayBuffer;
- }
- else
- {
- uiRenderBuffer = pFace->uiAutoRestoreBuffer;
- if ( pFace->uiAutoRestoreBuffer == FACE_NO_RESTORE_BUFFER )
- {
- return;
- }
- }
- }
- // BLIT HATCH
- if ( pFace->ubSoldierID != NOBODY )
- {
- pSoldier = MercPtrs[ pFace->ubSoldierID ];
- if ( ( MercPtrs[ pFace->ubSoldierID ]->bLife < CONSCIOUSNESS || MercPtrs[ pFace->ubSoldierID ]->fDeadPanel ) )
- {
- // Blit Closed eyes here!
- BltVideoObjectFromIndex( uiRenderBuffer, pFace->uiVideoObject, 1, usEyesX, usEyesY, VO_BLT_SRCTRANSPARENCY, NULL );
- // Blit hatch!
- BltVideoObjectFromIndex( uiRenderBuffer, guiHATCH, 0, sFaceX, sFaceY, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- if( MercPtrs[ pFace->ubSoldierID ]->fMercAsleep == TRUE )
- {
- // blit eyes closed
- BltVideoObjectFromIndex( uiRenderBuffer, pFace->uiVideoObject, 1, usEyesX, usEyesY, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- if ( ( pSoldier->uiStatusFlags & SOLDIER_DEAD ) )
- {
- // IF we are in the process of doing any deal/close animations, show face, not skill...
- if ( !pSoldier->fClosePanel && !pSoldier->fDeadPanel && !pSoldier->fUIdeadMerc && !pSoldier->fUICloseMerc )
- {
- // Put close panel there
- BltVideoObjectFromIndex( uiRenderBuffer, guiDEAD, 5, sFaceX, sFaceY, VO_BLT_SRCTRANSPARENCY, NULL );
- // Blit hatch!
- BltVideoObjectFromIndex( uiRenderBuffer, guiHATCH, 0, sFaceX, sFaceY, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- }
- // ATE: If talking in popup, don't do the other things.....
- if ( pFace->fTalking && gTacticalStatus.uiFlags & IN_ENDGAME_SEQUENCE )
- {
- return;
- }
- // ATE: Only do this, because we can be talking during an interrupt....
- if ( ( pFace->uiFlags & FACE_INACTIVE_HANDLED_ELSEWHERE ) && !fUseExternBuffer )
- {
- // Don't do this if we are being handled elsewhere and it's not an extern buffer...
- }
- else
- {
- HandleFaceHilights( pFace, uiRenderBuffer, sFaceX, sFaceY );
- #ifdef JA2BETAVERSION
- if ( pSoldier->bOppCnt != 0 )
- #else
- if ( pSoldier->bOppCnt > 0 )
- #endif
- {
- SetFontDestBuffer( uiRenderBuffer, 0, 0, 640, 480, FALSE );
- swprintf( sString, L"%d", pSoldier->bOppCnt );
- SetFont( TINYFONT1 );
- SetFontForeground( FONT_DKRED );
- SetFontBackground( FONT_NEARBLACK );
- sX1 = (INT16)( sFaceX );
- sY1 = (INT16)( sFaceY );
- sX2 = sX1 + StringPixLength( sString, TINYFONT1 ) + 1;
- sY2 = sY1 + GetFontHeight( TINYFONT1 ) - 1;
- mprintf( (INT16)( sX1 + 1), (INT16)( sY1 - 1 ), sString );
- SetFontDestBuffer( FRAME_BUFFER, 0, 0, 640, 480, FALSE );
- // Draw box
- pDestBuf = LockVideoSurface( uiRenderBuffer, &uiDestPitchBYTES );
- SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, 640, 480 );
- usLineColor = Get16BPPColor( FROMRGB( 105, 8, 9 ) );
- RectangleDraw( TRUE, sX1, sY1, sX2, sY2, usLineColor, pDestBuf );
- UnLockVideoSurface( uiRenderBuffer );
- }
- if ( MercPtrs[ pFace->ubSoldierID ]->bInSector && ( ( ( gTacticalStatus.ubCurrentTeam != OUR_TEAM ) || !OK_INTERRUPT_MERC( MercPtrs[ pFace->ubSoldierID ] ) ) && !gfHiddenInterrupt ) || ( ( gfSMDisableForItems && !gfInItemPickupMenu ) && gusSMCurrentMerc == pFace->ubSoldierID && gsCurInterfacePanel == SM_PANEL ) )
- {
- // Blit hatch!
- BltVideoObjectFromIndex( uiRenderBuffer, guiHATCH, 0, sFaceX, sFaceY, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- if ( !pFace->fDisabled && !pFace->fInvalidAnim )
- {
- // Render text above here if that's what was asked for
- if ( pFace->fDisplayTextOver != FACE_NO_TEXT_OVER )
- {
- SetFont( TINYFONT1 );
- SetFontBackground( FONT_MCOLOR_BLACK );
- SetFontForeground( FONT_MCOLOR_WHITE );
- SetFontDestBuffer( uiRenderBuffer, 0, 0, 640, 480, FALSE );
- VarFindFontCenterCoordinates( sFaceX, sFaceY, pFace->usFaceWidth, pFace->usFaceHeight, TINYFONT1, &sFontX, &sFontY, pFace->zDisplayText );
- if ( pFace->fDisplayTextOver == FACE_DRAW_TEXT_OVER )
- {
- gprintfinvalidate( sFontX, sFontY, pFace->zDisplayText );
- mprintf( sFontX, sFontY, pFace->zDisplayText );
- }
- else if ( pFace->fDisplayTextOver == FACE_ERASE_TEXT_OVER )
- {
- gprintfRestore( sFontX, sFontY, pFace->zDisplayText );
- pFace->fDisplayTextOver = FACE_NO_TEXT_OVER;
- }
- SetFontDestBuffer( FRAME_BUFFER, 0, 0, 640, 480, FALSE );
- }
- }
- }
- // Check if a robot and is not controlled....
- if ( MercPtrs[ pFace->ubSoldierID ]->uiStatusFlags & SOLDIER_ROBOT )
- {
- if ( !CanRobotBeControlled( MercPtrs[ pFace->ubSoldierID ] ) )
- {
- // Not controlled robot
- sIconIndex = 5;
- fDoIcon = TRUE;
- }
- }
- if ( ControllingRobot( MercPtrs[ pFace->ubSoldierID ] ) )
- {
- // controlling robot
- sIconIndex = 4;
- fDoIcon = TRUE;
- }
- // If blind...
- if ( MercPtrs[ pFace->ubSoldierID ]->bBlindedCounter > 0 )
- {
- DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 6 );
- bNumRightIcons++;
- }
- if ( MercPtrs[ pFace->ubSoldierID ]->bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
- {
- DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 7 );
- bNumRightIcons++;
- }
- if ( GetDrunkLevel( MercPtrs[ pFace->ubSoldierID ] ) != SOBER )
- {
- DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 8 );
- bNumRightIcons++;
- }
- switch( pSoldier->bAssignment )
- {
- case DOCTOR:
- sIconIndex = 1;
- fDoIcon = TRUE;
- sPtsAvailable = CalculateHealingPointsForDoctor( MercPtrs[ pFace->ubSoldierID ], &usMaximumPts, FALSE );
- fShowNumber = TRUE;
- fShowMaximum = TRUE;
- // divide both amounts by 10 to make the displayed numbers a little more user-palatable (smaller)
- sPtsAvailable = ( sPtsAvailable + 5 ) / 10;
- usMaximumPts = ( usMaximumPts + 5 ) / 10;
- break;
- case PATIENT:
- sIconIndex = 2;
- fDoIcon = TRUE;
- // show current health / maximum health
- sPtsAvailable = MercPtrs[ pFace->ubSoldierID ]->bLife;
- usMaximumPts = MercPtrs[ pFace->ubSoldierID ]->bLifeMax;
- fShowNumber = TRUE;
- fShowMaximum = TRUE;
- break;
- case TRAIN_SELF:
- case TRAIN_TOWN:
- case TRAIN_TEAMMATE:
- case TRAIN_BY_OTHER:
- sIconIndex = 3;
- fDoIcon = TRUE;
- fShowNumber = TRUE;
- fShowMaximum = TRUE;
- // there could be bonus pts for training at gun range
- if ( ( MercPtrs[ pFace->ubSoldierID ]->sSectorX == 13) && (MercPtrs[ pFace->ubSoldierID ]->sSectorY == MAP_ROW_H) && (MercPtrs[ pFace->ubSoldierID ]->bSectorZ == 0) )
- {
- fAtGunRange = TRUE;
- }
- switch( MercPtrs[ pFace->ubSoldierID ]->bAssignment )
- {
- case( TRAIN_SELF ):
- sPtsAvailable = GetSoldierTrainingPts( MercPtrs[ pFace->ubSoldierID ], MercPtrs[ pFace->ubSoldierID ]->bTrainStat, fAtGunRange, &usMaximumPts );
- break;
- case( TRAIN_BY_OTHER ):
- sPtsAvailable = GetSoldierStudentPts( MercPtrs[ pFace->ubSoldierID ], MercPtrs[ pFace->ubSoldierID ]->bTrainStat, fAtGunRange, &usMaximumPts );
- break;
- case( TRAIN_TOWN ):
- sPtsAvailable = GetTownTrainPtsForCharacter( MercPtrs[ pFace->ubSoldierID ], &usMaximumPts );
- // divide both amounts by 10 to make the displayed numbers a little more user-palatable (smaller)
- sPtsAvailable = ( sPtsAvailable + 5 ) / 10;
- usMaximumPts = ( usMaximumPts + 5 ) / 10;
- break;
- case( TRAIN_TEAMMATE ):
- sPtsAvailable = GetBonusTrainingPtsDueToInstructor( MercPtrs[ pFace->ubSoldierID ], NULL , MercPtrs[ pFace->ubSoldierID ]->bTrainStat, fAtGunRange, &usMaximumPts );
- break;
- }
- break;
- case REPAIR:
- sIconIndex = 0;
- fDoIcon = TRUE;
- sPtsAvailable = CalculateRepairPointsForRepairman( MercPtrs[ pFace->ubSoldierID ], &usMaximumPts, FALSE );
- fShowNumber = TRUE;
- fShowMaximum = TRUE;
- // check if we are repairing a vehicle
- if ( Menptr[ pFace->ubSoldierID ].bVehicleUnderRepairID != -1 )
- {
- // reduce to a multiple of VEHICLE_REPAIR_POINTS_DIVISOR. This way skill too low will show up as 0 repair pts.
- sPtsAvailable -= ( sPtsAvailable % VEHICLE_REPAIR_POINTS_DIVISOR );
- usMaximumPts -= ( usMaximumPts % VEHICLE_REPAIR_POINTS_DIVISOR );
- }
- break;
- }
- // Check for being serviced...
- if ( MercPtrs[ pFace->ubSoldierID ]->ubServicePartner != NOBODY )
- {
- // Doctor...
- sIconIndex = 1;
- fDoIcon = TRUE;
- }
- if ( MercPtrs[ pFace->ubSoldierID ]->ubServiceCount != 0 )
- {
- // Patient
- sIconIndex = 2;
- fDoIcon = TRUE;
- }
-
- if ( fDoIcon )
- {
- // Find X, y for placement
- GetXYForIconPlacement( pFace, sIconIndex, sFaceX, sFaceY, &sIconX, &sIconY );
- BltVideoObjectFromIndex( uiRenderBuffer, guiPORTRAITICONS, sIconIndex, sIconX, sIconY, VO_BLT_SRCTRANSPARENCY, NULL );
- // ATE: Show numbers only in mapscreen
- if( fShowNumber )
- {
- SetFontDestBuffer( uiRenderBuffer, 0, 0, 640, 480, FALSE );
- if ( fShowMaximum )
- {
- swprintf( sString, L"%d/%d", sPtsAvailable, usMaximumPts );
- }
- else
- {
- swprintf( sString, L"%d", sPtsAvailable );
- }
- usTextWidth = StringPixLength( sString, FONT10ARIAL );
- usTextWidth += 1;
- SetFont( FONT10ARIAL );
- SetFontForeground( FONT_YELLOW );
- SetFontBackground( FONT_BLACK );
- mprintf( sFaceX + pFace->usFaceWidth - usTextWidth, ( INT16 )( sFaceY + 3 ), sString );
- SetFontDestBuffer( FRAME_BUFFER, 0, 0, 640, 480, FALSE );
- }
- }
- }
- else
- {
- if ( pFace->ubCharacterNum == FATHER || pFace->ubCharacterNum == MICKY )
- {
- if ( gMercProfiles[ pFace->ubCharacterNum ].bNPCData >= 5 )
- {
- DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, 0, 8 );
- }
- }
- }
- }
- BOOLEAN RenderAutoFace( INT32 iFaceIndex )
- {
- FACETYPE *pFace;
- // Check face index
- CHECKF( iFaceIndex != -1 );
- pFace = &gFacesData[ iFaceIndex ];
- // Check for a valid slot!
- CHECKF( pFace->fAllocated != FALSE );
- // Check for disabled guy!
- CHECKF( pFace->fDisabled != TRUE );
- // Set shade
- if ( pFace->ubSoldierID != NOBODY )
- {
- SetFaceShade( MercPtrs[ pFace->ubSoldierID ], pFace, FALSE );
- }
- // Blit face to save buffer!
- if ( pFace->uiAutoRestoreBuffer != FACE_NO_RESTORE_BUFFER )
- {
- if ( pFace->uiAutoRestoreBuffer == guiSAVEBUFFER )
- {
- BltVideoObjectFromIndex( pFace->uiAutoRestoreBuffer, pFace->uiVideoObject, 0, pFace->usFaceX, pFace->usFaceY, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- else
- {
- BltVideoObjectFromIndex( pFace->uiAutoRestoreBuffer, pFace->uiVideoObject, 0, 0, 0, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- }
- HandleRenderFaceAdjustments( pFace, FALSE, FALSE, 0, pFace->usFaceX, pFace->usFaceY, pFace->usEyesX, pFace->usEyesY );
- // Restore extern rect
- if ( pFace->uiAutoRestoreBuffer == guiSAVEBUFFER )
- {
- FaceRestoreSavedBackgroundRect( iFaceIndex, (INT16)( pFace->usFaceX ), (INT16)( pFace->usFaceY ), (INT16)( pFace->usFaceX ), (INT16)( pFace->usFaceY ), ( INT16)( pFace->usFaceWidth ), (INT16)( pFace->usFaceHeight ) );
- }
- else
- {
- FaceRestoreSavedBackgroundRect( iFaceIndex, pFace->usFaceX, pFace->usFaceY, 0, 0, pFace->usFaceWidth, pFace->usFaceHeight );
- }
- return( TRUE );
- }
- BOOLEAN ExternRenderFaceFromSoldier( UINT32 uiBuffer, UINT8 ubSoldierID, INT16 sX, INT16 sY )
- {
- // Check for valid soldier
- CHECKF( ubSoldierID != NOBODY );
- return( ExternRenderFace( uiBuffer, MercPtrs[ ubSoldierID ]->iFaceIndex, sX, sY ) );
- }
- BOOLEAN ExternRenderFace( UINT32 uiBuffer, INT32 iFaceIndex, INT16 sX, INT16 sY )
- {
- UINT16 usEyesX;
- UINT16 usEyesY;
- UINT16 usMouthX;
- UINT16 usMouthY;
- FACETYPE *pFace;
- // Check face index
- CHECKF( iFaceIndex != -1 );
- pFace = &gFacesData[ iFaceIndex ];
- // Check for a valid slot!
- CHECKF( pFace->fAllocated != FALSE );
- // Here, any face can be rendered, even if disabled
- // Set shade
- if ( pFace->ubSoldierID != NOBODY )
- {
- SetFaceShade( MercPtrs[ pFace->ubSoldierID ], pFace , TRUE );
- }
- // Blit face to save buffer!
- BltVideoObjectFromIndex( uiBuffer, pFace->uiVideoObject, 0, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL );
- GetFaceRelativeCoordinates( pFace, &usEyesX, &usEyesY, &usMouthX, &usMouthY );
- HandleRenderFaceAdjustments( pFace, FALSE, TRUE, uiBuffer, sX, sY, ( UINT16)( sX + usEyesX ), ( UINT16)( sY + usEyesY ) );
- // Restore extern rect
- if ( uiBuffer == guiSAVEBUFFER )
- {
- RestoreExternBackgroundRect( sX, sY, pFace->usFaceWidth, pFace->usFaceWidth );
- }
- return( TRUE );
- }
- void NewEye( FACETYPE *pFace )
- {
- switch(pFace->sEyeFrame)
- {
- case 0 : //pFace->sEyeFrame = (INT16)Random(2); // normal - can blink or frown
- if ( pFace->ubExpression == ANGRY )
- {
- pFace->ubEyeWait = 0;
- pFace->sEyeFrame = 3;
- }
- else if ( pFace->ubExpression == SURPRISED )
- {
- pFace->ubEyeWait = 0;
- pFace->sEyeFrame = 4;
- }
- else
- //if (pFace->sEyeFrame && Talk.talking && Talk.expression != DYING)
- /// pFace->sEyeFrame = 3;
- //else
- pFace->sEyeFrame = 1;
- break;
- case 1 : // starting to blink - has to finish unless dying
- //if (Talk.expression == DYING)
- // pFace->sEyeFrame = 1;
- //else
- pFace->sEyeFrame = 2;
- break;
- case 2 : //pFace->sEyeFrame = (INT16)Random(2); // finishing blink - can go normal or frown
- //if (pFace->sEyeFrame && Talk.talking)
- // pFace->sEyeFrame = 3;
- //else
- // if (Talk.expression == ANGRY)
- // pFace->sEyeFrame = 3;
- // else
- pFace->sEyeFrame = 0;
- break;
- case 3 : //pFace->sEyeFrame = 4; break; // frown
- pFace->ubEyeWait++;
- if ( pFace->ubEyeWait > 6 )
- {
- pFace->sEyeFrame = 0;
- }
- break;
- case 4 :
- pFace->ubEyeWait++;
- if ( pFace->ubEyeWait > 6 )
- {
- pFace->sEyeFrame = 0;
- }
- break;
- case 5 : pFace->sEyeFrame = 6;
- pFace->sEyeFrame = 0;
- break;
-
- case 6 : pFace->sEyeFrame = 7; break;
- case 7 : pFace->sEyeFrame = (INT16)Random(2); // can stop frowning or continue
- //if (pFace->sEyeFrame && Talk.expression != DYING)
- // pFace->sEyeFrame = 8;
- //else
- // pFace->sEyeFrame = 0;
- //break;
- case 8 : pFace->sEyeFrame = 9; break;
- case 9 : pFace->sEyeFrame = 10; break;
- case 10: pFace->sEyeFrame = 11; break;
- case 11: pFace->sEyeFrame = 12; break;
- case 12: pFace->sEyeFrame = 0; break;
- }
- }
- void NewMouth( FACETYPE *pFace )
- {
- BOOLEAN OK = FALSE;
- UINT16 sOld = pFace->sMouthFrame;
- // if (audio_gap_active == 1)
- // {
- // Talk.mouth = 0;
- // return;
- // }
- do
- {
- //Talk.mouth = random(4);
- pFace->sMouthFrame = (INT16)Random(6);
- if ( pFace->sMouthFrame > 3)
- {
- pFace->sMouthFrame = 0;
- }
- switch( sOld)
- {
- case 0 : if ( pFace->sMouthFrame != 0 )
- OK = TRUE;
- break;
- case 1 : if ( pFace->sMouthFrame != 1 )
- OK = TRUE;
- break;
- case 2 : if ( pFace->sMouthFrame != 2 )
- OK = TRUE;
- break;
- case 3 : if ( pFace->sMouthFrame != 3 )
- OK = TRUE;
- break;
- }
- } while (!OK);
- }
- void HandleAutoFaces( )
- {
- UINT32 uiCount;
- FACETYPE *pFace;
- INT8 bLife;
- INT8 bInSector;
- INT8 bAPs;
- BOOLEAN fRerender = FALSE;
- BOOLEAN fHandleFace;
- BOOLEAN fHandleUIHatch;
- SOLDIERTYPE *pSoldier;
- for ( uiCount = 0; uiCount < guiNumFaces; uiCount++ )
- {
- fRerender = FALSE;
- fHandleFace = TRUE;
- fHandleUIHatch = FALSE;
- // OK, NOW, check if our bLife status has changed, re-render if so!
- if ( gFacesData[ uiCount ].fAllocated )
- {
- pFace = &gFacesData[ uiCount ];
- // Are we a soldier?
- if ( pFace->ubSoldierID != NOBODY )
- {
- // Get Life now
- pSoldier = MercPtrs[ pFace->ubSoldierID ];
- bLife = pSoldier->bLife;
- bInSector = pSoldier->bInSector;
- bAPs = pSoldier->bActionPoints;
- if ( pSoldier->ubID == gsSelectedGuy && gfUIHandleSelectionAboveGuy )
- {
- pFace->uiFlags |= FACE_SHOW_WHITE_HILIGHT;
- }
- else
- {
- pFace->uiFlags &= ( ~FACE_SHOW_WHITE_HILIGHT );
- }
- if ( pSoldier->sGridNo != pSoldier->sFinalDestination && pSoldier->sGridNo != NOWHERE )
- {
- pFace->uiFlags |= FACE_SHOW_MOVING_HILIGHT;
- }
- else
- {
- pFace->uiFlags &= ( ~FACE_SHOW_MOVING_HILIGHT );
- }
- if ( pSoldier->bStealthMode != pFace->bOldStealthMode )
- {
- fRerender = TRUE;
- }
- // Check if we have fallen below OKLIFE...
- if ( bLife < OKLIFE && pFace->bOldSoldierLife >= OKLIFE )
- {
- fRerender = TRUE;
- }
- if ( bLife >= OKLIFE && pFace->bOldSoldierLife < OKLIFE )
- {
- fRerender = TRUE;
- }
- // Check if we have fallen below CONSCIOUSNESS
- if ( bLife < CONSCIOUSNESS && pFace->bOldSoldierLife >= CONSCIOUSNESS )
- {
- fRerender = TRUE;
- }
-
- if ( bLife >= CONSCIOUSNESS && pFace->bOldSoldierLife < CONSCIOUSNESS )
- {
- fRerender = TRUE;
- }
- if ( pSoldier->bOppCnt != pFace->bOldOppCnt )
- {
- fRerender = TRUE;
- }
- // Check if assignment is idfferent....
- if ( pSoldier->bAssignment != pFace->bOldAssignment )
- {
- pFace->bOldAssignment = pSoldier->bAssignment;
- fRerender = TRUE;
- }
- // Check if we have fallen below CONSCIOUSNESS
- if ( bAPs == 0 && pFace->bOldActionPoints > 0 )
- {
- fRerender = TRUE;
- }
-
- if ( bAPs > 0 && pFace->bOldActionPoints == 0 )
- {
- fRerender = TRUE;
- }
- if ( !( pFace->uiFlags & FACE_SHOW_WHITE_HILIGHT ) && pFace->fOldShowHighlight )
- {
- fRerender = TRUE;
- }
- if ( ( pFace->uiFlags & FACE_SHOW_WHITE_HILIGHT ) && !( pFace->fOldShowHighlight ) )
- {
- fRerender = TRUE;
- }
- if ( !( pFace->uiFlags & FACE_SHOW_MOVING_HILIGHT ) && pFace->fOldShowMoveHilight )
- {
- fRerender = TRUE;
- }
- if ( ( pFace->uiFlags & FACE_SHOW_MOVING_HILIGHT ) && !( pFace->fOldShowMoveHilight ) )
- {
- fRerender = TRUE;
- }
- if ( pFace->ubOldServiceCount != pSoldier->ubServiceCount )
- {
- fRerender = TRUE;
- pFace->ubOldServiceCount = pSoldier->ubServiceCount;
- }
- if ( pFace->fOldCompatibleItems != pFace->fCompatibleItems || gfInItemPickupMenu || gpItemPointer != NULL )
- {
- fRerender = TRUE;
- pFace->fOldCompatibleItems = pFace->fCompatibleItems;
- }
- if ( pFace->ubOldServicePartner != pSoldier->ubServicePartner )
- {
- fRerender = TRUE;
- pFace->ubOldServicePartner = pSoldier->ubServicePartner;
- }
- pFace->fOldHandleUIHatch = fHandleUIHatch;
- pFace->bOldSoldierLife = bLife;
- pFace->bOldActionPoints = bAPs;
- pFace->bOldStealthMode = pSoldier->bStealthMode;
- pFace->bOldOppCnt = pSoldier->bOppCnt;
- if ( pFace->uiFlags & FACE_SHOW_WHITE_HILIGHT )
- {
- pFace->fOldShowHighlight = TRUE;
- }
- else
- {
- pFace->fOldShowHighlight = FALSE;
- }
- if ( pFace->uiFlags & FACE_SHOW_MOVING_HILIGHT )
- {
- pFace->fOldShowMoveHilight = TRUE;
- }
- else
- {
- pFace->fOldShowMoveHilight = FALSE;
- }
- if ( pSoldier->fGettingHit && pSoldier->fFlashPortrait == FLASH_PORTRAIT_STOP )
- {
- pSoldier->fFlashPortrait = TRUE;
- pSoldier->bFlashPortraitFrame = FLASH_PORTRAIT_STARTSHADE;
- RESETTIMECOUNTER( pSoldier->PortraitFlashCounter, FLASH_PORTRAIT_DELAY );
- fRerender = TRUE;
- }
- if ( pSoldier->fFlashPortrait == FLASH_PORTRAIT_START )
- {
- // Loop through flash values
- if ( TIMECOUNTERDONE( pSoldier->PortraitFlashCounter, FLASH_PORTRAIT_DELAY ) )
- {
- RESETTIMECOUNTER( pSoldier->PortraitFlashCounter, FLASH_PORTRAIT_DELAY );
- pSoldier->bFlashPortraitFrame++;
- if ( pSoldier->bFlashPortraitFrame > FLASH_PORTRAIT_ENDSHADE )
- {
- pSoldier->bFlashPortraitFrame = FLASH_PORTRAIT_ENDSHADE;
- if ( pSoldier->fGettingHit )
- {
- pSoldier->fFlashPortrait = FLASH_PORTRAIT_WAITING;
- }
- else
- {
- // Render face again!
- pSoldier->fFlashPortrait = FLASH_PORTRAIT_STOP;
- }
- fRerender = TRUE;
- }
- }
- }
- // CHECK IF WE WERE WAITING FOR GETTING HIT TO FINISH!
- if ( !pSoldier->fGettingHit && pSoldier->fFlashPortrait == FLASH_PORTRAIT_WAITING )
- {
- pSoldier->fFlashPortrait = FALSE;
- fRerender = TRUE;
- }
- if ( pSoldier->fFlashPortrait == FLASH_PORTRAIT_START )
- {
- fRerender = TRUE;
- }
- if( pFace->uiFlags & FACE_REDRAW_WHOLE_FACE_NEXT_FRAME )
- {
- pFace->uiFlags &= ~FACE_REDRAW_WHOLE_FACE_NEXT_FRAME;
- fRerender = TRUE;
- }
- if ( fInterfacePanelDirty == DIRTYLEVEL2 && guiCurrentScreen == GAME_SCREEN )
- {
- fRerender = TRUE;
- }
- if ( fRerender )
- {
- RenderAutoFace( uiCount );
- }
- if ( bLife < CONSCIOUSNESS )
- {
- fHandleFace = FALSE;
- }
- }
- if ( fHandleFace )
- {
- BlinkAutoFace( uiCount );
- }
- MouthAutoFace( uiCount );
- }
- }
-
- }
- void HandleTalkingAutoFaces( )
- {
- UINT32 uiCount;
- FACETYPE *pFace;
- for ( uiCount = 0; uiCount < guiNumFaces; uiCount++ )
- {
- // OK, NOW, check if our bLife status has changed, re-render if so!
- if ( gFacesData[ uiCount ].fAllocated )
- {
- pFace = &gFacesData[ uiCount ];
- HandleTalkingAutoFace( uiCount );
- }
- }
- }
- BOOLEAN FaceRestoreSavedBackgroundRect( INT32 iFaceIndex, INT16 sDestLeft, INT16 sDestTop, INT16 sSrcLeft, INT16 sSrcTop, INT16 sWidth, INT16 sHeight )
- {
- FACETYPE *pFace;
- UINT32 uiDestPitchBYTES, uiSrcPitchBYTES;
- UINT8 *pDestBuf, *pSrcBuf;
- // Check face index
- CHECKF( iFaceIndex != -1 );
- pFace = &gFacesData[ iFaceIndex ];
- // DOn't continue if we do not want the resotre to happen ( ei blitting entrie thing every frame...
- if ( pFace->uiAutoRestoreBuffer == FACE_NO_RESTORE_BUFFER )
- {
- return( FALSE );
- }
- pDestBuf = LockVideoSurface(pFace->uiAutoDisplayBuffer, &uiDestPitchBYTES);
- pSrcBuf = LockVideoSurface( pFace->uiAutoRestoreBuffer, &uiSrcPitchBYTES);
- Blt16BPPTo16BPP((UINT16 *)pDestBuf, uiDestPitchBYTES,
- (UINT16 *)pSrcBuf, uiSrcPitchBYTES,
- sDestLeft , sDestTop,
- sSrcLeft , sSrcTop,
- sWidth, sHeight);
- UnLockVideoSurface(pFace->uiAutoDisplayBuffer);
- UnLockVideoSurface(pFace->uiAutoRestoreBuffer);
- // Add rect to frame buffer queue
- if ( pFace->uiAutoDisplayBuffer == FRAME_BUFFER )
- {
- InvalidateRegionEx( sDestLeft - 2, sDestTop - 2, (sDestLeft + sWidth + 3), ( sDestTop + sHeight + 2 ), 0 );
- }
- return(TRUE);
- }
- BOOLEAN SetFaceTalking( INT32 iFaceIndex, CHAR8 *zSoundFile, STR16 zTextString, UINT32 usRate, UINT32 ubVolume, UINT32 ubLoops, UINT32 uiPan )
- {
- FACETYPE *pFace;
-
- pFace = &gFacesData[ iFaceIndex ];
- // Set face to talking
- pFace->fTalking = TRUE;
- pFace->fAnimatingTalking = TRUE;
- pFace->fFinishTalking = FALSE;
- if ( !AreInMeanwhile( ) )
- {
- TurnOnSectorLocator( pFace->ubCharacterNum );
- }
- // Play sample
- if( gGameSettings.fOptions[ TOPTION_SPEECH ] )
- pFace->uiSoundID = PlayJA2GapSample( zSoundFile, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN, &(pFace->GapList ) );
- else
- pFace->uiSoundID = SOUND_ERROR;
- if ( pFace->uiSoundID != SOUND_ERROR )
- {
- pFace->fValidSpeech = TRUE;
-
- pFace->uiTalkingFromVeryBeginningTimer = GetJA2Clock( );
- }
- else
- {
- pFace->fValidSpeech = FALSE;
- // Set delay based on sound...
- pFace->uiTalkingTimer = pFace->uiTalkingFromVeryBeginningTimer = GetJA2Clock( );
- pFace->uiTalkingDuration = FindDelayForString( zTextString );
- }
- return( TRUE );
- }
- BOOLEAN ExternSetFaceTalking( INT32 iFaceIndex, UINT32 uiSoundID )
- {
- FACETYPE *pFace;
-
- pFace = &gFacesData[ iFaceIndex ];
- // Set face to talki ng
- pFace->fTalking = TRUE;
- pFace->fAnimatingTalking = TRUE;
- pFace->fFinishTalking = FALSE;
- pFace->fValidSpeech = TRUE;
- pFace->uiSoundID = uiSoundID;
- return( TRUE );
- }
- void InternalShutupaYoFace( INT32 iFaceIndex, BOOLEAN fForce )
- {
- FACETYPE *pFace;
- // Check face index
- CHECKV( iFaceIndex != -1 );
-
- pFace = &gFacesData[ iFaceIndex ];
- if ( pFace->fTalking )
- {
- // OK, only do this if we have been talking for a min. amount fo time...
- if ( ( GetJA2Clock( ) - pFace->uiTalkingFromVeryBeginningTimer ) < 500 && !fForce )
- {
- return;
- }
- if ( pFace->uiSoundID != SOUND_ERROR )
- {
- SoundStop( pFace->uiSoundID );
- }
- // Remove gap info
- AudioGapListDone( &(pFace->GapList) );
- // Shutup mouth!
- pFace->sMouthFrame = 0;
- // ATE: Only change if active!
- if ( !pFace->fDisabled )
- {
- if ( pFace->uiAutoRestoreBuffer == guiSAVEBUFFER )
- {
- FaceRestoreSavedBackgroundRect( iFaceIndex, pFace->usMouthX, pFace->usMouthY, pFace->usMouthX, pFace->usMouthY, pFace->usMouthWidth, pFace->usMouthHeight );
- }
- else
- {
- FaceRestoreSavedBackgroundRect( iFaceIndex, pFace->usMouthX, pFace->usMouthY, pFace->usMouthOffsetX, pFace->usMouthOffsetY, pFace->usMouthWidth, pFace->usMouthHeight );
- }
- }
- // OK, smart guy, make sure this guy has finished talking,
- // before attempting to end dialogue UI.
- pFace->fTalking = FALSE;
- // Call dialogue handler function
- HandleDialogueEnd( pFace );
- pFace->fTalking = FALSE;
- pFace->fAnimatingTalking = FALSE;
- gfUIWaitingForUserSpeechAdvance = FALSE;
- }
- }
- void ShutupaYoFace( INT32 iFaceIndex )
- {
- InternalShutupaYoFace( iFaceIndex, TRUE );
- }
- void SetupFinalTalkingDelay( FACETYPE *pFace )
- {
- pFace->fFinishTalking = TRUE;
- pFace->fAnimatingTalking = FALSE;
- pFace->uiTalkingTimer = GetJA2Clock( );
- if ( gGameSettings.fOptions[ TOPTION_SUBTITLES ] )
- {
- //pFace->uiTalkingDuration = FINAL_TALKING_DURATION;
- pFace->uiTalkingDuration = 300;
- }
- else
- {
- pFace->uiTalkingDuration = 300;
- }
- pFace->sMouthFrame = 0;
- // Close mouth!
- if ( !pFace->fDisabled )
- {
- if ( pFace->uiAutoRestoreBuffer == guiSAVEBUFFER )
- {
- FaceRestoreSavedBackgroundRect( pFace->iID, pFace->usMouthX, pFace->usMouthY, pFace->usMouthX, pFace->usMouthY, pFace->usMouthWidth, pFace->usMouthHeight );
- }
- else
- {
- FaceRestoreSavedBackgroundRect( pFace->iID, pFace->usMouthX, pFace->usMouthY, pFace->usMouthOffsetX, pFace->usMouthOffsetY, pFace->usMouthWidth, pFace->usMouthHeight );
- }
- }
- // Setup flag to wait for advance ( because we have no text! )
- if ( gGameSettings.fOptions[ TOPTION_KEY_ADVANCE_SPEECH ] && ( pFace->uiFlags & FACE_POTENTIAL_KEYWAIT ) )
- {
- // Check if we have had valid speech!
- if ( !pFace->fValidSpeech || gGameSettings.fOptions[ TOPTION_SUBTITLES ] )
- {
- // Set false!
- pFace->fFinishTalking = FALSE;
- // Set waiting for advance to true!
- gfUIWaitingForUserSpeechAdvance = TRUE;
- }
- }
- // Set final delay!
- pFace->fValidSpeech = FALSE;
- }
|