Merge branch 'customize-skin-and-capes' into 'main'

Added customizable skin + capes and fixed flipped third person

See merge request whispers-lce/client!6
This commit is contained in:
Whisper W
2026-03-05 18:41:56 -05:00
19 changed files with 1359 additions and 337 deletions

View File

@@ -4145,6 +4145,35 @@ void CMinecraftApp::loadMediaArchive()
if (!mediapath.empty())
{
m_mediaArchive = new ArchiveFile( File(mediapath) );
#ifdef _WINDOWS64
{
vector<wstring>* fileList = m_mediaArchive->getFileList();
for (AUTO_VAR(it, fileList->begin()); it != fileList->end(); ++it)
{
const wstring& name = *it;
if (name.size() >= 7 && (name.substr(0, 7) == L"dlccape" || name.substr(0, 7) == L"defskin"))
{
byteArray data = m_mediaArchive->getFile(name);
AddMemoryTextureFile(name, data.data, data.length);
}
}
delete fileList;
}
#endif
}
#if 0
string path = "Common\\media.arc";

View File

@@ -84,6 +84,8 @@
#include "UIScene_SettingsGraphicsMenu.h"
#include "UIScene_SettingsUIMenu.h"
#include "UIScene_SkinSelectMenu.h"
#include "UIScene_CustomizeCharacterMenu.h"
#include "UIScene_CapeSelectMenu.h"
#include "UIScene_HowToPlayMenu.h"
#include "UIScene_HowToPlay.h"
#include "UIScene_ControlsMenu.h"

View File

@@ -68,7 +68,7 @@ void UIControl_PlayerSkinPreview::tick()
++m_framesAnimatingRotation;
m_yRot = m_fOriginalRotation + m_framesAnimatingRotation * ( (m_fTargetRotation - m_fOriginalRotation) / CHANGING_SKIN_FRAMES );
//if(m_framesAnimatingRotation == CHANGING_SKIN_FRAMES) m_bAnimatingToFacing = false;
if(m_framesAnimatingRotation == CHANGING_SKIN_FRAMES) m_bAnimatingToFacing = false;
}
else
{
@@ -150,6 +150,28 @@ void UIControl_PlayerSkinPreview::SetFacing(ESkinPreviewFacing facing, bool bAni
m_fTargetRotation = LOOK_RIGHT_EXTENT;
m_bRotatingLeft = true;
break;
case e_SkinPreviewFacing_Backward:
m_fTargetRotation = (m_yRot < 0) ? -180.0f : 180.0f;
m_bRotatingLeft = (m_fTargetRotation > 0);
break;
case e_SkinPreviewFacing_BackLeft:
{
float diff = 135.0f - (float)m_yRot;
if(diff > 180.0f) diff -= 360.0f;
if(diff < -180.0f) diff += 360.0f;
m_fTargetRotation = (float)m_yRot + diff;
m_bRotatingLeft = (diff > 0);
}
break;
case e_SkinPreviewFacing_BackRight:
{
float diff = -135.0f - (float)m_yRot;
if(diff > 180.0f) diff -= 360.0f;
if(diff < -180.0f) diff += 360.0f;
m_fTargetRotation = (float)m_yRot + diff;
m_bRotatingLeft = (diff > 0);
}
break;
}
if(!bAnimate)

View File

@@ -59,6 +59,9 @@ public:
e_SkinPreviewFacing_Forward,
e_SkinPreviewFacing_Left,
e_SkinPreviewFacing_Right,
e_SkinPreviewFacing_Backward,
e_SkinPreviewFacing_BackLeft,
e_SkinPreviewFacing_BackRight,
};
UIControl_PlayerSkinPreview();

View File

@@ -80,6 +80,8 @@ enum EUIScene
eUIComponent_Chat,
eUIScene_ReinstallMenu,
eUIScene_SkinSelectMenu,
eUIScene_CustomizeCharacterMenu,
eUIScene_CapeSelectMenu,
eUIScene_TextEntry,
eUIScene_InGameHostOptionsMenu,
eUIScene_InGamePlayerOptionsMenu,

View File

@@ -279,6 +279,12 @@ bool UILayer::NavigateToScene(int iPad, EUIScene scene, void *initData)
case eUIScene_SkinSelectMenu:
newScene = new UIScene_SkinSelectMenu(iPad, initData, this);
break;
case eUIScene_CustomizeCharacterMenu:
newScene = new UIScene_CustomizeCharacterMenu(iPad, initData, this);
break;
case eUIScene_CapeSelectMenu:
newScene = new UIScene_CapeSelectMenu(iPad, initData, this);
break;
case eUIScene_HowToPlayMenu:
newScene = new UIScene_HowToPlayMenu(iPad, initData, this);
break;

View File

@@ -0,0 +1,619 @@
#include "stdafx.h"
#include "UI.h"
#include "UIScene_CapeSelectMenu.h"
#include "..\..\Minecraft.h"
#include "..\..\..\Minecraft.World\StringHelpers.h"
#include "..\..\..\Minecraft.World\Definitions.h"
// Cape names — index 0 = No Cape, 1-52 correspond to dlccape00000001.png ... dlccape00000052.png
const wchar_t *UIScene_CapeSelectMenu::k_capeNames[UIScene_CapeSelectMenu::k_capeCount] =
{
L"No Cape",
L"15th Anniversary",
L"MCC 15th Year",
L"Minecraft Experience",
L"MINECON 2011",
L"MINECON 2012",
L"MINECON 2013",
L"MINECON 2015",
L"MINECON 2016",
L"Mojang",
L"Mojang Classic",
L"Mojang Studios",
L"Mojang Office",
L"4J Studios",
L"Microsoft Xbox 360",
L"Xbox 1st Birthday",
L"Founder's",
L"Common",
L"The Pan",
L"Migrator",
L"One Vanilla",
L"Purple Heart",
L"Progress Pride",
L"Cherry Blossom",
L"Follower's",
L"Home",
L"Menace",
L"Yearn",
L"Idaho",
L"Copper",
L"Zombie Horse",
L"Prismarine",
L"Turtle",
L"Birthday",
L"Valentine",
L"Oxeye",
L"Cobalt",
L"Snail",
L"Size M",
L"Scrolls Champion",
L"Millionth Customer",
L"Unidentified",
L"Translator",
L"Chinese Translator",
L"Moderator",
L"Mapmaker",
L"Christmas 2010",
L"New Year's 2011",
L"Bacon",
L"DannyBstyle's",
L"JulianClark's",
L"Cheapsh0t's",
L"MrMessiah's",
};
// Maps a default skin carousel index to the corresponding built-in TEXTURE_NAME.
// eDefaultSkins enum: ServerSelected=0, Skin0=1, Skin1=2, ..., Skin7=8
// This must match UIScene_SkinSelectMenu::getTextureId().
TEXTURE_NAME UIScene_CapeSelectMenu::getDefaultSkinTexture(int defaultSkinIndex)
{
switch(defaultSkinIndex)
{
case eDefaultSkins_ServerSelected:
case eDefaultSkins_Skin0: return TN_MOB_CHAR;
case eDefaultSkins_Skin1: return TN_MOB_CHAR1;
case eDefaultSkins_Skin2: return TN_MOB_CHAR2;
case eDefaultSkins_Skin3: return TN_MOB_CHAR3;
case eDefaultSkins_Skin4: return TN_MOB_CHAR4;
case eDefaultSkins_Skin5: return TN_MOB_CHAR5;
case eDefaultSkins_Skin6: return TN_MOB_CHAR6;
case eDefaultSkins_Skin7: return TN_MOB_CHAR7;
default: return TN_MOB_CHAR;
}
}
// Reads the player's current skin and populates m_currentSkinPath / m_currentSkinTexture
void UIScene_CapeSelectMenu::refreshCurrentSkinTexture()
{
DWORD dwSkin = app.GetPlayerSkinId(m_iPad);
if(GET_IS_DLC_SKIN_FROM_BITMASK(dwSkin) || GET_UGC_SKIN_ID_FROM_BITMASK(dwSkin) != 0)
{
// DLC or UGC skin — path is in MEM_Files
m_currentSkinPath = app.GetPlayerSkinName(m_iPad);
m_currentSkinTexture = TN_MOB_CHAR;
}
else
{
// Default skin (Steve/Alex/etc.) — use built-in engine texture, no file path
m_currentSkinPath = L"";
m_currentSkinTexture = getDefaultSkinTexture(GET_DEFAULT_SKIN_ID_FROM_BITMASK(dwSkin));
}
}
// Returns "dlccapeXXXXXXXX.png" for idx >= 1, or "" for idx == 0 (No Cape)
wstring UIScene_CapeSelectMenu::getCapePathForIndex(int idx)
{
if(idx <= 0) return L"";
wchar_t buf[32];
swprintf(buf, 32, L"dlccape%08d.png", idx);
return wstring(buf);
}
int UIScene_CapeSelectMenu::getNextCapeIndex(int idx)
{
int size = (int)m_tabs[m_tabIndex].capes.size();
return (idx + 1) % size;
}
int UIScene_CapeSelectMenu::getPreviousCapeIndex(int idx)
{
int size = (int)m_tabs[m_tabIndex].capes.size();
return (idx + size - 1) % size;
}
int UIScene_CapeSelectMenu::getNextTabIndex(int idx) const
{
return (idx + 1) % (int)m_tabs.size();
}
int UIScene_CapeSelectMenu::getPreviousTabIndex(int idx) const
{
return (idx + (int)m_tabs.size() - 1) % (int)m_tabs.size();
}
// Build m_tabs from the hardcoded cape list (tab 0) and any DLC skin packs that have capes.
// Called once at construction after DLC is mounted. Fully dynamic — no pack names hardcoded.
void UIScene_CapeSelectMenu::buildTabs()
{
m_tabs.clear();
// Tab 0: "Capes"
{
CapeTab mainTab;
mainTab.packName = L"Capes";
for(int i = 0; i < k_capeCount; ++i)
{
CapeEntry e;
e.name = k_capeNames[i];
e.path = getCapePathForIndex(i);
mainTab.capes.push_back(e);
}
m_tabs.push_back(mainTab);
}
// Tabs 1+: one per DLC skin pack that has at least one capped skin
DWORD packCount = app.m_dlcManager.getPackCount(DLCManager::e_DLCType_Skin);
for(DWORD p = 0; p < packCount; ++p)
{
DLCPack *pack = app.m_dlcManager.getPack(p, DLCManager::e_DLCType_Skin);
if(!pack) continue;
CapeTab tab;
tab.packName = pack->getName();
// "No Cape" is always the first entry in a pack tab
CapeEntry noCape;
noCape.name = L"No Cape";
noCape.path = L"";
tab.capes.push_back(noCape);
DWORD skinCount = pack->getSkinCount();
for(DWORD s = 0; s < skinCount; ++s)
{
DLCSkinFile *skinFile = pack->getSkinFile(s);
if(!skinFile) continue;
wstring capePath = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape);
if(capePath.empty()) continue;
CapeEntry e;
wstring skinName = skinFile->getParameterAsString(DLCManager::e_DLCParamType_DisplayName);
e.name = skinName + L"'s Cape";
e.path = capePath;
tab.capes.push_back(e);
}
// Only add the tab if at least one skin had a cape
if(tab.capes.size() > 1)
{
m_tabs.push_back(tab);
}
}
}
// Switch to m_tabIndex, reset to cape 0, refresh display
void UIScene_CapeSelectMenu::handleTabIndexChanged()
{
m_capeIndex = 0;
handleCapeIndexChanged();
updateTabDisplay();
}
// Set left/centre/right labels for the current tab and its neighbours
void UIScene_CapeSelectMenu::updateTabDisplay()
{
if(m_tabs.size() <= 1)
{
setLeftLabel(L"");
setRightLabel(L"");
return;
}
setLeftLabel(m_tabs[getPreviousTabIndex(m_tabIndex)].packName);
setRightLabel(m_tabs[getNextTabIndex(m_tabIndex)].packName);
}
UIScene_CapeSelectMenu::UIScene_CapeSelectMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
{
initialiseMovie();
m_labelSelected.init( app.GetString(IDS_SELECTED) );
m_bSlidingSkins = false;
m_bAnimatingMove = false;
m_bCapeIndexChanged = false;
m_currentNavigation = eCapeNavigation_Cape;
// Trigger DLC skin loading so pack capes are in m_MEM_Files before buildTabs()
app.StartInstallDLCProcess(m_iPad);
// Build tab list from hardcoded capes + any DLC skin packs that have capes
buildTabs();
// Find the tab and entry that match the player's currently saved cape path
wstring savedCapePath = app.GetPlayerCapeName(m_iPad);
m_tabIndex = 0;
m_capeIndex = 0;
for(int t = 0; t < (int)m_tabs.size(); ++t)
{
for(int c = 0; c < (int)m_tabs[t].capes.size(); ++c)
{
if(m_tabs[t].capes[c].path == savedCapePath)
{
m_tabIndex = t;
m_capeIndex = c;
goto found_saved_cape;
}
}
}
found_saved_cape:
m_confirmedTabIndex = m_tabIndex;
m_confirmedCapeIndex = m_capeIndex;
refreshCurrentSkinTexture();
m_labelCapeName.init(L"");
m_labelSkinOrigin.init(L"");
m_controlTimer.setVisible(false);
// Character facing — models face backward so the cape is visible
m_characters[eCharacter_Current].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Backward);
m_characters[eCharacter_Next1].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackLeft);
m_characters[eCharacter_Next2].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackLeft);
m_characters[eCharacter_Next3].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackLeft);
m_characters[eCharacter_Next4].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackLeft);
m_characters[eCharacter_Previous1].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackRight);
m_characters[eCharacter_Previous2].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackRight);
m_characters[eCharacter_Previous3].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackRight);
m_characters[eCharacter_Previous4].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackRight);
// Populate the initial preview and tab labels
handleCapeIndexChanged();
updateTabDisplay();
}
wstring UIScene_CapeSelectMenu::getMoviePath()
{
if(app.GetLocalPlayerCount() > 1)
{
return L"SkinSelectMenuSplit";
}
else
{
return L"SkinSelectMenu";
}
}
void UIScene_CapeSelectMenu::tick()
{
UIScene::tick();
if(m_bCapeIndexChanged)
{
m_bCapeIndexChanged = false;
handleCapeIndexChanged();
}
}
void UIScene_CapeSelectMenu::updateTooltips()
{
ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT_SKIN, IDS_TOOLTIPS_CANCEL, -1, -1, -1, -1, -1, -1, IDS_TOOLTIPS_NAVIGATE );
}
void UIScene_CapeSelectMenu::updateComponents()
{
m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, false);
}
void UIScene_CapeSelectMenu::handleAnimationEnd()
{
if(m_bSlidingSkins)
{
m_bSlidingSkins = false;
m_characters[eCharacter_Current].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Backward, false);
m_characters[eCharacter_Next1].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackLeft, false);
m_characters[eCharacter_Previous1].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackRight, false);
m_bCapeIndexChanged = true;
m_bAnimatingMove = false;
}
}
void UIScene_CapeSelectMenu::handleCapeIndexChanged()
{
const CapeTab &tab = m_tabs[m_tabIndex];
bool isConfirmed = (m_tabIndex == m_confirmedTabIndex && m_capeIndex == m_confirmedCapeIndex);
setCharacterSelected(isConfirmed);
setCharacterLocked(false);
m_controlSkinNamePlate.setVisible(true);
m_characters[eCharacter_Current].setVisible(true);
m_characters[eCharacter_Current].SetTexture(m_currentSkinPath, m_currentSkinTexture);
m_characters[eCharacter_Current].SetCapeTexture(tab.capes[m_capeIndex].path);
// Update adjacent preview slots
int nextIdx = m_capeIndex;
int prevIdx = m_capeIndex;
for(BYTE i = 0; i < sidePreviewControls; ++i)
{
nextIdx = getNextCapeIndex(nextIdx);
m_characters[eCharacter_Next1 + i].setVisible(true);
m_characters[eCharacter_Next1 + i].SetTexture(m_currentSkinPath, m_currentSkinTexture);
m_characters[eCharacter_Next1 + i].SetCapeTexture(tab.capes[nextIdx].path);
}
for(BYTE i = 0; i < sidePreviewControls; ++i)
{
prevIdx = getPreviousCapeIndex(prevIdx);
m_characters[eCharacter_Previous1 + i].setVisible(true);
m_characters[eCharacter_Previous1 + i].SetTexture(m_currentSkinPath, m_currentSkinTexture);
m_characters[eCharacter_Previous1 + i].SetCapeTexture(tab.capes[prevIdx].path);
}
// Name label and centre tab label
m_labelCapeName.init(tab.capes[m_capeIndex].name);
setCentreLabel(tab.packName);
}
void UIScene_CapeSelectMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
{
switch(key)
{
case ACTION_MENU_CANCEL:
if(pressed)
{
ui.AnimateKeyPress(iPad, key, repeat, pressed, released);
// Restore the cape to what it was when the menu opened
app.SetPlayerCape(iPad, m_tabs[m_confirmedTabIndex].capes[m_confirmedCapeIndex].path);
app.CheckGameSettingsChanged(true, iPad);
navigateBack();
}
break;
case ACTION_MENU_OK:
#ifdef __ORBIS__
case ACTION_MENU_TOUCHPAD_PRESS:
#endif
if(pressed)
{
ui.AnimateKeyPress(iPad, key, repeat, pressed, released);
// Confirm the currently highlighted cape
app.SetPlayerCape(iPad, m_tabs[m_tabIndex].capes[m_capeIndex].path);
app.CheckGameSettingsChanged(true, iPad);
m_confirmedTabIndex = m_tabIndex;
m_confirmedCapeIndex = m_capeIndex;
setCharacterSelected(true);
ui.PlayUISFX(eSFX_Press);
}
break;
case ACTION_MENU_UP:
case ACTION_MENU_DOWN:
if(pressed && !repeat && m_tabs.size() > 1)
{
ui.AnimateKeyPress(iPad, key, repeat, pressed, released);
ui.PlayUISFX(eSFX_Scroll);
m_currentNavigation = (m_currentNavigation == eCapeNavigation_Cape)
? eCapeNavigation_Tab : eCapeNavigation_Cape;
sendInputToMovie(key, repeat, pressed, released);
}
break;
case ACTION_MENU_LEFT:
if(pressed)
{
if(m_currentNavigation == eCapeNavigation_Tab)
{
if(!m_bAnimatingMove && m_tabs.size() > 1)
{
ui.AnimateKeyPress(iPad, key, repeat, pressed, released);
ui.PlayUISFX(eSFX_Scroll);
m_tabIndex = getPreviousTabIndex(m_tabIndex);
handleTabIndexChanged();
}
}
else
{
if(!m_bAnimatingMove)
{
ui.AnimateKeyPress(iPad, key, repeat, pressed, released);
ui.PlayUISFX(eSFX_Scroll);
m_capeIndex = getPreviousCapeIndex(m_capeIndex);
m_bSlidingSkins = true;
m_bAnimatingMove = true;
m_characters[eCharacter_Current].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackLeft, true);
m_characters[eCharacter_Previous1].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Backward, true);
sendInputToMovie(ACTION_MENU_RIGHT, repeat, pressed, released);
}
}
}
break;
case ACTION_MENU_RIGHT:
if(pressed)
{
if(m_currentNavigation == eCapeNavigation_Tab)
{
if(!m_bAnimatingMove && m_tabs.size() > 1)
{
ui.AnimateKeyPress(iPad, key, repeat, pressed, released);
ui.PlayUISFX(eSFX_Scroll);
m_tabIndex = getNextTabIndex(m_tabIndex);
handleTabIndexChanged();
}
}
else
{
if(!m_bAnimatingMove)
{
ui.AnimateKeyPress(iPad, key, repeat, pressed, released);
ui.PlayUISFX(eSFX_Scroll);
m_capeIndex = getNextCapeIndex(m_capeIndex);
m_bSlidingSkins = true;
m_bAnimatingMove = true;
m_characters[eCharacter_Current].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_BackRight, true);
m_characters[eCharacter_Next1].SetFacing(UIControl_PlayerSkinPreview::e_SkinPreviewFacing_Backward, true);
sendInputToMovie(ACTION_MENU_LEFT, repeat, pressed, released);
}
}
}
break;
case ACTION_MENU_OTHER_STICK_PRESS:
if(pressed)
{
ui.PlayUISFX(eSFX_Press);
m_characters[eCharacter_Current].ResetRotation();
}
break;
case ACTION_MENU_OTHER_STICK_LEFT:
if(pressed)
m_characters[eCharacter_Current].m_incYRot = true;
else if(released)
m_characters[eCharacter_Current].m_incYRot = false;
break;
case ACTION_MENU_OTHER_STICK_RIGHT:
if(pressed)
m_characters[eCharacter_Current].m_decYRot = true;
else if(released)
m_characters[eCharacter_Current].m_decYRot = false;
break;
case ACTION_MENU_OTHER_STICK_UP:
if(pressed)
m_characters[eCharacter_Current].CyclePreviousAnimation();
break;
case ACTION_MENU_OTHER_STICK_DOWN:
if(pressed)
m_characters[eCharacter_Current].CycleNextAnimation();
break;
}
}
void UIScene_CapeSelectMenu::customDraw(IggyCustomDrawCallbackRegion *region)
{
int characterId = -1;
swscanf((wchar_t*)region->name, L"Character%d", &characterId);
if(characterId == -1)
{
app.DebugPrintf("Invalid character to render found\n");
}
else
{
CustomDrawData *customDrawRegion = ui.setupCustomDraw(this, region);
delete customDrawRegion;
#ifdef __PS3__
if(region->stencil_func_ref != 0) RenderManager.StateSetStencil(GL_EQUAL, region->stencil_func_ref, region->stencil_func_mask);
#elif __PSVITA__
if(region->stencil_func_ref != 0) RenderManager.StateSetStencil(SCE_GXM_STENCIL_FUNC_EQUAL, region->stencil_func_mask, region->stencil_write_mask);
#else
if(region->stencil_func_ref != 0) RenderManager.StateSetStencil(GL_EQUAL, region->stencil_func_ref, region->stencil_func_mask, region->stencil_write_mask);
#endif
m_characters[characterId].render(region);
ui.endCustomDraw(region);
}
}
void UIScene_CapeSelectMenu::setCharacterSelected(bool selected)
{
IggyDataValue result;
IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_boolean;
value[0].boolval = selected;
IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetPlayerCharacterSelected, 1, value);
}
void UIScene_CapeSelectMenu::setCharacterLocked(bool locked)
{
IggyDataValue result;
IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_boolean;
value[0].boolval = locked;
IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetCharacterLocked, 1, value);
}
void UIScene_CapeSelectMenu::setLeftLabel(const wstring &label)
{
IggyDataValue result;
IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_string_UTF16;
value[0].string16.string = (IggyUTF16 *)label.c_str();
value[0].string16.length = (unsigned int)label.length();
IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetLeftLabel, 1, value);
}
void UIScene_CapeSelectMenu::setRightLabel(const wstring &label)
{
IggyDataValue result;
IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_string_UTF16;
value[0].string16.string = (IggyUTF16 *)label.c_str();
value[0].string16.length = (unsigned int)label.length();
IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetRightLabel, 1, value);
}
void UIScene_CapeSelectMenu::setCentreLabel(const wstring &label)
{
IggyDataValue result;
IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_string_UTF16;
value[0].string16.string = (IggyUTF16 *)label.c_str();
value[0].string16.length = (unsigned int)label.length();
IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetCentreLabel, 1, value);
}
void UIScene_CapeSelectMenu::HandleDLCInstalled()
{
app.StartInstallDLCProcess(m_iPad);
}
void UIScene_CapeSelectMenu::HandleDLCMountingComplete()
{
// DLC skin textures are now in m_MEM_Files — rebuild tabs to pick up newly mounted packs
refreshCurrentSkinTexture();
buildTabs();
// Re-locate the saved cape in the updated tab list
wstring savedCapePath = app.GetPlayerCapeName(m_iPad);
m_tabIndex = 0;
m_capeIndex = 0;
for(int t = 0; t < (int)m_tabs.size(); ++t)
{
for(int c = 0; c < (int)m_tabs[t].capes.size(); ++c)
{
if(m_tabs[t].capes[c].path == savedCapePath)
{
m_tabIndex = t;
m_capeIndex = c;
goto dlc_found_cape;
}
}
}
dlc_found_cape:
m_confirmedTabIndex = m_tabIndex;
m_confirmedCapeIndex = m_capeIndex;
handleCapeIndexChanged();
updateTabDisplay();
}

View File

@@ -0,0 +1,144 @@
#pragma once
#include "UIScene.h"
#include "UIControl_PlayerSkinPreview.h"
#include <vector>
class UIScene_CapeSelectMenu : public UIScene
{
private:
static const int k_capeCount = 53;
static const wchar_t *k_capeNames[k_capeCount];
static const BYTE sidePreviewControls = 4;
struct CapeEntry
{
wstring name;
wstring path;
};
struct CapeTab
{
wstring packName;
vector<CapeEntry> capes;
};
enum ECapeNavigation
{
eCapeNavigation_Cape,
eCapeNavigation_Tab,
};
enum ECharacters
{
eCharacter_Current,
eCharacter_Next1,
eCharacter_Next2,
eCharacter_Next3,
eCharacter_Next4,
eCharacter_Previous1,
eCharacter_Previous2,
eCharacter_Previous3,
eCharacter_Previous4,
eCharacter_COUNT,
};
UIControl_PlayerSkinPreview m_characters[eCharacter_COUNT];
UIControl_Label m_labelCapeName;
UIControl_Label m_labelSkinOrigin;
UIControl_Label m_labelSelected;
UIControl m_controlSkinNamePlate, m_controlSelectedPanel, m_controlIggyCharacters, m_controlTimer;
IggyName m_funcSetPlayerCharacterSelected, m_funcSetCharacterLocked;
IggyName m_funcSetLeftLabel, m_funcSetCentreLabel, m_funcSetRightLabel;
UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene)
UI_MAP_ELEMENT( m_controlSkinNamePlate, "SkinNamePlate")
UI_BEGIN_MAP_CHILD_ELEMENTS( m_controlSkinNamePlate )
UI_MAP_ELEMENT( m_labelCapeName, "SkinTitle1")
UI_MAP_ELEMENT( m_labelSkinOrigin, "SkinTitle2")
UI_END_MAP_CHILD_ELEMENTS()
UI_MAP_ELEMENT( m_controlSelectedPanel, "SelectedPanel" )
UI_BEGIN_MAP_CHILD_ELEMENTS( m_controlSelectedPanel )
UI_MAP_ELEMENT( m_labelSelected, "SelectedPanelLabel" )
UI_END_MAP_CHILD_ELEMENTS()
UI_MAP_ELEMENT( m_controlTimer, "Timer" )
UI_MAP_ELEMENT( m_controlIggyCharacters, "IggyCharacters" )
UI_BEGIN_MAP_CHILD_ELEMENTS( m_controlIggyCharacters )
UI_MAP_ELEMENT( m_characters[eCharacter_Current], "iggy_Character0" )
UI_MAP_ELEMENT( m_characters[eCharacter_Next1], "iggy_Character1" )
UI_MAP_ELEMENT( m_characters[eCharacter_Next2], "iggy_Character2" )
UI_MAP_ELEMENT( m_characters[eCharacter_Next3], "iggy_Character3" )
UI_MAP_ELEMENT( m_characters[eCharacter_Next4], "iggy_Character4" )
UI_MAP_ELEMENT( m_characters[eCharacter_Previous1], "iggy_Character5" )
UI_MAP_ELEMENT( m_characters[eCharacter_Previous2], "iggy_Character6" )
UI_MAP_ELEMENT( m_characters[eCharacter_Previous3], "iggy_Character7" )
UI_MAP_ELEMENT( m_characters[eCharacter_Previous4], "iggy_Character8" )
UI_END_MAP_CHILD_ELEMENTS()
UI_MAP_NAME( m_funcSetPlayerCharacterSelected, L"SetPlayerCharacterSelected" )
UI_MAP_NAME( m_funcSetCharacterLocked, L"SetCharacterLocked" )
UI_MAP_NAME( m_funcSetLeftLabel, L"SetLeftLabel" )
UI_MAP_NAME( m_funcSetCentreLabel, L"SetCenterLabel" )
UI_MAP_NAME( m_funcSetRightLabel, L"SetRightLabel" )
UI_END_MAP_ELEMENTS_AND_NAMES()
vector<CapeTab> m_tabs;
int m_tabIndex;
int m_confirmedTabIndex;
int m_capeIndex;
int m_confirmedCapeIndex;
ECapeNavigation m_currentNavigation;
wstring m_currentSkinPath;
TEXTURE_NAME m_currentSkinTexture;
bool m_bSlidingSkins;
bool m_bAnimatingMove;
bool m_bCapeIndexChanged;
public:
UIScene_CapeSelectMenu(int iPad, void *initData, UILayer *parentLayer);
virtual EUIScene getSceneType() { return eUIScene_CapeSelectMenu; }
virtual void tick();
virtual void updateTooltips();
virtual void updateComponents();
virtual void handleAnimationEnd();
virtual void HandleDLCInstalled();
virtual void HandleDLCMountingComplete();
protected:
virtual wstring getMoviePath();
public:
virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled);
virtual void customDraw(IggyCustomDrawCallbackRegion *region);
private:
void handleCapeIndexChanged();
int getNextCapeIndex(int idx);
int getPreviousCapeIndex(int idx);
void setCharacterSelected(bool selected);
void setCharacterLocked(bool locked);
void setCentreLabel(const wstring &label);
static wstring getCapePathForIndex(int idx);
static TEXTURE_NAME getDefaultSkinTexture(int defaultSkinIndex);
void refreshCurrentSkinTexture();
void buildTabs();
void handleTabIndexChanged();
void updateTabDisplay();
int getNextTabIndex(int idx) const;
int getPreviousTabIndex(int idx) const;
void setLeftLabel(const wstring &label);
void setRightLabel(const wstring &label);
};

View File

@@ -0,0 +1,128 @@
#include "stdafx.h"
#include "UI.h"
#include "UIScene_CustomizeCharacterMenu.h"
#include "..\..\Minecraft.h"
UIScene_CustomizeCharacterMenu::UIScene_CustomizeCharacterMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
{
initialiseMovie();
m_buttons[BUTTON_CCM_CHANGESKIN].init(L"Change Skin", BUTTON_CCM_CHANGESKIN);
m_buttons[BUTTON_CCM_CHANGECAPE].init(L"Change Cape", BUTTON_CCM_CHANGECAPE);
m_buttons[BUTTON_CCM_UNUSED2].init(L"", BUTTON_CCM_UNUSED2);
m_buttons[BUTTON_CCM_UNUSED3].init(L"", BUTTON_CCM_UNUSED3);
m_buttons[BUTTON_CCM_UNUSED4].init(L"", BUTTON_CCM_UNUSED4);
m_buttons[BUTTON_CCM_UNUSED5].init(L"", BUTTON_CCM_UNUSED5);
m_buttons[BUTTON_CCM_UNUSED6].init(L"", BUTTON_CCM_UNUSED6);
removeControl( &m_buttons[BUTTON_CCM_UNUSED2], false );
removeControl( &m_buttons[BUTTON_CCM_UNUSED3], false );
removeControl( &m_buttons[BUTTON_CCM_UNUSED4], false );
removeControl( &m_buttons[BUTTON_CCM_UNUSED5], false );
removeControl( &m_buttons[BUTTON_CCM_UNUSED6], false );
doHorizontalResizeCheck();
if(!ProfileManager.IsFullVersion())
{
removeControl( &m_buttons[BUTTON_CCM_CHANGESKIN], false );
removeControl( &m_buttons[BUTTON_CCM_CHANGECAPE], false );
}
}
UIScene_CustomizeCharacterMenu::~UIScene_CustomizeCharacterMenu()
{
}
void UIScene_CustomizeCharacterMenu::handleReload()
{
removeControl( &m_buttons[BUTTON_CCM_UNUSED2], false );
removeControl( &m_buttons[BUTTON_CCM_UNUSED3], false );
removeControl( &m_buttons[BUTTON_CCM_UNUSED4], false );
removeControl( &m_buttons[BUTTON_CCM_UNUSED5], false );
removeControl( &m_buttons[BUTTON_CCM_UNUSED6], false );
doHorizontalResizeCheck();
if(!ProfileManager.IsFullVersion())
{
removeControl( &m_buttons[BUTTON_CCM_CHANGESKIN], false );
removeControl( &m_buttons[BUTTON_CCM_CHANGECAPE], false );
}
}
wstring UIScene_CustomizeCharacterMenu::getMoviePath()
{
if(app.GetLocalPlayerCount() > 1)
{
return L"HelpAndOptionsMenuSplit";
}
else
{
return L"HelpAndOptionsMenu";
}
}
void UIScene_CustomizeCharacterMenu::updateTooltips()
{
ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK );
}
void UIScene_CustomizeCharacterMenu::updateComponents()
{
bool bNotInGame = (Minecraft::GetInstance()->level == NULL);
if(bNotInGame)
{
m_parentLayer->showComponent(m_iPad, eUIComponent_Panorama, true);
m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, true);
}
else
{
m_parentLayer->showComponent(m_iPad, eUIComponent_Panorama, false);
if(app.GetLocalPlayerCount() == 1) m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, true);
else m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, false);
}
}
void UIScene_CustomizeCharacterMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
{
ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released);
switch(key)
{
case ACTION_MENU_CANCEL:
if(pressed && !repeat)
{
navigateBack();
}
break;
case ACTION_MENU_OK:
#ifdef __ORBIS__
case ACTION_MENU_TOUCHPAD_PRESS:
#endif
if(pressed)
{
ui.PlayUISFX(eSFX_Press);
}
case ACTION_MENU_UP:
case ACTION_MENU_DOWN:
sendInputToMovie(key, repeat, pressed, released);
break;
}
}
void UIScene_CustomizeCharacterMenu::handlePress(F64 controlId, F64 childId)
{
switch((int)controlId)
{
case BUTTON_CCM_CHANGESKIN:
ui.NavigateToScene(m_iPad, eUIScene_SkinSelectMenu);
break;
case BUTTON_CCM_CHANGECAPE:
ui.NavigateToScene(m_iPad, eUIScene_CapeSelectMenu);
break;
}
}

View File

@@ -0,0 +1,47 @@
#pragma once
#include "UIScene.h"
#define BUTTON_CCM_CHANGESKIN 0
#define BUTTON_CCM_CHANGECAPE 1
#define BUTTON_CCM_UNUSED2 2
#define BUTTON_CCM_UNUSED3 3
#define BUTTON_CCM_UNUSED4 4
#define BUTTON_CCM_UNUSED5 5
#define BUTTON_CCM_UNUSED6 6
#define BUTTONS_CCM_MAX 7
class UIScene_CustomizeCharacterMenu : public UIScene
{
private:
UIControl_Button m_buttons[BUTTONS_CCM_MAX];
UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene)
UI_MAP_ELEMENT( m_buttons[BUTTON_CCM_CHANGESKIN], "Button1")
UI_MAP_ELEMENT( m_buttons[BUTTON_CCM_CHANGECAPE], "Button2")
UI_MAP_ELEMENT( m_buttons[BUTTON_CCM_UNUSED2], "Button3")
UI_MAP_ELEMENT( m_buttons[BUTTON_CCM_UNUSED3], "Button4")
UI_MAP_ELEMENT( m_buttons[BUTTON_CCM_UNUSED4], "Button5")
UI_MAP_ELEMENT( m_buttons[BUTTON_CCM_UNUSED5], "Button6")
UI_MAP_ELEMENT( m_buttons[BUTTON_CCM_UNUSED6], "Button7")
UI_END_MAP_ELEMENTS_AND_NAMES()
public:
UIScene_CustomizeCharacterMenu(int iPad, void *initData, UILayer *parentLayer);
virtual ~UIScene_CustomizeCharacterMenu();
virtual EUIScene getSceneType() { return eUIScene_CustomizeCharacterMenu; }
virtual void updateTooltips();
virtual void updateComponents();
virtual void handleReload();
protected:
virtual wstring getMoviePath();
public:
// INPUT
virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled);
protected:
void handlePress(F64 controlId, F64 childId);
};

View File

@@ -10,7 +10,7 @@ UIScene_HelpAndOptionsMenu::UIScene_HelpAndOptionsMenu(int iPad, void *initData,
m_bNotInGame=(Minecraft::GetInstance()->level==NULL);
m_buttons[BUTTON_HAO_CHANGESKIN].init(app.GetString(IDS_CHANGE_SKIN),BUTTON_HAO_CHANGESKIN);
m_buttons[BUTTON_HAO_CHANGESKIN].init(L"Customize Character",BUTTON_HAO_CHANGESKIN);
m_buttons[BUTTON_HAO_HOWTOPLAY].init(app.GetString(IDS_HOW_TO_PLAY),BUTTON_HAO_HOWTOPLAY);
m_buttons[BUTTON_HAO_CONTROLS].init(app.GetString(IDS_CONTROLS),BUTTON_HAO_CONTROLS);
m_buttons[BUTTON_HAO_SETTINGS].init(app.GetString(IDS_SETTINGS),BUTTON_HAO_SETTINGS);
@@ -209,7 +209,7 @@ void UIScene_HelpAndOptionsMenu::handlePress(F64 controlId, F64 childId)
switch((int)controlId)
{
case BUTTON_HAO_CHANGESKIN:
ui.NavigateToScene(m_iPad, eUIScene_SkinSelectMenu);
ui.NavigateToScene(m_iPad, eUIScene_CustomizeCharacterMenu);
break;
case BUTTON_HAO_HOWTOPLAY:
ui.NavigateToScene(m_iPad, eUIScene_HowToPlayMenu);

View File

@@ -229,7 +229,6 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr
{
case SKIN_SELECT_PACK_DEFAULT:
app.SetPlayerSkin(iPad, m_skinIndex);
app.SetPlayerCape(iPad, 0);
m_currentSkinPath = app.GetPlayerSkinName(iPad);
m_originalSkinId = app.GetPlayerSkinId(iPad);
setCharacterSelected(true);
@@ -242,13 +241,13 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr
wchar_t chars[256];
swprintf(chars, 256, L"dlcskin%08d.png", app.GetPlayerFavoriteSkin(iPad,m_skinIndex));
DLCPack *Pack=app.m_dlcManager.getPackContainingSkin(chars);
DLCPack *Pack=app.m_dlcManager.getPackContainingSkin(chars);
if(Pack)
{
DLCSkinFile *skinFile = Pack->getSkinFile(chars);
app.SetPlayerSkin(iPad, skinFile->getPath());
app.SetPlayerCape(iPad, skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape));
{ wstring _cp = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); if(!_cp.empty()) app.SetPlayerCape(iPad, _cp); }
setCharacterSelected(true);
m_currentSkinPath = app.GetPlayerSkinName(iPad);
m_originalSkinId = app.GetPlayerSkinId(iPad);
@@ -373,7 +372,7 @@ void UIScene_SkinSelectMenu::handleInput(int iPad, int key, bool repeat, bool pr
else
{
app.SetPlayerSkin(iPad, skinFile->getPath());
app.SetPlayerCape(iPad, skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape));
{ wstring _cp = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); if(!_cp.empty()) app.SetPlayerCape(iPad, _cp); }
setCharacterSelected(true);
m_currentSkinPath = app.GetPlayerSkinName(iPad);
m_originalSkinId = app.GetPlayerSkinId(iPad);
@@ -590,7 +589,7 @@ void UIScene_SkinSelectMenu::InputActionOK(unsigned int iPad)
{
DLCSkinFile *skinFile = Pack->getSkinFile(chars);
app.SetPlayerSkin(iPad, skinFile->getPath());
app.SetPlayerCape(iPad, skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape));
{ wstring _cp = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); if(!_cp.empty()) app.SetPlayerCape(iPad, _cp); }
setCharacterSelected(true);
m_currentSkinPath = app.GetPlayerSkinName(iPad);
m_originalSkinId = app.GetPlayerSkinId(iPad);
@@ -682,7 +681,7 @@ void UIScene_SkinSelectMenu::InputActionOK(unsigned int iPad)
else
{
app.SetPlayerSkin(iPad, skinFile->getPath());
app.SetPlayerCape(iPad, skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape));
{ wstring _cp = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); if(!_cp.empty()) app.SetPlayerCape(iPad, _cp); }
setCharacterSelected(true);
m_currentSkinPath = app.GetPlayerSkinName(iPad);
m_originalSkinId = app.GetPlayerSkinId(iPad);
@@ -694,7 +693,7 @@ void UIScene_SkinSelectMenu::InputActionOK(unsigned int iPad)
else
{
app.SetPlayerSkin(iPad, skinFile->getPath());
app.SetPlayerCape(iPad, skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape));
{ wstring _cp = skinFile->getParameterAsString(DLCManager::e_DLCParamType_Cape); if(!_cp.empty()) app.SetPlayerCape(iPad, _cp); }
setCharacterSelected(true);
m_currentSkinPath = app.GetPlayerSkinName(iPad);
m_originalSkinId = app.GetPlayerSkinId(iPad);
@@ -885,9 +884,10 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged()
}
m_characters[eCharacter_Current].SetTexture(m_selectedSkinPath, backupTexture);
m_characters[eCharacter_Current].SetCapeTexture(m_selectedCapePath);
wstring playerCapePath = app.GetPlayerCapeName(m_iPad);
m_characters[eCharacter_Current].SetCapeTexture(m_selectedCapePath.empty() ? playerCapePath : m_selectedCapePath);
showNext = TRUE;
showNext = TRUE;
showPrevious = TRUE;
nextIndex = getNextSkinIndex(m_skinIndex);
previousIndex = getPreviousSkinIndex(m_skinIndex);
@@ -998,7 +998,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged()
app.SetAnimOverrideBitmask(skinFile->getSkinID(),skinFile->getAnimOverrideBitmask());
}
m_characters[eCharacter_Next1 + i].SetTexture(otherSkinPath, backupTexture);
m_characters[eCharacter_Next1 + i].SetCapeTexture(otherCapePath);
m_characters[eCharacter_Next1 + i].SetCapeTexture(otherCapePath.empty() ? playerCapePath : otherCapePath);
}
nextIndex = getNextSkinIndex(nextIndex);
@@ -1069,7 +1069,7 @@ void UIScene_SkinSelectMenu::handleSkinIndexChanged()
app.SetAnimOverrideBitmask(skinFile->getSkinID(),skinFile->getAnimOverrideBitmask());
}
m_characters[eCharacter_Previous1 + i].SetTexture(otherSkinPath, backupTexture);
m_characters[eCharacter_Previous1 + i].SetCapeTexture(otherCapePath);
m_characters[eCharacter_Previous1 + i].SetCapeTexture(otherCapePath.empty() ? playerCapePath : otherCapePath);
}
previousIndex = getPreviousSkinIndex(previousIndex);

File diff suppressed because it is too large Load Diff

View File

@@ -4363,6 +4363,8 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
<ClInclude Include="Common\Network\LANSessionManager.h" />
<ClInclude Include="Common\Network\PacketRouter.h" />
<ClInclude Include="Common\Network\STUNClient.h" />
<ClInclude Include="Common\UI\UIScene_CapeSelectMenu.h" />
<ClInclude Include="Common\UI\UIScene_CustomizeCharacterMenu.h" />
<ClInclude Include="ConnectScreen.h" />
<ClInclude Include="KeyboardMouseInput.h" />
<ClInclude Include="miniupnpc\miniupnpcstrings.h" />
@@ -21537,6 +21539,8 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
<ClCompile Include="Common\Network\NATTraversal.cpp" />
<ClCompile Include="Common\Network\LANSessionManager.cpp" />
<ClCompile Include="Common\Network\STUNClient.cpp" />
<ClCompile Include="Common\UI\UIScene_CapeSelectMenu.cpp" />
<ClCompile Include="Common\UI\UIScene_CustomizeCharacterMenu.cpp" />
<ClCompile Include="ConnectScreen.cpp" />
<ClCompile Include="KeyboardMouseInput.cpp" />
<ClCompile Include="miniupnpc\addr_is_reserved.c" />

View File

@@ -3669,6 +3669,12 @@
<ClInclude Include="Extrax64Stubs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Common\UI\UIScene_CustomizeCharacterMenu.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Common\UI\UIScene_CapeSelectMenu.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@@ -5738,6 +5744,12 @@
<ClCompile Include="miniupnpc\addr_is_reserved.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Common\UI\UIScene_CustomizeCharacterMenu.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Common\UI\UIScene_CapeSelectMenu.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Library Include="Xbox\4JLibs\libs\4J_Render_d.lib">