the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "Gui.h"
3#include "ItemRenderer.h"
4#include "GameRenderer.h"
5#include "Options.h"
6#include "MultiplayerLocalPlayer.h"
7#include "Textures.h"
8#include "TextureAtlas.h"
9#include "GameMode.h"
10#include "Lighting.h"
11#include "ChatScreen.h"
12#include "MultiPlayerLevel.h"
13#include "..\Minecraft.World\JavaMath.h"
14#include "..\Minecraft.World\net.minecraft.world.entity.player.h"
15#include "..\Minecraft.World\net.minecraft.world.effect.h"
16#include "..\Minecraft.World\net.minecraft.world.food.h"
17#include "..\Minecraft.World\net.minecraft.world.item.h"
18#include "..\Minecraft.World\net.minecraft.world.level.h"
19#include "..\Minecraft.World\LevelData.h"
20#include "..\Minecraft.World\net.minecraft.world.level.tile.h"
21#include "..\Minecraft.World\System.h"
22#include "..\Minecraft.World\Language.h"
23#include "EntityRenderDispatcher.h"
24#include "..\Minecraft.World\Dimension.h"
25#include "..\Minecraft.World\net.minecraft.world.entity.boss.enderdragon.h"
26#include "EnderDragonRenderer.h"
27#include "..\Minecraft.World\net.minecraft.h"
28#include "..\Minecraft.World\net.minecraft.world.h"
29#include "..\Minecraft.World\LevelChunk.h"
30#include "..\Minecraft.World\Biome.h"
31
32ResourceLocation Gui::PUMPKIN_BLUR_LOCATION = ResourceLocation(TN__BLUR__MISC_PUMPKINBLUR);
33
34#define RENDER_HUD 0
35//#ifndef _XBOX
36//#undef RENDER_HUD
37//#define RENDER_HUD 1
38//#endif
39
40float Gui::currentGuiBlendFactor = 1.0f; // 4J added
41float Gui::currentGuiScaleFactor = 1.0f; // 4J added
42ItemRenderer *Gui::itemRenderer = new ItemRenderer();
43
44Gui::Gui(Minecraft *minecraft)
45{
46 // 4J - initialisers added
47 random = new Random();
48 tickCount = 0;
49 overlayMessageTime = 0;
50 animateOverlayMessageColor = false;
51 progress = 0.0f;
52 tbr = 1.0f;
53 fAlphaIncrementPerCent=255.0f/100.0f;
54
55 this->minecraft = minecraft;
56
57 lastTickA = 0.0f;
58}
59
60void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
61{
62 // 4J Stu - I have copied this code for XUI_BaseScene. If/when it gets changed it should be broken out
63 // 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
64 // happens in split screen modes results in a final scaling of 1 rather than 1.5.
65 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
66 int guiScale;// = ( minecraft->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_FULLSCREEN ? 3 : 2 );
67 int iPad=minecraft->player->GetXboxPad();
68 int iWidthOffset=0,iHeightOffset=0; // used to get the interface looking right on a 2 player split screen game
69
70 // 4J-PB - selected the gui scale based on the slider settings
71 if(minecraft->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_FULLSCREEN)
72 {
73 guiScale=app.GetGameSettings(iPad,eGameSetting_UISize) + 2;
74 }
75 else
76 {
77 guiScale=app.GetGameSettings(iPad,eGameSetting_UISizeSplitscreen) + 2;
78 }
79
80
81 ScreenSizeCalculator ssc(minecraft->options, minecraft->width, minecraft->height, guiScale );
82 int screenWidth = ssc.getWidth();
83 int screenHeight = ssc.getHeight();
84 int iSafezoneXHalf=0,iSafezoneYHalf=0,iSafezoneTopYHalf=0;
85 int iTooltipsYOffset=0;
86 int quickSelectWidth=182;
87 int quickSelectHeight=22;
88 float fScaleFactorWidth=1.0f,fScaleFactorHeight=1.0f;
89 bool bTwoPlayerSplitscreen=false;
90 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
91
92 switch(guiScale)
93 {
94 case 3:
95 splitYOffset = 0;
96 break;
97 case 4:
98 splitYOffset = -5;
99 break;
100 default: // 2
101 splitYOffset = 10;
102 break;
103 }
104
105 // Check which screen section this player is in
106 switch(minecraft->player->m_iScreenSection)
107 {
108 case C4JRender::VIEWPORT_TYPE_FULLSCREEN:
109 // single player
110 iSafezoneXHalf = screenWidth/20; // 5%
111 iSafezoneYHalf = screenHeight/20; // 5%
112 iSafezoneTopYHalf = iSafezoneYHalf;
113 iTooltipsYOffset=40+splitYOffset;
114 break;
115 case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
116 iSafezoneXHalf = screenWidth/10; // 5% (need to treat the whole screen is 2x this screen)
117 iSafezoneYHalf = splitYOffset;
118 iSafezoneTopYHalf = screenHeight/10;
119 fScaleFactorWidth=0.5f;
120 iWidthOffset=(int)((float)screenWidth*(1.0f - fScaleFactorWidth));
121 iTooltipsYOffset=44;
122 bTwoPlayerSplitscreen=true;
123 currentGuiScaleFactor *= 0.5f;
124 break;
125 case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
126 iSafezoneXHalf = screenWidth/10; // 5% (need to treat the whole screen is 2x this screen)
127 iSafezoneYHalf = splitYOffset + screenHeight/10;// 5% (need to treat the whole screen is 2x this screen)
128 iSafezoneTopYHalf = 0;
129 fScaleFactorWidth=0.5f;
130 iWidthOffset=(int)((float)screenWidth*(1.0f - fScaleFactorWidth));
131 iTooltipsYOffset=44;
132 bTwoPlayerSplitscreen=true;
133 currentGuiScaleFactor *= 0.5f;
134 break;
135 case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
136 iSafezoneXHalf = screenWidth/10; // 5% (the whole screen is 2x this screen)
137 iSafezoneYHalf = splitYOffset + screenHeight/10;// 5% (need to treat the whole screen is 2x this screen)
138 iSafezoneTopYHalf = screenHeight/10;
139 fScaleFactorHeight=0.5f;
140 iHeightOffset=screenHeight;
141 iTooltipsYOffset=44;
142 bTwoPlayerSplitscreen=true;
143 currentGuiScaleFactor *= 0.5f;
144 break;
145 case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
146 iSafezoneXHalf = 0;
147 iSafezoneYHalf = splitYOffset + screenHeight/10;// 5% (need to treat the whole screen is 2x this screen)
148 iSafezoneTopYHalf = splitYOffset + screenHeight/10;
149 fScaleFactorHeight=0.5f;
150 iHeightOffset=screenHeight;
151 iTooltipsYOffset=44;
152 bTwoPlayerSplitscreen=true;
153 currentGuiScaleFactor *= 0.5f;
154 break;
155 case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
156 iSafezoneXHalf = screenWidth/10; // 5% (the whole screen is 2x this screen)
157 iSafezoneYHalf = splitYOffset;
158 iSafezoneTopYHalf = screenHeight/10;
159 iTooltipsYOffset=44;
160 currentGuiScaleFactor *= 0.5f;
161 break;
162 case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
163 iSafezoneXHalf = 0;
164 iSafezoneYHalf = splitYOffset; // 5%
165 iSafezoneTopYHalf = screenHeight/10;
166 iTooltipsYOffset=44;
167 currentGuiScaleFactor *= 0.5f;
168 break;
169 case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
170 iSafezoneXHalf = screenWidth/10; // 5% (the whole screen is 2x this screen)
171 iSafezoneYHalf = splitYOffset + screenHeight/10; // 5% (the whole screen is 2x this screen)
172 iSafezoneTopYHalf = 0;
173 iTooltipsYOffset=44;
174 currentGuiScaleFactor *= 0.5f;
175 break;
176 case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
177 iSafezoneXHalf = 0;
178 iSafezoneYHalf = splitYOffset + screenHeight/10; // 5% (the whole screen is 2x this screen)
179 iSafezoneTopYHalf = 0;
180 iTooltipsYOffset=44;
181 currentGuiScaleFactor *= 0.5f;
182 break;
183
184 }
185
186 // 4J-PB - turn off the slot display if a xui menu is up, or if we're autosaving
187 bool bDisplayGui=!ui.GetMenuDisplayed(iPad) && !(app.GetXuiAction(iPad)==eAppAction_AutosaveSaveGameCapturedThumbnail);
188
189 // if tooltips are off, set the y offset to zero
190 if(app.GetGameSettings(iPad,eGameSetting_Tooltips)==0 && bDisplayGui)
191 {
192 switch(minecraft->player->m_iScreenSection)
193 {
194 case C4JRender::VIEWPORT_TYPE_FULLSCREEN:
195 iTooltipsYOffset=screenHeight/10;
196 break;
197 default:
198 //iTooltipsYOffset=screenHeight/10;
199 switch(guiScale)
200 {
201 case 3:
202 iTooltipsYOffset=28;//screenHeight/10;
203 break;
204 case 4:
205 iTooltipsYOffset=28;//screenHeight/10;
206 break;
207 default: // 2
208 iTooltipsYOffset=14;//screenHeight/10;
209 break;
210 }
211 break;
212 }
213 }
214
215 // 4J-PB - Turn off interface if eGameSetting_DisplayHUD is off - for screen shots/videos.
216 if ( app.GetGameSettings(iPad,eGameSetting_DisplayHUD)==0 )
217 {
218 bDisplayGui = false;
219 }
220
221 Font *font = minecraft->font;
222
223
224 minecraft->gameRenderer->setupGuiScreen(guiScale);
225
226
227
228 glEnable(GL_BLEND);
229 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
230
231 if (Minecraft::useFancyGraphics())
232 {
233 renderVignette(minecraft->player->getBrightness(a), screenWidth, screenHeight);
234 }
235
236 /////////////////////////////////////////////////////////////////////////////////////
237 // Display the pumpkin screen effect
238 /////////////////////////////////////////////////////////////////////////////////////
239
240 shared_ptr<ItemInstance> headGear = minecraft->player->inventory->getArmor(3);
241
242 // 4J-PB - changing this to be per player
243 //if (!minecraft->options->thirdPersonView && headGear != NULL && headGear->id == Tile::pumpkin_Id) renderPumpkin(screenWidth, screenHeight);
244 if ((minecraft->player->ThirdPersonView()==0) && headGear != NULL && headGear->id == Tile::pumpkin_Id) renderPumpkin(screenWidth, screenHeight);
245 if (!minecraft->player->hasEffect(MobEffect::confusion))
246 {
247 float pt = minecraft->player->oPortalTime + (minecraft->player->portalTime - minecraft->player->oPortalTime) * a;
248 if (pt > 0)
249 {
250 renderTp(pt, screenWidth, screenHeight);
251 }
252 }
253
254 if (!minecraft->gameMode->isCutScene())
255 {
256 if(bDisplayGui && bTwoPlayerSplitscreen)
257 {
258 // need to apply scale factors depending on the mode
259 glPushMatrix();
260 glScalef(fScaleFactorWidth, fScaleFactorHeight, fScaleFactorWidth);
261 }
262#if RENDER_HUD
263 /////////////////////////////////////////////////////////////////////////////////////
264 // Display the quick select background, the quick select selection, and the crosshair
265 /////////////////////////////////////////////////////////////////////////////////////
266
267 glColor4f(1, 1, 1, 1);
268
269 // 4J - this is where to set the blend factor for gui things
270 // use the primary player's settings
271 unsigned char ucAlpha=app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_InterfaceOpacity);
272
273 // If the user has started to navigate their quickselect bar, ignore the alpha setting, and display at default value
274 float fVal=fAlphaIncrementPerCent*(float)ucAlpha;
275 if(ucAlpha<80)
276 {
277 // check if we have the timer running for the opacity
278 unsigned int uiOpacityTimer=app.GetOpacityTimer(iPad);
279 if(uiOpacityTimer!=0)
280 {
281 if(uiOpacityTimer<10)
282 {
283 float fStep=(80.0f-(float)ucAlpha)/10.0f;
284 fVal=fAlphaIncrementPerCent*(80.0f-((10.0f-(float)uiOpacityTimer)*fStep));
285 }
286 else
287 {
288 fVal=fAlphaIncrementPerCent*80.0f;
289 }
290 }
291 else
292 {
293 fVal=fAlphaIncrementPerCent*(float)ucAlpha;
294 }
295 }
296 else
297 {
298 fVal=fAlphaIncrementPerCent*(float)ucAlpha;
299 }
300
301 RenderManager.StateSetBlendFactor(0xffffff |(((unsigned int)fVal)<<24));
302 currentGuiBlendFactor = fVal / 255.0f;
303 // RenderManager.StateSetBlendFactor(0x40ffffff);
304 glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
305
306 blitOffset = -90;
307
308 /////////////////////////////////////////////////////////////////////////////////////
309 // Display the quick select background, the quick select selection, and the crosshair
310 /////////////////////////////////////////////////////////////////////////////////////
311 if(bDisplayGui)
312 {
313 MemSect(31);
314 minecraft->textures->bindTexture(TN_GUI_GUI); // 4J was L"/gui/gui.png"
315 MemSect(0);
316
317 shared_ptr<Inventory> inventory = minecraft->player->inventory;
318 if(bTwoPlayerSplitscreen)
319 {
320 // need to apply scale factors depending on the mode
321
322 // 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
323 //glPushMatrix();
324 //glScalef(fScaleFactorWidth, fScaleFactorHeight, fScaleFactorWidth);
325
326 // 4J-PB - move into the safe zone, and account for 2 player splitscreen
327 blit(iWidthOffset + (screenWidth - quickSelectWidth)/2, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset , 0, 0, 182, 22);
328 blit(iWidthOffset + (screenWidth - quickSelectWidth)/2 - 1 + inventory->selected * 20, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset - 1, 0, 22, 24, 22);
329 }
330 else
331 {
332 blit(iWidthOffset + screenWidth / 2 - quickSelectWidth / 2, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset , 0, 0, 182, 22);
333 blit(iWidthOffset + screenWidth / 2 - quickSelectWidth / 2 - 1 + inventory->selected * 20, iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset - 1, 0, 22, 24, 22);
334 }
335
336
337 MemSect(31);
338 minecraft->textures->bindTexture(TN_GUI_ICONS);//L"/gui/icons.png"));
339 MemSect(0);
340 glEnable(GL_BLEND);
341 RenderManager.StateSetBlendFactor(0xffffff |(((unsigned int)fVal)<<24));
342 glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
343 //glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR);
344 // 4J Stu - We don't want to adjust the cursor by the safezone, we want it centred
345 if(bTwoPlayerSplitscreen)
346 {
347 blit(iWidthOffset + screenWidth / 2 - 7, (iHeightOffset + screenHeight) / 2 - 7, 0, 0, 16, 16);
348 }
349 else
350 {
351 blit(screenWidth / 2 - 7, screenHeight / 2 - 7, 0, 0, 16, 16);
352 }
353 glDisable(GL_BLEND);
354
355 // if(bTwoPlayerSplitscreen)
356 // {
357 // glPopMatrix();
358 // }
359
360 }
361
362 bool blink = minecraft->player->invulnerableTime / 3 % 2 == 1;
363 if (minecraft->player->invulnerableTime < 10) blink = false;
364 int iHealth = minecraft->player->getHealth();
365 int iLastHealth = minecraft->player->lastHealth;
366 random->setSeed(tickCount * 312871);
367
368 bool foodBlink = false;
369 FoodData *foodData = minecraft->player->getFoodData();
370 int food = foodData->getFoodLevel();
371 int oldFood = foodData->getLastFoodLevel();
372
373// if (false) //(true)
374// {
375// renderBossHealth();
376// }
377
378 /////////////////////////////////////////////////////////////////////////////////////
379 // Display the experience, food, armour, health and the air bubbles
380 /////////////////////////////////////////////////////////////////////////////////////
381 if(bDisplayGui)
382 {
383 // 4J - added blend for fading gui
384 glEnable(GL_BLEND);
385 glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
386
387 if (minecraft->gameMode->canHurtPlayer())
388 {
389 int xLeft, xRight;
390 // 4J Stu - TODO Work out proper positioning for splitscreen
391 if(bTwoPlayerSplitscreen)
392 {
393 xLeft = iWidthOffset + (screenWidth - quickSelectWidth)/2;
394 xRight = iWidthOffset + (screenWidth + quickSelectWidth)/2;
395 }
396 else
397 {
398 xLeft = (screenWidth - quickSelectWidth)/2;
399 xRight = (screenWidth + quickSelectWidth) / 2;
400 }
401
402 // render experience bar
403 int xpNeededForNextLevel = minecraft->player->getXpNeededForNextLevel();
404 if (xpNeededForNextLevel > 0)
405 {
406 int w = 182;
407
408 int progress = (int) (minecraft->player->experienceProgress * (float) (w + 1));
409
410 int yo = screenHeight - iSafezoneYHalf - iTooltipsYOffset - 8;
411 if(bTwoPlayerSplitscreen)
412 {
413 yo+=iHeightOffset;
414 }
415 blit(xLeft, yo, 0, 64, w, 5);
416 if (progress > 0)
417 {
418 blit(xLeft, yo, 0, 69, progress, 5);
419 }
420 }
421
422 int yLine1, yLine2;
423 if(bTwoPlayerSplitscreen)
424 {
425 //yo = iHeightOffset + screenHeight - 10 - iSafezoneYHalf - iTooltipsYOffset;
426 yLine1 = iHeightOffset + screenHeight - 18 - iSafezoneYHalf - iTooltipsYOffset;
427 yLine2 = yLine1 - 10;
428 }
429 else
430 {
431 //yo = screenHeight - 10 - iSafezoneYHalf - iTooltipsYOffset;
432 yLine1 = screenHeight - 18 - iSafezoneYHalf - iTooltipsYOffset;
433 yLine2 = yLine1 - 10;
434 }
435
436 double maxHealth = minecraft->localplayers[iPad]->getAttribute(SharedMonsterAttributes.MAX_HEALTH);
437
438 double totalAbsorption = minecraft->localplayers[iPad]->getAbsorptionAmount();
439 int numHealthRows = Mth.ceil((maxHealth + totalAbsorption) / 2 / (float) NUM_HEARTS_PER_ROW);
440 int healthRowHeight = Math.max(10 - (numHealthRows - 2), 3);
441 int yLine2 = yLine1 - (numHealthRows - 1) * healthRowHeight - 10;
442 absorption = totalAbsorption;
443
444 int armor = minecraft->player->getArmorValue();
445 int heartOffsetIndex = -1;
446 if (minecraft->player->hasEffect(MobEffect::regeneration))
447 {
448 heartOffsetIndex = tickCount % (int) ceil(maxHealth + 5);
449 }
450
451 // render health and armor
452 //minecraft.profiler.push("armor");
453 for (int i = 0; i < Player::MAX_HEALTH / 2; i++)
454 {
455 if (armor > 0)
456 {
457 int xo = xLeft + i * 8;
458 if (i * 2 + 1 < armor) blit(xo, yLine2, 16 + 2 * 9, 9, 9, 9);
459 if (i * 2 + 1 == armor) blit(xo, yLine2, 16 + 1 * 9, 9, 9, 9);
460 if (i * 2 + 1 > armor) blit(xo, yLine2, 16 + 0 * 9, 9, 9, 9);
461 }
462 }
463
464 //minecraft.profiler.popPush("health");
465 for (int i = Mth.ceil((maxHealth + totalAbsorption) / 2) - 1; i >= 0; i--)
466 {
467 int healthTexBaseX = 16;
468 if (minecraft.player.hasEffect(MobEffect.poison))
469 {
470 healthTexBaseX += 4 * 9;
471 }
472 else if (minecraft.player.hasEffect(MobEffect.wither))
473 {
474 healthTexBaseX += 8 * 9;
475 }
476
477 int bg = 0;
478 if (blink) bg = 1;
479 int rowIndex = Mth.ceil((i + 1) / (float) NUM_HEARTS_PER_ROW) - 1;
480 int xo = xLeft + (i % NUM_HEARTS_PER_ROW) * 8;
481 int yo = yLine1 - rowIndex * healthRowHeight;
482 if (currentHealth <= 4)
483 {
484 yo += random.nextInt(2);
485 }
486
487 if (i == heartOffsetIndex)
488 {
489 yo -= 2;
490 }
491
492 int y0 = 0;
493
494 // No hardcore on console
495 /*if (minecraft->level.getLevelData().isHardcore())
496 {
497 y0 = 5;
498 }*/
499
500 blit(xo, yo, 16 + bg * 9, 9 * y0, 9, 9);
501 if (blink)
502 {
503 if (i * 2 + 1 < oldHealth) blit(xo, yo, healthTexBaseX + 6 * 9, 9 * y0, 9, 9);
504 if (i * 2 + 1 == oldHealth) blit(xo, yo, healthTexBaseX + 7 * 9, 9 * y0, 9, 9);
505 }
506
507 if (absorption > 0)
508 {
509 if (absorption == totalAbsorption && totalAbsorption % 2 == 1)
510 {
511 blit(xo, yo, healthTexBaseX + 17 * 9, 9 * y0, 9, 9);
512 }
513 else
514 {
515 blit(xo, yo, healthTexBaseX + 16 * 9, 9 * y0, 9, 9);
516 }
517 absorption -= 2;
518 }
519 else
520 {
521 if (i * 2 + 1 < currentHealth) blit(xo, yo, healthTexBaseX + 4 * 9, 9 * y0, 9, 9);
522 if (i * 2 + 1 == currentHealth) blit(xo, yo, healthTexBaseX + 5 * 9, 9 * y0, 9, 9);
523 }
524 }
525
526 std::shared_ptr<Entity> riding = minecraft->localplayers[iPad].get()->riding;
527 std::shared_ptr<LivingEntity> living = dynamic_pointer_cast<LivingEntity>(riding);
528 if (riding == NULL)
529 {
530 // render food
531 for (int i = 0; i < FoodConstants::MAX_FOOD / 2; i++)
532 {
533 int yo = yLine1;
534
535
536 int texBaseX = 16;
537 int bg = 0;
538 if (minecraft->player->hasEffect(MobEffect::hunger))
539 {
540 texBaseX += 4 * 9;
541 bg = 13;
542 }
543
544 if (minecraft->player->getFoodData()->getSaturationLevel() <= 0)
545 {
546 if ((tickCount % (food * 3 + 1)) == 0)
547 {
548 yo += random->nextInt(3) - 1;
549 }
550 }
551
552 if (foodBlink) bg = 1;
553 int xo = xRight - i * 8 - 9;
554 blit(xo, yo, 16 + bg * 9, 9 * 3, 9, 9);
555 if (foodBlink)
556 {
557 if (i * 2 + 1 < oldFood) blit(xo, yo, texBaseX + 6 * 9, 9 * 3, 9, 9);
558 if (i * 2 + 1 == oldFood) blit(xo, yo, texBaseX + 7 * 9, 9 * 3, 9, 9);
559 }
560 if (i * 2 + 1 < food) blit(xo, yo, texBaseX + 4 * 9, 9 * 3, 9, 9);
561 if (i * 2 + 1 == food) blit(xo, yo, texBaseX + 5 * 9, 9 * 3, 9, 9);
562 }
563 }
564 else if (living != nullptr)
565 {
566 // Render mount health
567
568 int riderCurrentHealth = (int) ceil(living.get()->GetHealth());
569 float maxRiderHealth = living->GetMaxHealth();
570 int hearts = (int) (maxRiderHealth + .5f) / 2;
571 if (hearts > 30)
572 {
573 hearts = 30;
574 }
575
576 int yo = yLine1;
577 int baseHealth = 0;
578
579 while (hearts > 0)
580 {
581 int rowHearts = min(hearts, 10);
582 hearts -= rowHearts;
583
584 for (int i = 0; i < rowHearts; i++)
585 {
586 int texBaseX = 52;
587 int bg = 0;
588
589 if (foodBlink) bg = 1;
590 int xo = xRight - i * 8 - 9;
591 blit(xo, yo, texBaseX + bg * 9, 9 * 1, 9, 9);
592 if (i * 2 + 1 + baseHealth < riderCurrentHealth) blit(xo, yo, texBaseX + 4 * 9, 9 * 1, 9, 9);
593 if (i * 2 + 1 + baseHealth == riderCurrentHealth) blit(xo, yo, texBaseX + 5 * 9, 9 * 1, 9, 9);
594 }
595 yo -= 10;
596 baseHealth += 20;
597 }
598 }
599
600 // render air bubbles
601 if (minecraft->player->isUnderLiquid(Material::water))
602 {
603 int count = (int) ceil((minecraft->player->getAirSupply() - 2) * 10.0f / Player::TOTAL_AIR_SUPPLY);
604 int extra = (int) ceil((minecraft->player->getAirSupply()) * 10.0f / Player::TOTAL_AIR_SUPPLY) - count;
605 for (int i = 0; i < count + extra; i++)
606 {
607 // Air bubbles
608 if (i < count) blit(xRight - i * 8 - 9, yLine2, 16, 9 * 2, 9, 9);
609 else blit(xRight - i * 8 - 9, yLine2, 16 + 9, 9 * 2, 9, 9);
610 }
611 }
612 }
613
614 }
615
616 // 4J-PB - turn off the slot display if a xui menu is up
617
618 ////////////////////////////
619 // render the slot contents
620 ////////////////////////////
621 if(bDisplayGui)
622 {
623 // glDisable(GL_BLEND); 4J - removed - we want to be able to fade our gui
624
625 glEnable(GL_RESCALE_NORMAL);
626
627 Lighting::turnOnGui();
628
629
630 int x,y;
631
632 for (int i = 0; i < 9; i++)
633 {
634 if(bTwoPlayerSplitscreen)
635 {
636 x = iWidthOffset + screenWidth / 2 - 9 * 10 + i * 20 + 2;
637 y = iHeightOffset + screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22;
638 }
639 else
640 {
641 x = screenWidth / 2 - 9 * 10 + i * 20 + 2;
642 y = screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22;
643 }
644 this->renderSlot(i, x, y, a);
645 }
646 Lighting::turnOff();
647 glDisable(GL_RESCALE_NORMAL);
648 }
649#endif // RENDER_HUD
650
651 // 4J - do render of crouched player. This code is largely taken from the inventory render of the player, with some special hard-coded positions
652 // worked out by hand from the xui implementation of the crouch icon
653
654 if(app.GetGameSettings(iPad,eGameSetting_AnimatedCharacter))
655 {
656 //int playerIdx = minecraft->player->GetXboxPad();
657
658 static int characterDisplayTimer[4] = {0};
659 if( !bDisplayGui )
660 {
661 characterDisplayTimer[iPad] = 0;
662 }
663 else if( minecraft->player->isSneaking() )
664 {
665 characterDisplayTimer[iPad] = 30;
666 }
667 else if( minecraft->player->isSprinting() )
668 {
669 characterDisplayTimer[iPad] = 30;
670 }
671 else if( minecraft->player->abilities.flying)
672 {
673 characterDisplayTimer[iPad] = 5; // quickly get rid of the player display if they stop flying
674 }
675 else if( characterDisplayTimer[iPad] > 0 )
676 {
677 --characterDisplayTimer[iPad];
678 }
679 bool displayCrouch = minecraft->player->isSneaking() || ( characterDisplayTimer[iPad] > 0 );
680 bool displaySprint = minecraft->player->isSprinting() || ( characterDisplayTimer[iPad] > 0 );
681 bool displayFlying = minecraft->player->abilities.flying || ( characterDisplayTimer[iPad] > 0 );
682
683 if( bDisplayGui && (displayCrouch || displaySprint || displayFlying) )
684 {
685 EntityRenderDispatcher::instance->prepare(minecraft->level, minecraft->textures, minecraft->font, minecraft->cameraTargetPlayer, minecraft->crosshairPickMob, minecraft->options, a);
686 glEnable(GL_RESCALE_NORMAL);
687 glEnable(GL_COLOR_MATERIAL);
688
689 // 4J - TomK now using safe zone values directly instead of the magic number calculation that lived here before (which only worked for medium scale, the other two were off!)
690 int xo = iSafezoneXHalf + 10;
691 int yo = iSafezoneTopYHalf + 10;
692
693#ifdef __PSVITA__
694 // align directly with corners, there are no safe zones on vita
695 xo = 10;
696 yo = 10;
697#endif
698
699 glPushMatrix();
700 glTranslatef((float)xo, (float)yo, 50);
701 float ss = 12;
702 glScalef(-ss, ss, ss);
703 glRotatef(180, 0, 0, 1);
704
705 float oyr = minecraft->player->yRot;
706 float oyrO = minecraft->player->yRotO;
707 float oxr = minecraft->player->xRot;
708 int ofire = minecraft->player->onFire;
709 bool ofireflag = minecraft->player->getSharedFlag(Entity::FLAG_ONFIRE);
710
711 float xd = -40;
712 float yd = 10;
713
714 // 4J Stu - This is all based on the inventory player renderer, with changes to ensure that capes render correctly
715 // by minimising the changes to member variables of the player which are all related
716
717 glRotatef(45 + 90, 0, 1, 0);
718 Lighting::turnOn();
719 glRotatef(-45 - 90, 0, 1, 0);
720
721 glRotatef(-(float) atan(yd / 40.0f ) * 20, 1, 0, 0);
722 float bodyRot = (minecraft->player->yBodyRotO + (minecraft->player->yBodyRot - minecraft->player->yBodyRotO));
723 // Fixed rotation angle of degrees, adjusted by bodyRot to negate the rotation that occurs in the renderer
724 // bodyRot in the rotation below is a simplification of "180 - (180 - bodyRot)" where the first 180 is EntityRenderDispatcher::instance->playerRotY that we set below
725 // and (180 - bodyRot) is the angle of rotation that is performed within the mob renderer
726 glRotatef( bodyRot - ( (float) atan(xd / 40.0f) * 20), 0, 1, 0);
727 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
728
729 // Set head rotation to body rotation to make head static
730 minecraft->player->yRot = bodyRot;
731 minecraft->player->yRotO = minecraft->player->yRot;
732 minecraft->player->xRot = -(float) atan(yd / 40.0f) * 20;
733
734 minecraft->player->onFire = 0;
735 minecraft->player->setSharedFlag(Entity::FLAG_ONFIRE, false);
736
737 // 4J - TomK don't offset the player. it's easier to align it with the safe zones that way!
738 //glTranslatef(0, minecraft->player->heightOffset, 0);
739 glTranslatef(0, 0, 0);
740 EntityRenderDispatcher::instance->playerRotY = 180;
741 EntityRenderDispatcher::instance->isGuiRender = true;
742 EntityRenderDispatcher::instance->render(minecraft->player, 0, 0, 0, 0, 1);
743 EntityRenderDispatcher::instance->isGuiRender = false;
744
745 minecraft->player->yRot = oyr;
746 minecraft->player->yRotO = oyrO;
747 minecraft->player->xRot = oxr;
748 minecraft->player->onFire = ofire;
749 minecraft->player->setSharedFlag(Entity::FLAG_ONFIRE,ofireflag);
750 glPopMatrix();
751 Lighting::turnOff();
752 glDisable(GL_RESCALE_NORMAL);
753 }
754 }
755 }
756
757#if RENDER_HUD
758 // Moved so the opacity blend is applied to it
759 if (bDisplayGui && minecraft->gameMode->hasExperience() && minecraft->player->experienceLevel > 0)
760 {
761 if (true)
762 {
763 bool blink = false;
764 int col = blink ? 0xffffff : 0x80ff20;
765 wchar_t formatted[10];
766 swprintf(formatted, 10, L"%d",minecraft->player->experienceLevel);
767
768 wstring str = formatted;
769 int x = iWidthOffset + (screenWidth - font->width(str)) / 2;
770 int y = screenHeight - iSafezoneYHalf - iTooltipsYOffset;
771 // If we're in creative mode, we don't need to offset the XP display so much
772 if (minecraft->gameMode->canHurtPlayer())
773 {
774 y-=18;
775 }
776 else
777 {
778 y-=13;
779 }
780
781 if(bTwoPlayerSplitscreen)
782 {
783 y+=iHeightOffset;
784 }
785 //int y = screenHeight - 31 - 4;
786 font->draw(str, x + 1, y, 0x000000);
787 font->draw(str, x - 1, y, 0x000000);
788 font->draw(str, x, y + 1, 0x000000);
789 font->draw(str, x, y - 1, 0x000000);
790 // font->draw(str, x + 1, y + 1, 0x000000);
791 // font->draw(str, x - 1, y + 1, 0x000000);
792 // font->draw(str, x + 1, y - 1, 0x000000);
793 // font->draw(str, x - 1, y - 1, 0x000000);
794 font->draw(str, x, y, col);
795 }
796 }
797#endif // RENDER_HUD
798
799 // 4J - added to disable blends, which we have enabled previously to allow gui fading
800 glDisable(GL_BLEND);
801 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
802
803 // if the player is falling asleep we render a dark overlay
804 if (minecraft->player->getSleepTimer() > 0)
805 {
806 glDisable(GL_DEPTH_TEST);
807 glDisable(GL_ALPHA_TEST);
808 int timer = minecraft->player->getSleepTimer();
809 float amount = (float) timer / (float) Player::SLEEP_DURATION;
810 if (amount > 1)
811 {
812 // waking up
813 amount = 1.0f - ((float) (timer - Player::SLEEP_DURATION) / (float) Player::WAKE_UP_DURATION);
814 }
815
816 int color = (int) (220.0f * amount) << 24 | (0x101020);
817 fill(0, 0, screenWidth/fScaleFactorWidth, screenHeight/fScaleFactorHeight, color);
818 glEnable(GL_ALPHA_TEST);
819 glEnable(GL_DEPTH_TEST);
820 }
821
822 // 4J-PB - Request from Mojang to have a red death screen
823 if (!minecraft->player->isAlive())
824 {
825 glDisable(GL_DEPTH_TEST);
826 glDisable(GL_ALPHA_TEST);
827 int timer = minecraft->player->getDeathFadeTimer();
828 float amount = (float) timer / (float) Player::DEATHFADE_DURATION;
829
830 int color = (int) (220.0f * amount) << 24 | (0x200000);
831 fill(0, 0, screenWidth/fScaleFactorWidth, screenHeight/fScaleFactorHeight, color);
832 glEnable(GL_ALPHA_TEST);
833 glEnable(GL_DEPTH_TEST);
834
835 }
836
837
838 // {
839 // String str = "" + minecraft.player.getFoodData().getExhaustionLevel() + ", " + minecraft.player.getFoodData().getSaturationLevel();
840 // int x = (screenWidth - font.width(str)) / 2;
841 // int y = screenHeight - 64;
842 // font.draw(str, x + 1, y, 0xffffff);
843 // }
844
845#ifndef _FINAL_BUILD
846 MemSect(31);
847 if (minecraft->options->renderDebug)
848 {
849 glPushMatrix();
850 if (Minecraft::warezTime > 0) glTranslatef(0, 32, 0);
851 font->drawShadow(ClientConstants::VERSION_STRING + L" (" + minecraft->fpsString + L")", iSafezoneXHalf+2, 20, 0xffffff);
852 font->drawShadow(L"Seed: " + _toString<__int64>(minecraft->level->getLevelData()->getSeed() ), iSafezoneXHalf+2, 32 + 00, 0xffffff);
853 font->drawShadow(minecraft->gatherStats1(), iSafezoneXHalf+2, 32 + 10, 0xffffff);
854 font->drawShadow(minecraft->gatherStats2(), iSafezoneXHalf+2, 32 + 20, 0xffffff);
855 font->drawShadow(minecraft->gatherStats3(), iSafezoneXHalf+2, 32 + 30, 0xffffff);
856 font->drawShadow(minecraft->gatherStats4(), iSafezoneXHalf+2, 32 + 40, 0xffffff);
857
858 // TERRAIN FEATURES
859 int iYPos=82;
860
861 if(minecraft->level->dimension->id==0)
862 {
863 wstring wfeature[eTerrainFeature_Count];
864
865 wfeature[eTerrainFeature_Stronghold] = L"Stronghold: ";
866 wfeature[eTerrainFeature_Mineshaft] = L"Mineshaft: ";
867 wfeature[eTerrainFeature_Village] = L"Village: ";
868 wfeature[eTerrainFeature_Ravine] = L"Ravine: ";
869
870 for(int i=0;i<app.m_vTerrainFeatures.size();i++)
871 {
872 FEATURE_DATA *pFeatureData=app.m_vTerrainFeatures[i];
873
874 wstring itemInfo = L"[" + _toString<int>( pFeatureData->x*16 ) + L", " + _toString<int>( pFeatureData->z*16 ) + L"] ";
875 wfeature[pFeatureData->eTerrainFeature] += itemInfo;
876 }
877
878 for( int i = eTerrainFeature_Stronghold; i < (int) eTerrainFeature_Count; i++ )
879 {
880 font->drawShadow(wfeature[i], iSafezoneXHalf + 2, iYPos, 0xffffff);
881 iYPos+=10;
882 }
883 }
884
885 //font->drawShadow(minecraft->gatherStats5(), iSafezoneXHalf+2, 32 + 10, 0xffffff);
886 {
887 /* 4J - removed
888 long max = Runtime.getRuntime().maxMemory();
889 long total = Runtime.getRuntime().totalMemory();
890 long free = Runtime.getRuntime().freeMemory();
891 long used = total - free;
892 String msg = "Used memory: " + (used * 100 / max) + "% (" + (used / 1024 / 1024) + "MB) of " + (max / 1024 / 1024) + "MB";
893 drawString(font, msg, screenWidth - font.width(msg) - 2, 2, 0xe0e0e0);
894 msg = "Allocated memory: " + (total * 100 / max) + "% (" + (total / 1024 / 1024) + "MB)";
895 drawString(font, msg, screenWidth - font.width(msg) - 2, 12, 0xe0e0e0);
896 */
897 }
898 // 4J Stu - Moved these so that they don't overlap
899 double xBlockPos = floor(minecraft->player->x);
900 double yBlockPos = floor(minecraft->player->y);
901 double zBlockPos = floor(minecraft->player->z);
902 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);
903 drawString(font, L"y: " + _toString<double>(minecraft->player->y) + L"/ Head: " + _toString<double>(yBlockPos), iSafezoneXHalf+2, iYPos + 8 * 1, 0xe0e0e0);
904 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);
905 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);
906 iYPos += 8*4;
907
908 int px = Mth::floor(minecraft->player->x);
909 int py = Mth::floor(minecraft->player->y);
910 int pz = Mth::floor(minecraft->player->z);
911 if (minecraft->level != NULL && minecraft->level->hasChunkAt(px, py, pz))
912 {
913 LevelChunk *chunkAt = minecraft->level->getChunkAt(px, pz);
914 Biome *biome = chunkAt->getBiome(px & 15, pz & 15, minecraft->level->getBiomeSource());
915 drawString(
916 font,
917 L"b: " + biome->m_name + L" (" + _toString<int>(biome->id) + L")", iSafezoneXHalf+2, iYPos, 0xe0e0e0);
918 }
919
920 glPopMatrix();
921 }
922 MemSect(0);
923#endif
924
925 lastTickA = a;
926 // 4J Stu - This is now displayed in a xui scene
927#if 0
928 // Jukebox CD message
929 if (overlayMessageTime > 0)
930 {
931 float t = overlayMessageTime - a;
932 int alpha = (int) (t * 256 / 20);
933 if (alpha > 255) alpha = 255;
934 if (alpha > 0)
935 {
936 glPushMatrix();
937
938 if(bTwoPlayerSplitscreen)
939 {
940 glTranslatef((float)((screenWidth / 2)+iWidthOffset), ((float)(screenHeight+iHeightOffset)) - iTooltipsYOffset -12 -iSafezoneYHalf, 0);
941 }
942 else
943 {
944 glTranslatef(((float)screenWidth) / 2, ((float)screenHeight) - iTooltipsYOffset - 12 -iSafezoneYHalf, 0);
945 }
946 glEnable(GL_BLEND);
947 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
948
949 int col = 0xffffff;
950 if (animateOverlayMessageColor)
951 {
952 col = Color::HSBtoRGB(t / 50.0f, 0.7f, 0.6f) & 0xffffff;
953 }
954 // 4J-PB - this is the string displayed when cds are placed in a jukebox
955 font->draw(overlayMessageString,-font->width(overlayMessageString) / 2, -20, col + (alpha << 24));
956 glDisable(GL_BLEND);
957 glPopMatrix();
958 }
959 }
960#endif
961
962 unsigned int max = 10;
963 bool isChatting = false;
964 if (dynamic_cast<ChatScreen *>(minecraft->screen) != NULL)
965 {
966 max = 20;
967 isChatting = true;
968 }
969
970 glEnable(GL_BLEND);
971 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
972 glDisable(GL_ALPHA_TEST);
973
974// 4J Stu - We have moved the chat text to a xui
975#if 0
976 glPushMatrix();
977 // 4J-PB we need to move this up a bit because we've moved the quick select
978 //glTranslatef(0, ((float)screenHeight) - 48, 0);
979 glTranslatef(0.0f, (float)(screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22) - 24.0f, 0.0f);
980 // glScalef(1.0f / ssc.scale, 1.0f / ssc.scale, 1);
981
982 // 4J-PB - we need gui messages for each of the possible 4 splitscreen players
983 if(bDisplayGui)
984 {
985 int iPad=minecraft->player->GetXboxPad();
986 for (unsigned int i = 0; i < guiMessages[iPad].size() && i < max; i++)
987 {
988 if (guiMessages[iPad][i].ticks < 20 * 10 || isChatting)
989 {
990 double t = guiMessages[iPad][i].ticks / (20 * 10.0);
991 t = 1 - t;
992 t = t * 10;
993 if (t < 0) t = 0;
994 if (t > 1) t = 1;
995 t = t * t;
996 int alpha = (int) (255 * t);
997 if (isChatting) alpha = 255;
998
999 if (alpha > 0)
1000 {
1001 int x = iSafezoneXHalf+2;
1002 int y = -((int)i) * 9;
1003 if(bTwoPlayerSplitscreen)
1004 {
1005 y+= iHeightOffset;
1006 }
1007
1008 wstring msg = guiMessages[iPad][i].string;
1009 // 4J-PB - fill the black bar across the whole screen, otherwise it looks odd due to the safe area
1010 this->fill(0, y - 1, screenWidth/fScaleFactorWidth, y + 8, (alpha / 2) << 24);
1011 glEnable(GL_BLEND);
1012
1013 font->drawShadow(msg, iSafezoneXHalf+4, y, 0xffffff + (alpha << 24));
1014 }
1015 }
1016 }
1017 }
1018 glPopMatrix();
1019#endif
1020
1021 // 4J Stu - Copied over but not used
1022#if 0
1023 if (minecraft.player instanceof MultiplayerLocalPlayer && minecraft.options.keyPlayerList.isDown)
1024 {
1025 ClientConnection connection = ((MultiplayerLocalPlayer) minecraft.player).connection;
1026 List<PlayerInfo> playerInfos = connection.playerInfos;
1027 int slots = connection.maxPlayers;
1028
1029 int rows = slots;
1030 int cols = 1;
1031 while (rows > 20) {
1032 cols++;
1033 rows = (slots + cols - 1) / cols;
1034 }
1035
1036 /*
1037 * int fakeCount = 39; while (playerInfos.size() > fakeCount)
1038 * playerInfos.remove(playerInfos.size() - 1); while (playerInfos.size() <
1039 * fakeCount) playerInfos.add(new PlayerInfo("fiddle"));
1040 */
1041
1042 int slotWidth = 300 / cols;
1043 if (slotWidth > 150) slotWidth = 150;
1044
1045 int xxo = (screenWidth - cols * slotWidth) / 2;
1046 int yyo = 10;
1047 fill(xxo - 1, yyo - 1, xxo + slotWidth * cols, yyo + 9 * rows, 0x80000000);
1048 for (int i = 0; i < slots; i++) {
1049 int xo = xxo + i % cols * slotWidth;
1050 int yo = yyo + i / cols * 9;
1051
1052 fill(xo, yo, xo + slotWidth - 1, yo + 8, 0x20ffffff);
1053 glColor4f(1, 1, 1, 1);
1054 glEnable(GL_ALPHA_TEST);
1055
1056 if (i < playerInfos.size()) {
1057 PlayerInfo pl = playerInfos.get(i);
1058 font.drawShadow(pl.name, xo, yo, 0xffffff);
1059 minecraft.textures.bind(minecraft.textures.loadTexture("/gui/icons.png"));
1060 int xt = 0;
1061 int yt = 0;
1062 xt = 0;
1063 yt = 0;
1064 if (pl.latency < 0) yt = 5;
1065 else if (pl.latency < 150) yt = 0;
1066 else if (pl.latency < 300) yt = 1;
1067 else if (pl.latency < 600) yt = 2;
1068 else if (pl.latency < 1000) yt = 3;
1069 else yt = 4;
1070
1071 blitOffset += 100;
1072 blit(xo + slotWidth - 12, yo, 0 + xt * 10, 176 + yt * 8, 10, 8);
1073 blitOffset -= 100;
1074 }
1075 }
1076 }
1077#endif
1078
1079 if(bDisplayGui && bTwoPlayerSplitscreen)
1080 {
1081 // pop the scaled matrix
1082 glPopMatrix();
1083 }
1084
1085 glColor4f(1, 1, 1, 1);
1086 glDisable(GL_BLEND);
1087 glEnable(GL_ALPHA_TEST);
1088}
1089
1090// Moved to the xui base scene
1091// void Gui::renderBossHealth(void)
1092// {
1093// if (EnderDragonRenderer::bossInstance == NULL) return;
1094//
1095// shared_ptr<EnderDragon> boss = EnderDragonRenderer::bossInstance;
1096// EnderDragonRenderer::bossInstance = NULL;
1097//
1098// Minecraft *pMinecraft=Minecraft::GetInstance();
1099//
1100// Font *font = pMinecraft->font;
1101//
1102// ScreenSizeCalculator ssc(pMinecraft->options, pMinecraft->width_phys, pMinecraft->height_phys);
1103// int screenWidth = ssc.getWidth();
1104//
1105// int w = 182;
1106// int xLeft = screenWidth / 2 - w / 2;
1107//
1108// int progress = (int) (boss->getSynchedHealth() / (float) boss->getMaxHealth() * (float) (w + 1));
1109//
1110// int yo = 12;
1111// blit(xLeft, yo, 0, 74, w, 5);
1112// blit(xLeft, yo, 0, 74, w, 5);
1113// if (progress > 0)
1114// {
1115// blit(xLeft, yo, 0, 79, progress, 5);
1116// }
1117//
1118// wstring msg = L"Boss health - NON LOCALISED";
1119// font->drawShadow(msg, screenWidth / 2 - font->width(msg) / 2, yo - 10, 0xff00ff);
1120// glColor4f(1, 1, 1, 1);
1121// glBindTexture(GL_TEXTURE_2D, pMinecraft->textures->loadTexture(TN_GUI_ICONS) );//"/gui/icons.png"));
1122//
1123// }
1124
1125void Gui::renderPumpkin(int w, int h)
1126{
1127 glDisable(GL_DEPTH_TEST);
1128 glDepthMask(false);
1129 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1130 glColor4f(1, 1, 1, 1);
1131 glDisable(GL_ALPHA_TEST);
1132
1133 MemSect(31);
1134 minecraft->textures->bindTexture(&PUMPKIN_BLUR_LOCATION);
1135 MemSect(0);
1136 Tesselator *t = Tesselator::getInstance();
1137 t->begin();
1138 t->vertexUV((float)(0), (float)( h), (float)( -90), (float)( 0), (float)( 1));
1139 t->vertexUV((float)(w), (float)( h), (float)( -90), (float)( 1), (float)( 1));
1140 t->vertexUV((float)(w), (float)( 0), (float)( -90), (float)( 1), (float)( 0));
1141 t->vertexUV((float)(0), (float)( 0), (float)( -90), (float)( 0), (float)( 0));
1142 t->end();
1143 glDepthMask(true);
1144 glEnable(GL_DEPTH_TEST);
1145 glEnable(GL_ALPHA_TEST);
1146 glColor4f(1, 1, 1, 1);
1147
1148}
1149
1150void Gui::renderVignette(float br, int w, int h)
1151{
1152 br = 1 - br;
1153 if (br < 0) br = 0;
1154 if (br > 1) br = 1;
1155 tbr += (br - tbr) * 0.01f;
1156
1157#if 0 // 4J - removed - TODO put back when we have blend functions implemented
1158 glDisable(GL_DEPTH_TEST);
1159 glDepthMask(false);
1160 glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
1161 glColor4f(tbr, tbr, tbr, 1);
1162 glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture(TN__BLUR__MISC_VIGNETTE));//L"%blur%/misc/vignette.png"));
1163 Tesselator *t = Tesselator::getInstance();
1164 t->begin();
1165 t->vertexUV((float)(0), (float)( h), (float)( -90), (float)( 0), (float)( 1));
1166 t->vertexUV((float)(w), (float)( h), (float)( -90), (float)( 1), (float)( 1));
1167 t->vertexUV((float)(w), (float)( 0), (float)( -90), (float)( 1), (float)( 0));
1168 t->vertexUV((float)(0), (float)( 0), (float)( -90), (float)( 0), (float)( 0));
1169 t->end();
1170 glDepthMask(true);
1171 glEnable(GL_DEPTH_TEST);
1172 glColor4f(1, 1, 1, 1);
1173 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1174#endif
1175}
1176
1177void Gui::renderTp(float br, int w, int h)
1178{
1179 if (br < 1)
1180 {
1181 br = br * br;
1182 br = br * br;
1183 br = br * 0.8f + 0.2f;
1184 }
1185
1186 glDisable(GL_ALPHA_TEST);
1187 glDisable(GL_DEPTH_TEST);
1188 glDepthMask(false);
1189 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1190 glColor4f(1, 1, 1, br);
1191 MemSect(31);
1192 minecraft->textures->bindTexture(&TextureAtlas::LOCATION_BLOCKS);
1193 MemSect(0);
1194
1195 Icon *slot = Tile::portalTile->getTexture(Facing::UP);
1196 float u0 = slot->getU0();
1197 float v0 = slot->getV0();
1198 float u1 = slot->getU1();
1199 float v1 = slot->getV1();
1200 Tesselator *t = Tesselator::getInstance();
1201 t->begin();
1202 t->vertexUV((float)(0), (float)( h), (float)( -90), (float)( u0), (float)( v1));
1203 t->vertexUV((float)(w), (float)( h), (float)( -90), (float)( u1), (float)( v1));
1204 t->vertexUV((float)(w), (float)( 0), (float)( -90), (float)( u1), (float)( v0));
1205 t->vertexUV((float)(0), (float)( 0), (float)( -90), (float)( u0), (float)( v0));
1206 t->end();
1207 glDepthMask(true);
1208 glEnable(GL_DEPTH_TEST);
1209 glEnable(GL_ALPHA_TEST);
1210 glColor4f(1, 1, 1, 1);
1211
1212}
1213
1214void Gui::renderSlot(int slot, int x, int y, float a)
1215{
1216 shared_ptr<ItemInstance> item = minecraft->player->inventory->items[slot];
1217 if (item == NULL) return;
1218
1219 float pop = item->popTime - a;
1220 if (pop > 0)
1221 {
1222 glPushMatrix();
1223 float squeeze = 1 + pop / (float) Inventory::POP_TIME_DURATION;
1224 glTranslatef((float)(x + 8), (float)(y + 12), 0);
1225 glScalef(1 / squeeze, (squeeze + 1) / 2, 1);
1226 glTranslatef((float)-(x + 8), (float)-(y + 12), 0);
1227 }
1228
1229 itemRenderer->renderAndDecorateItem(minecraft->font, minecraft->textures, item, x, y);
1230
1231 if (pop > 0)
1232 {
1233 glPopMatrix();
1234 }
1235
1236 itemRenderer->renderGuiItemDecorations(minecraft->font, minecraft->textures, item, x, y);
1237
1238}
1239
1240void Gui::tick()
1241{
1242 if (overlayMessageTime > 0) overlayMessageTime--;
1243 tickCount++;
1244
1245 for(int iPad=0;iPad<XUSER_MAX_COUNT;iPad++)
1246 {
1247 // 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.
1248 // We don't show the guiMessages when a menu is up, so don't fade them out
1249 if(!ui.GetMenuDisplayed(iPad))
1250 {
1251 AUTO_VAR(itEnd, guiMessages[iPad].end());
1252 for (AUTO_VAR(it, guiMessages[iPad].begin()); it != itEnd; it++)
1253 {
1254 (*it).ticks++;
1255 }
1256 }
1257 }
1258}
1259
1260void Gui::clearMessages(int iPad)
1261{
1262 if(iPad==-1)
1263 {
1264 for(int i=0;i<XUSER_MAX_COUNT;i++)
1265 {
1266 if(minecraft->localplayers[i])
1267 {
1268 guiMessages[i].clear();
1269 }
1270 }
1271 }
1272 else
1273 {
1274 guiMessages[iPad].clear();
1275 }
1276}
1277
1278
1279void Gui::addMessage(const wstring& _string,int iPad,bool bIsDeathMessage)
1280{
1281 wstring string = _string; // 4J - Take copy of input as it is const
1282 //int iScale=1;
1283
1284 //if((minecraft->player->m_iScreenSection==C4JRender::VIEWPORT_TYPE_SPLIT_TOP) ||
1285 // (minecraft->player->m_iScreenSection==C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM))
1286 //{
1287 // iScale=2;
1288 //}
1289
1290 // while (minecraft->font->width(string) > (m_iMaxMessageWidth*iScale))
1291 //{
1292 // unsigned int i = 1;
1293 // while (i < string.length() && minecraft->font->width(string.substr(0, i + 1)) <= (m_iMaxMessageWidth*iScale))
1294 // {
1295 // i++;
1296 // }
1297 // int iLast=string.find_last_of(L" ",i);
1298
1299 // // if a space was found, include the space on this line
1300 // if(iLast!=i)
1301 // {
1302 // iLast++;
1303 // }
1304 // addMessage(string.substr(0, iLast), iPad);
1305 // string = string.substr(iLast);
1306 // }
1307
1308 int maximumChars;
1309
1310 switch(minecraft->player->m_iScreenSection)
1311 {
1312 case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
1313 case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
1314 case C4JRender::VIEWPORT_TYPE_FULLSCREEN:
1315 if(RenderManager.IsHiDef())
1316 {
1317 maximumChars = 105;
1318 }
1319 else
1320 {
1321 maximumChars = 55;
1322 }
1323#ifdef __PSVITA__
1324 maximumChars = 90;
1325#endif
1326 switch(XGetLanguage())
1327 {
1328 case XC_LANGUAGE_JAPANESE:
1329 case XC_LANGUAGE_TCHINESE:
1330 case XC_LANGUAGE_KOREAN:
1331 if(RenderManager.IsHiDef())
1332 {
1333 maximumChars = 70;
1334 }
1335 else
1336 {
1337 maximumChars = 35;
1338 }
1339#ifdef __PSVITA__
1340 maximumChars = 55;
1341#endif
1342 break;
1343 }
1344 break;
1345 default:
1346 maximumChars = 55;
1347 switch(XGetLanguage())
1348 {
1349 case XC_LANGUAGE_JAPANESE:
1350 case XC_LANGUAGE_TCHINESE:
1351 case XC_LANGUAGE_KOREAN:
1352 maximumChars = 35;
1353 break;
1354 }
1355 break;
1356 }
1357
1358
1359 while (string.length() > maximumChars)
1360 {
1361 unsigned int i = 1;
1362 while (i < string.length() && (i + 1) <= maximumChars)
1363 {
1364 i++;
1365 }
1366 int iLast=(int)string.find_last_of(L" ",i);
1367 switch(XGetLanguage())
1368 {
1369 case XC_LANGUAGE_JAPANESE:
1370 case XC_LANGUAGE_TCHINESE:
1371 case XC_LANGUAGE_KOREAN:
1372 iLast = maximumChars;
1373 break;
1374 default:
1375 iLast=(int)string.find_last_of(L" ",i);
1376 break;
1377 }
1378
1379 // if a space was found, include the space on this line
1380 if(iLast!=i)
1381 {
1382 iLast++;
1383 }
1384 addMessage(string.substr(0, iLast), iPad, bIsDeathMessage);
1385 string = string.substr(iLast);
1386 }
1387
1388 if(iPad==-1)
1389 {
1390 // add to all
1391 for(int i=0;i<XUSER_MAX_COUNT;i++)
1392 {
1393 if(minecraft->localplayers[i] && !(bIsDeathMessage && app.GetGameSettings(i,eGameSetting_DeathMessages)==0))
1394 {
1395 guiMessages[i].insert(guiMessages[i].begin(), GuiMessage(string));
1396 while (guiMessages[i].size() > 50)
1397 {
1398 guiMessages[i].pop_back();
1399 }
1400 }
1401 }
1402 }
1403 else if(!(bIsDeathMessage && app.GetGameSettings(iPad,eGameSetting_DeathMessages)==0))
1404 {
1405 guiMessages[iPad].insert(guiMessages[iPad].begin(), GuiMessage(string));
1406 while (guiMessages[iPad].size() > 50)
1407 {
1408 guiMessages[iPad].pop_back();
1409 }
1410 }
1411
1412
1413}
1414
1415// 4J Added
1416float Gui::getOpacity(int iPad, DWORD index)
1417{
1418 float opacityPercentage = 0;
1419 if (guiMessages[iPad].size() > index && guiMessages[iPad][index].ticks < 20 * 10)
1420 {
1421 double t = guiMessages[iPad][index].ticks / (20 * 10.0);
1422 t = 1 - t;
1423 t = t * 10;
1424 if (t < 0) t = 0;
1425 if (t > 1) t = 1;
1426 t = t * t;
1427 opacityPercentage = t;
1428 }
1429 return opacityPercentage;
1430}
1431
1432float Gui::getJukeboxOpacity(int iPad)
1433{
1434 float t = overlayMessageTime - lastTickA;
1435 int alpha = (int) (t * 256 / 20);
1436 if (alpha > 255) alpha = 255;
1437 alpha /= 255;
1438
1439 return alpha;
1440}
1441
1442void Gui::setNowPlaying(const wstring& string)
1443{
1444// overlayMessageString = L"Now playing: " + string;
1445 overlayMessageString = app.GetString(IDS_NOWPLAYING) + string;
1446 overlayMessageTime = 20 * 3;
1447 animateOverlayMessageColor = true;
1448}
1449
1450void Gui::displayClientMessage(int messageId, int iPad)
1451{
1452 //Language *language = Language::getInstance();
1453 wstring languageString = app.GetString(messageId);//language->getElement(messageId);
1454
1455 addMessage(languageString, iPad);
1456}
1457
1458// 4J Added
1459void Gui::renderGraph(int dataLength, int dataPos, __int64 *dataA, float dataAScale, int dataAWarning, __int64 *dataB, float dataBScale, int dataBWarning)
1460{
1461 int height = minecraft->height;
1462 // This causes us to cover xScale*dataLength pixels in the horizontal
1463 int xScale = 1;
1464 if(dataA != NULL && dataB != NULL) xScale = 2;
1465
1466 glClear(GL_DEPTH_BUFFER_BIT);
1467 glMatrixMode(GL_PROJECTION);
1468 glLoadIdentity();
1469 glOrtho(0, (float)minecraft->width, (float)height, 0, 1000, 3000);
1470 glMatrixMode(GL_MODELVIEW);
1471 glLoadIdentity();
1472 glTranslatef(0, 0, -2000);
1473
1474 glLineWidth(1);
1475 glDisable(GL_TEXTURE_2D);
1476 Tesselator *t = Tesselator::getInstance();
1477
1478 t->begin(GL_LINES);
1479 for (int i = 0; i < dataLength; i++)
1480 {
1481 int col = ((i - dataPos) & (dataLength - 1)) * 255 / dataLength;
1482 int cc = col * col / 255;
1483 cc = cc * cc / 255;
1484 int cc2 = cc * cc / 255;
1485 cc2 = cc2 * cc2 / 255;
1486
1487 if( dataA != NULL )
1488 {
1489 if (dataA[i] > dataAWarning)
1490 {
1491 t->color(0xff000000 + cc * 65536);
1492 }
1493 else
1494 {
1495 t->color(0xff000000 + cc * 256);
1496 }
1497
1498 __int64 aVal = dataA[i] / dataAScale;
1499
1500 t->vertex((float)(xScale*i + 0.5f), (float)( height - aVal + 0.5f), (float)( 0));
1501 t->vertex((float)(xScale*i + 0.5f), (float)( height + 0.5f), (float)( 0));
1502 }
1503
1504 if( dataB != NULL )
1505 {
1506 if (dataB[i]>dataBWarning)
1507 {
1508 t->color(0xff000000 + cc * 65536 + cc * 256 + cc * 1);
1509 }
1510 else
1511 {
1512 t->color(0xff808080 + cc/2 * 256);
1513 }
1514
1515 __int64 bVal = dataB[i] / dataBScale;
1516
1517 t->vertex((float)(xScale*i + (xScale - 1) + 0.5f), (float)( height - bVal + 0.5f), (float)( 0));
1518 t->vertex((float)(xScale*i + (xScale - 1) + 0.5f), (float)( height + 0.5f), (float)( 0));
1519 }
1520 }
1521 t->end();
1522
1523 glEnable(GL_TEXTURE_2D);
1524}
1525
1526void Gui::renderStackedGraph(int dataPos, int dataLength, int dataSources, __int64 (*func)(unsigned int dataPos, unsigned int dataSource) )
1527{
1528 int height = minecraft->height;
1529
1530 glClear(GL_DEPTH_BUFFER_BIT);
1531 glMatrixMode(GL_PROJECTION);
1532 glLoadIdentity();
1533 glOrtho(0, (float)minecraft->width, (float)height, 0, 1000, 3000);
1534 glMatrixMode(GL_MODELVIEW);
1535 glLoadIdentity();
1536 glTranslatef(0, 0, -2000);
1537
1538 glLineWidth(1);
1539 glDisable(GL_TEXTURE_2D);
1540 Tesselator *t = Tesselator::getInstance();
1541
1542 t->begin(GL_LINES);
1543 __int64 thisVal = 0;
1544 __int64 topVal = 0;
1545 for (int i = 0; i < dataLength; i++)
1546 {
1547 thisVal = 0;
1548 topVal = 0;
1549 int col = ((i - dataPos) & (dataLength - 1)) * 255 / dataLength;
1550 int cc = col * col / 255;
1551 cc = cc * cc / 255;
1552 int cc2 = cc * cc / 255;
1553 cc2 = cc2 * cc2 / 255;
1554
1555
1556 for(unsigned int source = 0; source < dataSources; ++source )
1557 {
1558 thisVal = func( i, source );
1559
1560 if( thisVal > 0 )
1561 {
1562 float vary = (float)source/dataSources;
1563 int fColour = floor(vary * 0xffffff);
1564
1565 int colour = 0xff000000 + fColour;
1566 //printf("Colour is %x\n", colour);
1567 t->color(colour);
1568
1569 t->vertex((float)(i + 0.5f), (float)( height - topVal - thisVal + 0.5f), (float)( 0));
1570 t->vertex((float)(i + 0.5f), (float)( height - topVal + 0.5f), (float)( 0));
1571
1572 topVal += thisVal;
1573 }
1574 }
1575
1576 // Draw some horizontals
1577 for(unsigned int horiz = 1; horiz < 7; ++horiz )
1578 {
1579 t->color(0xff000000);
1580
1581 t->vertex((float)(0 + 0.5f), (float)( height - (horiz*100) + 0.5f), (float)( 0));
1582 t->vertex((float)(dataLength + 0.5f), (float)( height - (horiz*100) + 0.5f), (float)( 0));
1583 }
1584 }
1585 t->end();
1586
1587 glEnable(GL_TEXTURE_2D);
1588}