mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
resolve merge conflict
This commit is contained in:
commit
6d0a53e730
|
|
@ -39,9 +39,7 @@ RemoveSemicolon: false
|
||||||
SeparateDefinitionBlocks: Leave
|
SeparateDefinitionBlocks: Leave
|
||||||
ShortNamespaceLines: 1
|
ShortNamespaceLines: 1
|
||||||
SkipMacroDefinitionBody: false
|
SkipMacroDefinitionBody: false
|
||||||
SortIncludes:
|
SortIncludes: CaseSensitive
|
||||||
Enabled: true
|
|
||||||
IgnoreCase: false
|
|
||||||
SpacesInParens: Never
|
SpacesInParens: Never
|
||||||
SpacesInParensOptions:
|
SpacesInParensOptions:
|
||||||
ExceptDoubleParentheses: false
|
ExceptDoubleParentheses: false
|
||||||
|
|
|
||||||
20
.github/pull_request_template.md
vendored
20
.github/pull_request_template.md
vendored
|
|
@ -1,5 +1,20 @@
|
||||||
<!--
|
<!--
|
||||||
Note: IF YOUR PR CHANGES THE GAME BEHAVIOR VISIBLY, REMEMBER TO ATTACH A GAMEPLAY FOOTAGE (or at least a screenshot) OF YOU *ACTUALLY* PLAYING THE GAME WITH YOUR CHANGES. Untested PRs are *NOT* welcome. Please don't forget to describe what did you do in each commit in your PR.
|
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
|
||||||
|
|
||||||
|
IF YOUR PR CHANGES THE GAME BEHAVIOR VISIBLY, REMEMBER TO ATTACH A GAMEPLAY FOOTAGE (or at least a screenshot) OF YOU *ACTUALLY* PLAYING THE GAME WITH YOUR CHANGES. Untested PRs are *NOT* welcome. Please don't forget to describe what did you do in each commit in your PR.
|
||||||
|
|
||||||
|
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
|
||||||
|
|
||||||
|
We will NOT accept PRs with code authored by AI. If your code
|
||||||
|
was written by an AI, your PR will be closed. Do not submit
|
||||||
|
vibe coded PRs.
|
||||||
|
|
||||||
|
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
|
||||||
|
|
||||||
|
PRs that do not fulfill the informational intent of this PR template will be closed. Please do your best to use this template as written.
|
||||||
|
|
||||||
|
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
@ -19,6 +34,9 @@ Note: IF YOUR PR CHANGES THE GAME BEHAVIOR VISIBLY, REMEMBER TO ATTACH A GAMEPLA
|
||||||
### Fix Implementation
|
### Fix Implementation
|
||||||
<!-- Detail exactly how the issue was resolved (specific code changes, algorithms, logic flows). -->
|
<!-- Detail exactly how the issue was resolved (specific code changes, algorithms, logic flows). -->
|
||||||
|
|
||||||
|
### AI Use Disclosure
|
||||||
|
<!-- Explain, if any, AI was used to solve this problem. Note that we do not accept code written by any LLM in this repo. -->
|
||||||
|
|
||||||
## Related Issues
|
## Related Issues
|
||||||
- Fixes #[issue-number]
|
- Fixes #[issue-number]
|
||||||
- Related to #[issue-number]
|
- Related to #[issue-number]
|
||||||
|
|
|
||||||
2
.github/workflows/nightly.yml
vendored
2
.github/workflows/nightly.yml
vendored
|
|
@ -36,7 +36,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
tag_name: nightly
|
tag_name: nightly
|
||||||
name: Nightly Release
|
name: Nightly Release
|
||||||
body: Requires at least Windows 7 and DirectX 11 compatible GPU to run. Compiled with MSVC v14.44.35207 in Release mode with Whole Program Optimization, as well as `/O2 /Ot /Oi /Ob3 /GF /fp:precise`.
|
body: Requires at least Windows 7 and DirectX 11 compatible GPU to run. Compiled with MSVC v14.44.35207 in Release mode with Whole Program Optimization, as well as `/O2 /Ot /Oi /Ob3 /GF /fp:precise`.\n\n# 🚨 First time here? 🚨\nIf you've never downloaded the game before, you need to download `LCEWindows64.zip` and extract it to the folder where you'd like to keep the game. The other files are included in this `.zip` file!
|
||||||
files: |
|
files: |
|
||||||
LCEWindows64.zip
|
LCEWindows64.zip
|
||||||
./x64/Release/Minecraft.Client.exe
|
./x64/Release/Minecraft.Client.exe
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ function(configure_msvc_target target)
|
||||||
$<$<AND:$<NOT:$<CONFIG:Release>>,$<COMPILE_LANGUAGE:C,CXX>>:/W3>
|
$<$<AND:$<NOT:$<CONFIG:Release>>,$<COMPILE_LANGUAGE:C,CXX>>:/W3>
|
||||||
$<$<AND:$<CONFIG:Release>,$<COMPILE_LANGUAGE:C,CXX>>:/W0>
|
$<$<AND:$<CONFIG:Release>,$<COMPILE_LANGUAGE:C,CXX>>:/W0>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:/MP>
|
$<$<COMPILE_LANGUAGE:C,CXX>:/MP>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:/FS>
|
||||||
$<$<COMPILE_LANGUAGE:CXX>:/EHsc>
|
$<$<COMPILE_LANGUAGE:CXX>:/EHsc>
|
||||||
$<$<AND:$<CONFIG:Release>,$<COMPILE_LANGUAGE:C,CXX>>:/GL /O2 /Oi /GT /GF>
|
$<$<AND:$<CONFIG:Release>,$<COMPILE_LANGUAGE:C,CXX>>:/GL /O2 /Oi /GT /GF>
|
||||||
)
|
)
|
||||||
|
|
@ -92,13 +93,59 @@ target_link_libraries(MinecraftClient PRIVATE
|
||||||
>
|
>
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_command(TARGET MinecraftClient POST_BUILD
|
if(WIN32)
|
||||||
COMMAND "${CMAKE_COMMAND}"
|
message(STATUS "Starting redist copy...")
|
||||||
-DPROJECT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
|
execute_process(
|
||||||
-DOUTPUT_DIR="$<TARGET_FILE_DIR:MinecraftClient>"
|
COMMAND robocopy.exe
|
||||||
-DCONFIGURATION=$<CONFIG>
|
"${CMAKE_CURRENT_SOURCE_DIR}/x64/Release"
|
||||||
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/CopyAssets.cmake"
|
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
VERBATIM
|
/S /MT /R:0 /W:0 /NP
|
||||||
)
|
)
|
||||||
|
message(STATUS "Starting asset copy...")
|
||||||
|
execute_process(
|
||||||
|
COMMAND robocopy.exe
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.Client"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
/S /MT /R:0 /W:0 /NP
|
||||||
|
/XF "*.cpp" "*.c" "*.h" "*.hpp" "*.asm"
|
||||||
|
"*.xml" "*.lang" "*.vcxproj" "*.vcxproj.*" "*.sln"
|
||||||
|
"*.docx" "*.xls"
|
||||||
|
"*.bat" "*.cmd" "*.ps1" "*.py"
|
||||||
|
"*Test*"
|
||||||
|
/XD "Durango*" "Orbis*" "PS*" "Xbox"
|
||||||
|
)
|
||||||
|
message(STATUS "Patching Windows64Media...")
|
||||||
|
execute_process(
|
||||||
|
COMMAND robocopy.exe
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.Client/DurangoMedia"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/Windows64Media"
|
||||||
|
/S /MT /R:0 /W:0 /NP
|
||||||
|
/XF "*.h" "*.xml" "*.lang" "*.bat"
|
||||||
|
)
|
||||||
|
elseif(UNIX)
|
||||||
|
message(STATUS "Starting redist copy...")
|
||||||
|
execute_process(
|
||||||
|
COMMAND rsync -av "${CMAKE_CURRENT_SOURCE_DIR}/x64/Release/" "${CMAKE_CURRENT_BINARY_DIR}/"
|
||||||
|
)
|
||||||
|
message(STATUS "Starting asset copy...")
|
||||||
|
execute_process(
|
||||||
|
COMMAND rsync -av
|
||||||
|
"--exclude=*.cpp" "--exclude=*.c" "--exclude=*.h" "--exclude=*.hpp" "--exclude=*.asm"
|
||||||
|
"--exclude=*.xml" "--exclude=*.lang" "--exclude=*.vcxproj" "--exclude=*.vcxproj.*" "--exclude=*.sln"
|
||||||
|
"--exclude=*.docx" "--exclude=*.xls"
|
||||||
|
"--exclude=*.bat" "--exclude=*.cmd" "--exclude=*.ps1" "--exclude=*.py"
|
||||||
|
"--exclude=*Test*"
|
||||||
|
"--exclude=Durango*" "--exclude=Orbis*" "--exclude=PS*" "--exclude=Xbox"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.Client/" "${CMAKE_CURRENT_BINARY_DIR}/"
|
||||||
|
)
|
||||||
|
message(STATUS "Patching Windows64Media...")
|
||||||
|
execute_process(
|
||||||
|
COMMAND rsync -av
|
||||||
|
"--exclude=*.h" "--exclude=*.xml" "--exclude=*.lang" "--exclude=*.bat"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.Client/DurangoMedia/" "${CMAKE_CURRENT_BINARY_DIR}/Windows64Media/"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Redist and asset copying is only supported on Windows (Robocopy) and Unix systems (rsync).")
|
||||||
|
endif()
|
||||||
|
|
||||||
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT MinecraftClient)
|
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT MinecraftClient)
|
||||||
|
|
|
||||||
25
CONTRIBUTING.md
Normal file
25
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Scope of Project
|
||||||
|
At the moment, this project's scope is generally limited outside of adding new content to the game (blocks, mobs, items). We are currently prioritizing stability, quality of life, and platform support over these things.
|
||||||
|
|
||||||
|
## Current Goals
|
||||||
|
- Being a robust Desktop version of LCE
|
||||||
|
- Having proper controller support across all types, brands on Desktop or Desktop-like platforms (Steam Deck)
|
||||||
|
- Improving stability as much as possible
|
||||||
|
- Fixing as many bugs as possible
|
||||||
|
- Enabling Desktop multiplayer options
|
||||||
|
- LAN P2P Multiplayer
|
||||||
|
- Splitscreen Multiplayer
|
||||||
|
- WAN Servers (IP:Port connectivity)
|
||||||
|
- Platform-based P2P Connectivity
|
||||||
|
- Steam Networking
|
||||||
|
- GameDate?
|
||||||
|
- Maybe more?
|
||||||
|
- Refining rendering settings, renderer options, as well as reaching rendering parity with true LCE
|
||||||
|
- Having workable multi-platform compilation for ARM, Consoles, Linux
|
||||||
|
- Being a good base for further expansion and modding of LCE, such as backports and "modpacks".
|
||||||
|
|
||||||
|
# Use of AI and LLMs
|
||||||
|
We currently do not accept any new code into the project that was written largely, entirely, or even noticably by an LLM. All contributions should be made by humans that understand the codebase.
|
||||||
|
|
||||||
|
# Pull Request Template
|
||||||
|
We request that all PRs made for this repo use our PR template to the fullest extent possible. Completely wiping it out to write minimal information will likely get your PR closed.
|
||||||
|
|
@ -52,7 +52,7 @@ Chunk::Chunk(Level *level, LevelRenderer::rteMap &globalRenderableTileEntities,
|
||||||
: globalRenderableTileEntities( &globalRenderableTileEntities ), globalRenderableTileEntities_cs(&globalRenderableTileEntities_cs)
|
: globalRenderableTileEntities( &globalRenderableTileEntities ), globalRenderableTileEntities_cs(&globalRenderableTileEntities_cs)
|
||||||
{
|
{
|
||||||
clipChunk->visible = false;
|
clipChunk->visible = false;
|
||||||
bb = NULL;
|
bb = nullptr;
|
||||||
id = 0;
|
id = 0;
|
||||||
|
|
||||||
this->level = level;
|
this->level = level;
|
||||||
|
|
@ -101,15 +101,15 @@ void Chunk::setPos(int x, int y, int z)
|
||||||
|
|
||||||
float g = 6.0f;
|
float g = 6.0f;
|
||||||
// 4J - changed to just set the value rather than make a new one, if we've already created storage
|
// 4J - changed to just set the value rather than make a new one, if we've already created storage
|
||||||
if( bb == NULL )
|
if( !bb )
|
||||||
{
|
{
|
||||||
bb = AABB::newPermanent(-g, -g, -g, XZSIZE+g, SIZE+g, XZSIZE+g);
|
bb = shared_ptr<AABB>(AABB::newPermanent(-g, -g, -g, XZSIZE+g, SIZE+g, XZSIZE+g));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 4J MGH - bounds are relative to the position now, so the AABB will be setup already, either above, or from the tesselator bounds.
|
// 4J MGH - bounds are relative to the position now, so the AABB will be setup already, either above, or from the tesselator bounds.
|
||||||
// bb->set(-g, -g, -g, SIZE+g, SIZE+g, SIZE+g);
|
// bb->set(-g, -g, -g, SIZE+g, SIZE+g, SIZE+g);
|
||||||
}
|
}
|
||||||
clipChunk->aabb[0] = bb->x0 + x;
|
clipChunk->aabb[0] = bb->x0 + x;
|
||||||
clipChunk->aabb[1] = bb->y0 + y;
|
clipChunk->aabb[1] = bb->y0 + y;
|
||||||
clipChunk->aabb[2] = bb->z0 + z;
|
clipChunk->aabb[2] = bb->z0 + z;
|
||||||
|
|
@ -154,6 +154,7 @@ void Chunk::translateToPos()
|
||||||
|
|
||||||
Chunk::Chunk()
|
Chunk::Chunk()
|
||||||
{
|
{
|
||||||
|
bb = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chunk::makeCopyForRebuild(Chunk *source)
|
void Chunk::makeCopyForRebuild(Chunk *source)
|
||||||
|
|
@ -998,7 +999,7 @@ int Chunk::getList(int layer)
|
||||||
|
|
||||||
void Chunk::cull(Culler *culler)
|
void Chunk::cull(Culler *culler)
|
||||||
{
|
{
|
||||||
clipChunk->visible = culler->isVisible(bb);
|
clipChunk->visible = culler->isVisible(bb.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chunk::renderBB()
|
void Chunk::renderBB()
|
||||||
|
|
@ -1027,10 +1028,7 @@ void Chunk::clearDirty()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Chunk::~Chunk()
|
Chunk::~Chunk() = default;
|
||||||
{
|
|
||||||
delete bb;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Chunk::emptyFlagSet(int layer)
|
bool Chunk::emptyFlagSet(int layer)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,11 @@ public:
|
||||||
int xRender, yRender, zRender;
|
int xRender, yRender, zRender;
|
||||||
int xRenderOffs, yRenderOffs, zRenderOffs;
|
int xRenderOffs, yRenderOffs, zRenderOffs;
|
||||||
|
|
||||||
int xm, ym, zm;
|
int xm, ym, zm;
|
||||||
AABB *bb;
|
shared_ptr<AABB> bb;
|
||||||
ClipChunk *clipChunk;
|
ClipChunk *clipChunk;
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
//public:
|
//public:
|
||||||
// vector<shared_ptr<TileEntity> > renderableTileEntities; // 4J - removed
|
// vector<shared_ptr<TileEntity> > renderableTileEntities; // 4J - removed
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2694,6 +2694,10 @@ void ClientConnection::handleRespawn(shared_ptr<RespawnPacket> packet)
|
||||||
int oldDimension = minecraft->localplayers[m_userIndex]->dimension;
|
int oldDimension = minecraft->localplayers[m_userIndex]->dimension;
|
||||||
started = false;
|
started = false;
|
||||||
|
|
||||||
|
// Stop any streaming music (e.g. jukebox) when changing dimensions
|
||||||
|
// so it doesn't leak into the new dimension
|
||||||
|
level->playStreamingMusic(L"", 0, 0, 0);
|
||||||
|
|
||||||
// Remove client connection from this level
|
// Remove client connection from this level
|
||||||
level->removeClientConnection(this, false);
|
level->removeClientConnection(this, false);
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -362,12 +362,23 @@ void CPlatformNetworkManagerStub::HostGame(int localUsersMask, bool bOnlineGame,
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
int port = WIN64_NET_DEFAULT_PORT;
|
int port = WIN64_NET_DEFAULT_PORT;
|
||||||
|
const char* bindIp = NULL;
|
||||||
|
if (g_Win64DedicatedServer)
|
||||||
|
{
|
||||||
|
if (g_Win64DedicatedServerPort > 0)
|
||||||
|
port = g_Win64DedicatedServerPort;
|
||||||
|
if (g_Win64DedicatedServerBindIP[0] != 0)
|
||||||
|
bindIp = g_Win64DedicatedServerBindIP;
|
||||||
|
}
|
||||||
if (!WinsockNetLayer::IsActive())
|
if (!WinsockNetLayer::IsActive())
|
||||||
WinsockNetLayer::HostGame(port);
|
WinsockNetLayer::HostGame(port, bindIp);
|
||||||
|
|
||||||
const wchar_t* hostName = IQNet::m_player[0].m_gamertag;
|
if (WinsockNetLayer::IsActive())
|
||||||
unsigned int settings = app.GetGameHostOption(eGameHostOption_All);
|
{
|
||||||
WinsockNetLayer::StartAdvertising(port, hostName, settings, 0, 0, MINECRAFT_NET_VERSION);
|
const wchar_t* hostName = IQNet::m_player[0].m_gamertag;
|
||||||
|
unsigned int settings = app.GetGameHostOption(eGameHostOption_All);
|
||||||
|
WinsockNetLayer::StartAdvertising(port, hostName, settings, 0, 0, MINECRAFT_NET_VERSION);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ bool ChoiceTask::isCompleted()
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
if (!m_bConfirmMappingComplete &&
|
if (!m_bConfirmMappingComplete &&
|
||||||
(InputManager.GetValue(xboxPad, m_iConfirmMapping) > 0
|
(InputManager.GetValue(xboxPad, m_iConfirmMapping) > 0
|
||||||
|| KMInput.IsKeyDown(VK_RETURN)))
|
|| g_KBMInput.IsKeyDown(VK_RETURN)))
|
||||||
#else
|
#else
|
||||||
if (!m_bConfirmMappingComplete &&
|
if (!m_bConfirmMappingComplete &&
|
||||||
InputManager.GetValue(xboxPad, m_iConfirmMapping) > 0)
|
InputManager.GetValue(xboxPad, m_iConfirmMapping) > 0)
|
||||||
|
|
@ -70,7 +70,7 @@ bool ChoiceTask::isCompleted()
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
if (!m_bCancelMappingComplete &&
|
if (!m_bCancelMappingComplete &&
|
||||||
(InputManager.GetValue(xboxPad, m_iCancelMapping) > 0
|
(InputManager.GetValue(xboxPad, m_iCancelMapping) > 0
|
||||||
|| KMInput.IsKeyDown('B')))
|
|| g_KBMInput.IsKeyDown('B')))
|
||||||
#else
|
#else
|
||||||
if (!m_bCancelMappingComplete &&
|
if (!m_bCancelMappingComplete &&
|
||||||
InputManager.GetValue(xboxPad, m_iCancelMapping) > 0)
|
InputManager.GetValue(xboxPad, m_iCancelMapping) > 0)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
#include "TutorialConstraints.h"
|
#include "TutorialConstraints.h"
|
||||||
#include "InfoTask.h"
|
#include "InfoTask.h"
|
||||||
#include "..\..\..\Minecraft.World\Material.h"
|
#include "..\..\..\Minecraft.World\Material.h"
|
||||||
#include "..\..\KeyboardMouseInput.h"
|
#include "..\..\Windows64\KeyboardMouseInput.h"
|
||||||
|
|
||||||
InfoTask::InfoTask(Tutorial *tutorial, int descriptionId, int promptId /*= -1*/, bool requiresUserInput /*= false*/,
|
InfoTask::InfoTask(Tutorial *tutorial, int descriptionId, int promptId /*= -1*/, bool requiresUserInput /*= false*/,
|
||||||
int iMapping /*= 0*/, ETelemetryChallenges telemetryEvent /*= eTelemetryTutorial_NoEvent*/)
|
int iMapping /*= 0*/, ETelemetryChallenges telemetryEvent /*= eTelemetryTutorial_NoEvent*/)
|
||||||
|
|
@ -67,7 +67,7 @@ bool InfoTask::isCompleted()
|
||||||
if(!current)
|
if(!current)
|
||||||
{
|
{
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
if (InputManager.GetValue(pMinecraft->player->GetXboxPad(), (*it).first) > 0 || KMInput.IsKeyDown(VK_SPACE))
|
if (InputManager.GetValue(pMinecraft->player->GetXboxPad(), (*it).first) > 0 || g_KBMInput.IsKeyDown(VK_SPACE))
|
||||||
#else
|
#else
|
||||||
if( InputManager.GetValue(pMinecraft->player->GetXboxPad(), (*it).first) > 0)
|
if( InputManager.GetValue(pMinecraft->player->GetXboxPad(), (*it).first) > 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,12 @@
|
||||||
#include <pad.h>
|
#include <pad.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
#include "..\..\Windows64\KeyboardMouseInput.h"
|
||||||
|
|
||||||
|
SavedInventoryCursorPos g_savedInventoryCursorPos = { 0.0f, 0.0f, false };
|
||||||
|
#endif
|
||||||
|
|
||||||
IUIScene_AbstractContainerMenu::IUIScene_AbstractContainerMenu()
|
IUIScene_AbstractContainerMenu::IUIScene_AbstractContainerMenu()
|
||||||
{
|
{
|
||||||
m_menu = NULL;
|
m_menu = NULL;
|
||||||
|
|
@ -474,6 +480,34 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (!g_KBMInput.IsMouseGrabbed() && g_KBMInput.IsKBMActive())
|
||||||
|
{
|
||||||
|
int deltaX = g_KBMInput.GetMouseDeltaX();
|
||||||
|
int deltaY = g_KBMInput.GetMouseDeltaY();
|
||||||
|
|
||||||
|
extern HWND g_hWnd;
|
||||||
|
RECT rc;
|
||||||
|
GetClientRect(g_hWnd, &rc);
|
||||||
|
int winW = rc.right - rc.left;
|
||||||
|
int winH = rc.bottom - rc.top;
|
||||||
|
|
||||||
|
if (winW > 0 && winH > 0)
|
||||||
|
{
|
||||||
|
float scaleX = (float)getMovieWidth() / (float)winW;
|
||||||
|
float scaleY = (float)getMovieHeight() / (float)winH;
|
||||||
|
|
||||||
|
vPointerPos.x += (float)deltaX * scaleX;
|
||||||
|
vPointerPos.y += (float)deltaY * scaleY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deltaX != 0 || deltaY != 0)
|
||||||
|
{
|
||||||
|
bStickInput = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Determine which slot the pointer is currently over.
|
// Determine which slot the pointer is currently over.
|
||||||
ESceneSection eSectionUnderPointer = eSectionNone;
|
ESceneSection eSectionUnderPointer = eSectionNone;
|
||||||
int iNewSlotX = -1;
|
int iNewSlotX = -1;
|
||||||
|
|
@ -694,7 +728,11 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
|
||||||
|
|
||||||
// If there is no stick input, and we are over a slot, then snap pointer to slot centre.
|
// If there is no stick input, and we are over a slot, then snap pointer to slot centre.
|
||||||
// 4J - TomK - only if this particular component allows so!
|
// 4J - TomK - only if this particular component allows so!
|
||||||
if(!m_bPointerDrivenByMouse && CanHaveFocus(eSectionUnderPointer))
|
#ifdef _WINDOWS64
|
||||||
|
if((g_KBMInput.IsMouseGrabbed() || !g_KBMInput.IsKBMActive()) && CanHaveFocus(eSectionUnderPointer))
|
||||||
|
#else
|
||||||
|
if(CanHaveFocus(eSectionUnderPointer))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
vPointerPos.x = vSnapPos.x;
|
vPointerPos.x = vSnapPos.x;
|
||||||
vPointerPos.y = vSnapPos.y;
|
vPointerPos.y = vSnapPos.y;
|
||||||
|
|
@ -1329,7 +1367,7 @@ bool IUIScene_AbstractContainerMenu::handleKeyDown(int iPad, int iAction, bool b
|
||||||
|
|
||||||
// Standard left click
|
// Standard left click
|
||||||
buttonNum = 0;
|
buttonNum = 0;
|
||||||
if (KMInput.IsKeyDown(VK_SHIFT))
|
if (g_KBMInput.IsKeyDown(VK_LSHIFT))
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
validKeyPress = TRUE;
|
validKeyPress = TRUE;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
struct SavedInventoryCursorPos
|
||||||
|
{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
bool hasSavedPos;
|
||||||
|
};
|
||||||
|
extern SavedInventoryCursorPos g_savedInventoryCursorPos;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Uncomment to enable tap input detection to jump 1 slot. Doesn't work particularly well yet, and I feel the system does not need it.
|
// Uncomment to enable tap input detection to jump 1 slot. Doesn't work particularly well yet, and I feel the system does not need it.
|
||||||
// Would probably be required if we decide to slow down the pointer movement.
|
// Would probably be required if we decide to slow down the pointer movement.
|
||||||
// 4J Stu - There was a request to be able to navigate the scenes with the dpad, so I have used much of the TAP_DETECTION
|
// 4J Stu - There was a request to be able to navigate the scenes with the dpad, so I have used much of the TAP_DETECTION
|
||||||
|
|
@ -265,4 +275,6 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual int getPad() = 0;
|
virtual int getPad() = 0;
|
||||||
|
virtual int getMovieWidth() = 0;
|
||||||
|
virtual int getMovieHeight() = 0;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -387,8 +387,10 @@ vector<HtmlString> *IUIScene_BeaconMenu::GetSectionHoverText(ESceneSection eSect
|
||||||
|
|
||||||
desc = new vector<HtmlString>();
|
desc = new vector<HtmlString>();
|
||||||
|
|
||||||
HtmlString string( app.GetString(MobEffect::effects[effectId]->getDescriptionId()), eHTMLColor_White );
|
if (effectId < MobEffect::e_MobEffectIcon_COUNT && MobEffect::effects[effectId]) {
|
||||||
desc->push_back( string );
|
HtmlString string( app.GetString(MobEffect::effects[effectId]->getDescriptionId()), eHTMLColor_White );
|
||||||
|
desc->push_back( string );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,6 @@ void IUIScene_CreativeMenu::staticCtor()
|
||||||
ITEM_AUX(Tile::woolCarpet_Id,13) // Green
|
ITEM_AUX(Tile::woolCarpet_Id,13) // Green
|
||||||
ITEM_AUX(Tile::woolCarpet_Id,12) // Brown
|
ITEM_AUX(Tile::woolCarpet_Id,12) // Brown
|
||||||
|
|
||||||
#if 0
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,14) // Red
|
ITEM_AUX(Tile::stained_glass_Id,14) // Red
|
||||||
ITEM_AUX(Tile::stained_glass_Id,1) // Orange
|
ITEM_AUX(Tile::stained_glass_Id,1) // Orange
|
||||||
ITEM_AUX(Tile::stained_glass_Id,4) // Yellow
|
ITEM_AUX(Tile::stained_glass_Id,4) // Yellow
|
||||||
|
|
@ -244,7 +243,6 @@ void IUIScene_CreativeMenu::staticCtor()
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,15) // Black
|
ITEM_AUX(Tile::stained_glass_pane_Id,15) // Black
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,13) // Green
|
ITEM_AUX(Tile::stained_glass_pane_Id,13) // Green
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,12) // Brown
|
ITEM_AUX(Tile::stained_glass_pane_Id,12) // Brown
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _CONTENT_PACKAGE
|
#ifndef _CONTENT_PACKAGE
|
||||||
DEF(eCreativeInventory_ArtToolsDecorations)
|
DEF(eCreativeInventory_ArtToolsDecorations)
|
||||||
|
|
@ -265,40 +263,6 @@ void IUIScene_CreativeMenu::staticCtor()
|
||||||
BuildFirework(list, FireworksItem::TYPE_CREEPER, DyePowderItem::BLUE, 1, true, false);
|
BuildFirework(list, FireworksItem::TYPE_CREEPER, DyePowderItem::BLUE, 1, true, false);
|
||||||
BuildFirework(list, FireworksItem::TYPE_STAR, DyePowderItem::YELLOW, 1, false, false);
|
BuildFirework(list, FireworksItem::TYPE_STAR, DyePowderItem::YELLOW, 1, false, false);
|
||||||
BuildFirework(list, FireworksItem::TYPE_BIG, DyePowderItem::WHITE, 1, true, true);
|
BuildFirework(list, FireworksItem::TYPE_BIG, DyePowderItem::WHITE, 1, true, true);
|
||||||
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,14) // Red
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,1) // Orange
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,4) // Yellow
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,5) // Lime
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,3) // Light Blue
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,9) // Cyan
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,11) // Blue
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,10) // Purple
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,2) // Magenta
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,6) // Pink
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,0) // White
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,8) // Light Gray
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,7) // Gray
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,15) // Black
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,13) // Green
|
|
||||||
ITEM_AUX(Tile::stained_glass_Id,12) // Brown
|
|
||||||
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,14) // Red
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,1) // Orange
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,4) // Yellow
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,5) // Lime
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,3) // Light Blue
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,9) // Cyan
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,11) // Blue
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,10) // Purple
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,2) // Magenta
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,6) // Pink
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,0) // White
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,8) // Light Gray
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,7) // Gray
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,15) // Black
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,13) // Green
|
|
||||||
ITEM_AUX(Tile::stained_glass_pane_Id,12) // Brown
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -882,7 +846,7 @@ void IUIScene_CreativeMenu::TabSpec::populateMenu(AbstractContainerMenu *menu, i
|
||||||
for(; currentGroup < m_staticGroupsCount; ++currentGroup)
|
for(; currentGroup < m_staticGroupsCount; ++currentGroup)
|
||||||
{
|
{
|
||||||
int size = categoryGroups[m_staticGroupsA[currentGroup]].size();
|
int size = categoryGroups[m_staticGroupsA[currentGroup]].size();
|
||||||
if( currentIndex + size < startIndex)
|
if( currentIndex + size <= startIndex)
|
||||||
{
|
{
|
||||||
currentIndex += size;
|
currentIndex += size;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -932,7 +896,7 @@ void IUIScene_CreativeMenu::TabSpec::populateMenu(AbstractContainerMenu *menu, i
|
||||||
for(; currentGroup < m_debugGroupsCount; ++currentGroup)
|
for(; currentGroup < m_debugGroupsCount; ++currentGroup)
|
||||||
{
|
{
|
||||||
int size = categoryGroups[m_debugGroupsA[currentGroup]].size();
|
int size = categoryGroups[m_debugGroupsA[currentGroup]].size();
|
||||||
if( currentIndex + size < startIndex)
|
if( currentIndex + size <= startIndex)
|
||||||
{
|
{
|
||||||
currentIndex += size;
|
currentIndex += size;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -973,7 +937,9 @@ unsigned int IUIScene_CreativeMenu::TabSpec::getPageCount()
|
||||||
#ifndef _CONTENT_PACKAGE
|
#ifndef _CONTENT_PACKAGE
|
||||||
if(app.DebugArtToolsOn())
|
if(app.DebugArtToolsOn())
|
||||||
{
|
{
|
||||||
return (int)ceil((float)(m_staticItems + m_debugItems) / m_staticPerPage);
|
int totalItems = m_staticItems + m_debugItems;
|
||||||
|
const int totalRows = (totalItems + columns - 1) / columns;
|
||||||
|
return std::max<int>(1, totalRows - rows + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1132,7 +1098,15 @@ void IUIScene_CreativeMenu::handleAdditionalKeyPress(int iAction)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_MENU_OTHER_STICK_DOWN:
|
case ACTION_MENU_OTHER_STICK_DOWN:
|
||||||
++m_tabPage[m_curTab];
|
{
|
||||||
|
int pageStep = TabSpec::rows;
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (g_KBMInput.WasMouseWheelConsumed())
|
||||||
|
{
|
||||||
|
pageStep = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
m_tabPage[m_curTab] += pageStep;
|
||||||
if(m_tabPage[m_curTab] >= specs[m_curTab]->getPageCount())
|
if(m_tabPage[m_curTab] >= specs[m_curTab]->getPageCount())
|
||||||
{
|
{
|
||||||
m_tabPage[m_curTab] = specs[m_curTab]->getPageCount() - 1;
|
m_tabPage[m_curTab] = specs[m_curTab]->getPageCount() - 1;
|
||||||
|
|
@ -1141,9 +1115,18 @@ void IUIScene_CreativeMenu::handleAdditionalKeyPress(int iAction)
|
||||||
{
|
{
|
||||||
switchTab(m_curTab);
|
switchTab(m_curTab);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_MENU_OTHER_STICK_UP:
|
case ACTION_MENU_OTHER_STICK_UP:
|
||||||
--m_tabPage[m_curTab];
|
{
|
||||||
|
int pageStep = TabSpec::rows;
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (g_KBMInput.WasMouseWheelConsumed())
|
||||||
|
{
|
||||||
|
pageStep = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
m_tabPage[m_curTab] -= pageStep;
|
||||||
if(m_tabPage[m_curTab] < 0)
|
if(m_tabPage[m_curTab] < 0)
|
||||||
{
|
{
|
||||||
m_tabPage[m_curTab] = 0;
|
m_tabPage[m_curTab] = 0;
|
||||||
|
|
@ -1152,6 +1135,7 @@ void IUIScene_CreativeMenu::handleAdditionalKeyPress(int iAction)
|
||||||
{
|
{
|
||||||
switchTab(m_curTab);
|
switchTab(m_curTab);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ bool UIControl::setupControl(UIScene *scene, IggyValuePath *parent, const string
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __PSVITA__
|
|
||||||
void UIControl::UpdateControl()
|
void UIControl::UpdateControl()
|
||||||
{
|
{
|
||||||
F64 fx, fy, fwidth, fheight;
|
F64 fx, fy, fwidth, fheight;
|
||||||
|
|
@ -55,7 +54,6 @@ void UIControl::UpdateControl()
|
||||||
m_width = (S32)Math::round(fwidth);
|
m_width = (S32)Math::round(fwidth);
|
||||||
m_height = (S32)Math::round(fheight);
|
m_height = (S32)Math::round(fheight);
|
||||||
}
|
}
|
||||||
#endif // __PSVITA__
|
|
||||||
|
|
||||||
void UIControl::ReInit()
|
void UIControl::ReInit()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,8 @@ public:
|
||||||
UIControl();
|
UIControl();
|
||||||
|
|
||||||
virtual bool setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName);
|
virtual bool setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName);
|
||||||
#ifdef __PSVITA__
|
|
||||||
void UpdateControl();
|
void UpdateControl();
|
||||||
|
#ifdef __PSVITA__
|
||||||
void setHidden(bool bHidden) {m_bHidden=bHidden;}
|
void setHidden(bool bHidden) {m_bHidden=bHidden;}
|
||||||
bool getHidden(void) {return m_bHidden;}
|
bool getHidden(void) {return m_bHidden;}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include "UIController.h"
|
#include "UIController.h"
|
||||||
#include "UI.h"
|
#include "UI.h"
|
||||||
#include "UIScene.h"
|
#include "UIScene.h"
|
||||||
|
#include "UIControl_Slider.h"
|
||||||
#include "..\..\..\Minecraft.World\StringHelpers.h"
|
#include "..\..\..\Minecraft.World\StringHelpers.h"
|
||||||
#include "..\..\LocalPlayer.h"
|
#include "..\..\LocalPlayer.h"
|
||||||
#include "..\..\DLCTexturePack.h"
|
#include "..\..\DLCTexturePack.h"
|
||||||
|
|
@ -11,6 +12,9 @@
|
||||||
#include "..\..\EnderDragonRenderer.h"
|
#include "..\..\EnderDragonRenderer.h"
|
||||||
#include "..\..\MultiPlayerLocalPlayer.h"
|
#include "..\..\MultiPlayerLocalPlayer.h"
|
||||||
#include "UIFontData.h"
|
#include "UIFontData.h"
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
#include "..\..\Windows64\KeyboardMouseInput.h"
|
||||||
|
#endif
|
||||||
#ifdef __PSVITA__
|
#ifdef __PSVITA__
|
||||||
#include <message_dialog.h>
|
#include <message_dialog.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -52,6 +56,21 @@ bool UIController::ms_bReloadSkinCSInitialised = false;
|
||||||
|
|
||||||
DWORD UIController::m_dwTrialTimerLimitSecs=DYNAMIC_CONFIG_DEFAULT_TRIAL_TIME;
|
DWORD UIController::m_dwTrialTimerLimitSecs=DYNAMIC_CONFIG_DEFAULT_TRIAL_TIME;
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
static UIControl_Slider *FindSliderById(UIScene *pScene, int sliderId)
|
||||||
|
{
|
||||||
|
vector<UIControl *> *controls = pScene->GetControls();
|
||||||
|
if (!controls) return NULL;
|
||||||
|
for (size_t i = 0; i < controls->size(); ++i)
|
||||||
|
{
|
||||||
|
UIControl *ctrl = (*controls)[i];
|
||||||
|
if (ctrl && ctrl->getControlType() == UIControl::eSlider && ctrl->getId() == sliderId)
|
||||||
|
return (UIControl_Slider *)ctrl;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void RADLINK WarningCallback(void *user_callback_data, Iggy *player, IggyResult code, const char *message)
|
static void RADLINK WarningCallback(void *user_callback_data, Iggy *player, IggyResult code, const char *message)
|
||||||
{
|
{
|
||||||
//enum IggyResult{ IGGY_RESULT_SUCCESS = 0, IGGY_RESULT_Warning_None = 0,
|
//enum IggyResult{ IGGY_RESULT_SUCCESS = 0, IGGY_RESULT_Warning_None = 0,
|
||||||
|
|
@ -216,6 +235,10 @@ UIController::UIController()
|
||||||
m_currentRenderViewport = C4JRender::VIEWPORT_TYPE_FULLSCREEN;
|
m_currentRenderViewport = C4JRender::VIEWPORT_TYPE_FULLSCREEN;
|
||||||
m_bCustomRenderPosition = false;
|
m_bCustomRenderPosition = false;
|
||||||
m_winUserIndex = 0;
|
m_winUserIndex = 0;
|
||||||
|
m_mouseDraggingSliderScene = eUIScene_COUNT;
|
||||||
|
m_mouseDraggingSliderId = -1;
|
||||||
|
m_lastHoverMouseX = -1;
|
||||||
|
m_lastHoverMouseY = -1;
|
||||||
m_accumulatedTicks = 0;
|
m_accumulatedTicks = 0;
|
||||||
m_lastUiSfx = 0;
|
m_lastUiSfx = 0;
|
||||||
|
|
||||||
|
|
@ -761,6 +784,168 @@ void UIController::tickInput()
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (!g_KBMInput.IsMouseGrabbed() && g_KBMInput.IsKBMActive())
|
||||||
|
{
|
||||||
|
UIScene *pScene = NULL;
|
||||||
|
for (int grp = 0; grp < eUIGroup_COUNT && !pScene; ++grp)
|
||||||
|
{
|
||||||
|
pScene = m_groups[grp]->GetTopScene(eUILayer_Debug);
|
||||||
|
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Tooltips);
|
||||||
|
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Error);
|
||||||
|
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Alert);
|
||||||
|
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Popup);
|
||||||
|
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Fullscreen);
|
||||||
|
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Scene);
|
||||||
|
}
|
||||||
|
if (pScene && pScene->getMovie())
|
||||||
|
{
|
||||||
|
Iggy *movie = pScene->getMovie();
|
||||||
|
int rawMouseX = g_KBMInput.GetMouseX();
|
||||||
|
int rawMouseY = g_KBMInput.GetMouseY();
|
||||||
|
F32 mouseX = (F32)rawMouseX;
|
||||||
|
F32 mouseY = (F32)rawMouseY;
|
||||||
|
|
||||||
|
extern HWND g_hWnd;
|
||||||
|
if (g_hWnd)
|
||||||
|
{
|
||||||
|
RECT rc;
|
||||||
|
GetClientRect(g_hWnd, &rc);
|
||||||
|
int winW = rc.right - rc.left;
|
||||||
|
int winH = rc.bottom - rc.top;
|
||||||
|
if (winW > 0 && winH > 0)
|
||||||
|
{
|
||||||
|
mouseX = mouseX * (m_fScreenWidth / (F32)winW);
|
||||||
|
mouseY = mouseY * (m_fScreenHeight / (F32)winH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only update hover focus when the mouse has actually moved,
|
||||||
|
// so that mouse-wheel scrolling can change list selection
|
||||||
|
// without the hover immediately snapping focus back.
|
||||||
|
bool mouseMoved = (rawMouseX != m_lastHoverMouseX || rawMouseY != m_lastHoverMouseY);
|
||||||
|
m_lastHoverMouseX = rawMouseX;
|
||||||
|
m_lastHoverMouseY = rawMouseY;
|
||||||
|
|
||||||
|
if (mouseMoved)
|
||||||
|
{
|
||||||
|
IggyFocusHandle currentFocus = IGGY_FOCUS_NULL;
|
||||||
|
IggyFocusableObject focusables[64];
|
||||||
|
S32 numFocusables = 0;
|
||||||
|
IggyPlayerGetFocusableObjects(movie, ¤tFocus, focusables, 64, &numFocusables);
|
||||||
|
|
||||||
|
if (numFocusables > 0 && numFocusables <= 64)
|
||||||
|
{
|
||||||
|
IggyFocusHandle hitObject = IGGY_FOCUS_NULL;
|
||||||
|
for (S32 i = 0; i < numFocusables; ++i)
|
||||||
|
{
|
||||||
|
if (mouseX >= focusables[i].x0 && mouseX <= focusables[i].x1 &&
|
||||||
|
mouseY >= focusables[i].y0 && mouseY <= focusables[i].y1)
|
||||||
|
{
|
||||||
|
hitObject = focusables[i].object;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hitObject != currentFocus)
|
||||||
|
{
|
||||||
|
IggyPlayerSetFocusRS(movie, hitObject, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert mouse to scene/movie coordinates for slider hit testing
|
||||||
|
F32 sceneMouseX = mouseX;
|
||||||
|
F32 sceneMouseY = mouseY;
|
||||||
|
{
|
||||||
|
S32 displayWidth = 0, displayHeight = 0;
|
||||||
|
pScene->GetParentLayer()->getRenderDimensions(displayWidth, displayHeight);
|
||||||
|
if (displayWidth > 0 && displayHeight > 0)
|
||||||
|
{
|
||||||
|
sceneMouseX = mouseX * ((F32)pScene->getRenderWidth() / (F32)displayWidth);
|
||||||
|
sceneMouseY = mouseY * ((F32)pScene->getRenderHeight() / (F32)displayHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get main panel offset (controls are positioned relative to it)
|
||||||
|
S32 panelOffsetX = 0, panelOffsetY = 0;
|
||||||
|
UIControl *pMainPanel = pScene->GetMainPanel();
|
||||||
|
if (pMainPanel)
|
||||||
|
{
|
||||||
|
pMainPanel->UpdateControl();
|
||||||
|
panelOffsetX = pMainPanel->getXPos();
|
||||||
|
panelOffsetY = pMainPanel->getYPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool leftPressed = g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_LEFT);
|
||||||
|
bool leftDown = leftPressed || g_KBMInput.IsMouseButtonDown(KeyboardMouseInput::MOUSE_LEFT);
|
||||||
|
|
||||||
|
if (m_mouseDraggingSliderScene != eUIScene_COUNT && m_mouseDraggingSliderScene != pScene->getSceneType())
|
||||||
|
{
|
||||||
|
m_mouseDraggingSliderScene = eUIScene_COUNT;
|
||||||
|
m_mouseDraggingSliderId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftPressed)
|
||||||
|
{
|
||||||
|
vector<UIControl *> *controls = pScene->GetControls();
|
||||||
|
if (controls)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < controls->size(); ++i)
|
||||||
|
{
|
||||||
|
UIControl *ctrl = (*controls)[i];
|
||||||
|
if (!ctrl || ctrl->getControlType() != UIControl::eSlider || !ctrl->getVisible())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
UIControl_Slider *pSlider = (UIControl_Slider *)ctrl;
|
||||||
|
pSlider->UpdateControl();
|
||||||
|
S32 cx = pSlider->getXPos() + panelOffsetX;
|
||||||
|
S32 cy = pSlider->getYPos() + panelOffsetY;
|
||||||
|
S32 cw = pSlider->GetRealWidth();
|
||||||
|
S32 ch = pSlider->getHeight();
|
||||||
|
if (cw <= 0 || ch <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sceneMouseX >= cx && sceneMouseX <= cx + cw && sceneMouseY >= cy && sceneMouseY <= cy + ch)
|
||||||
|
{
|
||||||
|
m_mouseDraggingSliderScene = pScene->getSceneType();
|
||||||
|
m_mouseDraggingSliderId = pSlider->getId();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftDown && m_mouseDraggingSliderScene == pScene->getSceneType() && m_mouseDraggingSliderId >= 0)
|
||||||
|
{
|
||||||
|
UIControl_Slider *pSlider = FindSliderById(pScene, m_mouseDraggingSliderId);
|
||||||
|
if (pSlider && pSlider->getVisible())
|
||||||
|
{
|
||||||
|
pSlider->UpdateControl();
|
||||||
|
S32 sliderX = pSlider->getXPos() + panelOffsetX;
|
||||||
|
S32 sliderWidth = pSlider->GetRealWidth();
|
||||||
|
if (sliderWidth > 0)
|
||||||
|
{
|
||||||
|
float fNewSliderPos = (sceneMouseX - (float)sliderX) / (float)sliderWidth;
|
||||||
|
if (fNewSliderPos < 0.0f) fNewSliderPos = 0.0f;
|
||||||
|
if (fNewSliderPos > 1.0f) fNewSliderPos = 1.0f;
|
||||||
|
pSlider->SetSliderTouchPos(fNewSliderPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_mouseDraggingSliderScene = eUIScene_COUNT;
|
||||||
|
m_mouseDraggingSliderId = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!leftDown)
|
||||||
|
{
|
||||||
|
m_mouseDraggingSliderScene = eUIScene_COUNT;
|
||||||
|
m_mouseDraggingSliderId = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
handleInput();
|
handleInput();
|
||||||
++m_accumulatedTicks;
|
++m_accumulatedTicks;
|
||||||
}
|
}
|
||||||
|
|
@ -995,28 +1180,59 @@ void UIController::handleKeyPress(unsigned int iPad, unsigned int key)
|
||||||
released = InputManager.ButtonReleased(iPad,key); // Toggle
|
released = InputManager.ButtonReleased(iPad,key); // Toggle
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
// Keyboard menu input for player 0
|
|
||||||
if (iPad == 0)
|
if (iPad == 0)
|
||||||
{
|
{
|
||||||
bool kbDown = false, kbPressed = false, kbReleased = false;
|
int vk = 0;
|
||||||
switch(key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case ACTION_MENU_UP: kbDown = KMInput.IsKeyDown(VK_UP); kbPressed = KMInput.IsKeyPressed(VK_UP); kbReleased = KMInput.IsKeyReleased(VK_UP); break;
|
case ACTION_MENU_OK: case ACTION_MENU_A: vk = VK_RETURN; break;
|
||||||
case ACTION_MENU_DOWN: kbDown = KMInput.IsKeyDown(VK_DOWN); kbPressed = KMInput.IsKeyPressed(VK_DOWN); kbReleased = KMInput.IsKeyReleased(VK_DOWN); break;
|
case ACTION_MENU_CANCEL: case ACTION_MENU_B: vk = VK_ESCAPE; break;
|
||||||
case ACTION_MENU_LEFT: kbDown = KMInput.IsKeyDown(VK_LEFT); kbPressed = KMInput.IsKeyPressed(VK_LEFT); kbReleased = KMInput.IsKeyReleased(VK_LEFT); break;
|
case ACTION_MENU_UP: vk = VK_UP; break;
|
||||||
case ACTION_MENU_RIGHT: kbDown = KMInput.IsKeyDown(VK_RIGHT); kbPressed = KMInput.IsKeyPressed(VK_RIGHT); kbReleased = KMInput.IsKeyReleased(VK_RIGHT); break;
|
case ACTION_MENU_DOWN: vk = VK_DOWN; break;
|
||||||
case ACTION_MENU_OK: kbDown = KMInput.IsKeyDown(VK_RETURN); kbPressed = KMInput.IsKeyPressed(VK_RETURN); kbReleased = KMInput.IsKeyReleased(VK_RETURN); break;
|
case ACTION_MENU_LEFT: vk = VK_LEFT; break;
|
||||||
case ACTION_MENU_A: kbDown = KMInput.IsKeyDown(VK_RETURN); kbPressed = KMInput.IsKeyPressed(VK_RETURN); kbReleased = KMInput.IsKeyReleased(VK_RETURN); break;
|
case ACTION_MENU_RIGHT: vk = VK_RIGHT; break;
|
||||||
case ACTION_MENU_CANCEL: kbDown = KMInput.IsKeyDown(VK_ESCAPE); kbPressed = KMInput.IsKeyPressed(VK_ESCAPE); kbReleased = KMInput.IsKeyReleased(VK_ESCAPE); break;
|
case ACTION_MENU_X: vk = 'R'; break;
|
||||||
case ACTION_MENU_B: kbDown = KMInput.IsKeyDown(VK_ESCAPE); kbPressed = KMInput.IsKeyPressed(VK_ESCAPE); kbReleased = KMInput.IsKeyReleased(VK_ESCAPE); break;
|
case ACTION_MENU_Y: vk = VK_TAB; break;
|
||||||
case ACTION_MENU_PAUSEMENU: kbDown = KMInput.IsKeyDown(VK_ESCAPE); kbPressed = KMInput.IsKeyPressed(VK_ESCAPE); kbReleased = KMInput.IsKeyReleased(VK_ESCAPE); break;
|
case ACTION_MENU_LEFT_SCROLL: vk = 'Q'; break;
|
||||||
case ACTION_MENU_LEFT_SCROLL: kbDown = KMInput.IsKeyDown('Q'); kbPressed = KMInput.IsKeyPressed('Q'); kbReleased = KMInput.IsKeyReleased('Q'); break;
|
case ACTION_MENU_RIGHT_SCROLL: vk = 'E'; break;
|
||||||
case ACTION_MENU_RIGHT_SCROLL: kbDown = KMInput.IsKeyDown('E'); kbPressed = KMInput.IsKeyPressed('E'); kbReleased = KMInput.IsKeyReleased('E'); break;
|
case ACTION_MENU_PAGEUP: vk = VK_PRIOR; break;
|
||||||
case ACTION_MENU_QUICK_MOVE: kbDown = KMInput.IsKeyDown(VK_SHIFT); kbPressed = KMInput.IsKeyPressed(VK_SHIFT); kbReleased = KMInput.IsKeyReleased(VK_SHIFT); break;
|
case ACTION_MENU_PAGEDOWN: vk = VK_NEXT; break;
|
||||||
|
}
|
||||||
|
if (vk != 0)
|
||||||
|
{
|
||||||
|
if (g_KBMInput.IsKeyPressed(vk)) { pressed = true; down = true; }
|
||||||
|
if (g_KBMInput.IsKeyReleased(vk)) { released = true; down = false; }
|
||||||
|
if (!pressed && !released && g_KBMInput.IsKeyDown(vk)) { down = true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((key == ACTION_MENU_OK || key == ACTION_MENU_A) && !g_KBMInput.IsMouseGrabbed())
|
||||||
|
{
|
||||||
|
if (m_mouseDraggingSliderId < 0)
|
||||||
|
{
|
||||||
|
if (g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_LEFT)) { pressed = true; down = true; }
|
||||||
|
if (g_KBMInput.IsMouseButtonReleased(KeyboardMouseInput::MOUSE_LEFT)) { released = true; down = false; }
|
||||||
|
if (!pressed && !released && g_KBMInput.IsMouseButtonDown(KeyboardMouseInput::MOUSE_LEFT)) { down = true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll wheel for list scrolling — only consume the wheel value when the
|
||||||
|
// action key actually matches, so the other direction isn't lost.
|
||||||
|
if (!g_KBMInput.IsMouseGrabbed() && (key == ACTION_MENU_OTHER_STICK_UP || key == ACTION_MENU_OTHER_STICK_DOWN))
|
||||||
|
{
|
||||||
|
int wheel = g_KBMInput.PeekMouseWheel();
|
||||||
|
if (key == ACTION_MENU_OTHER_STICK_UP && wheel > 0)
|
||||||
|
{
|
||||||
|
g_KBMInput.ConsumeMouseWheel();
|
||||||
|
pressed = true;
|
||||||
|
down = true;
|
||||||
|
}
|
||||||
|
else if (key == ACTION_MENU_OTHER_STICK_DOWN && wheel < 0)
|
||||||
|
{
|
||||||
|
g_KBMInput.ConsumeMouseWheel();
|
||||||
|
pressed = true;
|
||||||
|
down = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pressed = pressed || kbPressed;
|
|
||||||
released = released || kbReleased;
|
|
||||||
down = down || kbDown;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -1445,7 +1661,7 @@ GDrawTexture * RADLINK UIController::TextureSubstitutionCreateCallback ( void *
|
||||||
|
|
||||||
// 4J Stu - All our flash controls that allow replacing textures use a special 64x64 symbol
|
// 4J Stu - All our flash controls that allow replacing textures use a special 64x64 symbol
|
||||||
// Force this size here so that our images don't get scaled wildly
|
// Force this size here so that our images don't get scaled wildly
|
||||||
#if (defined __ORBIS__ || defined _DURANGO )
|
#if (defined __ORBIS__ || defined _DURANGO || defined _WINDOWS64 )
|
||||||
*width = 96;
|
*width = 96;
|
||||||
*height = 96;
|
*height = 96;
|
||||||
#else
|
#else
|
||||||
|
|
@ -3138,4 +3354,4 @@ void UIController::SendTouchInput(unsigned int iPad, unsigned int key, bool bPre
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,10 @@ private:
|
||||||
vector<QueuedMessageBoxData *> m_queuedMessageBoxData;
|
vector<QueuedMessageBoxData *> m_queuedMessageBoxData;
|
||||||
|
|
||||||
unsigned int m_winUserIndex;
|
unsigned int m_winUserIndex;
|
||||||
|
EUIScene m_mouseDraggingSliderScene;
|
||||||
|
int m_mouseDraggingSliderId;
|
||||||
|
int m_lastHoverMouseX;
|
||||||
|
int m_lastHoverMouseY;
|
||||||
//bool m_bSysUIShowing;
|
//bool m_bSysUIShowing;
|
||||||
bool m_bSystemUIShowing;
|
bool m_bSystemUIShowing;
|
||||||
C4JThread *m_reloadSkinThread;
|
C4JThread *m_reloadSkinThread;
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,7 @@ private:
|
||||||
public:
|
public:
|
||||||
UIGroup(EUIGroup group, int iPad);
|
UIGroup(EUIGroup group, int iPad);
|
||||||
|
|
||||||
#ifdef __PSVITA__
|
|
||||||
EUIGroup GetGroup() {return m_group;}
|
EUIGroup GetGroup() {return m_group;}
|
||||||
#endif
|
|
||||||
UIComponent_Tooltips *getTooltips() { return m_tooltips; }
|
UIComponent_Tooltips *getTooltips() { return m_tooltips; }
|
||||||
UIComponent_TutorialPopup *getTutorialPopup() { return m_tutorialPopup; }
|
UIComponent_TutorialPopup *getTutorialPopup() { return m_tutorialPopup; }
|
||||||
UIScene_HUD *getHUD() { return m_hud; }
|
UIScene_HUD *getHUD() { return m_hud; }
|
||||||
|
|
|
||||||
|
|
@ -107,8 +107,10 @@ public:
|
||||||
int getRenderHeight() { return m_renderHeight; }
|
int getRenderHeight() { return m_renderHeight; }
|
||||||
|
|
||||||
#ifdef __PSVITA__
|
#ifdef __PSVITA__
|
||||||
UILayer *GetParentLayer() {return m_parentLayer;}
|
|
||||||
EUIGroup GetParentLayerGroup() {return m_parentLayer->m_parentGroup->GetGroup();}
|
EUIGroup GetParentLayerGroup() {return m_parentLayer->m_parentGroup->GetGroup();}
|
||||||
|
#endif
|
||||||
|
#if defined(__PSVITA__) || defined(_WINDOWS64)
|
||||||
|
UILayer *GetParentLayer() {return m_parentLayer;}
|
||||||
vector<UIControl *> *GetControls() {return &m_controls;}
|
vector<UIControl *> *GetControls() {return &m_controls;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,6 @@ UIScene_AbstractContainerMenu::UIScene_AbstractContainerMenu(int iPad, UILayer *
|
||||||
ui.OverrideSFX(m_iPad,ACTION_MENU_DOWN,true);
|
ui.OverrideSFX(m_iPad,ACTION_MENU_DOWN,true);
|
||||||
|
|
||||||
m_bIgnoreInput=false;
|
m_bIgnoreInput=false;
|
||||||
#ifdef _WINDOWS64
|
|
||||||
m_bMouseDragSlider=false;
|
|
||||||
m_bHasMousePosition = false;
|
|
||||||
m_lastMouseX = 0;
|
|
||||||
m_lastMouseY = 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UIScene_AbstractContainerMenu::~UIScene_AbstractContainerMenu()
|
UIScene_AbstractContainerMenu::~UIScene_AbstractContainerMenu()
|
||||||
|
|
@ -44,6 +38,16 @@ UIScene_AbstractContainerMenu::~UIScene_AbstractContainerMenu()
|
||||||
void UIScene_AbstractContainerMenu::handleDestroy()
|
void UIScene_AbstractContainerMenu::handleDestroy()
|
||||||
{
|
{
|
||||||
app.DebugPrintf("UIScene_AbstractContainerMenu::handleDestroy\n");
|
app.DebugPrintf("UIScene_AbstractContainerMenu::handleDestroy\n");
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
g_savedInventoryCursorPos.x = m_pointerPos.x;
|
||||||
|
g_savedInventoryCursorPos.y = m_pointerPos.y;
|
||||||
|
g_savedInventoryCursorPos.hasSavedPos = true;
|
||||||
|
|
||||||
|
g_KBMInput.SetScreenCursorHidden(false);
|
||||||
|
g_KBMInput.SetCursorHiddenForUI(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||||
if( pMinecraft->localgameModes[m_iPad] != NULL )
|
if( pMinecraft->localgameModes[m_iPad] != NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -79,6 +83,10 @@ void UIScene_AbstractContainerMenu::InitDataAssociations(int iPad, AbstractConta
|
||||||
|
|
||||||
void UIScene_AbstractContainerMenu::PlatformInitialize(int iPad, int startIndex)
|
void UIScene_AbstractContainerMenu::PlatformInitialize(int iPad, int startIndex)
|
||||||
{
|
{
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
g_KBMInput.SetScreenCursorHidden(true);
|
||||||
|
g_KBMInput.SetCursorHiddenForUI(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
m_labelInventory.init( app.GetString(IDS_INVENTORY) );
|
m_labelInventory.init( app.GetString(IDS_INVENTORY) );
|
||||||
|
|
||||||
|
|
@ -163,6 +171,19 @@ void UIScene_AbstractContainerMenu::PlatformInitialize(int iPad, int startIndex)
|
||||||
//m_pointerControl->SetPosition( &vPointerPos );
|
//m_pointerControl->SetPosition( &vPointerPos );
|
||||||
m_pointerPos = vPointerPos;
|
m_pointerPos = vPointerPos;
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (g_savedInventoryCursorPos.hasSavedPos)
|
||||||
|
{
|
||||||
|
m_pointerPos.x = g_savedInventoryCursorPos.x;
|
||||||
|
m_pointerPos.y = g_savedInventoryCursorPos.y;
|
||||||
|
|
||||||
|
if (m_pointerPos.x < m_fPointerMinX) m_pointerPos.x = m_fPointerMinX;
|
||||||
|
if (m_pointerPos.x > m_fPointerMaxX) m_pointerPos.x = m_fPointerMaxX;
|
||||||
|
if (m_pointerPos.y < m_fPointerMinY) m_pointerPos.y = m_fPointerMinY;
|
||||||
|
if (m_pointerPos.y > m_fPointerMaxY) m_pointerPos.y = m_fPointerMaxY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
IggyEvent mouseEvent;
|
IggyEvent mouseEvent;
|
||||||
S32 width, height;
|
S32 width, height;
|
||||||
m_parentLayer->getRenderDimensions(width, height);
|
m_parentLayer->getRenderDimensions(width, height);
|
||||||
|
|
@ -185,134 +206,15 @@ void UIScene_AbstractContainerMenu::tick()
|
||||||
{
|
{
|
||||||
UIScene::tick();
|
UIScene::tick();
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
|
||||||
bool mouseActive = (m_iPad == 0 && !KMInput.IsCaptured());
|
|
||||||
bool drivePointerFromMouse = false;
|
|
||||||
float rawMouseMovieX = 0, rawMouseMovieY = 0;
|
|
||||||
int scrollDelta = 0;
|
|
||||||
// Map Windows mouse position to the virtual pointer in movie coordinates
|
|
||||||
if (mouseActive)
|
|
||||||
{
|
|
||||||
RECT clientRect;
|
|
||||||
GetClientRect(KMInput.GetHWnd(), &clientRect);
|
|
||||||
int clientWidth = clientRect.right;
|
|
||||||
int clientHeight = clientRect.bottom;
|
|
||||||
if (clientWidth > 0 && clientHeight > 0)
|
|
||||||
{
|
|
||||||
int mouseX = KMInput.GetMouseX();
|
|
||||||
int mouseY = KMInput.GetMouseY();
|
|
||||||
bool mouseMoved = !m_bHasMousePosition || mouseX != m_lastMouseX || mouseY != m_lastMouseY;
|
|
||||||
|
|
||||||
m_bHasMousePosition = true;
|
|
||||||
m_lastMouseX = mouseX;
|
|
||||||
m_lastMouseY = mouseY;
|
|
||||||
scrollDelta = KMInput.ConsumeScrollDelta();
|
|
||||||
|
|
||||||
// Convert mouse position to movie coordinates using the movie/client ratio
|
|
||||||
float mx = (float)mouseX * ((float)m_movieWidth / (float)clientWidth);
|
|
||||||
float my = (float)mouseY * ((float)m_movieHeight / (float)clientHeight);
|
|
||||||
|
|
||||||
rawMouseMovieX = mx;
|
|
||||||
rawMouseMovieY = my;
|
|
||||||
|
|
||||||
// Once the mouse has taken over the container cursor, keep following the OS cursor
|
|
||||||
// until explicit controller input takes ownership back.
|
|
||||||
drivePointerFromMouse = m_bPointerDrivenByMouse || mouseMoved || KMInput.IsMouseDown(0) || KMInput.IsMouseDown(1) || KMInput.IsMouseDown(2) || scrollDelta != 0;
|
|
||||||
if (drivePointerFromMouse)
|
|
||||||
{
|
|
||||||
m_bPointerDrivenByMouse = true;
|
|
||||||
m_eCurrTapState = eTapStateNoInput;
|
|
||||||
m_pointerPos.x = mx;
|
|
||||||
m_pointerPos.y = my;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
onMouseTick();
|
onMouseTick();
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
|
||||||
// Dispatch mouse clicks AFTER onMouseTick() has updated m_eCurrSection from the new pointer position
|
|
||||||
if (mouseActive)
|
|
||||||
{
|
|
||||||
if (KMInput.ConsumeMousePress(0))
|
|
||||||
{
|
|
||||||
if (m_eCurrSection == eSectionInventoryCreativeSlider)
|
|
||||||
{
|
|
||||||
// Scrollbar click: use raw mouse position (onMouseTick may have snapped m_pointerPos)
|
|
||||||
m_bMouseDragSlider = true;
|
|
||||||
m_pointerPos.x = rawMouseMovieX;
|
|
||||||
m_pointerPos.y = rawMouseMovieY;
|
|
||||||
handleOtherClicked(m_iPad, eSectionInventoryCreativeSlider, 0, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_A, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_bMouseDragSlider && KMInput.IsMouseDown(0))
|
|
||||||
{
|
|
||||||
// Continue scrollbar drag: update scroll position from current mouse Y
|
|
||||||
m_pointerPos.x = rawMouseMovieX;
|
|
||||||
m_pointerPos.y = rawMouseMovieY;
|
|
||||||
handleOtherClicked(m_iPad, eSectionInventoryCreativeSlider, 0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!KMInput.IsMouseDown(0))
|
|
||||||
m_bMouseDragSlider = false;
|
|
||||||
|
|
||||||
if (KMInput.ConsumeMousePress(1))
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_X, false);
|
|
||||||
}
|
|
||||||
if (KMInput.ConsumeMousePress(2))
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_Y, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse scroll wheel for page scrolling
|
|
||||||
if (scrollDelta > 0)
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_OTHER_STICK_UP, false);
|
|
||||||
}
|
|
||||||
else if (scrollDelta < 0)
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_OTHER_STICK_DOWN, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ESC to close — must be last since it may destroy this scene
|
|
||||||
if (KMInput.ConsumeKeyPress(VK_ESCAPE))
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_B, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
IggyEvent mouseEvent;
|
IggyEvent mouseEvent;
|
||||||
S32 width, height;
|
S32 width, height;
|
||||||
m_parentLayer->getRenderDimensions(width, height);
|
m_parentLayer->getRenderDimensions(width, height);
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
S32 x = (S32)(m_pointerPos.x * ((float)width / m_movieWidth));
|
||||||
S32 x, y;
|
S32 y = (S32)(m_pointerPos.y * ((float)height / m_movieHeight));
|
||||||
if (mouseActive && m_bPointerDrivenByMouse)
|
|
||||||
{
|
|
||||||
// Send raw mouse position directly as Iggy event to avoid coordinate round-trip errors
|
|
||||||
// Scale mouse client coords to the Iggy display space (which was set to getRenderDimensions())
|
|
||||||
RECT clientRect;
|
|
||||||
GetClientRect(KMInput.GetHWnd(), &clientRect);
|
|
||||||
x = (S32)((float)KMInput.GetMouseX() * ((float)width / (float)clientRect.right));
|
|
||||||
y = (S32)((float)KMInput.GetMouseY() * ((float)height / (float)clientRect.bottom));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x = (S32)(m_pointerPos.x * ((float)width / m_movieWidth));
|
|
||||||
y = (S32)(m_pointerPos.y * ((float)height / m_movieHeight));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
S32 x = m_pointerPos.x*((float)width/m_movieWidth);
|
|
||||||
S32 y = m_pointerPos.y*((float)height/m_movieHeight);
|
|
||||||
#endif
|
|
||||||
IggyMakeEventMouseMove( &mouseEvent, x, y);
|
IggyMakeEventMouseMove( &mouseEvent, x, y);
|
||||||
|
|
||||||
// 4J Stu - This seems to be broken on Durango, so do it ourself
|
// 4J Stu - This seems to be broken on Durango, so do it ourself
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,6 @@ class UIScene_AbstractContainerMenu : public UIScene, public virtual IUIScene_Ab
|
||||||
private:
|
private:
|
||||||
ESceneSection m_focusSection;
|
ESceneSection m_focusSection;
|
||||||
bool m_bIgnoreInput;
|
bool m_bIgnoreInput;
|
||||||
#ifdef _WINDOWS64
|
|
||||||
bool m_bMouseDragSlider;
|
|
||||||
bool m_bHasMousePosition;
|
|
||||||
int m_lastMouseX;
|
|
||||||
int m_lastMouseY;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UIControl m_controlMainPanel;
|
UIControl m_controlMainPanel;
|
||||||
|
|
@ -42,6 +36,8 @@ public:
|
||||||
virtual void handleDestroy();
|
virtual void handleDestroy();
|
||||||
|
|
||||||
int getPad() { return m_iPad; }
|
int getPad() { return m_iPad; }
|
||||||
|
int getMovieWidth() { return m_movieWidth; }
|
||||||
|
int getMovieHeight() { return m_movieHeight; }
|
||||||
bool getIgnoreInput() { return m_bIgnoreInput; }
|
bool getIgnoreInput() { return m_bIgnoreInput; }
|
||||||
void setIgnoreInput(bool bVal) { m_bIgnoreInput=bVal; }
|
void setIgnoreInput(bool bVal) { m_bIgnoreInput=bVal; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1085,6 +1085,7 @@ void UIScene_CreateWorldMenu::CreateGame(UIScene_CreateWorldMenu* pClass, DWORD
|
||||||
__int64 seedValue = 0;
|
__int64 seedValue = 0;
|
||||||
|
|
||||||
NetworkGameInitData *param = new NetworkGameInitData();
|
NetworkGameInitData *param = new NetworkGameInitData();
|
||||||
|
param->levelName = wWorldName;
|
||||||
|
|
||||||
if (wSeed.length() != 0)
|
if (wSeed.length() != 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -39,17 +39,37 @@ UIScene_DebugOverlay::UIScene_DebugOverlay(int iPad, void *initData, UILayer *pa
|
||||||
m_buttonSetNight.init(L"Set Night", eControl_SetNight);
|
m_buttonSetNight.init(L"Set Night", eControl_SetNight);
|
||||||
|
|
||||||
m_buttonListItems.init(eControl_Items);
|
m_buttonListItems.init(eControl_Items);
|
||||||
|
|
||||||
|
// Sort items alphabetically
|
||||||
|
std::vector<std::pair<std::wstring, unsigned int>> sortedItems;
|
||||||
|
for (size_t i = 0; i < Item::items.length; ++i)
|
||||||
|
{
|
||||||
|
if (Item::items[i] != NULL)
|
||||||
|
{
|
||||||
|
sortedItems.emplace_back(std::wstring(app.GetString(Item::items[i]->getDescriptionId())), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i < sortedItems.size(); ++i)
|
||||||
|
{
|
||||||
|
auto key = sortedItems[i];
|
||||||
|
int j = i - 1;
|
||||||
|
while (j >= 0 && sortedItems[j].first > key.first)
|
||||||
|
{
|
||||||
|
sortedItems[j + 1] = sortedItems[j];
|
||||||
|
--j;
|
||||||
|
}
|
||||||
|
sortedItems[j + 1] = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate the list in sorted order
|
||||||
int listId = 0;
|
int listId = 0;
|
||||||
for(unsigned int i = 0; i < Item::items.length; ++i)
|
for (const auto& entry : sortedItems)
|
||||||
{
|
{
|
||||||
if(Item::items[i] != NULL)
|
m_itemIds.push_back(entry.second);
|
||||||
{
|
m_buttonListItems.addItem(entry.first.c_str(), listId);
|
||||||
m_itemIds.push_back(i);
|
++listId;
|
||||||
m_buttonListItems.addItem(app.GetString(Item::items[i]->getDescriptionId()), listId);
|
}
|
||||||
++listId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_buttonListEnchantments.init(eControl_Enchantments);
|
m_buttonListEnchantments.init(eControl_Enchantments);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,7 @@ UIScene_LoadMenu::UIScene_LoadMenu(int iPad, void *initData, UILayer *parentLaye
|
||||||
#endif
|
#endif
|
||||||
m_bShowTimer = true;
|
m_bShowTimer = true;
|
||||||
}
|
}
|
||||||
#if defined(_DURANGO)
|
#if defined(_DURANGO)
|
||||||
m_labelGameName.init(params->saveDetails->UTF16SaveName);
|
m_labelGameName.init(params->saveDetails->UTF16SaveName);
|
||||||
#else
|
#else
|
||||||
wchar_t wSaveName[128];
|
wchar_t wSaveName[128];
|
||||||
|
|
@ -246,6 +246,16 @@ UIScene_LoadMenu::UIScene_LoadMenu(int iPad, void *initData, UILayer *parentLaye
|
||||||
mbstowcs(wSaveName, params->saveDetails->UTF8SaveName, strlen(params->saveDetails->UTF8SaveName)+1); // plus null
|
mbstowcs(wSaveName, params->saveDetails->UTF8SaveName, strlen(params->saveDetails->UTF8SaveName)+1); // plus null
|
||||||
m_labelGameName.init(wSaveName);
|
m_labelGameName.init(wSaveName);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (params->saveDetails != NULL && params->saveDetails->UTF8SaveName[0] != '\0')
|
||||||
|
{
|
||||||
|
wchar_t wSaveName[128];
|
||||||
|
ZeroMemory(wSaveName, sizeof(wSaveName));
|
||||||
|
mbstowcs(wSaveName, params->saveDetails->UTF8SaveName, 127);
|
||||||
|
m_levelName = wstring(wSaveName);
|
||||||
|
m_labelGameName.init(m_levelName);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1574,6 +1584,7 @@ void UIScene_LoadMenu::StartGameFromSave(UIScene_LoadMenu* pClass, DWORD dwLocal
|
||||||
param->saveData = NULL;
|
param->saveData = NULL;
|
||||||
param->levelGen = pClass->m_levelGen;
|
param->levelGen = pClass->m_levelGen;
|
||||||
param->texturePackId = pClass->m_MoreOptionsParams.dwTexturePack;
|
param->texturePackId = pClass->m_MoreOptionsParams.dwTexturePack;
|
||||||
|
param->levelName = pClass->m_levelName;
|
||||||
|
|
||||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||||
pMinecraft->skins->selectTexturePackById(pClass->m_MoreOptionsParams.dwTexturePack);
|
pMinecraft->skins->selectTexturePackById(pClass->m_MoreOptionsParams.dwTexturePack);
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ private:
|
||||||
bool m_bIsCorrupt;
|
bool m_bIsCorrupt;
|
||||||
bool m_bThumbnailGetFailed;
|
bool m_bThumbnailGetFailed;
|
||||||
__int64 m_seed;
|
__int64 m_seed;
|
||||||
|
wstring m_levelName;
|
||||||
|
|
||||||
#ifdef __PS3__
|
#ifdef __PS3__
|
||||||
std::vector<SonyCommerce::ProductInfo>*m_pvProductInfo;
|
std::vector<SonyCommerce::ProductInfo>*m_pvProductInfo;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,98 @@
|
||||||
#include "message_dialog.h"
|
#include "message_dialog.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
#include "..\..\..\Minecraft.World\NbtIo.h"
|
||||||
|
#include "..\..\..\Minecraft.World\compression.h"
|
||||||
|
|
||||||
|
static wstring ReadLevelNameFromSaveFile(const wstring& filePath)
|
||||||
|
{
|
||||||
|
HANDLE hFile = CreateFileW(filePath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE) return L"";
|
||||||
|
|
||||||
|
DWORD fileSize = GetFileSize(hFile, NULL);
|
||||||
|
if (fileSize < 12 || fileSize == INVALID_FILE_SIZE) { CloseHandle(hFile); return L""; }
|
||||||
|
|
||||||
|
unsigned char *rawData = new unsigned char[fileSize];
|
||||||
|
DWORD bytesRead = 0;
|
||||||
|
if (!ReadFile(hFile, rawData, fileSize, &bytesRead, NULL) || bytesRead != fileSize)
|
||||||
|
{
|
||||||
|
CloseHandle(hFile);
|
||||||
|
delete[] rawData;
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
unsigned char *saveData = NULL;
|
||||||
|
unsigned int saveSize = 0;
|
||||||
|
bool freeSaveData = false;
|
||||||
|
|
||||||
|
if (*(unsigned int*)rawData == 0)
|
||||||
|
{
|
||||||
|
// Compressed format: bytes 0-3=0, bytes 4-7=decompressed size, bytes 8+=compressed data
|
||||||
|
unsigned int decompSize = *(unsigned int*)(rawData + 4);
|
||||||
|
if (decompSize == 0 || decompSize > 128 * 1024 * 1024)
|
||||||
|
{
|
||||||
|
delete[] rawData;
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
saveData = new unsigned char[decompSize];
|
||||||
|
Compression::getCompression()->Decompress(saveData, &decompSize, rawData + 8, fileSize - 8);
|
||||||
|
saveSize = decompSize;
|
||||||
|
freeSaveData = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
saveData = rawData;
|
||||||
|
saveSize = fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
wstring result = L"";
|
||||||
|
if (saveSize >= 12)
|
||||||
|
{
|
||||||
|
unsigned int headerOffset = *(unsigned int*)saveData;
|
||||||
|
unsigned int numEntries = *(unsigned int*)(saveData + 4);
|
||||||
|
const unsigned int entrySize = sizeof(FileEntrySaveData);
|
||||||
|
|
||||||
|
if (headerOffset < saveSize && numEntries > 0 && numEntries < 10000 &&
|
||||||
|
headerOffset + numEntries * entrySize <= saveSize)
|
||||||
|
{
|
||||||
|
FileEntrySaveData *table = (FileEntrySaveData *)(saveData + headerOffset);
|
||||||
|
for (unsigned int i = 0; i < numEntries; i++)
|
||||||
|
{
|
||||||
|
if (wcscmp(table[i].filename, L"level.dat") == 0)
|
||||||
|
{
|
||||||
|
unsigned int off = table[i].startOffset;
|
||||||
|
unsigned int len = table[i].length;
|
||||||
|
if (off >= 12 && off + len <= saveSize && len > 0 && len < 4 * 1024 * 1024)
|
||||||
|
{
|
||||||
|
byteArray ba;
|
||||||
|
ba.data = (byte*)(saveData + off);
|
||||||
|
ba.length = len;
|
||||||
|
CompoundTag *root = NbtIo::decompress(ba);
|
||||||
|
if (root != NULL)
|
||||||
|
{
|
||||||
|
CompoundTag *dataTag = root->getCompound(L"Data");
|
||||||
|
if (dataTag != NULL)
|
||||||
|
result = dataTag->getString(L"LevelName");
|
||||||
|
delete root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (freeSaveData) delete[] saveData;
|
||||||
|
delete[] rawData;
|
||||||
|
// "world" is the engine default — it means no real name was ever set, so
|
||||||
|
// return empty to let the caller fall back to the save filename (timestamp).
|
||||||
|
if (result == L"world") result = L"";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef SONY_REMOTE_STORAGE_DOWNLOAD
|
#ifdef SONY_REMOTE_STORAGE_DOWNLOAD
|
||||||
unsigned long UIScene_LoadOrJoinMenu::m_ulFileSize=0L;
|
unsigned long UIScene_LoadOrJoinMenu::m_ulFileSize=0L;
|
||||||
|
|
@ -159,7 +251,7 @@ UIScene_LoadOrJoinMenu::UIScene_LoadOrJoinMenu(int iPad, void *initData, UILayer
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) || defined(_DURANGO)
|
#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) || defined(_DURANGO) || defined(_WINDOWS64)
|
||||||
// Always clear the saves when we enter this menu
|
// Always clear the saves when we enter this menu
|
||||||
StorageManager.ClearSavesInfo();
|
StorageManager.ClearSavesInfo();
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -614,6 +706,22 @@ void UIScene_LoadOrJoinMenu::tick()
|
||||||
m_saveDetails = new SaveListDetails[m_pSaveDetails->iSaveC];
|
m_saveDetails = new SaveListDetails[m_pSaveDetails->iSaveC];
|
||||||
|
|
||||||
m_iSaveDetailsCount = m_pSaveDetails->iSaveC;
|
m_iSaveDetailsCount = m_pSaveDetails->iSaveC;
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
// Build sorted index array (newest-first by filename timestamp YYYYMMDDHHMMSS)
|
||||||
|
int *sortedIdx = new int[m_pSaveDetails->iSaveC];
|
||||||
|
for (int si = 0; si < (int)m_pSaveDetails->iSaveC; ++si) sortedIdx[si] = si;
|
||||||
|
for (int si = 1; si < (int)m_pSaveDetails->iSaveC; ++si)
|
||||||
|
{
|
||||||
|
int key = sortedIdx[si];
|
||||||
|
int sj = si - 1;
|
||||||
|
while (sj >= 0 && strcmp(m_pSaveDetails->SaveInfoA[sortedIdx[sj]].UTF8SaveFilename, m_pSaveDetails->SaveInfoA[key].UTF8SaveFilename) < 0)
|
||||||
|
{
|
||||||
|
sortedIdx[sj + 1] = sortedIdx[sj];
|
||||||
|
--sj;
|
||||||
|
}
|
||||||
|
sortedIdx[sj + 1] = key;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
for(unsigned int i = 0; i < m_pSaveDetails->iSaveC; ++i)
|
for(unsigned int i = 0; i < m_pSaveDetails->iSaveC; ++i)
|
||||||
{
|
{
|
||||||
#if defined(_XBOX_ONE)
|
#if defined(_XBOX_ONE)
|
||||||
|
|
@ -627,14 +735,40 @@ void UIScene_LoadOrJoinMenu::tick()
|
||||||
m_saveDetails[i].saveId = i;
|
m_saveDetails[i].saveId = i;
|
||||||
memcpy(m_saveDetails[i].UTF16SaveName, m_pSaveDetails->SaveInfoA[i].UTF16SaveTitle, 128);
|
memcpy(m_saveDetails[i].UTF16SaveName, m_pSaveDetails->SaveInfoA[i].UTF16SaveTitle, 128);
|
||||||
memcpy(m_saveDetails[i].UTF16SaveFilename, m_pSaveDetails->SaveInfoA[i].UTF16SaveFilename, MAX_SAVEFILENAME_LENGTH);
|
memcpy(m_saveDetails[i].UTF16SaveFilename, m_pSaveDetails->SaveInfoA[i].UTF16SaveFilename, MAX_SAVEFILENAME_LENGTH);
|
||||||
|
#else
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
{
|
||||||
|
int origIdx = sortedIdx[i];
|
||||||
|
wchar_t wFilename[MAX_SAVEFILENAME_LENGTH];
|
||||||
|
ZeroMemory(wFilename, sizeof(wFilename));
|
||||||
|
mbstowcs(wFilename, m_pSaveDetails->SaveInfoA[origIdx].UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH - 1);
|
||||||
|
wstring filePath = wstring(L"Windows64\\GameHDD\\") + wstring(wFilename) + wstring(L"\\saveData.ms");
|
||||||
|
wstring levelName = ReadLevelNameFromSaveFile(filePath);
|
||||||
|
if (!levelName.empty())
|
||||||
|
{
|
||||||
|
m_buttonListSaves.addItem(levelName, wstring(L""));
|
||||||
|
wcstombs(m_saveDetails[i].UTF8SaveName, levelName.c_str(), 127);
|
||||||
|
m_saveDetails[i].UTF8SaveName[127] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_buttonListSaves.addItem(m_pSaveDetails->SaveInfoA[origIdx].UTF8SaveTitle, L"");
|
||||||
|
memcpy(m_saveDetails[i].UTF8SaveName, m_pSaveDetails->SaveInfoA[origIdx].UTF8SaveTitle, 128);
|
||||||
|
}
|
||||||
|
m_saveDetails[i].saveId = origIdx;
|
||||||
|
memcpy(m_saveDetails[i].UTF8SaveFilename, m_pSaveDetails->SaveInfoA[origIdx].UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
m_buttonListSaves.addItem(m_pSaveDetails->SaveInfoA[i].UTF8SaveTitle, L"");
|
m_buttonListSaves.addItem(m_pSaveDetails->SaveInfoA[i].UTF8SaveTitle, L"");
|
||||||
|
|
||||||
m_saveDetails[i].saveId = i;
|
|
||||||
memcpy(m_saveDetails[i].UTF8SaveName, m_pSaveDetails->SaveInfoA[i].UTF8SaveTitle, 128);
|
memcpy(m_saveDetails[i].UTF8SaveName, m_pSaveDetails->SaveInfoA[i].UTF8SaveTitle, 128);
|
||||||
|
m_saveDetails[i].saveId = i;
|
||||||
memcpy(m_saveDetails[i].UTF8SaveFilename, m_pSaveDetails->SaveInfoA[i].UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH);
|
memcpy(m_saveDetails[i].UTF8SaveFilename, m_pSaveDetails->SaveInfoA[i].UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
delete[] sortedIdx;
|
||||||
|
#endif
|
||||||
m_controlSavesTimer.setVisible( false );
|
m_controlSavesTimer.setVisible( false );
|
||||||
|
|
||||||
// set focus on the first button
|
// set focus on the first button
|
||||||
|
|
@ -650,7 +784,11 @@ void UIScene_LoadOrJoinMenu::tick()
|
||||||
app.DebugPrintf("Requesting the first thumbnail\n");
|
app.DebugPrintf("Requesting the first thumbnail\n");
|
||||||
// set the save to load
|
// set the save to load
|
||||||
PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo();
|
PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo();
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveDataThumbnail(&pSaveDetails->SaveInfoA[m_saveDetails[m_iRequestingThumbnailId].saveId],&LoadSaveDataThumbnailReturned,this);
|
||||||
|
#else
|
||||||
C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveDataThumbnail(&pSaveDetails->SaveInfoA[(int)m_iRequestingThumbnailId],&LoadSaveDataThumbnailReturned,this);
|
C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveDataThumbnail(&pSaveDetails->SaveInfoA[(int)m_iRequestingThumbnailId],&LoadSaveDataThumbnailReturned,this);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(eLoadStatus!=C4JStorage::ESaveGame_GetSaveThumbnail)
|
if(eLoadStatus!=C4JStorage::ESaveGame_GetSaveThumbnail)
|
||||||
{
|
{
|
||||||
|
|
@ -713,7 +851,11 @@ void UIScene_LoadOrJoinMenu::tick()
|
||||||
app.DebugPrintf("Requesting another thumbnail\n");
|
app.DebugPrintf("Requesting another thumbnail\n");
|
||||||
// set the save to load
|
// set the save to load
|
||||||
PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo();
|
PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo();
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveDataThumbnail(&pSaveDetails->SaveInfoA[m_saveDetails[m_iRequestingThumbnailId].saveId],&LoadSaveDataThumbnailReturned,this);
|
||||||
|
#else
|
||||||
C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveDataThumbnail(&pSaveDetails->SaveInfoA[(int)m_iRequestingThumbnailId],&LoadSaveDataThumbnailReturned,this);
|
C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveDataThumbnail(&pSaveDetails->SaveInfoA[(int)m_iRequestingThumbnailId],&LoadSaveDataThumbnailReturned,this);
|
||||||
|
#endif
|
||||||
if(eLoadStatus!=C4JStorage::ESaveGame_GetSaveThumbnail)
|
if(eLoadStatus!=C4JStorage::ESaveGame_GetSaveThumbnail)
|
||||||
{
|
{
|
||||||
// something went wrong
|
// something went wrong
|
||||||
|
|
@ -1175,6 +1317,14 @@ void UIScene_LoadOrJoinMenu::handleInput(int iPad, int key, bool repeat, bool pr
|
||||||
sendInputToMovie(key, repeat, pressed, released);
|
sendInputToMovie(key, repeat, pressed, released);
|
||||||
handled = true;
|
handled = true;
|
||||||
break;
|
break;
|
||||||
|
case ACTION_MENU_OTHER_STICK_UP:
|
||||||
|
sendInputToMovie(ACTION_MENU_UP, repeat, pressed, released);
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case ACTION_MENU_OTHER_STICK_DOWN:
|
||||||
|
sendInputToMovie(ACTION_MENU_DOWN, repeat, pressed, released);
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1323,7 +1473,7 @@ void UIScene_LoadOrJoinMenu::handlePress(F64 controlId, F64 childId)
|
||||||
LoadMenuInitData *params = new LoadMenuInitData();
|
LoadMenuInitData *params = new LoadMenuInitData();
|
||||||
params->iPad = m_iPad;
|
params->iPad = m_iPad;
|
||||||
// need to get the iIndex from the list item, since the position in the list doesn't correspond to the GetSaveGameInfo list because of sorting
|
// need to get the iIndex from the list item, since the position in the list doesn't correspond to the GetSaveGameInfo list because of sorting
|
||||||
params->iSaveGameInfoIndex=((int)childId)-m_iDefaultButtonsC;
|
params->iSaveGameInfoIndex=m_saveDetails[((int)childId)-m_iDefaultButtonsC].saveId;
|
||||||
//params->pbSaveRenamed=&m_bSaveRenamed;
|
//params->pbSaveRenamed=&m_bSaveRenamed;
|
||||||
params->levelGen = NULL;
|
params->levelGen = NULL;
|
||||||
params->saveDetails = &m_saveDetails[ ((int)childId)-m_iDefaultButtonsC ];
|
params->saveDetails = &m_saveDetails[ ((int)childId)-m_iDefaultButtonsC ];
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,33 @@
|
||||||
#include "..\..\Minecraft.h"
|
#include "..\..\Minecraft.h"
|
||||||
#include "..\..\GameRenderer.h"
|
#include "..\..\GameRenderer.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const int FOV_MIN = 70;
|
||||||
|
const int FOV_MAX = 110;
|
||||||
|
const int FOV_SLIDER_MAX = 100;
|
||||||
|
|
||||||
|
int clampFov(int value)
|
||||||
|
{
|
||||||
|
if (value < FOV_MIN) return FOV_MIN;
|
||||||
|
if (value > FOV_MAX) return FOV_MAX;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fovToSliderValue(float fov)
|
||||||
|
{
|
||||||
|
int clampedFov = clampFov((int)(fov + 0.5f));
|
||||||
|
return ((clampedFov - FOV_MIN) * FOV_SLIDER_MAX) / (FOV_MAX - FOV_MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sliderValueToFov(int sliderValue)
|
||||||
|
{
|
||||||
|
if (sliderValue < 0) sliderValue = 0;
|
||||||
|
if (sliderValue > FOV_SLIDER_MAX) sliderValue = FOV_SLIDER_MAX;
|
||||||
|
return FOV_MIN + ((sliderValue * (FOV_MAX - FOV_MIN)) / FOV_SLIDER_MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UIScene_SettingsGraphicsMenu::UIScene_SettingsGraphicsMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
UIScene_SettingsGraphicsMenu::UIScene_SettingsGraphicsMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
||||||
{
|
{
|
||||||
// Setup all the Iggy references we need for this scene
|
// Setup all the Iggy references we need for this scene
|
||||||
|
|
@ -22,8 +49,9 @@ UIScene_SettingsGraphicsMenu::UIScene_SettingsGraphicsMenu(int iPad, void *initD
|
||||||
swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_GAMMA ),app.GetGameSettings(m_iPad,eGameSetting_Gamma));
|
swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_GAMMA ),app.GetGameSettings(m_iPad,eGameSetting_Gamma));
|
||||||
m_sliderGamma.init(TempString,eControl_Gamma,0,100,app.GetGameSettings(m_iPad,eGameSetting_Gamma));
|
m_sliderGamma.init(TempString,eControl_Gamma,0,100,app.GetGameSettings(m_iPad,eGameSetting_Gamma));
|
||||||
|
|
||||||
swprintf((WCHAR*)TempString, 256, L"FOV: %d%%", (int)pMinecraft->gameRenderer->GetFovVal());
|
int initialFov = clampFov((int)(pMinecraft->gameRenderer->GetFovVal() + 0.5f));
|
||||||
m_sliderFOV.init(TempString, eControl_FOV, 70, 110, (int)pMinecraft->gameRenderer->GetFovVal());
|
swprintf((WCHAR*)TempString, 256, L"FOV: %d", initialFov);
|
||||||
|
m_sliderFOV.init(TempString, eControl_FOV, 0, FOV_SLIDER_MAX, fovToSliderValue((float)initialFov));
|
||||||
|
|
||||||
swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_INTERFACEOPACITY ),app.GetGameSettings(m_iPad,eGameSetting_InterfaceOpacity));
|
swprintf( (WCHAR *)TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_INTERFACEOPACITY ),app.GetGameSettings(m_iPad,eGameSetting_InterfaceOpacity));
|
||||||
m_sliderInterfaceOpacity.init(TempString,eControl_InterfaceOpacity,0,100,app.GetGameSettings(m_iPad,eGameSetting_InterfaceOpacity));
|
m_sliderInterfaceOpacity.init(TempString,eControl_InterfaceOpacity,0,100,app.GetGameSettings(m_iPad,eGameSetting_InterfaceOpacity));
|
||||||
|
|
@ -150,10 +178,12 @@ void UIScene_SettingsGraphicsMenu::handleSliderMove(F64 sliderId, F64 currentVal
|
||||||
|
|
||||||
case eControl_FOV:
|
case eControl_FOV:
|
||||||
{
|
{
|
||||||
|
m_sliderFOV.handleSliderMove(value);
|
||||||
Minecraft* pMinecraft = Minecraft::GetInstance();
|
Minecraft* pMinecraft = Minecraft::GetInstance();
|
||||||
pMinecraft->gameRenderer->SetFovVal((float)currentValue);
|
int fovValue = sliderValueToFov(value);
|
||||||
|
pMinecraft->gameRenderer->SetFovVal((float)fovValue);
|
||||||
WCHAR TempString[256];
|
WCHAR TempString[256];
|
||||||
swprintf((WCHAR*)TempString, 256, L"FOV: %d%%", (int)currentValue);
|
swprintf((WCHAR*)TempString, 256, L"FOV: %d", fovValue);
|
||||||
m_sliderFOV.setLabel(TempString);
|
m_sliderFOV.setLabel(TempString);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -6,35 +6,33 @@
|
||||||
// 4J - added
|
// 4J - added
|
||||||
void CreeperModel::_init(float g)
|
void CreeperModel::_init(float g)
|
||||||
{
|
{
|
||||||
int yo = 4;
|
|
||||||
|
|
||||||
head = new ModelPart(this, 0, 0);
|
head = new ModelPart(this, 0, 0);
|
||||||
head->addBox(-4, - 8, -4, 8, 8, 8, g); // Head
|
head->addBox(-4, - 8, -4, 8, 8, 8, g); // Head
|
||||||
head->setPos(0, (float)(yo), 0);
|
head->setPos(0, 6, 0);
|
||||||
|
|
||||||
hair = new ModelPart(this, 32, 0);
|
hair = new ModelPart(this, 32, 0);
|
||||||
hair->addBox(-4, -8, -4, 8, 8, 8, g + 0.5f); // Head
|
hair->addBox(-4, -8, -4, 8, 8, 8, g + 0.5f); // Head
|
||||||
hair->setPos(0, (float)(yo), 0);
|
hair->setPos(0, 6, 0);
|
||||||
|
|
||||||
body = new ModelPart(this, 16, 16);
|
body = new ModelPart(this, 16, 16);
|
||||||
body->addBox(-4, 0, -2, 8, 12, 4, g); // Body
|
body->addBox(-4, 0, -2, 8, 12, 4, g); // Body
|
||||||
body->setPos(0, (float)(yo), 0);
|
body->setPos(0, 6, 0);
|
||||||
|
|
||||||
leg0 = new ModelPart(this, 0, 16);
|
leg0 = new ModelPart(this, 0, 16);
|
||||||
leg0->addBox(-2, 0, -2, 4, 6, 4, g); // Leg0
|
leg0->addBox(-2, 0, -2, 4, 6, 4, g); // Leg0
|
||||||
leg0->setPos(-2, (float)(12 + yo), 4);
|
leg0->setPos(-2, 18, 4);
|
||||||
|
|
||||||
leg1 = new ModelPart(this, 0, 16);
|
leg1 = new ModelPart(this, 0, 16);
|
||||||
leg1->addBox(-2, 0, -2, 4, 6, 4, g); // Leg1
|
leg1->addBox(-2, 0, -2, 4, 6, 4, g); // Leg1
|
||||||
leg1->setPos(2, (float)(12 + yo), 4);
|
leg1->setPos(2, 18, 4);
|
||||||
|
|
||||||
leg2 = new ModelPart(this, 0, 16);
|
leg2 = new ModelPart(this, 0, 16);
|
||||||
leg2->addBox(-2, 0, -2, 4, 6, 4, g); // Leg2
|
leg2->addBox(-2, 0, -2, 4, 6, 4, g); // Leg2
|
||||||
leg2->setPos(-2, (float)(12 + yo), -4);
|
leg2->setPos(-2, 18, -4);
|
||||||
|
|
||||||
leg3 = new ModelPart(this, 0, 16);
|
leg3 = new ModelPart(this, 0, 16);
|
||||||
leg3->addBox(-2, 0, -2, 4, 6, 4, g); // Leg3
|
leg3->addBox(-2, 0, -2, 4, 6, 4, g); // Leg3
|
||||||
leg3->setPos(2, (float)(12 + yo), -4);
|
leg3->setPos(2, 18, -4);
|
||||||
|
|
||||||
// 4J added - compile now to avoid random performance hit first time cubes are rendered
|
// 4J added - compile now to avoid random performance hit first time cubes are rendered
|
||||||
head->compile(1.0f/16.0f);
|
head->compile(1.0f/16.0f);
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -54,13 +54,13 @@ void EntityTracker::addEntity(shared_ptr<Entity> e)
|
||||||
else if (e->instanceof(eTYPE_THROWNEXPBOTTLE)) addEntity(e, 16 * 4, 10, true);
|
else if (e->instanceof(eTYPE_THROWNEXPBOTTLE)) addEntity(e, 16 * 4, 10, true);
|
||||||
else if (e->instanceof(eTYPE_FIREWORKS_ROCKET)) addEntity(e, 16 * 4, 10, true);
|
else if (e->instanceof(eTYPE_FIREWORKS_ROCKET)) addEntity(e, 16 * 4, 10, true);
|
||||||
else if (e->instanceof(eTYPE_ITEMENTITY)) addEntity(e, 16 * 4, 20, true);
|
else if (e->instanceof(eTYPE_ITEMENTITY)) addEntity(e, 16 * 4, 20, true);
|
||||||
else if (e->instanceof(eTYPE_MINECART)) addEntity(e, 16 * 5, 3, true);
|
else if (e->instanceof(eTYPE_MINECART)) addEntity(e, 16 * 5, 1, true);
|
||||||
else if (e->instanceof(eTYPE_BOAT)) addEntity(e, 16 * 5, 3, true);
|
else if (e->instanceof(eTYPE_BOAT)) addEntity(e, 16 * 5, 1, true);
|
||||||
else if (e->instanceof(eTYPE_SQUID)) addEntity(e, 16 * 4, 3, true);
|
else if (e->instanceof(eTYPE_SQUID)) addEntity(e, 16 * 4, 1, true);
|
||||||
else if (e->instanceof(eTYPE_WITHERBOSS)) addEntity(e, 16 * 5, 3, false);
|
else if (e->instanceof(eTYPE_WITHERBOSS)) addEntity(e, 16 * 5, 1, false);
|
||||||
else if (e->instanceof(eTYPE_BAT)) addEntity(e, 16 * 5, 3, false);
|
else if (e->instanceof(eTYPE_BAT)) addEntity(e, 16 * 5, 1, false);
|
||||||
else if (dynamic_pointer_cast<Creature>(e)!=NULL) addEntity(e, 16 * 5, 3, true);
|
else if (dynamic_pointer_cast<Creature>(e)!=NULL) addEntity(e, 16 * 5, 1, true);
|
||||||
else if (e->instanceof(eTYPE_ENDERDRAGON)) addEntity(e, 16 * 10, 3, true);
|
else if (e->instanceof(eTYPE_ENDERDRAGON)) addEntity(e, 16 * 10, 1, true);
|
||||||
else if (e->instanceof(eTYPE_PRIMEDTNT)) addEntity(e, 16 * 10, 10, true);
|
else if (e->instanceof(eTYPE_PRIMEDTNT)) addEntity(e, 16 * 10, 10, true);
|
||||||
else if (e->instanceof(eTYPE_FALLINGTILE)) addEntity(e, 16 * 10, 20, true);
|
else if (e->instanceof(eTYPE_FALLINGTILE)) addEntity(e, 16 * 10, 20, true);
|
||||||
else if (e->instanceof(eTYPE_HANGING_ENTITY)) addEntity(e, 16 * 10, INT_MAX, false);
|
else if (e->instanceof(eTYPE_HANGING_ENTITY)) addEntity(e, 16 * 10, INT_MAX, false);
|
||||||
|
|
@ -245,4 +245,4 @@ shared_ptr<TrackedEntity> EntityTracker::getTracker(shared_ptr<Entity> e)
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -501,23 +501,26 @@ void GameRenderer::moveCameraToPlayer(float a)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 4J - corrected bug where this used to just take player->xRot & yRot directly and so wasn't taking into account interpolation, allowing camera to go through walls
|
// 4J - corrected bug where this used to just take player->xRot & yRot directly and so wasn't taking into account interpolation, allowing camera to go through walls
|
||||||
float playerYRot = player->yRotO + (player->yRot - player->yRotO) * a;
|
float yRot = player->yRotO + (player->yRot - player->yRotO) * a;
|
||||||
float playerXRot = player->xRotO + (player->xRot - player->xRotO) * a;
|
float xRot = player->xRotO + (player->xRot - player->xRotO) * a;
|
||||||
float yRot = playerYRot;
|
|
||||||
float xRot = playerXRot;
|
|
||||||
|
|
||||||
// Thirdperson view values are now 0 for disabled, 1 for original mode, 2 for reversed.
|
// Thirdperson view values are now 0 for disabled, 1 for original mode, 2 for reversed.
|
||||||
if( localplayer->ThirdPersonView() == 2 )
|
if( localplayer->ThirdPersonView() == 2 )
|
||||||
{
|
{
|
||||||
// Reverse x rotation - note that this is only used in doing collision to calculate our view
|
// Reverse y rotation - note that this is only used in doing collision to calculate our view
|
||||||
// distance, the actual rotation itself is just below this else {} block
|
// distance, the actual rotation itself is just below this else {} block
|
||||||
xRot += 180.0f;
|
yRot += 180.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
double xd = -Mth::sin(yRot / 180 * PI) * Mth::cos(xRot / 180 * PI) * cameraDist;
|
double xd = -Mth::sin(yRot / 180 * PI) * Mth::cos(xRot / 180 * PI) * cameraDist;
|
||||||
double zd = Mth::cos(yRot / 180 * PI) * Mth::cos(xRot / 180 * PI) * cameraDist;
|
double zd = Mth::cos(yRot / 180 * PI) * Mth::cos(xRot / 180 * PI) * cameraDist;
|
||||||
double yd = -Mth::sin(xRot / 180 * PI) * cameraDist;
|
double yd = -Mth::sin(xRot / 180 * PI) * cameraDist;
|
||||||
|
|
||||||
|
if (localplayer->ThirdPersonView() == 2)
|
||||||
|
{
|
||||||
|
yd = Mth::sin(xRot / 180 * PI) * cameraDist;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
float xo = (float)((i & 1) * 2 - 1);
|
float xo = (float)((i & 1) * 2 - 1);
|
||||||
|
|
@ -538,16 +541,7 @@ void GameRenderer::moveCameraToPlayer(float a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( localplayer->ThirdPersonView() == 2)
|
|
||||||
{
|
|
||||||
glRotatef(180, 0, 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
glRotatef(playerXRot - xRot, 1, 0, 0);
|
|
||||||
glRotatef(playerYRot - yRot, 0, 1, 0);
|
|
||||||
glTranslatef(0, 0, (float) -cameraDist);
|
glTranslatef(0, 0, (float) -cameraDist);
|
||||||
glRotatef(yRot - playerYRot, 0, 1, 0);
|
|
||||||
glRotatef(xRot - playerXRot, 1, 0, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -557,8 +551,21 @@ void GameRenderer::moveCameraToPlayer(float a)
|
||||||
|
|
||||||
if (!mc->options->fixedCamera)
|
if (!mc->options->fixedCamera)
|
||||||
{
|
{
|
||||||
glRotatef(player->xRotO + (player->xRot - player->xRotO) * a, 1, 0, 0);
|
float pitch = player->xRotO + (player->xRot - player->xRotO) * a;
|
||||||
glRotatef(player->yRotO + (player->yRot - player->yRotO) * a + 180, 0, 1, 0);
|
if (localplayer->ThirdPersonView() == 2)
|
||||||
|
{
|
||||||
|
pitch = -pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
glRotatef(pitch, 1, 0, 0);
|
||||||
|
if (localplayer->ThirdPersonView() == 2)
|
||||||
|
{
|
||||||
|
glRotatef(player->yRotO + (player->yRot - player->yRotO) * a, 0, 1, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glRotatef(player->yRotO + (player->yRot - player->yRotO) * a + 180, 0, 1, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glTranslatef(0, heightOffset, 0);
|
glTranslatef(0, heightOffset, 0);
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,21 @@
|
||||||
#include "Input.h"
|
#include "Input.h"
|
||||||
#include "..\Minecraft.Client\LocalPlayer.h"
|
#include "..\Minecraft.Client\LocalPlayer.h"
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
#include "Windows64\KeyboardMouseInput.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
Input::Input()
|
Input::Input()
|
||||||
{
|
{
|
||||||
xa = 0;
|
xa = 0;
|
||||||
ya = 0;
|
ya = 0;
|
||||||
sprintForward = 0;
|
|
||||||
wasJumping = false;
|
wasJumping = false;
|
||||||
jumping = false;
|
jumping = false;
|
||||||
sneaking = false;
|
sneaking = false;
|
||||||
usingKeyboardMovement = false;
|
sprinting = false;
|
||||||
|
|
||||||
lReset = false;
|
lReset = false;
|
||||||
rReset = false;
|
rReset = false;
|
||||||
m_gamepadSneaking = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::tick(LocalPlayer *player)
|
void Input::tick(LocalPlayer *player)
|
||||||
|
|
@ -32,43 +33,43 @@ void Input::tick(LocalPlayer *player)
|
||||||
Minecraft *pMinecraft=Minecraft::GetInstance();
|
Minecraft *pMinecraft=Minecraft::GetInstance();
|
||||||
int iPad=player->GetXboxPad();
|
int iPad=player->GetXboxPad();
|
||||||
|
|
||||||
|
float controllerXA = 0.0f;
|
||||||
|
float controllerYA = 0.0f;
|
||||||
|
|
||||||
// 4J-PB minecraft movement seems to be the wrong way round, so invert x!
|
// 4J-PB minecraft movement seems to be the wrong way round, so invert x!
|
||||||
if( pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LEFT) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_RIGHT) )
|
if( pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LEFT) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_RIGHT) )
|
||||||
xa = -InputManager.GetJoypadStick_LX(iPad);
|
controllerXA = -InputManager.GetJoypadStick_LX(iPad);
|
||||||
else
|
|
||||||
xa = 0.0f;
|
|
||||||
|
|
||||||
if( pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_FORWARD) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_BACKWARD) )
|
if( pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_FORWARD) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_BACKWARD) )
|
||||||
ya = InputManager.GetJoypadStick_LY(iPad);
|
controllerYA = InputManager.GetJoypadStick_LY(iPad);
|
||||||
else
|
|
||||||
ya = 0.0f;
|
|
||||||
sprintForward = ya;
|
|
||||||
usingKeyboardMovement = false;
|
|
||||||
|
|
||||||
|
float kbXA = 0.0f;
|
||||||
|
float kbYA = 0.0f;
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
// WASD movement (combine with gamepad)
|
if (iPad == 0 && g_KBMInput.IsMouseGrabbed() && g_KBMInput.IsKBMActive())
|
||||||
if (iPad == 0 && KMInput.IsCaptured())
|
|
||||||
{
|
{
|
||||||
float kbX = 0.0f, kbY = 0.0f;
|
if( pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LEFT) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_RIGHT) )
|
||||||
if (KMInput.IsKeyDown('W')) { kbY += 1.0f; sprintForward += 1.0f; usingKeyboardMovement = true; }
|
kbXA = g_KBMInput.GetMoveX();
|
||||||
if (KMInput.IsKeyDown('S')) { kbY -= 1.0f; sprintForward -= 1.0f; usingKeyboardMovement = true; }
|
if( pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_FORWARD) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_BACKWARD) )
|
||||||
if (KMInput.IsKeyDown('A')) { kbX += 1.0f; usingKeyboardMovement = true; } // inverted like gamepad
|
kbYA = g_KBMInput.GetMoveY();
|
||||||
if (KMInput.IsKeyDown('D')) { kbX -= 1.0f; usingKeyboardMovement = true; }
|
|
||||||
// Normalize diagonal
|
|
||||||
if (kbX != 0.0f && kbY != 0.0f) { kbX *= 0.707f; kbY *= 0.707f; }
|
|
||||||
if (pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LEFT) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_RIGHT))
|
|
||||||
xa = max(min(xa + kbX, 1.0f), -1.0f);
|
|
||||||
if (pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_FORWARD) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_BACKWARD))
|
|
||||||
ya = max(min(ya + kbY, 1.0f), -1.0f);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
sprintForward = max(min(sprintForward, 1.0f), -1.0f);
|
|
||||||
|
if (kbXA != 0.0f || kbYA != 0.0f)
|
||||||
|
{
|
||||||
|
xa = kbXA;
|
||||||
|
ya = kbYA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xa = controllerXA;
|
||||||
|
ya = controllerYA;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef _CONTENT_PACKAGE
|
#ifndef _CONTENT_PACKAGE
|
||||||
if (app.GetFreezePlayers())
|
if (app.GetFreezePlayers())
|
||||||
{
|
{
|
||||||
xa = ya = 0.0f;
|
xa = ya = 0.0f;
|
||||||
sprintForward = 0.0f;
|
|
||||||
player->abilities.flying = true;
|
player->abilities.flying = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -80,7 +81,6 @@ void Input::tick(LocalPlayer *player)
|
||||||
lReset = true;
|
lReset = true;
|
||||||
}
|
}
|
||||||
xa = ya = 0.0f;
|
xa = ya = 0.0f;
|
||||||
sprintForward = 0.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4J: In flying mode, don't actually toggle sneaking (unless we're riding in which case we need to sneak to dismount)
|
// 4J: In flying mode, don't actually toggle sneaking (unless we're riding in which case we need to sneak to dismount)
|
||||||
|
|
@ -88,15 +88,41 @@ void Input::tick(LocalPlayer *player)
|
||||||
{
|
{
|
||||||
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_SNEAK_TOGGLE)) && pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_SNEAK_TOGGLE))
|
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_SNEAK_TOGGLE)) && pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_SNEAK_TOGGLE))
|
||||||
{
|
{
|
||||||
m_gamepadSneaking=!m_gamepadSneaking;
|
sneaking=!sneaking;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sneaking = m_gamepadSneaking;
|
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
// Keyboard hold-to-sneak (overrides gamepad toggle)
|
if (iPad == 0 && g_KBMInput.IsMouseGrabbed() && g_KBMInput.IsKBMActive())
|
||||||
if (iPad == 0 && KMInput.IsCaptured() && KMInput.IsKeyDown(VK_SHIFT) && !player->abilities.flying)
|
{
|
||||||
sneaking = true;
|
// Left Shift = sneak (hold to crouch)
|
||||||
|
if (pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_SNEAK_TOGGLE))
|
||||||
|
{
|
||||||
|
if (!player->abilities.flying)
|
||||||
|
{
|
||||||
|
sneaking = g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_SNEAK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ctrl + forward = sprint (hold to sprint, including while flying)
|
||||||
|
{
|
||||||
|
bool ctrlHeld = g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_SPRINT);
|
||||||
|
bool movingForward = (kbYA > 0.0f);
|
||||||
|
|
||||||
|
if (ctrlHeld && movingForward)
|
||||||
|
{
|
||||||
|
sprinting = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprinting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (iPad == 0)
|
||||||
|
{
|
||||||
|
sprinting = false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(sneaking)
|
if(sneaking)
|
||||||
|
|
@ -109,6 +135,7 @@ void Input::tick(LocalPlayer *player)
|
||||||
|
|
||||||
float tx = 0.0f;
|
float tx = 0.0f;
|
||||||
float ty = 0.0f;
|
float ty = 0.0f;
|
||||||
|
|
||||||
if( pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_LEFT) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_RIGHT) )
|
if( pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_LEFT) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_RIGHT) )
|
||||||
tx = InputManager.GetJoypadStick_RX(iPad)*(((float)app.GetGameSettings(iPad,eGameSetting_Sensitivity_InGame))/100.0f); // apply sensitivity to look
|
tx = InputManager.GetJoypadStick_RX(iPad)*(((float)app.GetGameSettings(iPad,eGameSetting_Sensitivity_InGame))/100.0f); // apply sensitivity to look
|
||||||
if( pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_UP) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_DOWN) )
|
if( pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_UP) || pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_DOWN) )
|
||||||
|
|
@ -132,47 +159,52 @@ void Input::tick(LocalPlayer *player)
|
||||||
}
|
}
|
||||||
tx = ty = 0.0f;
|
tx = ty = 0.0f;
|
||||||
}
|
}
|
||||||
player->interpolateTurn(tx * abs(tx) * turnSpeed, ty * abs(ty) * turnSpeed);
|
|
||||||
|
float turnX = tx * abs(tx) * turnSpeed;
|
||||||
|
float turnY = ty * abs(ty) * turnSpeed;
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
// Mouse look is now handled per-frame in Minecraft::applyFrameMouseLook()
|
if (iPad == 0 && g_KBMInput.IsMouseGrabbed() && g_KBMInput.IsKBMActive())
|
||||||
// to eliminate the 20Hz tick delay. Only flush any remaining delta here
|
|
||||||
// as a safety measure.
|
|
||||||
if (iPad == 0 && KMInput.IsCaptured())
|
|
||||||
{
|
{
|
||||||
float rawDx, rawDy;
|
float mouseSensitivity = ((float)app.GetGameSettings(iPad,eGameSetting_Sensitivity_InGame)) / 100.0f;
|
||||||
KMInput.ConsumeMouseDelta(rawDx, rawDy);
|
float mouseLookScale = 5.0f;
|
||||||
// Delta should normally be 0 since applyFrameMouseLook() already consumed it
|
float mx = g_KBMInput.GetLookX(mouseSensitivity * mouseLookScale);
|
||||||
if (rawDx != 0.0f || rawDy != 0.0f)
|
float my = g_KBMInput.GetLookY(mouseSensitivity * mouseLookScale);
|
||||||
|
|
||||||
|
if ( app.GetGameSettings(iPad,eGameSetting_ControlInvertLook) )
|
||||||
{
|
{
|
||||||
float mouseSensitivity = ((float)app.GetGameSettings(iPad, eGameSetting_Sensitivity_InGame)) / 100.0f;
|
my = -my;
|
||||||
float mdx = rawDx * mouseSensitivity;
|
|
||||||
float mdy = -rawDy * mouseSensitivity;
|
|
||||||
if (app.GetGameSettings(iPad, eGameSetting_ControlInvertLook))
|
|
||||||
mdy = -mdy;
|
|
||||||
player->interpolateTurn(mdx, mdy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
turnX += mx;
|
||||||
|
turnY += my;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
player->interpolateTurn(turnX, turnY);
|
||||||
|
|
||||||
//jumping = controller.isButtonPressed(0);
|
//jumping = controller.isButtonPressed(0);
|
||||||
|
|
||||||
|
|
||||||
unsigned int jump = InputManager.GetValue(iPad, MINECRAFT_ACTION_JUMP);
|
unsigned int jump = InputManager.GetValue(iPad, MINECRAFT_ACTION_JUMP);
|
||||||
if( jump > 0 && pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_JUMP) )
|
bool kbJump = false;
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
kbJump = (iPad == 0) && g_KBMInput.IsMouseGrabbed() && g_KBMInput.IsKBMActive() && g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_JUMP);
|
||||||
|
#endif
|
||||||
|
if( (jump > 0 || kbJump) && pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_JUMP) )
|
||||||
jumping = true;
|
jumping = true;
|
||||||
else
|
else
|
||||||
jumping = false;
|
jumping = false;
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
|
||||||
// Keyboard jump (Space)
|
|
||||||
if (iPad == 0 && KMInput.IsCaptured() && KMInput.IsKeyDown(VK_SPACE) && pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_JUMP))
|
|
||||||
jumping = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _CONTENT_PACKAGE
|
#ifndef _CONTENT_PACKAGE
|
||||||
if (app.GetFreezePlayers()) jumping = false;
|
if (app.GetFreezePlayers()) jumping = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (iPad == 0 && g_KBMInput.IsKeyPressed(VK_ESCAPE) && g_KBMInput.IsMouseGrabbed())
|
||||||
|
{
|
||||||
|
g_KBMInput.SetMouseGrabbed(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//OutputDebugString("INPUT: End input tick\n");
|
//OutputDebugString("INPUT: End input tick\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,17 @@ class Input
|
||||||
public:
|
public:
|
||||||
float xa;
|
float xa;
|
||||||
float ya;
|
float ya;
|
||||||
float sprintForward;
|
|
||||||
|
|
||||||
bool wasJumping;
|
bool wasJumping;
|
||||||
bool jumping;
|
bool jumping;
|
||||||
bool sneaking;
|
bool sneaking;
|
||||||
bool usingKeyboardMovement;
|
bool sprinting;
|
||||||
|
|
||||||
Input(); // 4J - added
|
Input();
|
||||||
|
|
||||||
virtual void tick(LocalPlayer *player);
|
virtual void tick(LocalPlayer *player);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool lReset;
|
bool lReset;
|
||||||
bool rReset;
|
bool rReset;
|
||||||
bool m_gamepadSneaking;
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -548,7 +548,7 @@ void ItemInHandRenderer::render(float a)
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
float d = 0.8f;
|
float d = 0.8f;
|
||||||
|
|
||||||
#if defined __ORBIS__ || defined __PS3__
|
#if defined __ORBIS__ || defined __PS3__ || defined _WINDOWS64
|
||||||
static const float swingPowFactor = 1.0f;
|
static const float swingPowFactor = 1.0f;
|
||||||
#else
|
#else
|
||||||
static const float swingPowFactor = 4.0f; // 4J added, to slow the swing down when nearest the player for avoiding luminance flash issues
|
static const float swingPowFactor = 4.0f; // 4J added, to slow the swing down when nearest the player for avoiding luminance flash issues
|
||||||
|
|
|
||||||
|
|
@ -2557,13 +2557,19 @@ void LevelRenderer::cull(Culler *culler, float a)
|
||||||
{
|
{
|
||||||
unsigned char flags = pClipChunk->globalIdx == -1 ? 0 : globalChunkFlags[ pClipChunk->globalIdx ];
|
unsigned char flags = pClipChunk->globalIdx == -1 ? 0 : globalChunkFlags[ pClipChunk->globalIdx ];
|
||||||
|
|
||||||
|
// Always perform frustum cull test
|
||||||
|
bool clipres = clip(pClipChunk->aabb, fdraw);
|
||||||
|
|
||||||
if ( (flags & CHUNK_FLAG_COMPILED ) && ( ( flags & CHUNK_FLAG_EMPTYBOTH ) != CHUNK_FLAG_EMPTYBOTH ) )
|
if ( (flags & CHUNK_FLAG_COMPILED ) && ( ( flags & CHUNK_FLAG_EMPTYBOTH ) != CHUNK_FLAG_EMPTYBOTH ) )
|
||||||
{
|
{
|
||||||
bool clipres = clip(pClipChunk->aabb, fdraw);
|
|
||||||
pClipChunk->visible = clipres;
|
pClipChunk->visible = clipres;
|
||||||
if( pClipChunk->visible ) vis++;
|
if( pClipChunk->visible ) vis++;
|
||||||
total++;
|
total++;
|
||||||
}
|
}
|
||||||
|
else if (clipres)
|
||||||
|
{
|
||||||
|
pClipChunk->visible = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pClipChunk->visible = false;
|
pClipChunk->visible = false;
|
||||||
|
|
@ -2572,6 +2578,7 @@ void LevelRenderer::cull(Culler *culler, float a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LevelRenderer::playStreamingMusic(const wstring& name, int x, int y, int z)
|
void LevelRenderer::playStreamingMusic(const wstring& name, int x, int y, int z)
|
||||||
{
|
{
|
||||||
if (name != L"")
|
if (name != L"")
|
||||||
|
|
|
||||||
|
|
@ -487,11 +487,11 @@ void LivingEntityRenderer::renderNameTag(shared_ptr<LivingEntity> mob, const wst
|
||||||
|
|
||||||
Font *font = getFont();
|
Font *font = getFont();
|
||||||
|
|
||||||
float size = 1.60f;
|
constexpr float size = 1.60f;
|
||||||
float s = 1 / 60.0f * size;
|
constexpr float s = 1 / 60.0f * size;
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef((float) x + 0, (float) y + 2.3f, (float) z);
|
glTranslatef(static_cast<float>(x) + 0, static_cast<float>(y) + mob->bbHeight + 0.5f, static_cast<float>(z));
|
||||||
glNormal3f(0, 1, 0);
|
glNormal3f(0, 1, 0);
|
||||||
|
|
||||||
glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0);
|
glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0);
|
||||||
|
|
|
||||||
|
|
@ -251,13 +251,10 @@ void LocalPlayer::aiStep()
|
||||||
if (changingDimensionDelay > 0) changingDimensionDelay--;
|
if (changingDimensionDelay > 0) changingDimensionDelay--;
|
||||||
bool wasJumping = input->jumping;
|
bool wasJumping = input->jumping;
|
||||||
float runTreshold = 0.8f;
|
float runTreshold = 0.8f;
|
||||||
float sprintForward = input->sprintForward;
|
bool wasRunning = input->ya >= runTreshold;
|
||||||
|
|
||||||
bool wasRunning = sprintForward >= runTreshold;
|
|
||||||
//input->tick( dynamic_pointer_cast<Player>( shared_from_this() ) );
|
//input->tick( dynamic_pointer_cast<Player>( shared_from_this() ) );
|
||||||
// 4J-PB - make it a localplayer
|
// 4J-PB - make it a localplayer
|
||||||
input->tick( this );
|
input->tick( this );
|
||||||
sprintForward = input->sprintForward;
|
|
||||||
if (isUsingItem() && !isRiding())
|
if (isUsingItem() && !isRiding())
|
||||||
{
|
{
|
||||||
input->xa *= 0.2f;
|
input->xa *= 0.2f;
|
||||||
|
|
@ -281,25 +278,9 @@ void LocalPlayer::aiStep()
|
||||||
// world with low food, then reload it in creative.
|
// world with low food, then reload it in creative.
|
||||||
if(abilities.mayfly || isAllowedToFly() ) enoughFoodToSprint = true;
|
if(abilities.mayfly || isAllowedToFly() ) enoughFoodToSprint = true;
|
||||||
|
|
||||||
bool forwardEnoughToTriggerSprint = sprintForward >= runTreshold;
|
bool forwardEnoughToTriggerSprint = input->ya >= runTreshold;
|
||||||
bool forwardReturnedToDeadzone = sprintForward == 0.0f;
|
bool forwardReturnedToDeadzone = input->ya == 0.0f;
|
||||||
bool forwardEnoughToContinueSprint = sprintForward >= runTreshold;
|
bool forwardEnoughToContinueSprint = input->ya >= runTreshold;
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
|
||||||
if (GetXboxPad() == 0 && input->usingKeyboardMovement)
|
|
||||||
{
|
|
||||||
forwardEnoughToContinueSprint = sprintForward > 0.0f;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
|
||||||
// Keyboard sprint: Ctrl held while moving forward
|
|
||||||
if (GetXboxPad() == 0 && input->usingKeyboardMovement && KMInput.IsKeyDown(VK_CONTROL) && sprintForward > 0.0f &&
|
|
||||||
enoughFoodToSprint && !isUsingItem() && !hasEffect(MobEffect::blindness) && onGround)
|
|
||||||
{
|
|
||||||
if (!isSprinting()) setSprinting(true);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 4J - altered this slightly to make sure that the joypad returns to below returnTreshold in between registering two movements up to runThreshold
|
// 4J - altered this slightly to make sure that the joypad returns to below returnTreshold in between registering two movements up to runThreshold
|
||||||
if (onGround && !isSprinting() && enoughFoodToSprint && !isUsingItem() && !hasEffect(MobEffect::blindness))
|
if (onGround && !isSprinting() && enoughFoodToSprint && !isUsingItem() && !hasEffect(MobEffect::blindness))
|
||||||
|
|
@ -327,6 +308,12 @@ void LocalPlayer::aiStep()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isSneaking()) sprintTriggerTime = 0;
|
if (isSneaking()) sprintTriggerTime = 0;
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (input->sprinting && onGround && enoughFoodToSprint && !isUsingItem() && !hasEffect(MobEffect::blindness) && !isSneaking())
|
||||||
|
{
|
||||||
|
setSprinting(true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// 4J-PB - try not stopping sprint on collision
|
// 4J-PB - try not stopping sprint on collision
|
||||||
//if (isSprinting() && (input->ya < runTreshold || horizontalCollision || !enoughFoodToSprint))
|
//if (isSprinting() && (input->ya < runTreshold || horizontalCollision || !enoughFoodToSprint))
|
||||||
if (isSprinting() && (!forwardEnoughToContinueSprint || !enoughFoodToSprint || isSneaking() || isUsingItem()))
|
if (isSprinting() && (!forwardEnoughToContinueSprint || !enoughFoodToSprint || isSneaking() || isUsingItem()))
|
||||||
|
|
|
||||||
|
|
@ -1545,6 +1545,7 @@ if not exist "$(TargetDir)\savedata" mkdir "$(TargetDir)\savedata"</Command>
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||||
<ShowIncludes>false</ShowIncludes>
|
<ShowIncludes>false</ShowIncludes>
|
||||||
|
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
|
@ -1773,7 +1774,7 @@ xcopy /q /y /i /s /e $(ProjectDir)DurangoMedia\CU $(LayoutDir)Image\Loose\CU</C
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<AdditionalOptions>/Ob3</AdditionalOptions>
|
<AdditionalOptions>/FS /Ob3 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
|
@ -48680,4 +48681,4 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -19,4 +19,4 @@
|
||||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)$(Platform)\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
<LocalDebuggerWorkingDirectory>$(SolutionDir)$(Platform)\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -502,6 +502,13 @@ void Minecraft::setScreen(Screen *screen)
|
||||||
this->screen->removed();
|
this->screen->removed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (screen != NULL && g_KBMInput.IsMouseGrabbed())
|
||||||
|
{
|
||||||
|
g_KBMInput.SetMouseGrabbed(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//4J Gordon: Do not force a stats save here
|
//4J Gordon: Do not force a stats save here
|
||||||
/*if (dynamic_cast<TitleScreen *>(screen)!=NULL)
|
/*if (dynamic_cast<TitleScreen *>(screen)!=NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -1184,11 +1191,11 @@ void Minecraft::applyFrameMouseLook()
|
||||||
int iPad = localplayers[i]->GetXboxPad();
|
int iPad = localplayers[i]->GetXboxPad();
|
||||||
if (iPad != 0) continue; // Mouse only applies to pad 0
|
if (iPad != 0) continue; // Mouse only applies to pad 0
|
||||||
|
|
||||||
if (!KMInput.IsCaptured()) continue;
|
if (!g_KBMInput.IsMouseGrabbed()) continue;
|
||||||
if (localgameModes[iPad] == NULL) continue;
|
if (localgameModes[iPad] == NULL) continue;
|
||||||
|
|
||||||
float rawDx, rawDy;
|
float rawDx, rawDy;
|
||||||
KMInput.ConsumeMouseDelta(rawDx, rawDy);
|
g_KBMInput.ConsumeMouseDelta(rawDx, rawDy);
|
||||||
if (rawDx == 0.0f && rawDy == 0.0f) continue;
|
if (rawDx == 0.0f && rawDy == 0.0f) continue;
|
||||||
|
|
||||||
float mouseSensitivity = ((float)app.GetGameSettings(iPad, eGameSetting_Sensitivity_InGame)) / 100.0f;
|
float mouseSensitivity = ((float)app.GetGameSettings(iPad, eGameSetting_Sensitivity_InGame)) / 100.0f;
|
||||||
|
|
@ -1450,14 +1457,54 @@ void Minecraft::run_middle()
|
||||||
// Keyboard/mouse button presses for player 0
|
// Keyboard/mouse button presses for player 0
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
if (KMInput.ConsumeKeyPress(VK_ESCAPE)) localplayers[i]->ullButtonsPressed |= 1LL<<MINECRAFT_ACTION_PAUSEMENU;
|
if (g_KBMInput.IsKBMActive())
|
||||||
if (KMInput.ConsumeKeyPress('E')) localplayers[i]->ullButtonsPressed |= 1LL<<MINECRAFT_ACTION_INVENTORY;
|
{
|
||||||
if (KMInput.ConsumeKeyPress('Q')) localplayers[i]->ullButtonsPressed |= 1LL<<MINECRAFT_ACTION_DROP;
|
if(g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_LEFT))
|
||||||
if (KMInput.ConsumeKeyPress('C')) localplayers[i]->ullButtonsPressed |= 1LL<<MINECRAFT_ACTION_CRAFTING;
|
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_ACTION;
|
||||||
if (KMInput.ConsumeKeyPress(VK_F5)) localplayers[i]->ullButtonsPressed |= 1LL<<MINECRAFT_ACTION_RENDER_THIRD_PERSON;
|
|
||||||
|
if(g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_RIGHT))
|
||||||
|
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_USE;
|
||||||
|
|
||||||
|
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_INVENTORY))
|
||||||
|
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_INVENTORY;
|
||||||
|
|
||||||
|
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_DROP))
|
||||||
|
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_DROP;
|
||||||
|
|
||||||
|
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_CRAFTING) || g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_CRAFTING_ALT))
|
||||||
|
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_CRAFTING;
|
||||||
|
|
||||||
|
for (int slot = 0; slot < 9; slot++)
|
||||||
|
{
|
||||||
|
if (g_KBMInput.IsKeyPressed('1' + slot))
|
||||||
|
{
|
||||||
|
if (localplayers[i]->inventory)
|
||||||
|
localplayers[i]->inventory->selected = slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility keys always work regardless of KBM active state
|
||||||
|
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_PAUSE) && !ui.IsTutorialVisible(i) && !ui.GetMenuDisplayed(i))
|
||||||
|
{
|
||||||
|
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_PAUSEMENU;
|
||||||
|
app.DebugPrintf("PAUSE PRESSED (keyboard) - ipad = %d\n",i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_THIRD_PERSON))
|
||||||
|
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_RENDER_THIRD_PERSON;
|
||||||
|
|
||||||
|
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_DEBUG_MENU))
|
||||||
|
{
|
||||||
|
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_RENDER_DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
// In flying mode, Shift held = sneak/descend
|
// In flying mode, Shift held = sneak/descend
|
||||||
if (localplayers[i]->abilities.flying && KMInput.IsKeyDown(VK_SHIFT) && !ui.GetMenuDisplayed(i))
|
if(g_KBMInput.IsKBMActive() && g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_SNEAK))
|
||||||
localplayers[i]->ullButtonsPressed |= 1LL<<MINECRAFT_ACTION_SNEAK_TOGGLE;
|
{
|
||||||
|
if (localplayers[i]->abilities.flying && !ui.GetMenuDisplayed(i))
|
||||||
|
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_SNEAK_TOGGLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -2277,8 +2324,21 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if ((screen != NULL || ui.GetMenuDisplayed(iPad)) && g_KBMInput.IsMouseGrabbed())
|
||||||
|
{
|
||||||
|
g_KBMInput.SetMouseGrabbed(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (screen == NULL && !ui.GetMenuDisplayed(iPad) )
|
if (screen == NULL && !ui.GetMenuDisplayed(iPad) )
|
||||||
{
|
{
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (!g_KBMInput.IsMouseGrabbed() && g_KBMInput.IsWindowFocused())
|
||||||
|
{
|
||||||
|
g_KBMInput.SetMouseGrabbed(true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// 4J-PB - add some tooltips if required
|
// 4J-PB - add some tooltips if required
|
||||||
int iA=-1, iB=-1, iX, iY=IDS_CONTROLS_INVENTORY, iLT=-1, iRT=-1, iLB=-1, iRB=-1, iLS=-1, iRS=-1;
|
int iA=-1, iB=-1, iX, iY=IDS_CONTROLS_INVENTORY, iLT=-1, iRT=-1, iLB=-1, iRB=-1, iLS=-1, iRS=-1;
|
||||||
|
|
||||||
|
|
@ -3432,26 +3492,9 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
// Mouse scroll wheel for hotbar
|
if (iPad == 0 && wheel == 0 && g_KBMInput.IsKBMActive())
|
||||||
if (iPad == 0)
|
|
||||||
{
|
{
|
||||||
int kbWheel = KMInput.ConsumeScrollDelta();
|
wheel = g_KBMInput.GetMouseWheel();
|
||||||
if (kbWheel > 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_LEFT_SCROLL)) wheel += 1;
|
|
||||||
else if (kbWheel < 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_RIGHT_SCROLL)) wheel -= 1;
|
|
||||||
|
|
||||||
// 1-9 keys for direct hotbar selection
|
|
||||||
if (gameMode->isInputAllowed(MINECRAFT_ACTION_LEFT_SCROLL))
|
|
||||||
{
|
|
||||||
for (int k = '1'; k <= '9'; k++)
|
|
||||||
{
|
|
||||||
if (KMInput.ConsumeKeyPress(k))
|
|
||||||
{
|
|
||||||
player->inventory->selected = k - '1';
|
|
||||||
app.SetOpacityTimer(iPad);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (wheel != 0)
|
if (wheel != 0)
|
||||||
|
|
@ -3485,33 +3528,20 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||||
player->handleMouseClick(0);
|
player->handleMouseClick(0);
|
||||||
player->lastClickTick[0] = ticks;
|
player->lastClickTick[0] = ticks;
|
||||||
}
|
}
|
||||||
#ifdef _WINDOWS64
|
|
||||||
else if (iPad == 0 && KMInput.IsCaptured() && KMInput.ConsumeMousePress(0))
|
|
||||||
{
|
|
||||||
player->handleMouseClick(0);
|
|
||||||
player->lastClickTick[0] = ticks;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (InputManager.ButtonDown(iPad, MINECRAFT_ACTION_ACTION) && ticks - player->lastClickTick[0] >= timer->ticksPerSecond / 4)
|
#ifdef _WINDOWS64
|
||||||
|
bool actionHeld = InputManager.ButtonDown(iPad, MINECRAFT_ACTION_ACTION) || (iPad == 0 && g_KBMInput.IsKBMActive() && g_KBMInput.IsMouseButtonDown(KeyboardMouseInput::MOUSE_LEFT));
|
||||||
|
#else
|
||||||
|
bool actionHeld = InputManager.ButtonDown(iPad, MINECRAFT_ACTION_ACTION);
|
||||||
|
#endif
|
||||||
|
if (actionHeld && ticks - player->lastClickTick[0] >= timer->ticksPerSecond / 4)
|
||||||
{
|
{
|
||||||
//printf("MINECRAFT_ACTION_ACTION ButtonDown");
|
//printf("MINECRAFT_ACTION_ACTION ButtonDown");
|
||||||
player->handleMouseClick(0);
|
player->handleMouseClick(0);
|
||||||
player->lastClickTick[0] = ticks;
|
player->lastClickTick[0] = ticks;
|
||||||
}
|
}
|
||||||
#ifdef _WINDOWS64
|
|
||||||
else if (iPad == 0 && KMInput.IsCaptured() && KMInput.IsMouseDown(0) && ticks - player->lastClickTick[0] >= timer->ticksPerSecond / 4)
|
|
||||||
{
|
|
||||||
player->handleMouseClick(0);
|
|
||||||
player->lastClickTick[0] = ticks;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(InputManager.ButtonDown(iPad, MINECRAFT_ACTION_ACTION)
|
if(actionHeld)
|
||||||
#ifdef _WINDOWS64
|
|
||||||
|| (iPad == 0 && KMInput.IsCaptured() && KMInput.IsMouseDown(0))
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
player->handleMouseDown(0, true );
|
player->handleMouseDown(0, true );
|
||||||
}
|
}
|
||||||
|
|
@ -3530,25 +3560,21 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||||
lastClickTick = ticks;
|
lastClickTick = ticks;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
bool useHeld = InputManager.ButtonDown(iPad, MINECRAFT_ACTION_USE) || (iPad == 0 && g_KBMInput.IsKBMActive() && g_KBMInput.IsMouseButtonDown(KeyboardMouseInput::MOUSE_RIGHT));
|
||||||
|
#else
|
||||||
|
bool useHeld = InputManager.ButtonDown(iPad, MINECRAFT_ACTION_USE);
|
||||||
|
#endif
|
||||||
if( player->isUsingItem() )
|
if( player->isUsingItem() )
|
||||||
{
|
{
|
||||||
if(!InputManager.ButtonDown(iPad, MINECRAFT_ACTION_USE)
|
if(!useHeld) gameMode->releaseUsingItem(player);
|
||||||
#ifdef _WINDOWS64
|
|
||||||
&& !(iPad == 0 && KMInput.IsCaptured() && KMInput.IsMouseDown(1))
|
|
||||||
#endif
|
|
||||||
) gameMode->releaseUsingItem(player);
|
|
||||||
}
|
}
|
||||||
else if( gameMode->isInputAllowed(MINECRAFT_ACTION_USE) )
|
else if( gameMode->isInputAllowed(MINECRAFT_ACTION_USE) )
|
||||||
{
|
{
|
||||||
#ifdef _WINDOWS64
|
|
||||||
bool useButtonDown = InputManager.ButtonDown(iPad, MINECRAFT_ACTION_USE) || (iPad == 0 && KMInput.IsCaptured() && KMInput.IsMouseDown(1));
|
|
||||||
#else
|
|
||||||
bool useButtonDown = InputManager.ButtonDown(iPad, MINECRAFT_ACTION_USE);
|
|
||||||
#endif
|
|
||||||
if( player->abilities.instabuild )
|
if( player->abilities.instabuild )
|
||||||
{
|
{
|
||||||
// 4J - attempt to handle click in special creative mode fashion if possible (used for placing blocks at regular intervals)
|
// 4J - attempt to handle click in special creative mode fashion if possible (used for placing blocks at regular intervals)
|
||||||
bool didClick = player->creativeModeHandleMouseClick(1, useButtonDown );
|
bool didClick = player->creativeModeHandleMouseClick(1, useHeld );
|
||||||
// If this handler has put us in lastClick_oldRepeat mode then it is because we aren't placing blocks - behave largely as the code used to
|
// If this handler has put us in lastClick_oldRepeat mode then it is because we aren't placing blocks - behave largely as the code used to
|
||||||
if( player->lastClickState == LocalPlayer::lastClick_oldRepeat )
|
if( player->lastClickState == LocalPlayer::lastClick_oldRepeat )
|
||||||
{
|
{
|
||||||
|
|
@ -3560,7 +3586,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise just the original game code for handling autorepeat
|
// Otherwise just the original game code for handling autorepeat
|
||||||
if (useButtonDown && ticks - player->lastClickTick[1] >= timer->ticksPerSecond / 4)
|
if (useHeld && ticks - player->lastClickTick[1] >= timer->ticksPerSecond / 4)
|
||||||
{
|
{
|
||||||
player->handleMouseClick(1);
|
player->handleMouseClick(1);
|
||||||
player->lastClickTick[1] = ticks;
|
player->lastClickTick[1] = ticks;
|
||||||
|
|
@ -3576,7 +3602,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||||
bool firstClick = ( player->lastClickTick[1] == 0 );
|
bool firstClick = ( player->lastClickTick[1] == 0 );
|
||||||
bool autoRepeat = ticks - player->lastClickTick[1] >= timer->ticksPerSecond / 4;
|
bool autoRepeat = ticks - player->lastClickTick[1] >= timer->ticksPerSecond / 4;
|
||||||
if ( player->isRiding() || player->isSprinting() || player->isSleeping() ) autoRepeat = false;
|
if ( player->isRiding() || player->isSprinting() || player->isSleeping() ) autoRepeat = false;
|
||||||
if (useButtonDown )
|
if (useHeld )
|
||||||
{
|
{
|
||||||
// If the player has just exited a bed, then delay the time before a repeat key is allowed without releasing
|
// If the player has just exited a bed, then delay the time before a repeat key is allowed without releasing
|
||||||
if(player->isSleeping() ) player->lastClickTick[1] = ticks + (timer->ticksPerSecond * 2);
|
if(player->isSleeping() ) player->lastClickTick[1] = ticks + (timer->ticksPerSecond * 2);
|
||||||
|
|
@ -3618,8 +3644,6 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||||
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_RENDER_DEBUG)) )
|
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_RENDER_DEBUG)) )
|
||||||
{
|
{
|
||||||
#ifndef _CONTENT_PACKAGE
|
#ifndef _CONTENT_PACKAGE
|
||||||
|
|
||||||
options->renderDebug = !options->renderDebug;
|
|
||||||
#ifdef _XBOX
|
#ifdef _XBOX
|
||||||
app.EnableDebugOverlay(options->renderDebug,iPad);
|
app.EnableDebugOverlay(options->renderDebug,iPad);
|
||||||
#else
|
#else
|
||||||
|
|
@ -3629,13 +3653,11 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_SPAWN_CREEPER)) && app.GetMobsDontAttackEnabled())
|
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_SPAWN_CREEPER)))
|
||||||
{
|
{
|
||||||
//shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(Creeper::_class->newInstance( level ));
|
#ifndef _CONTENT_PACKAGE
|
||||||
//shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(Wolf::_class->newInstance( level ));
|
options->renderDebug = !options->renderDebug;
|
||||||
shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(shared_ptr<Spider>(new Spider( level )));
|
#endif
|
||||||
mob->moveTo(player->x+1, player->y, player->z+1, level->random->nextFloat() * 360, 0);
|
|
||||||
level->addEntity(mob);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,14 @@
|
||||||
#include "..\Minecraft.World\Pos.h"
|
#include "..\Minecraft.World\Pos.h"
|
||||||
#include "..\Minecraft.World\System.h"
|
#include "..\Minecraft.World\System.h"
|
||||||
#include "..\Minecraft.World\StringHelpers.h"
|
#include "..\Minecraft.World\StringHelpers.h"
|
||||||
|
#include "..\Minecraft.World\net.minecraft.world.entity.item.h"
|
||||||
|
#include "..\Minecraft.World\net.minecraft.world.item.h"
|
||||||
|
#include "..\Minecraft.World\net.minecraft.world.item.enchantment.h"
|
||||||
|
#include "..\Minecraft.World\net.minecraft.world.damagesource.h"
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
#include "Windows64\Network\WinsockNetLayer.h"
|
||||||
|
#endif
|
||||||
|
#include <sstream>
|
||||||
#ifdef SPLIT_SAVES
|
#ifdef SPLIT_SAVES
|
||||||
#include "..\Minecraft.World\ConsoleSaveFileSplit.h"
|
#include "..\Minecraft.World\ConsoleSaveFileSplit.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -78,6 +86,462 @@ bool MinecraftServer::s_slowQueuePacketSent = false;
|
||||||
|
|
||||||
unordered_map<wstring, int> MinecraftServer::ironTimers;
|
unordered_map<wstring, int> MinecraftServer::ironTimers;
|
||||||
|
|
||||||
|
static bool ShouldUseDedicatedServerProperties()
|
||||||
|
{
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
return g_Win64DedicatedServer;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetDedicatedServerInt(Settings *settings, const wchar_t *key, int defaultValue)
|
||||||
|
{
|
||||||
|
return (ShouldUseDedicatedServerProperties() && settings != NULL) ? settings->getInt(key, defaultValue) : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool GetDedicatedServerBool(Settings *settings, const wchar_t *key, bool defaultValue)
|
||||||
|
{
|
||||||
|
return (ShouldUseDedicatedServerProperties() && settings != NULL) ? settings->getBoolean(key, defaultValue) : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static wstring GetDedicatedServerString(Settings *settings, const wchar_t *key, const wstring &defaultValue)
|
||||||
|
{
|
||||||
|
return (ShouldUseDedicatedServerProperties() && settings != NULL) ? settings->getString(key, defaultValue) : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintConsoleLine(const wchar_t *prefix, const wstring &message)
|
||||||
|
{
|
||||||
|
wprintf(L"%ls%ls\n", prefix, message.c_str());
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool TryParseIntValue(const wstring &text, int &value)
|
||||||
|
{
|
||||||
|
std::wistringstream stream(text);
|
||||||
|
stream >> value;
|
||||||
|
return !stream.fail() && stream.eof();
|
||||||
|
}
|
||||||
|
|
||||||
|
static vector<wstring> SplitConsoleCommand(const wstring &command)
|
||||||
|
{
|
||||||
|
vector<wstring> tokens;
|
||||||
|
std::wistringstream stream(command);
|
||||||
|
wstring token;
|
||||||
|
while (stream >> token)
|
||||||
|
{
|
||||||
|
tokens.push_back(token);
|
||||||
|
}
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
static wstring JoinConsoleCommandTokens(const vector<wstring> &tokens, size_t startIndex)
|
||||||
|
{
|
||||||
|
wstring joined;
|
||||||
|
for (size_t i = startIndex; i < tokens.size(); ++i)
|
||||||
|
{
|
||||||
|
if (!joined.empty()) joined += L" ";
|
||||||
|
joined += tokens[i];
|
||||||
|
}
|
||||||
|
return joined;
|
||||||
|
}
|
||||||
|
|
||||||
|
static shared_ptr<ServerPlayer> FindPlayerByName(PlayerList *playerList, const wstring &name)
|
||||||
|
{
|
||||||
|
if (playerList == NULL) return nullptr;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < playerList->players.size(); ++i)
|
||||||
|
{
|
||||||
|
shared_ptr<ServerPlayer> player = playerList->players[i];
|
||||||
|
if (player != NULL && equalsIgnoreCase(player->getName(), name))
|
||||||
|
{
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetAllLevelTimes(MinecraftServer *server, int value)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < server->levels.length; ++i)
|
||||||
|
{
|
||||||
|
if (server->levels[i] != NULL)
|
||||||
|
{
|
||||||
|
server->levels[i]->setDayTime(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ExecuteConsoleCommand(MinecraftServer *server, const wstring &rawCommand)
|
||||||
|
{
|
||||||
|
if (server == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wstring command = trimString(rawCommand);
|
||||||
|
if (command.empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (command[0] == L'/')
|
||||||
|
{
|
||||||
|
command = trimString(command.substr(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<wstring> tokens = SplitConsoleCommand(command);
|
||||||
|
if (tokens.empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const wstring action = toLower(tokens[0]);
|
||||||
|
PlayerList *playerList = server->getPlayers();
|
||||||
|
|
||||||
|
if (action == L"help" || action == L"?")
|
||||||
|
{
|
||||||
|
server->info(L"Commands: help, stop, list, say <message>, save-all, time <set day|night|ticks|add ticks>, weather <clear|rain|thunder> [seconds], tp <player> <target>, give <player> <itemId> [amount] [aux], enchant <player> <enchantId> [level], kill <player>");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == L"stop")
|
||||||
|
{
|
||||||
|
server->info(L"Stopping server...");
|
||||||
|
MinecraftServer::HaltServer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == L"list")
|
||||||
|
{
|
||||||
|
wstring playerNames = (playerList != NULL) ? playerList->getPlayerNames() : L"";
|
||||||
|
if (playerNames.empty()) playerNames = L"(none)";
|
||||||
|
server->info(L"Players (" + _toString((playerList != NULL) ? playerList->getPlayerCount() : 0) + L"): " + playerNames);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == L"say")
|
||||||
|
{
|
||||||
|
if (tokens.size() < 2)
|
||||||
|
{
|
||||||
|
server->warn(L"Usage: say <message>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wstring message = L"[Server] " + JoinConsoleCommandTokens(tokens, 1);
|
||||||
|
if (playerList != NULL)
|
||||||
|
{
|
||||||
|
playerList->broadcastAll(shared_ptr<ChatPacket>(new ChatPacket(message)));
|
||||||
|
}
|
||||||
|
server->info(message);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == L"save-all")
|
||||||
|
{
|
||||||
|
if (playerList != NULL)
|
||||||
|
{
|
||||||
|
playerList->saveAll(NULL, false);
|
||||||
|
}
|
||||||
|
server->info(L"World saved.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == L"time")
|
||||||
|
{
|
||||||
|
if (tokens.size() < 2)
|
||||||
|
{
|
||||||
|
server->warn(L"Usage: time set <day|night|ticks> | time add <ticks>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toLower(tokens[1]) == L"add")
|
||||||
|
{
|
||||||
|
if (tokens.size() < 3)
|
||||||
|
{
|
||||||
|
server->warn(L"Usage: time add <ticks>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int delta = 0;
|
||||||
|
if (!TryParseIntValue(tokens[2], delta))
|
||||||
|
{
|
||||||
|
server->warn(L"Invalid tick value: " + tokens[2]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < server->levels.length; ++i)
|
||||||
|
{
|
||||||
|
if (server->levels[i] != NULL)
|
||||||
|
{
|
||||||
|
server->levels[i]->setDayTime(server->levels[i]->getDayTime() + delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server->info(L"Added " + _toString(delta) + L" ticks.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
wstring timeValue = toLower(tokens[1]);
|
||||||
|
if (timeValue == L"set")
|
||||||
|
{
|
||||||
|
if (tokens.size() < 3)
|
||||||
|
{
|
||||||
|
server->warn(L"Usage: time set <day|night|ticks>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
timeValue = toLower(tokens[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int targetTime = 0;
|
||||||
|
if (timeValue == L"day")
|
||||||
|
{
|
||||||
|
targetTime = 0;
|
||||||
|
}
|
||||||
|
else if (timeValue == L"night")
|
||||||
|
{
|
||||||
|
targetTime = 12500;
|
||||||
|
}
|
||||||
|
else if (!TryParseIntValue(timeValue, targetTime))
|
||||||
|
{
|
||||||
|
server->warn(L"Invalid time value: " + timeValue);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetAllLevelTimes(server, targetTime);
|
||||||
|
server->info(L"Time set to " + _toString(targetTime) + L".");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == L"weather")
|
||||||
|
{
|
||||||
|
if (tokens.size() < 2)
|
||||||
|
{
|
||||||
|
server->warn(L"Usage: weather <clear|rain|thunder> [seconds]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int durationSeconds = 600;
|
||||||
|
if (tokens.size() >= 3 && !TryParseIntValue(tokens[2], durationSeconds))
|
||||||
|
{
|
||||||
|
server->warn(L"Invalid duration: " + tokens[2]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server->levels[0] == NULL)
|
||||||
|
{
|
||||||
|
server->warn(L"The overworld is not loaded.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LevelData *levelData = server->levels[0]->getLevelData();
|
||||||
|
int duration = durationSeconds * SharedConstants::TICKS_PER_SECOND;
|
||||||
|
levelData->setRainTime(duration);
|
||||||
|
levelData->setThunderTime(duration);
|
||||||
|
|
||||||
|
wstring weather = toLower(tokens[1]);
|
||||||
|
if (weather == L"clear")
|
||||||
|
{
|
||||||
|
levelData->setRaining(false);
|
||||||
|
levelData->setThundering(false);
|
||||||
|
}
|
||||||
|
else if (weather == L"rain")
|
||||||
|
{
|
||||||
|
levelData->setRaining(true);
|
||||||
|
levelData->setThundering(false);
|
||||||
|
}
|
||||||
|
else if (weather == L"thunder")
|
||||||
|
{
|
||||||
|
levelData->setRaining(true);
|
||||||
|
levelData->setThundering(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
server->warn(L"Usage: weather <clear|rain|thunder> [seconds]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
server->info(L"Weather set to " + weather + L".");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == L"tp" || action == L"teleport")
|
||||||
|
{
|
||||||
|
if (tokens.size() < 3)
|
||||||
|
{
|
||||||
|
server->warn(L"Usage: tp <player> <target>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ServerPlayer> subject = FindPlayerByName(playerList, tokens[1]);
|
||||||
|
shared_ptr<ServerPlayer> destination = FindPlayerByName(playerList, tokens[2]);
|
||||||
|
if (subject == NULL)
|
||||||
|
{
|
||||||
|
server->warn(L"Unknown player: " + tokens[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (destination == NULL)
|
||||||
|
{
|
||||||
|
server->warn(L"Unknown player: " + tokens[2]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (subject->level->dimension->id != destination->level->dimension->id || !subject->isAlive())
|
||||||
|
{
|
||||||
|
server->warn(L"Teleport failed because the players are not in the same dimension or the source player is dead.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
subject->ride(nullptr);
|
||||||
|
subject->connection->teleport(destination->x, destination->y, destination->z, destination->yRot, destination->xRot);
|
||||||
|
server->info(L"Teleported " + subject->getName() + L" to " + destination->getName() + L".");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == L"give")
|
||||||
|
{
|
||||||
|
if (tokens.size() < 3)
|
||||||
|
{
|
||||||
|
server->warn(L"Usage: give <player> <itemId> [amount] [aux]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ServerPlayer> player = FindPlayerByName(playerList, tokens[1]);
|
||||||
|
if (player == NULL)
|
||||||
|
{
|
||||||
|
server->warn(L"Unknown player: " + tokens[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int itemId = 0;
|
||||||
|
int amount = 1;
|
||||||
|
int aux = 0;
|
||||||
|
if (!TryParseIntValue(tokens[2], itemId))
|
||||||
|
{
|
||||||
|
server->warn(L"Invalid item id: " + tokens[2]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (tokens.size() >= 4 && !TryParseIntValue(tokens[3], amount))
|
||||||
|
{
|
||||||
|
server->warn(L"Invalid amount: " + tokens[3]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (tokens.size() >= 5 && !TryParseIntValue(tokens[4], aux))
|
||||||
|
{
|
||||||
|
server->warn(L"Invalid aux value: " + tokens[4]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (itemId <= 0 || Item::items[itemId] == NULL)
|
||||||
|
{
|
||||||
|
server->warn(L"Unknown item id: " + _toString(itemId));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (amount <= 0)
|
||||||
|
{
|
||||||
|
server->warn(L"Amount must be positive.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ItemInstance> itemInstance(new ItemInstance(itemId, amount, aux));
|
||||||
|
shared_ptr<ItemEntity> drop = player->drop(itemInstance);
|
||||||
|
if (drop != NULL)
|
||||||
|
{
|
||||||
|
drop->throwTime = 0;
|
||||||
|
}
|
||||||
|
server->info(L"Gave item " + _toString(itemId) + L" x" + _toString(amount) + L" to " + player->getName() + L".");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == L"enchant")
|
||||||
|
{
|
||||||
|
if (tokens.size() < 3)
|
||||||
|
{
|
||||||
|
server->warn(L"Usage: enchant <player> <enchantId> [level]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ServerPlayer> player = FindPlayerByName(playerList, tokens[1]);
|
||||||
|
if (player == NULL)
|
||||||
|
{
|
||||||
|
server->warn(L"Unknown player: " + tokens[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int enchantmentId = 0;
|
||||||
|
int enchantmentLevel = 1;
|
||||||
|
if (!TryParseIntValue(tokens[2], enchantmentId))
|
||||||
|
{
|
||||||
|
server->warn(L"Invalid enchantment id: " + tokens[2]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (tokens.size() >= 4 && !TryParseIntValue(tokens[3], enchantmentLevel))
|
||||||
|
{
|
||||||
|
server->warn(L"Invalid enchantment level: " + tokens[3]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ItemInstance> selectedItem = player->getSelectedItem();
|
||||||
|
if (selectedItem == NULL)
|
||||||
|
{
|
||||||
|
server->warn(L"The player is not holding an item.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Enchantment *enchantment = Enchantment::enchantments[enchantmentId];
|
||||||
|
if (enchantment == NULL)
|
||||||
|
{
|
||||||
|
server->warn(L"Unknown enchantment id: " + _toString(enchantmentId));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!enchantment->canEnchant(selectedItem))
|
||||||
|
{
|
||||||
|
server->warn(L"That enchantment cannot be applied to the selected item.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enchantmentLevel < enchantment->getMinLevel()) enchantmentLevel = enchantment->getMinLevel();
|
||||||
|
if (enchantmentLevel > enchantment->getMaxLevel()) enchantmentLevel = enchantment->getMaxLevel();
|
||||||
|
|
||||||
|
if (selectedItem->hasTag())
|
||||||
|
{
|
||||||
|
ListTag<CompoundTag> *enchantmentTags = selectedItem->getEnchantmentTags();
|
||||||
|
if (enchantmentTags != NULL)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < enchantmentTags->size(); i++)
|
||||||
|
{
|
||||||
|
int type = enchantmentTags->get(i)->getShort((wchar_t *)ItemInstance::TAG_ENCH_ID);
|
||||||
|
if (Enchantment::enchantments[type] != NULL && !Enchantment::enchantments[type]->isCompatibleWith(enchantment))
|
||||||
|
{
|
||||||
|
server->warn(L"That enchantment conflicts with an existing enchantment on the selected item.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedItem->enchant(enchantment, enchantmentLevel);
|
||||||
|
server->info(L"Enchanted " + player->getName() + L"'s held item with " + _toString(enchantmentId) + L" " + _toString(enchantmentLevel) + L".");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == L"kill")
|
||||||
|
{
|
||||||
|
if (tokens.size() < 2)
|
||||||
|
{
|
||||||
|
server->warn(L"Usage: kill <player>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ServerPlayer> player = FindPlayerByName(playerList, tokens[1]);
|
||||||
|
if (player == NULL)
|
||||||
|
{
|
||||||
|
server->warn(L"Unknown player: " + tokens[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
player->hurt(DamageSource::outOfWorld, 3.4e38f);
|
||||||
|
server->info(L"Killed " + player->getName() + L".");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
server->warn(L"Unknown command: " + command);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MinecraftServer::MinecraftServer()
|
MinecraftServer::MinecraftServer()
|
||||||
{
|
{
|
||||||
// 4J - added initialisers
|
// 4J - added initialisers
|
||||||
|
|
@ -107,12 +571,14 @@ MinecraftServer::MinecraftServer()
|
||||||
forceGameType = false;
|
forceGameType = false;
|
||||||
|
|
||||||
commandDispatcher = new ServerCommandDispatcher();
|
commandDispatcher = new ServerCommandDispatcher();
|
||||||
|
InitializeCriticalSection(&m_consoleInputCS);
|
||||||
|
|
||||||
DispenserBootstrap::bootStrap();
|
DispenserBootstrap::bootStrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
MinecraftServer::~MinecraftServer()
|
MinecraftServer::~MinecraftServer()
|
||||||
{
|
{
|
||||||
|
DeleteCriticalSection(&m_consoleInputCS);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DWORD initSettings, bool findSeed)
|
bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DWORD initSettings, bool findSeed)
|
||||||
|
|
@ -150,6 +616,15 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW
|
||||||
#endif
|
#endif
|
||||||
settings = new Settings(new File(L"server.properties"));
|
settings = new Settings(new File(L"server.properties"));
|
||||||
|
|
||||||
|
app.SetGameHostOption(eGameHostOption_Difficulty, GetDedicatedServerInt(settings, L"difficulty", app.GetGameHostOption(eGameHostOption_Difficulty)));
|
||||||
|
app.SetGameHostOption(eGameHostOption_GameType, GetDedicatedServerInt(settings, L"gamemode", app.GetGameHostOption(eGameHostOption_GameType)));
|
||||||
|
app.SetGameHostOption(eGameHostOption_Structures, GetDedicatedServerBool(settings, L"generate-structures", app.GetGameHostOption(eGameHostOption_Structures) > 0) ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_BonusChest, GetDedicatedServerBool(settings, L"bonus-chest", app.GetGameHostOption(eGameHostOption_BonusChest) > 0) ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_PvP, GetDedicatedServerBool(settings, L"pvp", app.GetGameHostOption(eGameHostOption_PvP) > 0) ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_TrustPlayers, GetDedicatedServerBool(settings, L"trust-players", app.GetGameHostOption(eGameHostOption_TrustPlayers) > 0) ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_FireSpreads, GetDedicatedServerBool(settings, L"fire-spreads", app.GetGameHostOption(eGameHostOption_FireSpreads) > 0) ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_TNT, GetDedicatedServerBool(settings, L"tnt", app.GetGameHostOption(eGameHostOption_TNT) > 0) ? 1 : 0);
|
||||||
|
|
||||||
app.DebugPrintf("\n*** SERVER SETTINGS ***\n");
|
app.DebugPrintf("\n*** SERVER SETTINGS ***\n");
|
||||||
app.DebugPrintf("ServerSettings: host-friends-only is %s\n",(app.GetGameHostOption(eGameHostOption_FriendsOfFriends)>0)?"on":"off");
|
app.DebugPrintf("ServerSettings: host-friends-only is %s\n",(app.GetGameHostOption(eGameHostOption_FriendsOfFriends)>0)?"on":"off");
|
||||||
app.DebugPrintf("ServerSettings: game-type is %s\n",(app.GetGameHostOption(eGameHostOption_GameType)==0)?"Survival Mode":"Creative Mode");
|
app.DebugPrintf("ServerSettings: game-type is %s\n",(app.GetGameHostOption(eGameHostOption_GameType)==0)?"Survival Mode":"Creative Mode");
|
||||||
|
|
@ -165,15 +640,15 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW
|
||||||
//localIp = settings->getString(L"server-ip", L"");
|
//localIp = settings->getString(L"server-ip", L"");
|
||||||
//onlineMode = settings->getBoolean(L"online-mode", true);
|
//onlineMode = settings->getBoolean(L"online-mode", true);
|
||||||
//motd = settings->getString(L"motd", L"A Minecraft Server");
|
//motd = settings->getString(L"motd", L"A Minecraft Server");
|
||||||
//motd.replace('§', '$');
|
//motd.replace('<EFBFBD>', '$');
|
||||||
|
|
||||||
setAnimals(settings->getBoolean(L"spawn-animals", true));
|
setAnimals(GetDedicatedServerBool(settings, L"spawn-animals", true));
|
||||||
setNpcsEnabled(settings->getBoolean(L"spawn-npcs", true));
|
setNpcsEnabled(GetDedicatedServerBool(settings, L"spawn-npcs", true));
|
||||||
setPvpAllowed(app.GetGameHostOption( eGameHostOption_PvP )>0?true:false); // settings->getBoolean(L"pvp", true);
|
setPvpAllowed(app.GetGameHostOption( eGameHostOption_PvP )>0?true:false);
|
||||||
|
|
||||||
// 4J Stu - We should never have hacked clients flying when they shouldn't be like the PC version, so enable flying always
|
// 4J Stu - We should never have hacked clients flying when they shouldn't be like the PC version, so enable flying always
|
||||||
// Fix for #46612 - TU5: Code: Multiplayer: A client can be banned for flying when accidentaly being blown by dynamite
|
// Fix for #46612 - TU5: Code: Multiplayer: A client can be banned for flying when accidentaly being blown by dynamite
|
||||||
setFlightAllowed(true); //settings->getBoolean(L"allow-flight", false);
|
setFlightAllowed(GetDedicatedServerBool(settings, L"allow-flight", true));
|
||||||
|
|
||||||
// 4J Stu - Enabling flight to stop it kicking us when we use it
|
// 4J Stu - Enabling flight to stop it kicking us when we use it
|
||||||
#ifdef _DEBUG_MENUS_ENABLED
|
#ifdef _DEBUG_MENUS_ENABLED
|
||||||
|
|
@ -219,8 +694,8 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW
|
||||||
|
|
||||||
__int64 levelNanoTime = System::nanoTime();
|
__int64 levelNanoTime = System::nanoTime();
|
||||||
|
|
||||||
wstring levelName = settings->getString(L"level-name", L"world");
|
wstring levelName = (initData && !initData->levelName.empty()) ? initData->levelName : GetDedicatedServerString(settings, L"level-name", L"world");
|
||||||
wstring levelTypeString;
|
wstring levelTypeString;
|
||||||
|
|
||||||
bool gameRuleUseFlatWorld = false;
|
bool gameRuleUseFlatWorld = false;
|
||||||
if(app.getLevelGenerationOptions() != NULL)
|
if(app.getLevelGenerationOptions() != NULL)
|
||||||
|
|
@ -229,11 +704,11 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW
|
||||||
}
|
}
|
||||||
if(gameRuleUseFlatWorld || app.GetGameHostOption(eGameHostOption_LevelType)>0)
|
if(gameRuleUseFlatWorld || app.GetGameHostOption(eGameHostOption_LevelType)>0)
|
||||||
{
|
{
|
||||||
levelTypeString = settings->getString(L"level-type", L"flat");
|
levelTypeString = GetDedicatedServerString(settings, L"level-type", L"flat");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
levelTypeString = settings->getString(L"level-type",L"default");
|
levelTypeString = GetDedicatedServerString(settings, L"level-type",L"default");
|
||||||
}
|
}
|
||||||
|
|
||||||
LevelType *pLevelType = LevelType::getLevelType(levelTypeString);
|
LevelType *pLevelType = LevelType::getLevelType(levelTypeString);
|
||||||
|
|
@ -254,7 +729,7 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
setMaxBuildHeight(settings->getInt(L"max-build-height", Level::maxBuildHeight));
|
setMaxBuildHeight(GetDedicatedServerInt(settings, L"max-build-height", Level::maxBuildHeight));
|
||||||
setMaxBuildHeight(((getMaxBuildHeight() + 8) / 16) * 16);
|
setMaxBuildHeight(((getMaxBuildHeight() + 8) / 16) * 16);
|
||||||
setMaxBuildHeight(Mth::clamp(getMaxBuildHeight(), 64, Level::maxBuildHeight));
|
setMaxBuildHeight(Mth::clamp(getMaxBuildHeight(), 64, Level::maxBuildHeight));
|
||||||
//settings->setProperty(L"max-build-height", maxBuildHeight);
|
//settings->setProperty(L"max-build-height", maxBuildHeight);
|
||||||
|
|
@ -403,7 +878,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring
|
||||||
// 4J TODO - free levels here if there are already some?
|
// 4J TODO - free levels here if there are already some?
|
||||||
levels = ServerLevelArray(3);
|
levels = ServerLevelArray(3);
|
||||||
|
|
||||||
int gameTypeId = settings->getInt(L"gamemode", app.GetGameHostOption(eGameHostOption_GameType));//LevelSettings::GAMETYPE_SURVIVAL);
|
int gameTypeId = GetDedicatedServerInt(settings, L"gamemode", app.GetGameHostOption(eGameHostOption_GameType));//LevelSettings::GAMETYPE_SURVIVAL);
|
||||||
GameType *gameType = LevelSettings::validateGameType(gameTypeId);
|
GameType *gameType = LevelSettings::validateGameType(gameTypeId);
|
||||||
app.DebugPrintf("Default game type: %d\n" , gameTypeId);
|
app.DebugPrintf("Default game type: %d\n" , gameTypeId);
|
||||||
|
|
||||||
|
|
@ -502,7 +977,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring
|
||||||
#if DEBUG_SERVER_DONT_SPAWN_MOBS
|
#if DEBUG_SERVER_DONT_SPAWN_MOBS
|
||||||
levels[i]->setSpawnSettings(false, false);
|
levels[i]->setSpawnSettings(false, false);
|
||||||
#else
|
#else
|
||||||
levels[i]->setSpawnSettings(settings->getBoolean(L"spawn-monsters", true), animals);
|
levels[i]->setSpawnSettings(GetDedicatedServerBool(settings, L"spawn-monsters", true), animals);
|
||||||
#endif
|
#endif
|
||||||
levels[i]->getLevelData()->setGameType(gameType);
|
levels[i]->getLevelData()->setGameType(gameType);
|
||||||
|
|
||||||
|
|
@ -590,7 +1065,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring
|
||||||
for (int i = 0; i < levels.length ; i++)
|
for (int i = 0; i < levels.length ; i++)
|
||||||
{
|
{
|
||||||
// logger.info("Preparing start region for level " + i);
|
// logger.info("Preparing start region for level " + i);
|
||||||
if (i == 0 || settings->getBoolean(L"allow-nether", true))
|
if (i == 0 || GetDedicatedServerBool(settings, L"allow-nether", true))
|
||||||
{
|
{
|
||||||
ServerLevel *level = levels[i];
|
ServerLevel *level = levels[i];
|
||||||
if(levelChunksNeedConverted)
|
if(levelChunksNeedConverted)
|
||||||
|
|
@ -1332,7 +1807,7 @@ void MinecraftServer::run(__int64 seed, void *lpParameter)
|
||||||
MinecraftServer::setTimeOfDayAtEndOfTick = false;
|
MinecraftServer::setTimeOfDayAtEndOfTick = false;
|
||||||
for (unsigned int i = 0; i < levels.length; i++)
|
for (unsigned int i = 0; i < levels.length; i++)
|
||||||
{
|
{
|
||||||
if (i == 0 || settings->getBoolean(L"allow-nether", true))
|
if (i == 0 || GetDedicatedServerBool(settings, L"allow-nether", true))
|
||||||
{
|
{
|
||||||
ServerLevel *level = levels[i];
|
ServerLevel *level = levels[i];
|
||||||
level->setDayTime( MinecraftServer::setTimeOfDay );
|
level->setDayTime( MinecraftServer::setTimeOfDay );
|
||||||
|
|
@ -1707,17 +2182,23 @@ void MinecraftServer::tick()
|
||||||
|
|
||||||
void MinecraftServer::handleConsoleInput(const wstring& msg, ConsoleInputSource *source)
|
void MinecraftServer::handleConsoleInput(const wstring& msg, ConsoleInputSource *source)
|
||||||
{
|
{
|
||||||
|
EnterCriticalSection(&m_consoleInputCS);
|
||||||
consoleInput.push_back(new ConsoleInput(msg, source));
|
consoleInput.push_back(new ConsoleInput(msg, source));
|
||||||
|
LeaveCriticalSection(&m_consoleInputCS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MinecraftServer::handleConsoleInputs()
|
void MinecraftServer::handleConsoleInputs()
|
||||||
{
|
{
|
||||||
while (consoleInput.size() > 0)
|
vector<ConsoleInput *> pendingInputs;
|
||||||
|
EnterCriticalSection(&m_consoleInputCS);
|
||||||
|
pendingInputs.swap(consoleInput);
|
||||||
|
LeaveCriticalSection(&m_consoleInputCS);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < pendingInputs.size(); ++i)
|
||||||
{
|
{
|
||||||
AUTO_VAR(it, consoleInput.begin());
|
ConsoleInput *input = pendingInputs[i];
|
||||||
ConsoleInput *input = *it;
|
ExecuteConsoleCommand(this, input->msg);
|
||||||
consoleInput.erase(it);
|
delete input;
|
||||||
// commands->handleCommand(input); // 4J - removed - TODO - do we want equivalent of console commands?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1750,10 +2231,12 @@ File *MinecraftServer::getFile(const wstring& name)
|
||||||
|
|
||||||
void MinecraftServer::info(const wstring& string)
|
void MinecraftServer::info(const wstring& string)
|
||||||
{
|
{
|
||||||
|
PrintConsoleLine(L"[INFO] ", string);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MinecraftServer::warn(const wstring& string)
|
void MinecraftServer::warn(const wstring& string)
|
||||||
{
|
{
|
||||||
|
PrintConsoleLine(L"[WARN] ", string);
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring MinecraftServer::getConsoleName()
|
wstring MinecraftServer::getConsoleName()
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ typedef struct _NetworkGameInitData
|
||||||
unsigned int xzSize;
|
unsigned int xzSize;
|
||||||
unsigned char hellScale;
|
unsigned char hellScale;
|
||||||
ESavePlatform savePlatform;
|
ESavePlatform savePlatform;
|
||||||
|
wstring levelName;
|
||||||
|
|
||||||
_NetworkGameInitData()
|
_NetworkGameInitData()
|
||||||
{
|
{
|
||||||
|
|
@ -103,6 +104,7 @@ private:
|
||||||
// vector<Tickable *> tickables = new ArrayList<Tickable>(); // 4J - removed
|
// vector<Tickable *> tickables = new ArrayList<Tickable>(); // 4J - removed
|
||||||
CommandDispatcher *commandDispatcher;
|
CommandDispatcher *commandDispatcher;
|
||||||
vector<ConsoleInput *> consoleInput; // 4J - was synchronizedList - TODO - investigate
|
vector<ConsoleInput *> consoleInput; // 4J - was synchronizedList - TODO - investigate
|
||||||
|
CRITICAL_SECTION m_consoleInputCS;
|
||||||
public:
|
public:
|
||||||
bool onlineMode;
|
bool onlineMode;
|
||||||
bool animals;
|
bool animals;
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,6 @@ bool MultiPlayerGameMode::destroyBlock(int x, int y, int z, int face)
|
||||||
if (g_NetworkManager.IsHost())
|
if (g_NetworkManager.IsHost())
|
||||||
{
|
{
|
||||||
level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, x, y, z, oldTile->id + (level->getData(x, y, z) << Tile::TILE_NUM_SHIFT));
|
level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, x, y, z, oldTile->id + (level->getData(x, y, z) << Tile::TILE_NUM_SHIFT));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -370,7 +369,9 @@ bool MultiPlayerGameMode::useItemOn(shared_ptr<Player> player, Level *level, sha
|
||||||
// are meant to be directly caused by this. If we don't do this, then the sounds never happen as the tile's use method is only called on the
|
// are meant to be directly caused by this. If we don't do this, then the sounds never happen as the tile's use method is only called on the
|
||||||
// server, and that won't allow any sounds that are directly made, or broadcast back level events to us that would make the sound, since we are
|
// server, and that won't allow any sounds that are directly made, or broadcast back level events to us that would make the sound, since we are
|
||||||
// the source of the event.
|
// the source of the event.
|
||||||
if( ( t > 0 ) && ( !bTestUseOnly ) && player->isAllowedToUse(Tile::tiles[t]) )
|
// ---------------------------------------------------------------------------------
|
||||||
|
// Only call soundOnly version if we didn't already call the tile's use method above
|
||||||
|
if( !didSomething && ( t > 0 ) && ( !bTestUseOnly ) && player->isAllowedToUse(Tile::tiles[t]) )
|
||||||
{
|
{
|
||||||
Tile::tiles[t]->use(level, x, y, z, player, face, clickX, clickY, clickZ, true);
|
Tile::tiles[t]->use(level, x, y, z, player, face, clickX, clickY, clickZ, true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,14 +53,12 @@ PlayerList::PlayerList(MinecraftServer *server)
|
||||||
|
|
||||||
//int viewDistance = server->settings->getInt(L"view-distance", 10);
|
//int viewDistance = server->settings->getInt(L"view-distance", 10);
|
||||||
|
|
||||||
maxPlayers = server->settings->getInt(L"max-players", 20);
|
|
||||||
doWhiteList = false;
|
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
||||||
#else
|
#else
|
||||||
maxPlayers = server->settings->getInt(L"max-players", 20);
|
maxPlayers = server->settings->getInt(L"max-players", 20);
|
||||||
#endif
|
#endif
|
||||||
|
doWhiteList = false;
|
||||||
InitializeCriticalSection(&m_kickPlayersCS);
|
InitializeCriticalSection(&m_kickPlayersCS);
|
||||||
InitializeCriticalSection(&m_closePlayersCS);
|
InitializeCriticalSection(&m_closePlayersCS);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,13 +110,13 @@ void Screen::updateEvents()
|
||||||
// Poll mouse button state and dispatch click/release events
|
// Poll mouse button state and dispatch click/release events
|
||||||
for (int btn = 0; btn < 3; btn++)
|
for (int btn = 0; btn < 3; btn++)
|
||||||
{
|
{
|
||||||
if (KMInput.ConsumeMousePress(btn))
|
if (g_KBMInput.IsMouseButtonPressed(btn))
|
||||||
{
|
{
|
||||||
int xm = Mouse::getX() * width / minecraft->width;
|
int xm = Mouse::getX() * width / minecraft->width;
|
||||||
int ym = height - Mouse::getY() * height / minecraft->height - 1;
|
int ym = height - Mouse::getY() * height / minecraft->height - 1;
|
||||||
mouseClicked(xm, ym, btn);
|
mouseClicked(xm, ym, btn);
|
||||||
}
|
}
|
||||||
if (KMInput.ConsumeMouseRelease(btn))
|
if (g_KBMInput.IsMouseButtonReleased(btn))
|
||||||
{
|
{
|
||||||
int xm = Mouse::getX() * width / minecraft->width;
|
int xm = Mouse::getX() * width / minecraft->width;
|
||||||
int ym = height - Mouse::getY() * height / minecraft->height - 1;
|
int ym = height - Mouse::getY() * height / minecraft->height - 1;
|
||||||
|
|
@ -127,7 +127,7 @@ void Screen::updateEvents()
|
||||||
// Poll keyboard events
|
// Poll keyboard events
|
||||||
for (int vk = 0; vk < 256; vk++)
|
for (int vk = 0; vk < 256; vk++)
|
||||||
{
|
{
|
||||||
if (KMInput.ConsumeKeyPress(vk))
|
if (g_KBMInput.IsKeyPressed(vk))
|
||||||
{
|
{
|
||||||
// Map Windows virtual key to the Keyboard constants used by Screen::keyPressed
|
// Map Windows virtual key to the Keyboard constants used by Screen::keyPressed
|
||||||
int mappedKey = -1;
|
int mappedKey = -1;
|
||||||
|
|
@ -144,7 +144,7 @@ void Screen::updateEvents()
|
||||||
else if (vk >= 'A' && vk <= 'Z')
|
else if (vk >= 'A' && vk <= 'Z')
|
||||||
{
|
{
|
||||||
ch = (wchar_t)(vk - 'A' + L'a');
|
ch = (wchar_t)(vk - 'A' + L'a');
|
||||||
if (KMInput.IsKeyDown(VK_SHIFT)) ch = (wchar_t)vk;
|
if (g_KBMInput.IsKeyDown(VK_LSHIFT) || g_KBMInput.IsKeyDown(VK_RSHIFT)) ch = (wchar_t)vk;
|
||||||
}
|
}
|
||||||
else if (vk >= '0' && vk <= '9') ch = (wchar_t)vk;
|
else if (vk >= '0' && vk <= '9') ch = (wchar_t)vk;
|
||||||
else if (vk == VK_SPACE) ch = L' ';
|
else if (vk == VK_SPACE) ch = L' ';
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,90 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
#include "..\Minecraft.World\File.h"
|
||||||
#include "..\Minecraft.World\StringHelpers.h"
|
#include "..\Minecraft.World\StringHelpers.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
static wstring ParsePropertyText(const string &text)
|
||||||
|
{
|
||||||
|
return trimString(convStringToWstring(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool TryParseBoolean(const wstring &text, bool defaultValue)
|
||||||
|
{
|
||||||
|
wstring lowered = toLower(trimString(text));
|
||||||
|
if (lowered == L"true" || lowered == L"1" || lowered == L"yes" || lowered == L"on")
|
||||||
|
return true;
|
||||||
|
if (lowered == L"false" || lowered == L"0" || lowered == L"no" || lowered == L"off")
|
||||||
|
return false;
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
// 4J - TODO - serialise/deserialise from file
|
|
||||||
Settings::Settings(File *file)
|
Settings::Settings(File *file)
|
||||||
{
|
{
|
||||||
|
if (file != NULL)
|
||||||
|
{
|
||||||
|
filePath = file->getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filePath.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::ifstream stream(wstringtofilename(filePath), std::ios::in | std::ios::binary);
|
||||||
|
if (!stream.is_open())
|
||||||
|
return;
|
||||||
|
|
||||||
|
string line;
|
||||||
|
while (std::getline(stream, line))
|
||||||
|
{
|
||||||
|
if (!line.empty() && line[line.size() - 1] == '\r')
|
||||||
|
line.erase(line.size() - 1);
|
||||||
|
|
||||||
|
if (line.size() >= 3 &&
|
||||||
|
(unsigned char)line[0] == 0xEF &&
|
||||||
|
(unsigned char)line[1] == 0xBB &&
|
||||||
|
(unsigned char)line[2] == 0xBF)
|
||||||
|
{
|
||||||
|
line.erase(0, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t commentPos = line.find_first_of("#;");
|
||||||
|
if (commentPos != string::npos && line.find_first_not_of(" \t") == commentPos)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
size_t separatorPos = line.find('=');
|
||||||
|
if (separatorPos == string::npos)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wstring key = ParsePropertyText(line.substr(0, separatorPos));
|
||||||
|
if (key.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wstring value = ParsePropertyText(line.substr(separatorPos + 1));
|
||||||
|
properties[key] = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::generateNewProperties()
|
void Settings::generateNewProperties()
|
||||||
{
|
{
|
||||||
|
saveProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::saveProperties()
|
void Settings::saveProperties()
|
||||||
{
|
{
|
||||||
|
if (filePath.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::ofstream stream(wstringtofilename(filePath), std::ios::out | std::ios::binary | std::ios::trunc);
|
||||||
|
if (!stream.is_open())
|
||||||
|
return;
|
||||||
|
|
||||||
|
stream << "# MinecraftConsoles dedicated server properties\r\n";
|
||||||
|
for (unordered_map<wstring, wstring>::const_iterator it = properties.begin(); it != properties.end(); ++it)
|
||||||
|
{
|
||||||
|
string key = string(wstringtochararray(it->first));
|
||||||
|
string value = string(wstringtochararray(it->second));
|
||||||
|
stream << key << "=" << value << "\r\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring Settings::getString(const wstring& key, const wstring& defaultValue)
|
wstring Settings::getString(const wstring& key, const wstring& defaultValue)
|
||||||
|
|
@ -39,17 +111,17 @@ bool Settings::getBoolean(const wstring& key, bool defaultValue)
|
||||||
{
|
{
|
||||||
if(properties.find(key) == properties.end())
|
if(properties.find(key) == properties.end())
|
||||||
{
|
{
|
||||||
properties[key] = _toString<bool>(defaultValue);
|
properties[key] = defaultValue ? L"true" : L"false";
|
||||||
saveProperties();
|
saveProperties();
|
||||||
}
|
}
|
||||||
MemSect(35);
|
MemSect(35);
|
||||||
bool retval = _fromString<bool>(properties[key]);
|
bool retval = TryParseBoolean(properties[key], defaultValue);
|
||||||
MemSect(0);
|
MemSect(0);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::setBooleanAndSave(const wstring& key, bool value)
|
void Settings::setBooleanAndSave(const wstring& key, bool value)
|
||||||
{
|
{
|
||||||
properties[key] = _toString<bool>(value);
|
properties[key] = value ? L"true" : L"false";
|
||||||
saveProperties();
|
saveProperties();
|
||||||
}
|
}
|
||||||
|
|
@ -7,8 +7,8 @@ class Settings
|
||||||
// public static Logger logger = Logger.getLogger("Minecraft");
|
// public static Logger logger = Logger.getLogger("Minecraft");
|
||||||
// private Properties properties = new Properties();
|
// private Properties properties = new Properties();
|
||||||
private:
|
private:
|
||||||
unordered_map<wstring,wstring> properties; // 4J - TODO was Properties type, will need to implement something we can serialise/deserialise too
|
unordered_map<wstring,wstring> properties;
|
||||||
//File *file;
|
wstring filePath;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Settings(File *file);
|
Settings(File *file);
|
||||||
|
|
@ -18,4 +18,4 @@ public:
|
||||||
int getInt(const wstring& key, int defaultValue);
|
int getInt(const wstring& key, int defaultValue);
|
||||||
bool getBoolean(const wstring& key, bool defaultValue);
|
bool getBoolean(const wstring& key, bool defaultValue);
|
||||||
void setBooleanAndSave(const wstring& key, bool value);
|
void setBooleanAndSave(const wstring& key, bool value);
|
||||||
};
|
};
|
||||||
|
|
@ -424,12 +424,109 @@ void Textures::bindTextureLayers(ResourceLocation *resource)
|
||||||
{
|
{
|
||||||
assert(resource->isPreloaded());
|
assert(resource->isPreloaded());
|
||||||
|
|
||||||
|
// Hack: 4JLibs on Windows does not currently reproduce Minecraft's layered horse texture path reliably.
|
||||||
|
// Merge the layers on the CPU and bind the cached result as a normal single texture instead.
|
||||||
|
wstring cacheKey = L"%layered%";
|
||||||
int layers = resource->getTextureCount();
|
int layers = resource->getTextureCount();
|
||||||
|
|
||||||
for( int i = 0; i < layers; i++ )
|
for( int i = 0; i < layers; i++ )
|
||||||
{
|
{
|
||||||
RenderManager.TextureBind(loadTexture(resource->getTexture(i)));
|
cacheKey += std::to_wstring(resource->getTexture(i));
|
||||||
|
cacheKey += L"/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int id = -1;
|
||||||
|
bool inMap = ( idMap.find(cacheKey) != idMap.end() );
|
||||||
|
if( inMap )
|
||||||
|
{
|
||||||
|
id = idMap[cacheKey];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Cache by layer signature so the merge cost is only paid once per horse texture combination.
|
||||||
|
intArray mergedPixels;
|
||||||
|
int mergedWidth = 0;
|
||||||
|
int mergedHeight = 0;
|
||||||
|
bool hasMergedPixels = false;
|
||||||
|
|
||||||
|
for( int i = 0; i < layers; i++ )
|
||||||
|
{
|
||||||
|
TEXTURE_NAME textureName = resource->getTexture(i);
|
||||||
|
if( textureName == (_TEXTURE_NAME)-1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
wstring resourceName = wstring(preLoaded[textureName]) + L".png";
|
||||||
|
BufferedImage *image = readImage(textureName, resourceName);
|
||||||
|
if( image == NULL )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = image->getWidth();
|
||||||
|
int height = image->getHeight();
|
||||||
|
intArray layerPixels = loadTexturePixels(image);
|
||||||
|
delete image;
|
||||||
|
|
||||||
|
if( !hasMergedPixels )
|
||||||
|
{
|
||||||
|
mergedWidth = width;
|
||||||
|
mergedHeight = height;
|
||||||
|
mergedPixels = intArray(width * height);
|
||||||
|
memcpy(mergedPixels.data, layerPixels.data, width * height * sizeof(int));
|
||||||
|
hasMergedPixels = true;
|
||||||
|
}
|
||||||
|
else if( width == mergedWidth && height == mergedHeight )
|
||||||
|
{
|
||||||
|
for( int p = 0; p < width * height; p++ )
|
||||||
|
{
|
||||||
|
int dst = mergedPixels[p];
|
||||||
|
int src = layerPixels[p];
|
||||||
|
|
||||||
|
float srcAlpha = ((src >> 24) & 0xff) / 255.0f;
|
||||||
|
if( srcAlpha <= 0.0f )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dstAlpha = ((dst >> 24) & 0xff) / 255.0f;
|
||||||
|
float outAlpha = srcAlpha + dstAlpha * (1.0f - srcAlpha);
|
||||||
|
if( outAlpha <= 0.0f )
|
||||||
|
{
|
||||||
|
mergedPixels[p] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float srcFactor = srcAlpha / outAlpha;
|
||||||
|
float dstFactor = (dstAlpha * (1.0f - srcAlpha)) / outAlpha;
|
||||||
|
|
||||||
|
int outA = (int)(outAlpha * 255.0f + 0.5f);
|
||||||
|
int outR = (int)((((src >> 16) & 0xff) * srcFactor) + (((dst >> 16) & 0xff) * dstFactor) + 0.5f);
|
||||||
|
int outG = (int)((((src >> 8) & 0xff) * srcFactor) + (((dst >> 8) & 0xff) * dstFactor) + 0.5f);
|
||||||
|
int outB = (int)(((src & 0xff) * srcFactor) + ((dst & 0xff) * dstFactor) + 0.5f);
|
||||||
|
mergedPixels[p] = (outA << 24) | (outR << 16) | (outG << 8) | outB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] layerPixels.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( hasMergedPixels )
|
||||||
|
{
|
||||||
|
BufferedImage *mergedImage = new BufferedImage(mergedWidth, mergedHeight, BufferedImage::TYPE_INT_ARGB);
|
||||||
|
memcpy(mergedImage->getData(), mergedPixels.data, mergedWidth * mergedHeight * sizeof(int));
|
||||||
|
delete[] mergedPixels.data;
|
||||||
|
id = getTexture(mergedImage, C4JRender::TEXTURE_FORMAT_RxGyBzAw, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
idMap[cacheKey] = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderManager.TextureBind(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Textures::bind(int id)
|
void Textures::bind(int id)
|
||||||
|
|
|
||||||
|
|
@ -973,6 +973,9 @@ void gdraw_D3D1X_(SetRendertargetSize)(S32 w, S32 h)
|
||||||
|
|
||||||
void gdraw_D3D1X_(SetTileOrigin)(ID3D1X(RenderTargetView) *main_rt, ID3D1X(DepthStencilView) *main_ds, ID3D1X(ShaderResourceView) *non_msaa_rt, S32 x, S32 y)
|
void gdraw_D3D1X_(SetTileOrigin)(ID3D1X(RenderTargetView) *main_rt, ID3D1X(DepthStencilView) *main_ds, ID3D1X(ShaderResourceView) *non_msaa_rt, S32 x, S32 y)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (!gdraw) return; // AAR - saftey check because windows calls resize early
|
||||||
|
|
||||||
D3D1X_(RENDER_TARGET_VIEW_DESC) desc;
|
D3D1X_(RENDER_TARGET_VIEW_DESC) desc;
|
||||||
|
|
||||||
if (gdraw->frame_done) {
|
if (gdraw->frame_done) {
|
||||||
|
|
|
||||||
|
|
@ -3,117 +3,176 @@
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
|
|
||||||
#include "KeyboardMouseInput.h"
|
#include "KeyboardMouseInput.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
KeyboardMouseInput KMInput;
|
KeyboardMouseInput g_KBMInput;
|
||||||
|
|
||||||
KeyboardMouseInput::KeyboardMouseInput()
|
extern HWND g_hWnd;
|
||||||
: m_mouseDeltaXAccum(0.0f)
|
|
||||||
, m_mouseDeltaYAccum(0.0f)
|
// Forward declaration
|
||||||
, m_scrollDeltaAccum(0)
|
static void ClipCursorToWindow(HWND hWnd);
|
||||||
, m_captured(false)
|
|
||||||
, m_hWnd(NULL)
|
static bool IsModifierKeyDown(const bool* keyState, int vkCode)
|
||||||
, m_initialized(false)
|
|
||||||
, m_mouseX(0)
|
|
||||||
, m_mouseY(0)
|
|
||||||
{
|
{
|
||||||
memset(m_keyState, 0, sizeof(m_keyState));
|
switch (vkCode)
|
||||||
memset(m_keyStatePrev, 0, sizeof(m_keyStatePrev));
|
|
||||||
memset(m_mouseButtons, 0, sizeof(m_mouseButtons));
|
|
||||||
memset(m_mouseButtonsPrev, 0, sizeof(m_mouseButtonsPrev));
|
|
||||||
memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
|
|
||||||
memset(m_mousePressedAccum, 0, sizeof(m_mousePressedAccum));
|
|
||||||
memset(m_mouseReleasedAccum, 0, sizeof(m_mouseReleasedAccum));
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyboardMouseInput::~KeyboardMouseInput()
|
|
||||||
{
|
|
||||||
if (m_captured)
|
|
||||||
{
|
{
|
||||||
SetCapture(false);
|
case VK_SHIFT:
|
||||||
|
return keyState[VK_LSHIFT] || keyState[VK_RSHIFT];
|
||||||
|
case VK_CONTROL:
|
||||||
|
return keyState[VK_LCONTROL] || keyState[VK_RCONTROL];
|
||||||
|
case VK_MENU:
|
||||||
|
return keyState[VK_LMENU] || keyState[VK_RMENU];
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyboardMouseInput::Init(HWND hWnd)
|
void KeyboardMouseInput::Init()
|
||||||
{
|
{
|
||||||
m_hWnd = hWnd;
|
memset(m_keyDown, 0, sizeof(m_keyDown));
|
||||||
m_initialized = true;
|
memset(m_keyDownPrev, 0, sizeof(m_keyDownPrev));
|
||||||
|
memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
|
||||||
|
memset(m_keyReleasedAccum, 0, sizeof(m_keyReleasedAccum));
|
||||||
|
memset(m_keyPressed, 0, sizeof(m_keyPressed));
|
||||||
|
memset(m_keyReleased, 0, sizeof(m_keyReleased));
|
||||||
|
memset(m_mouseButtonDown, 0, sizeof(m_mouseButtonDown));
|
||||||
|
memset(m_mouseButtonDownPrev, 0, sizeof(m_mouseButtonDownPrev));
|
||||||
|
memset(m_mouseBtnPressedAccum, 0, sizeof(m_mouseBtnPressedAccum));
|
||||||
|
memset(m_mouseBtnReleasedAccum, 0, sizeof(m_mouseBtnReleasedAccum));
|
||||||
|
memset(m_mouseBtnPressed, 0, sizeof(m_mouseBtnPressed));
|
||||||
|
memset(m_mouseBtnReleased, 0, sizeof(m_mouseBtnReleased));
|
||||||
|
m_mouseX = 0;
|
||||||
|
m_mouseY = 0;
|
||||||
|
m_mouseDeltaX = 0;
|
||||||
|
m_mouseDeltaY = 0;
|
||||||
|
m_mouseDeltaAccumX = 0;
|
||||||
|
m_mouseDeltaAccumY = 0;
|
||||||
|
m_mouseWheelAccum = 0;
|
||||||
|
m_mouseWheelConsumed = false;
|
||||||
|
m_mouseGrabbed = false;
|
||||||
|
m_cursorHiddenForUI = false;
|
||||||
|
m_windowFocused = true;
|
||||||
|
m_hasInput = false;
|
||||||
|
m_kbmActive = true;
|
||||||
|
m_screenWantsCursorHidden = false;
|
||||||
|
|
||||||
// Register for raw mouse input
|
|
||||||
RAWINPUTDEVICE rid;
|
RAWINPUTDEVICE rid;
|
||||||
rid.usUsagePage = HID_USAGE_PAGE_GENERIC;
|
rid.usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
|
||||||
rid.usUsage = HID_USAGE_GENERIC_MOUSE;
|
rid.usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE
|
||||||
rid.dwFlags = 0;
|
rid.dwFlags = 0;
|
||||||
rid.hwndTarget = hWnd;
|
rid.hwndTarget = g_hWnd;
|
||||||
RegisterRawInputDevices(&rid, 1, sizeof(rid));
|
RegisterRawInputDevices(&rid, 1, sizeof(rid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KeyboardMouseInput::ClearAllState()
|
||||||
|
{
|
||||||
|
memset(m_keyDown, 0, sizeof(m_keyDown));
|
||||||
|
memset(m_keyDownPrev, 0, sizeof(m_keyDownPrev));
|
||||||
|
memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
|
||||||
|
memset(m_keyReleasedAccum, 0, sizeof(m_keyReleasedAccum));
|
||||||
|
memset(m_keyPressed, 0, sizeof(m_keyPressed));
|
||||||
|
memset(m_keyReleased, 0, sizeof(m_keyReleased));
|
||||||
|
memset(m_mouseButtonDown, 0, sizeof(m_mouseButtonDown));
|
||||||
|
memset(m_mouseButtonDownPrev, 0, sizeof(m_mouseButtonDownPrev));
|
||||||
|
memset(m_mouseBtnPressedAccum, 0, sizeof(m_mouseBtnPressedAccum));
|
||||||
|
memset(m_mouseBtnReleasedAccum, 0, sizeof(m_mouseBtnReleasedAccum));
|
||||||
|
memset(m_mouseBtnPressed, 0, sizeof(m_mouseBtnPressed));
|
||||||
|
memset(m_mouseBtnReleased, 0, sizeof(m_mouseBtnReleased));
|
||||||
|
m_mouseDeltaX = 0;
|
||||||
|
m_mouseDeltaY = 0;
|
||||||
|
m_mouseDeltaAccumX = 0;
|
||||||
|
m_mouseDeltaAccumY = 0;
|
||||||
|
m_mouseWheelAccum = 0;
|
||||||
|
m_mouseWheelConsumed = false;
|
||||||
|
}
|
||||||
|
|
||||||
void KeyboardMouseInput::Tick()
|
void KeyboardMouseInput::Tick()
|
||||||
{
|
{
|
||||||
// Keep cursor pinned to center while captured
|
memcpy(m_keyDownPrev, m_keyDown, sizeof(m_keyDown));
|
||||||
if (m_captured)
|
memcpy(m_mouseButtonDownPrev, m_mouseButtonDown, sizeof(m_mouseButtonDown));
|
||||||
CenterCursor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyboardMouseInput::EndFrame()
|
memcpy(m_keyPressed, m_keyPressedAccum, sizeof(m_keyPressedAccum));
|
||||||
{
|
memcpy(m_keyReleased, m_keyReleasedAccum, sizeof(m_keyReleasedAccum));
|
||||||
// Advance previous state for next frame's edge detection.
|
memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
|
||||||
// Must be called AFTER all per-frame consumers have read IsKeyPressed/Released etc.
|
memset(m_keyReleasedAccum, 0, sizeof(m_keyReleasedAccum));
|
||||||
memcpy(m_keyStatePrev, m_keyState, sizeof(m_keyState));
|
|
||||||
memcpy(m_mouseButtonsPrev, m_mouseButtons, sizeof(m_mouseButtons));
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyboardMouseInput::OnKeyDown(WPARAM vk)
|
memcpy(m_mouseBtnPressed, m_mouseBtnPressedAccum, sizeof(m_mouseBtnPressedAccum));
|
||||||
{
|
memcpy(m_mouseBtnReleased, m_mouseBtnReleasedAccum, sizeof(m_mouseBtnReleasedAccum));
|
||||||
if (vk < 256)
|
memset(m_mouseBtnPressedAccum, 0, sizeof(m_mouseBtnPressedAccum));
|
||||||
|
memset(m_mouseBtnReleasedAccum, 0, sizeof(m_mouseBtnReleasedAccum));
|
||||||
|
|
||||||
|
m_mouseDeltaX = m_mouseDeltaAccumX;
|
||||||
|
m_mouseDeltaY = m_mouseDeltaAccumY;
|
||||||
|
m_mouseDeltaAccumX = 0;
|
||||||
|
m_mouseDeltaAccumY = 0;
|
||||||
|
m_mouseWheelConsumed = false;
|
||||||
|
|
||||||
|
m_hasInput = (m_mouseDeltaX != 0 || m_mouseDeltaY != 0 || m_mouseWheelAccum != 0);
|
||||||
|
if (!m_hasInput)
|
||||||
{
|
{
|
||||||
if (!m_keyState[vk]) m_keyPressedAccum[vk] = true;
|
for (int i = 0; i < MAX_KEYS; i++)
|
||||||
m_keyState[vk] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyboardMouseInput::OnKeyUp(WPARAM vk)
|
|
||||||
{
|
|
||||||
if (vk < 256)
|
|
||||||
{
|
|
||||||
m_keyState[vk] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyboardMouseInput::OnRawMouseInput(LPARAM lParam)
|
|
||||||
{
|
|
||||||
if (!m_captured) return;
|
|
||||||
|
|
||||||
UINT dwSize = 0;
|
|
||||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
|
|
||||||
|
|
||||||
BYTE* lpb = (BYTE*)alloca(dwSize);
|
|
||||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize)
|
|
||||||
return;
|
|
||||||
|
|
||||||
RAWINPUT* raw = (RAWINPUT*)lpb;
|
|
||||||
if (raw->header.dwType == RIM_TYPEMOUSE)
|
|
||||||
{
|
|
||||||
if (raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
|
|
||||||
{
|
{
|
||||||
m_mouseDeltaXAccum += (float)raw->data.mouse.lLastX;
|
if (m_keyDown[i]) { m_hasInput = true; break; }
|
||||||
m_mouseDeltaYAccum += (float)raw->data.mouse.lLastY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!m_hasInput)
|
||||||
|
|
||||||
void KeyboardMouseInput::OnMouseButton(int button, bool down)
|
|
||||||
{
|
|
||||||
if (button >= 0 && button < 3)
|
|
||||||
{
|
{
|
||||||
if (down && !m_mouseButtons[button]) m_mousePressedAccum[button] = true;
|
for (int i = 0; i < MAX_MOUSE_BUTTONS; i++)
|
||||||
if (!down && m_mouseButtons[button]) m_mouseReleasedAccum[button] = true;
|
{
|
||||||
m_mouseButtons[button] = down;
|
if (m_mouseButtonDown[i]) { m_hasInput = true; break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_mouseGrabbed || m_cursorHiddenForUI) && g_hWnd)
|
||||||
|
{
|
||||||
|
RECT rc;
|
||||||
|
GetClientRect(g_hWnd, &rc);
|
||||||
|
POINT center;
|
||||||
|
center.x = (rc.right - rc.left) / 2;
|
||||||
|
center.y = (rc.bottom - rc.top) / 2;
|
||||||
|
ClientToScreen(g_hWnd, ¢er);
|
||||||
|
SetCursorPos(center.x, center.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyboardMouseInput::OnMouseWheel(int delta)
|
void KeyboardMouseInput::OnKeyDown(int vkCode)
|
||||||
{
|
{
|
||||||
m_scrollDeltaAccum += delta;
|
if (vkCode >= 0 && vkCode < MAX_KEYS)
|
||||||
|
{
|
||||||
|
if (!m_keyDown[vkCode])
|
||||||
|
m_keyPressedAccum[vkCode] = true;
|
||||||
|
m_keyDown[vkCode] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardMouseInput::OnKeyUp(int vkCode)
|
||||||
|
{
|
||||||
|
if (vkCode >= 0 && vkCode < MAX_KEYS)
|
||||||
|
{
|
||||||
|
if (m_keyDown[vkCode])
|
||||||
|
m_keyReleasedAccum[vkCode] = true;
|
||||||
|
m_keyDown[vkCode] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardMouseInput::OnMouseButtonDown(int button)
|
||||||
|
{
|
||||||
|
if (button >= 0 && button < MAX_MOUSE_BUTTONS)
|
||||||
|
{
|
||||||
|
if (!m_mouseButtonDown[button])
|
||||||
|
m_mouseBtnPressedAccum[button] = true;
|
||||||
|
m_mouseButtonDown[button] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardMouseInput::OnMouseButtonUp(int button)
|
||||||
|
{
|
||||||
|
if (button >= 0 && button < MAX_MOUSE_BUTTONS)
|
||||||
|
{
|
||||||
|
if (m_mouseButtonDown[button])
|
||||||
|
m_mouseBtnReleasedAccum[button] = true;
|
||||||
|
m_mouseButtonDown[button] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyboardMouseInput::OnMouseMove(int x, int y)
|
void KeyboardMouseInput::OnMouseMove(int x, int y)
|
||||||
|
|
@ -122,139 +181,204 @@ void KeyboardMouseInput::OnMouseMove(int x, int y)
|
||||||
m_mouseY = y;
|
m_mouseY = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int KeyboardMouseInput::GetMouseX() const { return m_mouseX; }
|
void KeyboardMouseInput::OnMouseWheel(int delta)
|
||||||
int KeyboardMouseInput::GetMouseY() const { return m_mouseY; }
|
|
||||||
HWND KeyboardMouseInput::GetHWnd() const { return m_hWnd; }
|
|
||||||
|
|
||||||
void KeyboardMouseInput::ClearAllState()
|
|
||||||
{
|
{
|
||||||
memset(m_keyState, 0, sizeof(m_keyState));
|
// Normalize from raw Windows delta (multiples of WHEEL_DELTA=120) to discrete notch counts
|
||||||
memset(m_mouseButtons, 0, sizeof(m_mouseButtons));
|
m_mouseWheelAccum += delta / WHEEL_DELTA;
|
||||||
memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
|
|
||||||
memset(m_mousePressedAccum, 0, sizeof(m_mousePressedAccum));
|
|
||||||
memset(m_mouseReleasedAccum, 0, sizeof(m_mouseReleasedAccum));
|
|
||||||
m_mouseDeltaXAccum = 0.0f;
|
|
||||||
m_mouseDeltaYAccum = 0.0f;
|
|
||||||
m_scrollDeltaAccum = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per-frame key queries
|
int KeyboardMouseInput::GetMouseWheel()
|
||||||
bool KeyboardMouseInput::IsKeyDown(int vk) const
|
|
||||||
{
|
{
|
||||||
if (vk < 0 || vk >= 256) return false;
|
int val = m_mouseWheelAccum;
|
||||||
return m_keyState[vk];
|
if (val != 0)
|
||||||
|
m_mouseWheelConsumed = true;
|
||||||
|
m_mouseWheelAccum = 0;
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyboardMouseInput::IsKeyPressed(int vk) const
|
void KeyboardMouseInput::OnRawMouseDelta(int dx, int dy)
|
||||||
{
|
{
|
||||||
if (vk < 0 || vk >= 256) return false;
|
m_mouseDeltaAccumX += dx;
|
||||||
return m_keyState[vk] && !m_keyStatePrev[vk];
|
m_mouseDeltaAccumY += dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyboardMouseInput::IsKeyReleased(int vk) const
|
bool KeyboardMouseInput::IsKeyDown(int vkCode) const
|
||||||
{
|
{
|
||||||
if (vk < 0 || vk >= 256) return false;
|
if (vkCode == VK_SHIFT || vkCode == VK_CONTROL || vkCode == VK_MENU)
|
||||||
return !m_keyState[vk] && m_keyStatePrev[vk];
|
return IsModifierKeyDown(m_keyDown, vkCode);
|
||||||
|
|
||||||
|
if (vkCode >= 0 && vkCode < MAX_KEYS)
|
||||||
|
return m_keyDown[vkCode];
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per-frame mouse button queries
|
bool KeyboardMouseInput::IsKeyPressed(int vkCode) const
|
||||||
bool KeyboardMouseInput::IsMouseDown(int btn) const
|
|
||||||
{
|
{
|
||||||
if (btn < 0 || btn >= 3) return false;
|
if (vkCode == VK_SHIFT || vkCode == VK_CONTROL || vkCode == VK_MENU)
|
||||||
return m_mouseButtons[btn];
|
return IsModifierKeyDown(m_keyPressed, vkCode);
|
||||||
|
|
||||||
|
if (vkCode >= 0 && vkCode < MAX_KEYS)
|
||||||
|
return m_keyPressed[vkCode];
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyboardMouseInput::IsMousePressed(int btn) const
|
bool KeyboardMouseInput::IsKeyReleased(int vkCode) const
|
||||||
{
|
{
|
||||||
if (btn < 0 || btn >= 3) return false;
|
if (vkCode == VK_SHIFT || vkCode == VK_CONTROL || vkCode == VK_MENU)
|
||||||
return m_mouseButtons[btn] && !m_mouseButtonsPrev[btn];
|
return IsModifierKeyDown(m_keyReleased, vkCode);
|
||||||
|
|
||||||
|
if (vkCode >= 0 && vkCode < MAX_KEYS)
|
||||||
|
return m_keyReleased[vkCode];
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyboardMouseInput::IsMouseReleased(int btn) const
|
bool KeyboardMouseInput::IsMouseButtonDown(int button) const
|
||||||
{
|
{
|
||||||
if (btn < 0 || btn >= 3) return false;
|
if (button >= 0 && button < MAX_MOUSE_BUTTONS)
|
||||||
return !m_mouseButtons[btn] && m_mouseButtonsPrev[btn];
|
return m_mouseButtonDown[button];
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game-tick consume methods
|
bool KeyboardMouseInput::IsMouseButtonPressed(int button) const
|
||||||
bool KeyboardMouseInput::ConsumeKeyPress(int vk)
|
|
||||||
{
|
{
|
||||||
if (vk < 0 || vk >= 256) return false;
|
if (button >= 0 && button < MAX_MOUSE_BUTTONS)
|
||||||
bool pressed = m_keyPressedAccum[vk];
|
return m_mouseBtnPressed[button];
|
||||||
m_keyPressedAccum[vk] = false;
|
return false;
|
||||||
return pressed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyboardMouseInput::ConsumeMousePress(int btn)
|
bool KeyboardMouseInput::IsMouseButtonReleased(int button) const
|
||||||
{
|
{
|
||||||
if (btn < 0 || btn >= 3) return false;
|
if (button >= 0 && button < MAX_MOUSE_BUTTONS)
|
||||||
bool pressed = m_mousePressedAccum[btn];
|
return m_mouseBtnReleased[button];
|
||||||
m_mousePressedAccum[btn] = false;
|
return false;
|
||||||
return pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KeyboardMouseInput::ConsumeMouseRelease(int btn)
|
|
||||||
{
|
|
||||||
if (btn < 0 || btn >= 3) return false;
|
|
||||||
bool released = m_mouseReleasedAccum[btn];
|
|
||||||
m_mouseReleasedAccum[btn] = false;
|
|
||||||
return released;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyboardMouseInput::ConsumeMouseDelta(float &dx, float &dy)
|
void KeyboardMouseInput::ConsumeMouseDelta(float &dx, float &dy)
|
||||||
{
|
{
|
||||||
dx = m_mouseDeltaXAccum;
|
dx = (float)m_mouseDeltaAccumX;
|
||||||
dy = m_mouseDeltaYAccum;
|
dy = (float)m_mouseDeltaAccumY;
|
||||||
m_mouseDeltaXAccum = 0.0f;
|
m_mouseDeltaAccumX = 0;
|
||||||
m_mouseDeltaYAccum = 0.0f;
|
m_mouseDeltaAccumY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int KeyboardMouseInput::ConsumeScrollDelta()
|
void KeyboardMouseInput::SetMouseGrabbed(bool grabbed)
|
||||||
{
|
{
|
||||||
int delta = m_scrollDeltaAccum;
|
if (m_mouseGrabbed == grabbed)
|
||||||
m_scrollDeltaAccum = 0;
|
return;
|
||||||
return delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse capture
|
m_mouseGrabbed = grabbed;
|
||||||
void KeyboardMouseInput::SetCapture(bool capture)
|
if (grabbed && g_hWnd)
|
||||||
{
|
|
||||||
if (capture == m_captured) return;
|
|
||||||
m_captured = capture;
|
|
||||||
|
|
||||||
if (capture)
|
|
||||||
{
|
{
|
||||||
ShowCursor(FALSE);
|
while (ShowCursor(FALSE) >= 0) {}
|
||||||
RECT rect;
|
ClipCursorToWindow(g_hWnd);
|
||||||
GetClientRect(m_hWnd, &rect);
|
|
||||||
POINT topLeft = { rect.left, rect.top };
|
|
||||||
POINT bottomRight = { rect.right, rect.bottom };
|
|
||||||
ClientToScreen(m_hWnd, &topLeft);
|
|
||||||
ClientToScreen(m_hWnd, &bottomRight);
|
|
||||||
RECT screenRect = { topLeft.x, topLeft.y, bottomRight.x, bottomRight.y };
|
|
||||||
ClipCursor(&screenRect);
|
|
||||||
CenterCursor();
|
|
||||||
|
|
||||||
// Flush accumulated deltas so the snap-to-center doesn't cause a jump
|
RECT rc;
|
||||||
m_mouseDeltaXAccum = 0.0f;
|
GetClientRect(g_hWnd, &rc);
|
||||||
m_mouseDeltaYAccum = 0.0f;
|
POINT center;
|
||||||
|
center.x = (rc.right - rc.left) / 2;
|
||||||
|
center.y = (rc.bottom - rc.top) / 2;
|
||||||
|
ClientToScreen(g_hWnd, ¢er);
|
||||||
|
SetCursorPos(center.x, center.y);
|
||||||
|
|
||||||
|
m_mouseDeltaAccumX = 0;
|
||||||
|
m_mouseDeltaAccumY = 0;
|
||||||
}
|
}
|
||||||
else
|
else if (!grabbed && !m_cursorHiddenForUI && g_hWnd)
|
||||||
{
|
{
|
||||||
ShowCursor(TRUE);
|
while (ShowCursor(TRUE) < 0) {}
|
||||||
ClipCursor(NULL);
|
ClipCursor(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyboardMouseInput::IsCaptured() const { return m_captured; }
|
void KeyboardMouseInput::SetCursorHiddenForUI(bool hidden)
|
||||||
|
|
||||||
void KeyboardMouseInput::CenterCursor()
|
|
||||||
{
|
{
|
||||||
RECT rect;
|
if (m_cursorHiddenForUI == hidden)
|
||||||
GetClientRect(m_hWnd, &rect);
|
return;
|
||||||
POINT center = { (rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2 };
|
|
||||||
ClientToScreen(m_hWnd, ¢er);
|
m_cursorHiddenForUI = hidden;
|
||||||
SetCursorPos(center.x, center.y);
|
if (hidden && g_hWnd)
|
||||||
|
{
|
||||||
|
while (ShowCursor(FALSE) >= 0) {}
|
||||||
|
ClipCursorToWindow(g_hWnd);
|
||||||
|
|
||||||
|
RECT rc;
|
||||||
|
GetClientRect(g_hWnd, &rc);
|
||||||
|
POINT center;
|
||||||
|
center.x = (rc.right - rc.left) / 2;
|
||||||
|
center.y = (rc.bottom - rc.top) / 2;
|
||||||
|
ClientToScreen(g_hWnd, ¢er);
|
||||||
|
SetCursorPos(center.x, center.y);
|
||||||
|
|
||||||
|
m_mouseDeltaAccumX = 0;
|
||||||
|
m_mouseDeltaAccumY = 0;
|
||||||
|
}
|
||||||
|
else if (!hidden && !m_mouseGrabbed && g_hWnd)
|
||||||
|
{
|
||||||
|
while (ShowCursor(TRUE) < 0) {}
|
||||||
|
ClipCursor(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ClipCursorToWindow(HWND hWnd)
|
||||||
|
{
|
||||||
|
if (!hWnd) return;
|
||||||
|
RECT rc;
|
||||||
|
GetClientRect(hWnd, &rc);
|
||||||
|
POINT topLeft = { rc.left, rc.top };
|
||||||
|
POINT bottomRight = { rc.right, rc.bottom };
|
||||||
|
ClientToScreen(hWnd, &topLeft);
|
||||||
|
ClientToScreen(hWnd, &bottomRight);
|
||||||
|
RECT clipRect = { topLeft.x, topLeft.y, bottomRight.x, bottomRight.y };
|
||||||
|
ClipCursor(&clipRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardMouseInput::SetWindowFocused(bool focused)
|
||||||
|
{
|
||||||
|
m_windowFocused = focused;
|
||||||
|
if (focused)
|
||||||
|
{
|
||||||
|
if (m_mouseGrabbed || m_cursorHiddenForUI)
|
||||||
|
{
|
||||||
|
while (ShowCursor(FALSE) >= 0) {}
|
||||||
|
ClipCursorToWindow(g_hWnd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (ShowCursor(TRUE) < 0) {}
|
||||||
|
ClipCursor(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (ShowCursor(TRUE) < 0) {}
|
||||||
|
ClipCursor(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float KeyboardMouseInput::GetMoveX() const
|
||||||
|
{
|
||||||
|
float x = 0.0f;
|
||||||
|
if (m_keyDown[KEY_LEFT]) x += 1.0f;
|
||||||
|
if (m_keyDown[KEY_RIGHT]) x -= 1.0f;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float KeyboardMouseInput::GetMoveY() const
|
||||||
|
{
|
||||||
|
float y = 0.0f;
|
||||||
|
if (m_keyDown[KEY_FORWARD]) y += 1.0f;
|
||||||
|
if (m_keyDown[KEY_BACKWARD]) y -= 1.0f;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float KeyboardMouseInput::GetLookX(float sensitivity) const
|
||||||
|
{
|
||||||
|
return (float)m_mouseDeltaX * sensitivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
float KeyboardMouseInput::GetLookY(float sensitivity) const
|
||||||
|
{
|
||||||
|
return (float)(-m_mouseDeltaY) * sensitivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _WINDOWS64
|
#endif // _WINDOWS64
|
||||||
|
|
|
||||||
|
|
@ -4,88 +4,133 @@
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
// HID usage page and usage for raw input registration
|
|
||||||
#ifndef HID_USAGE_PAGE_GENERIC
|
|
||||||
#define HID_USAGE_PAGE_GENERIC ((USHORT)0x01)
|
|
||||||
#endif
|
|
||||||
#ifndef HID_USAGE_GENERIC_MOUSE
|
|
||||||
#define HID_USAGE_GENERIC_MOUSE ((USHORT)0x02)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class KeyboardMouseInput
|
class KeyboardMouseInput
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
KeyboardMouseInput();
|
static const int MAX_KEYS = 256;
|
||||||
~KeyboardMouseInput();
|
|
||||||
|
|
||||||
void Init(HWND hWnd);
|
static const int MOUSE_LEFT = 0;
|
||||||
|
static const int MOUSE_RIGHT = 1;
|
||||||
|
static const int MOUSE_MIDDLE = 2;
|
||||||
|
static const int MAX_MOUSE_BUTTONS = 3;
|
||||||
|
|
||||||
|
static const int KEY_FORWARD = 'W';
|
||||||
|
static const int KEY_BACKWARD = 'S';
|
||||||
|
static const int KEY_LEFT = 'A';
|
||||||
|
static const int KEY_RIGHT = 'D';
|
||||||
|
static const int KEY_JUMP = VK_SPACE;
|
||||||
|
static const int KEY_SNEAK = VK_LSHIFT;
|
||||||
|
static const int KEY_SPRINT = VK_CONTROL;
|
||||||
|
static const int KEY_INVENTORY = 'E';
|
||||||
|
static const int KEY_DROP = 'Q';
|
||||||
|
static const int KEY_CRAFTING = 'C';
|
||||||
|
static const int KEY_CRAFTING_ALT = 'R';
|
||||||
|
static const int KEY_CONFIRM = VK_RETURN;
|
||||||
|
static const int KEY_CANCEL = VK_ESCAPE;
|
||||||
|
static const int KEY_PAUSE = VK_ESCAPE;
|
||||||
|
static const int KEY_THIRD_PERSON = VK_F5;
|
||||||
|
static const int KEY_DEBUG_INFO = VK_F3;
|
||||||
|
static const int KEY_DEBUG_MENU = VK_F4;
|
||||||
|
|
||||||
|
void Init();
|
||||||
void Tick();
|
void Tick();
|
||||||
void EndFrame();
|
|
||||||
|
|
||||||
// Called from WndProc
|
|
||||||
void OnKeyDown(WPARAM vk);
|
|
||||||
void OnKeyUp(WPARAM vk);
|
|
||||||
void OnRawMouseInput(LPARAM lParam);
|
|
||||||
void OnMouseButton(int button, bool down);
|
|
||||||
void OnMouseWheel(int delta);
|
|
||||||
void ClearAllState();
|
void ClearAllState();
|
||||||
|
|
||||||
// Per-frame edge detection (for UI / per-frame logic like Alt toggle)
|
void OnKeyDown(int vkCode);
|
||||||
bool IsKeyDown(int vk) const;
|
void OnKeyUp(int vkCode);
|
||||||
bool IsKeyPressed(int vk) const;
|
void OnMouseButtonDown(int button);
|
||||||
bool IsKeyReleased(int vk) const;
|
void OnMouseButtonUp(int button);
|
||||||
bool IsMouseDown(int btn) const;
|
|
||||||
bool IsMousePressed(int btn) const;
|
|
||||||
bool IsMouseReleased(int btn) const;
|
|
||||||
|
|
||||||
// Game-tick consume methods: accumulate across frames, clear on read.
|
|
||||||
// Use these from code that runs at game tick rate (20Hz).
|
|
||||||
bool ConsumeKeyPress(int vk);
|
|
||||||
bool ConsumeMousePress(int btn);
|
|
||||||
bool ConsumeMouseRelease(int btn);
|
|
||||||
void ConsumeMouseDelta(float &dx, float &dy);
|
|
||||||
int ConsumeScrollDelta();
|
|
||||||
|
|
||||||
// Absolute cursor position (client-area coordinates, for GUI when not captured)
|
|
||||||
void OnMouseMove(int x, int y);
|
void OnMouseMove(int x, int y);
|
||||||
int GetMouseX() const;
|
void OnMouseWheel(int delta);
|
||||||
int GetMouseY() const;
|
void OnRawMouseDelta(int dx, int dy);
|
||||||
HWND GetHWnd() const;
|
|
||||||
|
|
||||||
// Mouse capture for FPS look
|
bool IsKeyDown(int vkCode) const;
|
||||||
void SetCapture(bool capture);
|
bool IsKeyPressed(int vkCode) const;
|
||||||
bool IsCaptured() const;
|
bool IsKeyReleased(int vkCode) const;
|
||||||
|
|
||||||
|
bool IsMouseButtonDown(int button) const;
|
||||||
|
bool IsMouseButtonPressed(int button) const;
|
||||||
|
bool IsMouseButtonReleased(int button) const;
|
||||||
|
|
||||||
|
int GetMouseX() const { return m_mouseX; }
|
||||||
|
int GetMouseY() const { return m_mouseY; }
|
||||||
|
|
||||||
|
int GetMouseDeltaX() const { return m_mouseDeltaX; }
|
||||||
|
int GetMouseDeltaY() const { return m_mouseDeltaY; }
|
||||||
|
|
||||||
|
int GetMouseWheel();
|
||||||
|
int PeekMouseWheel() const { return m_mouseWheelAccum; }
|
||||||
|
void ConsumeMouseWheel() { if (m_mouseWheelAccum != 0) m_mouseWheelConsumed = true; m_mouseWheelAccum = 0; }
|
||||||
|
bool WasMouseWheelConsumed() const { return m_mouseWheelConsumed; }
|
||||||
|
|
||||||
|
// Per-frame delta consumption for low-latency mouse look.
|
||||||
|
// Reads and clears the raw accumulators (not the per-tick snapshot).
|
||||||
|
void ConsumeMouseDelta(float &dx, float &dy);
|
||||||
|
|
||||||
|
void SetMouseGrabbed(bool grabbed);
|
||||||
|
bool IsMouseGrabbed() const { return m_mouseGrabbed; }
|
||||||
|
|
||||||
|
void SetCursorHiddenForUI(bool hidden);
|
||||||
|
bool IsCursorHiddenForUI() const { return m_cursorHiddenForUI; }
|
||||||
|
|
||||||
|
void SetWindowFocused(bool focused);
|
||||||
|
bool IsWindowFocused() const { return m_windowFocused; }
|
||||||
|
|
||||||
|
bool HasAnyInput() const { return m_hasInput; }
|
||||||
|
|
||||||
|
void SetKBMActive(bool active) { m_kbmActive = active; }
|
||||||
|
bool IsKBMActive() const { return m_kbmActive; }
|
||||||
|
|
||||||
|
void SetScreenCursorHidden(bool hidden) { m_screenWantsCursorHidden = hidden; }
|
||||||
|
bool IsScreenCursorHidden() const { return m_screenWantsCursorHidden; }
|
||||||
|
|
||||||
|
float GetMoveX() const;
|
||||||
|
float GetMoveY() const;
|
||||||
|
|
||||||
|
float GetLookX(float sensitivity) const;
|
||||||
|
float GetLookY(float sensitivity) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CenterCursor();
|
bool m_keyDown[MAX_KEYS];
|
||||||
|
bool m_keyDownPrev[MAX_KEYS];
|
||||||
|
|
||||||
// Per-frame double-buffered state (for IsKeyPressed/Released per-frame edge detection)
|
bool m_keyPressedAccum[MAX_KEYS];
|
||||||
bool m_keyState[256];
|
bool m_keyReleasedAccum[MAX_KEYS];
|
||||||
bool m_keyStatePrev[256];
|
bool m_keyPressed[MAX_KEYS];
|
||||||
bool m_mouseButtons[3];
|
bool m_keyReleased[MAX_KEYS];
|
||||||
bool m_mouseButtonsPrev[3];
|
|
||||||
|
|
||||||
// Sticky press accumulators (persist until consumed by game tick)
|
bool m_mouseButtonDown[MAX_MOUSE_BUTTONS];
|
||||||
bool m_keyPressedAccum[256];
|
bool m_mouseButtonDownPrev[MAX_MOUSE_BUTTONS];
|
||||||
bool m_mousePressedAccum[3];
|
|
||||||
bool m_mouseReleasedAccum[3];
|
|
||||||
|
|
||||||
// Mouse delta accumulators (persist until consumed by game tick)
|
bool m_mouseBtnPressedAccum[MAX_MOUSE_BUTTONS];
|
||||||
float m_mouseDeltaXAccum;
|
bool m_mouseBtnReleasedAccum[MAX_MOUSE_BUTTONS];
|
||||||
float m_mouseDeltaYAccum;
|
bool m_mouseBtnPressed[MAX_MOUSE_BUTTONS];
|
||||||
|
bool m_mouseBtnReleased[MAX_MOUSE_BUTTONS];
|
||||||
|
|
||||||
// Scroll accumulator (persists until consumed by game tick)
|
|
||||||
int m_scrollDeltaAccum;
|
|
||||||
|
|
||||||
bool m_captured;
|
|
||||||
HWND m_hWnd;
|
|
||||||
bool m_initialized;
|
|
||||||
|
|
||||||
// Absolute cursor position in client coordinates
|
|
||||||
int m_mouseX;
|
int m_mouseX;
|
||||||
int m_mouseY;
|
int m_mouseY;
|
||||||
|
|
||||||
|
int m_mouseDeltaX;
|
||||||
|
int m_mouseDeltaY;
|
||||||
|
int m_mouseDeltaAccumX;
|
||||||
|
int m_mouseDeltaAccumY;
|
||||||
|
|
||||||
|
int m_mouseWheelAccum;
|
||||||
|
bool m_mouseWheelConsumed;
|
||||||
|
|
||||||
|
bool m_mouseGrabbed;
|
||||||
|
|
||||||
|
bool m_cursorHiddenForUI;
|
||||||
|
|
||||||
|
bool m_windowFocused;
|
||||||
|
|
||||||
|
bool m_hasInput;
|
||||||
|
|
||||||
|
bool m_kbmActive;
|
||||||
|
|
||||||
|
bool m_screenWantsCursorHidden;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern KeyboardMouseInput KMInput;
|
extern KeyboardMouseInput g_KBMInput;
|
||||||
|
|
||||||
#endif // _WINDOWS64
|
#endif // _WINDOWS64
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,9 @@ bool g_Win64MultiplayerHost = false;
|
||||||
bool g_Win64MultiplayerJoin = false;
|
bool g_Win64MultiplayerJoin = false;
|
||||||
int g_Win64MultiplayerPort = WIN64_NET_DEFAULT_PORT;
|
int g_Win64MultiplayerPort = WIN64_NET_DEFAULT_PORT;
|
||||||
char g_Win64MultiplayerIP[256] = "127.0.0.1";
|
char g_Win64MultiplayerIP[256] = "127.0.0.1";
|
||||||
|
bool g_Win64DedicatedServer = false;
|
||||||
|
int g_Win64DedicatedServerPort = WIN64_NET_DEFAULT_PORT;
|
||||||
|
char g_Win64DedicatedServerBindIP[256] = "";
|
||||||
|
|
||||||
bool WinsockNetLayer::Initialize()
|
bool WinsockNetLayer::Initialize()
|
||||||
{
|
{
|
||||||
|
|
@ -139,7 +142,7 @@ void WinsockNetLayer::Shutdown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WinsockNetLayer::HostGame(int port)
|
bool WinsockNetLayer::HostGame(int port, const char* bindIp)
|
||||||
{
|
{
|
||||||
if (!s_initialized && !Initialize()) return false;
|
if (!s_initialized && !Initialize()) return false;
|
||||||
|
|
||||||
|
|
@ -159,15 +162,19 @@ bool WinsockNetLayer::HostGame(int port)
|
||||||
hints.ai_family = AF_INET;
|
hints.ai_family = AF_INET;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_protocol = IPPROTO_TCP;
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
hints.ai_flags = AI_PASSIVE;
|
hints.ai_flags = (bindIp == NULL || bindIp[0] == 0) ? AI_PASSIVE : 0;
|
||||||
|
|
||||||
char portStr[16];
|
char portStr[16];
|
||||||
sprintf_s(portStr, "%d", port);
|
sprintf_s(portStr, "%d", port);
|
||||||
|
|
||||||
int iResult = getaddrinfo(NULL, portStr, &hints, &result);
|
const char* resolvedBindIp = (bindIp != NULL && bindIp[0] != 0) ? bindIp : NULL;
|
||||||
|
int iResult = getaddrinfo(resolvedBindIp, portStr, &hints, &result);
|
||||||
if (iResult != 0)
|
if (iResult != 0)
|
||||||
{
|
{
|
||||||
app.DebugPrintf("getaddrinfo failed: %d\n", iResult);
|
app.DebugPrintf("getaddrinfo failed for %s:%d - %d\n",
|
||||||
|
resolvedBindIp != NULL ? resolvedBindIp : "*",
|
||||||
|
port,
|
||||||
|
iResult);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,7 +213,9 @@ bool WinsockNetLayer::HostGame(int port)
|
||||||
|
|
||||||
s_acceptThread = CreateThread(NULL, 0, AcceptThreadProc, NULL, 0, NULL);
|
s_acceptThread = CreateThread(NULL, 0, AcceptThreadProc, NULL, 0, NULL);
|
||||||
|
|
||||||
app.DebugPrintf("Win64 LAN: Hosting on port %d\n", port);
|
app.DebugPrintf("Win64 LAN: Hosting on %s:%d\n",
|
||||||
|
resolvedBindIp != NULL ? resolvedBindIp : "*",
|
||||||
|
port);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -908,4 +917,4 @@ DWORD WINAPI WinsockNetLayer::DiscoveryThreadProc(LPVOID param)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ public:
|
||||||
static bool Initialize();
|
static bool Initialize();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
static bool HostGame(int port);
|
static bool HostGame(int port, const char* bindIp = NULL);
|
||||||
static bool JoinGame(const char* ip, int port);
|
static bool JoinGame(const char* ip, int port);
|
||||||
|
|
||||||
static bool SendToSmallId(BYTE targetSmallId, const void* data, int dataSize);
|
static bool SendToSmallId(BYTE targetSmallId, const void* data, int dataSize);
|
||||||
|
|
@ -147,5 +147,8 @@ extern bool g_Win64MultiplayerHost;
|
||||||
extern bool g_Win64MultiplayerJoin;
|
extern bool g_Win64MultiplayerJoin;
|
||||||
extern int g_Win64MultiplayerPort;
|
extern int g_Win64MultiplayerPort;
|
||||||
extern char g_Win64MultiplayerIP[256];
|
extern char g_Win64MultiplayerIP[256];
|
||||||
|
extern bool g_Win64DedicatedServer;
|
||||||
|
extern int g_Win64DedicatedServerPort;
|
||||||
|
extern char g_Win64DedicatedServerBindIP[256];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Minecraft.Client/Windows64Media/Media/logo-original.png
Normal file
BIN
Minecraft.Client/Windows64Media/Media/logo-original.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 196 KiB |
BIN
Minecraft.Client/Windows64Media/Media/logo-tempscaled.png
Normal file
BIN
Minecraft.Client/Windows64Media/Media/logo-tempscaled.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 122 KiB |
Binary file not shown.
Binary file not shown.
|
|
@ -48,13 +48,11 @@ void glLoadIdentity()
|
||||||
RenderManager.MatrixSetIdentity();
|
RenderManager.MatrixSetIdentity();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int g_iScreenWidth;
|
// AAR - Use calculated aspect ratio to support dynamic resizing
|
||||||
extern int g_iScreenHeight;
|
extern float g_iAspectRatio;
|
||||||
|
|
||||||
void gluPerspective(float fovy, float aspect, float zNear, float zFar)
|
void gluPerspective(float fovy, float aspect, float zNear, float zFar)
|
||||||
{
|
{
|
||||||
float dynamicAspect = (float)g_iScreenWidth / (float)g_iScreenHeight;
|
RenderManager.MatrixPerspective(fovy, g_iAspectRatio, zNear, zFar);
|
||||||
RenderManager.MatrixPerspective(fovy, dynamicAspect, zNear, zFar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void glOrtho(float left,float right,float bottom,float top,float zNear,float zFar)
|
void glOrtho(float left,float right,float bottom,float top,float zNear,float zFar)
|
||||||
|
|
|
||||||
|
|
@ -3,41 +3,98 @@
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
#include "Windows64\KeyboardMouseInput.h"
|
#include "Windows64\KeyboardMouseInput.h"
|
||||||
|
|
||||||
|
static const int s_keyToVK[] = {
|
||||||
|
'A', // KEY_A = 0
|
||||||
|
'B', // KEY_B = 1
|
||||||
|
'C', // KEY_C = 2
|
||||||
|
'D', // KEY_D = 3
|
||||||
|
'E', // KEY_E = 4
|
||||||
|
'F', // KEY_F = 5
|
||||||
|
'G', // KEY_G = 6
|
||||||
|
'H', // KEY_H = 7
|
||||||
|
'I', // KEY_I = 8
|
||||||
|
'J', // KEY_J = 9
|
||||||
|
'K', // KEY_K = 10
|
||||||
|
'L', // KEY_L = 11
|
||||||
|
'M', // KEY_M = 12
|
||||||
|
'N', // KEY_N = 13
|
||||||
|
'O', // KEY_O = 14
|
||||||
|
'P', // KEY_P = 15
|
||||||
|
'Q', // KEY_Q = 16
|
||||||
|
'R', // KEY_R = 17
|
||||||
|
'S', // KEY_S = 18
|
||||||
|
'T', // KEY_T = 19
|
||||||
|
'U', // KEY_U = 20
|
||||||
|
'V', // KEY_V = 21
|
||||||
|
'W', // KEY_W = 22
|
||||||
|
'X', // KEY_X = 23
|
||||||
|
'Y', // KEY_Y = 24
|
||||||
|
'Z', // KEY_Z = 25
|
||||||
|
VK_SPACE, // KEY_SPACE = 26
|
||||||
|
VK_LSHIFT, // KEY_LSHIFT = 27
|
||||||
|
VK_ESCAPE, // KEY_ESCAPE = 28
|
||||||
|
VK_BACK, // KEY_BACK = 29
|
||||||
|
VK_RETURN, // KEY_RETURN = 30
|
||||||
|
VK_RSHIFT, // KEY_RSHIFT = 31
|
||||||
|
VK_UP, // KEY_UP = 32
|
||||||
|
VK_DOWN, // KEY_DOWN = 33
|
||||||
|
VK_TAB, // KEY_TAB = 34
|
||||||
|
'1', // KEY_1 = 35
|
||||||
|
'2', // KEY_2 = 36
|
||||||
|
'3', // KEY_3 = 37
|
||||||
|
'4', // KEY_4 = 38
|
||||||
|
'5', // KEY_5 = 39
|
||||||
|
'6', // KEY_6 = 40
|
||||||
|
'7', // KEY_7 = 41
|
||||||
|
'8', // KEY_8 = 42
|
||||||
|
'9', // KEY_9 = 43
|
||||||
|
VK_F1, // KEY_F1 = 44
|
||||||
|
VK_F3, // KEY_F3 = 45
|
||||||
|
VK_F4, // KEY_F4 = 46
|
||||||
|
VK_F5, // KEY_F5 = 47
|
||||||
|
VK_F6, // KEY_F6 = 48
|
||||||
|
VK_F8, // KEY_F8 = 49
|
||||||
|
VK_F9, // KEY_F9 = 50
|
||||||
|
VK_F11, // KEY_F11 = 51
|
||||||
|
VK_ADD, // KEY_ADD = 52
|
||||||
|
VK_SUBTRACT,// KEY_SUBTRACT = 53
|
||||||
|
VK_LEFT, // KEY_LEFT = 54
|
||||||
|
VK_RIGHT, // KEY_RIGHT = 55
|
||||||
|
};
|
||||||
|
static const int s_keyToVKCount = sizeof(s_keyToVK) / sizeof(s_keyToVK[0]);
|
||||||
|
|
||||||
|
int Keyboard::toVK(int keyConst)
|
||||||
|
{
|
||||||
|
if (keyConst >= 0 && keyConst < s_keyToVKCount)
|
||||||
|
return s_keyToVK[keyConst];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::isKeyDown(int keyCode)
|
||||||
|
{
|
||||||
|
int vk = toVK(keyCode);
|
||||||
|
if (vk > 0)
|
||||||
|
return g_KBMInput.IsKeyDown(vk);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int Mouse::getX()
|
int Mouse::getX()
|
||||||
{
|
{
|
||||||
return KMInput.GetMouseX();
|
return g_KBMInput.GetMouseX();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Mouse::getY()
|
int Mouse::getY()
|
||||||
{
|
{
|
||||||
// Return Y in bottom-up coordinates (OpenGL convention, matching original Java LWJGL Mouse)
|
// Return Y in bottom-up coordinates (OpenGL convention, matching original Java LWJGL Mouse)
|
||||||
|
extern HWND g_hWnd;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
GetClientRect(KMInput.GetHWnd(), &rect);
|
GetClientRect(g_hWnd, &rect);
|
||||||
return (rect.bottom - 1) - KMInput.GetMouseY();
|
return (rect.bottom - 1) - g_KBMInput.GetMouseY();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mouse::isButtonDown(int button)
|
bool Mouse::isButtonDown(int button)
|
||||||
{
|
{
|
||||||
return KMInput.IsMouseDown(button);
|
return g_KBMInput.IsMouseButtonDown(button);
|
||||||
}
|
|
||||||
|
|
||||||
bool Keyboard::isKeyDown(int key)
|
|
||||||
{
|
|
||||||
// Map Keyboard constants to Windows virtual key codes
|
|
||||||
if (key == Keyboard::KEY_LSHIFT) return KMInput.IsKeyDown(VK_LSHIFT);
|
|
||||||
if (key == Keyboard::KEY_RSHIFT) return KMInput.IsKeyDown(VK_RSHIFT);
|
|
||||||
if (key == Keyboard::KEY_ESCAPE) return KMInput.IsKeyDown(VK_ESCAPE);
|
|
||||||
if (key == Keyboard::KEY_RETURN) return KMInput.IsKeyDown(VK_RETURN);
|
|
||||||
if (key == Keyboard::KEY_BACK) return KMInput.IsKeyDown(VK_BACK);
|
|
||||||
if (key == Keyboard::KEY_SPACE) return KMInput.IsKeyDown(VK_SPACE);
|
|
||||||
if (key == Keyboard::KEY_TAB) return KMInput.IsKeyDown(VK_TAB);
|
|
||||||
if (key == Keyboard::KEY_UP) return KMInput.IsKeyDown(VK_UP);
|
|
||||||
if (key == Keyboard::KEY_DOWN) return KMInput.IsKeyDown(VK_DOWN);
|
|
||||||
if (key == Keyboard::KEY_LEFT) return KMInput.IsKeyDown(VK_LEFT);
|
|
||||||
if (key == Keyboard::KEY_RIGHT) return KMInput.IsKeyDown(VK_RIGHT);
|
|
||||||
if (key >= Keyboard::KEY_A && key <= Keyboard::KEY_Z)
|
|
||||||
return KMInput.IsKeyDown('A' + (key - Keyboard::KEY_A));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,12 +187,13 @@ public:
|
||||||
static void create() {}
|
static void create() {}
|
||||||
static void destroy() {}
|
static void destroy() {}
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
static bool isKeyDown(int key);
|
static bool isKeyDown(int keyCode);
|
||||||
#else
|
#else
|
||||||
static bool isKeyDown(int) {return false;}
|
static bool isKeyDown(int) { return false; }
|
||||||
#endif
|
#endif
|
||||||
static wstring getKeyName(int) { return L"KEYNAME"; }
|
static wstring getKeyName(int) { return L"KEYNAME"; }
|
||||||
static void enableRepeatEvents(bool) {}
|
static void enableRepeatEvents(bool) {}
|
||||||
|
|
||||||
static const int KEY_A = 0;
|
static const int KEY_A = 0;
|
||||||
static const int KEY_B = 1;
|
static const int KEY_B = 1;
|
||||||
static const int KEY_C = 2;
|
static const int KEY_C = 2;
|
||||||
|
|
@ -228,8 +229,32 @@ public:
|
||||||
static const int KEY_UP = 32;
|
static const int KEY_UP = 32;
|
||||||
static const int KEY_DOWN = 33;
|
static const int KEY_DOWN = 33;
|
||||||
static const int KEY_TAB = 34;
|
static const int KEY_TAB = 34;
|
||||||
static const int KEY_LEFT = 35;
|
static const int KEY_1 = 35;
|
||||||
static const int KEY_RIGHT = 36;
|
static const int KEY_2 = 36;
|
||||||
|
static const int KEY_3 = 37;
|
||||||
|
static const int KEY_4 = 38;
|
||||||
|
static const int KEY_5 = 39;
|
||||||
|
static const int KEY_6 = 40;
|
||||||
|
static const int KEY_7 = 41;
|
||||||
|
static const int KEY_8 = 42;
|
||||||
|
static const int KEY_9 = 43;
|
||||||
|
static const int KEY_F1 = 44;
|
||||||
|
static const int KEY_F3 = 45;
|
||||||
|
static const int KEY_F4 = 46;
|
||||||
|
static const int KEY_F5 = 47;
|
||||||
|
static const int KEY_F6 = 48;
|
||||||
|
static const int KEY_F8 = 49;
|
||||||
|
static const int KEY_F9 = 50;
|
||||||
|
static const int KEY_F11 = 51;
|
||||||
|
static const int KEY_ADD = 52;
|
||||||
|
static const int KEY_SUBTRACT = 53;
|
||||||
|
static const int KEY_LEFT = 54;
|
||||||
|
static const int KEY_RIGHT = 55;
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
// Map LWJGL-style key constant to Windows VK code
|
||||||
|
static int toVK(int keyConst);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mouse
|
class Mouse
|
||||||
|
|
|
||||||
|
|
@ -749,7 +749,7 @@ void ConsoleSaveFileOriginal::Flush(bool autosave, bool updateThumbnail )
|
||||||
PBYTE pbDataSaveImage=NULL;
|
PBYTE pbDataSaveImage=NULL;
|
||||||
DWORD dwDataSizeSaveImage=0;
|
DWORD dwDataSizeSaveImage=0;
|
||||||
|
|
||||||
#if ( defined _XBOX || defined _DURANGO )
|
#if ( defined _XBOX || defined _DURANGO || defined _WINDOWS64 )
|
||||||
app.GetSaveThumbnail(&pbThumbnailData,&dwThumbnailDataSize);
|
app.GetSaveThumbnail(&pbThumbnailData,&dwThumbnailDataSize);
|
||||||
#elif ( defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ )
|
#elif ( defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ )
|
||||||
app.GetSaveThumbnail(&pbThumbnailData,&dwThumbnailDataSize,&pbDataSaveImage,&dwDataSizeSaveImage);
|
app.GetSaveThumbnail(&pbThumbnailData,&dwThumbnailDataSize,&pbDataSaveImage,&dwDataSizeSaveImage);
|
||||||
|
|
|
||||||
|
|
@ -479,7 +479,7 @@ void EntityHorse::createInventory()
|
||||||
|
|
||||||
void EntityHorse::updateEquipment()
|
void EntityHorse::updateEquipment()
|
||||||
{
|
{
|
||||||
if (!level->isClientSide)
|
if (level && !level->isClientSide)
|
||||||
{
|
{
|
||||||
setSaddled(inventory->getItem(INV_SLOT_SADDLE) != NULL);
|
setSaddled(inventory->getItem(INV_SLOT_SADDLE) != NULL);
|
||||||
if (canWearArmor())
|
if (canWearArmor())
|
||||||
|
|
|
||||||
|
|
@ -288,10 +288,10 @@ shared_ptr<ItemInstance> FilledBucketDispenseBehavior::execute(BlockSource *sour
|
||||||
return dispensed;
|
return dispensed;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefaultDispenseItemBehavior::dispense(source, dispensed);
|
outcome = LEFT_ITEM;
|
||||||
|
return dispensed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* EmptyBucket */
|
/* EmptyBucket */
|
||||||
|
|
||||||
shared_ptr<ItemInstance> EmptyBucketDispenseBehavior::execute(BlockSource *source, shared_ptr<ItemInstance> dispensed, eOUTCOME &outcome)
|
shared_ptr<ItemInstance> EmptyBucketDispenseBehavior::execute(BlockSource *source, shared_ptr<ItemInstance> dispensed, eOUTCOME &outcome)
|
||||||
|
|
@ -454,4 +454,4 @@ shared_ptr<ItemInstance> TntDispenseBehavior::execute(BlockSource *source, share
|
||||||
outcome = LEFT_ITEM;
|
outcome = LEFT_ITEM;
|
||||||
}
|
}
|
||||||
return dispensed;
|
return dispensed;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1257,6 +1257,7 @@
|
||||||
<UseFullPaths>false</UseFullPaths>
|
<UseFullPaths>false</UseFullPaths>
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||||
|
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
|
@ -1355,7 +1356,7 @@
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<AdditionalOptions>/Ob3</AdditionalOptions>
|
<AdditionalOptions>/FS /Ob3 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
|
@ -4957,4 +4958,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ bool NearestAttackableTargetGoal::DistComp::operator() (shared_ptr<Entity> e1, s
|
||||||
double distSqr2 = source->distanceToSqr(e2);
|
double distSqr2 = source->distanceToSqr(e2);
|
||||||
if (distSqr1 < distSqr2) return true;
|
if (distSqr1 < distSqr2) return true;
|
||||||
if (distSqr1 > distSqr2) return false;
|
if (distSqr1 > distSqr2) return false;
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NearestAttackableTargetGoal::NearestAttackableTargetGoal(PathfinderMob *mob, const type_info& targetType, int randomInterval, bool mustSee, bool mustReach /*= false*/, EntitySelector *entitySelector /* =NULL */)
|
NearestAttackableTargetGoal::NearestAttackableTargetGoal(PathfinderMob *mob, const type_info& targetType, int randomInterval, bool mustSee, bool mustReach /*= false*/, EntitySelector *entitySelector /* =NULL */)
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,24 @@ PanicGoal::PanicGoal(PathfinderMob *mob, double speedModifier)
|
||||||
{
|
{
|
||||||
this->mob = mob;
|
this->mob = mob;
|
||||||
this->speedModifier = speedModifier;
|
this->speedModifier = speedModifier;
|
||||||
setRequiredControlFlags(Control::MoveControlFlag);
|
Goal::setRequiredControlFlags(Control::MoveControlFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PanicGoal::canUse()
|
bool PanicGoal::canUse()
|
||||||
{
|
{
|
||||||
if (mob->getLastHurtByMob() == NULL && !mob->isOnFire()) return false;
|
if (mob->getLastHurtByMob() == nullptr && !mob->isOnFire()) return false;
|
||||||
Vec3 *pos = RandomPos::getPos(dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 5, 4);
|
const int hurtTimeout = mob->getLastHurtByMobTimestamp();
|
||||||
if (pos == NULL) return false;
|
if (hurtTimeout == 0) return false;
|
||||||
|
static thread_local std::mt19937 rng(std::random_device{}());
|
||||||
|
std::uniform_int_distribution<int> dist(60, 100);
|
||||||
|
const int panicDuration = dist(rng);
|
||||||
|
if (mob->tickCount - hurtTimeout > panicDuration) return false;
|
||||||
|
const Vec3* pos = RandomPos::getPos(dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 5, 4);
|
||||||
|
if (pos == nullptr) return false;
|
||||||
posX = pos->x;
|
posX = pos->x;
|
||||||
posY = pos->y;
|
posY = pos->y;
|
||||||
posZ = pos->z;
|
posZ = pos->z;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,5 +38,6 @@ void PanicGoal::start()
|
||||||
|
|
||||||
bool PanicGoal::canContinueToUse()
|
bool PanicGoal::canContinueToUse()
|
||||||
{
|
{
|
||||||
|
if (mob->getLastHurtByMob() == nullptr && !mob->isOnFire()) return false;
|
||||||
return !mob->getNavigation()->isDone();
|
return !mob->getNavigation()->isDone();
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Goal.h"
|
#include "Goal.h"
|
||||||
|
#include <random>
|
||||||
|
|
||||||
class PathfinderMob;
|
class PathfinderMob;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -627,6 +627,7 @@ void Player::ride(shared_ptr<Entity> e)
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this->abilities.flying = false;
|
||||||
LivingEntity::ride(e);
|
LivingEntity::ride(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -166,9 +166,15 @@ void SignTileEntity::setChanged()
|
||||||
|
|
||||||
|
|
||||||
void SignTileEntity::SetMessage(int iIndex,wstring &wsText)
|
void SignTileEntity::SetMessage(int iIndex,wstring &wsText)
|
||||||
{
|
{
|
||||||
|
if (wsText.length() > MAX_LINE_LENGTH) // MAX_LINE_LENGTH == 15
|
||||||
|
{
|
||||||
|
wsText = wsText.substr(0, MAX_LINE_LENGTH);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
OutputDebugStringW(L"Sign text truncated to 15 characters\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
m_wsmessages[iIndex]=wsText;
|
m_wsmessages[iIndex]=wsText;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4J-PB - added for string verification
|
// 4J-PB - added for string verification
|
||||||
|
|
|
||||||
|
|
@ -535,7 +535,7 @@ void WitherBoss::registerAttributes()
|
||||||
getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.6f);
|
getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.6f);
|
||||||
|
|
||||||
// 4J Stu - Don't make it so far!
|
// 4J Stu - Don't make it so far!
|
||||||
//getAttribute(SharedMonsterAttributes::FOLLOW_RANGE)->setBaseValue(40);
|
getAttribute(SharedMonsterAttributes::FOLLOW_RANGE)->setBaseValue(40);
|
||||||
}
|
}
|
||||||
|
|
||||||
float WitherBoss::getHeadYRot(int i)
|
float WitherBoss::getHeadYRot(int i)
|
||||||
|
|
@ -581,4 +581,4 @@ MobType WitherBoss::getMobType()
|
||||||
void WitherBoss::ride(shared_ptr<Entity> e)
|
void WitherBoss::ride(shared_ptr<Entity> e)
|
||||||
{
|
{
|
||||||
riding = nullptr;
|
riding = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ void Zombie::registerAttributes()
|
||||||
Monster::registerAttributes();
|
Monster::registerAttributes();
|
||||||
|
|
||||||
// 4J Stu - Don't make it so far!
|
// 4J Stu - Don't make it so far!
|
||||||
//getAttribute(SharedMonsterAttributes::FOLLOW_RANGE)->setBaseValue(40);
|
getAttribute(SharedMonsterAttributes::FOLLOW_RANGE)->setBaseValue(40);
|
||||||
|
|
||||||
getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.23f);
|
getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.23f);
|
||||||
getAttribute(SharedMonsterAttributes::ATTACK_DAMAGE)->setBaseValue(3);
|
getAttribute(SharedMonsterAttributes::ATTACK_DAMAGE)->setBaseValue(3);
|
||||||
|
|
@ -490,4 +490,4 @@ Zombie::ZombieGroupData::ZombieGroupData(bool baby, bool villager)
|
||||||
{
|
{
|
||||||
isBaby = baby;
|
isBaby = baby;
|
||||||
isVillager = villager;
|
isVillager = villager;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
32
README.md
32
README.md
|
|
@ -20,10 +20,11 @@ This project contains the source code of Minecraft Legacy Console Edition v1.6.0
|
||||||
- Fixed compilation and execution in both Debug and Release mode on Windows using Visual Studio 2022
|
- Fixed compilation and execution in both Debug and Release mode on Windows using Visual Studio 2022
|
||||||
- Added support for keyboard and mouse input
|
- Added support for keyboard and mouse input
|
||||||
- Added fullscreen mode support (toggle using F11)
|
- Added fullscreen mode support (toggle using F11)
|
||||||
- Disabled V-Sync for better performance
|
- (WIP) Disabled V-Sync for better performance
|
||||||
- Added a high-resolution timer path on Windows for smoother high-FPS gameplay timing
|
- Added a high-resolution timer path on Windows for smoother high-FPS gameplay timing
|
||||||
- Device's screen resolution will be used as the game resolution instead of using a fixed resolution (1920x1080)
|
- Device's screen resolution will be used as the game resolution instead of using a fixed resolution (1920x1080)
|
||||||
- LAN Multiplayer & Discovery
|
- LAN Multiplayer & Discovery
|
||||||
|
- Added persistent username system via "username.txt"
|
||||||
|
|
||||||
## Multiplayer
|
## Multiplayer
|
||||||
|
|
||||||
|
|
@ -33,10 +34,30 @@ Basic LAN multiplayer is available on the Windows build
|
||||||
- Other players on the same LAN can discover the session from the in-game Join Game menu
|
- Other players on the same LAN can discover the session from the in-game Join Game menu
|
||||||
- Game connections use TCP port `25565` by default
|
- Game connections use TCP port `25565` by default
|
||||||
- LAN discovery uses UDP port `25566`
|
- LAN discovery uses UDP port `25566`
|
||||||
- You can override your in-game username at launch with `username.txt`
|
|
||||||
|
|
||||||
This feature is based on [LCEMP](https://github.com/LCEMP/LCEMP/)
|
This feature is based on [LCEMP](https://github.com/LCEMP/LCEMP/)
|
||||||
|
|
||||||
|
### Launch Arguments
|
||||||
|
|
||||||
|
| Argument | Description |
|
||||||
|
|--------------------|-----------------------------------------------------------------------------------------------------|
|
||||||
|
| `-name <username>` | Sets your in-game username |
|
||||||
|
| `-server` | Launches a headless server instead of the client |
|
||||||
|
| `-ip <address>` | Client mode: manually connect to an IP. Server mode: override the bind IP from `server.properties` |
|
||||||
|
| `-port <port>` | Client mode: override the join port. Server mode: override the listen port from `server.properties` |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
Minecraft.Client.exe -name Steve -ip 192.168.0.25 -port 25565
|
||||||
|
```
|
||||||
|
|
||||||
|
Headless server example:
|
||||||
|
```
|
||||||
|
Minecraft.Client.exe -server -ip 0.0.0.0 -port 25565
|
||||||
|
```
|
||||||
|
|
||||||
|
The headless server also reads and writes `server.properties` in the working directory. If `-ip` / `-port` are omitted in `-server` mode, it falls back to `server-ip` / `server-port` from that file. Dedicated-server host options such as `trust-players`, `pvp`, `fire-spreads`, `tnt`, `difficulty`, `gamemode`, `spawn-animals`, and `spawn-npcs` are persisted there as well.
|
||||||
|
|
||||||
## Controls (Keyboard & Mouse)
|
## Controls (Keyboard & Mouse)
|
||||||
|
|
||||||
- **Movement**: `W` `A` `S` `D`
|
- **Movement**: `W` `A` `S` `D`
|
||||||
|
|
@ -45,11 +66,10 @@ This feature is based on [LCEMP](https://github.com/LCEMP/LCEMP/)
|
||||||
- **Sprint**: `Ctrl` (Hold) or Double-tap `W`
|
- **Sprint**: `Ctrl` (Hold) or Double-tap `W`
|
||||||
- **Inventory**: `E`
|
- **Inventory**: `E`
|
||||||
- **Drop Item**: `Q`
|
- **Drop Item**: `Q`
|
||||||
- **Crafting**: `C`
|
- **Crafting**: `C` Use `Q` and `E` to move through tabs (cycles Left/Right)
|
||||||
- **Toggle View (FPS/TPS)**: `F5`
|
- **Toggle View (FPS/TPS)**: `F5`
|
||||||
- **Fullscreen**: `F11`
|
- **Fullscreen**: `F11`
|
||||||
- **Pause Menu**: `Esc`
|
- **Pause Menu**: `Esc`
|
||||||
- **Toggle Mouse Capture**: `Left Alt` (for debugging)
|
|
||||||
- **Attack / Destroy**: `Left Click`
|
- **Attack / Destroy**: `Left Click`
|
||||||
- **Use / Place**: `Right Click`
|
- **Use / Place**: `Right Click`
|
||||||
- **Select Item**: `Mouse Wheel` or keys `1` to `9`
|
- **Select Item**: `Mouse Wheel` or keys `1` to `9`
|
||||||
|
|
@ -58,6 +78,7 @@ This feature is based on [LCEMP](https://github.com/LCEMP/LCEMP/)
|
||||||
- **Toggle HUD**: `F1`
|
- **Toggle HUD**: `F1`
|
||||||
- **Toggle Debug Info**: `F3`
|
- **Toggle Debug Info**: `F3`
|
||||||
- **Open Debug Overlay**: `F4`
|
- **Open Debug Overlay**: `F4`
|
||||||
|
- **Toggle Debug Console**: `F6`
|
||||||
|
|
||||||
## Build & Run
|
## Build & Run
|
||||||
|
|
||||||
|
|
@ -80,6 +101,9 @@ For more information, see [COMPILE.md](COMPILE.md)
|
||||||
|
|
||||||
- Native builds for platforms other than Windows have not been tested and are most likely non-functional. The Windows nightly build may still run on macOS and Linux through Wine or CrossOver, but that path is unofficial and not currently supported
|
- Native builds for platforms other than Windows have not been tested and are most likely non-functional. The Windows nightly build may still run on macOS and Linux through Wine or CrossOver, but that path is unofficial and not currently supported
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
Would you like to contribute to this project? Please read our [Contributor's Guide](CONTRIBUTING.md) before doing so! This document includes our current goals, standards for inclusions, rules, and more.
|
||||||
|
|
||||||
## Star History
|
## Star History
|
||||||
|
|
||||||
[](https://www.star-history.com/?spm=a2c6h.12873639.article-detail.7.7b9d7fabjNxTRk#smartcmd/MinecraftConsoles&type=date&legend=top-left)
|
[](https://www.star-history.com/?spm=a2c6h.12873639.article-detail.7.7b9d7fabjNxTRk#smartcmd/MinecraftConsoles&type=date&legend=top-left)
|
||||||
|
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
if(NOT DEFINED PROJECT_SOURCE_DIR OR NOT DEFINED OUTPUT_DIR OR NOT DEFINED CONFIGURATION)
|
|
||||||
message(FATAL_ERROR "CopyAssets.cmake requires PROJECT_SOURCE_DIR, OUTPUT_DIR, and CONFIGURATION.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Some generators may pass quoted values (e.g. "Debug"); normalize that.
|
|
||||||
string(REPLACE "\"" "" PROJECT_SOURCE_DIR "${PROJECT_SOURCE_DIR}")
|
|
||||||
string(REPLACE "\"" "" OUTPUT_DIR "${OUTPUT_DIR}")
|
|
||||||
string(REPLACE "\"" "" CONFIGURATION "${CONFIGURATION}")
|
|
||||||
|
|
||||||
set(_project_dir "${PROJECT_SOURCE_DIR}/Minecraft.Client")
|
|
||||||
|
|
||||||
function(copy_tree_if_exists src_rel dst_rel)
|
|
||||||
set(_src "${_project_dir}/${src_rel}")
|
|
||||||
set(_dst "${OUTPUT_DIR}/${dst_rel}")
|
|
||||||
|
|
||||||
if(EXISTS "${_src}")
|
|
||||||
file(MAKE_DIRECTORY "${_dst}")
|
|
||||||
file(GLOB_RECURSE _files RELATIVE "${_src}" "${_src}/*")
|
|
||||||
|
|
||||||
foreach(_file IN LISTS _files) # if not a source file
|
|
||||||
if(NOT _file MATCHES "\\.(cpp|c|h|hpp|xml|lang)$")
|
|
||||||
set(_full_src "${_src}/${_file}")
|
|
||||||
set(_full_dst "${_dst}/${_file}")
|
|
||||||
|
|
||||||
if(IS_DIRECTORY "${_full_src}")
|
|
||||||
file(MAKE_DIRECTORY "${_full_dst}")
|
|
||||||
else()
|
|
||||||
get_filename_component(_dst_dir "${_full_dst}" DIRECTORY)
|
|
||||||
file(MAKE_DIRECTORY "${_dst_dir}")
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
|
||||||
"${_full_src}" "${_full_dst}"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(ensure_dir rel_path)
|
|
||||||
file(MAKE_DIRECTORY "${OUTPUT_DIR}/${rel_path}")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(copy_file_if_exists src_rel dst_rel)
|
|
||||||
set(_src "${PROJECT_SOURCE_DIR}/${src_rel}")
|
|
||||||
set(_dst "${OUTPUT_DIR}/${dst_rel}")
|
|
||||||
|
|
||||||
get_filename_component(_dst_dir "${_dst}" DIRECTORY)
|
|
||||||
file(MAKE_DIRECTORY "${_dst_dir}")
|
|
||||||
|
|
||||||
if(EXISTS "${_src}")
|
|
||||||
execute_process(
|
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
|
||||||
"${_src}" "${_dst}"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(copy_first_existing dst_rel)
|
|
||||||
set(_copied FALSE)
|
|
||||||
foreach(_candidate IN LISTS ARGN)
|
|
||||||
if(EXISTS "${PROJECT_SOURCE_DIR}/${_candidate}")
|
|
||||||
copy_file_if_exists("${_candidate}" "${dst_rel}")
|
|
||||||
set(_copied TRUE)
|
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
if(NOT _copied)
|
|
||||||
message(WARNING "Runtime file not found for ${dst_rel}. Checked: ${ARGN}")
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(remove_directory_if_exists rel_path)
|
|
||||||
set(_dir "${OUTPUT_DIR}/${rel_path}")
|
|
||||||
if(EXISTS "${_dir}")
|
|
||||||
file(REMOVE_RECURSE "${_dir}")
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
#copy_tree_if_exists("Durango/Sound" "Windows64/Sound")
|
|
||||||
copy_tree_if_exists("music" "music")
|
|
||||||
copy_tree_if_exists("Windows64/GameHDD" "Windows64/GameHDD")
|
|
||||||
copy_file_if_exists("Minecraft.Client/Common/Media/MediaWindows64.arc" "Common/Media/MediaWindows64.arc")
|
|
||||||
copy_tree_if_exists("Common/res" "Common/res")
|
|
||||||
copy_tree_if_exists("Common/Trial" "Common/Trial")
|
|
||||||
copy_tree_if_exists("Common/Tutorial" "Common/Tutorial")
|
|
||||||
copy_tree_if_exists("DurangoMedia" "Windows64Media")
|
|
||||||
copy_tree_if_exists("Windows64Media" "Windows64Media")
|
|
||||||
|
|
||||||
remove_directory_if_exists("Windows64Media/Layout")
|
|
||||||
|
|
||||||
# Some runtime code asserts if this directory tree is missing.
|
|
||||||
ensure_dir("Windows64/GameHDD")
|
|
||||||
|
|
||||||
# Keep legacy runtime redistributables in a familiar location.
|
|
||||||
copy_tree_if_exists("Windows64/Miles/lib/redist64" "redist64")
|
|
||||||
copy_tree_if_exists("Windows64/Iggy/lib/redist64" "redist64")
|
|
||||||
|
|
||||||
# Runtime DLLs required at launch.
|
|
||||||
copy_first_existing("iggy_w64.dll"
|
|
||||||
"Minecraft.Client/Windows64/Iggy/lib/redist64/iggy_w64.dll"
|
|
||||||
"x64/${CONFIGURATION}/iggy_w64.dll"
|
|
||||||
)
|
|
||||||
copy_first_existing("mss64.dll"
|
|
||||||
"Minecraft.Client/Windows64/Miles/lib/redist64/mss64.dll"
|
|
||||||
"x64/${CONFIGURATION}/mss64.dll"
|
|
||||||
)
|
|
||||||
Loading…
Reference in a new issue