/* ** Command & Conquer Generals Zero Hour(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program 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 3 of the License, or ** (at your option) any later version. ** ** This program 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 this program. If not, see . */ //////////////////////////////////////////////////////////////////////////////// // // // (c) 2001-2003 Electronic Arts Inc. // // // //////////////////////////////////////////////////////////////////////////////// // FILE: W3DMainMenu.cpp ///////////////////////////////////////////////// //----------------------------------------------------------------------------- // // Electronic Arts Pacific. // // Confidential Information // Copyright (C) 2002 - All Rights Reserved // //----------------------------------------------------------------------------- // // created: Apr 2002 // // Filename: W3DMainMenu.cpp // // author: Chris Huybregts // // purpose: The Draw Routine for the main menu // //----------------------------------------------------------------------------- /////////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- // SYSTEM INCLUDES //////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- #define WIN32_LEAN_AND_MEAN #include #include #include //----------------------------------------------------------------------------- // USER INCLUDES ////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- #include "GameClient/GameWindow.h" #include "Lib/BaseType.h" #include "W3DDevice/GameClient/W3DGameWindow.h" #include "GameClient/Display.h" #include "GameLogic/GameLogic.h" #include "GameClient/Shell.h" #include "GameClient/ShellMenuScheme.h" #include "GameClient/Credits.h" #include "GameClient/Gadget.h" #include "GameClient/GameWindowGlobal.h" #include "GameClient/GameWindowManager.h" #include "GameClient/GadgetPushButton.h" #include "W3DDevice/GameClient/W3DDisplay.h" #include "W3DDevice/GameClient/W3DGadget.h" #include "GameClient/GUICallbacks.h" //----------------------------------------------------------------------------- // DEFINES //////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- void drawText( GameWindow *window, WinInstanceData *instData ); static Color BrownishColor = GameMakeColor(167,134,94,255); static IRegion2D clipRegion; //----------------------------------------------------------------------------- // PUBLIC FUNCTIONS /////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // PRIVATE FUNCTIONS ////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- static void advancePosition(GameWindow *window, const Image *image, UnsignedInt posX, UnsignedInt posY, UnsignedInt sizeX, UnsignedInt sizeY) { if(!image) return; static Bool goingForward = TRUE; ICoord2D pos, size; if(!window) { pos.x = posX; pos.y = posY; size.x = sizeX; size.y = sizeY; } else { window->winGetScreenPosition(&pos.x, &pos.y); window->winGetSize(&size.x,&size.y); } static Int Width = size.x + image->getImageWidth(); static Int x = -800; static Int y = pos.y - (image->getImageHeight()/2); static UnsignedInt m_startTime = timeGetTime(); Int time = timeGetTime() - m_startTime; Real percentDone = INT_TO_REAL(time) / 10000; if(goingForward) { if(percentDone >= 1) { y = pos.y + size.y - (image->getImageHeight()/2); m_startTime = timeGetTime(); goingForward = FALSE; } else { y = pos.y - (image->getImageHeight()/2); x = (percentDone * Width) - image->getImageWidth(); } } else { if(percentDone >= 1) { y = pos.y - (image->getImageHeight()/2); m_startTime = timeGetTime(); goingForward = TRUE; } else { y = pos.y + size.y - (image->getImageHeight()/2); x = size.x - (percentDone * Width); } } TheDisplay->drawImage(image,x, y, x + image->getImageWidth(), y + image->getImageHeight()); } void W3DShellMenuSchemeDraw( GameWindow *window, WinInstanceData *instData ) { if(TheShell && TheShell->isShellActive()) TheShell->getShellMenuSchemeManager()->draw(); } void W3DMainMenuDraw( GameWindow *window, WinInstanceData *instData ) { //W3DGameWinDefaultDraw( window, instData ); //R:83 G:78 B:52 static UnsignedInt color = BrownishColor; static UnsignedInt colorDrop = GameMakeColor(38,30,21,255); ICoord2D pos, size; Int height = TheDisplay->getHeight(); window->winGetScreenPosition(&pos.x, &pos.y); window->winGetSize(&size.x,&size.y); IRegion2D topHorizontal1 ={pos.x, pos.y, pos.x + size.x, pos.y }; IRegion2D topHorizontal1drop ={pos.x, pos.y+1, pos.x + size.x, pos.y+1 }; IRegion2D topHorizontal2 ={pos.x, pos.y + (size.y * .1) , pos.x + size.x, pos.y + (size.y * .1) }; IRegion2D topHorizontal2drop ={pos.x, pos.y + (size.y * .12) , pos.x + size.x, pos.y + (size.y * .12) }; IRegion2D bottomHorizontal1={pos.x, pos.y + (size.y * .9), pos.x + size.x, pos.y + (size.y * .9) }; IRegion2D bottomHorizontal1drop={pos.x, pos.y + (size.y * .92), pos.x + size.x, pos.y + (size.y * .92) }; IRegion2D bottomHorizontal2= {pos.x, pos.y + size.y, pos.x + size.x, pos.y + size.y }; IRegion2D bottomHorizontal2drop= {pos.x, pos.y + size.y + 1, pos.x + size.x, pos.y + size.y + 1 }; IRegion2D verticle1 ={pos.x + (size.x * .225), pos.y , pos.x + (size.x * .225), height }; IRegion2D verticle2 ={pos.x + (size.x * .445), pos.y, pos.x + (size.x * .445), height }; IRegion2D verticle3 ={pos.x + (size.x * .6662), pos.y, pos.x + (size.x * .6662), height }; IRegion2D verticle4 ={pos.x + (size.x * .885), pos.y , pos.x + (size.x * .885), height }; // static IRegion2D verticle5 ={pos.x + (size.x * .7250), pos.y + (size.y * .12), pos.x + (size.x * .7250), pos.y + (size.y * .86) }; // static IRegion2D verticle6 ={pos.x + (size.x * .9062), pos.y + (size.y * .12), pos.x + (size.x * .9062), pos.y + (size.y * .86) }; TheDisplay->drawLine(topHorizontal1.lo.x,topHorizontal1.lo.y,topHorizontal1.hi.x,topHorizontal1.hi.y,2,color); TheDisplay->drawLine(topHorizontal1drop.lo.x,topHorizontal1drop.lo.y,topHorizontal1drop.hi.x,topHorizontal1drop.hi.y,2,colorDrop); TheDisplay->drawLine(topHorizontal2.lo.x,topHorizontal2.lo.y,topHorizontal2.hi.x,topHorizontal2.hi.y,1,color); TheDisplay->drawLine(topHorizontal2drop.lo.x,topHorizontal2drop.lo.y,topHorizontal2drop.hi.x,topHorizontal2drop.hi.y,1,colorDrop); TheDisplay->drawLine(bottomHorizontal1.lo.x,bottomHorizontal1.lo.y,bottomHorizontal1.hi.x,bottomHorizontal1.hi.y,1,color); TheDisplay->drawLine(bottomHorizontal1drop.lo.x,bottomHorizontal1drop.lo.y,bottomHorizontal1drop.hi.x,bottomHorizontal1drop.hi.y,1,colorDrop); TheDisplay->drawLine(bottomHorizontal2.lo.x,bottomHorizontal2.lo.y,bottomHorizontal2.hi.x,bottomHorizontal2.hi.y,2,color); TheDisplay->drawLine(bottomHorizontal2drop.lo.x,bottomHorizontal2drop.lo.y,bottomHorizontal2drop.hi.x,bottomHorizontal2drop.hi.y,2,colorDrop); TheDisplay->drawLine(verticle1.lo.x,verticle1.lo.y,verticle1.hi.x,verticle1.hi.y,3,color); TheDisplay->drawLine(verticle2.lo.x,verticle2.lo.y,verticle2.hi.x,verticle2.hi.y,3,color); TheDisplay->drawLine(verticle3.lo.x,verticle3.lo.y,verticle3.hi.x,verticle3.hi.y,3,color); TheDisplay->drawLine(verticle4.lo.x,verticle4.lo.y,verticle4.hi.x,verticle4.hi.y,3,color); // TheDisplay->drawLine(verticle5.lo.x,verticle5.lo.y,verticle5.hi.x,verticle5.hi.y,3,color); // TheDisplay->drawLine(verticle6.lo.x,verticle6.lo.y,verticle6.hi.x,verticle6.hi.y,3,color); // TheDisplay->drawLine(m_rightLineFromButton.lo.x,m_rightLineFromButton.lo.y,m_rightLineFromButton.hi.x,m_rightLineFromButton.hi.y,3,color1,color2); advancePosition(NULL, TheMappedImageCollection->findImageByName("MainMenuPulse"),pos.x,pos.y,size.x, size.y); //TheDisplay->drawLine(); } void W3DMainMenuFourDraw( GameWindow *window, WinInstanceData *instData ) { //W3DGameWinDefaultDraw( window, instData ); //R:83 G:78 B:52 static UnsignedInt color = BrownishColor; static UnsignedInt colorDrop = GameMakeColor(38,30,21,255); ICoord2D pos, size; Int height = TheDisplay->getHeight(); window->winGetScreenPosition(&pos.x, &pos.y); window->winGetSize(&size.x,&size.y); IRegion2D topHorizontal1 ={pos.x, pos.y, pos.x + size.x, pos.y }; IRegion2D topHorizontal1drop ={pos.x, pos.y+1, pos.x + size.x, pos.y+1 }; IRegion2D topHorizontal2 ={pos.x, pos.y + (size.y * .1) , pos.x + size.x, pos.y + (size.y * .1) }; IRegion2D topHorizontal2drop ={pos.x, pos.y + (size.y * .12) , pos.x + size.x, pos.y + (size.y * .12) }; IRegion2D bottomHorizontal1={pos.x, pos.y + (size.y * .9), pos.x + size.x, pos.y + (size.y * .9) }; IRegion2D bottomHorizontal1drop={pos.x, pos.y + (size.y * .92), pos.x + size.x, pos.y + (size.y * .92) }; IRegion2D bottomHorizontal2= {pos.x, pos.y + size.y, pos.x + size.x, pos.y + size.y }; IRegion2D bottomHorizontal2drop= {pos.x, pos.y + size.y + 1, pos.x + size.x, pos.y + size.y + 1 }; IRegion2D verticle1 ={pos.x + (size.x * .295), pos.y , pos.x + (size.x * .295), height }; IRegion2D verticle2 ={pos.x + (size.x * .59), pos.y, pos.x + (size.x * .59), height }; //IRegion2D verticle3 ={pos.x + (size.x * .6662), pos.y, pos.x + (size.x * .6662), height }; IRegion2D verticle4 ={pos.x + (size.x * .885), pos.y , pos.x + (size.x * .885), height }; // static IRegion2D verticle5 ={pos.x + (size.x * .7250), pos.y + (size.y * .12), pos.x + (size.x * .7250), pos.y + (size.y * .86) }; // static IRegion2D verticle6 ={pos.x + (size.x * .9062), pos.y + (size.y * .12), pos.x + (size.x * .9062), pos.y + (size.y * .86) }; TheDisplay->drawLine(topHorizontal1.lo.x,topHorizontal1.lo.y,topHorizontal1.hi.x,topHorizontal1.hi.y,2,color); TheDisplay->drawLine(topHorizontal1drop.lo.x,topHorizontal1drop.lo.y,topHorizontal1drop.hi.x,topHorizontal1drop.hi.y,2,colorDrop); TheDisplay->drawLine(topHorizontal2.lo.x,topHorizontal2.lo.y,topHorizontal2.hi.x,topHorizontal2.hi.y,1,color); TheDisplay->drawLine(topHorizontal2drop.lo.x,topHorizontal2drop.lo.y,topHorizontal2drop.hi.x,topHorizontal2drop.hi.y,1,colorDrop); TheDisplay->drawLine(bottomHorizontal1.lo.x,bottomHorizontal1.lo.y,bottomHorizontal1.hi.x,bottomHorizontal1.hi.y,1,color); TheDisplay->drawLine(bottomHorizontal1drop.lo.x,bottomHorizontal1drop.lo.y,bottomHorizontal1drop.hi.x,bottomHorizontal1drop.hi.y,1,colorDrop); TheDisplay->drawLine(bottomHorizontal2.lo.x,bottomHorizontal2.lo.y,bottomHorizontal2.hi.x,bottomHorizontal2.hi.y,2,color); TheDisplay->drawLine(bottomHorizontal2drop.lo.x,bottomHorizontal2drop.lo.y,bottomHorizontal2drop.hi.x,bottomHorizontal2drop.hi.y,2,colorDrop); TheDisplay->drawLine(verticle1.lo.x,verticle1.lo.y,verticle1.hi.x,verticle1.hi.y,3,color); TheDisplay->drawLine(verticle2.lo.x,verticle2.lo.y,verticle2.hi.x,verticle2.hi.y,3,color); //TheDisplay->drawLine(verticle3.lo.x,verticle3.lo.y,verticle3.hi.x,verticle3.hi.y,3,color); TheDisplay->drawLine(verticle4.lo.x,verticle4.lo.y,verticle4.hi.x,verticle4.hi.y,3,color); // TheDisplay->drawLine(verticle5.lo.x,verticle5.lo.y,verticle5.hi.x,verticle5.hi.y,3,color); // TheDisplay->drawLine(verticle6.lo.x,verticle6.lo.y,verticle6.hi.x,verticle6.hi.y,3,color); // TheDisplay->drawLine(m_rightLineFromButton.lo.x,m_rightLineFromButton.lo.y,m_rightLineFromButton.hi.x,m_rightLineFromButton.hi.y,3,color1,color2); advancePosition(NULL, TheMappedImageCollection->findImageByName("MainMenuPulse"),pos.x,pos.y,size.x, size.y); //TheDisplay->drawLine(); } void W3DMetalBarMenuDraw( GameWindow *window, WinInstanceData *instData ) { //ICoord2D original, size; // TheDisplay->setClipRegion(&clipRegion); window->winDrawBorder(); //window->winGetScreenPosition(&original.x, &original.y); //window->winGetSize(&size.x, &size.y); //blitBorderRect( original.x, original.y, size.x, size.y ); //W3DGameWinDefaultDraw( window, instData ); // TheDisplay->enableClipping(FALSE); } //W3DGameWinDefaultDraw( window, instData ); // // //R:83 G:78 B:52 // // //// UnsignedInt color = GameMakeColor(113,108,82,212); // ICoord2D pos, size; // // window->winGetScreenPosition(&pos.x, &pos.y); // window->winGetSize(&size.x,&size.y); // // const Image *image = TheMappedImageCollection->findImageByName("LogoGlow"); // // if(!image) // return; // // Int Width = size.x + image->getImageWidth(); // // static Int x = pos.x - image->getImageWidth(); // static Int y = pos.y - (image->getImageHeight()/2); // // static UnsignedInt m_startTime = timeGetTime(); // Int time = timeGetTime() - m_startTime; // Real percentDone = INT_TO_REAL(time) / 15624; // // if(percentDone >= 1) // { //// y = pos.y + size.y - (image->getImageHeight()/2) - 2; // m_startTime = timeGetTime(); // } // else // { // x = (percentDone * Width) - image->getImageWidth(); // } // // IRegion2D clip; // clip.lo.x = pos.x; // clip.lo.y = pos.y - image->getImageHeight(); // clip.hi.x = pos.x + size.x; // clip.hi.y = pos.y + size.y; // TheDisplay->setClipRegion(&clip); // Int alpha; // if(percentDone > .5) // alpha = ((1-percentDone) * 2) * 255; // else // alpha = ( percentDone * 2) * 255; // // TheDisplay->drawImage(image,x, y , x + image->getImageWidth(), y + image->getImageHeight(), GameMakeColor(255,255,255,alpha)); // //TheDisplay->drawImage(image,x, y , x + image->getImageWidth(), y + image->getImageHeight(), GameMakeColor(255,200,250,alpha)); // TheDisplay->enableClipping(FALSE ); // //TheDisplay->drawLine(); // void W3DClockDraw( GameWindow *window, WinInstanceData *instData ) { W3DGameWinDefaultDraw( window, instData ); ICoord2D pos, size; window->winGetScreenPosition(&pos.x, &pos.y); window->winGetSize(&size.x,&size.y); char datestr[256] = ""; time_t longTime; struct tm *curtime; time(&longTime); curtime = localtime(&longTime); strftime(datestr, 256, "%H:%M:%S", curtime); UnicodeString temp; temp.translate(datestr); instData->setText(temp); DisplayString *dString; dString = instData->getTextDisplayString(); dString->setFont(TheFontLibrary->getFont("Arial",16,0)); Int textWidth, textHeight; ICoord2D textPos; IRegion2D clockClipRegion; // sanity // how much space will this text take up dString->getSize( &textWidth, &textHeight ); //Init the clip region clockClipRegion.lo.x = pos.x + 1; clockClipRegion.lo.y = pos.y + 1; clockClipRegion.hi.x = pos.x + size.x - 1; clockClipRegion.hi.y = pos.y + size.y - 1; textPos.x = pos.x + (size.x / 2) - (textWidth / 2); textPos.y = pos.y + (size.y / 2) - (textHeight / 2); dString->setClipRegion(&clockClipRegion); dString->draw( textPos.x, textPos.y, GameMakeColor(255,255,255,255), GameMakeColor(0,0,0,255) ); } void W3DMainMenuMapBorder( GameWindow *window, WinInstanceData *instData ) { enum { BORDER_CORNER_SIZE = 10, BORDER_LINE_SIZE = 20, }; //( Int x, Int y, Int width, Int height ) // save original x, y Int x, y, width, height; window->winGetScreenPosition(&x, &y); window->winGetSize(&width,&height); // TheDisplay->setClipRegion(&clipRegion); Int originalX = x; Int originalY = y; Int maxX = x + width; Int maxY = y + height; Int x2, y2; // used for simultaneous drawing of line pairs Int size = 20; Int halfSize = size / 2; const Image *image = NULL; // Draw Horizontal Lines // All border pieces are based on a 10 pixel offset from the centerline y = originalY - 10; y2 = maxY - 10; x2 = maxX - (10 + BORDER_LINE_SIZE); image = TheMappedImageCollection->findImageByName("FrameCornerHorizontal"); if(image) { for( x=(originalX + 10); x <= x2; x += BORDER_LINE_SIZE ) { TheDisplay->drawImage( image, x, y, x + size, y + size ); TheDisplay->drawImage( image, x, y2, x + size, y2 + size ); } x2 = maxX - BORDER_CORNER_SIZE; // x == place to draw remainder if any if( (x2 - x) >= (BORDER_LINE_SIZE / 2) ) { //Blit Half piece TheDisplay->drawImage( image, x, y, x + halfSize, y + size ); TheDisplay->drawImage( image, x, y2, x + halfSize, y2 + size ); x += (BORDER_LINE_SIZE / 2); } // x2 - x ... must now be less than a half piece // check for equals and if not blit an adjusted half piece border pieces have // a two pixel repeat so we will blit one pixel over if necessary to line up // the art, but we'll cover-up the overlap with the corners if( x < x2 ) { x -= ((BORDER_LINE_SIZE / 2) - (((x2 - x) + 1) & ~1)); //Blit Half piece TheDisplay->drawImage( image, x, y, x + halfSize, y + size ); TheDisplay->drawImage( image, x, y2, x + halfSize, y2 + size ); } } image = TheMappedImageCollection->findImageByName("FrameCornerVertical"); if( image ) { // Draw Vertical Lines // All border pieces are based on a 10 pixel offset from the centerline x = originalX - 10; x2 = maxX - 10; y2 = maxY - (10 + BORDER_LINE_SIZE); for( y=(originalY + 10); y <= y2; y += BORDER_LINE_SIZE ) { TheDisplay->drawImage( image, x, y, x + size, y + size ); TheDisplay->drawImage( image, x2, y, x2 + size, y + size ); } y2 = maxY - BORDER_CORNER_SIZE; // y == place to draw remainder if any if( (y2 - y) >= (BORDER_LINE_SIZE / 2) ) { //Blit Half piece TheDisplay->drawImage( image, x, y, x + size, y + halfSize ); TheDisplay->drawImage( image, x2, y, x2 + size, y + halfSize ); y += (BORDER_LINE_SIZE / 2); } // y2 - y ... must now be less than a half piece // check for equals and if not blit an adjusted half piece border pieces have // a two pixel repeat so we will blit one pixel over if necessary to line up // the art, but we'll cover-up the overlap with the corners if( y < y2 ) { y -= ((BORDER_LINE_SIZE / 2) - (((y2 - y) + 1) & ~1)); //Blit Half piece TheDisplay->drawImage( image, x, y, x + size, y + halfSize ); TheDisplay->drawImage( image, x2, y, x2 + size, y + halfSize ); } } // Draw Corners x = originalX - BORDER_CORNER_SIZE; y = originalY - BORDER_CORNER_SIZE; TheDisplay->drawImage( TheMappedImageCollection->findImageByName("FrameCornerUL"), x, y, x + size, y + size ); x = maxX - BORDER_CORNER_SIZE; y = originalY - BORDER_CORNER_SIZE; TheDisplay->drawImage( TheMappedImageCollection->findImageByName("FrameCornerUR"), x, y, x + size, y + size ); x = originalX - BORDER_CORNER_SIZE; y = maxY - BORDER_CORNER_SIZE; TheDisplay->drawImage( TheMappedImageCollection->findImageByName("FrameCornerLL"), x, y, x + size, y + size ); x = maxX - BORDER_CORNER_SIZE; y = maxY - BORDER_CORNER_SIZE; TheDisplay->drawImage(TheMappedImageCollection->findImageByName("FrameCornerLR"), x, y, x + size, y + size ); TheDisplay->enableClipping(FALSE); } //Specialized drawing function for the buttons with the weird drop shadow // W3DMainMenuButtonDropShadowDraw =============================================== /** Draw pushbutton with user supplied images */ //============================================================================= void W3DMainMenuButtonDropShadowDraw( GameWindow *window, WinInstanceData *instData ) { const Image *leftImage, *rightImage, *centerImage; ICoord2D origin, size, start, end; Int xOffset, yOffset; Int i; // get screen position and size window->winGetScreenPosition( &origin.x, &origin.y ); window->winGetSize( &size.x, &size.y ); // get image offset xOffset = instData->m_imageOffset.x; yOffset = instData->m_imageOffset.y; // // get pointer to image we want to draw depending on our state, // see GadgetPushButton.h for info // if( BitTest( window->winGetStatus(), WIN_STATUS_ENABLED ) == FALSE ) { if( BitTest( instData->getState(), WIN_STATE_SELECTED ) ) { leftImage = GadgetButtonGetLeftDisabledSelectedImage( window ); rightImage = GadgetButtonGetRightDisabledSelectedImage( window ); centerImage = GadgetButtonGetMiddleDisabledSelectedImage( window ); } else { leftImage = GadgetButtonGetLeftDisabledImage( window ); rightImage = GadgetButtonGetRightDisabledImage( window ); centerImage = GadgetButtonGetMiddleDisabledImage( window ); } } // end if, disabled else if( BitTest( instData->getState(), WIN_STATE_HILITED ) ) { if( BitTest( instData->getState(), WIN_STATE_SELECTED ) ) { leftImage = GadgetButtonGetLeftHiliteSelectedImage( window ); rightImage = GadgetButtonGetRightHiliteSelectedImage( window ); centerImage = GadgetButtonGetMiddleHiliteSelectedImage( window ); } else { leftImage = GadgetButtonGetLeftHiliteImage( window ); rightImage = GadgetButtonGetRightHiliteImage( window ); centerImage = GadgetButtonGetMiddleHiliteImage( window ); } } // end else if, hilited and enabled else { if( BitTest( instData->getState(), WIN_STATE_SELECTED ) ) { leftImage = GadgetButtonGetLeftEnabledSelectedImage( window ); rightImage = GadgetButtonGetRightEnabledSelectedImage( window ); centerImage = GadgetButtonGetMiddleEnabledSelectedImage( window ); } else { leftImage = GadgetButtonGetLeftEnabledImage( window ); rightImage = GadgetButtonGetRightEnabledImage( window ); centerImage = GadgetButtonGetMiddleEnabledImage( window ); } } // end else, enabled only // sanity, we need to have these images to make it look right if( leftImage == NULL || rightImage == NULL || centerImage == NULL ) return; // get image sizes for the ends ICoord2D leftSize, rightSize; leftSize.x = leftImage->getImageWidth(); leftSize.y = leftImage->getImageHeight(); rightSize.x = rightImage->getImageWidth(); rightSize.y = rightImage->getImageHeight(); // get two key points used in the end drawing ICoord2D leftEnd, rightStart; leftEnd.x = origin.x + leftSize.x + xOffset; leftEnd.y = origin.y + size.y + yOffset; rightStart.x = origin.x + size.x - rightSize.x + xOffset; rightStart.y = origin.y + yOffset; // draw the center repeating bar Int centerWidth, pieces; // get width we have to draw our repeating center in centerWidth = rightStart.x - leftEnd.x; if( centerWidth <= 0) { // TheDisplay->setClipRegion(&clipRegion); // draw left end start.x = origin.x + xOffset; start.y = origin.y + yOffset; end.y = leftEnd.y; end.x = origin.x + xOffset + size.x/2; TheWindowManager->winDrawImage(leftImage, start.x, start.y, end.x, end.y); // draw right end start.y = rightStart.y; start.x = end.x; end.x = origin.x + size.x; end.y = start.y + size.y; TheWindowManager->winDrawImage(rightImage, start.x, start.y, end.x, end.y); } else { // how many whole repeating pieces will fit in that width pieces = centerWidth / centerImage->getImageWidth(); // draw the pieces start.x = leftEnd.x; start.y = origin.y + yOffset; end.y = start.y + size.y + yOffset; //centerImage->getImageHeight() + yOffset; // TheDisplay->setClipRegion(&clipRegion); for( i = 0; i < pieces; i++ ) { end.x = start.x + centerImage->getImageWidth(); TheWindowManager->winDrawImage( centerImage, start.x, start.y, end.x, end.y ); start.x += centerImage->getImageWidth(); } // end for i // we will draw the image but clip the parts we don't want to show IRegion2D reg; reg.lo.x = start.x; reg.lo.y = clipRegion.lo.y; reg.hi.x = rightStart.x; reg.hi.y = clipRegion.hi.y; centerWidth = rightStart.x - start.x; if( centerWidth > 0) { TheDisplay->setClipRegion(®); end.x = start.x + centerImage->getImageWidth(); TheWindowManager->winDrawImage( centerImage, start.x, start.y, end.x, end.y ); TheDisplay->enableClipping(FALSE); } // TheDisplay->setClipRegion(&clipRegion); // draw left end start.x = origin.x + xOffset; start.y = origin.y + yOffset; end = leftEnd; TheWindowManager->winDrawImage(leftImage, start.x, start.y, end.x, end.y); // draw right end start = rightStart; end.x = start.x + rightSize.x; end.y = start.y + size.y; TheWindowManager->winDrawImage(rightImage, start.x, start.y, end.x, end.y); } // draw the button text if( instData->getTextLength() ) drawText( window, instData ); // get window position window->winGetScreenPosition( &start.x, &start.y ); window->winGetSize( &size.x, &size.y ); // if we have a video buffer, draw the video buffer if ( instData->m_videoBuffer ) { TheDisplay->drawVideoBuffer( instData->m_videoBuffer, start.x, start.y, start.x + size.x, start.y + size.y ); } PushButtonData *pData = (PushButtonData *)window->winGetUserData(); if( pData ) { if( pData->overlayImage ) { TheDisplay->drawImage( pData->overlayImage, start.x, start.y, start.x + size.x, start.y + size.y ); } if( pData->drawClock ) { if( pData->drawClock == NORMAL_CLOCK ) { TheDisplay->drawRectClock(start.x, start.y, size.x, size.y, pData->percentClock,pData->colorClock); } else if( pData->drawClock == INVERSE_CLOCK ) { TheDisplay->drawRemainingRectClock( start.x, start.y, size.x, size.y, pData->percentClock,pData->colorClock ); } pData->drawClock = NO_CLOCK; window->winSetUserData(pData); } if( pData->drawBorder && pData->colorBorder != GAME_COLOR_UNDEFINED ) { TheDisplay->drawOpenRect(start.x - 1, start.y - 1, size.x + 2, size.y + 2, 1, pData->colorBorder); } } // TheDisplay->enableClipping(FALSE); } // end W3DGadgetPushButtonImageDraw // drawButtonText ============================================================= /** Draw button text to the screen */ //============================================================================= static void drawText( GameWindow *window, WinInstanceData *instData ) { ICoord2D origin, size, textPos; Int width, height; Color textColor, dropColor; DisplayString *text = instData->getTextDisplayString(); // sanity if( text == NULL || text->getTextLength() == 0 ) return; // get window position and size window->winGetScreenPosition( &origin.x, &origin.y ); window->winGetSize( &size.x, &size.y ); // set whether or not we center the wrapped text text->setWordWrapCentered( BitTest( instData->getStatus(), WIN_STATUS_WRAP_CENTERED )); text->setWordWrap(size.x); // get the right text color if( BitTest( window->winGetStatus(), WIN_STATUS_ENABLED ) == FALSE ) { textColor = window->winGetDisabledTextColor(); dropColor = window->winGetDisabledTextBorderColor(); } // end if, disabled else if( BitTest( instData->getState(), WIN_STATE_HILITED ) ) { textColor = window->winGetHiliteTextColor(); dropColor = window->winGetHiliteTextBorderColor(); } // end else if, hilited else { textColor = window->winGetEnabledTextColor(); dropColor = window->winGetEnabledTextBorderColor(); } // end enabled only // set our font to that of our parent if not the same if( text->getFont() != window->winGetFont() ) text->setFont( window->winGetFont() ); // get text size text->getSize( &width, &height ); // where to draw textPos.x = origin.x + (size.x / 2) - (width / 2); textPos.y = origin.y + (size.y / 2) - (height / 2); // text->setClipRegion(&clipRegion); // draw it text->draw( textPos.x, textPos.y, textColor, dropColor ); } // end drawButtonText // W3DMainMenuRandomTextDraw ================================================== /** Specialized drawing function for the random text */ //============================================================================= void W3DMainMenuRandomTextDraw( GameWindow *window, WinInstanceData *instData ) { TextData *tData = (TextData *)window->winGetUserData(); Color textColor, textOutlineColor; ICoord2D size, origin, textPos; Int textWidth, textHeight; IRegion2D textclipRegion; // get window position and size window->winGetScreenPosition( &origin.x, &origin.y ); window->winGetSize( &size.x, &size.y ); textColor = window->winGetDisabledTextColor(); textOutlineColor = window->winGetDisabledTextBorderColor(); // draw the text if( !(tData->text && (textColor != WIN_COLOR_UNDEFINED)) ) return; DisplayString *text = tData->text; //Init the clip region textclipRegion.lo.x = origin.x + 1; textclipRegion.lo.y = origin.y + 1; textclipRegion.hi.x = origin.x + size.x - 1; textclipRegion.hi.y = origin.y + size.y - 1; // how much space will this text take up text->getSize( &textWidth, &textHeight ); // draw the text textPos.x = origin.x; textPos.y = origin.y + (size.y / 2) - (textHeight / 2); text->setClipRegion(&textclipRegion); text->draw( textPos.x, textPos.y, textColor, textOutlineColor ); } void W3DThinBorderDraw( GameWindow *window, WinInstanceData *instData ) { ICoord2D start, size; const Image *image; //W3DGameWinDefaultDraw( window, instData ); // TheDisplay->setClipRegion(&clipRegion); window->winGetScreenPosition( &start.x, &start.y ); window->winGetSize( &size.x, &size.y ); image = window->winGetEnabledImage( 0 ); if( image ) { ICoord2D begin, end; begin.x = start.x + instData->m_imageOffset.x; begin.y = start.y + instData->m_imageOffset.y; end.x = begin.x + size.x; end.y = begin.y + size.y; TheWindowManager->winDrawImage( image, begin.x, begin.y, end.x, end.y ); } // end if // get window position // TheDisplay->drawOpenRect(start.x - 1, start.y - 1, size.x + 2, size.y + 2, 1, BrownishColor); TheDisplay->enableClipping(FALSE); } void W3DMainMenuInit( WindowLayout *layout, void *userData ) { /* GameWindow *parent = layout->getFirstWindow(); // NameKeyType buttonWorldBuilderID = TheNameKeyGenerator->nameToKey( "MainMenu.wnd:ButtonWorldBuilder" ); // GameWindow *buttonWorldBuilder = TheWindowManager->winGetWindowFromId( parent, buttonWorldBuilderID ); // if (buttonWorldBuilder) // buttonWorldBuilder->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); NameKeyType staticTextRandom1ID = TheNameKeyGenerator->nameToKey( "MainMenu.wnd:StaticTextRandom1" ); NameKeyType staticTextRandom2ID = TheNameKeyGenerator->nameToKey( "MainMenu.wnd:StaticTextRandom2" ); GameWindow *staticTextRandom1 = TheWindowManager->winGetWindowFromId( parent, staticTextRandom1ID); GameWindow *staticTextRandom2 = TheWindowManager->winGetWindowFromId( parent, staticTextRandom2ID); if (staticTextRandom1) staticTextRandom1->winSetDrawFunc(W3DMainMenuRandomTextDraw); if (staticTextRandom2) staticTextRandom2->winSetDrawFunc(W3DMainMenuRandomTextDraw); // //NameKeyType getUpdateID = TheNameKeyGenerator->nameToKey( "MainMenu.wnd:ButtonGetUpdate" ); NameKeyType buttonUSAID = TheNameKeyGenerator->nameToKey( "MainMenu.wnd:ButtonUSA" ); NameKeyType buttonGLAID = TheNameKeyGenerator->nameToKey( "MainMenu.wnd:ButtonGLA" ); NameKeyType buttonChinaID = TheNameKeyGenerator->nameToKey( "MainMenu.wnd:ButtonChina" ); NameKeyType skirmishID = TheNameKeyGenerator->nameToKey( AsciiString("MainMenu.wnd:ButtonSkirmish") ); NameKeyType onlineID = TheNameKeyGenerator->nameToKey( AsciiString("MainMenu.wnd:ButtonOnline") ); NameKeyType networkID = TheNameKeyGenerator->nameToKey( AsciiString("MainMenu.wnd:ButtonNetwork") ); GameWindow *button = TheWindowManager->winGetWindowFromId( parent, skirmishID ); if (button) button->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); button = TheWindowManager->winGetWindowFromId( parent, onlineID ); if (button) button->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); button = TheWindowManager->winGetWindowFromId( parent, networkID ); if (button) button->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); //GameWindow *getUpdate = TheWindowManager->winGetWindowFromId( parent, getUpdateID ); // if (getUpdate) // getUpdate->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); GameWindow *buttonUSA = TheWindowManager->winGetWindowFromId( parent, buttonUSAID ); if (buttonUSA) buttonUSA->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); GameWindow *buttonGLA = TheWindowManager->winGetWindowFromId( parent, buttonGLAID ); if (buttonGLA) buttonGLA->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); GameWindow *buttonChina = TheWindowManager->winGetWindowFromId( parent, buttonChinaID ); if (buttonChina) buttonChina->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); GameWindow *win = NULL; win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonMultiBack")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonSingleBack")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonExit")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonOptions")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonMultiplayer")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonSinglePlayer")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonReplay")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonLoadGame")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonLoadReplay")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonLoadReplayBack")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonTRAINING")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); win = TheWindowManager->winGetWindowFromId(parent, TheNameKeyGenerator->nameToKey("MainMenu.wnd:ButtonCredits")); if(win) win->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); GameWindow *clipRegionWin = TheWindowManager->winGetWindowFromId( parent, TheNameKeyGenerator->nameToKey( AsciiString("MainMenu.wnd:MapBorder") )); Int x,y,width,height; clipRegionWin->winGetScreenPosition(&x, &y); clipRegionWin->winGetSize(&width, &height); clipRegion.lo.x = x - 10; clipRegion.lo.y = y ; clipRegion.hi.x = x + width + 10; clipRegion.hi.y = y + height + 10; */ MainMenuInit( layout, userData ); } void W3DCreditsMenuDraw( GameWindow *window, WinInstanceData *instData ) { TheCredits->draw(); }