layout: restructure into src/ tests/ android/ scripts/ tools/
- extension/src/{port,platform,codepage} -> src/; native_render -> src/host
(+ dxt, shaders/); libgr2 -> src/gr2; extension/third_party -> third_party
- extension/tests -> tests/port, libgr2/tests -> tests/gr2
- android-native -> android (build.sh, push-client.sh moved in)
- script -> scripts; tools/40250 -> tools/server; oracle -> tools/granny-oracle;
perf tools -> tools/perf
- all build trees under build/ (native, release, android, port-gate)
- xrender:: CMake aliases -> mt::; port-map ledger impl paths rewritten
No code changes. ctest 15/15, port_gate macos+android PASS, port_map check 0 errors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
70710477cf
commit
a46093104c
@@ -0,0 +1,23 @@
|
||||
// Platform skeleton for UserInterface/ProcessCRC.h (40250 UserInterface/ProcessCRC.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "UserInterface/StdAfx.h"
|
||||
#include "UserInterface/ProcessCRC.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
auto GetExeCRC(DWORD &, DWORD &) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto BuildProcessCRC() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto GetProcessCRCMagicCubePiece() -> BYTE
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<BYTE>();
|
||||
}
|
||||
@@ -0,0 +1,777 @@
|
||||
#include "UserInterface/StdAfx.h"
|
||||
#include "UserInterface/PythonApplication.h"
|
||||
#include "UserInterface/MarkManager.h"
|
||||
#include "GameLib/GameUtil.h"
|
||||
#include "EterLib/Camera.h"
|
||||
#include "EterBase/Timer.h"
|
||||
#include "EterLib/ResourceManager.h"
|
||||
#include "UserInterface/PythonNetworkStream.h"
|
||||
#include "UserInterface/AccountConnector.h"
|
||||
#include "UserInterface/PythonItem.h"
|
||||
#include "UserInterface/PythonTextTail.h"
|
||||
#include "UserInterface/PythonSkill.h"
|
||||
#include "UserInterface/PythonNonPlayer.h"
|
||||
#include "GameLib/ItemManager.h"
|
||||
#include "EterLib/NetDevice.h"
|
||||
#include "../PlatformStub.h"
|
||||
#include "../EterLib/UIRenderCommands.h"
|
||||
#include "../EterLib/RenderCommands3D.h"
|
||||
#include "EterLib/GrpDevice.h"
|
||||
#include "EterGrnLib/LODController.h"
|
||||
#include "UserInterface/PythonBackground.h"
|
||||
#include "UserInterface/PythonSystem.h"
|
||||
#include "../ScriptLib/PythonBoot.h"
|
||||
#include "ServerClock.h"
|
||||
#include "../EterBase/PerfCounters.h"
|
||||
|
||||
#if defined(__linux__) || defined(__ANDROID__)
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
// 2V0-d link surface; 2V0-f adds the application lifecycle (Create/Loop/Process/Exit) that
|
||||
// prototype.RunApp() drives. The rest of the members still wait for the game slices (2V1-2V3).
|
||||
//
|
||||
// PORT: there is no CPythonApplication object yet (its members are the whole game: background,
|
||||
// network stream, player, ...), so these functions only use the singletons PythonBoot owns
|
||||
alignas(alignof(CPythonApplication)) static char s_app_storage[sizeof(CPythonApplication)] = {};
|
||||
CPythonApplication* CPythonApplication::ms_pInstance = reinterpret_cast<CPythonApplication*>(s_app_storage);
|
||||
extern double g_specularSpd;
|
||||
|
||||
void CPythonApplication::ShowWebPage(const char*, const RECT&) { MT_PLATFORM_STUB(); }
|
||||
void CPythonApplication::MoveWebPage(const RECT&) { MT_PLATFORM_STUB(); }
|
||||
void CPythonApplication::HideWebPage() { MT_PLATFORM_STUB(); }
|
||||
bool CPythonApplication::IsWebPageMode() { MT_PLATFORM_STUB(); return false; }
|
||||
void CPythonApplication::GetInfo(UINT, std::string* out) { MT_PLATFORM_STUB(); if (out) out->clear(); }
|
||||
// In 40250, Loop() is: while (1) { if (IsMessage()) { if (!MessageProcess()) break; } else { if (!Process()) break; } }
|
||||
// PORT: Godot owns the message pump and forwards input to the window manager between frames
|
||||
// (PythonBoot::UIMouseMove & co.), so the loop here only waits for the host's next frame. It runs
|
||||
// on PythonBoot's script thread; WM_QUIT is PythonBoot::AppRequestQuit.
|
||||
void CPythonApplication::Loop()
|
||||
{
|
||||
while (PythonBoot::AppLoopWait())
|
||||
{
|
||||
if (!Process())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// In 40250 this is PostQuitMessage(0).
|
||||
void CPythonApplication::Exit() { PythonBoot::AppRequestQuit(); }
|
||||
|
||||
// 40250 also writes a TraceError banner first; the caller (system.py) has already logged the reason.
|
||||
void CPythonApplication::Abort()
|
||||
{
|
||||
TraceError("============================================================================================================");
|
||||
TraceError("Abort!!!!\n\n");
|
||||
PythonBoot::AppRequestQuit();
|
||||
}
|
||||
static float MIN_FOG = 2400.0f;
|
||||
void CPythonApplication::SetMinFog(float fMinFog) { MIN_FOG = fMinFog; }
|
||||
// In 40250 Process() copies CTimer::GetCurrentSecond() into m_fGlobalTime right after Advance() and
|
||||
// this returns it. PORT: no member to hold it; the timer only advances in Process(), so reading it
|
||||
// here gives the same value.
|
||||
float CPythonApplication::GetGlobalTime() { return CTimer::Instance().GetCurrentSecond(); }
|
||||
// In 40250 Process() also copies CTimer::GetElapsedSecond() into m_fGlobalElapsedTime (PythonApplication.cpp:448).
|
||||
// PORT: read straight from the timer, as GetGlobalTime above.
|
||||
float CPythonApplication::GetGlobalElapsedTime() { return CTimer::Instance().GetElapsedSecond(); }
|
||||
static bool s_isFrameSkipDisable = false;
|
||||
// m_iForceSightRange (the 40250 constructor sets -1: automatic sight range).
|
||||
static int s_iForceSightRange = -1;
|
||||
static float s_nativeRenderFrameTime = 0.0f;
|
||||
void PythonBoot::SetNativeRenderFrameTime(float milliseconds) { s_nativeRenderFrameTime = milliseconds; }
|
||||
void CPythonApplication::SetFrameSkip(bool isEnable) { s_isFrameSkipDisable = !isEnable; }
|
||||
// PORT: 40250 creates the Win32 window, the D3D8 device, cursors, sound, keyboard, the net device,
|
||||
// fonts and the IME here. The Godot window and its canvas already exist when the host starts the
|
||||
// script, so the window size is the canvas size (PythonBoot::SetUISize) rather than the width/height
|
||||
// passed from metin2.cfg, and the graphic device is the recording device (RecordingDevice.h) at that
|
||||
// size. Cursors, sound, keyboard and fonts are not created here yet.
|
||||
bool CPythonApplication::Create(PyObject*, const char*, int, int, int)
|
||||
{
|
||||
unsigned width = 0, height = 0;
|
||||
UIRenderGetSize(&width, &height);
|
||||
if (!width || !height)
|
||||
{
|
||||
// appCreate returns NULL on failure; RunApp turns this into the original LogBox.
|
||||
TraceError("CreateDevice: GraphicDevice create failed");
|
||||
PyErr_SetString(PyExc_RuntimeError, "CREATE_DEVICE");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:1196-1199.
|
||||
extern bool GRAPHICS_CAPS_SOFTWARE_TILING;
|
||||
|
||||
if (!CPythonSystem::Instance().IsAutoTiling())
|
||||
GRAPHICS_CAPS_SOFTWARE_TILING = CPythonSystem::Instance().IsSoftwareTiling();
|
||||
|
||||
// In 40250 m_grpDevice is a member created here (PythonApplication.cpp:909).
|
||||
static CGraphicDevice s_grpDevice;
|
||||
int iRet = s_grpDevice.Create(NULL, width, height, true, 32, 0);
|
||||
|
||||
switch (iRet)
|
||||
{
|
||||
case CGraphicDevice::CREATE_OK:
|
||||
break;
|
||||
|
||||
case CGraphicDevice::CREATE_REFRESHRATE:
|
||||
break;
|
||||
|
||||
case CGraphicDevice::CREATE_GET_DEVICE_CAPS:
|
||||
PyErr_SetString(PyExc_RuntimeError, "GetDevCaps failed");
|
||||
TraceError("CreateDevice: GetDevCaps failed");
|
||||
return false;
|
||||
|
||||
case CGraphicDevice::CREATE_GET_DEVICE_CAPS2:
|
||||
PyErr_SetString(PyExc_RuntimeError, "GetDevCaps2 failed");
|
||||
TraceError("CreateDevice: GetDevCaps2 failed");
|
||||
return false;
|
||||
|
||||
default:
|
||||
// PORT: the recording device returns only the cases above; the rest is 40250's fallback.
|
||||
if (iRet & CGraphicDevice::CREATE_OK)
|
||||
break;
|
||||
|
||||
TraceError("CreateDevice: Unknown Error!");
|
||||
PyErr_SetString(PyExc_RuntimeError, "UNKNOWN_ERROR");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:1206-1220.
|
||||
if (CPythonSystem::Instance().IsAutoTiling())
|
||||
{
|
||||
if (s_grpDevice.IsFastTNL())
|
||||
{
|
||||
CPythonBackground::Instance().ReserveSoftwareTilingEnable(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
CPythonBackground::Instance().ReserveSoftwareTilingEnable(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CPythonBackground::Instance().ReserveSoftwareTilingEnable(CPythonSystem::Instance().IsSoftwareTiling());
|
||||
}
|
||||
|
||||
// In 40250 m_netDevice is a member created here (PythonApplication.cpp:1242).
|
||||
static CNetworkDevice s_netDevice;
|
||||
if (!s_netDevice.Create())
|
||||
{
|
||||
TraceError("NetDevice::Create failed");
|
||||
PyErr_SetString(PyExc_RuntimeError, "CREATE_NETWORK");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:1250-1251.
|
||||
if (!s_grpDevice.IsFastTNL())
|
||||
CGrannyLODController::SetMinLODMode(true);
|
||||
|
||||
// 40250 m_pyItem.Create() (PythonApplication.cpp:1253): registers dropitem.mse with CEffectManager.
|
||||
CPythonItem::Instance().Create();
|
||||
|
||||
// 40250 PythonApplication.cpp:1258-1259 (after DefaultFont_Startup).
|
||||
CPythonIME::Instance().Create(GetWindowHandle());
|
||||
CPythonIME::Instance().SetText("", 0);
|
||||
|
||||
// 40250 PythonApplication.cpp:1260.
|
||||
CPythonTextTail::Instance().Initialize();
|
||||
|
||||
// 40250 PythonApplication.cpp:1262-1263.
|
||||
// Light Manager
|
||||
m_LightManager.Initialize();
|
||||
|
||||
if (IsNativeTerrainRenderEnabled())
|
||||
{
|
||||
const bool use_hardware_cursor = PythonBoot::HostHardwareCursorEnabled() || PythonBoot::TouchInput();
|
||||
if (CPythonSystem::InstancePtr() && CPythonSystem::Instance().GetConfig())
|
||||
CPythonSystem::Instance().GetConfig()->is_software_cursor = !use_hardware_cursor;
|
||||
SetCursorMode(use_hardware_cursor ? CURSOR_MODE_HARDWARE : CURSOR_MODE_SOFTWARE);
|
||||
CGrannyMaterial::CreateSphereMap(0, "d:/ymir work/special/spheremap.jpg");
|
||||
CGrannyMaterial::CreateSphereMap(1, "d:/ymir work/special/spheremap01.jpg");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// 40250 PythonApplication.cpp:105
|
||||
void CPythonApplication::GetMousePosition(POINT* ppt)
|
||||
{
|
||||
CMSApplication::GetMousePosition(ppt);
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:168, the !PERF_CHECKER_RENDER_GAME branch (the profiling copy below it
|
||||
// only adds timers). game.GameWindow.OnRender calls it every frame.
|
||||
// PORT: the members are reached through their singletons (see the note at the top of the file).
|
||||
void CPythonApplication::RenderGame()
|
||||
{
|
||||
MtPerf::CScope kPerf(MtPerf::SECTION_RENDER_GAME);
|
||||
float fAspect=UI::CWindowManager::Instance().GetAspect();
|
||||
float fFarClip=CPythonBackground::Instance().GetFarClip();
|
||||
|
||||
CPythonGraphic::Instance().SetPerspective(30.0f, fAspect, 100.0, fFarClip);
|
||||
|
||||
CCullingManager::Instance().Process();
|
||||
|
||||
CPythonCharacterManager::Instance().Deform();
|
||||
CEffectManager::Instance().Update();
|
||||
|
||||
CPythonBackground::Instance().RenderCharacterShadowToTexture();
|
||||
|
||||
CPythonGraphic::Instance().SetGameRenderState();
|
||||
CPythonGraphic::Instance().PushState();
|
||||
|
||||
{
|
||||
long lx, ly;
|
||||
UI::CWindowManager::Instance().GetMousePosition(lx, ly);
|
||||
// PORT: window coordinates -> the screen coordinates of the full-width 3D view.
|
||||
lx += UI::CWindowManager::Instance().GetScreenOffsetX();
|
||||
CPythonGraphic::Instance().SetCursorPosition(lx, ly);
|
||||
}
|
||||
|
||||
CPythonBackground::Instance().RenderSky();
|
||||
|
||||
CPythonBackground::Instance().RenderBeforeLensFlare();
|
||||
|
||||
CPythonBackground::Instance().RenderCloud();
|
||||
|
||||
CPythonBackground::Instance().BeginEnvironment();
|
||||
CPythonBackground::Instance().Render();
|
||||
|
||||
CPythonBackground::Instance().SetCharacterDirLight();
|
||||
CPythonCharacterManager::Instance().Render();
|
||||
|
||||
CPythonBackground::Instance().SetBackgroundDirLight();
|
||||
CPythonBackground::Instance().RenderWater();
|
||||
CPythonBackground::Instance().RenderSnow();
|
||||
CPythonBackground::Instance().RenderEffect();
|
||||
|
||||
CPythonBackground::Instance().EndEnvironment();
|
||||
|
||||
CEffectManager::Instance().Render();
|
||||
CPythonItem::Instance().Render();
|
||||
CFlyingManager::Instance().Render();
|
||||
|
||||
CPythonBackground::Instance().BeginEnvironment();
|
||||
CPythonBackground::Instance().RenderPCBlocker();
|
||||
CPythonBackground::Instance().EndEnvironment();
|
||||
|
||||
CPythonBackground::Instance().RenderAfterLensFlare();
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:321 without the PERF_CHECKER_RENDER_GAME timers. game.GameWindow.OnUpdate
|
||||
// calls it every frame. PORT: members through their singletons, as in RenderGame.
|
||||
void CPythonApplication::UpdateGame()
|
||||
{
|
||||
MtPerf::CScope kPerf(MtPerf::SECTION_UPDATE_GAME);
|
||||
POINT ptMouse;
|
||||
GetMousePosition(&ptMouse);
|
||||
|
||||
CGraphicTextInstance::Hyperlink_UpdateMousePos(ptMouse.x, ptMouse.y);
|
||||
|
||||
//!@# Alt+Tab 중 SetTransfor 에서 튕김 현상 해결을 위해 - [levites]
|
||||
//if (m_isActivateWnd)
|
||||
{
|
||||
CScreen s;
|
||||
float fAspect = UI::CWindowManager::Instance().GetAspect();
|
||||
float fFarClip = CPythonBackground::Instance().GetFarClip();
|
||||
|
||||
s.SetPerspective(30.0f,fAspect, 100.0f, fFarClip);
|
||||
s.BuildViewFrustum();
|
||||
}
|
||||
|
||||
TPixelPosition kPPosMainActor;
|
||||
CPythonPlayer::Instance().NEW_GetMainActorPosition(&kPPosMainActor);
|
||||
|
||||
CPythonBackground::Instance().Update(kPPosMainActor.x, kPPosMainActor.y, kPPosMainActor.z);
|
||||
|
||||
CGameEventManager::Instance().SetCenterPosition(kPPosMainActor.x, kPPosMainActor.y, kPPosMainActor.z);
|
||||
CGameEventManager::Instance().Update();
|
||||
|
||||
CPythonCharacterManager::Instance().Update();
|
||||
CEffectManager::Instance().UpdateSound();
|
||||
CFlyingManager::Instance().Update();
|
||||
CPythonItem::Instance().Update(ptMouse);
|
||||
CPythonPlayer::Instance().Update();
|
||||
|
||||
// NOTE : Update 에서 위치 값이 바뀌므로 다시 얻어 옵니다 - [levites]
|
||||
// 이 부분 때문에 메인 케릭터의 Sound가 이전 위치에서 플레이 되는 현상이 있었음.
|
||||
CPythonPlayer::Instance().NEW_GetMainActorPosition(&kPPosMainActor);
|
||||
SetCenterPosition(kPPosMainActor.x, kPPosMainActor.y, kPPosMainActor.z);
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:399. Kept in order: timer, network (2V1), input polling (Godot pushes
|
||||
// input instead), camera (2V3), resource GC, mouse/UI update, then the render block's interface pass.
|
||||
// PORT: the frame-skip bookkeeping and the game render pass are left out; the Godot frame clock
|
||||
// decides when this runs, and RenderGame belongs to 2V3.
|
||||
// PORT: telemetry for --perf-log (platform/EterBase/PerfCounters.h); 40250 has no counterpart.
|
||||
static void __PerfSampleWorld()
|
||||
{
|
||||
if (!MtPerf::Enabled())
|
||||
return;
|
||||
MtPerf::SCounters& rkCounters = MtPerf::Counters();
|
||||
CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance();
|
||||
int iActors = 0;
|
||||
for (CPythonCharacterManager::CharacterIterator i = rkChrMgr.CharacterInstanceBegin(); i != rkChrMgr.CharacterInstanceEnd(); ++i)
|
||||
++iActors;
|
||||
rkCounters.actorCount = iActors;
|
||||
#if defined(__linux__) || defined(__ANDROID__)
|
||||
rkCounters.scriptCpu = sched_getcpu();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CPythonApplication::Process()
|
||||
{
|
||||
MtPerf::CScope kPerfProcess(MtPerf::SECTION_PROCESS);
|
||||
__PerfSampleWorld();
|
||||
ELTimer_SetFrameMSec();
|
||||
|
||||
CTimer& rkTimer=CTimer::Instance();
|
||||
rkTimer.Advance();
|
||||
|
||||
// Network I/O
|
||||
{
|
||||
MtPerf::CScope kPerf(MtPerf::SECTION_NETWORK);
|
||||
CPythonNetworkStream::Instance().Process();
|
||||
// PORT: m_kGuildMarkUploader/m_kGuildMarkDownloader.Process() follow here in 40250; the guild mark
|
||||
// transfer is not ported yet (GuildMarkDownloader.cpp/GuildMarkUploader.cpp).
|
||||
CAccountConnector::Instance().Process();
|
||||
}
|
||||
|
||||
{
|
||||
MtPerf::CScope kPerf(MtPerf::SECTION_CAMERA);
|
||||
//!@# Alt+Tab 중 SetTransfor 에서 튕김 현상 해결을 위해 - [levites]
|
||||
//if (m_isActivateWnd)
|
||||
__UpdateCamera();
|
||||
|
||||
CResourceManager::Instance().Update();
|
||||
|
||||
OnCameraUpdate();
|
||||
if (IsNativeTerrainRenderEnabled())
|
||||
OnMouseUpdate();
|
||||
}
|
||||
{
|
||||
MtPerf::CScope kPerf(MtPerf::SECTION_UI_UPDATE);
|
||||
OnUIUpdate();
|
||||
}
|
||||
|
||||
if (IsNativeTerrainRenderEnabled())
|
||||
CGrannyMaterial::TranslateSpecularMatrix(g_specularSpd, g_specularSpd, 0.0f);
|
||||
|
||||
// PORT: the render block without the lost-device restore, ClearDepthBuffer and Show (Godot clears
|
||||
// and presents the frame), and without the !IsActive() SkipRenderBuffering(3000): the host has no
|
||||
// Win32 activation (CMSWindow::IsActive is a stub). The frame's UI and 3D command lists restart here.
|
||||
// 40250 PythonApplication.cpp:681.
|
||||
DWORD dwRenderStartTime = ELTimer_GetMSec();
|
||||
{
|
||||
MtPerf::CScope kPerf(MtPerf::SECTION_RENDER_BEGIN);
|
||||
CCullingManager::Instance().Update();
|
||||
UIRenderBeginFrame();
|
||||
Render3DBeginFrame();
|
||||
}
|
||||
CPythonGraphic& rkGraphic = CPythonGraphic::Instance();
|
||||
if (rkGraphic.Begin())
|
||||
{
|
||||
rkGraphic.SetInterfaceRenderState();
|
||||
|
||||
{
|
||||
MtPerf::CScope kPerf(MtPerf::SECTION_UI_RENDER);
|
||||
OnUIRender();
|
||||
if (IsNativeTerrainRenderEnabled())
|
||||
{
|
||||
rkGraphic.SetInterfaceRenderState();
|
||||
unsigned cw = 0, ch = 0;
|
||||
UIRenderGetSize(&cw, &ch);
|
||||
UIRenderSetClip(0.0f, 0.0f, float(cw), float(ch));
|
||||
OnMouseRender();
|
||||
}
|
||||
}
|
||||
|
||||
rkGraphic.End();
|
||||
|
||||
// 40250 PythonApplication.cpp:741-842 (render time, face count, automatic sight range), minus the
|
||||
// per-second FPS/face counters and the windowed dwBufRenderTime rounding, whose result 40250 never
|
||||
// uses (its Sleep is commented out).
|
||||
DWORD dwRenderEndTime = ELTimer_GetMSec();
|
||||
|
||||
static DWORD s_dwRenderCheckTime = dwRenderEndTime;
|
||||
static DWORD s_dwRenderRangeTime = 0;
|
||||
static DWORD s_dwRenderRangeFrame = 0;
|
||||
|
||||
// The native host completes Vulkan work after this command-recording pass.
|
||||
// Use its last completed frame, including presentation, for automatic sight range.
|
||||
m_dwCurRenderTime = s_nativeRenderFrameTime > 0.0f
|
||||
? static_cast<DWORD>(s_nativeRenderFrameTime + 0.5f)
|
||||
: dwRenderEndTime - dwRenderStartTime;
|
||||
s_dwRenderRangeTime += m_dwCurRenderTime;
|
||||
++s_dwRenderRangeFrame;
|
||||
|
||||
if (dwRenderEndTime-s_dwRenderCheckTime>1000)
|
||||
{
|
||||
m_fAveRenderTime=float(double(s_dwRenderRangeTime)/double(s_dwRenderRangeFrame));
|
||||
|
||||
s_dwRenderCheckTime=ELTimer_GetMSec();
|
||||
s_dwRenderRangeTime=0;
|
||||
s_dwRenderRangeFrame=0;
|
||||
}
|
||||
|
||||
DWORD dwCurFaceCount=rkGraphic.GetFaceCount();
|
||||
rkGraphic.ResetFaceCount();
|
||||
|
||||
if (dwCurFaceCount > 5000)
|
||||
{
|
||||
// 프레임 완충 처리
|
||||
if (dwRenderEndTime > m_dwBufSleepSkipTime)
|
||||
{
|
||||
static float s_fBufRenderTime = 0.0f;
|
||||
|
||||
float fCurRenderTime = m_dwCurRenderTime;
|
||||
|
||||
if (fCurRenderTime > s_fBufRenderTime)
|
||||
{
|
||||
float fRatio = fMAX(0.5f, (fCurRenderTime - s_fBufRenderTime) / 30.0f);
|
||||
s_fBufRenderTime = (s_fBufRenderTime * (100.0f - fRatio) + (fCurRenderTime + 5) * fRatio) / 100.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float fRatio = 0.5f;
|
||||
s_fBufRenderTime = (s_fBufRenderTime * (100.0f - fRatio) + fCurRenderTime * fRatio) / 100.0f;
|
||||
}
|
||||
|
||||
// 한계치를 정한다
|
||||
if (s_fBufRenderTime > 100.0f)
|
||||
s_fBufRenderTime = 100.0f;
|
||||
|
||||
m_fAveRenderTime=s_fBufRenderTime;
|
||||
}
|
||||
|
||||
m_dwFaceAccCount += dwCurFaceCount;
|
||||
m_dwFaceAccTime += m_dwCurRenderTime;
|
||||
|
||||
// PORT: recording a frame can take under 1 ms, so the integer division is guarded (40250's
|
||||
// D3D frame never took 0 ms).
|
||||
if (m_dwFaceAccTime)
|
||||
m_fFaceSpd=(m_dwFaceAccCount/m_dwFaceAccTime);
|
||||
|
||||
// 거리 자동 조절
|
||||
if (-1 == s_iForceSightRange)
|
||||
{
|
||||
static float s_fAveRenderTime = 16.0f;
|
||||
float fRatio=0.3f;
|
||||
s_fAveRenderTime=(s_fAveRenderTime*(100.0f-fRatio)+max(16.0f, m_dwCurRenderTime)*fRatio)/100.0f;
|
||||
|
||||
|
||||
float fFar=25600.0f;
|
||||
float fNear=MIN_FOG;
|
||||
double dbAvePow=double(1000.0f/s_fAveRenderTime);
|
||||
double dbMaxPow=60.0;
|
||||
float fDistance=max(fNear+(fFar-fNear)*(dbAvePow)/dbMaxPow, fNear);
|
||||
CPythonBackground::Instance().SetViewDistanceSet(0, fDistance);
|
||||
}
|
||||
// 거리 강제 설정시
|
||||
else
|
||||
{
|
||||
CPythonBackground::Instance().SetViewDistanceSet(0, float(s_iForceSightRange));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 10000 폴리곤 보다 적을때는 가장 멀리 보이게 한다
|
||||
CPythonBackground::Instance().SetViewDistanceSet(0, 25600.0f);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 40250 PythonApplicationCursor.cpp. PORT: the members live here until the application object exists
|
||||
// (initial values from the constructor and CreateCursors); the host draws no hardware cursor, so every
|
||||
// shape in [0, CURSOR_COUNT) counts as loaded in place of m_CursorHandleMap.
|
||||
PyObject* s_poMouseHandler = NULL; // m_poMouseHandler
|
||||
namespace
|
||||
{
|
||||
int s_iCursorNum = CPythonApplication::CURSOR_SHAPE_NORMAL; // m_iCursorNum
|
||||
int s_iContinuousCursorNum = CPythonApplication::CURSOR_SHAPE_NORMAL; // m_iContinuousCursorNum
|
||||
BOOL s_bCursorVisible = TRUE; // m_bCursorVisible
|
||||
bool s_bLiarCursorOn = false; // m_bLiarCursorOn
|
||||
int s_iCursorMode = CPythonApplication::CURSOR_MODE_HARDWARE; // m_iCursorMode
|
||||
}
|
||||
|
||||
void CPythonApplication::SetCursorVisible(BOOL bFlag, bool bLiarCursorOn)
|
||||
{
|
||||
s_bCursorVisible = bFlag;
|
||||
// PORT: a touch screen has no cursor, not even the stand-in 40250 draws while the real one is hidden.
|
||||
s_bLiarCursorOn = bLiarCursorOn && !PythonBoot::TouchInput();
|
||||
// PORT: 40250 also counts ShowCursor up or down in hardware mode; the host has no OS cursor to hide.
|
||||
}
|
||||
|
||||
BOOL CPythonApplication::GetCursorVisible()
|
||||
{
|
||||
return s_bCursorVisible;
|
||||
}
|
||||
|
||||
bool CPythonApplication::GetLiarCursorOn()
|
||||
{
|
||||
return s_bLiarCursorOn;
|
||||
}
|
||||
|
||||
int CPythonApplication::GetCursorMode()
|
||||
{
|
||||
return s_iCursorMode;
|
||||
}
|
||||
|
||||
int CPythonApplication::GetCursorNum()
|
||||
{
|
||||
return s_iCursorNum;
|
||||
}
|
||||
|
||||
BOOL CPythonApplication::__IsContinuousChangeTypeCursor(int iCursorNum)
|
||||
{
|
||||
switch (iCursorNum)
|
||||
{
|
||||
case CURSOR_SHAPE_NORMAL:
|
||||
case CURSOR_SHAPE_ATTACK:
|
||||
case CURSOR_SHAPE_TARGET:
|
||||
case CURSOR_SHAPE_MAGIC:
|
||||
case CURSOR_SHAPE_BUY:
|
||||
case CURSOR_SHAPE_SELL:
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CPythonApplication::SetCursorNum(int iCursorNum)
|
||||
{
|
||||
if (CURSOR_SHAPE_NORMAL == iCursorNum)
|
||||
{
|
||||
if (!__IsContinuousChangeTypeCursor(s_iCursorNum))
|
||||
{
|
||||
iCursorNum = s_iContinuousCursorNum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__IsContinuousChangeTypeCursor(s_iCursorNum))
|
||||
{
|
||||
s_iContinuousCursorNum = s_iCursorNum;
|
||||
}
|
||||
}
|
||||
|
||||
if (CURSOR_MODE_HARDWARE == s_iCursorMode)
|
||||
{
|
||||
// PORT: m_CursorHandleMap.find(iCursorNum) and SetCursor(hCursor).
|
||||
if (iCursorNum < 0 || iCursorNum >= CURSOR_COUNT)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s_iCursorNum = iCursorNum;
|
||||
|
||||
PyCallClassMemberFunc(s_poMouseHandler, "ChangeCursor", Py_BuildValue("(i)", s_iCursorNum));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CPythonApplication::SetCursorMode(int iMode)
|
||||
{
|
||||
switch (iMode)
|
||||
{
|
||||
case CURSOR_MODE_HARDWARE:
|
||||
s_iCursorMode = CURSOR_MODE_HARDWARE;
|
||||
break;
|
||||
|
||||
case CURSOR_MODE_SOFTWARE:
|
||||
s_iCursorMode = CURSOR_MODE_SOFTWARE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:871.
|
||||
void CPythonApplication::SetMouseHandler(PyObject* poMouseHandler)
|
||||
{
|
||||
s_poMouseHandler = poMouseHandler;
|
||||
}
|
||||
void CPythonApplication::SetGlobalCenterPosition(LONG x, LONG y)
|
||||
{
|
||||
// 40250 PythonApplication.cpp:1284: the background owns the global-to-local map offset.
|
||||
CPythonBackground& background = CPythonBackground::Instance();
|
||||
background.GlobalPositionToLocalPosition(x, y);
|
||||
SetCenterPosition(x, y, background.GetHeight(x, y));
|
||||
}
|
||||
void CPythonApplication::SetFPS(int) {}
|
||||
namespace {
|
||||
DWORD s_server_start_msec = 0;
|
||||
time_t s_server_time = 0;
|
||||
time_t s_local_start_time = 0;
|
||||
}
|
||||
|
||||
void SetPlatformServerTime(time_t server_time)
|
||||
{
|
||||
s_server_start_msec = ELTimer_GetMSec();
|
||||
s_server_time = server_time;
|
||||
s_local_start_time = time(nullptr);
|
||||
}
|
||||
|
||||
time_t GetPlatformServerTime()
|
||||
{
|
||||
return static_cast<time_t>(ELTimer_GetMSec() - s_server_start_msec) + s_server_time;
|
||||
}
|
||||
|
||||
time_t GetPlatformServerTimeStamp()
|
||||
{
|
||||
return (time(nullptr) - s_local_start_time) + s_server_time;
|
||||
}
|
||||
|
||||
void CPythonApplication::SetServerTime(time_t server_time) { SetPlatformServerTime(server_time); }
|
||||
time_t CPythonApplication::GetServerTime() { return GetPlatformServerTime(); }
|
||||
time_t CPythonApplication::GetServerTimeStamp() { return GetPlatformServerTimeStamp(); }
|
||||
void CPythonApplication::SetConnectData(const char*, int) { MT_PLATFORM_STUB(); }
|
||||
void CPythonApplication::GetConnectData(std::string& ip, int& port) { MT_PLATFORM_STUB(); ip.clear(); port = 0; }
|
||||
// 40250 PythonApplication.cpp:1377.
|
||||
void CPythonApplication::SetForceSightRange(int iRange)
|
||||
{
|
||||
s_iForceSightRange = iRange;
|
||||
}
|
||||
|
||||
int CPythonApplication::CheckDeviceState()
|
||||
{
|
||||
return DEVICE_STATE_OK;
|
||||
}
|
||||
|
||||
bool CPythonApplication::CreateDevice(int width, int height, int Windowed, int bit, int frequency)
|
||||
{
|
||||
static CGraphicDevice s_grpDevice;
|
||||
return s_grpDevice.Create(NULL, width, height, Windowed ? true : false, bit, frequency) == CGraphicDevice::CREATE_OK;
|
||||
}
|
||||
|
||||
void CPythonApplication::NotifyHack(const char* c_szFormat, ...)
|
||||
{
|
||||
char szBuf[1024];
|
||||
va_list args;
|
||||
va_start(args, c_szFormat);
|
||||
vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args);
|
||||
va_end(args);
|
||||
CPythonNetworkStream::Instance().NotifyHack(szBuf);
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:394
|
||||
void CPythonApplication::SkipRenderBuffering(DWORD dwSleepMSec)
|
||||
{
|
||||
m_dwBufSleepSkipTime=ELTimer_GetMSec()+dwSleepMSec;
|
||||
}
|
||||
|
||||
void CPythonApplication::UpdateClientRect()
|
||||
{
|
||||
unsigned w = 0, h = 0;
|
||||
UIRenderGetSize(&w, &h);
|
||||
UI::CWindowManager::Instance().SetResolution(w, h);
|
||||
}
|
||||
|
||||
int CPythonApplication::GetWidth()
|
||||
{
|
||||
unsigned w = 0, h = 0;
|
||||
UIRenderGetSize(&w, &h);
|
||||
return (int)w;
|
||||
}
|
||||
|
||||
int CPythonApplication::GetHeight()
|
||||
{
|
||||
unsigned w = 0, h = 0;
|
||||
UIRenderGetSize(&w, &h);
|
||||
return (int)h;
|
||||
}
|
||||
|
||||
void CPythonApplication::Clear()
|
||||
{
|
||||
CPythonSystem::Instance().Clear();
|
||||
}
|
||||
|
||||
void CPythonApplication::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
void CMovieMan::PlayLogo(const char*) { MT_PLATFORM_STUB(); }
|
||||
|
||||
BOOL PERF_CHECKER_RENDER_GAME = FALSE;
|
||||
double g_specularSpd = 0;
|
||||
|
||||
// 40250 UserInterface/PythonApplication.cpp, verbatim.
|
||||
// SUPPORT_NEW_KOREA_SERVER
|
||||
bool LoadLocaleData(const char* localePath)
|
||||
{
|
||||
NANOBEGIN
|
||||
CPythonNonPlayer& rkNPCMgr = CPythonNonPlayer::Instance();
|
||||
CItemManager& rkItemMgr = CItemManager::Instance();
|
||||
CPythonSkill& rkSkillMgr = CPythonSkill::Instance();
|
||||
CPythonNetworkStream& rkNetStream = CPythonNetworkStream::Instance();
|
||||
|
||||
char szItemList[256];
|
||||
char szItemProto[256];
|
||||
char szItemDesc[256];
|
||||
char szMobProto[256];
|
||||
char szSkillDescFileName[256];
|
||||
char szSkillTableFileName[256];
|
||||
char szInsultList[256];
|
||||
snprintf(szItemList, sizeof(szItemList) , "%s/item_list.txt", localePath);
|
||||
snprintf(szItemProto, sizeof(szItemProto), "%s/item_proto", localePath);
|
||||
snprintf(szItemDesc, sizeof(szItemDesc), "%s/itemdesc.txt", localePath);
|
||||
snprintf(szMobProto, sizeof(szMobProto), "%s/mob_proto", localePath);
|
||||
snprintf(szSkillDescFileName, sizeof(szSkillDescFileName), "%s/SkillDesc.txt", localePath);
|
||||
snprintf(szSkillTableFileName, sizeof(szSkillTableFileName), "%s/SkillTable.txt", localePath);
|
||||
snprintf(szInsultList, sizeof(szInsultList), "%s/insult.txt", localePath);
|
||||
|
||||
rkNPCMgr.Destroy();
|
||||
rkItemMgr.Destroy();
|
||||
rkSkillMgr.Destroy();
|
||||
|
||||
if (!rkItemMgr.LoadItemList(szItemList))
|
||||
{
|
||||
TraceError("LoadLocaleData - LoadItemList(%s) Error", szItemList);
|
||||
}
|
||||
|
||||
if (!rkItemMgr.LoadItemTable(szItemProto))
|
||||
{
|
||||
TraceError("LoadLocaleData - LoadItemProto(%s) Error", szItemProto);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rkItemMgr.LoadItemDesc(szItemDesc))
|
||||
{
|
||||
Tracenf("LoadLocaleData - LoadItemDesc(%s) Error", szItemDesc);
|
||||
}
|
||||
|
||||
if (!rkNPCMgr.LoadNonPlayerData(szMobProto))
|
||||
{
|
||||
TraceError("LoadLocaleData - LoadMobProto(%s) Error", szMobProto);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rkSkillMgr.RegisterSkillDesc(szSkillDescFileName))
|
||||
{
|
||||
TraceError("LoadLocaleData - RegisterSkillDesc(%s) Error", szMobProto);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rkSkillMgr.RegisterSkillTable(szSkillTableFileName))
|
||||
{
|
||||
TraceError("LoadLocaleData - RegisterSkillTable(%s) Error", szMobProto);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rkNetStream.LoadInsultList(szInsultList))
|
||||
{
|
||||
Tracenf("CPythonApplication - CPythonNetworkStream::LoadInsultList(%s)", szInsultList);
|
||||
}
|
||||
|
||||
if (LocaleService_IsYMIR())
|
||||
{
|
||||
char szEmpireTextConvFile[256];
|
||||
for (DWORD dwEmpireID=1; dwEmpireID<=3; ++dwEmpireID)
|
||||
{
|
||||
sprintf(szEmpireTextConvFile, "%s/lang%d.cvt", localePath, dwEmpireID);
|
||||
if (!rkNetStream.LoadConvertTable(dwEmpireID, szEmpireTextConvFile))
|
||||
{
|
||||
TraceError("LoadLocaleData - CPythonNetworkStream::LoadConvertTable(%d, %s) FAILURE", dwEmpireID, szEmpireTextConvFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NANOEND
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,478 @@
|
||||
// 40250 UserInterface/PythonApplicationCamera.cpp plus the camera members' other functions in
|
||||
// PythonApplication.cpp (SetCenterPosition, EnableSpecialCameraMode, SetCameraSpeed).
|
||||
// PORT: there is no CPythonApplication object (see PythonApplication.cpp), so the camera members live
|
||||
// in s_app below with 40250's names and constructor values, and m_pyGraphic is CPythonGraphic::Instance().
|
||||
#include "UserInterface/StdAfx.h"
|
||||
#include "UserInterface/PythonApplication.h"
|
||||
|
||||
#include "EterBase/Timer.h"
|
||||
#include "EterLib/Camera.h"
|
||||
#include "EterLib/Util.h"
|
||||
#include "EterLib/TextFileLoader.h"
|
||||
|
||||
// 40250 PythonApplication.cpp:28-30
|
||||
float c_fDefaultCameraRotateSpeed = 1.5f;
|
||||
float c_fDefaultCameraPitchSpeed = 1.5f;
|
||||
float c_fDefaultCameraZoomSpeed = 0.05f;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ApplicationCamera
|
||||
{
|
||||
D3DXVECTOR3 m_v3CenterPosition{0.0f, 0.0f, 0.0f};
|
||||
|
||||
CPythonApplication::SCameraSetting m_DefaultCameraSetting;
|
||||
CPythonApplication::SCameraSetting m_kEventCameraSetting;
|
||||
|
||||
int m_iCameraMode = CPythonApplication::CAMERA_MODE_NORMAL;
|
||||
float m_fBlendCameraStartTime = 0.0f;
|
||||
float m_fBlendCameraBlendTime = 0.0f;
|
||||
CPythonApplication::SCameraSetting m_kEndBlendCameraSetting;
|
||||
|
||||
float m_fRotationSpeed = 0.0f;
|
||||
float m_fPitchSpeed = 0.0f;
|
||||
float m_fZoomSpeed = 0.0f;
|
||||
float m_fCameraRotateSpeed = c_fDefaultCameraRotateSpeed;
|
||||
float m_fCameraPitchSpeed = c_fDefaultCameraPitchSpeed;
|
||||
float m_fCameraZoomSpeed = c_fDefaultCameraZoomSpeed;
|
||||
|
||||
CPythonApplication::SCameraPos m_kCmrPos;
|
||||
CPythonApplication::SCameraSpeed m_kCmrSpd;
|
||||
|
||||
BOOL m_isSpecialCameraMode = FALSE;
|
||||
|
||||
// The constructor's CCameraManager::Instance().AddCamera(EVENT_CAMERA_NUMBER), on first use.
|
||||
ApplicationCamera() { CCameraManager::Instance().AddCamera(CPythonApplication::EVENT_CAMERA_NUMBER); }
|
||||
};
|
||||
|
||||
ApplicationCamera& app()
|
||||
{
|
||||
static ApplicationCamera s_app;
|
||||
return s_app;
|
||||
}
|
||||
}
|
||||
|
||||
float BlendValueByLinear(float fElapsedTime, float fDuration, float fBeginValue, float fEndValue)
|
||||
{
|
||||
if (fElapsedTime >= fDuration)
|
||||
return fEndValue;
|
||||
|
||||
return (fEndValue - fBeginValue) * (fElapsedTime / fDuration) + fBeginValue;
|
||||
}
|
||||
|
||||
void CPythonApplication::__UpdateCamera()
|
||||
{
|
||||
ApplicationCamera& s_app = app();
|
||||
|
||||
//////////////////////
|
||||
// Camera Setting
|
||||
CCamera * pMainCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pMainCamera)
|
||||
return;
|
||||
|
||||
if (CAMERA_MODE_BLEND == s_app.m_iCameraMode)
|
||||
{
|
||||
float fcurTime = CTimer::Instance().GetCurrentSecond();
|
||||
float fElapsedTime = fcurTime - s_app.m_fBlendCameraStartTime;
|
||||
|
||||
float fxCenter = BlendValueByLinear(fElapsedTime, s_app.m_fBlendCameraBlendTime, s_app.m_kEventCameraSetting.v3CenterPosition.x, s_app.m_kEndBlendCameraSetting.v3CenterPosition.x);
|
||||
float fyCenter = BlendValueByLinear(fElapsedTime, s_app.m_fBlendCameraBlendTime, s_app.m_kEventCameraSetting.v3CenterPosition.y, s_app.m_kEndBlendCameraSetting.v3CenterPosition.y);
|
||||
float fzCenter = BlendValueByLinear(fElapsedTime, s_app.m_fBlendCameraBlendTime, s_app.m_kEventCameraSetting.v3CenterPosition.z, s_app.m_kEndBlendCameraSetting.v3CenterPosition.z);
|
||||
|
||||
float fDistance = BlendValueByLinear(fElapsedTime, s_app.m_fBlendCameraBlendTime, s_app.m_kEventCameraSetting.fZoom, s_app.m_kEndBlendCameraSetting.fZoom);
|
||||
float fPitch = BlendValueByLinear(fElapsedTime, s_app.m_fBlendCameraBlendTime, s_app.m_kEventCameraSetting.fPitch, s_app.m_kEndBlendCameraSetting.fPitch);
|
||||
float fRotation = BlendValueByLinear(fElapsedTime, s_app.m_fBlendCameraBlendTime, s_app.m_kEventCameraSetting.fRotation, s_app.m_kEndBlendCameraSetting.fRotation);
|
||||
|
||||
float fUpDir = BlendValueByLinear(fElapsedTime, s_app.m_fBlendCameraBlendTime, s_app.m_kEventCameraSetting.kCmrPos.m_fUpDir, s_app.m_kEndBlendCameraSetting.kCmrPos.m_fUpDir);
|
||||
float fViewDir = BlendValueByLinear(fElapsedTime, s_app.m_fBlendCameraBlendTime, s_app.m_kEventCameraSetting.kCmrPos.m_fViewDir, s_app.m_kEndBlendCameraSetting.kCmrPos.m_fViewDir);
|
||||
float fCrossDir = BlendValueByLinear(fElapsedTime, s_app.m_fBlendCameraBlendTime, s_app.m_kEventCameraSetting.kCmrPos.m_fCrossDir, s_app.m_kEndBlendCameraSetting.kCmrPos.m_fCrossDir);
|
||||
|
||||
// Temporary. Have to fix that this work in camera class. - [levites]
|
||||
pMainCamera->Unlock();
|
||||
CPythonGraphic::Instance().SetPositionCamera(fxCenter, fyCenter, fzCenter, fDistance, fPitch, fRotation);
|
||||
pMainCamera->MoveVertical(fUpDir);
|
||||
pMainCamera->MoveFront(fViewDir);
|
||||
pMainCamera->MoveAlongCross(fCrossDir);
|
||||
pMainCamera->Lock();
|
||||
}
|
||||
else if (CAMERA_MODE_STAND == s_app.m_iCameraMode)
|
||||
{
|
||||
float fDistance, fPitch, fRotation, fHeight;
|
||||
GetCamera(&fDistance, &fPitch, &fRotation, &fHeight);
|
||||
CPythonGraphic::Instance().SetPositionCamera(s_app.m_kEventCameraSetting.v3CenterPosition.x,
|
||||
s_app.m_kEventCameraSetting.v3CenterPosition.y,
|
||||
s_app.m_kEventCameraSetting.v3CenterPosition.z + pMainCamera->GetTargetHeight(),
|
||||
fDistance, fPitch, fRotation);
|
||||
}
|
||||
else if (CAMERA_MODE_NORMAL == s_app.m_iCameraMode)
|
||||
{
|
||||
float fDistance, fPitch, fRotation, fHeight;
|
||||
GetCamera(&fDistance, &fPitch, &fRotation, &fHeight);
|
||||
CPythonGraphic::Instance().SetPositionCamera(s_app.m_v3CenterPosition.x, s_app.m_v3CenterPosition.y, s_app.m_v3CenterPosition.z + pMainCamera->GetTargetHeight(), fDistance, fPitch, fRotation);
|
||||
}
|
||||
|
||||
if (0.0f != s_app.m_fRotationSpeed)
|
||||
pMainCamera->Roll(s_app.m_fRotationSpeed);
|
||||
if (0.0f != s_app.m_fPitchSpeed)
|
||||
pMainCamera->Pitch(s_app.m_fPitchSpeed);
|
||||
if (0.0f != s_app.m_fZoomSpeed)
|
||||
pMainCamera->Zoom(s_app.m_fZoomSpeed);
|
||||
|
||||
if (0.0f !=s_app.m_kCmrSpd.m_fViewDir)
|
||||
s_app.m_kCmrPos.m_fViewDir+=s_app.m_kCmrSpd.m_fViewDir;
|
||||
if (0.0f !=s_app.m_kCmrSpd.m_fCrossDir)
|
||||
s_app.m_kCmrPos.m_fCrossDir+=s_app.m_kCmrSpd.m_fCrossDir;
|
||||
if (0.0f !=s_app.m_kCmrSpd.m_fUpDir)
|
||||
s_app.m_kCmrPos.m_fUpDir+=s_app.m_kCmrSpd.m_fUpDir;
|
||||
|
||||
if (0.0f != s_app.m_kCmrPos.m_fViewDir)
|
||||
pMainCamera->MoveFront(s_app.m_kCmrPos.m_fViewDir);
|
||||
if (0.0f != s_app.m_kCmrPos.m_fCrossDir)
|
||||
pMainCamera->MoveAlongCross(s_app.m_kCmrPos.m_fCrossDir);
|
||||
if (0.0f != s_app.m_kCmrPos.m_fUpDir)
|
||||
pMainCamera->MoveVertical(s_app.m_kCmrPos.m_fUpDir);
|
||||
|
||||
// PORT: SkipRenderBuffering while dragging and the listener update of m_SoundManager follow here in
|
||||
// 40250; there is no render buffering and sound is not ported (2V4).
|
||||
}
|
||||
|
||||
void CPythonApplication::SetViewDirCameraSpeed(float fSpeed)
|
||||
{
|
||||
if (IsLockCurrentCamera())
|
||||
return;
|
||||
|
||||
app().m_kCmrSpd.m_fViewDir=fSpeed;
|
||||
}
|
||||
|
||||
void CPythonApplication::SetCrossDirCameraSpeed(float fSpeed)
|
||||
{
|
||||
if (IsLockCurrentCamera())
|
||||
return;
|
||||
|
||||
app().m_kCmrSpd.m_fCrossDir=fSpeed;
|
||||
}
|
||||
|
||||
void CPythonApplication::SetUpDirCameraSpeed(float fSpeed)
|
||||
{
|
||||
if (IsLockCurrentCamera())
|
||||
return;
|
||||
|
||||
app().m_kCmrSpd.m_fUpDir=fSpeed;
|
||||
}
|
||||
|
||||
void CPythonApplication::SetCamera(float Distance, float Pitch, float Rotation, float fDestinationHeight)
|
||||
{
|
||||
if (IsLockCurrentCamera())
|
||||
return;
|
||||
|
||||
CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCurrentCamera)
|
||||
return;
|
||||
|
||||
D3DXVECTOR3 v3Target = pCurrentCamera->GetTarget();
|
||||
CPythonGraphic::Instance().SetPositionCamera(v3Target.x, v3Target.y, v3Target.z, Distance, Pitch, Rotation);
|
||||
|
||||
CCamera * pMainCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (pMainCamera)
|
||||
pMainCamera->SetTargetHeight(fDestinationHeight);
|
||||
}
|
||||
|
||||
void CPythonApplication::GetCamera(float * Distance, float * Pitch, float * Rotation, float * DestinationHeight)
|
||||
{
|
||||
CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
*Distance = pCurrentCamera->GetDistance();
|
||||
*Pitch = pCurrentCamera->GetPitch();
|
||||
*Rotation = pCurrentCamera->GetRoll();
|
||||
*DestinationHeight = pCurrentCamera->GetTarget().z;
|
||||
}
|
||||
|
||||
void CPythonApplication::RotateCamera(int iDirection)
|
||||
{
|
||||
if (IsLockCurrentCamera())
|
||||
return;
|
||||
|
||||
float fDegree = app().m_fCameraRotateSpeed * float(iDirection);
|
||||
app().m_fRotationSpeed = fDegree;
|
||||
}
|
||||
|
||||
void CPythonApplication::PitchCamera(int iDirection)
|
||||
{
|
||||
if (IsLockCurrentCamera())
|
||||
return;
|
||||
|
||||
float fDegree = app().m_fCameraPitchSpeed * float(iDirection);
|
||||
app().m_fPitchSpeed = fDegree;
|
||||
}
|
||||
|
||||
void CPythonApplication::ZoomCamera(int iDirection)
|
||||
{
|
||||
if (IsLockCurrentCamera())
|
||||
return;
|
||||
|
||||
float fRatio = 1.0f + app().m_fCameraZoomSpeed * float(iDirection);
|
||||
app().m_fZoomSpeed = fRatio;
|
||||
}
|
||||
|
||||
// PORT: in special camera mode 40250 checks GetKeyState(VK_SCROLL) & 1 (Scroll Lock on) to move the
|
||||
// camera instead; the platform has no Scroll Lock state, so it is always off.
|
||||
void CPythonApplication::MovieRotateCamera(int iDirection)
|
||||
{
|
||||
if (IsLockCurrentCamera())
|
||||
return;
|
||||
|
||||
float fDegree = app().m_fCameraRotateSpeed * float(iDirection);
|
||||
app().m_fRotationSpeed = fDegree;
|
||||
}
|
||||
|
||||
void CPythonApplication::MoviePitchCamera(int iDirection)
|
||||
{
|
||||
if (IsLockCurrentCamera())
|
||||
return;
|
||||
|
||||
float fDegree = app().m_fCameraPitchSpeed * float(iDirection);
|
||||
app().m_fPitchSpeed = fDegree;
|
||||
}
|
||||
|
||||
void CPythonApplication::MovieZoomCamera(int iDirection)
|
||||
{
|
||||
if (IsLockCurrentCamera())
|
||||
return;
|
||||
|
||||
float fRatio = 1.0f + app().m_fCameraZoomSpeed * float(iDirection);
|
||||
app().m_fZoomSpeed = fRatio;
|
||||
}
|
||||
|
||||
void CPythonApplication::MovieResetCamera()
|
||||
{
|
||||
if (IsLockCurrentCamera())
|
||||
return;
|
||||
|
||||
ApplicationCamera& s_app = app();
|
||||
if (s_app.m_isSpecialCameraMode)
|
||||
{
|
||||
SetCrossDirCameraSpeed(0.0f);
|
||||
SetViewDirCameraSpeed(0.0f);
|
||||
SetUpDirCameraSpeed(0.0f);
|
||||
|
||||
s_app.m_kCmrPos.m_fViewDir = 0;
|
||||
s_app.m_kCmrPos.m_fCrossDir = 0;
|
||||
s_app.m_kCmrPos.m_fUpDir = 0;
|
||||
}
|
||||
}
|
||||
|
||||
float CPythonApplication::GetRotation()
|
||||
{
|
||||
return CCameraManager::Instance().GetCurrentCamera()->GetRoll();
|
||||
}
|
||||
|
||||
float CPythonApplication::GetPitch()
|
||||
{
|
||||
return CCameraManager::Instance().GetCurrentCamera()->GetPitch();
|
||||
}
|
||||
|
||||
bool CPythonApplication::IsLockCurrentCamera()
|
||||
{
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCamera)
|
||||
return false;
|
||||
|
||||
return pCamera->IsLock();
|
||||
}
|
||||
|
||||
void CPythonApplication::SetEventCamera(const SCameraSetting & c_rCameraSetting)
|
||||
{
|
||||
ApplicationCamera& s_app = app();
|
||||
if (CCameraManager::DEFAULT_PERSPECTIVE_CAMERA == CCameraManager::Instance().GetCurrentCameraNum())
|
||||
{
|
||||
GetCameraSetting(&s_app.m_DefaultCameraSetting);
|
||||
}
|
||||
|
||||
/////
|
||||
|
||||
CCameraManager::Instance().SetCurrentCamera(EVENT_CAMERA_NUMBER);
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCamera)
|
||||
return;
|
||||
|
||||
SetCameraSetting(c_rCameraSetting);
|
||||
s_app.m_kEventCameraSetting = c_rCameraSetting;
|
||||
s_app.m_iCameraMode = CAMERA_MODE_STAND;
|
||||
}
|
||||
|
||||
void CPythonApplication::BlendEventCamera(const SCameraSetting & c_rCameraSetting, float fBlendTime)
|
||||
{
|
||||
ApplicationCamera& s_app = app();
|
||||
s_app.m_iCameraMode = CAMERA_MODE_BLEND;
|
||||
s_app.m_fBlendCameraStartTime = CTimer::Instance().GetCurrentSecond();
|
||||
s_app.m_fBlendCameraBlendTime = fBlendTime;
|
||||
s_app.m_kEndBlendCameraSetting = c_rCameraSetting;
|
||||
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (pCamera)
|
||||
pCamera->Lock();
|
||||
}
|
||||
|
||||
void CPythonApplication::SetDefaultCamera()
|
||||
{
|
||||
ApplicationCamera& s_app = app();
|
||||
s_app.m_iCameraMode = CAMERA_MODE_NORMAL;
|
||||
s_app.m_fBlendCameraStartTime = 0.0f;
|
||||
s_app.m_fBlendCameraBlendTime = 0.0f;
|
||||
|
||||
/////
|
||||
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (pCamera)
|
||||
pCamera->Unlock();
|
||||
|
||||
if (CCameraManager::DEFAULT_PERSPECTIVE_CAMERA != CCameraManager::Instance().GetCurrentCameraNum())
|
||||
{
|
||||
CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA);
|
||||
SetCameraSetting(s_app.m_DefaultCameraSetting);
|
||||
}
|
||||
}
|
||||
|
||||
void CPythonApplication::SetCameraSetting(const SCameraSetting & c_rCameraSetting)
|
||||
{
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCamera)
|
||||
return;
|
||||
|
||||
CPythonGraphic::Instance().SetPositionCamera( c_rCameraSetting.v3CenterPosition.x,
|
||||
c_rCameraSetting.v3CenterPosition.y,
|
||||
c_rCameraSetting.v3CenterPosition.z,
|
||||
c_rCameraSetting.fZoom,
|
||||
c_rCameraSetting.fPitch,
|
||||
c_rCameraSetting.fRotation);
|
||||
|
||||
if (0.0f != c_rCameraSetting.kCmrPos.m_fViewDir)
|
||||
pCamera->MoveFront(c_rCameraSetting.kCmrPos.m_fViewDir);
|
||||
if (0.0f != c_rCameraSetting.kCmrPos.m_fCrossDir)
|
||||
pCamera->MoveAlongCross(c_rCameraSetting.kCmrPos.m_fCrossDir);
|
||||
if (0.0f != c_rCameraSetting.kCmrPos.m_fUpDir)
|
||||
pCamera->MoveVertical(c_rCameraSetting.kCmrPos.m_fUpDir);
|
||||
|
||||
ApplicationCamera& s_app = app();
|
||||
s_app.m_kCmrPos.m_fUpDir = 0.0f;
|
||||
s_app.m_kCmrPos.m_fViewDir = 0.0f;
|
||||
s_app.m_kCmrPos.m_fCrossDir = 0.0f;
|
||||
s_app.m_kCmrSpd.m_fUpDir = 0.0f;
|
||||
s_app.m_kCmrSpd.m_fViewDir = 0.0f;
|
||||
s_app.m_kCmrSpd.m_fCrossDir = 0.0f;
|
||||
s_app.m_fZoomSpeed = 0.0f;
|
||||
s_app.m_fPitchSpeed = 0.0f;
|
||||
s_app.m_fRotationSpeed = 0.0f;
|
||||
}
|
||||
|
||||
void CPythonApplication::GetCameraSetting(SCameraSetting * pCameraSetting)
|
||||
{
|
||||
ApplicationCamera& s_app = app();
|
||||
pCameraSetting->v3CenterPosition = s_app.m_v3CenterPosition;
|
||||
pCameraSetting->kCmrPos = s_app.m_kCmrPos;
|
||||
|
||||
if (CCameraManager::Instance().GetCurrentCamera())
|
||||
pCameraSetting->v3CenterPosition.z += CCameraManager::Instance().GetCurrentCamera()->GetTargetHeight();
|
||||
|
||||
float fHeight;
|
||||
GetCamera(&pCameraSetting->fZoom, &pCameraSetting->fPitch, &pCameraSetting->fRotation, &fHeight);
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:1294
|
||||
void CPythonApplication::SetCenterPosition(float fx, float fy, float fz)
|
||||
{
|
||||
ApplicationCamera& s_app = app();
|
||||
s_app.m_v3CenterPosition.x = +fx;
|
||||
s_app.m_v3CenterPosition.y = -fy;
|
||||
s_app.m_v3CenterPosition.z = +fz;
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:1301
|
||||
void CPythonApplication::GetCenterPosition(TPixelPosition * pPixelPosition)
|
||||
{
|
||||
ApplicationCamera& s_app = app();
|
||||
pPixelPosition->x = +s_app.m_v3CenterPosition.x;
|
||||
pPixelPosition->y = -s_app.m_v3CenterPosition.y;
|
||||
pPixelPosition->z = +s_app.m_v3CenterPosition.z;
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:1365
|
||||
void CPythonApplication::EnableSpecialCameraMode()
|
||||
{
|
||||
app().m_isSpecialCameraMode = TRUE;
|
||||
}
|
||||
|
||||
void CPythonApplication::SetCameraSpeed(int iPercentage)
|
||||
{
|
||||
ApplicationCamera& s_app = app();
|
||||
s_app.m_fCameraRotateSpeed = c_fDefaultCameraRotateSpeed * float(iPercentage) / 100.0f;
|
||||
s_app.m_fCameraPitchSpeed = c_fDefaultCameraPitchSpeed * float(iPercentage) / 100.0f;
|
||||
s_app.m_fCameraZoomSpeed = c_fDefaultCameraZoomSpeed * float(iPercentage) / 100.0f;
|
||||
}
|
||||
|
||||
void CPythonApplication::SaveCameraSetting(const char * c_szFileName)
|
||||
{
|
||||
SCameraSetting CameraSetting;
|
||||
GetCameraSetting(&CameraSetting);
|
||||
|
||||
FILE * File = fopen(c_szFileName, "w");
|
||||
if (!File)
|
||||
return;
|
||||
|
||||
PrintfTabs(File, 0, "CenterPos %f %f %f\n", CameraSetting.v3CenterPosition.x, CameraSetting.v3CenterPosition.y, CameraSetting.v3CenterPosition.z);
|
||||
PrintfTabs(File, 0, "CameraSetting %f %f %f\n", CameraSetting.fZoom, CameraSetting.fPitch, CameraSetting.fRotation);
|
||||
PrintfTabs(File, 0, "CmrPos %f %f %f\n", CameraSetting.kCmrPos.m_fUpDir, CameraSetting.kCmrPos.m_fViewDir, CameraSetting.kCmrPos.m_fCrossDir);
|
||||
Tracef("SaveCameraSetting(%s) - (CenterPos %d %d %d) (Distance %d, Pitch %d, Rotation %d) (UpDir %d, ViewDir %d, CrossDir %d)\n",
|
||||
c_szFileName,
|
||||
int(CameraSetting.v3CenterPosition.x),
|
||||
int(CameraSetting.v3CenterPosition.y),
|
||||
int(CameraSetting.v3CenterPosition.z),
|
||||
int(CameraSetting.fZoom),
|
||||
int(CameraSetting.fPitch),
|
||||
int(CameraSetting.fRotation),
|
||||
int(CameraSetting.kCmrPos.m_fUpDir),
|
||||
int(CameraSetting.kCmrPos.m_fViewDir),
|
||||
int(CameraSetting.kCmrPos.m_fCrossDir));
|
||||
fclose(File);
|
||||
}
|
||||
|
||||
bool CPythonApplication::LoadCameraSetting(const char * c_szFileName)
|
||||
{
|
||||
CTextFileLoader TextFileLoader;
|
||||
if (!TextFileLoader.Load(c_szFileName))
|
||||
return false;
|
||||
|
||||
D3DXVECTOR3 v3CenterPosition;
|
||||
CTokenVector * pCenterPos;
|
||||
if (TextFileLoader.GetTokenVector("centerpos", &pCenterPos))
|
||||
if (3 == pCenterPos->size())
|
||||
{
|
||||
v3CenterPosition.x = atof(pCenterPos->at(0).c_str());
|
||||
v3CenterPosition.y = atof(pCenterPos->at(1).c_str());
|
||||
v3CenterPosition.z = atof(pCenterPos->at(2).c_str());
|
||||
}
|
||||
|
||||
CTokenVector * pCameraSetting;
|
||||
CTokenVector * pCmrPos;
|
||||
if (TextFileLoader.GetTokenVector("camerasetting", &pCameraSetting))
|
||||
if (TextFileLoader.GetTokenVector("cmrpos", &pCmrPos))
|
||||
if (3 == pCameraSetting->size())
|
||||
if (3 == pCmrPos->size())
|
||||
{
|
||||
SCameraSetting CameraSetting;
|
||||
CameraSetting.v3CenterPosition = v3CenterPosition;
|
||||
|
||||
CameraSetting.fZoom = atof(pCameraSetting->at(0).c_str());
|
||||
CameraSetting.fPitch = atof(pCameraSetting->at(1).c_str());
|
||||
CameraSetting.fRotation = atof(pCameraSetting->at(2).c_str());
|
||||
|
||||
CameraSetting.kCmrPos.m_fUpDir = atof(pCmrPos->at(0).c_str());
|
||||
CameraSetting.kCmrPos.m_fViewDir = atof(pCmrPos->at(1).c_str());
|
||||
CameraSetting.kCmrPos.m_fCrossDir = atof(pCmrPos->at(2).c_str());
|
||||
|
||||
SetEventCamera(CameraSetting);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
#include "UserInterface/StdAfx.h"
|
||||
#include "UserInterface/PythonApplication.h"
|
||||
#include "UserInterface/PythonBackground.h"
|
||||
#include "EterLib/Camera.h"
|
||||
|
||||
extern PyObject* s_poMouseHandler;
|
||||
|
||||
void CPythonApplication::OnCameraUpdate()
|
||||
{
|
||||
if ( CPythonBackground::Instance().IsMapReady() )
|
||||
{
|
||||
CCamera* pkCameraMgr = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (pkCameraMgr)
|
||||
{
|
||||
pkCameraMgr->Update();
|
||||
CPythonGraphic::Instance().UpdateViewMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPythonApplication::OnUIUpdate()
|
||||
{
|
||||
UI::CWindowManager& rkUIMgr = UI::CWindowManager::Instance();
|
||||
rkUIMgr.Update();
|
||||
}
|
||||
|
||||
void CPythonApplication::OnUIRender()
|
||||
{
|
||||
UI::CWindowManager& rkUIMgr = UI::CWindowManager::Instance();
|
||||
rkUIMgr.Render();
|
||||
}
|
||||
|
||||
void CPythonApplication::OnSizeChange(int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
void CPythonApplication::OnMouseMiddleButtonDown(int x, int y)
|
||||
{
|
||||
CCameraManager& rkCmrMgr = CCameraManager::Instance();
|
||||
CCamera* pkCmrCur = rkCmrMgr.GetCurrentCamera();
|
||||
if (pkCmrCur)
|
||||
pkCmrCur->BeginDrag(x, y);
|
||||
|
||||
if ( !CPythonBackground::Instance().IsMapReady() )
|
||||
return;
|
||||
|
||||
SetCursorNum(CAMERA_ROTATE);
|
||||
if ( CURSOR_MODE_HARDWARE == GetCursorMode())
|
||||
SetCursorVisible(FALSE, true);
|
||||
}
|
||||
|
||||
void CPythonApplication::OnMouseMiddleButtonUp(int x, int y)
|
||||
{
|
||||
CCameraManager& rkCmrMgr = CCameraManager::Instance();
|
||||
CCamera* pkCmrCur = rkCmrMgr.GetCurrentCamera();
|
||||
if (pkCmrCur)
|
||||
pkCmrCur->EndDrag();
|
||||
|
||||
if ( !CPythonBackground::Instance().IsMapReady() )
|
||||
return;
|
||||
|
||||
SetCursorNum(NORMAL);
|
||||
if ( CURSOR_MODE_HARDWARE == GetCursorMode())
|
||||
SetCursorVisible(TRUE);
|
||||
}
|
||||
|
||||
void CPythonApplication::OnMouseWheel(int nLen)
|
||||
{
|
||||
CCameraManager& rkCmrMgr = CCameraManager::Instance();
|
||||
CCamera* pkCmrCur = rkCmrMgr.GetCurrentCamera();
|
||||
if (pkCmrCur)
|
||||
pkCmrCur->Wheel(nLen);
|
||||
}
|
||||
|
||||
void CPythonApplication::OnMouseMove(int x, int y)
|
||||
{
|
||||
CCameraManager& rkCmrMgr = CCameraManager::Instance();
|
||||
CCamera* pkCmrCur = rkCmrMgr.GetCurrentCamera();
|
||||
|
||||
POINT Point;
|
||||
if (pkCmrCur)
|
||||
{
|
||||
if ( CPythonBackground::Instance().IsMapReady() && pkCmrCur->Drag(x, y, &Point) )
|
||||
{
|
||||
x = Point.x;
|
||||
y = Point.y;
|
||||
}
|
||||
}
|
||||
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunMouseMove(x, y);
|
||||
}
|
||||
|
||||
void CPythonApplication::OnMouseLeftButtonDown(int x, int y)
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunMouseLeftButtonDown(x, y);
|
||||
}
|
||||
|
||||
void CPythonApplication::OnMouseLeftButtonUp(int x, int y)
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunMouseLeftButtonUp(x, y);
|
||||
}
|
||||
|
||||
void CPythonApplication::OnMouseLeftButtonDoubleClick(int x, int y)
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunMouseLeftButtonDown(x, y);
|
||||
rkWndMgr.RunMouseLeftButtonDoubleClick(x, y);
|
||||
}
|
||||
|
||||
void CPythonApplication::OnMouseRightButtonDown(int x, int y)
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunMouseRightButtonDown(x, y);
|
||||
}
|
||||
|
||||
void CPythonApplication::OnMouseRightButtonUp(int x, int y)
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunMouseRightButtonUp(x, y);
|
||||
}
|
||||
|
||||
void CPythonApplication::OnKeyDown(int iIndex)
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
|
||||
if (DIK_ESCAPE == iIndex)
|
||||
{
|
||||
rkWndMgr.RunPressEscapeKey();
|
||||
}
|
||||
|
||||
rkWndMgr.RunKeyDown(iIndex);
|
||||
}
|
||||
|
||||
void CPythonApplication::OnKeyUp(int iIndex)
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunKeyUp(iIndex);
|
||||
}
|
||||
|
||||
void CPythonApplication::RunIMEUpdate()
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunIMEUpdate();
|
||||
}
|
||||
|
||||
void CPythonApplication::RunIMETabEvent()
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunIMETabEvent();
|
||||
}
|
||||
|
||||
void CPythonApplication::RunIMEReturnEvent()
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunIMEReturnEvent();
|
||||
}
|
||||
|
||||
void CPythonApplication::OnIMEKeyDown(int iIndex)
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunIMEKeyDown(iIndex);
|
||||
}
|
||||
|
||||
void CPythonApplication::RunIMEChangeCodePage()
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunChangeCodePage();
|
||||
}
|
||||
|
||||
void CPythonApplication::RunIMEOpenCandidateListEvent()
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunOpenCandidate();
|
||||
}
|
||||
|
||||
void CPythonApplication::RunIMECloseCandidateListEvent()
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunCloseCandidate();
|
||||
}
|
||||
|
||||
void CPythonApplication::RunIMEOpenReadingWndEvent()
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunOpenReading();
|
||||
}
|
||||
|
||||
void CPythonApplication::RunIMECloseReadingWndEvent()
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunCloseReading();
|
||||
}
|
||||
|
||||
void CPythonApplication::RunPressExitKey()
|
||||
{
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
rkWndMgr.RunPressExitKey();
|
||||
}
|
||||
|
||||
void CPythonApplication::OnMouseUpdate()
|
||||
{
|
||||
if (!s_poMouseHandler)
|
||||
return;
|
||||
|
||||
UI::CWindowManager& rkWndMgr = UI::CWindowManager::Instance();
|
||||
long lx, ly;
|
||||
rkWndMgr.GetMousePosition(lx, ly);
|
||||
PyCallClassMemberFunc(s_poMouseHandler, "Update", Py_BuildValue("(ii)", lx, ly));
|
||||
}
|
||||
|
||||
void CPythonApplication::OnMouseRender()
|
||||
{
|
||||
if (!s_poMouseHandler)
|
||||
return;
|
||||
|
||||
PyCallClassMemberFunc(s_poMouseHandler, "Render", Py_BuildValue("()"));
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctime>
|
||||
|
||||
// CPythonApplication is not constructed by the Godot host. Keep the three values that its
|
||||
// 40250 SetServerTime/GetServerTime/GetServerTimeStamp methods use in the platform adapter.
|
||||
void SetPlatformServerTime(time_t server_time);
|
||||
time_t GetPlatformServerTime();
|
||||
time_t GetPlatformServerTimeStamp();
|
||||
@@ -0,0 +1,170 @@
|
||||
// Platform implementation of the pack bootstrap from 40250 UserInterface/UserInterface.cpp. PackInitialize is the 40250
|
||||
// function with three platform differences:
|
||||
// - pack names in Index are matched to the on-disk .eix/.epk case-insensitively ("Etc" is ETC.eix on NTFS, and
|
||||
// CEterPack::CreateIndexFile fopens the name as given), so the registered dbname carries the on-disk spelling;
|
||||
// - no LogBoxf (a Win32 message box), only the TraceError next to it;
|
||||
// - CTextFileLoader::SetCacheMode and CSoundData::SetPackMode are not called: EterLib/TextFileLoader and MilesLib
|
||||
// are not ported yet, and neither affects which files the pack manager registers or returns.
|
||||
// Built as in the Distribute configuration (_DISTRIBUTE): pack first.
|
||||
#include "EterBase/StdAfx.h"
|
||||
#include "EterBase/FileLoader.h"
|
||||
#include "EterBase/MappedFile.h"
|
||||
#include "EterBase/Debug.h"
|
||||
#include "EterBase/lzo.h"
|
||||
#include "EterPack/EterPackManager.h"
|
||||
#include "UserInterface.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
// 40250 UserInterface.cpp:49.
|
||||
bool __IS_TEST_SERVER_MODE__=false;
|
||||
|
||||
// 40250 UserInterface.cpp:98. PORT: LoadString reads the executable's STRINGTABLE; the one the supplied English
|
||||
// client resolves is UserInterface.rc's LANG_ENGLISH, SUBLANG_ENGLISH_US section (ids from resource.h).
|
||||
namespace
|
||||
{
|
||||
const char* LoadAppString(DWORD dwID)
|
||||
{
|
||||
switch (dwID)
|
||||
{
|
||||
case 1: return "Metin 2"; // IDS_APP_NAME
|
||||
case 2: return "'s"; // IDS_POSSESSIVE_MORPHENE
|
||||
case 3: return "IDS_WARN_BAD_DRIVER"; // IDS_WARN_BAD_DRIVER
|
||||
case 4: return "IDS_WARN_NO_TNL"; // IDS_WARN_NO_TNL
|
||||
case 5: return "Cannot read %s file"; // IDS_ERR_CANNOT_READ_FILE
|
||||
case 6: return "File '%s' is not latest version. Please launch patcher."; // IDS_ERR_NOT_LATEST_FILE
|
||||
case 7: return "Please run patcher."; // IDS_ERR_MUST_LAUNCH_FROM_PATCHER
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::map<DWORD, std::string> gs_kMap_dwID_stLocale;
|
||||
} // namespace
|
||||
|
||||
const std::string& ApplicationStringTable_GetString(DWORD dwID)
|
||||
{
|
||||
std::string& rstLocale=gs_kMap_dwID_stLocale[dwID];
|
||||
rstLocale=LoadAppString(dwID);
|
||||
|
||||
return rstLocale;
|
||||
}
|
||||
|
||||
const char* ApplicationStringTable_GetStringz(DWORD dwID)
|
||||
{
|
||||
return ApplicationStringTable_GetString(dwID).c_str();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// Lowercased file name -> on-disk spelling, for the files directly in `folder`.
|
||||
std::map<std::string, std::string> list_folder(const std::string& folder)
|
||||
{
|
||||
std::map<std::string, std::string> names;
|
||||
auto add = [&](const std::string& name) {
|
||||
std::string lower = name;
|
||||
for (char& c : lower)
|
||||
c = (char) tolower((unsigned char) c);
|
||||
names.emplace(lower, name);
|
||||
};
|
||||
#if defined(_WIN32)
|
||||
_finddata_t fd;
|
||||
intptr_t h = _findfirst((folder + "*").c_str(), &fd);
|
||||
if (h != -1)
|
||||
{
|
||||
do
|
||||
add(fd.name);
|
||||
while (_findnext(h, &fd) == 0);
|
||||
_findclose(h);
|
||||
}
|
||||
#else
|
||||
if (DIR* d = opendir(folder.c_str()))
|
||||
{
|
||||
while (dirent* e = readdir(d))
|
||||
add(e->d_name);
|
||||
closedir(d);
|
||||
}
|
||||
#endif
|
||||
return names;
|
||||
}
|
||||
|
||||
// <folder><name> with `name` in the spelling of the on-disk <name>.eix, or unchanged when there is none.
|
||||
std::string on_disk(const std::map<std::string, std::string>& names, const std::string& folder, const std::string& name)
|
||||
{
|
||||
std::string lower = name + ".eix";
|
||||
for (char& c : lower)
|
||||
c = (char) tolower((unsigned char) c);
|
||||
auto it = names.find(lower);
|
||||
if (it == names.end())
|
||||
return folder + name;
|
||||
return folder + it->second.substr(0, it->second.size() - 4);
|
||||
}
|
||||
}
|
||||
|
||||
void PackSingletons()
|
||||
{
|
||||
static CLZO lzo;
|
||||
static CEterPackManager EterPackManager;
|
||||
}
|
||||
|
||||
// 40250: PackInitialize
|
||||
bool PackInitialize(const char * c_pszFolder)
|
||||
{
|
||||
if (_access(c_pszFolder, 0) != 0)
|
||||
return true;
|
||||
|
||||
std::string stFolder(c_pszFolder);
|
||||
stFolder += "/";
|
||||
|
||||
std::string stFileName(stFolder);
|
||||
stFileName += "Index";
|
||||
|
||||
CMappedFile file;
|
||||
LPCVOID pvData;
|
||||
|
||||
if (!file.Create(stFileName.c_str(), &pvData, 0, 0))
|
||||
{
|
||||
TraceError("FATAL ERROR! File not exist: %s", stFileName.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
CMemoryTextFileLoader TextLoader;
|
||||
TextLoader.Bind(file.Size(), pvData);
|
||||
|
||||
bool bPackFirst = TRUE;
|
||||
|
||||
const std::string& strPackType = TextLoader.GetLineString(0);
|
||||
|
||||
if (strPackType.compare("FILE") && strPackType.compare("PACK"))
|
||||
{
|
||||
TraceError("Pack/Index has invalid syntax. First line must be 'PACK' or 'FILE'");
|
||||
return false;
|
||||
}
|
||||
|
||||
CEterPackManager::Instance().SetCacheMode();
|
||||
CEterPackManager::Instance().SetSearchMode(bPackFirst);
|
||||
|
||||
const std::map<std::string, std::string> names = list_folder(stFolder);
|
||||
|
||||
std::string strPackName, strTexCachePackName;
|
||||
for (DWORD i = 1; i < TextLoader.GetLineCount() - 1; i += 2)
|
||||
{
|
||||
const std::string & c_rstFolder = TextLoader.GetLineString(i);
|
||||
const std::string & c_rstName = TextLoader.GetLineString(i + 1);
|
||||
|
||||
strPackName = on_disk(names, stFolder, c_rstName);
|
||||
strTexCachePackName = on_disk(names, stFolder, c_rstName + "_texcache");
|
||||
|
||||
CEterPackManager::Instance().RegisterPack(strPackName.c_str(), c_rstFolder.c_str());
|
||||
CEterPackManager::Instance().RegisterPack(strTexCachePackName.c_str(), c_rstFolder.c_str());
|
||||
}
|
||||
|
||||
CEterPackManager::Instance().RegisterRootPack(on_disk(names, stFolder, "root").c_str());
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
// Platform-layer pieces of 40250 UserInterface/UserInterface.cpp (the WinMain unit). 40250 declares these nowhere:
|
||||
// Main() in the same file calls them. The extension's pack bootstrap calls them instead.
|
||||
|
||||
// 40250: PackInitialize
|
||||
// Registers <folder>/Index the way the 40250 client does at startup. The CLZO and CEterPackManager singletons
|
||||
// it needs must already exist (see PackSingletons).
|
||||
bool PackInitialize(const char * c_pszFolder);
|
||||
|
||||
// The two function-static singletons 40250 Main() creates before PackInitialize("pack")
|
||||
// (`static CLZO lzo; static CEterPackManager EterPackManager;`), created on first use and alive until exit.
|
||||
void PackSingletons();
|
||||
@@ -0,0 +1,29 @@
|
||||
// 40250 UserInterface/WiseLogicXTrap.cpp: the build without XTRAP_CLIENT_ENABLE (the XTrap anti-cheat SDK is
|
||||
// Win32-only and not shipped), verbatim.
|
||||
#include "UserInterface/StdAfx.h"
|
||||
#include "UserInterface/Locale.h"
|
||||
#include "UserInterface/WiseLogicXTrap.h"
|
||||
|
||||
bool XTrap_Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XTrap_CheckInit()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void XTrap_PollEvent()
|
||||
{
|
||||
}
|
||||
|
||||
void XTrap_SetUserInfo(LPCSTR szUserID, LPCSTR szServerName, LPCSTR szCharacterName, LPCSTR szCharacterClass, SOCKET hSocket)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void XTrap_ValidateCheckStream( LPVOID PacketBufferIn, LPVOID PacketBufferOut )
|
||||
{
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user