123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663 |
- #define LOADSCREEN_CPP
- /*************************************************************************************************\
- LoadScreen.cpp : Implementation of the LoadScreen component.
- //---------------------------------------------------------------------------//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- \*************************************************************************************************/
- #include <windows.h>
- #include <ddraw.h>
- #include "LoadScreen.h"
- #include "aAnimObject.h"
- #include "tgaInfo.h"
- #include "mclib.h"
- #include "Prefs.h"
- #include "multplyr.h"
- #include "mission.h"
- #include "gameSound.h"
- float loadProgress = 0.0f;
- long LoadScreen::xProgressLoc = 0;
- long LoadScreen::yProgressLoc = 0;
- long LoadScreen::xWaitLoc = 0;
- long LoadScreen::yWaitLoc = 0;
- bool LoadScreen::turnOffAsyncMouse = false;
- TGAFileHeader* LoadScreen::progressTextureMemory = 0;
- TGAFileHeader* LoadScreen::progressBackground = 0;
- TGAFileHeader* LoadScreen::mergedTexture = 0;
- TGAFileHeader* LoadScreen::waitingForPlayersMemory = 0;
- LoadScreen* LoadScreenWrapper::enterScreen = NULL;
- LoadScreen* LoadScreenWrapper::exitScreen = NULL;
- extern volatile bool mc2IsInMouseTimer;
- extern volatile bool mc2IsInDisplayBackBuffer;
- extern void (*AsynFunc)(RECT& WinRect,DDSURFACEDESC2& mouseSurfaceDesc );
- extern CPrefs prefs;
- //
- // Returns the number of bits in a given mask. Used to determine if we are in 555 mode vs 565 mode.
- WORD GetNumberOfBits( DWORD dwMask );
- void MouseTimerInit();
- void MouseTimerKill();
- LoadScreenWrapper::LoadScreenWrapper()
- {
- //How about, for shits and giggles we toss the static members we created for single player when this inits for multiplayer
- // or any other player!!!!
- if ( enterScreen )
- delete enterScreen;
- if ( exitScreen )
- delete exitScreen;
- enterScreen = exitScreen = NULL;
- enterScreen = new LoadScreen;
- exitScreen = new LoadScreen;
- bFirstTime = 0;
- }
- LoadScreenWrapper::~LoadScreenWrapper()
- {
- if ( enterScreen )
- delete enterScreen;
- if ( exitScreen )
- delete exitScreen;
- enterScreen = exitScreen = NULL;
- }
- void LoadScreenWrapper::init( FitIniFile& file )
- {
- enterScreen->init( file );
- // changeRes();
- bFirstTime = 0;
- }
- void LoadScreenWrapper::changeRes()
- {
- const char* Appendix = NULL;
- switch( prefs.resolution )
- {
- case 0:
- Appendix = "_640";
- break;
- case 1:
- break;
- case 2:
- Appendix = "_1024";
- break;
- case 3:
- Appendix = "_1280";
- break;
- case 4:
- Appendix = "_1600";
- break;
- default:
- Assert( 0, 0, "Unexpected resolution found in prefs" );
- break;
- }
- char fileName[256];
- sprintf( fileName, "mcl_loadingscreen" );
- if ( Appendix )
- strcat( fileName, Appendix );
- FullPathFileName path;
- path.init( artPath, fileName, ".fit" );
- FitIniFile outFile;
- if ( NO_ERR != outFile.open( path ) )
- {
- char error[256];
- sprintf( error, "couldn't open file %s", path );
- Assert( 0, 0, error );
- return;
- }
- //The 0x2 means that we do NOT want to flush this texture when we toss
- // the texture cache before a mission. BUT we DO want the texture to cache out
- // to make more room for stuff.
- exitScreen->init( outFile, 0x2 );
- exitScreen->setupOutAnims();
- LoadScreen::changeRes( outFile );
- }
- void LoadScreen::changeRes( FitIniFile& outFile )
- {
- if ( progressBackground )
- delete [] progressBackground;
- progressBackground = NULL;
- if ( waitingForPlayersMemory )
- delete [] waitingForPlayersMemory;
- waitingForPlayersMemory = NULL;
- if ( !progressBackground )
- {
- char progressPath[256];
- char progressBackgroundPath[256];
- long result = outFile.seekBlock( "LoadingBar" );
- gosASSERT( result == NO_ERR );
- outFile.readIdLong( "XLocation", xProgressLoc );
- outFile.readIdLong( "YLocation", yProgressLoc );
- outFile.readIdString( "FileName", progressPath, 255 );
- outFile.readIdString( "BackgroundFileName", progressBackgroundPath, 255);
- File tgaFile;
- FullPathFileName path;
- path.init( artPath, progressBackgroundPath, ".tga" );
- if ( NO_ERR != tgaFile.open( path ) )
- {
- char error[256];
- sprintf( error, "couldn't open file %s", path );
- Assert( 0, 0, error );
- return;
- }
- long size = tgaFile.fileSize();
-
- progressBackground = (TGAFileHeader*)new char[size];
- tgaFile.read( (unsigned char*)progressBackground, tgaFile.fileSize() );
- tgaFile.close();
- path.init( artPath, progressPath, ".tga" );
- if ( NO_ERR != tgaFile.open( path ) )
- {
- char error[256];
- sprintf( error, "couldn't open file %s", path );
- Assert( 0, 0, error );
- return;
- }
- size = tgaFile.fileSize();
- progressTextureMemory = (TGAFileHeader*)new char[size];
- tgaFile.read( (unsigned char*)progressTextureMemory, tgaFile.fileSize() );
- mergedTexture = (TGAFileHeader*)new char[size];
- memcpy( mergedTexture, progressTextureMemory, size );
- tgaFile.close();
- result = outFile.seekBlock( "WaitImage" );
- gosASSERT( result == NO_ERR );
- outFile.readIdString( "FileName", progressPath, 255 );
- outFile.readIdLong( "XLocation", xWaitLoc );
- outFile.readIdLong( "YLocation", yWaitLoc );
- path.init( artPath, progressPath, ".tga" );
- if ( NO_ERR != tgaFile.open( path ) )
- {
- char error[256];
- sprintf( error, "couldn't open file %s", path );
- Assert( 0, 0, error );
- return;
- }
- size = tgaFile.fileSize();
- waitingForPlayersMemory = (TGAFileHeader*)new char[size];
- tgaFile.read( (unsigned char*)waitingForPlayersMemory, tgaFile.fileSize() );
- flipTopToBottom( (BYTE*)(waitingForPlayersMemory + 1), waitingForPlayersMemory->pixel_depth,
- waitingForPlayersMemory->width, waitingForPlayersMemory->height );
- }
- }
- void LoadScreenWrapper::begin()
- {
- waitForResChange = 0;
- bFirstTime = true;
- enterScreen->begin();
- }
- void LoadScreenWrapper::update()
- {
- if ( loadProgress > 99 )
- soundSystem->playDigitalSample( LOAD_DOORS_OPENING );
- else if ( bFirstTime )
- soundSystem->playDigitalSample( LOAD_DOORS_CLOSING );
- bFirstTime = 0;
- if ( waitForResChange ) // waiting one more render to force
- {
- status = READYTOLOAD;
- waitForResChange = 0;
- }
- else
- {
- if ( Environment.screenWidth == 800 )
- {
- enterScreen->update();
- status = enterScreen->getStatus();
- if ( status == READYTOLOAD )
- {
- waitForResChange = 1;
- changeRes();
- status = RUNNING;
- }
- }
- else
- {
- exitScreen->update();
- status = exitScreen->getStatus();
- }
- }
- }
- void LoadScreenWrapper::render( int xOffset, int yOffset )
- {
- if ( Environment.screenWidth == 800 )
- {
- enterScreen->render( xOffset, yOffset );
- }
- else
- exitScreen->render( xOffset, yOffset );
- }
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- LoadScreen::LoadScreen( )
- {
- progressBackground = 0;
- progressTextureMemory = 0;
- animIndices = 0;
- }
- //-------------------------------------------------------------------------------------------------
- LoadScreen::~LoadScreen()
- {
- if ( progressBackground )
- delete [] progressBackground;
- if ( progressTextureMemory )
- delete [] progressTextureMemory;
- if ( mergedTexture )
- delete [] mergedTexture;
- if ( animIndices )
- delete [] animIndices;
- if ( waitingForPlayersMemory)
- delete [] waitingForPlayersMemory;
- animIndices = NULL;
- waitingForPlayersMemory = progressBackground = progressTextureMemory = mergedTexture = NULL;
- }
- void LoadScreen::begin()
- {
- for ( int i = 0; i < animObjectsCount; i++ )
- {
- //The assign below will overwrite the assign in defaultConstructor, leaking the memory
- animObjects[i].animInfo.destroy();
- animObjects[i].animInfo = inAnims[animIndices[i]];
- animObjects[i].animInfo.begin();
- animObjects[i].update();
- }
- loadProgress = 0;
- //-----------------------------------------------
- //Turn the mouse cursor OFF until load is done.
- // This will be keep ghost images from occuring.
- userInput->mouseOff();
- }
- void LoadScreen::init(FitIniFile& file, DWORD neverFlush)
- {
- LogisticsScreen::init( file, "Static", "Text", "Rect", "Button", "Edit", "AnimObject", neverFlush );
- file.seekBlock( "AnimationTopOut" );
- outAnims[0].init( &file, "" );
- file.seekBlock( "AnimationBottomOut" );
- outAnims[1].init( &file, "" );
- file.seekBlock( "AnimationLeftOut" );
- outAnims[2].init( &file, "" );
- file.seekBlock( "AnimationRightOut" );
- outAnims[3].init( &file, "" );
- file.seekBlock( "AnimationTopIn" );
- inAnims[0].init( &file, "" );
- file.seekBlock( "AnimationBottomIn" );
- inAnims[1].init( &file, "" );
- file.seekBlock( "AnimationLeftIn" );
- inAnims[2].init( &file, "" );
- file.seekBlock( "AnimationRightIn" );
- inAnims[3].init( &file, "" );
- file.seekBlock( "AnimationTop2In" );
- inAnims[4].init( &file, "" );
- file.seekBlock( "AnimationTop2Out" );
- outAnims[4].init( &file, "" );
- text.init( &file, "AnimObject18" );
-
- if ( animObjectsCount )
- {
- char blockName[256];
- animIndices = new int[animObjectsCount];
- for ( int i= 0; i < animObjectsCount; i++ )
- {
- sprintf( blockName, "AnimObject%ld", i );
- file.seekBlock( blockName );
- file.readIdString( "AnimationOut", blockName, 255 );
- if ( strstr( blockName, "2" ) )
- animIndices[i] = 4;
- else if ( strstr( blockName, "Top" ) )
- animIndices[i] = 0;
- else if ( strstr( blockName, "Bottom" ) )
- animIndices[i] = 1;
- else if ( strstr( blockName, "Left" ) )
- animIndices[i] = 2;
- else
- animIndices[i] = 3;
- }
- }
- }
- void LoadScreen::update()
- {
- status = RUNNING;
- LogisticsScreen::update();
- bool bDone = true;
- for ( int i = 0; i < animObjectsCount; i++ )
- {
- bDone &= animObjects[i].isDone();
- }
- if ( bDone )
- {
- if ( loadProgress < 99.f )
- {
- for ( int i = 0; i < animObjectsCount; i++ )
- {
- //The assign below will overwrite the assign in begin, leaking the memory
- animObjects[i].animInfo.destroy();
- animObjects[i].animInfo = outAnims[animIndices[i]];
- animObjects[i].begin();
- animObjects[i].update();
- }
- status = READYTOLOAD;
- prefs.applyPrefs( true );
- turnOffAsyncMouse = mc2UseAsyncMouse;
- if ( !mc2UseAsyncMouse )
- MouseTimerInit();
- mc2UseAsyncMouse = true;
- AsynFunc = ProgressTimer;
- }
- else
- {
- loadProgress = 0;
- status = NEXT;
- //YIKES!! We could be checking the if before the null and executing after!! Block the thread!
- //Wait for thread to finish.
- while (mc2IsInMouseTimer)
- ;
- //ONLY set the mouse BLT data at the end of each update. NO MORE FLICKERING THEN!!!
- // BLOCK THREAD WHILE THIS IS HAPPENING
- mc2IsInDisplayBackBuffer = true;
- AsynFunc = NULL;
- mc2UseAsyncMouse = turnOffAsyncMouse;
- if ( !mc2UseAsyncMouse)
- MouseTimerKill();
- mc2IsInDisplayBackBuffer = false;
- //Force mouse Cursors to smaller or larger depending on new video mode.
- userInput->initMouseCursors("cursors");
- userInput->mouseOn();
- }
- }
- else
- {
- userInput->mouseOff();
- }
- }
- void LoadScreen::render( int x, int y )
- {
- //ignoring animation information...
- LogisticsScreen::render();
- int curX = animObjects[0].animInfo.getXDelta();
- int curY = animObjects[0].animInfo.getYDelta();
- text.move( x + curX, y + curY );
- text.render( );
- text.move( -x - curX, -y - curY);
- }
- void ProgressTimer( RECT& WinRect,DDSURFACEDESC2& mouseSurfaceDesc )
- {
- if ( !LoadScreen::progressBackground )
- return;
- long destX = 0;
- long destY = 0;
- BYTE* pMem = (BYTE*)(LoadScreen::mergedTexture + 1);
- long destRight = 0;
- long destBottom = 0;
- long srcWidth = 0;
- long srcDepth = 0;
- if ( loadProgress > 0 && loadProgress < 100 )
- {
- destX = 0;
- destY = 0;
- long destWidth = LoadScreen::progressBackground->width;
- long destHeight = LoadScreen::progressBackground->height;
- float widthIncPerProgress = (float)destWidth * 0.01f;
- long* pLSrc = (long*)(LoadScreen::progressBackground+1);
- long* pLDest = (long*)(LoadScreen::mergedTexture+1);
- // merge background and current progress together...
- for ( int i = 0; i < 2; i++ )
- {
- for ( int y = 0; y < destHeight; y++ )
- {
- for ( long x = 0; x < LoadScreen::progressBackground->width; x++ )
- {
- if ( x < destWidth )
- *pLDest++ = *pLSrc++;
- else
- {
- pLDest++;
- pLSrc++;
- }
- }
- }
- pLSrc = (long*)( LoadScreen::progressTextureMemory + 1 );
- pLDest = (long*)(LoadScreen::mergedTexture+1);
- destWidth = loadProgress * widthIncPerProgress;
- }
- destX = WinRect.left + (LoadScreen::xProgressLoc);
- destY = WinRect.top + (LoadScreen::yProgressLoc);
- pMem = (BYTE*)(LoadScreen::mergedTexture + 1);
- destRight = destX + LoadScreen::progressBackground->width;
- destBottom = (destY + LoadScreen::progressBackground->height);
- srcWidth = LoadScreen::progressBackground->width;
- srcDepth = LoadScreen::progressBackground->pixel_depth/8;
- }
- else if ( loadProgress == 1000 )
- {
- destX = WinRect.left + LoadScreen::xWaitLoc;
- destY = WinRect.top + LoadScreen::yWaitLoc;
- pMem = (BYTE*)(LoadScreen::waitingForPlayersMemory + 1);
- destRight = destX + LoadScreen::waitingForPlayersMemory->width;
- destBottom = (destY + LoadScreen::waitingForPlayersMemory->height);
- destRight = destRight > WinRect.right ? WinRect.right : destRight;
- destBottom = destBottom > WinRect.bottom ? WinRect.top : destBottom;
- srcWidth = LoadScreen::waitingForPlayersMemory->width;
- srcDepth = LoadScreen::waitingForPlayersMemory->pixel_depth/8;
- }
- else
- return;
- // now put it on the screen...
- long destWidth = destRight - destX;
- long destHeight = destBottom - destY;
- for ( int y = 0; y < destHeight; y++ )
- {
- BYTE* pSrc = pMem + y * srcWidth * srcDepth;
- BYTE* pDest = (MemoryPtr)mouseSurfaceDesc.lpSurface + destX * mouseSurfaceDesc.ddpfPixelFormat.dwRGBBitCount/8 +
- ((destY + y) * mouseSurfaceDesc.lPitch);
- for ( long x = 0; x < destWidth; x++ )
- {
- DWORD mColor = *(long*)pSrc;
- BYTE baseAlpha = 0;
- BYTE baseColorRed = (mColor & 0x00ff0000)>>16;
- BYTE baseColorGreen = (mColor & 0x0000ff00)>>8;
- BYTE baseColorBlue = (mColor & 0x000000ff);
- pSrc += 4;
- if ( mouseSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 32 )
- {
- (*(long*)pDest) = mColor;
- pDest += 4;
- }
- else if ( mouseSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 24 )
- {
-
- if ( !baseAlpha )
- {
- pDest++;
- pDest++;
- pDest++;
- }
- *pDest++ = baseColorRed;
- *pDest++ = baseColorGreen;
- *pDest++ = baseColorBlue;
- }
- else if ( mouseSurfaceDesc.ddpfPixelFormat.dwRGBBitCount == 16 )
- {
- bool in555Mode = false;
- if (GetNumberOfBits(mouseSurfaceDesc.ddpfPixelFormat.dwGBitMask) == 5)
- in555Mode = true;
- if ( !baseAlpha )
- {
- long clr;
- if (in555Mode)
- {
- clr = (baseColorRed >> 3) << 10;
- clr += (baseColorGreen >> 3) << 5;
- clr += (baseColorBlue >> 3);
- }
- else
- {
- clr = (baseColorRed >> 3) << 11;
- clr += (baseColorGreen >> 2) << 5;
- clr += (baseColorBlue >> 3);
- }
-
- *pDest++ = clr & 0xff;
- *pDest++ = clr >> 8;
- }
- else
- {
- pDest++;
- pDest++;
- }
- }
- }
- }
- }
- void LoadScreen::setupOutAnims()
- {
- for ( int i = 0; i < animObjectsCount; i++ )
- {
- //The assign below will overwrite the assign in begin, leaking the memory
- animObjects[i].animInfo.destroy();
- animObjects[i].animInfo = outAnims[animIndices[i]];
- animObjects[i].begin();
- animObjects[i].update();
- }
- }
- //*************************************************************************************************
- // end of file ( LoadScreen.cpp )
|