@@ -50,6 +50,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
50
50
#include " irrlichttypes_extrabloated.h"
51
51
#include " debug.h"
52
52
#include " test.h"
53
+ #include " clouds.h"
53
54
#include " server.h"
54
55
#include " constants.h"
55
56
#include " porting.h"
@@ -596,50 +597,120 @@ class RandomInputHandler : public InputHandler
596
597
bool rightreleased;
597
598
};
598
599
599
- void drawMenuBackground (video::IVideoDriver* driver)
600
- {
600
+ // Draw the tiled menu background
601
+ void drawMenuBackground (video::IVideoDriver* driver) {
601
602
core::dimension2d<u32> screensize = driver->getScreenSize ();
603
+
604
+ std::string path = getTexturePath (" menubg.png" );
605
+ if (path[0 ]) {
606
+ video::ITexture *bgtexture =
607
+ driver->getTexture (path.c_str ());
608
+
609
+ if (bgtexture) {
610
+ s32 scaledsize = 128 ;
602
611
603
- video::ITexture *bgtexture =
604
- driver->getTexture (getTexturePath (" menubg.png" ).c_str ());
605
- if (bgtexture)
606
- {
607
- s32 scaledsize = 128 ;
608
-
609
- // The important difference between destsize and screensize is
610
- // that destsize is rounded to whole scaled pixels.
611
- // These formulas use component-wise multiplication and division of v2u32.
612
- v2u32 texturesize = bgtexture->getSize ();
613
- v2u32 sourcesize = texturesize * screensize / scaledsize + v2u32 (1 ,1 );
614
- v2u32 destsize = scaledsize * sourcesize / texturesize;
612
+ // The important difference between destsize and screensize is
613
+ // that destsize is rounded to whole scaled pixels.
614
+ // These formulas use component-wise multiplication and division of v2u32.
615
+ v2u32 texturesize = bgtexture->getSize ();
616
+ v2u32 sourcesize = texturesize * screensize / scaledsize + v2u32 (1 ,1 );
617
+ v2u32 destsize = scaledsize * sourcesize / texturesize;
615
618
616
- // Default texture wrapping mode in Irrlicht is ETC_REPEAT.
617
- driver->draw2DImage (bgtexture,
618
- core::rect<s32>(0 , 0 , destsize.X , destsize.Y ),
619
- core::rect<s32>(0 , 0 , sourcesize.X , sourcesize.Y ),
620
- NULL , NULL , true );
619
+ // Default texture wrapping mode in Irrlicht is ETC_REPEAT.
620
+ driver->draw2DImage (bgtexture,
621
+ core::rect<s32>(0 , 0 , destsize.X , destsize.Y ),
622
+ core::rect<s32>(0 , 0 , sourcesize.X , sourcesize.Y ),
623
+ NULL , NULL , true );
624
+ }
621
625
}
622
-
623
- video::ITexture *logotexture =
624
- driver->getTexture (getTexturePath (" menulogo.png" ).c_str ());
625
- if (logotexture)
626
- {
627
- v2s32 logosize (logotexture->getOriginalSize ().Width ,
628
- logotexture->getOriginalSize ().Height );
629
- logosize *= 4 ;
630
-
631
- video::SColor bgcolor (255 ,50 ,50 ,50 );
632
- core::rect<s32> bgrect (0 , screensize.Height -logosize.Y -20 ,
633
- screensize.Width , screensize.Height );
634
- driver->draw2DRectangle (bgcolor, bgrect, NULL );
635
-
636
- core::rect<s32> rect (0 ,0 ,logosize.X ,logosize.Y );
637
- rect += v2s32 (screensize.Width /2 ,screensize.Height -10 -logosize.Y );
638
- rect -= v2s32 (logosize.X /2 , 0 );
639
- driver->draw2DImage (logotexture, rect,
640
- core::rect<s32>(core::position2d<s32>(0 ,0 ),
641
- core::dimension2di (logotexture->getSize ())),
642
- NULL , NULL , true );
626
+ }
627
+
628
+ // Draw the footer at the bottom of the window
629
+ void drawMenuFooter (video::IVideoDriver* driver, bool clouds) {
630
+ core::dimension2d<u32> screensize = driver->getScreenSize ();
631
+ std::string path = getTexturePath (clouds ?
632
+ " menufooter_clouds.png" : " menufooter.png" );
633
+ if (path[0 ]) {
634
+ video::ITexture *footertexture =
635
+ driver->getTexture (path.c_str ());
636
+
637
+ if (footertexture) {
638
+ f32 mult = (((f32)screensize.Width )) /
639
+ ((f32)footertexture->getOriginalSize ().Width );
640
+
641
+ v2s32 footersize (((f32)footertexture->getOriginalSize ().Width ) * mult,
642
+ ((f32)footertexture->getOriginalSize ().Height ) * mult);
643
+
644
+ // Don't draw the footer if there isn't enough room
645
+ s32 free_space = (((s32)screensize.Height )-320 )/2 ;
646
+ if (free_space > footersize.Y ) {
647
+ core::rect<s32> rect (0 ,0 ,footersize.X ,footersize.Y );
648
+ rect += v2s32 (screensize.Width /2 ,screensize.Height -footersize.Y );
649
+ rect -= v2s32 (footersize.X /2 , 0 );
650
+
651
+ driver->draw2DImage (footertexture, rect,
652
+ core::rect<s32>(core::position2d<s32>(0 ,0 ),
653
+ core::dimension2di (footertexture->getSize ())),
654
+ NULL , NULL , true );
655
+ }
656
+ }
657
+ }
658
+ }
659
+
660
+ // Draw the Header over the main menu
661
+ void drawMenuHeader (video::IVideoDriver* driver) {
662
+ core::dimension2d<u32> screensize = driver->getScreenSize ();
663
+
664
+ std::string path = getTexturePath (" menuheader.png" );
665
+ if (path[0 ]) {
666
+ video::ITexture *splashtexture =
667
+ driver->getTexture (path.c_str ());
668
+
669
+ if (splashtexture) {
670
+ // v2s32 splashsize((splashtexture->getOriginalSize().Width*100)/
671
+ // splashtexture->getOriginalSize().Height, 80);
672
+
673
+ f32 mult = (((f32)screensize.Width / 2 )) /
674
+ ((f32)splashtexture->getOriginalSize ().Width );
675
+
676
+ v2s32 splashsize (((f32)splashtexture->getOriginalSize ().Width ) * mult,
677
+ ((f32)splashtexture->getOriginalSize ().Height ) * mult);
678
+
679
+ // Don't draw the header is there isn't enough room
680
+ s32 free_space = (((s32)screensize.Height )-320 )/2 ;
681
+ if (free_space > splashsize.Y ) {
682
+ core::rect<s32> splashrect (0 , 0 , splashsize.X , splashsize.Y );
683
+ splashrect += v2s32 ((screensize.Width /2 )-(splashsize.X /2 ),
684
+ ((free_space/2 )-splashsize.Y /2 )+10 );
685
+
686
+ video::SColor bgcolor (255 ,50 ,50 ,50 );
687
+
688
+ driver->draw2DImage (splashtexture, splashrect,
689
+ core::rect<s32>(core::position2d<s32>(0 ,0 ),
690
+ core::dimension2di (splashtexture->getSize ())),
691
+ NULL , NULL , true );
692
+ }
693
+ }
694
+ }
695
+ }
696
+
697
+ // Draw the Splash over the clouds and under the main menu
698
+ void drawMenuSplash (video::IVideoDriver* driver) {
699
+ core::dimension2d<u32> screensize = driver->getScreenSize ();
700
+ if (getTexturePath (" menusplash.png" ) != " " ) {
701
+ video::ITexture *splashtexture =
702
+ driver->getTexture (getTexturePath (" menusplash.png" ).c_str ());
703
+
704
+ if (splashtexture) {
705
+ core::rect<s32> splashrect (0 , 0 , screensize.Width , screensize.Height );
706
+
707
+ video::SColor bgcolor (255 ,50 ,50 ,50 );
708
+
709
+ driver->draw2DImage (splashtexture, splashrect,
710
+ core::rect<s32>(core::position2d<s32>(0 ,0 ),
711
+ core::dimension2di (splashtexture->getSize ())),
712
+ NULL , NULL , true );
713
+ }
643
714
}
644
715
}
645
716
@@ -1540,6 +1611,22 @@ int main(int argc, char *argv[])
1540
1611
&g_menumgr, &menudata, g_gamecallback);
1541
1612
menu->allowFocusRemoval (true );
1542
1613
1614
+ // Clouds for the main menu
1615
+ bool cloud_menu_background = false ;
1616
+ Clouds *clouds = NULL ;
1617
+ if (g_settings->getBool (" menu_clouds" )) {
1618
+ cloud_menu_background = true ;
1619
+ clouds = new Clouds (smgr->getRootSceneNode (),
1620
+ smgr, -1 , rand (), 100 );
1621
+ clouds->update (v2f (0 , 0 ), video::SColor (255 ,200 ,200 ,255 ));
1622
+
1623
+ // A camera to see the clouds
1624
+ scene::ICameraSceneNode* camera;
1625
+ camera = smgr->addCameraSceneNode (0 ,
1626
+ v3f (0 ,0 ,0 ), v3f (0 , 60 , 100 ));
1627
+ camera->setFarValue (10000 );
1628
+ }
1629
+
1543
1630
if (error_message != L" " )
1544
1631
{
1545
1632
verbosestream<<" error_message = "
@@ -1552,30 +1639,60 @@ int main(int argc, char *argv[])
1552
1639
error_message = L" " ;
1553
1640
}
1554
1641
1642
+ // Time is in milliseconds, for clouds
1643
+ u32 lasttime = device->getTimer ()->getTime ();
1644
+
1555
1645
infostream<<" Created main menu" <<std::endl;
1556
1646
1557
1647
while (device->run () && kill == false )
1558
1648
{
1559
1649
if (menu->getStatus () == true )
1560
1650
break ;
1561
1651
1562
- // driver->beginScene(true, true, video::SColor(255,0,0,0));
1563
- driver->beginScene (true , true , video::SColor (255 ,128 ,128 ,128 ));
1652
+ // Time calc for the clouds
1653
+ f32 dtime; // in seconds
1654
+ if (cloud_menu_background) {
1655
+ u32 time = device->getTimer ()->getTime ();
1656
+ if (time > lasttime)
1657
+ dtime = (time - lasttime) / 1000.0 ;
1658
+ else
1659
+ dtime = 0 ;
1660
+ lasttime = time ;
1661
+ }
1564
1662
1565
- drawMenuBackground (driver);
1663
+ // driver->beginScene(true, true, video::SColor(255,0,0,0));
1664
+ driver->beginScene (true , true , video::SColor (255 ,140 ,186 ,250 ));
1665
+
1666
+ if (cloud_menu_background) {
1667
+ // *3 otherwise the clouds would move very slowly
1668
+ clouds->step (dtime*3 );
1669
+ clouds->render ();
1670
+ smgr->drawAll ();
1671
+ drawMenuSplash (driver);
1672
+ drawMenuFooter (driver, true );
1673
+ drawMenuHeader (driver);
1674
+ } else {
1675
+ drawMenuBackground (driver);
1676
+ drawMenuFooter (driver, false );
1677
+ }
1566
1678
1567
1679
guienv->drawAll ();
1568
-
1680
+
1569
1681
driver->endScene ();
1570
1682
1571
1683
// On some computers framerate doesn't seem to be
1572
1684
// automatically limited
1573
- sleep_ms (25 );
1685
+ if (!cloud_menu_background)
1686
+ sleep_ms (25 );
1574
1687
}
1575
1688
1576
1689
infostream<<" Dropping main menu" <<std::endl;
1577
1690
1578
1691
menu->drop ();
1692
+ if (cloud_menu_background) {
1693
+ clouds->drop ();
1694
+ smgr->clear ();
1695
+ }
1579
1696
}
1580
1697
1581
1698
playername = wide_to_narrow (menudata.name );
1 commit comments
CasimirKaPazi commentedon Mar 14, 2013
Beautiful.
One thing I noticed: The menu-clouds look better than the ingame-clouds. Can we change the ingame ones to look more like this?