aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Common/UI/UIScene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.Client/Common/UI/UIScene.cpp')
-rw-r--r--Minecraft.Client/Common/UI/UIScene.cpp1248
1 files changed, 1248 insertions, 0 deletions
diff --git a/Minecraft.Client/Common/UI/UIScene.cpp b/Minecraft.Client/Common/UI/UIScene.cpp
new file mode 100644
index 00000000..e7d907ec
--- /dev/null
+++ b/Minecraft.Client/Common/UI/UIScene.cpp
@@ -0,0 +1,1248 @@
+#include "stdafx.h"
+#include "UI.h"
+#include "UIScene.h"
+
+#include "..\..\Lighting.h"
+#include "..\..\LocalPlayer.h"
+#include "..\..\ItemRenderer.h"
+#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
+
+UIScene::UIScene(int iPad, UILayer *parentLayer)
+{
+ m_parentLayer = parentLayer;
+ m_iPad = iPad;
+ swf = NULL;
+ m_pItemRenderer = NULL;
+
+ bHasFocus = false;
+ m_hasTickedOnce = false;
+ m_bFocussedOnce = false;
+ m_bVisible = true;
+ m_bCanHandleInput = false;
+ m_bIsReloading = false;
+
+ m_iFocusControl = -1;
+ m_iFocusChild = 0;
+ m_lastOpacity = 1.0f;
+ m_bUpdateOpacity = false;
+
+ m_backScene = NULL;
+
+ m_cacheSlotRenders = false;
+ m_needsCacheRendered = true;
+ m_expectedCachedSlotCount = 0;
+ m_callbackUniqueId = 0;
+}
+
+UIScene::~UIScene()
+{
+ /* Destroy the Iggy player. */
+ IggyPlayerDestroy( swf );
+
+ for(AUTO_VAR(it,m_registeredTextures.begin()); it != m_registeredTextures.end(); ++it)
+ {
+ ui.unregisterSubstitutionTexture( it->first, it->second );
+ }
+
+ if(m_callbackUniqueId != 0)
+ {
+ ui.UnregisterCallbackId(m_callbackUniqueId);
+ }
+
+ if(m_pItemRenderer != NULL) delete m_pItemRenderer;
+}
+
+void UIScene::destroyMovie()
+{
+ /* Destroy the Iggy player. */
+ IggyPlayerDestroy( swf );
+ swf = NULL;
+
+ // Clear out the controls collection (doesn't delete the controls, and they get re-setup later)
+ m_controls.clear();
+
+ // Clear out all the fast names for the current movie
+ m_fastNames.clear();
+}
+
+void UIScene::reloadMovie(bool force)
+{
+ if(!force && (stealsFocus() && (getSceneType() != eUIScene_FullscreenProgress && !bHasFocus))) return;
+
+ m_bIsReloading = true;
+ if(swf)
+ {
+ /* Destroy the Iggy player. */
+ IggyPlayerDestroy( swf );
+
+ // Clear out the controls collection (doesn't delete the controls, and they get re-setup later)
+ m_controls.clear();
+
+ // Clear out all the fast names for the current movie
+ m_fastNames.clear();
+ }
+
+ // Reload everything
+ initialiseMovie();
+
+ handlePreReload();
+
+ // Reload controls
+ for(AUTO_VAR(it, m_controls.begin()); it != m_controls.end(); ++it)
+ {
+ (*it)->ReInit();
+ }
+
+ handleReload();
+
+ IggyDataValue result;
+ IggyDataValue value[1];
+
+ value[0].type = IGGY_DATATYPE_number;
+ value[0].number = m_iFocusControl;
+
+ IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetFocus , 1 , value );
+
+ m_needsCacheRendered = true;
+ m_bIsReloading = false;
+}
+
+bool UIScene::needsReloaded()
+{
+ return !swf && (!stealsFocus() || bHasFocus);
+}
+
+bool UIScene::hasMovie()
+{
+ return swf != NULL;
+}
+
+F64 UIScene::getSafeZoneHalfHeight()
+{
+ float height = ui.getScreenHeight();
+
+ float safeHeight = 0.0f;
+
+#ifndef __PSVITA__
+ if( !RenderManager.IsHiDef() && RenderManager.IsWidescreen() )
+ {
+ // 90% safezone
+ safeHeight = height * (0.15f / 2);
+ }
+ else
+ {
+ // 90% safezone
+ safeHeight = height * (0.1f / 2);
+ }
+#endif
+ return safeHeight;
+}
+
+F64 UIScene::getSafeZoneHalfWidth()
+{
+ float width = ui.getScreenWidth();
+
+ float safeWidth = 0.0f;
+#ifndef __PSVITA__
+ if( !RenderManager.IsHiDef() && RenderManager.IsWidescreen() )
+ {
+ // 85% safezone
+ safeWidth = width * (0.15f / 2);
+ }
+ else
+ {
+ // 90% safezone
+ safeWidth = width * (0.1f / 2);
+ }
+#endif
+ return safeWidth;
+}
+
+void UIScene::updateSafeZone()
+{
+ // Distance from edge
+ F64 safeTop = 0.0;
+ F64 safeBottom = 0.0;
+ F64 safeLeft = 0.0;
+ F64 safeRight = 0.0;
+
+ switch( m_parentLayer->getViewport() )
+ {
+ case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
+ safeTop = getSafeZoneHalfHeight();
+ break;
+ case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
+ safeBottom = getSafeZoneHalfHeight();
+ break;
+ case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
+ safeLeft = getSafeZoneHalfWidth();
+ break;
+ case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
+ safeRight = getSafeZoneHalfWidth();
+ break;
+ case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
+ safeTop = getSafeZoneHalfHeight();
+ safeLeft = getSafeZoneHalfWidth();
+ break;
+ case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
+ safeTop = getSafeZoneHalfHeight();
+ safeRight = getSafeZoneHalfWidth();
+ break;
+ case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
+ safeBottom = getSafeZoneHalfHeight();
+ safeLeft = getSafeZoneHalfWidth();
+ break;
+ case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
+ safeBottom = getSafeZoneHalfHeight();
+ safeRight = getSafeZoneHalfWidth();
+ break;
+ case C4JRender::VIEWPORT_TYPE_FULLSCREEN:
+ default:
+ safeTop = getSafeZoneHalfHeight();
+ safeBottom = getSafeZoneHalfHeight();
+ safeLeft = getSafeZoneHalfWidth();
+ safeRight = getSafeZoneHalfWidth();
+ break;
+ }
+ setSafeZone(safeTop, safeBottom, safeLeft, safeRight);
+}
+
+void UIScene::setSafeZone(S32 safeTop, S32 safeBottom, S32 safeLeft, S32 safeRight)
+{
+ IggyDataValue result;
+ IggyDataValue value[4];
+
+ value[0].type = IGGY_DATATYPE_number;
+ value[0].number = safeTop;
+ value[1].type = IGGY_DATATYPE_number;
+ value[1].number = safeBottom;
+ value[2].type = IGGY_DATATYPE_number;
+ value[2].number = safeLeft;
+ value[3].type = IGGY_DATATYPE_number;
+ value[3].number = safeRight;
+ IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetSafeZone , 4 , value );
+}
+
+void UIScene::initialiseMovie()
+{
+ loadMovie();
+ mapElementsAndNames();
+
+ updateSafeZone();
+
+ m_bUpdateOpacity = true;
+}
+
+#ifdef __PSVITA__
+void UIScene::SetFocusToElement(int iID)
+{
+ IggyDataValue result;
+ IggyDataValue value[1];
+
+ value[0].type = IGGY_DATATYPE_number;
+ value[0].number = iID;
+
+ IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetFocus , 1 , value );
+
+ // also trigger handle focus change (just in case if anything else in relation needs updating!)
+ _handleFocusChange(iID, 0);
+}
+#endif
+
+bool UIScene::mapElementsAndNames()
+{
+ m_rootPath = IggyPlayerRootPath( swf );
+
+ m_funcRemoveObject = registerFastName( L"RemoveObject" );
+ m_funcSlideLeft = registerFastName( L"SlideLeft" );
+ m_funcSlideRight = registerFastName( L"SlideRight" );
+ m_funcSetSafeZone = registerFastName( L"SetSafeZone" );
+ m_funcSetAlpha = registerFastName( L"SetAlpha" );
+ m_funcSetFocus = registerFastName( L"SetFocus" );
+ m_funcHorizontalResizeCheck = registerFastName( L"DoHorizontalResizeCheck");
+ return true;
+}
+
+extern CRITICAL_SECTION s_loadSkinCS;
+void UIScene::loadMovie()
+{
+ EnterCriticalSection(&UIController::ms_reloadSkinCS); // MGH - added to prevent crash loading Iggy movies while the skins were being reloaded
+ wstring moviePath = getMoviePath();
+
+#ifdef __PS3__
+ if(RenderManager.IsWidescreen())
+ {
+ moviePath.append(L"720.swf");
+ m_loadedResolution = eSceneResolution_720;
+ }
+ else
+ {
+ moviePath.append(L"480.swf");
+ m_loadedResolution = eSceneResolution_480;
+ }
+#elif defined __PSVITA__
+ moviePath.append(L"Vita.swf");
+ m_loadedResolution = eSceneResolution_Vita;
+#elif defined _WINDOWS64
+ if(ui.getScreenHeight() == 720)
+ {
+ moviePath.append(L"720.swf");
+ m_loadedResolution = eSceneResolution_720;
+ }
+ else if(ui.getScreenHeight() == 480)
+ {
+ moviePath.append(L"480.swf");
+ m_loadedResolution = eSceneResolution_480;
+ }
+ else if(ui.getScreenHeight() < 720)
+ {
+ moviePath.append(L"Vita.swf");
+ m_loadedResolution = eSceneResolution_Vita;
+ }
+ else
+ {
+ moviePath.append(L"1080.swf");
+ m_loadedResolution = eSceneResolution_1080;
+ }
+#else
+ moviePath.append(L"1080.swf");
+ m_loadedResolution = eSceneResolution_1080;
+#endif
+
+ if(!app.hasArchiveFile(moviePath))
+ {
+ app.DebugPrintf("WARNING: Could not find iggy movie %ls, falling back on 720\n", moviePath.c_str());
+
+ moviePath = getMoviePath();
+ moviePath.append(L"720.swf");
+ m_loadedResolution = eSceneResolution_720;
+
+ if(!app.hasArchiveFile(moviePath))
+ {
+ app.DebugPrintf("ERROR: Could not find any iggy movie for %ls!\n", moviePath.c_str());
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ app.FatalLoadError();
+ }
+ }
+
+ byteArray baFile = ui.getMovieData(moviePath.c_str());
+ __int64 beforeLoad = ui.iggyAllocCount;
+ swf = IggyPlayerCreateFromMemory ( baFile.data , baFile.length, NULL);
+ __int64 afterLoad = ui.iggyAllocCount;
+ IggyPlayerInitializeAndTickRS ( swf );
+ __int64 afterTick = ui.iggyAllocCount;
+
+ if(!swf)
+ {
+ app.DebugPrintf("ERROR: Failed to load iggy scene!\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ app.FatalLoadError();
+ }
+ app.DebugPrintf( app.USER_SR, "Loaded iggy movie %ls\n", moviePath.c_str() );
+ IggyProperties *properties = IggyPlayerProperties ( swf );
+ m_movieHeight = properties->movie_height_in_pixels;
+ m_movieWidth = properties->movie_width_in_pixels;
+
+ m_renderWidth = m_movieWidth;
+ m_renderHeight = m_movieHeight;
+
+ S32 width, height;
+ m_parentLayer->getRenderDimensions(width, height);
+ IggyPlayerSetDisplaySize( swf, width, height );
+
+ IggyPlayerSetUserdata(swf,this);
+
+//#ifdef _DEBUG
+#if 0
+ IggyMemoryUseInfo memoryInfo;
+ rrbool res;
+ int iteration = 0;
+ __int64 totalStatic = 0;
+ __int64 totalDynamic = 0;
+ while(res = IggyDebugGetMemoryUseInfo ( swf ,
+ NULL ,
+ 0 ,
+ 0 ,
+ iteration ,
+ &memoryInfo ))
+ {
+ totalStatic += memoryInfo.static_allocation_bytes;
+ totalDynamic += memoryInfo.dynamic_allocation_bytes;
+ app.DebugPrintf(app.USER_SR, "%ls - %.*s static: %d ( %d ) dynamic: %d ( %d )\n", moviePath.c_str(), memoryInfo.subcategory_stringlen, memoryInfo.subcategory,
+ memoryInfo.static_allocation_bytes, memoryInfo.static_allocation_count, memoryInfo.dynamic_allocation_bytes, memoryInfo.dynamic_allocation_count);
+ ++iteration;
+ //if(memoryInfo.static_allocation_bytes > 0) getDebugMemoryUseRecursive(moviePath, memoryInfo);
+
+ }
+
+ app.DebugPrintf(app.USER_SR, "%ls - Total: %d, Expected: %d, Diff: %d\n", moviePath.c_str(), totalStatic + totalDynamic, afterTick - beforeLoad, (afterTick - beforeLoad) - (totalStatic + totalDynamic));
+
+#endif
+ LeaveCriticalSection(&UIController::ms_reloadSkinCS);
+
+}
+
+void UIScene::getDebugMemoryUseRecursive(const wstring &moviePath, IggyMemoryUseInfo &memoryInfo)
+{
+ rrbool res;
+ IggyMemoryUseInfo internalMemoryInfo;
+ int internalIteration = 0;
+ while(res = IggyDebugGetMemoryUseInfo ( swf ,
+ NULL ,
+ memoryInfo.subcategory ,
+ memoryInfo.subcategory_stringlen ,
+ internalIteration ,
+ &internalMemoryInfo ))
+ {
+ app.DebugPrintf(app.USER_SR, "%ls - %.*s static: %d ( %d ) dynamic: %d ( %d )\n", moviePath.c_str(), internalMemoryInfo.subcategory_stringlen, internalMemoryInfo.subcategory,
+ internalMemoryInfo.static_allocation_bytes, internalMemoryInfo.static_allocation_count, internalMemoryInfo.dynamic_allocation_bytes, internalMemoryInfo.dynamic_allocation_count);
+ ++internalIteration;
+ if(internalMemoryInfo.subcategory_stringlen > memoryInfo.subcategory_stringlen) getDebugMemoryUseRecursive(moviePath, internalMemoryInfo);
+ }
+}
+
+void UIScene::PrintTotalMemoryUsage(__int64 &totalStatic, __int64 &totalDynamic)
+{
+ if(!swf) return;
+
+ IggyMemoryUseInfo memoryInfo;
+ rrbool res;
+ int iteration = 0;
+ __int64 sceneStatic = 0;
+ __int64 sceneDynamic = 0;
+ while(res = IggyDebugGetMemoryUseInfo ( swf ,
+ NULL ,
+ "" ,
+ 0 ,
+ iteration ,
+ &memoryInfo ))
+ {
+ sceneStatic += memoryInfo.static_allocation_bytes;
+ sceneDynamic += memoryInfo.dynamic_allocation_bytes;
+ totalStatic += memoryInfo.static_allocation_bytes;
+ totalDynamic += memoryInfo.dynamic_allocation_bytes;
+ ++iteration;
+
+ }
+
+ app.DebugPrintf(app.USER_SR, " \\- Scene static: %d , Scene dynamic: %d , Total: %d - %ls\n", sceneStatic, sceneDynamic, sceneStatic + sceneDynamic, getMoviePath().c_str());
+}
+
+void UIScene::tick()
+{
+ if(m_bIsReloading) return;
+ if(m_hasTickedOnce) m_bCanHandleInput = true;
+ while(IggyPlayerReadyToTick( swf ))
+ {
+ tickTimers();
+ for(AUTO_VAR(it, m_controls.begin()); it != m_controls.end(); ++it)
+ {
+ (*it)->tick();
+ }
+ IggyPlayerTickRS( swf );
+ m_hasTickedOnce = true;
+ }
+}
+
+UIControl* UIScene::GetMainPanel()
+{
+ return NULL;
+}
+
+
+void UIScene::addTimer(int id, int ms)
+{
+ int currentTime = System::currentTimeMillis();
+
+ TimerInfo info;
+ info.running = true;
+ info.duration = ms;
+ info.targetTime = currentTime + ms;
+ m_timers[id] = info;
+}
+
+void UIScene::killTimer(int id)
+{
+ AUTO_VAR(it, m_timers.find(id));
+ if(it != m_timers.end())
+ {
+ it->second.running = false;
+ }
+}
+
+void UIScene::tickTimers()
+{
+ int currentTime = System::currentTimeMillis();
+ for(AUTO_VAR(it, m_timers.begin()); it != m_timers.end();)
+ {
+ if(!it->second.running)
+ {
+ it = m_timers.erase(it);
+ }
+ else
+ {
+ if(currentTime > it->second.targetTime)
+ {
+ handleTimerComplete(it->first);
+
+ // Auto-restart
+ it->second.targetTime = it->second.duration + currentTime;
+ }
+ ++it;
+ }
+ }
+}
+
+IggyName UIScene::registerFastName(const wstring &name)
+{
+ IggyName var;
+ AUTO_VAR(it,m_fastNames.find(name));
+ if(it != m_fastNames.end())
+ {
+ var = it->second;
+ }
+ else
+ {
+ var = IggyPlayerCreateFastName ( getMovie() , (IggyUTF16 *)name.c_str() , -1 );
+ m_fastNames[name] = var;
+ }
+ return var;
+}
+
+void UIScene::removeControl( UIControl_Base *control, bool centreScene)
+{
+ IggyDataValue result;
+ IggyDataValue value[2];
+
+ string name = control->getControlName();
+ IggyStringUTF8 stringVal;
+ stringVal.string = (char*)name.c_str();
+ stringVal.length = name.length();
+ value[0].type = IGGY_DATATYPE_string_UTF8;
+ value[0].string8 = stringVal;
+
+ value[1].type = IGGY_DATATYPE_boolean;
+ value[1].boolval = centreScene;
+ IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcRemoveObject , 2 , value );
+
+#ifdef __PSVITA__
+ // update the button positions since they may have changed
+ UpdateSceneControls();
+
+ // mark the button as removed
+ control->setHidden(true);
+ // remove it from the touchboxes
+ ui.TouchBoxRebuild(control->getParentScene());
+#endif
+
+}
+
+void UIScene::slideLeft()
+{
+ IggyDataValue result;
+ IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSlideLeft , 0 , NULL );
+}
+
+void UIScene::slideRight()
+{
+ IggyDataValue result;
+ IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSlideRight , 0 , NULL );
+}
+
+void UIScene::doHorizontalResizeCheck()
+{
+ IggyDataValue result;
+ IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcHorizontalResizeCheck , 0 , NULL );
+}
+
+void UIScene::render(S32 width, S32 height, C4JRender::eViewportType viewport)
+{
+ if(m_bIsReloading) return;
+ if(!m_hasTickedOnce || !swf) return;
+ ui.setupRenderPosition(viewport);
+ IggyPlayerSetDisplaySize( swf, width, height );
+ IggyPlayerDraw( swf );
+}
+
+void UIScene::setOpacity(float percent)
+{
+ if(percent != m_lastOpacity || (m_bUpdateOpacity && getMovie()))
+ {
+ m_lastOpacity = percent;
+
+ // 4J-TomK once a scene has been freshly loaded or re-loaded we force update opacity via initialiseMovie
+ if(m_bUpdateOpacity)
+ m_bUpdateOpacity = false;
+
+ IggyDataValue result;
+ IggyDataValue value[1];
+ value[0].type = IGGY_DATATYPE_number;
+ value[0].number = percent;
+
+ IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetAlpha , 1 , value );
+ }
+}
+
+void UIScene::setVisible(bool visible)
+{
+ m_bVisible = visible;
+}
+
+void UIScene::customDraw(IggyCustomDrawCallbackRegion *region)
+{
+ app.DebugPrintf("Handling custom draw for scene with no override!\n");
+}
+
+void UIScene::customDrawSlotControl(IggyCustomDrawCallbackRegion *region, int iPad, shared_ptr<ItemInstance> item, float fAlpha, bool isFoil, bool bDecorations)
+{
+ if (item!= NULL)
+ {
+ if(m_cacheSlotRenders)
+ {
+ if( (m_cachedSlotDraw.size() + 1) == m_expectedCachedSlotCount)
+ {
+ //Make sure that pMinecraft->player is the correct player so that player specific rendering
+ // eg clock and compass, are rendered correctly
+ Minecraft *pMinecraft=Minecraft::GetInstance();
+ shared_ptr<MultiplayerLocalPlayer> oldPlayer = pMinecraft->player;
+ if( iPad >= 0 && iPad < XUSER_MAX_COUNT ) pMinecraft->player = pMinecraft->localplayers[iPad];
+
+ // Setup GDraw, normal game render states and matrices
+ //CustomDrawData *customDrawRegion = ui.setupCustomDraw(this,region);
+ PIXBeginNamedEvent(0,"Starting Iggy custom draw\n");
+ CustomDrawData *customDrawRegion = ui.calculateCustomDraw(region);
+ ui.beginIggyCustomDraw4J(region, customDrawRegion);
+ ui.setupCustomDrawGameState();
+
+ int list = m_parentLayer->m_parentGroup->getCommandBufferList();
+
+ bool useCommandBuffers = false;
+#ifdef _XBOX_ONE
+ useCommandBuffers = true;
+
+ // 4J Stu - Temporary until we fix the glint animation which needs updated if we are just replaying a command buffer
+ m_needsCacheRendered = true;
+#endif
+
+ if(!useCommandBuffers || m_needsCacheRendered)
+ {
+#if (!defined __PS3__) && (!defined __PSVITA__)
+ if(useCommandBuffers) RenderManager.CBuffStart(list, true);
+#endif
+ PIXBeginNamedEvent(0,"Draw uncached");
+ ui.setupCustomDrawMatrices(this, customDrawRegion);
+ _customDrawSlotControl(customDrawRegion, iPad, item, fAlpha, isFoil, bDecorations, useCommandBuffers);
+ delete customDrawRegion;
+ PIXEndNamedEvent();
+
+ PIXBeginNamedEvent(0,"Draw all cache");
+ // Draw all the cached slots
+ for(AUTO_VAR(it, m_cachedSlotDraw.begin()); it != m_cachedSlotDraw.end(); ++it)
+ {
+ CachedSlotDrawData *drawData = *it;
+ ui.setupCustomDrawMatrices(this, drawData->customDrawRegion);
+ _customDrawSlotControl(drawData->customDrawRegion, iPad, drawData->item, drawData->fAlpha, drawData->isFoil, drawData->bDecorations, useCommandBuffers);
+ delete drawData->customDrawRegion;
+ delete drawData;
+ }
+ PIXEndNamedEvent();
+#ifndef __PS3__
+ if(useCommandBuffers) RenderManager.CBuffEnd();
+#endif
+ }
+ m_cachedSlotDraw.clear();
+
+#ifndef __PS3__
+ if(useCommandBuffers) RenderManager.CBuffCall(list);
+#endif
+
+ // Finish GDraw and anything else that needs to be finalised
+ ui.endCustomDraw(region);
+
+ pMinecraft->player = oldPlayer;
+ }
+ else
+ {
+ PIXBeginNamedEvent(0,"Caching region");
+ CachedSlotDrawData *drawData = new CachedSlotDrawData();
+ drawData->item = item;
+ drawData->fAlpha = fAlpha;
+ drawData->isFoil = isFoil;
+ drawData->bDecorations = bDecorations;
+ drawData->customDrawRegion = ui.calculateCustomDraw(region);
+
+ m_cachedSlotDraw.push_back(drawData);
+ PIXEndNamedEvent();
+ }
+ }
+ else
+ {
+ // Setup GDraw, normal game render states and matrices
+ CustomDrawData *customDrawRegion = ui.setupCustomDraw(this,region);
+
+ Minecraft *pMinecraft=Minecraft::GetInstance();
+
+ //Make sure that pMinecraft->player is the correct player so that player specific rendering
+ // eg clock and compass, are rendered correctly
+ shared_ptr<MultiplayerLocalPlayer> oldPlayer = pMinecraft->player;
+ if( iPad >= 0 && iPad < XUSER_MAX_COUNT ) pMinecraft->player = pMinecraft->localplayers[iPad];
+
+ _customDrawSlotControl(customDrawRegion, iPad, item, fAlpha, isFoil, bDecorations, false);
+ delete customDrawRegion;
+ pMinecraft->player = oldPlayer;
+
+ // Finish GDraw and anything else that needs to be finalised
+ ui.endCustomDraw(region);
+ }
+ }
+}
+
+void UIScene::_customDrawSlotControl(CustomDrawData *region, int iPad, shared_ptr<ItemInstance> item, float fAlpha, bool isFoil, bool bDecorations, bool usingCommandBuffer)
+{
+ Minecraft *pMinecraft=Minecraft::GetInstance();
+
+ float bwidth,bheight;
+ bwidth = region->x1 - region->x0;
+ bheight = region->y1 - region->y0;
+
+ float x = region->x0;
+ float y = region->y0;
+
+ // Base scale on height of this control, compared to height of what the item renderer normally renders (16 pixels high). Potentially
+ // we might want separate x & y scales here
+
+ float scaleX = bwidth / 16.0f;
+ float scaleY = bheight / 16.0f;
+
+ glEnable(GL_RESCALE_NORMAL);
+ glPushMatrix();
+ glRotatef(120, 1, 0, 0);
+ Lighting::turnOn();
+ glPopMatrix();
+
+ float pop = item->popTime;
+ if (pop > 0)
+ {
+ glPushMatrix();
+ float squeeze = 1 + pop / (float) Inventory::POP_TIME_DURATION;
+ float sx = x;
+ float sy = y;
+ float sxoffs = 8 * scaleX;
+ float syoffs = 12 * scaleY;
+ glTranslatef((float)(sx + sxoffs), (float)(sy + syoffs), 0);
+ glScalef(1 / squeeze, (squeeze + 1) / 2, 1);
+ glTranslatef((float)-(sx + sxoffs), (float)-(sy + syoffs), 0);
+ }
+
+ PIXBeginNamedEvent(0,"Render and decorate");
+ if(m_pItemRenderer == NULL) m_pItemRenderer = new ItemRenderer();
+ m_pItemRenderer->renderAndDecorateItem(pMinecraft->font, pMinecraft->textures, item, x, y,scaleX,scaleY,fAlpha,isFoil,false, !usingCommandBuffer);
+ PIXEndNamedEvent();
+
+ if (pop > 0)
+ {
+ glPopMatrix();
+ }
+
+ if(bDecorations)
+ {
+ if((scaleX!=1.0f) ||(scaleY!=1.0f))
+ {
+ glPushMatrix();
+ glScalef(scaleX, scaleY, 1.0f);
+ int iX= (int)(0.5f+((float)x)/scaleX);
+ int iY= (int)(0.5f+((float)y)/scaleY);
+
+ m_pItemRenderer->renderGuiItemDecorations(pMinecraft->font, pMinecraft->textures, item, iX, iY, fAlpha);
+ glPopMatrix();
+ }
+ else
+ {
+ m_pItemRenderer->renderGuiItemDecorations(pMinecraft->font, pMinecraft->textures, item, (int)x, (int)y, fAlpha);
+ }
+ }
+
+ Lighting::turnOff();
+ glDisable(GL_RESCALE_NORMAL);
+}
+
+// 4J Stu - Not threadsafe
+//void UIScene::navigateForward(int iPad, EUIScene scene, void *initData)
+//{
+// if(m_parentLayer == NULL)
+// {
+// app.DebugPrintf("A scene is trying to navigate forwards, but it's parent layer is NULL!\n");
+//#ifndef _CONTENT_PACKAGE
+// __debugbreak();
+//#endif
+// }
+// else
+// {
+// m_parentLayer->NavigateToScene(iPad,scene,initData);
+// }
+//}
+
+void UIScene::navigateBack()
+{
+ //CD - Added for audio
+ ui.PlayUISFX(eSFX_Back);
+
+ ui.NavigateBack(m_iPad);
+
+ if(m_parentLayer == NULL)
+ {
+// app.DebugPrintf("A scene is trying to navigate back, but it's parent layer is NULL!\n");
+#ifndef _CONTENT_PACKAGE
+// __debugbreak();
+#endif
+ }
+ else
+ {
+// m_parentLayer->removeScene(this);
+
+#ifdef _DURANGO
+ if (ui.GetTopScene(0))
+ InputManager.SetEnabledGtcButtons( ui.GetTopScene(0)->getDefaultGtcButtons() );
+#endif
+ }
+
+}
+
+void UIScene::gainFocus()
+{
+ if( !bHasFocus && stealsFocus() )
+ {
+ // 4J Stu - Don't do this
+ /*
+ IggyEvent event;
+ IggyMakeEventFocusGained( &event , 0);
+
+ IggyEventResult result;
+ IggyPlayerDispatchEventRS( getMovie() , &event , &result );
+
+ app.DebugPrintf("Sent gain focus event to scene\n");
+ */
+ bHasFocus = true;
+ if(app.GetGameStarted() && needsReloaded())
+ {
+ reloadMovie();
+ }
+
+ updateTooltips();
+ updateComponents();
+
+ if(!m_bFocussedOnce)
+ {
+ IggyDataValue result;
+ IggyDataValue value[1];
+
+ value[0].type = IGGY_DATATYPE_number;
+ value[0].number = -1;
+
+ IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetFocus , 1 , value );
+ }
+
+ handleGainFocus(m_bFocussedOnce);
+ if(bHasFocus) m_bFocussedOnce = true;
+ }
+ else if(bHasFocus && stealsFocus())
+ {
+ updateTooltips();
+ }
+}
+
+void UIScene::loseFocus()
+{
+ if(bHasFocus)
+ {
+ // 4J Stu - Don't do this
+ /*
+ IggyEvent event;
+ IggyMakeEventFocusLost( &event );
+ IggyEventResult result;
+ IggyPlayerDispatchEventRS ( getMovie() , &event , &result );
+ */
+
+ app.DebugPrintf("Sent lose focus event to scene\n");
+ bHasFocus = false;
+ handleLoseFocus();
+ }
+}
+
+void UIScene::handleGainFocus(bool navBack)
+{
+#ifdef _DURANGO
+ InputManager.SetEnabledGtcButtons( this->getDefaultGtcButtons() );
+#endif
+}
+
+void UIScene::updateTooltips()
+{
+ ui.SetTooltips(m_iPad, -1);
+}
+
+void UIScene::sendInputToMovie(int key, bool repeat, bool pressed, bool released)
+{
+ if(!swf) return;
+
+ int iggyKeyCode = convertGameActionToIggyKeycode(key);
+
+ if(iggyKeyCode < 0)
+ {
+ app.DebugPrintf("UI WARNING: Ignoring input as game action does not translate to an Iggy keycode\n");
+ return;
+ }
+ IggyEvent keyEvent;
+ // 4J Stu - Keyloc is always standard as we don't care about shift/alt
+ IggyMakeEventKey( &keyEvent, pressed?IGGY_KEYEVENT_Down:IGGY_KEYEVENT_Up, (IggyKeycode)iggyKeyCode, IGGY_KEYLOC_Standard );
+
+ IggyEventResult result;
+ IggyPlayerDispatchEventRS ( swf , &keyEvent , &result );
+}
+
+int UIScene::convertGameActionToIggyKeycode(int action)
+{
+ int keycode = -1;
+ switch(action)
+ {
+#ifdef __ORBIS__
+ case ACTION_MENU_TOUCHPAD_PRESS:
+#endif
+ case ACTION_MENU_A:
+ keycode = IGGY_KEYCODE_ENTER;
+ break;
+ case ACTION_MENU_B:
+ keycode = IGGY_KEYCODE_ESCAPE;
+ break;
+ case ACTION_MENU_X:
+ keycode = IGGY_KEYCODE_F1;
+ break;
+ case ACTION_MENU_Y:
+ keycode = IGGY_KEYCODE_F2;
+ break;
+ case ACTION_MENU_OK:
+ keycode = IGGY_KEYCODE_ENTER;
+ break;
+ case ACTION_MENU_CANCEL:
+ keycode = IGGY_KEYCODE_ESCAPE;
+ break;
+ case ACTION_MENU_UP:
+ keycode = IGGY_KEYCODE_UP;
+ break;
+ case ACTION_MENU_DOWN:
+ keycode = IGGY_KEYCODE_DOWN;
+ break;
+ case ACTION_MENU_RIGHT:
+ keycode = IGGY_KEYCODE_RIGHT;
+ break;
+ case ACTION_MENU_LEFT:
+ keycode = IGGY_KEYCODE_LEFT;
+ break;
+ case ACTION_MENU_PAGEUP:
+ keycode = IGGY_KEYCODE_PAGE_UP;
+ break;
+ case ACTION_MENU_PAGEDOWN:
+ keycode = IGGY_KEYCODE_PAGE_DOWN;
+ break;
+ case ACTION_MENU_RIGHT_SCROLL:
+ keycode = IGGY_KEYCODE_F3;
+ break;
+ case ACTION_MENU_LEFT_SCROLL:
+ keycode = IGGY_KEYCODE_F4;
+ break;
+ case ACTION_MENU_STICK_PRESS:
+ break;
+ case ACTION_MENU_OTHER_STICK_PRESS:
+ break;
+ case ACTION_MENU_OTHER_STICK_UP:
+ keycode = IGGY_KEYCODE_F11;
+ break;
+ case ACTION_MENU_OTHER_STICK_DOWN:
+ keycode = IGGY_KEYCODE_F12;
+ break;
+ case ACTION_MENU_OTHER_STICK_LEFT:
+ break;
+ case ACTION_MENU_OTHER_STICK_RIGHT:
+ break;
+ };
+
+ return keycode;
+}
+
+bool UIScene::allowRepeat(int key)
+{
+ // 4J-PB - ignore repeats of action ABXY buttons
+ // fix for PS3 213 - [MAIN MENU] Holding down buttons will continue to activate every prompt.
+ switch(key)
+ {
+ case ACTION_MENU_OK:
+ case ACTION_MENU_CANCEL:
+ case ACTION_MENU_A:
+ case ACTION_MENU_B:
+ case ACTION_MENU_X:
+ case ACTION_MENU_Y:
+ return false;
+ }
+ return true;
+}
+
+void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call)
+{
+ if(wcscmp((wchar_t *)call->function_name.string,L"handlePress")==0)
+ {
+ if(call->num_arguments != 2)
+ {
+ app.DebugPrintf("Callback for handlePress did not have the correct number of arguments\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_number)
+ {
+ app.DebugPrintf("Arguments for handlePress were not of the correct type\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ handlePress(call->arguments[0].number, call->arguments[1].number);
+ }
+ else if(wcscmp((wchar_t *)call->function_name.string,L"handleFocusChange")==0)
+ {
+ if(call->num_arguments != 2)
+ {
+ app.DebugPrintf("Callback for handleFocusChange did not have the correct number of arguments\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_number)
+ {
+ app.DebugPrintf("Arguments for handleFocusChange were not of the correct type\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ _handleFocusChange(call->arguments[0].number, call->arguments[1].number);
+ }
+ else if(wcscmp((wchar_t *)call->function_name.string,L"handleInitFocus")==0)
+ {
+ if(call->num_arguments != 2)
+ {
+ app.DebugPrintf("Callback for handleInitFocus did not have the correct number of arguments\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_number)
+ {
+ app.DebugPrintf("Arguments for handleInitFocus were not of the correct type\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ _handleInitFocus(call->arguments[0].number, call->arguments[1].number);
+ }
+ else if(wcscmp((wchar_t *)call->function_name.string,L"handleCheckboxToggled")==0)
+ {
+ if(call->num_arguments != 2)
+ {
+ app.DebugPrintf("Callback for handleCheckboxToggled did not have the correct number of arguments\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_boolean)
+ {
+ app.DebugPrintf("Arguments for handleCheckboxToggled were not of the correct type\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ handleCheckboxToggled(call->arguments[0].number, call->arguments[1].boolval);
+ }
+ else if(wcscmp((wchar_t *)call->function_name.string,L"handleSliderMove")==0)
+ {
+ if(call->num_arguments != 2)
+ {
+ app.DebugPrintf("Callback for handleSliderMove did not have the correct number of arguments\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_number)
+ {
+ app.DebugPrintf("Arguments for handleSliderMove were not of the correct type\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ handleSliderMove(call->arguments[0].number, call->arguments[1].number);
+ }
+ else if(wcscmp((wchar_t *)call->function_name.string,L"handleAnimationEnd")==0)
+ {
+ if(call->num_arguments != 0)
+ {
+ app.DebugPrintf("Callback for handleAnimationEnd did not have the correct number of arguments\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ handleAnimationEnd();
+ }
+ else if(wcscmp((wchar_t *)call->function_name.string,L"handleSelectionChanged")==0)
+ {
+ if(call->num_arguments != 1)
+ {
+ app.DebugPrintf("Callback for handleSelectionChanged did not have the correct number of arguments\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ if(call->arguments[0].type != IGGY_DATATYPE_number)
+ {
+ app.DebugPrintf("Arguments for handleSelectionChanged were not of the correct type\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ handleSelectionChanged(call->arguments[0].number);
+ }
+ else if(wcscmp((wchar_t *)call->function_name.string,L"handleRequestMoreData")==0)
+ {
+ if(call->num_arguments == 0)
+ {
+ handleRequestMoreData(0,false);
+ }
+ else
+ {
+ if(call->num_arguments != 2)
+ {
+ app.DebugPrintf("Callback for handleRequestMoreData did not have the correct number of arguments\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ if(call->arguments[0].type != IGGY_DATATYPE_number || call->arguments[1].type != IGGY_DATATYPE_boolean)
+ {
+ app.DebugPrintf("Arguments for handleRequestMoreData were not of the correct type\n");
+#ifndef _CONTENT_PACKAGE
+ __debugbreak();
+#endif
+ return;
+ }
+ handleRequestMoreData(call->arguments[0].number, call->arguments[1].boolval);
+ }
+ }
+ else if(wcscmp((wchar_t *)call->function_name.string,L"handleTouchBoxRebuild")==0)
+ {
+ handleTouchBoxRebuild();
+ }
+ else
+ {
+ app.DebugPrintf("Unhandled callback: %s\n", call->function_name.string);
+ }
+}
+
+void UIScene::registerSubstitutionTexture(const wstring &textureName, PBYTE pbData, DWORD dwLength, bool deleteData)
+{
+ m_registeredTextures[textureName] = deleteData;;
+ ui.registerSubstitutionTexture(textureName, pbData, dwLength);
+}
+
+bool UIScene::hasRegisteredSubstitutionTexture(const wstring &textureName)
+{
+ AUTO_VAR(it, m_registeredTextures.find( textureName ) );
+
+ return it != m_registeredTextures.end();
+}
+
+void UIScene::_handleFocusChange(F64 controlId, F64 childId)
+{
+ m_iFocusControl = (int)controlId;
+ m_iFocusChild = (int)childId;
+
+ handleFocusChange(controlId, childId);
+ ui.PlayUISFX(eSFX_Focus);
+}
+
+void UIScene::_handleInitFocus(F64 controlId, F64 childId)
+{
+ m_iFocusControl = (int)controlId;
+ m_iFocusChild = (int)childId;
+
+ //handleInitFocus(controlId, childId);
+ handleFocusChange(controlId, childId);
+}
+
+bool UIScene::controlHasFocus(int iControlId)
+{
+ return m_iFocusControl == iControlId;
+}
+
+bool UIScene::controlHasFocus(UIControl_Base *control)
+{
+ return controlHasFocus( control->getId() );
+}
+
+int UIScene::getControlChildFocus()
+{
+ return m_iFocusChild;
+}
+
+int UIScene::getControlFocus()
+{
+ return m_iFocusControl;
+}
+
+void UIScene::setBackScene(UIScene *scene)
+{
+ m_backScene = scene;
+}
+
+UIScene *UIScene::getBackScene()
+{
+ return m_backScene;
+}
+#ifdef __PSVITA__
+void UIScene::UpdateSceneControls()
+{
+ AUTO_VAR(itEnd, GetControls()->end());
+ for (AUTO_VAR(it, GetControls()->begin()); it != itEnd; it++)
+ {
+ UIControl *control=(UIControl *)*it;
+ control->UpdateControl();
+ }
+}
+#endif
+
+size_t UIScene::GetCallbackUniqueId()
+{
+ if( m_callbackUniqueId == 0)
+ {
+ m_callbackUniqueId = ui.RegisterForCallbackId(this);
+ }
+ return m_callbackUniqueId;
+}
+
+bool UIScene::isReadyToDelete()
+{
+ return true;
+} \ No newline at end of file