Merge branch 'master' of github.com:supertuxkart/stk-code

This commit is contained in:
hiker 2018-02-07 08:34:51 +11:00
commit a72ed7ef30
22 changed files with 224 additions and 238 deletions

View File

@ -73,7 +73,11 @@
<spacer height="4" width="10" /> <spacer height="4" width="10" />
<!-- Nothing here yet --> <div layout="horizontal-row" proportion="1" height="fit">
<checkbox id="split_screen_horizontally"/>
<spacer width="20" height="100%" />
<label height="100%" I18N="In the ui settings" text="Multiplayer splits screen horizontally"/>
</div>
</div> </div>
<spacer height="18" width="4"/> <spacer height="18" width="4"/>

View File

@ -129,6 +129,9 @@ when the border that intersect at this corner are enabled.
hborder_out_portion="0.2" /> hborder_out_portion="0.2" />
<!-- Stateless --> <!-- Stateless -->
<element type="squareFocusHaloBW" image="forest/glass_square_focused_bw.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />
<element type="squareFocusHalo" image="forest/glass_square_focused.png" <element type="squareFocusHalo" image="forest/glass_square_focused.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6" left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" /> hborder_out_portion="1.0" />

View File

@ -128,6 +128,9 @@ when the border that intersect at this corner are enabled.
hborder_out_portion="0.2" /> hborder_out_portion="0.2" />
<!-- Stateless --> <!-- Stateless -->
<element type="squareFocusHaloBW" image="ocean/glass_square_focused_bw.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />
<element type="squareFocusHalo" image="ocean/glass_square_focused.png" <element type="squareFocusHalo" image="ocean/glass_square_focused.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6" left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" /> hborder_out_portion="1.0" />

View File

@ -129,6 +129,9 @@ when the border that intersect at this corner are enabled.
<!-- Stateless --> <!-- Stateless -->
<element type="squareFocusHaloBW" image="peach/glass_square_focused_bw.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />
<element type="squareFocusHalo" image="peach/glass_square_focused.png" <element type="squareFocusHalo" image="peach/glass_square_focused.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6" left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" /> hborder_out_portion="1.0" />

View File

@ -130,6 +130,9 @@ when the border that intersect at this corner are enabled.
<!-- Stateless --> <!-- Stateless -->
<element type="squareFocusHaloBW" image="ruby/glass_square_focused_bw.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" />
<element type="squareFocusHalo" image="ruby/glass_square_focused.png" <element type="squareFocusHalo" image="ruby/glass_square_focused.png"
left_border="6" right_border ="6" top_border="6" bottom_border="6" left_border="6" right_border ="6" top_border="6" bottom_border="6"
hborder_out_portion="1.0" /> hborder_out_portion="1.0" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 942 B

View File

@ -269,10 +269,14 @@ void STKConfig::getAllData(const XMLNode * root)
if (const XMLNode *camera = root->getNode("camera")) if (const XMLNode *camera = root->getNode("camera"))
{ {
camera->get("fov-1", &m_camera_fov[0]); for (int i = 0; i < 4; i++)
camera->get("fov-2", &m_camera_fov[1]); {
camera->get("fov-3", &m_camera_fov[2]); camera->get("fov-" + std::to_string(i + 1), &m_camera_fov[i]);
camera->get("fov-4", &m_camera_fov[3]); }
for (int i = 4; i < MAX_PLAYER_COUNT; i++)
{
camera->get("fov-" + std::to_string(4), &m_camera_fov[i]);
}
camera->get("cutscene-fov", &m_cutscene_fov); camera->get("cutscene-fov", &m_cutscene_fov);
} }

View File

@ -29,6 +29,7 @@
#include "network/remote_kart_info.hpp" #include "network/remote_kart_info.hpp"
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
#include "utils/constants.hpp"
#include <vector> #include <vector>
#include <string> #include <string>
#include <map> #include <map>
@ -148,7 +149,7 @@ public:
float m_replay_delta_angle; float m_replay_delta_angle;
/** The field of view for 1, 2, 3, 4 player split screen. */ /** The field of view for 1, 2, 3, 4 player split screen. */
float m_camera_fov[4]; float m_camera_fov[MAX_PLAYER_COUNT];
float m_cutscene_fov; float m_cutscene_fov;

View File

@ -561,7 +561,10 @@ namespace UserConfigParams
PARAM_PREFIX BoolUserConfigParam m_force_legacy_device PARAM_PREFIX BoolUserConfigParam m_force_legacy_device
PARAM_DEFAULT(BoolUserConfigParam(false, "force_legacy_device", PARAM_DEFAULT(BoolUserConfigParam(false, "force_legacy_device",
&m_video_group, "Force OpenGL 2 context, even if OpenGL 3 is available.")); &m_video_group, "Force OpenGL 2 context, even if OpenGL 3 is available."));
PARAM_PREFIX BoolUserConfigParam split_screen_horizontally
PARAM_DEFAULT(BoolUserConfigParam(true, "split_screen_horizontally",
&m_video_group, "When playing a non-square amount of players (e.g. 2),"
" should it split horizontally (top/bottom)"));
PARAM_PREFIX BoolUserConfigParam m_texture_compression PARAM_PREFIX BoolUserConfigParam m_texture_compression
PARAM_DEFAULT(BoolUserConfigParam(true, "enable_texture_compression", PARAM_DEFAULT(BoolUserConfigParam(true, "enable_texture_compression",
&m_video_group, "Enable Texture Compression")); &m_video_group, "Enable Texture Compression"));
@ -614,7 +617,6 @@ namespace UserConfigParams
PARAM_DEFAULT(BoolUserConfigParam(true, "limit_game_fps", PARAM_DEFAULT(BoolUserConfigParam(true, "limit_game_fps",
&m_recording_group, "Limit game framerate not beyond the fps of" &m_recording_group, "Limit game framerate not beyond the fps of"
" recording video.")); " recording video."));
PARAM_PREFIX IntUserConfigParam m_video_format PARAM_PREFIX IntUserConfigParam m_video_format
PARAM_DEFAULT(IntUserConfigParam(0, "video_format", PARAM_DEFAULT(IntUserConfigParam(0, "video_format",
&m_recording_group, "Specify the video for record, which is the enum" &m_recording_group, "Specify the video for record, which is the enum"

View File

@ -163,71 +163,15 @@ void Camera::setKart(AbstractKart *new_kart)
*/ */
void Camera::setupCamera() void Camera::setupCamera()
{ {
m_aspect = (float)(irr_driver->getActualScreenSize().Width) m_viewport = irr_driver->GetSplitscreenWindow(m_index);
/ irr_driver->getActualScreenSize().Height; m_aspect = (float)((float)(m_viewport.getWidth()) / (float)(m_viewport.getHeight()));
switch(race_manager->getNumLocalPlayers())
{ m_scaling = core::vector2df(
case 1: m_viewport = core::recti(0, 0, irr_driver->getActualScreenSize().Width / m_viewport.getWidth() ,
irr_driver->getActualScreenSize().Width, irr_driver->getActualScreenSize().Height / m_viewport.getHeight());
irr_driver->getActualScreenSize().Height);
m_scaling = core::vector2df(1.0f, 1.0f); m_fov = DEGREE_TO_RAD * stk_config->m_camera_fov[race_manager->getNumLocalPlayers() - 1];
m_fov = DEGREE_TO_RAD*stk_config->m_camera_fov[0];
break;
case 2: m_viewport = core::recti(0,
m_index==0 ? 0
: irr_driver->getActualScreenSize().Height>>1,
irr_driver->getActualScreenSize().Width,
m_index==0 ? irr_driver->getActualScreenSize().Height>>1
: irr_driver->getActualScreenSize().Height);
m_scaling = core::vector2df(1.0f, 0.5f);
m_aspect *= 2.0f;
m_fov = DEGREE_TO_RAD*stk_config->m_camera_fov[1];
break;
case 3:
/*
if(m_index<2)
{
m_viewport = core::recti(m_index==0 ? 0
: irr_driver->getActualScreenSize().Width>>1,
0,
m_index==0 ? irr_driver->getActualScreenSize().Width>>1
: irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height>>1);
m_scaling = core::vector2df(0.5f, 0.5f);
m_fov = DEGREE_TO_RAD*50.0f;
}
else
{
m_viewport = core::recti(0, irr_driver->getActualScreenSize().Height>>1,
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height);
m_scaling = core::vector2df(1.0f, 0.5f);
m_fov = DEGREE_TO_RAD*65.0f;
m_aspect *= 2.0f;
}
break;*/
case 4:
{ // g++ 4.3 whines about the variables in switch/case if not {}-wrapped (???)
const int x1 = (m_index%2==0 ? 0 : irr_driver->getActualScreenSize().Width>>1);
const int y1 = (m_index<2 ? 0 : irr_driver->getActualScreenSize().Height>>1);
const int x2 = (m_index%2==0 ? irr_driver->getActualScreenSize().Width>>1 : irr_driver->getActualScreenSize().Width);
const int y2 = (m_index<2 ? irr_driver->getActualScreenSize().Height>>1 : irr_driver->getActualScreenSize().Height);
m_viewport = core::recti(x1, y1, x2, y2);
m_scaling = core::vector2df(0.5f, 0.5f);
m_fov = DEGREE_TO_RAD*stk_config->m_camera_fov[3];
}
break;
default:
if(UserConfigParams::logMisc())
Log::warn("Camera", "Incorrect number of players: '%d' - assuming 1.",
race_manager->getNumLocalPlayers());
m_viewport = core::recti(0, 0,
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height);
m_scaling = core::vector2df(1.0f, 1.0f);
m_fov = DEGREE_TO_RAD*75.0f;
break;
} // switch
m_camera->setFOV(m_fov); m_camera->setFOV(m_fov);
m_camera->setAspectRatio(m_aspect); m_camera->setAspectRatio(m_aspect);
m_camera->setFarValue(Track::getCurrentTrack()->getCameraFar()); m_camera->setFarValue(Track::getCurrentTrack()->getCameraFar());

View File

@ -230,7 +230,31 @@ void IrrDriver::updateConfigIfRelevant()
} }
#endif // !SERVER_ONLY #endif // !SERVER_ONLY
} // updateConfigIfRelevant } // updateConfigIfRelevant
core::recti IrrDriver::GetSplitscreenWindow(int WindowNum)
{
const int playernum = race_manager->getNumLocalPlayers();
const float playernum_sqrt = sqrt(playernum);
int rows = UserConfigParams::split_screen_horizontally ? ceil(playernum_sqrt) : round(playernum_sqrt);
int cols = UserConfigParams::split_screen_horizontally ? round(playernum_sqrt) : ceil(playernum_sqrt);
if (rows == 0){rows = 1;}
if (cols == 0) {cols = 1;}
//This could add a bit of overhang
const int width_of_space = ceil((float)irr_driver->getActualScreenSize().Width / (float)cols);
const int height_of_space = ceil((float)irr_driver->getActualScreenSize().Height / (float)rows);
const int x_grid_Position = WindowNum % cols;
const int y_grid_Position = floor((WindowNum) / cols);
int wid = (int)irr_driver->getActualScreenSize().Width;
//To prevent the viewport going over the right side, we use std::min to ensure the right corners are never larger than the total width
return core::recti(
x_grid_Position * width_of_space,
y_grid_Position * height_of_space,
(x_grid_Position * width_of_space) + width_of_space,
(y_grid_Position * height_of_space) + height_of_space);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Gets a list of supported video modes from the irrlicht device. This data /** Gets a list of supported video modes from the irrlicht device. This data
* is stored in m_modes. * is stored in m_modes.

View File

@ -203,6 +203,7 @@ public:
void increaseObjectCount(); void increaseObjectCount();
core::array<video::IRenderTarget> &getMainSetup(); core::array<video::IRenderTarget> &getMainSetup();
void updateConfigIfRelevant(); void updateConfigIfRelevant();
core::recti GetSplitscreenWindow(int WindowNum);
void setAllMaterialFlags(scene::IMesh *mesh) const; void setAllMaterialFlags(scene::IMesh *mesh) const;
scene::IAnimatedMesh *getAnimatedMesh(const std::string &name); scene::IAnimatedMesh *getAnimatedMesh(const std::string &name);
scene::IMesh *getMesh(const std::string &name); scene::IMesh *getMesh(const std::string &name);

View File

@ -912,6 +912,19 @@ void Skin::drawRibbon(const core::recti &rect, Widget* widget,
{ {
} // drawRibbon } // drawRibbon
SColorf GetPlayerColor(int player_id)
{
SColorHSL col = { 0,100,50 };
col.Hue += (360 / 4) * (player_id % 4);
int color_id = player_id % 4;
SColorf color_rgb = { 0,0,0,1 };
col.Saturation = col.Saturation * (1.0F / (floor(player_id / 4) + 1) );
col.toRGB(color_rgb);
return color_rgb;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** /**
* @param focused whether this element is focus by the master player (whether * @param focused whether this element is focus by the master player (whether
@ -1069,8 +1082,8 @@ void Skin::drawRibbonChild(const core::recti &rect, Widget* widget,
} }
} }
// if multiple player selected the same ribbon item, we need to know
// to make it visible //Handle drawing for the first player
int nPlayersOnThisItem = 0; int nPlayersOnThisItem = 0;
if (mark_focused) if (mark_focused)
@ -1134,11 +1147,24 @@ void Skin::drawRibbonChild(const core::recti &rect, Widget* widget,
} }
} // end if mark_focused } // end if mark_focused
//Handle drawing for everyone else
for (int i = 1; i < MAX_PLAYER_COUNT; i++)
{
// ---- Draw selection for other players than player 1 // ---- Draw selection for other players than player 1
if (parentRibbon->isFocusedForPlayer(1) && if (parentRibbon->isFocusedForPlayer(i) &&
parentRibbon->getSelectionIDString(1) == parentRibbon->getSelectionIDString(i) ==
widget->m_properties[PROP_ID]) widget->m_properties[PROP_ID])
{ {
short red_previous = parentRibbonWidget->m_skin_r;
short green_previous = parentRibbonWidget->m_skin_g;
short blue_previous = parentRibbonWidget->m_skin_b;
SColorf color_rgb = GetPlayerColor(i);
parentRibbonWidget->m_skin_r = color_rgb.r * 255.0F;
parentRibbonWidget->m_skin_g = color_rgb.g * 255.0F;
parentRibbonWidget->m_skin_b = color_rgb.b * 255.0F;
if (nPlayersOnThisItem > 0) if (nPlayersOnThisItem > 0)
{ {
core::recti rect2 = rect; core::recti rect2 = rect;
@ -1147,62 +1173,20 @@ void Skin::drawRibbonChild(const core::recti &rect, Widget* widget,
rect2.UpperLeftCorner.Y -= enlarge; rect2.UpperLeftCorner.Y -= enlarge;
rect2.LowerRightCorner.X += enlarge; rect2.LowerRightCorner.X += enlarge;
rect2.LowerRightCorner.Y += enlarge; rect2.LowerRightCorner.Y += enlarge;
drawBoxFromStretchableTexture(parentRibbonWidget, rect2, drawBoxFromStretchableTexture(parentRibbonWidget, rect2,
SkinConfig::m_render_params["squareFocusHalo2::neutral"]); SkinConfig::m_render_params["squareFocusHaloBW::neutral"]);
} }
else else
{ {
drawBoxFromStretchableTexture(parentRibbonWidget, rect, drawBoxFromStretchableTexture(parentRibbonWidget, rect,
SkinConfig::m_render_params["squareFocusHalo2::neutral"]); SkinConfig::m_render_params["squareFocusHaloBW::neutral"]);
} }
parentRibbonWidget->m_skin_r = red_previous;
parentRibbonWidget->m_skin_g = green_previous;
parentRibbonWidget->m_skin_b = blue_previous;
nPlayersOnThisItem++; nPlayersOnThisItem++;
} }
if (parentRibbon->isFocusedForPlayer(2) &&
parentRibbon->getSelectionIDString(2) ==
widget->m_properties[PROP_ID])
{
if (nPlayersOnThisItem > 0)
{
core::recti rect2 = rect;
const int enlarge = nPlayersOnThisItem*6;
rect2.UpperLeftCorner.X -= enlarge;
rect2.UpperLeftCorner.Y -= enlarge;
rect2.LowerRightCorner.X += enlarge;
rect2.LowerRightCorner.Y += enlarge;
drawBoxFromStretchableTexture(parentRibbonWidget, rect2,
SkinConfig::m_render_params["squareFocusHalo3::neutral"]);
}
else
{
drawBoxFromStretchableTexture(parentRibbonWidget, rect,
SkinConfig::m_render_params["squareFocusHalo3::neutral"]);
}
nPlayersOnThisItem++;
}
if (parentRibbon->isFocusedForPlayer(3) &&
parentRibbon->getSelectionIDString(3) ==
widget->m_properties[PROP_ID])
{
if (nPlayersOnThisItem > 0)
{
core::recti rect2 = rect;
const int enlarge = nPlayersOnThisItem*6;
rect2.UpperLeftCorner.X -= enlarge;
rect2.UpperLeftCorner.Y -= enlarge;
rect2.LowerRightCorner.X += enlarge;
rect2.LowerRightCorner.Y += enlarge;
drawBoxFromStretchableTexture(parentRibbonWidget, rect2,
SkinConfig::m_render_params["squareFocusHalo4::neutral"]);
}
else
{
drawBoxFromStretchableTexture(parentRibbonWidget, rect,
SkinConfig::m_render_params["squareFocusHalo4::neutral"]);
}
nPlayersOnThisItem++;
} }
drawIconButton(rect, widget, pressed, focused); drawIconButton(rect, widget, pressed, focused);
@ -1224,6 +1208,7 @@ void Skin::drawRibbonChild(const core::recti &rect, Widget* widget,
#endif #endif
} // drawRibbonChild } // drawRibbonChild
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** /**
* @param focused whether this element is focus by the master player (whether * @param focused whether this element is focus by the master player (whether
@ -1256,25 +1241,28 @@ void Skin::drawSpinnerBody(const core::recti &rect, Widget* widget,
} }
} }
BoxRenderParams* params; BoxRenderParams* params;
SpinnerWidget* q = dynamic_cast<SpinnerWidget*>(widget); SpinnerWidget* q = dynamic_cast<SpinnerWidget*>(widget);
if(q->getUseBackgroundColor()) if(q->getUseBackgroundColor())
{ {
int player_id=q->getSpinnerWidgetPlayerID(); int player_id=q->getSpinnerWidgetPlayerID();
params = &SkinConfig::m_render_params[
"spinner::deactivated"];
SColorf color_rgb = GetPlayerColor(player_id);
widget->m_skin_r = color_rgb.r * 255.0F;
widget->m_skin_g = color_rgb.g * 255.0F;
widget->m_skin_b = color_rgb.b * 255.0F;
if (player_id == 0) if (player_id == 0)
params=&SkinConfig::m_render_params["spinner1::neutral"];
else if(player_id==1)
params=&SkinConfig::m_render_params["spinner2::neutral"];
else if(player_id==2)
params=&SkinConfig::m_render_params["spinner3::neutral"];
else if(player_id==3)
params=&SkinConfig::m_render_params["spinner4::neutral"];
else
{ {
Log::fatal("Skin::drawSpinnerBody", "Unknown playerID (more than 4 players?)"); color_rgb = { 1,1,1,1 };
// Silence compiler warning
params = NULL;
} }
} }
else if (widget->m_deactivated) else if (widget->m_deactivated)
{ {
@ -1288,49 +1276,24 @@ void Skin::drawSpinnerBody(const core::recti &rect, Widget* widget,
{ {
params=&SkinConfig::m_render_params["spinner::neutral"]; params=&SkinConfig::m_render_params["spinner::neutral"];
} }
if (widget->isFocusedForPlayer(0)) for (int i = 1; i < MAX_PLAYER_COUNT + 1; i++)
{ {
if (widget->isFocusedForPlayer(i - 1)) {
core::recti rect2 = rect; core::recti rect2 = rect;
rect2.UpperLeftCorner.X += 2; rect2.UpperLeftCorner.X += 2;
rect2.UpperLeftCorner.Y -= 3; rect2.UpperLeftCorner.Y -= 3;
rect2.LowerRightCorner.X -= 2; rect2.LowerRightCorner.X -= 2;
rect2.LowerRightCorner.Y += 5; rect2.LowerRightCorner.Y += 5;
drawBoxFromStretchableTexture(widget, rect2,
SkinConfig::m_render_params["squareFocusHalo::neutral"]);
}
else if (widget->isFocusedForPlayer(1))
{
core::recti rect2 = rect;
rect2.UpperLeftCorner.X += 2;
rect2.UpperLeftCorner.Y -= 3;
rect2.LowerRightCorner.X -= 2;
rect2.LowerRightCorner.Y += 5;
drawBoxFromStretchableTexture(widget, rect2, drawBoxFromStretchableTexture(widget, rect2,
SkinConfig::m_render_params["squareFocusHalo2::neutral"]); SkinConfig::m_render_params["squareFocusHaloBW::neutral"]);
//TODO add squarefocushalo0
} }
else if (widget->isFocusedForPlayer(2))
{
core::recti rect2 = rect;
rect2.UpperLeftCorner.X += 2;
rect2.UpperLeftCorner.Y -= 3;
rect2.LowerRightCorner.X -= 2;
rect2.LowerRightCorner.Y += 5;
drawBoxFromStretchableTexture(widget, rect2,
SkinConfig::m_render_params["squareFocusHalo3::neutral"]);
}
else if (widget->isFocusedForPlayer(3))
{
core::recti rect2 = rect;
rect2.UpperLeftCorner.X += 2;
rect2.UpperLeftCorner.Y -= 3;
rect2.LowerRightCorner.X -= 2;
rect2.LowerRightCorner.Y += 5;
drawBoxFromStretchableTexture(widget, rect2,
SkinConfig::m_render_params["squareFocusHalo4::neutral"]);
} }
core::recti sized_rect = rect; core::recti sized_rect = rect;
if (m_dialog && m_dialog_size < 1.0f && widget->m_parent != NULL && if (m_dialog && m_dialog_size < 1.0f && widget->m_parent != NULL &&
widget->m_parent->getType() == gui::EGUIET_WINDOW) widget->m_parent->getType() == gui::EGUIET_WINDOW)

View File

@ -489,6 +489,16 @@ public:
{ {
return m_num_local_players; return m_num_local_players;
} // getNumLocalPlayers } // getNumLocalPlayers
// ------------------------------------------------------------------------
bool getIfEmptyScreenSpaceExists() const
{
const float Sqrt = sqrt(getNumLocalPlayers());
const int rows = ceil(Sqrt);
const int cols = round(Sqrt);
const int total_spaces = rows * cols;
return (total_spaces - getNumLocalPlayers() > 0);
} // getNumLocalPlayers
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the selected number of karts (selected number of players and /** Returns the selected number of karts (selected number of players and
* AI karts. */ * AI karts. */

View File

@ -128,6 +128,13 @@ void OptionsScreenUI::init()
assert( skinSelector != NULL ); assert( skinSelector != NULL );
// ---- video modes // ---- video modes
CheckBoxWidget* splitscreen_method = getWidget<CheckBoxWidget>("split_screen_horizontally");
assert(splitscreen_method != NULL);
splitscreen_method->setState(UserConfigParams::split_screen_horizontally);
//Forbid changing this setting in game
bool in_game = StateManager::get()->getGameState() == GUIEngine::INGAME_MENU;
splitscreen_method->setActive(!in_game);
CheckBoxWidget* fps = getWidget<CheckBoxWidget>("showfps"); CheckBoxWidget* fps = getWidget<CheckBoxWidget>("showfps");
assert( fps != NULL ); assert( fps != NULL );
@ -221,6 +228,7 @@ void OptionsScreenUI::init()
// tearing down and rebuilding the menu stack. not good when in-game) // tearing down and rebuilding the menu stack. not good when in-game)
list_widget->setActive(StateManager::get()->getGameState() != GUIEngine::INGAME_MENU); list_widget->setActive(StateManager::get()->getGameState() != GUIEngine::INGAME_MENU);
} // init } // init
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -258,6 +266,13 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
UserConfigParams::m_skin_file = core::stringc(selectedSkin.c_str()).c_str() + std::string(".stkskin"); UserConfigParams::m_skin_file = core::stringc(selectedSkin.c_str()).c_str() + std::string(".stkskin");
GUIEngine::reloadSkin(); GUIEngine::reloadSkin();
} }
else if (name == "split_screen_horizontally")
{
CheckBoxWidget* split_screen_horizontally = getWidget<CheckBoxWidget>("split_screen_horizontally");
assert(split_screen_horizontally != NULL);
UserConfigParams::split_screen_horizontally = split_screen_horizontally->getState();
}
else if (name == "showfps") else if (name == "showfps")
{ {
CheckBoxWidget* fps = getWidget<CheckBoxWidget>("showfps"); CheckBoxWidget* fps = getWidget<CheckBoxWidget>("showfps");

View File

@ -121,7 +121,7 @@ RaceGUI::RaceGUI()
// special case : when 3 players play, use available 4th space for such things // special case : when 3 players play, use available 4th space for such things
if (race_manager->getNumLocalPlayers() == 3) if (race_manager->getIfEmptyScreenSpaceExists())
{ {
m_map_left = irr_driver->getActualScreenSize().Width - m_map_width; m_map_left = irr_driver->getActualScreenSize().Width - m_map_width;
} }
@ -190,15 +190,13 @@ void RaceGUI::renderGlobal(float dt)
// Special case : when 3 players play, use 4th window to display such // Special case : when 3 players play, use 4th window to display such
// stuff (but we must clear it) // stuff (but we must clear it)
if (race_manager->getNumLocalPlayers() == 3 && if (race_manager->getIfEmptyScreenSpaceExists() &&
!GUIEngine::ModalDialog::isADialogActive()) !GUIEngine::ModalDialog::isADialogActive())
{ {
static video::SColor black = video::SColor(255,0,0,0); static video::SColor black = video::SColor(255,0,0,0);
GL32_draw2DRectangle(black,
core::rect<s32>(irr_driver->getActualScreenSize().Width/2, GL32_draw2DRectangle(black, irr_driver->GetSplitscreenWindow(
irr_driver->getActualScreenSize().Height/2, race_manager->getNumLocalPlayers()));
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height));
} }
World *world = World::getWorld(); World *world = World::getWorld();
@ -255,7 +253,7 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt)
drawPlungerInFace(camera, dt); drawPlungerInFace(camera, dt);
scaling *= viewport.getWidth()/800.0f; // scale race GUI along screen size scaling *= float(viewport.getWidth()) / float(irr_driver->getActualScreenSize().Width); // scale race GUI along screen size
drawAllMessages(kart, viewport, scaling); drawAllMessages(kart, viewport, scaling);
if(!World::getWorld()->isRacePhase()) return; if(!World::getWorld()->isRacePhase()) return;
@ -368,9 +366,10 @@ void RaceGUI::drawGlobalTimer()
irr_driver->getActualScreenSize().Width , 50); irr_driver->getActualScreenSize().Width , 50);
// special case : when 3 players play, use available 4th space for such things // special case : when 3 players play, use available 4th space for such things
if (race_manager->getNumLocalPlayers() == 3) if (race_manager->getIfEmptyScreenSpaceExists())
{ {
pos += core::vector2d<s32>(0, irr_driver->getActualScreenSize().Height/2); pos -= core::vector2d<s32>(0, pos.LowerRightCorner.Y / 2);
pos += core::vector2d<s32>(0, irr_driver->getActualScreenSize().Height - irr_driver->GetSplitscreenWindow(0).getHeight());
} }
gui::ScalableFont* font = (use_digit_font ? GUIEngine::getHighresDigitFont() : GUIEngine::getFont()); gui::ScalableFont* font = (use_digit_font ? GUIEngine::getHighresDigitFont() : GUIEngine::getFont());
@ -888,14 +887,20 @@ void RaceGUI::drawLap(const AbstractKart* kart,
if (lap < 0 ) return; if (lap < 0 ) return;
core::recti pos; core::recti pos;
pos.UpperLeftCorner.Y = viewport.UpperLeftCorner.Y + m_font_height;
// If the time display in the top right is in this viewport, // If the time display in the top right is in this viewport,
// move the lap/rank display down a little bit so that it is // move the lap/rank display down a little bit so that it is
// displayed under the time. // displayed under the time.
if (viewport.UpperLeftCorner.Y == 0 && if (viewport.UpperLeftCorner.Y == 0 &&
viewport.LowerRightCorner.X == (int)(irr_driver->getActualScreenSize().Width) && viewport.LowerRightCorner.X == (int)(irr_driver->getActualScreenSize().Width) &&
race_manager->getNumPlayers()!=3) !race_manager->getIfEmptyScreenSpaceExists())
{
pos.UpperLeftCorner.Y += m_font_height; pos.UpperLeftCorner.Y += m_font_height;
}
else
{
pos.UpperLeftCorner.Y = viewport.UpperLeftCorner.Y + m_font_height;
}
pos.LowerRightCorner.Y = viewport.LowerRightCorner.Y+20; pos.LowerRightCorner.Y = viewport.LowerRightCorner.Y+20;
pos.UpperLeftCorner.X = viewport.LowerRightCorner.X pos.UpperLeftCorner.X = viewport.LowerRightCorner.X
- m_lap_width - 10; - m_lap_width - 10;

View File

@ -207,8 +207,8 @@ void RaceGUIBase::drawAllMessages(const AbstractKart* kart,
{ {
int y = viewport.LowerRightCorner.Y - m_small_font_max_height - 10; int y = viewport.LowerRightCorner.Y - m_small_font_max_height - 10;
const int x = (viewport.LowerRightCorner.X + viewport.UpperLeftCorner.X)/2; const int x = viewport.getCenter().X;
const int w = (viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X); const int w = viewport.getWidth();
// Draw less important messages first, at the very bottom of the screen // Draw less important messages first, at the very bottom of the screen
// unimportant messages are skipped in multiplayer, they take too much screen space // unimportant messages are skipped in multiplayer, they take too much screen space
@ -244,7 +244,7 @@ void RaceGUIBase::drawAllMessages(const AbstractKart* kart,
} }
// First line of text somewhat under the top of the viewport. // First line of text somewhat under the top of the viewport.
y = (int)(viewport.UpperLeftCorner.Y + 164*scaling.Y); y = (int)(viewport.UpperLeftCorner.Y + 20);
gui::ScalableFont* font = GUIEngine::getFont(); gui::ScalableFont* font = GUIEngine::getFont();
gui::ScalableFont* big_font = GUIEngine::getTitleFont(); gui::ScalableFont* big_font = GUIEngine::getTitleFont();
@ -665,10 +665,11 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
int y_base = 20; int y_base = 20;
unsigned int y_space = irr_driver->getActualScreenSize().Height - bottom_margin - y_base; unsigned int y_space = irr_driver->getActualScreenSize().Height - bottom_margin - y_base;
// Special case : when 3 players play, use 4th window to display such stuff // Special case : when 3 players play, use 4th window to display such stuff
if (race_manager->getNumLocalPlayers() == 3) if (race_manager->getIfEmptyScreenSpaceExists())
{ {
x_base = irr_driver->getActualScreenSize().Width/2 + x_base; irr::core::recti Last_Space = irr_driver->GetSplitscreenWindow(race_manager->getNumLocalPlayers());
y_base = irr_driver->getActualScreenSize().Height/2 + y_base; x_base = Last_Space.UpperLeftCorner.X;
y_base = Last_Space.UpperLeftCorner.Y;
y_space = irr_driver->getActualScreenSize().Height - y_base; y_space = irr_driver->getActualScreenSize().Height - y_base;
} }
@ -729,7 +730,7 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
//where is the limit to hide last icons //where is the limit to hide last icons
int y_icons_limit = irr_driver->getActualScreenSize().Height - int y_icons_limit = irr_driver->getActualScreenSize().Height -
bottom_margin - ICON_PLAYER_WIDTH; bottom_margin - ICON_PLAYER_WIDTH;
if (race_manager->getNumLocalPlayers() == 3) if (race_manager->getIfEmptyScreenSpaceExists())
{ {
y_icons_limit = irr_driver->getActualScreenSize().Height - ICON_WIDTH; y_icons_limit = irr_driver->getActualScreenSize().Height - ICON_WIDTH;
} }

View File

@ -122,7 +122,7 @@ RaceGUIOverworld::RaceGUIOverworld()
// special case : when 3 players play, use available 4th space for such things // special case : when 3 players play, use available 4th space for such things
if (race_manager->getNumLocalPlayers() == 3) if (race_manager->getIfEmptyScreenSpaceExists())
{ {
m_map_left = irr_driver->getActualScreenSize().Width - m_map_width; m_map_left = irr_driver->getActualScreenSize().Width - m_map_width;
} }
@ -179,15 +179,15 @@ void RaceGUIOverworld::renderGlobal(float dt)
// Special case : when 3 players play, use 4th window to display such // Special case : when 3 players play, use 4th window to display such
// stuff (but we must clear it) // stuff (but we must clear it)
if (race_manager->getNumLocalPlayers() == 3 && if (race_manager->getIfEmptyScreenSpaceExists() &&
!GUIEngine::ModalDialog::isADialogActive()) !GUIEngine::ModalDialog::isADialogActive())
{ {
const float Sqrt = sqrt(race_manager->getNumLocalPlayers());
const int rows = ceil(Sqrt);
const int cols = round(Sqrt);
static video::SColor black = video::SColor(255,0,0,0); static video::SColor black = video::SColor(255,0,0,0);
GL32_draw2DRectangle(black, GL32_draw2DRectangle(black, irr_driver->GetSplitscreenWindow(
core::rect<s32>(irr_driver->getActualScreenSize().Width/2, race_manager->getNumLocalPlayers()));
irr_driver->getActualScreenSize().Height/2,
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height));
} }
World *world = World::getWorld(); World *world = World::getWorld();

View File

@ -47,7 +47,7 @@
#define DEGREE_TO_RAD (M_PI/180.0f) #define DEGREE_TO_RAD (M_PI/180.0f)
#define RAD_TO_DEGREE (180.0f/M_PI) #define RAD_TO_DEGREE (180.0f/M_PI)
const unsigned int MAX_PLAYER_COUNT = 4; const unsigned int MAX_PLAYER_COUNT = 8;
extern const bool IS_LITTLE_ENDIAN; extern const bool IS_LITTLE_ENDIAN;