Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 106 additions & 3 deletions Minecraft.Client/Extrax64Stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
#include "Orbis\Sentient\DynamicConfigurations.h"
#include <perf.h>
#endif
#ifdef _WINDOWS64
#include "Windows64/RichPresence/discord_rpc.h"
#endif

#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
#ifdef _WINDOWS64
Expand Down Expand Up @@ -679,9 +682,109 @@ eAwardType C_4JProfile::GetAwardType(int iAwardNumber) { return eAwardType_Ach
bool C_4JProfile::CanBeAwarded(int iQuadrant, int iAwardNumber) { return false; }
void C_4JProfile::Award(int iQuadrant, int iAwardNumber, bool bForce) {}
bool C_4JProfile::IsAwardsFlagSet(int iQuadrant, int iAward) { return false; }
void C_4JProfile::RichPresenceInit(int iPresenceCount, int iContextCount) {}
void C_4JProfile::RegisterRichPresenceContext(int iGameConfigContextID) {}
void C_4JProfile::SetRichPresenceContextValue(int iPad, int iContextID, int iVal) {}
void C_4JProfile::RichPresenceInit(int iPresenceCount, int iContextCount)
{
#ifdef _WINDOWS64
DiscordEventHandlers discordPresence;
memset(&discordPresence, 0, sizeof(discordPresence));

// 1480245069947732159 is on my discord account (acth2)
Discord_Initialize("1480245069947732159", &discordPresence, 1, NULL);
#endif
}
void C_4JProfile::RegisterRichPresenceContext(int iGameConfigContextID)
{
}

std::string WStringToUtf8(LPCWSTR wstr)
{
int size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
std::string result(size - 1, 0);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, result.data(), size, NULL, NULL);
return result;
}

void C_4JProfile::SetRichPresenceContextValue(int iPad, int iContextID, int iVal)
{
#ifdef _WINDOWS64
DiscordRichPresence discordPresence;
memset(&discordPresence, 0, sizeof(discordPresence));

// std::string = UTF8
// LPCWSTR = UTF16

static std::string s_detailsUtf8;
static std::string s_stateUtf8;

// i cannot instantly do = because app.getString
s_detailsUtf8 = WStringToUtf8(app.GetString(IDS_RICHPRESENCESTATE_BLANK));

if (iContextID == CONTEXT_GAME_STATE)
{
discordPresence.details = "Playing Minecraft: Legacy Console Edition";

// the comments are pretty generic, that would be sick if i could find the real ones
// i will probably make different icons depending of what situation the player is to make the rich presence more fun soon
discordPresence.largeImageKey = "main_icon";
discordPresence.largeImageText = "Minecraft: LCE";

switch (iVal)
{
case CONTEXT_GAME_STATE_NETHER:
s_stateUtf8 = WStringToUtf8(app.GetString(IDS_RICHPRESENCESTATE_NETHER));
discordPresence.smallImageKey = "nether_icon";
break;

case CONTEXT_GAME_STATE_FORGING:
s_stateUtf8 = WStringToUtf8(app.GetString(IDS_RICHPRESENCESTATE_FORGING));
discordPresence.smallImageKey = "anvil_icon";
break;

case CONTEXT_GAME_STATE_BOATING:
s_stateUtf8 = WStringToUtf8(app.GetString(IDS_RICHPRESENCESTATE_BOATING));
discordPresence.smallImageKey = "boat_icon";
break;

case CONTEXT_GAME_STATE_CRAFTING:
s_stateUtf8 = WStringToUtf8(app.GetString(IDS_RICHPRESENCESTATE_CRAFTING));
discordPresence.smallImageKey = "crafting_icon";
break;

case CONTEXT_GAME_STATE_RIDING_MINECART:
s_stateUtf8 = WStringToUtf8(app.GetString(IDS_RICHPRESENCESTATE_RIDING_MINECART));
discordPresence.smallImageKey = "minecart_icon";
break;

case CONTEXT_GAME_STATE_RIDING_PIG:
s_stateUtf8 = WStringToUtf8(app.GetString(IDS_RICHPRESENCESTATE_RIDING_PIG));
discordPresence.smallImageKey = "pig_icon";
break;

case CONTEXT_GAME_STATE_BLANK:
default:
s_stateUtf8 = WStringToUtf8(app.GetString(IDS_RICHPRESENCESTATE_BLANK));
discordPresence.smallImageKey = nullptr;
break;
}

// After leaving for exemple an anvil the rich presence would get stuck at "Forging" so to avoid that behaviour,
// i just reset every (5*20 / 10) ticks (5 seconds), the division by ten is due to the fact that i call this function once per 10 ticks.
// If the player is still forging it will just reset itself and if he dont it will be corrected!
//
// \/ CODE TO CHANGE \/
static int resetRP = 0;
if (++resetRP >= (5 * 20) / 10)
{
iVal = CONTEXT_GAME_STATE_BLANK;
s_stateUtf8 = WStringToUtf8(app.GetString(IDS_RICHPRESENCESTATE_BLANK));
discordPresence.smallImageKey = nullptr;
}

discordPresence.state = s_stateUtf8.c_str();
Discord_UpdatePresence(&discordPresence);
}
#endif
}
void C_4JProfile::SetCurrentGameActivity(int iPad, int iNewPresence, bool bSetOthersToIdle) {}
void C_4JProfile::DisplayFullVersionPurchase(bool bRequired, int iQuadrant, int iUpsellParam) {}
void C_4JProfile::SetUpsellCallback(void (*Func)(LPVOID lpParam, eUpsellType type, eUpsellResponse response, int iUserData), LPVOID lpParam) {}
Expand Down
21 changes: 14 additions & 7 deletions Minecraft.Client/Minecraft.Client.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1572,9 +1572,10 @@ if not exist "$(TargetDir)\savedata" mkdir "$(TargetDir)\savedata"</Command>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
<AdditionalDependencies>legacy_stdio_definitions.lib;d3d11.lib;d3dcompiler.lib;..\Minecraft.World\x64_Debug\Minecraft.World.lib;%(AdditionalDependencies);XInput9_1_0.lib;wsock32.lib</AdditionalDependencies>
<AdditionalDependencies>legacy_stdio_definitions.lib;d3d11.lib;d3dcompiler.lib;..\Minecraft.World\x64_Debug\Minecraft.World.lib;%(AdditionalDependencies);XInput9_1_0.lib;wsock32.lib;discord-rpc.lib;discord-rpc.lib</AdditionalDependencies>
<ShowProgress>NotSet</ShowProgress>
<SuppressStartupBanner>false</SuppressStartupBanner>
<AdditionalLibraryDirectories>Windows64\RichPresence\$(Configuration);Windows64\RichPresence;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<ImageXex>
<ConfigurationFile>$(ProjectDir)xbox\xex-dev.xml</ConfigurationFile>
Expand Down Expand Up @@ -1808,10 +1809,11 @@ xcopy /q /y /i /s /e $(ProjectDir)DurangoMedia\CU $(LayoutDir)Image\Loose\CU</C
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
<AdditionalDependencies>legacy_stdio_definitions.lib;d3d11.lib;d3dcompiler.lib;..\Minecraft.World\x64_Release\Minecraft.World.lib;XInput9_1_0.lib;Windows64\Iggy\lib\iggy_w64.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>legacy_stdio_definitions.lib;d3d11.lib;d3dcompiler.lib;..\Minecraft.World\x64_Release\Minecraft.World.lib;XInput9_1_0.lib;Windows64\Iggy\lib\iggy_w64.lib;Windows64\RichPresence\discord-rpc.lib;%(AdditionalDependencies);discord-rpc.lib</AdditionalDependencies>
<ShowProgress>NotSet</ShowProgress>
<SuppressStartupBanner>false</SuppressStartupBanner>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<AdditionalLibraryDirectories>Windows64\RichPresence\$(Configuration);</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Message>Run postbuild script</Message>
Expand Down Expand Up @@ -1947,9 +1949,10 @@ xcopy /q /y /i /s /e $(ProjectDir)DurangoMedia\CU $(LayoutDir)Image\Loose\CU</C
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
<AdditionalDependencies>d3d11.lib;d3dcompiler.lib;..\Minecraft.World\x64_Release\Minecraft.World.lib;XInput9_1_0.lib;Windows64\Iggy\lib\iggy_w64.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>d3d11.lib;d3dcompiler.lib;..\Minecraft.World\x64_Release\Minecraft.World.lib;XInput9_1_0.lib;Windows64\Iggy\lib\iggy_w64.lib;%(AdditionalDependencies);discord-rpc.lib</AdditionalDependencies>
<ShowProgress>NotSet</ShowProgress>
<SuppressStartupBanner>false</SuppressStartupBanner>
<AdditionalLibraryDirectories>Windows64\RichPresence\$(Configuration);</AdditionalLibraryDirectories>
</Link>
<ImageXex>
<ConfigurationFile>$(ProjectDir)xbox\xex-dev.xml</ConfigurationFile>
Expand Down Expand Up @@ -2798,10 +2801,11 @@ if not exist "$(TargetDir)\savedata" mkdir "$(TargetDir)\savedata"</Command>
<OptimizeReferences>false</OptimizeReferences>
<ProgramDatabaseFile>$(OutDir)default.pdb</ProgramDatabaseFile>
<SetChecksum>true</SetChecksum>
<AdditionalDependencies>xavatar2.lib;xapilib.lib;d3d9.lib;d3dx9.lib;xgraphics.lib;xboxkrnl.lib;xbox\Sentient\libs\SenCore.lib;xnet.lib;xaudio2.lib;xact3.lib;x3daudio.lib;xmcore.lib;vcomp.lib;xuirun.lib;xuirender.lib;xuihtml.lib;xonline.lib;xhv2.lib;qnetxaudio2.lib;xbox\4JLibs\libs\4J_Input.lib;xbox\4JLibs\libs\4J_Storage.lib;xbox\4JLibs\libs\4J_Profile.lib;xbox\4JLibs\libs\4J_Render.lib;..\Minecraft.World\ContentPackage\Minecraft.World.lib;xsocialpost.lib;xrnm.lib;xparty.lib;xbox\Sentient\libs\SenNews.lib;xbox\Sentient\libs\SenUGC.lib;xbox\Sentient\libs\SenBoxArt.lib;NuiApi.lib;ST.lib;NuiFitnessApi.lib;NuiHandles.lib;NuiSpeech.lib;NuiAudio.lib;xhttp.lib;xauth.lib;xgetserviceendpoint.lib;xav.lib;xjson.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>xavatar2.lib;xapilib.lib;d3d9.lib;d3dx9.lib;xgraphics.lib;xboxkrnl.lib;xbox\Sentient\libs\SenCore.lib;xnet.lib;xaudio2.lib;xact3.lib;x3daudio.lib;xmcore.lib;vcomp.lib;xuirun.lib;xuirender.lib;xuihtml.lib;xonline.lib;xhv2.lib;qnetxaudio2.lib;xbox\4JLibs\libs\4J_Input.lib;xbox\4JLibs\libs\4J_Storage.lib;xbox\4JLibs\libs\4J_Profile.lib;xbox\4JLibs\libs\4J_Render.lib;..\Minecraft.World\ContentPackage\Minecraft.World.lib;xsocialpost.lib;xrnm.lib;xparty.lib;xbox\Sentient\libs\SenNews.lib;xbox\Sentient\libs\SenUGC.lib;xbox\Sentient\libs\SenBoxArt.lib;NuiApi.lib;ST.lib;NuiFitnessApi.lib;NuiHandles.lib;NuiSpeech.lib;NuiAudio.lib;xhttp.lib;xauth.lib;xgetserviceendpoint.lib;xav.lib;xjson.lib;%(AdditionalDependencies);discord-rpc.lib</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>xapilib.lib</IgnoreSpecificDefaultLibraries>
<GenerateMapFile>false</GenerateMapFile>
<MapExports>false</MapExports>
<AdditionalLibraryDirectories>Windows64\RichPresence\$(Configuration);</AdditionalLibraryDirectories>
</Link>
<ImageXex>
<ConfigurationFile>$(ProjectDir)xbox\xex.xml</ConfigurationFile>
Expand Down Expand Up @@ -2919,10 +2923,11 @@ if not exist "$(TargetDir)\savedata" mkdir "$(TargetDir)\savedata"</Command>
<OptimizeReferences>false</OptimizeReferences>
<ProgramDatabaseFile>$(OutDir)default.pdb</ProgramDatabaseFile>
<SetChecksum>true</SetChecksum>
<AdditionalDependencies>xavatar2.lib;xapilib.lib;d3d9.lib;d3dx9.lib;xgraphics.lib;xboxkrnl.lib;xbox\Sentient\libs\SenCore.lib;xnet.lib;xaudio2.lib;xact3.lib;x3daudio.lib;xmcore.lib;vcomp.lib;xuirun.lib;xuirender.lib;xuihtml.lib;xonline.lib;xhv2.lib;qnetxaudio2.lib;xbox\4JLibs\libs\4J_Input.lib;xbox\4JLibs\libs\4J_Storage.lib;xbox\4JLibs\libs\4J_Profile.lib;xbox\4JLibs\libs\4J_Render.lib;..\Minecraft.World\ContentPackage\Minecraft.World.lib;xsocialpost.lib;xrnm.lib;xparty.lib;xbox\Sentient\libs\SenNews.lib;xbox\Sentient\libs\SenUGC.lib;xbox\Sentient\libs\SenBoxArt.lib;NuiApi.lib;ST.lib;NuiFitnessApi.lib;NuiHandles.lib;NuiSpeech.lib;NuiAudio.lib;xhttp.lib;xauth.lib;xgetserviceendpoint.lib;xav.lib;xjson.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>xavatar2.lib;xapilib.lib;d3d9.lib;d3dx9.lib;xgraphics.lib;xboxkrnl.lib;xbox\Sentient\libs\SenCore.lib;xnet.lib;xaudio2.lib;xact3.lib;x3daudio.lib;xmcore.lib;vcomp.lib;xuirun.lib;xuirender.lib;xuihtml.lib;xonline.lib;xhv2.lib;qnetxaudio2.lib;xbox\4JLibs\libs\4J_Input.lib;xbox\4JLibs\libs\4J_Storage.lib;xbox\4JLibs\libs\4J_Profile.lib;xbox\4JLibs\libs\4J_Render.lib;..\Minecraft.World\ContentPackage\Minecraft.World.lib;xsocialpost.lib;xrnm.lib;xparty.lib;xbox\Sentient\libs\SenNews.lib;xbox\Sentient\libs\SenUGC.lib;xbox\Sentient\libs\SenBoxArt.lib;NuiApi.lib;ST.lib;NuiFitnessApi.lib;NuiHandles.lib;NuiSpeech.lib;NuiAudio.lib;xhttp.lib;xauth.lib;xgetserviceendpoint.lib;xav.lib;xjson.lib;%(AdditionalDependencies);discord-rpc.lib</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>xapilib.lib</IgnoreSpecificDefaultLibraries>
<GenerateMapFile>false</GenerateMapFile>
<MapExports>false</MapExports>
<AdditionalLibraryDirectories>Windows64\RichPresence\$(Configuration);</AdditionalLibraryDirectories>
</Link>
<ImageXex>
<ConfigurationFile>$(ProjectDir)xbox\xex.xml</ConfigurationFile>
Expand Down Expand Up @@ -3040,10 +3045,11 @@ if not exist "$(TargetDir)\savedata" mkdir "$(TargetDir)\savedata"</Command>
<OptimizeReferences>false</OptimizeReferences>
<ProgramDatabaseFile>$(OutDir)default.pdb</ProgramDatabaseFile>
<SetChecksum>true</SetChecksum>
<AdditionalDependencies>xavatar2.lib;xapilib.lib;d3d9.lib;d3dx9.lib;xgraphics.lib;xboxkrnl.lib;xbox\Sentient\libs\SenCore.lib;xnet.lib;xaudio2.lib;xact3.lib;x3daudio.lib;xmcore.lib;vcomp.lib;xuirun.lib;xuirender.lib;xuihtml.lib;xonline.lib;xhv2.lib;qnetxaudio2.lib;xbox\4JLibs\libs\4J_Input.lib;xbox\4JLibs\libs\4J_Storage.lib;xbox\4JLibs\libs\4J_Profile.lib;xbox\4JLibs\libs\4J_Render.lib;..\Minecraft.World\ContentPackage\Minecraft.World.lib;xsocialpost.lib;xrnm.lib;xparty.lib;xbox\Sentient\libs\SenNews.lib;xbox\Sentient\libs\SenUGC.lib;xbox\Sentient\libs\SenBoxArt.lib;NuiApi.lib;ST.lib;NuiFitnessApi.lib;NuiHandles.lib;NuiSpeech.lib;NuiAudio.lib;xhttp.lib;xauth.lib;xgetserviceendpoint.lib;xav.lib;xjson.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>xavatar2.lib;xapilib.lib;d3d9.lib;d3dx9.lib;xgraphics.lib;xboxkrnl.lib;xbox\Sentient\libs\SenCore.lib;xnet.lib;xaudio2.lib;xact3.lib;x3daudio.lib;xmcore.lib;vcomp.lib;xuirun.lib;xuirender.lib;xuihtml.lib;xonline.lib;xhv2.lib;qnetxaudio2.lib;xbox\4JLibs\libs\4J_Input.lib;xbox\4JLibs\libs\4J_Storage.lib;xbox\4JLibs\libs\4J_Profile.lib;xbox\4JLibs\libs\4J_Render.lib;..\Minecraft.World\ContentPackage\Minecraft.World.lib;xsocialpost.lib;xrnm.lib;xparty.lib;xbox\Sentient\libs\SenNews.lib;xbox\Sentient\libs\SenUGC.lib;xbox\Sentient\libs\SenBoxArt.lib;NuiApi.lib;ST.lib;NuiFitnessApi.lib;NuiHandles.lib;NuiSpeech.lib;NuiAudio.lib;xhttp.lib;xauth.lib;xgetserviceendpoint.lib;xav.lib;xjson.lib;%(AdditionalDependencies);discord-rpc.lib</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>xapilib.lib</IgnoreSpecificDefaultLibraries>
<GenerateMapFile>false</GenerateMapFile>
<MapExports>false</MapExports>
<AdditionalLibraryDirectories>Windows64\RichPresence\$(Configuration);</AdditionalLibraryDirectories>
</Link>
<ImageXex>
<ConfigurationFile>$(ProjectDir)xbox\xex.xml</ConfigurationFile>
Expand Down Expand Up @@ -3161,10 +3167,11 @@ if not exist "$(TargetDir)\savedata" mkdir "$(TargetDir)\savedata"</Command>
<OptimizeReferences>false</OptimizeReferences>
<ProgramDatabaseFile>$(OutDir)default.pdb</ProgramDatabaseFile>
<SetChecksum>true</SetChecksum>
<AdditionalDependencies>xavatar2.lib;xapilib.lib;d3d9.lib;d3dx9.lib;xgraphics.lib;xboxkrnl.lib;xbox\Sentient\libs\SenCore.lib;xnet.lib;xaudio2.lib;xact3.lib;x3daudio.lib;xmcore.lib;vcomp.lib;xuirun.lib;xuirender.lib;xuihtml.lib;xonline.lib;xhv2.lib;qnetxaudio2.lib;xbox\4JLibs\libs\4J_Input.lib;xbox\4JLibs\libs\4J_Storage.lib;xbox\4JLibs\libs\4J_Profile.lib;xbox\4JLibs\libs\4J_Render.lib;..\Minecraft.World\ContentPackage\Minecraft.World.lib;xsocialpost.lib;xrnm.lib;xparty.lib;xbox\Sentient\libs\SenNews.lib;xbox\Sentient\libs\SenUGC.lib;xbox\Sentient\libs\SenBoxArt.lib;NuiApi.lib;ST.lib;NuiFitnessApi.lib;NuiHandles.lib;NuiSpeech.lib;NuiAudio.lib;xhttp.lib;xauth.lib;xgetserviceendpoint.lib;xav.lib;xjson.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>xavatar2.lib;xapilib.lib;d3d9.lib;d3dx9.lib;xgraphics.lib;xboxkrnl.lib;xbox\Sentient\libs\SenCore.lib;xnet.lib;xaudio2.lib;xact3.lib;x3daudio.lib;xmcore.lib;vcomp.lib;xuirun.lib;xuirender.lib;xuihtml.lib;xonline.lib;xhv2.lib;qnetxaudio2.lib;xbox\4JLibs\libs\4J_Input.lib;xbox\4JLibs\libs\4J_Storage.lib;xbox\4JLibs\libs\4J_Profile.lib;xbox\4JLibs\libs\4J_Render.lib;..\Minecraft.World\ContentPackage\Minecraft.World.lib;xsocialpost.lib;xrnm.lib;xparty.lib;xbox\Sentient\libs\SenNews.lib;xbox\Sentient\libs\SenUGC.lib;xbox\Sentient\libs\SenBoxArt.lib;NuiApi.lib;ST.lib;NuiFitnessApi.lib;NuiHandles.lib;NuiSpeech.lib;NuiAudio.lib;xhttp.lib;xauth.lib;xgetserviceendpoint.lib;xav.lib;xjson.lib;%(AdditionalDependencies);discord-rpc.lib</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>xapilib.lib</IgnoreSpecificDefaultLibraries>
<GenerateMapFile>false</GenerateMapFile>
<MapExports>false</MapExports>
<AdditionalLibraryDirectories>Windows64\RichPresence\$(Configuration);</AdditionalLibraryDirectories>
</Link>
<ImageXex>
<ConfigurationFile>$(ProjectDir)xbox\xex.xml</ConfigurationFile>
Expand Down
14 changes: 14 additions & 0 deletions Minecraft.Client/Minecraft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,11 @@ void Minecraft::init()
progressRenderer = new ProgressRenderer(this);

RenderManager.CBuffLockStaticCreations();

// Setup discord rich presence
#ifdef _WINDOWS64
ProfileManager.RichPresenceInit(4, 1);
#endif
}

void Minecraft::renderLoadingScreen()
Expand Down Expand Up @@ -2281,6 +2286,15 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
// Tick the opacity timer (to display the interface at default opacity for a certain time if the user has been navigating it)
app.TickOpacityTimer(iPad);

#ifdef _WINDOWS64
static int tickRP = 0;
if (++tickRP >= 10)
{
player->updateRichPresence();
tickRP = 0;
}
#endif

// 4J added
if( bFirst ) levelRenderer->destroyedTileManager->tick();

Expand Down
Binary file not shown.
Binary file not shown.
Loading