diff options
Diffstat (limited to 'Minecraft.Client/Gui.cpp')
| -rw-r--r-- | Minecraft.Client/Gui.cpp | 1523 |
1 files changed, 1523 insertions, 0 deletions
diff --git a/Minecraft.Client/Gui.cpp b/Minecraft.Client/Gui.cpp new file mode 100644 index 00000000..7d76edbd --- /dev/null +++ b/Minecraft.Client/Gui.cpp @@ -0,0 +1,1523 @@ +#include "stdafx.h" +#include "Gui.h" +#include "ItemRenderer.h" +#include "GameRenderer.h" +#include "Options.h" +#include "MultiplayerLocalPlayer.h" +#include "Textures.h" +#include "GameMode.h" +#include "Lighting.h" +#include "ChatScreen.h" +#include "MultiPlayerLevel.h" +#include "..\Minecraft.World\JavaMath.h" +#include "..\Minecraft.World\net.minecraft.world.entity.player.h" +#include "..\Minecraft.World\net.minecraft.world.effect.h" +#include "..\Minecraft.World\net.minecraft.world.food.h" +#include "..\Minecraft.World\net.minecraft.world.item.h" +#include "..\Minecraft.World\net.minecraft.world.level.h" +#include "..\Minecraft.World\LevelData.h" +#include "..\Minecraft.World\net.minecraft.world.level.tile.h" +#include "..\Minecraft.World\System.h" +#include "..\Minecraft.World\Language.h" +#include "EntityRenderDispatcher.h" +#include "..\Minecraft.World\Dimension.h" +#include "..\Minecraft.World\net.minecraft.world.entity.boss.enderdragon.h" +#include "EnderDragonRenderer.h" +#include "..\Minecraft.World\net.minecraft.h" +#include "..\Minecraft.World\net.minecraft.world.h" +#include "..\Minecraft.World\LevelChunk.h" +#include "..\Minecraft.World\Biome.h" + +#define RENDER_HUD 0 +//#ifndef _XBOX +//#undef RENDER_HUD +//#define RENDER_HUD 1 +//#endif + +float Gui::currentGuiBlendFactor = 1.0f; // 4J added +float Gui::currentGuiScaleFactor = 1.0f; // 4J added +ItemRenderer *Gui::itemRenderer = new ItemRenderer(); + +Gui::Gui(Minecraft *minecraft) +{ + // 4J - initialisers added + random = new Random(); + tickCount = 0; + overlayMessageTime = 0; + animateOverlayMessageColor = false; + progress = 0.0f; + tbr = 1.0f; + fAlphaIncrementPerCent=255.0f/100.0f; + + this->minecraft = minecraft; + + lastTickA = 0.0f; +} + +void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) +{ + // 4J Stu - I have copied this code for XUI_BaseScene. If/when it gets changed it should be broken out + // 4J - altered to force full screen mode to 3X scaling, and any split screen modes to 2X scaling. This is so that the further scaling by 0.5 that + // happens in split screen modes results in a final scaling of 1 rather than 1.5. + int splitYOffset;// = 20; // This offset is applied when doing the 2X scaling above to move the gui out of the way of the tool tips + int guiScale;// = ( minecraft->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_FULLSCREEN ? 3 : 2 ); + int iPad=minecraft->player->GetXboxPad(); + int iWidthOffset=0,iHeightOffset=0; // used to get the interface looking right on a 2 player split screen game + + // 4J-PB - selected the gui scale based on the slider settings + if(minecraft->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_FULLSCREEN) + { + guiScale=app.GetGameSettings(iPad,eGameSetting_UISize) + 2; + } + else + { + guiScale=app.GetGameSettings(iPad,eGameSetting_UISizeSplitscreen) + 2; + } + + + ScreenSizeCalculator ssc(minecraft->options, minecraft->width, minecraft->height, guiScale ); + int screenWidth = ssc.getWidth(); + int screenHeight = ssc.getHeight(); + int iSafezoneXHalf=0,iSafezoneYHalf=0; + int iTooltipsYOffset=0; + int quickSelectWidth=182; + int quickSelectHeight=22; + float fScaleFactorWidth=1.0f,fScaleFactorHeight=1.0f; + bool bTwoPlayerSplitscreen=false; + currentGuiScaleFactor = (float) guiScale; // Keep static copy of scale so we know how gui coordinates map to physical pixels - this is also affected by the viewport + + switch(guiScale) + { + case 3: + splitYOffset = 0; + break; + case 4: + splitYOffset = -5; + break; + default: // 2 + splitYOffset = 10; + break; + } + + // Check which screen section this player is in + switch(minecraft->player->m_iScreenSection) + { + case C4JRender::VIEWPORT_TYPE_FULLSCREEN: + // single player + iSafezoneXHalf = screenWidth/20; // 5% + iSafezoneYHalf = screenHeight/20; // 5% + iTooltipsYOffset=40+splitYOffset; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: + iSafezoneXHalf = screenWidth/10; // 5% (need to treat the whole screen is 2x this screen) + iSafezoneYHalf = splitYOffset; + fScaleFactorWidth=0.5f; + iWidthOffset=(int)((float)screenWidth*(1.0f - fScaleFactorWidth)); + iTooltipsYOffset=44; + bTwoPlayerSplitscreen=true; + currentGuiScaleFactor *= 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: + iSafezoneXHalf = screenWidth/10; // 5% (need to treat the whole screen is 2x this screen) + iSafezoneYHalf = splitYOffset + screenHeight/10;// 5% (need to treat the whole screen is 2x this screen) + fScaleFactorWidth=0.5f; + iWidthOffset=(int)((float)screenWidth*(1.0f - fScaleFactorWidth)); + iTooltipsYOffset=44; + bTwoPlayerSplitscreen=true; + currentGuiScaleFactor *= 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: + iSafezoneXHalf = screenWidth/10; // 5% (the whole screen is 2x this screen) + iSafezoneYHalf = splitYOffset + screenHeight/10;// 5% (need to treat the whole screen is 2x this screen) + fScaleFactorHeight=0.5f; + iHeightOffset=screenHeight; + iTooltipsYOffset=44; + bTwoPlayerSplitscreen=true; + currentGuiScaleFactor *= 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: + iSafezoneXHalf = 0; + iSafezoneYHalf = splitYOffset + screenHeight/10;// 5% (need to treat the whole screen is 2x this screen) + fScaleFactorHeight=0.5f; + iHeightOffset=screenHeight; + iTooltipsYOffset=44; + bTwoPlayerSplitscreen=true; + currentGuiScaleFactor *= 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: + iSafezoneXHalf = screenWidth/10; // 5% (the whole screen is 2x this screen) + iSafezoneYHalf = splitYOffset; + iTooltipsYOffset=44; + currentGuiScaleFactor *= 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: + iSafezoneXHalf = 0; + iSafezoneYHalf = splitYOffset; // 5% + iTooltipsYOffset=44; + currentGuiScaleFactor *= 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: + iSafezoneXHalf = screenWidth/10; // 5% (the whole screen is 2x this screen) + iSafezoneYHalf = splitYOffset + screenHeight/10; // 5% (the whole screen is 2x this screen) + iTooltipsYOffset=44; + currentGuiScaleFactor *= 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: + iSafezoneXHalf = 0; + iSafezoneYHalf = splitYOffset + screenHeight/10; // 5% (the whole screen is 2x this screen) + iTooltipsYOffset=44; + currentGuiScaleFactor *= 0.5f; + break; + + } + + // 4J-PB - turn off the slot display if a xui menu is up, or if we're autosaving + bool bDisplayGui=!ui.GetMenuDisplayed(iPad) && !(app.GetXuiAction(iPad)==eAppAction_AutosaveSaveGameCapturedThumbnail); + + // if tooltips are off, set the y offset to zero + if(app.GetGameSettings(iPad,eGameSetting_Tooltips)==0 && bDisplayGui) + { + switch(minecraft->player->m_iScreenSection) + { + case C4JRender::VIEWPORT_TYPE_FULLSCREEN: + iTooltipsYOffset=screenHeight/10; + break; + default: + //iTooltipsYOffset=screenHeight/10; + switch(guiScale) + { + case 3: + iTooltipsYOffset=28;//screenHeight/10; + break; + case 4: + iTooltipsYOffset=28;//screenHeight/10; + break; + default: // 2 + iTooltipsYOffset=14;//screenHeight/10; + break; + } + break; + } + } + + // 4J-PB - Turn off interface if eGameSetting_DisplayHUD is off - for screen shots/videos. + if ( app.GetGameSettings(iPad,eGameSetting_DisplayHUD)==0 ) + { + bDisplayGui = false; + } + + Font *font = minecraft->font; + + + minecraft->gameRenderer->setupGuiScreen(guiScale); + + + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // 4J - added - this did actually get set in renderVignette but that code is currently commented out + + if (Minecraft::useFancyGraphics()) + { + renderVignette(minecraft->player->getBrightness(a), screenWidth, screenHeight); + } + + ///////////////////////////////////////////////////////////////////////////////////// + // Display the pumpkin screen effect + ///////////////////////////////////////////////////////////////////////////////////// + + shared_ptr<ItemInstance> headGear = minecraft->player->inventory->getArmor(3); + + // 4J-PB - changing this to be per player + //if (!minecraft->options->thirdPersonView && headGear != NULL && headGear->id == Tile::pumpkin_Id) renderPumpkin(screenWidth, screenHeight); + if ((minecraft->player->ThirdPersonView()==0) && headGear != NULL && headGear->id == Tile::pumpkin_Id) renderPumpkin(screenWidth, screenHeight); + if (!minecraft->player->hasEffect(MobEffect::confusion)) + { + float pt = minecraft->player->oPortalTime + (minecraft->player->portalTime - minecraft->player->oPortalTime) * a; + if (pt > 0) + { + renderTp(pt, screenWidth, screenHeight); + } + } + + if (!minecraft->gameMode->isCutScene()) + { + if(bDisplayGui && bTwoPlayerSplitscreen) + { + // need to apply scale factors depending on the mode + glPushMatrix(); + glScalef(fScaleFactorWidth, fScaleFactorHeight, fScaleFactorWidth); + } +#if RENDER_HUD + ///////////////////////////////////////////////////////////////////////////////////// + // Display the quick select background, the quick select selection, and the crosshair + ///////////////////////////////////////////////////////////////////////////////////// + + glColor4f(1, 1, 1, 1); + + // 4J - this is where to set the blend factor for gui things + // use the primary player's settings + unsigned char ucAlpha=app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_InterfaceOpacity); + + // If the user has started to navigate their quickselect bar, ignore the alpha setting, and display at default value + float fVal=fAlphaIncrementPerCent*(float)ucAlpha; + if(ucAlpha<80) + { + // check if we have the timer running for the opacity + unsigned int uiOpacityTimer=app.GetOpacityTimer(iPad); + if(uiOpacityTimer!=0) + { + if(uiOpacityTimer<10) + { + float fStep=(80.0f-(float)ucAlpha)/10.0f; + fVal=fAlphaIncrementPerCent*(80.0f-((10.0f-(float)uiOpacityTimer)*fStep)); + } + else + { + fVal=fAlphaIncrementPerCent*80.0f; + } + } + else + { + fVal=fAlphaIncrementPerCent*(float)ucAlpha; + } + } + else + { + fVal=fAlphaIncrementPerCent*(float)ucAlpha; + } + + RenderManager.StateSetBlendFactor(0xffffff |(((unsigned int)fVal)<<24)); + currentGuiBlendFactor = fVal / 255.0f; + // RenderManager.StateSetBlendFactor(0x40ffffff); + glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); + + blitOffset = -90; + + ///////////////////////////////////////////////////////////////////////////////////// + // Display the quick select background, the quick select selection, and the crosshair + ///////////////////////////////////////////////////////////////////////////////////// + if(bDisplayGui) + { + MemSect(31); + minecraft->textures->bindTexture(TN_GUI_GUI); // 4J was L"/gui/gui.png" + MemSect(0); + + shared_ptr<Inventory> inventory = minecraft->player->inventory; + if(bTwoPlayerSplitscreen) + { + // need to apply scale factors depending on the mode + + // 4J Stu - Moved this push and scale further up as we still need to do it for the few HUD components not replaced by xui + //glPushMatrix(); + //glScalef(fScaleFactorWidth, fScaleFactorHeight, fScaleFactorWidth); + + // 4J-PB - move into the safe zone, and account for 2 player splitscreen + blit(iWidthOffset + (screenWidth - quickSelectWidth)/2, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset , 0, 0, 182, 22); + blit(iWidthOffset + (screenWidth - quickSelectWidth)/2 - 1 + inventory->selected * 20, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset - 1, 0, 22, 24, 22); + } + else + { + blit(iWidthOffset + screenWidth / 2 - quickSelectWidth / 2, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset , 0, 0, 182, 22); + blit(iWidthOffset + screenWidth / 2 - quickSelectWidth / 2 - 1 + inventory->selected * 20, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset - 1, 0, 22, 24, 22); + } + + + MemSect(31); + minecraft->textures->bindTexture(TN_GUI_ICONS);//L"/gui/icons.png")); + MemSect(0); + glEnable(GL_BLEND); + RenderManager.StateSetBlendFactor(0xffffff |(((unsigned int)fVal)<<24)); + glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); + //glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR); + // 4J Stu - We don't want to adjust the cursor by the safezone, we want it centred + if(bTwoPlayerSplitscreen) + { + blit(iWidthOffset + screenWidth / 2 - 7, (iHeightOffset + screenHeight) / 2 - 7, 0, 0, 16, 16); + } + else + { + blit(screenWidth / 2 - 7, screenHeight / 2 - 7, 0, 0, 16, 16); + } + glDisable(GL_BLEND); + + // if(bTwoPlayerSplitscreen) + // { + // glPopMatrix(); + // } + + } + + bool blink = minecraft->player->invulnerableTime / 3 % 2 == 1; + if (minecraft->player->invulnerableTime < 10) blink = false; + int iHealth = minecraft->player->getHealth(); + int iLastHealth = minecraft->player->lastHealth; + random->setSeed(tickCount * 312871); + + bool foodBlink = false; + FoodData *foodData = minecraft->player->getFoodData(); + int food = foodData->getFoodLevel(); + int oldFood = foodData->getLastFoodLevel(); + +// if (false) //(true) +// { +// renderBossHealth(); +// } + + ///////////////////////////////////////////////////////////////////////////////////// + // Display the experience, food, armour, health and the air bubbles + ///////////////////////////////////////////////////////////////////////////////////// + if(bDisplayGui) + { + // 4J - added blend for fading gui + glEnable(GL_BLEND); + glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); + + if (minecraft->gameMode->canHurtPlayer()) + { + int xLeft, xRight; + // 4J Stu - TODO Work out proper positioning for splitscreen + if(bTwoPlayerSplitscreen) + { + xLeft = iWidthOffset + (screenWidth - quickSelectWidth)/2; + xRight = iWidthOffset + (screenWidth + quickSelectWidth)/2; + } + else + { + xLeft = (screenWidth - quickSelectWidth)/2; + xRight = (screenWidth + quickSelectWidth) / 2; + } + + // render experience bar + int xpNeededForNextLevel = minecraft->player->getXpNeededForNextLevel(); + if (xpNeededForNextLevel > 0) + { + int w = 182; + + int progress = (int) (minecraft->player->experienceProgress * (float) (w + 1)); + + int yo = screenHeight - iSafezoneYHalf - iTooltipsYOffset - 8; + if(bTwoPlayerSplitscreen) + { + yo+=iHeightOffset; + } + blit(xLeft, yo, 0, 64, w, 5); + if (progress > 0) + { + blit(xLeft, yo, 0, 69, progress, 5); + } + } + + int yLine1, yLine2; + if(bTwoPlayerSplitscreen) + { + //yo = iHeightOffset + screenHeight - 10 - iSafezoneYHalf - iTooltipsYOffset; + yLine1 = iHeightOffset + screenHeight - 18 - iSafezoneYHalf - iTooltipsYOffset; + yLine2 = yLine1 - 10; + } + else + { + //yo = screenHeight - 10 - iSafezoneYHalf - iTooltipsYOffset; + yLine1 = screenHeight - 18 - iSafezoneYHalf - iTooltipsYOffset; + yLine2 = yLine1 - 10; + } + + int armor = minecraft->player->getArmorValue(); + int heartOffsetIndex = -1; + if (minecraft->player->hasEffect(MobEffect::regeneration)) + { + heartOffsetIndex = tickCount % 25; + } + + // render health and armor + for (int i = 0; i < Player::MAX_HEALTH / 2; i++) + { + if (armor > 0) + { + int xo = xLeft + i * 8; + + // HEALTH + if (i * 2 + 1 < armor) blit(xo, yLine2, 16 + 2 * 9, 9 * 1, 9, 9); + if (i * 2 + 1 == armor) blit(xo, yLine2, 16 + 1 * 9, 9 * 1, 9, 9); + if (i * 2 + 1 > armor) blit(xo, yLine2, 16 + 0 * 9, 9 * 1, 9, 9); + } + + int healthTexBaseX = 16; + if (minecraft->player->hasEffect(MobEffect::poison)) + { + healthTexBaseX += 4 * 9; + } + + int bg = 0; + if (blink) bg = 1; + int xo = xLeft + i * 8; + int yo = yLine1; + + if (iHealth <= 4) + { + yo += random->nextInt(2); + } + if (i == heartOffsetIndex) + { + yo -= 2; + } + + int y0 = 0; + // 4J-PB - no hardcore in xbox +// if (minecraft.level.getLevelData().isHardcore()) { +// y0 = 5; +// } + blit(xo, yo, 16 + bg * 9, 9 * 0, 9, 9); + if (blink) + { + if (i * 2 + 1 < iLastHealth) blit(xo, yo, healthTexBaseX + 6 * 9, 9 * y0, 9, 9); + if (i * 2 + 1 == iLastHealth) blit(xo, yo, healthTexBaseX + 7 * 9, 9 * y0, 9, 9); + } + if (i * 2 + 1 < iHealth) blit(xo, yo, healthTexBaseX + 4 * 9, 9 * y0, 9, 9); + if (i * 2 + 1 == iHealth) blit(xo, yo, healthTexBaseX + 5 * 9, 9 * y0, 9, 9); + } + + // render food + for (int i = 0; i < FoodConstants::MAX_FOOD / 2; i++) + { + int yo = yLine1; + + + int texBaseX = 16; + int bg = 0; + if (minecraft->player->hasEffect(MobEffect::hunger)) + { + texBaseX += 4 * 9; + bg = 13; + } + + if (minecraft->player->getFoodData()->getSaturationLevel() <= 0) + { + if ((tickCount % (food * 3 + 1)) == 0) + { + yo += random->nextInt(3) - 1; + } + } + + if (foodBlink) bg = 1; + int xo = xRight - i * 8 - 9; + blit(xo, yo, 16 + bg * 9, 9 * 3, 9, 9); + if (foodBlink) + { + if (i * 2 + 1 < oldFood) blit(xo, yo, texBaseX + 6 * 9, 9 * 3, 9, 9); + if (i * 2 + 1 == oldFood) blit(xo, yo, texBaseX + 7 * 9, 9 * 3, 9, 9); + } + if (i * 2 + 1 < food) blit(xo, yo, texBaseX + 4 * 9, 9 * 3, 9, 9); + if (i * 2 + 1 == food) blit(xo, yo, texBaseX + 5 * 9, 9 * 3, 9, 9); + } + + // render air bubbles + if (minecraft->player->isUnderLiquid(Material::water)) + { + int count = (int) ceil((minecraft->player->getAirSupply() - 2) * 10.0f / Player::TOTAL_AIR_SUPPLY); + int extra = (int) ceil((minecraft->player->getAirSupply()) * 10.0f / Player::TOTAL_AIR_SUPPLY) - count; + for (int i = 0; i < count + extra; i++) + { + // Air bubbles + if (i < count) blit(xRight - i * 8 - 9, yLine2, 16, 9 * 2, 9, 9); + else blit(xRight - i * 8 - 9, yLine2, 16 + 9, 9 * 2, 9, 9); + } + } + } + + } + + // 4J-PB - turn off the slot display if a xui menu is up + + //////////////////////////// + // render the slot contents + //////////////////////////// + if(bDisplayGui) + { + // glDisable(GL_BLEND); 4J - removed - we want to be able to fade our gui + + glEnable(GL_RESCALE_NORMAL); + + Lighting::turnOnGui(); + + + int x,y; + + for (int i = 0; i < 9; i++) + { + if(bTwoPlayerSplitscreen) + { + x = iWidthOffset + screenWidth / 2 - 9 * 10 + i * 20 + 2; + y = iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22; + } + else + { + x = screenWidth / 2 - 9 * 10 + i * 20 + 2; + y = screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22; + } + this->renderSlot(i, x, y, a); + } + Lighting::turnOff(); + glDisable(GL_RESCALE_NORMAL); + } +#endif // RENDER_HUD + + // 4J - do render of crouched player. This code is largely taken from the inventory render of the player, with some special hard-coded positions + // worked out by hand from the xui implementation of the crouch icon + + if(app.GetGameSettings(iPad,eGameSetting_AnimatedCharacter)) + { + //int playerIdx = minecraft->player->GetXboxPad(); + + static int characterDisplayTimer[4] = {0}; + if( !bDisplayGui ) + { + characterDisplayTimer[iPad] = 0; + } + else if( minecraft->player->isSneaking() ) + { + characterDisplayTimer[iPad] = 30; + } + else if( minecraft->player->isSprinting() ) + { + characterDisplayTimer[iPad] = 30; + } + else if( minecraft->player->abilities.flying) + { + characterDisplayTimer[iPad] = 5; // quickly get rid of the player display if they stop flying + } + else if( characterDisplayTimer[iPad] > 0 ) + { + --characterDisplayTimer[iPad]; + } + bool displayCrouch = minecraft->player->isSneaking() || ( characterDisplayTimer[iPad] > 0 ); + bool displaySprint = minecraft->player->isSprinting() || ( characterDisplayTimer[iPad] > 0 ); + bool displayFlying = minecraft->player->abilities.flying || ( characterDisplayTimer[iPad] > 0 ); + + if( bDisplayGui && (displayCrouch || displaySprint || displayFlying) ) + { + EntityRenderDispatcher::instance->prepare(minecraft->level, minecraft->textures, minecraft->font, minecraft->cameraTargetPlayer, minecraft->options, a); + glEnable(GL_RESCALE_NORMAL); + glEnable(GL_COLOR_MATERIAL); + + int xo = 0; + int yo = 0; + switch( minecraft->player->m_iScreenSection ) + { + case C4JRender::VIEWPORT_TYPE_FULLSCREEN: + default: + if(RenderManager.IsHiDef()) xo = -22; + yo = -36; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: + xo = 0; yo = -25; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: + xo = 0; yo = -48; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: + xo = 0; yo = -25; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: + xo = -43; yo = -25; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: + xo = 0; yo = -25; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: + xo = -43; yo = -25; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: + xo = 0; yo = -48; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: + xo = -43; yo = -48; + break; + } + glPushMatrix(); + glTranslatef((float)xo + 51, (float)yo + 75, 50); + float ss = 12; + glScalef(-ss, ss, ss); + glRotatef(180, 0, 0, 1); + + float oyr = minecraft->player->yRot; + float oyrO = minecraft->player->yRotO; + float oxr = minecraft->player->xRot; + int ofire = minecraft->player->onFire; + bool ofireflag = minecraft->player->getSharedFlag(Entity::FLAG_ONFIRE); + + float xd = -40; + float yd = 10; + + // 4J Stu - This is all based on the inventory player renderer, with changes to ensure that capes render correctly + // by minimising the changes to member variables of the player which are all related + + glRotatef(45 + 90, 0, 1, 0); + Lighting::turnOn(); + glRotatef(-45 - 90, 0, 1, 0); + + glRotatef(-(float) atan(yd / 40.0f ) * 20, 1, 0, 0); + float bodyRot = (minecraft->player->yBodyRotO + (minecraft->player->yBodyRot - minecraft->player->yBodyRotO)); + // Fixed rotation angle of degrees, adjusted by bodyRot to negate the rotation that occurs in the renderer + // bodyRot in the rotation below is a simplification of "180 - (180 - bodyRot)" where the first 180 is EntityRenderDispatcher::instance->playerRotY that we set below + // and (180 - bodyRot) is the angle of rotation that is performed within the mob renderer + glRotatef( bodyRot - ( (float) atan(xd / 40.0f) * 20), 0, 1, 0); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + // Set head rotation to body rotation to make head static + minecraft->player->yRot = bodyRot; + minecraft->player->yRotO = minecraft->player->yRot; + minecraft->player->xRot = -(float) atan(yd / 40.0f) * 20; + + minecraft->player->onFire = 0; + minecraft->player->setSharedFlag(Entity::FLAG_ONFIRE, false); + + glTranslatef(0, minecraft->player->heightOffset, 0); + EntityRenderDispatcher::instance->playerRotY = 180; + EntityRenderDispatcher::instance->isGuiRender = true; + EntityRenderDispatcher::instance->render(minecraft->player, 0, 0, 0, 0, 1); + EntityRenderDispatcher::instance->isGuiRender = false; + + minecraft->player->yRot = oyr; + minecraft->player->yRotO = oyrO; + minecraft->player->xRot = oxr; + minecraft->player->onFire = ofire; + minecraft->player->setSharedFlag(Entity::FLAG_ONFIRE,ofireflag); + glPopMatrix(); + Lighting::turnOff(); + glDisable(GL_RESCALE_NORMAL); + } + } + } + +#if RENDER_HUD + // Moved so the opacity blend is applied to it + if (bDisplayGui && minecraft->gameMode->hasExperience() && minecraft->player->experienceLevel > 0) + { + if (true) + { + bool blink = false; + int col = blink ? 0xffffff : 0x80ff20; + wchar_t formatted[10]; + swprintf(formatted, 10, L"%d",minecraft->player->experienceLevel); + + wstring str = formatted; + int x = iWidthOffset + (screenWidth - font->width(str)) / 2; + int y = screenHeight - iSafezoneYHalf - iTooltipsYOffset; + // If we're in creative mode, we don't need to offset the XP display so much + if (minecraft->gameMode->canHurtPlayer()) + { + y-=18; + } + else + { + y-=13; + } + + if(bTwoPlayerSplitscreen) + { + y+=iHeightOffset; + } + //int y = screenHeight - 31 - 4; + font->draw(str, x + 1, y, 0x000000); + font->draw(str, x - 1, y, 0x000000); + font->draw(str, x, y + 1, 0x000000); + font->draw(str, x, y - 1, 0x000000); + // font->draw(str, x + 1, y + 1, 0x000000); + // font->draw(str, x - 1, y + 1, 0x000000); + // font->draw(str, x + 1, y - 1, 0x000000); + // font->draw(str, x - 1, y - 1, 0x000000); + font->draw(str, x, y, col); + } + } +#endif // RENDER_HUD + + // 4J - added to disable blends, which we have enabled previously to allow gui fading + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // if the player is falling asleep we render a dark overlay + if (minecraft->player->getSleepTimer() > 0) + { + glDisable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + int timer = minecraft->player->getSleepTimer(); + float amount = (float) timer / (float) Player::SLEEP_DURATION; + if (amount > 1) + { + // waking up + amount = 1.0f - ((float) (timer - Player::SLEEP_DURATION) / (float) Player::WAKE_UP_DURATION); + } + + int color = (int) (220.0f * amount) << 24 | (0x101020); + fill(0, 0, screenWidth/fScaleFactorWidth, screenHeight/fScaleFactorHeight, color); + glEnable(GL_ALPHA_TEST); + glEnable(GL_DEPTH_TEST); + } + + // 4J-PB - Request from Mojang to have a red death screen + if (!minecraft->player->isAlive()) + { + glDisable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + int timer = minecraft->player->getDeathFadeTimer(); + float amount = (float) timer / (float) Player::DEATHFADE_DURATION; + + int color = (int) (220.0f * amount) << 24 | (0x200000); + fill(0, 0, screenWidth/fScaleFactorWidth, screenHeight/fScaleFactorHeight, color); + glEnable(GL_ALPHA_TEST); + glEnable(GL_DEPTH_TEST); + + } + + + // { + // String str = "" + minecraft.player.getFoodData().getExhaustionLevel() + ", " + minecraft.player.getFoodData().getSaturationLevel(); + // int x = (screenWidth - font.width(str)) / 2; + // int y = screenHeight - 64; + // font.draw(str, x + 1, y, 0xffffff); + // } + +#ifndef _FINAL_BUILD + MemSect(31); + if (minecraft->options->renderDebug) + { + glPushMatrix(); + if (Minecraft::warezTime > 0) glTranslatef(0, 32, 0); + font->drawShadow(ClientConstants::VERSION_STRING + L" (" + minecraft->fpsString + L")", iSafezoneXHalf+2, 20, 0xffffff); + font->drawShadow(L"Seed: " + _toString<__int64>(minecraft->level->getLevelData()->getSeed() ), iSafezoneXHalf+2, 32 + 00, 0xffffff); + font->drawShadow(minecraft->gatherStats1(), iSafezoneXHalf+2, 32 + 10, 0xffffff); + font->drawShadow(minecraft->gatherStats2(), iSafezoneXHalf+2, 32 + 20, 0xffffff); + font->drawShadow(minecraft->gatherStats3(), iSafezoneXHalf+2, 32 + 30, 0xffffff); + font->drawShadow(minecraft->gatherStats4(), iSafezoneXHalf+2, 32 + 40, 0xffffff); + + // TERRAIN FEATURES + int iYPos=82; + + if(minecraft->level->dimension->id==0) + { + wstring wfeature[eTerrainFeature_Count]; + + wfeature[eTerrainFeature_Stronghold] = L"Stronghold: "; + wfeature[eTerrainFeature_Mineshaft] = L"Mineshaft: "; + wfeature[eTerrainFeature_Village] = L"Village: "; + wfeature[eTerrainFeature_Ravine] = L"Ravine: "; + + for(int i=0;i<app.m_vTerrainFeatures.size();i++) + { + FEATURE_DATA *pFeatureData=app.m_vTerrainFeatures[i]; + + wstring itemInfo = L"[" + _toString<int>( pFeatureData->x*16 ) + L", " + _toString<int>( pFeatureData->z*16 ) + L"] "; + wfeature[pFeatureData->eTerrainFeature] += itemInfo; + } + + for( int i = eTerrainFeature_Stronghold; i < (int) eTerrainFeature_Count; i++ ) + { + font->drawShadow(wfeature[i], iSafezoneXHalf + 2, iYPos, 0xffffff); + iYPos+=10; + } + } + + //font->drawShadow(minecraft->gatherStats5(), iSafezoneXHalf+2, 32 + 10, 0xffffff); + { + /* 4J - removed + long max = Runtime.getRuntime().maxMemory(); + long total = Runtime.getRuntime().totalMemory(); + long free = Runtime.getRuntime().freeMemory(); + long used = total - free; + String msg = "Used memory: " + (used * 100 / max) + "% (" + (used / 1024 / 1024) + "MB) of " + (max / 1024 / 1024) + "MB"; + drawString(font, msg, screenWidth - font.width(msg) - 2, 2, 0xe0e0e0); + msg = "Allocated memory: " + (total * 100 / max) + "% (" + (total / 1024 / 1024) + "MB)"; + drawString(font, msg, screenWidth - font.width(msg) - 2, 12, 0xe0e0e0); + */ + } + // 4J Stu - Moved these so that they don't overlap + double xBlockPos = floor(minecraft->player->x); + double yBlockPos = floor(minecraft->player->y); + double zBlockPos = floor(minecraft->player->z); + drawString(font, L"x: " + _toString<double>(minecraft->player->x) + L"/ Head: " + _toString<double>(xBlockPos) + L"/ Chunk: " + _toString<double>(minecraft->player->xChunk), iSafezoneXHalf+2, iYPos + 8 * 0, 0xe0e0e0); + drawString(font, L"y: " + _toString<double>(minecraft->player->y) + L"/ Head: " + _toString<double>(yBlockPos), iSafezoneXHalf+2, iYPos + 8 * 1, 0xe0e0e0); + drawString(font, L"z: " + _toString<double>(minecraft->player->z) + L"/ Head: " + _toString<double>(zBlockPos) + L"/ Chunk: " + _toString<double>(minecraft->player->zChunk), iSafezoneXHalf+2, iYPos + 8 * 2, 0xe0e0e0); + drawString(font, L"f: " + _toString<double>(Mth::floor(minecraft->player->yRot * 4.0f / 360.0f + 0.5) & 0x3) + L"/ yRot: " + _toString<double>(minecraft->player->yRot), iSafezoneXHalf+2, iYPos + 8 * 3, 0xe0e0e0); + iYPos += 8*4; + + int px = Mth::floor(minecraft->player->x); + int py = Mth::floor(minecraft->player->y); + int pz = Mth::floor(minecraft->player->z); + if (minecraft->level != NULL && minecraft->level->hasChunkAt(px, py, pz)) + { + LevelChunk *chunkAt = minecraft->level->getChunkAt(px, pz); + Biome *biome = chunkAt->getBiome(px & 15, pz & 15, minecraft->level->getBiomeSource()); + drawString( + font, + L"b: " + biome->m_name + L" (" + _toString<int>(biome->id) + L")", iSafezoneXHalf+2, iYPos, 0xe0e0e0); + } + + glPopMatrix(); + } + MemSect(0); +#endif + + lastTickA = a; + // 4J Stu - This is now displayed in a xui scene +#if 0 + // Jukebox CD message + if (overlayMessageTime > 0) + { + float t = overlayMessageTime - a; + int alpha = (int) (t * 256 / 20); + if (alpha > 255) alpha = 255; + if (alpha > 0) + { + glPushMatrix(); + + if(bTwoPlayerSplitscreen) + { + glTranslatef((float)((screenWidth / 2)+iWidthOffset), ((float)(screenHeight+iHeightOffset)) - iTooltipsYOffset -12 -iSafezoneYHalf, 0); + } + else + { + glTranslatef(((float)screenWidth) / 2, ((float)screenHeight) - iTooltipsYOffset - 12 -iSafezoneYHalf, 0); + } + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + int col = 0xffffff; + if (animateOverlayMessageColor) + { + col = Color::HSBtoRGB(t / 50.0f, 0.7f, 0.6f) & 0xffffff; + } + // 4J-PB - this is the string displayed when cds are placed in a jukebox + font->draw(overlayMessageString,-font->width(overlayMessageString) / 2, -20, col + (alpha << 24)); + glDisable(GL_BLEND); + glPopMatrix(); + } + } +#endif + + unsigned int max = 10; + bool isChatting = false; + if (dynamic_cast<ChatScreen *>(minecraft->screen) != NULL) + { + max = 20; + isChatting = true; + } + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_ALPHA_TEST); + +// 4J Stu - We have moved the chat text to a xui +#if 0 + glPushMatrix(); + // 4J-PB we need to move this up a bit because we've moved the quick select + //glTranslatef(0, ((float)screenHeight) - 48, 0); + glTranslatef(0.0f, (float)(screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22) - 24.0f, 0.0f); + // glScalef(1.0f / ssc.scale, 1.0f / ssc.scale, 1); + + // 4J-PB - we need gui messages for each of the possible 4 splitscreen players + if(bDisplayGui) + { + int iPad=minecraft->player->GetXboxPad(); + for (unsigned int i = 0; i < guiMessages[iPad].size() && i < max; i++) + { + if (guiMessages[iPad][i].ticks < 20 * 10 || isChatting) + { + double t = guiMessages[iPad][i].ticks / (20 * 10.0); + t = 1 - t; + t = t * 10; + if (t < 0) t = 0; + if (t > 1) t = 1; + t = t * t; + int alpha = (int) (255 * t); + if (isChatting) alpha = 255; + + if (alpha > 0) + { + int x = iSafezoneXHalf+2; + int y = -((int)i) * 9; + if(bTwoPlayerSplitscreen) + { + y+= iHeightOffset; + } + + wstring msg = guiMessages[iPad][i].string; + // 4J-PB - fill the black bar across the whole screen, otherwise it looks odd due to the safe area + this->fill(0, y - 1, screenWidth/fScaleFactorWidth, y + 8, (alpha / 2) << 24); + glEnable(GL_BLEND); + + font->drawShadow(msg, iSafezoneXHalf+4, y, 0xffffff + (alpha << 24)); + } + } + } + } + glPopMatrix(); +#endif + + // 4J Stu - Copied over but not used +#if 0 + if (minecraft.player instanceof MultiplayerLocalPlayer && minecraft.options.keyPlayerList.isDown) + { + ClientConnection connection = ((MultiplayerLocalPlayer) minecraft.player).connection; + List<PlayerInfo> playerInfos = connection.playerInfos; + int slots = connection.maxPlayers; + + int rows = slots; + int cols = 1; + while (rows > 20) { + cols++; + rows = (slots + cols - 1) / cols; + } + + /* + * int fakeCount = 39; while (playerInfos.size() > fakeCount) + * playerInfos.remove(playerInfos.size() - 1); while (playerInfos.size() < + * fakeCount) playerInfos.add(new PlayerInfo("fiddle")); + */ + + int slotWidth = 300 / cols; + if (slotWidth > 150) slotWidth = 150; + + int xxo = (screenWidth - cols * slotWidth) / 2; + int yyo = 10; + fill(xxo - 1, yyo - 1, xxo + slotWidth * cols, yyo + 9 * rows, 0x80000000); + for (int i = 0; i < slots; i++) { + int xo = xxo + i % cols * slotWidth; + int yo = yyo + i / cols * 9; + + fill(xo, yo, xo + slotWidth - 1, yo + 8, 0x20ffffff); + glColor4f(1, 1, 1, 1); + glEnable(GL_ALPHA_TEST); + + if (i < playerInfos.size()) { + PlayerInfo pl = playerInfos.get(i); + font.drawShadow(pl.name, xo, yo, 0xffffff); + minecraft.textures.bind(minecraft.textures.loadTexture("/gui/icons.png")); + int xt = 0; + int yt = 0; + xt = 0; + yt = 0; + if (pl.latency < 0) yt = 5; + else if (pl.latency < 150) yt = 0; + else if (pl.latency < 300) yt = 1; + else if (pl.latency < 600) yt = 2; + else if (pl.latency < 1000) yt = 3; + else yt = 4; + + blitOffset += 100; + blit(xo + slotWidth - 12, yo, 0 + xt * 10, 176 + yt * 8, 10, 8); + blitOffset -= 100; + } + } + } +#endif + + if(bDisplayGui && bTwoPlayerSplitscreen) + { + // pop the scaled matrix + glPopMatrix(); + } + + glColor4f(1, 1, 1, 1); + glDisable(GL_BLEND); + glEnable(GL_ALPHA_TEST); +} + +// Moved to the xui base scene +// void Gui::renderBossHealth(void) +// { +// if (EnderDragonRenderer::bossInstance == NULL) return; +// +// shared_ptr<EnderDragon> boss = EnderDragonRenderer::bossInstance; +// EnderDragonRenderer::bossInstance = NULL; +// +// Minecraft *pMinecraft=Minecraft::GetInstance(); +// +// Font *font = pMinecraft->font; +// +// ScreenSizeCalculator ssc(pMinecraft->options, pMinecraft->width_phys, pMinecraft->height_phys); +// int screenWidth = ssc.getWidth(); +// +// int w = 182; +// int xLeft = screenWidth / 2 - w / 2; +// +// int progress = (int) (boss->getSynchedHealth() / (float) boss->getMaxHealth() * (float) (w + 1)); +// +// int yo = 12; +// blit(xLeft, yo, 0, 74, w, 5); +// blit(xLeft, yo, 0, 74, w, 5); +// if (progress > 0) +// { +// blit(xLeft, yo, 0, 79, progress, 5); +// } +// +// wstring msg = L"Boss health - NON LOCALISED"; +// font->drawShadow(msg, screenWidth / 2 - font->width(msg) / 2, yo - 10, 0xff00ff); +// glColor4f(1, 1, 1, 1); +// glBindTexture(GL_TEXTURE_2D, pMinecraft->textures->loadTexture(TN_GUI_ICONS) );//"/gui/icons.png")); +// +// } + +void Gui::renderPumpkin(int w, int h) +{ + glDisable(GL_DEPTH_TEST); + glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(1, 1, 1, 1); + glDisable(GL_ALPHA_TEST); + + MemSect(31); + minecraft->textures->bindTexture(TN__BLUR__MISC_PUMPKINBLUR);//L"%blur%/misc/pumpkinblur.png")); + MemSect(0); + Tesselator *t = Tesselator::getInstance(); + t->begin(); + t->vertexUV((float)(0), (float)( h), (float)( -90), (float)( 0), (float)( 1)); + t->vertexUV((float)(w), (float)( h), (float)( -90), (float)( 1), (float)( 1)); + t->vertexUV((float)(w), (float)( 0), (float)( -90), (float)( 1), (float)( 0)); + t->vertexUV((float)(0), (float)( 0), (float)( -90), (float)( 0), (float)( 0)); + t->end(); + glDepthMask(true); + glEnable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); + glColor4f(1, 1, 1, 1); + +} + +void Gui::renderVignette(float br, int w, int h) +{ + br = 1 - br; + if (br < 0) br = 0; + if (br > 1) br = 1; + tbr += (br - tbr) * 0.01f; + +#if 0 // 4J - removed - TODO put back when we have blend functions implemented + glDisable(GL_DEPTH_TEST); + glDepthMask(false); + glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); + glColor4f(tbr, tbr, tbr, 1); + glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture(TN__BLUR__MISC_VIGNETTE));//L"%blur%/misc/vignette.png")); + Tesselator *t = Tesselator::getInstance(); + t->begin(); + t->vertexUV((float)(0), (float)( h), (float)( -90), (float)( 0), (float)( 1)); + t->vertexUV((float)(w), (float)( h), (float)( -90), (float)( 1), (float)( 1)); + t->vertexUV((float)(w), (float)( 0), (float)( -90), (float)( 1), (float)( 0)); + t->vertexUV((float)(0), (float)( 0), (float)( -90), (float)( 0), (float)( 0)); + t->end(); + glDepthMask(true); + glEnable(GL_DEPTH_TEST); + glColor4f(1, 1, 1, 1); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +#endif +} + +void Gui::renderTp(float br, int w, int h) +{ + if (br < 1) + { + br = br * br; + br = br * br; + br = br * 0.8f + 0.2f; + } + + glDisable(GL_ALPHA_TEST); + glDisable(GL_DEPTH_TEST); + glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(1, 1, 1, br); + MemSect(31); + minecraft->textures->bindTexture(TN_TERRAIN);//L"/terrain.png")); + MemSect(0); + + Icon *slot = Tile::portalTile->getTexture(Facing::UP); + float u0 = slot->getU0(); + float v0 = slot->getV0(); + float u1 = slot->getU1(); + float v1 = slot->getV1(); + Tesselator *t = Tesselator::getInstance(); + t->begin(); + t->vertexUV((float)(0), (float)( h), (float)( -90), (float)( u0), (float)( v1)); + t->vertexUV((float)(w), (float)( h), (float)( -90), (float)( u1), (float)( v1)); + t->vertexUV((float)(w), (float)( 0), (float)( -90), (float)( u1), (float)( v0)); + t->vertexUV((float)(0), (float)( 0), (float)( -90), (float)( u0), (float)( v0)); + t->end(); + glDepthMask(true); + glEnable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); + glColor4f(1, 1, 1, 1); + +} + +void Gui::renderSlot(int slot, int x, int y, float a) +{ + shared_ptr<ItemInstance> item = minecraft->player->inventory->items[slot]; + if (item == NULL) return; + + float pop = item->popTime - a; + if (pop > 0) + { + glPushMatrix(); + float squeeze = 1 + pop / (float) Inventory::POP_TIME_DURATION; + glTranslatef((float)(x + 8), (float)(y + 12), 0); + glScalef(1 / squeeze, (squeeze + 1) / 2, 1); + glTranslatef((float)-(x + 8), (float)-(y + 12), 0); + } + + itemRenderer->renderAndDecorateItem(minecraft->font, minecraft->textures, item, x, y); + + if (pop > 0) + { + glPopMatrix(); + } + + itemRenderer->renderGuiItemDecorations(minecraft->font, minecraft->textures, item, x, y); + +} + +void Gui::tick() +{ + if (overlayMessageTime > 0) overlayMessageTime--; + tickCount++; + + for(int iPad=0;iPad<XUSER_MAX_COUNT;iPad++) + { + // 4J Stu - Fix for #10929 - MP LAB: Network Disconnects: Host does not receive an error message stating the client left the game when viewing the Pause Menu. + // We don't show the guiMessages when a menu is up, so don't fade them out + if(!ui.GetMenuDisplayed(iPad)) + { + AUTO_VAR(itEnd, guiMessages[iPad].end()); + for (AUTO_VAR(it, guiMessages[iPad].begin()); it != itEnd; it++) + { + (*it).ticks++; + } + } + } +} + +void Gui::clearMessages(int iPad) +{ + if(iPad==-1) + { + for(int i=0;i<XUSER_MAX_COUNT;i++) + { + if(minecraft->localplayers[i]) + { + guiMessages[i].clear(); + } + } + } + else + { + guiMessages[iPad].clear(); + } +} + + +void Gui::addMessage(const wstring& _string,int iPad,bool bIsDeathMessage) +{ + wstring string = _string; // 4J - Take copy of input as it is const + //int iScale=1; + + //if((minecraft->player->m_iScreenSection==C4JRender::VIEWPORT_TYPE_SPLIT_TOP) || + // (minecraft->player->m_iScreenSection==C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM)) + //{ + // iScale=2; + //} + + // while (minecraft->font->width(string) > (m_iMaxMessageWidth*iScale)) + //{ + // unsigned int i = 1; + // while (i < string.length() && minecraft->font->width(string.substr(0, i + 1)) <= (m_iMaxMessageWidth*iScale)) + // { + // i++; + // } + // int iLast=string.find_last_of(L" ",i); + + // // if a space was found, include the space on this line + // if(iLast!=i) + // { + // iLast++; + // } + // addMessage(string.substr(0, iLast), iPad); + // string = string.substr(iLast); + // } + + int maximumChars; + + switch(minecraft->player->m_iScreenSection) + { + case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: + case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: + case C4JRender::VIEWPORT_TYPE_FULLSCREEN: + if(RenderManager.IsHiDef()) + { + maximumChars = 105; + } + else + { + maximumChars = 55; + } +#ifdef __PSVITA__ + maximumChars = 90; +#endif + switch(XGetLanguage()) + { + case XC_LANGUAGE_JAPANESE: + case XC_LANGUAGE_TCHINESE: + case XC_LANGUAGE_KOREAN: + if(RenderManager.IsHiDef()) + { + maximumChars = 70; + } + else + { + maximumChars = 35; + } +#ifdef __PSVITA__ + maximumChars = 55; +#endif + break; + } + break; + default: + maximumChars = 55; + switch(XGetLanguage()) + { + case XC_LANGUAGE_JAPANESE: + case XC_LANGUAGE_TCHINESE: + case XC_LANGUAGE_KOREAN: + maximumChars = 35; + break; + } + break; + } + + + while (string.length() > maximumChars) + { + unsigned int i = 1; + while (i < string.length() && (i + 1) <= maximumChars) + { + i++; + } + int iLast=(int)string.find_last_of(L" ",i); + switch(XGetLanguage()) + { + case XC_LANGUAGE_JAPANESE: + case XC_LANGUAGE_TCHINESE: + case XC_LANGUAGE_KOREAN: + iLast = maximumChars; + break; + default: + iLast=(int)string.find_last_of(L" ",i); + break; + } + + // if a space was found, include the space on this line + if(iLast!=i) + { + iLast++; + } + addMessage(string.substr(0, iLast), iPad, bIsDeathMessage); + string = string.substr(iLast); + } + + if(iPad==-1) + { + // add to all + for(int i=0;i<XUSER_MAX_COUNT;i++) + { + if(minecraft->localplayers[i] && !(bIsDeathMessage && app.GetGameSettings(i,eGameSetting_DeathMessages)==0)) + { + guiMessages[i].insert(guiMessages[i].begin(), GuiMessage(string)); + while (guiMessages[i].size() > 50) + { + guiMessages[i].pop_back(); + } + } + } + } + else if(!(bIsDeathMessage && app.GetGameSettings(iPad,eGameSetting_DeathMessages)==0)) + { + guiMessages[iPad].insert(guiMessages[iPad].begin(), GuiMessage(string)); + while (guiMessages[iPad].size() > 50) + { + guiMessages[iPad].pop_back(); + } + } + + +} + +// 4J Added +float Gui::getOpacity(int iPad, DWORD index) +{ + float opacityPercentage = 0; + if (guiMessages[iPad].size() > index && guiMessages[iPad][index].ticks < 20 * 10) + { + double t = guiMessages[iPad][index].ticks / (20 * 10.0); + t = 1 - t; + t = t * 10; + if (t < 0) t = 0; + if (t > 1) t = 1; + t = t * t; + opacityPercentage = t; + } + return opacityPercentage; +} + +float Gui::getJukeboxOpacity(int iPad) +{ + float t = overlayMessageTime - lastTickA; + int alpha = (int) (t * 256 / 20); + if (alpha > 255) alpha = 255; + alpha /= 255; + + return alpha; +} + +void Gui::setNowPlaying(const wstring& string) +{ +// overlayMessageString = L"Now playing: " + string; + overlayMessageString = app.GetString(IDS_NOWPLAYING) + string; + overlayMessageTime = 20 * 3; + animateOverlayMessageColor = true; +} + +void Gui::displayClientMessage(int messageId, int iPad) +{ + //Language *language = Language::getInstance(); + wstring languageString = app.GetString(messageId);//language->getElement(messageId); + + addMessage(languageString, iPad); +} + +// 4J Added +void Gui::renderGraph(int dataLength, int dataPos, __int64 *dataA, float dataAScale, int dataAWarning, __int64 *dataB, float dataBScale, int dataBWarning) +{ + int height = minecraft->height; + // This causes us to cover xScale*dataLength pixels in the horizontal + int xScale = 1; + if(dataA != NULL && dataB != NULL) xScale = 2; + + glClear(GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, (float)minecraft->width, (float)height, 0, 1000, 3000); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -2000); + + glLineWidth(1); + glDisable(GL_TEXTURE_2D); + Tesselator *t = Tesselator::getInstance(); + + t->begin(GL_LINES); + for (int i = 0; i < dataLength; i++) + { + int col = ((i - dataPos) & (dataLength - 1)) * 255 / dataLength; + int cc = col * col / 255; + cc = cc * cc / 255; + int cc2 = cc * cc / 255; + cc2 = cc2 * cc2 / 255; + + if( dataA != NULL ) + { + if (dataA[i] > dataAWarning) + { + t->color(0xff000000 + cc * 65536); + } + else + { + t->color(0xff000000 + cc * 256); + } + + __int64 aVal = dataA[i] / dataAScale; + + t->vertex((float)(xScale*i + 0.5f), (float)( height - aVal + 0.5f), (float)( 0)); + t->vertex((float)(xScale*i + 0.5f), (float)( height + 0.5f), (float)( 0)); + } + + if( dataB != NULL ) + { + if (dataB[i]>dataBWarning) + { + t->color(0xff000000 + cc * 65536 + cc * 256 + cc * 1); + } + else + { + t->color(0xff808080 + cc/2 * 256); + } + + __int64 bVal = dataB[i] / dataBScale; + + t->vertex((float)(xScale*i + (xScale - 1) + 0.5f), (float)( height - bVal + 0.5f), (float)( 0)); + t->vertex((float)(xScale*i + (xScale - 1) + 0.5f), (float)( height + 0.5f), (float)( 0)); + } + } + t->end(); + + glEnable(GL_TEXTURE_2D); +} + +void Gui::renderStackedGraph(int dataPos, int dataLength, int dataSources, __int64 (*func)(unsigned int dataPos, unsigned int dataSource) ) +{ + int height = minecraft->height; + + glClear(GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, (float)minecraft->width, (float)height, 0, 1000, 3000); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -2000); + + glLineWidth(1); + glDisable(GL_TEXTURE_2D); + Tesselator *t = Tesselator::getInstance(); + + t->begin(GL_LINES); + __int64 thisVal = 0; + __int64 topVal = 0; + for (int i = 0; i < dataLength; i++) + { + thisVal = 0; + topVal = 0; + int col = ((i - dataPos) & (dataLength - 1)) * 255 / dataLength; + int cc = col * col / 255; + cc = cc * cc / 255; + int cc2 = cc * cc / 255; + cc2 = cc2 * cc2 / 255; + + + for(unsigned int source = 0; source < dataSources; ++source ) + { + thisVal = func( i, source ); + + if( thisVal > 0 ) + { + float vary = (float)source/dataSources; + int fColour = floor(vary * 0xffffff); + + int colour = 0xff000000 + fColour; + //printf("Colour is %x\n", colour); + t->color(colour); + + t->vertex((float)(i + 0.5f), (float)( height - topVal - thisVal + 0.5f), (float)( 0)); + t->vertex((float)(i + 0.5f), (float)( height - topVal + 0.5f), (float)( 0)); + + topVal += thisVal; + } + } + + // Draw some horizontals + for(unsigned int horiz = 1; horiz < 7; ++horiz ) + { + t->color(0xff000000); + + t->vertex((float)(0 + 0.5f), (float)( height - (horiz*100) + 0.5f), (float)( 0)); + t->vertex((float)(dataLength + 0.5f), (float)( height - (horiz*100) + 0.5f), (float)( 0)); + } + } + t->end(); + + glEnable(GL_TEXTURE_2D); +} |
