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,72 @@
|
||||
#pragma once
|
||||
// CPU-memory vertex/index buffers behind the D3D8 buffer handles. 40250 fills its buffers through
|
||||
// Lock/Unlock (CGrannyModel::__LoadVertices, CGrannyModelInstance deform) and the renderer later reads
|
||||
// them back, so the platform keeps the bytes in memory instead of creating device objects.
|
||||
#include "EterLib/StdAfx.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
inline std::atomic<std::uint64_t> mt_next_cpu_buffer_id{1};
|
||||
|
||||
struct MtCpuVertexBuffer : IDirect3DVertexBuffer8
|
||||
{
|
||||
const std::uint64_t id = mt_next_cpu_buffer_id.fetch_add(1, std::memory_order_relaxed);
|
||||
std::uint64_t revision = 0;
|
||||
std::vector<uint8_t> bytes;
|
||||
DWORD fvf = 0;
|
||||
|
||||
HRESULT Lock(UINT offset, UINT size, BYTE** data, DWORD) override
|
||||
{
|
||||
if (size_t(offset) + size > bytes.size())
|
||||
return E_FAIL;
|
||||
*data = bytes.data() + offset;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT Unlock() override { ++revision; return S_OK; }
|
||||
};
|
||||
|
||||
struct MtCpuIndexBuffer : IDirect3DIndexBuffer8
|
||||
{
|
||||
const std::uint64_t id = mt_next_cpu_buffer_id.fetch_add(1, std::memory_order_relaxed);
|
||||
std::uint64_t revision = 0;
|
||||
std::vector<uint8_t> bytes;
|
||||
D3DFORMAT format = D3DFMT_INDEX16;
|
||||
|
||||
HRESULT Lock(UINT offset, UINT size, BYTE** data, DWORD) override
|
||||
{
|
||||
if (size_t(offset) + size > bytes.size())
|
||||
return E_FAIL;
|
||||
*data = bytes.data() + offset;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT Unlock() override { ++revision; return S_OK; }
|
||||
};
|
||||
|
||||
// D3DXGetFVFVertexSize.
|
||||
inline unsigned mt_fvf_vertex_size(DWORD fvf)
|
||||
{
|
||||
unsigned size = 0;
|
||||
switch (fvf & D3DFVF_POSITION_MASK)
|
||||
{
|
||||
case D3DFVF_XYZ: size += 12; break;
|
||||
case D3DFVF_XYZRHW: size += 16; break;
|
||||
case D3DFVF_XYZB1: size += 16; break;
|
||||
case D3DFVF_XYZB2: size += 20; break;
|
||||
case D3DFVF_XYZB3: size += 24; break;
|
||||
case D3DFVF_XYZB4: size += 28; break;
|
||||
case D3DFVF_XYZB5: size += 32; break;
|
||||
}
|
||||
if (fvf & D3DFVF_NORMAL) size += 12;
|
||||
if (fvf & D3DFVF_PSIZE) size += 4;
|
||||
if (fvf & D3DFVF_DIFFUSE) size += 4;
|
||||
if (fvf & D3DFVF_SPECULAR) size += 4;
|
||||
const unsigned texCount = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
|
||||
for (unsigned i = 0; i < texCount; ++i)
|
||||
{
|
||||
static const unsigned coordSize[4] = { 8, 12, 16, 4 };
|
||||
size += coordSize[(fvf >> (16 + i * 2)) & 3];
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// Platform skeleton for EterLib/DibBar.h (40250 EterLib/DibBar.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/DibBar.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CDibBar::CDibBar()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CDibBar::~CDibBar()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CDibBar::Create(HDC, DWORD, DWORD) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CDibBar::Invalidate() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CDibBar::SetClipRect(const RECT &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CDibBar::ClearBar() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CDibBar::Render(int, int) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CDibBar::__NearTextureSize(DWORD) -> DWORD
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<DWORD>();
|
||||
}
|
||||
|
||||
auto CDibBar::__DivideTextureSize(DWORD, DWORD, DWORD *, DWORD *, DWORD *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CDibBar::__BuildTextureBlock(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD) -> CBlockTexture *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<CBlockTexture *>();
|
||||
}
|
||||
|
||||
auto CDibBar::__BuildTextureBlockList(DWORD, DWORD, DWORD) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Platform skeleton for EterLib/FileLoaderThread.h (40250 EterLib/FileLoaderThread.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/FileLoaderThread.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CFileLoaderThread::CFileLoaderThread()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CFileLoaderThread::~CFileLoaderThread()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CFileLoaderThread::Create(void *) -> int
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
}
|
||||
|
||||
auto CFileLoaderThread::Request(std::string &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CFileLoaderThread::Fetch(TData **) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CFileLoaderThread::Shutdown() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CFileLoaderThread::EntryPoint(void *) -> UINT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
}
|
||||
|
||||
auto CFileLoaderThread::Run(void *) -> UINT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
}
|
||||
|
||||
auto CFileLoaderThread::Setup() -> UINT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
}
|
||||
|
||||
auto CFileLoaderThread::Execute(void *) -> UINT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
}
|
||||
|
||||
auto CFileLoaderThread::Destroy() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CFileLoaderThread::Process() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// Platform skeleton for EterLib/GrpColor.h (40250 EterLib/GrpColor.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpColor.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CGraphicColor::CGraphicColor(const CGraphicColor &)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CGraphicColor::CGraphicColor(float, float, float, float)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CGraphicColor::CGraphicColor(DWORD)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CGraphicColor::CGraphicColor()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CGraphicColor::~CGraphicColor()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicColor::Clear() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicColor::Set(float, float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicColor::Set(const CGraphicColor &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicColor::Set(DWORD) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicColor::Blend(float, const CGraphicColor &, const CGraphicColor &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicColor::GetPackValue() const -> DWORD
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<DWORD>();
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Platform skeleton for EterLib/GrpColorInstance.h (40250 EterLib/GrpColorInstance.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpColorInstance.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CGraphicColorInstance::CGraphicColorInstance()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CGraphicColorInstance::~CGraphicColorInstance()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicColorInstance::Clear() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicColorInstance::SetColorReference(const CGraphicColor &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicColorInstance::BlendColorReference(DWORD, const CGraphicColor &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicColorInstance::Update() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicColorInstance::GetCurrentColorReference() const -> const CGraphicColor &
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<const CGraphicColor &>();
|
||||
}
|
||||
|
||||
auto CGraphicColorInstance::GetCurrentTime() -> DWORD
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<DWORD>();
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
// 40250 EterLib/GrpDIB.cpp, verbatim. The GDI calls are the FreeType-backed platform/Win32Gdi.cpp.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpDIB.h"
|
||||
|
||||
CGraphicDib::CGraphicDib()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CGraphicDib::~CGraphicDib()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CGraphicDib::Initialize()
|
||||
{
|
||||
m_hDC=NULL;
|
||||
m_hBmp=NULL;
|
||||
m_pvBuf=NULL;
|
||||
m_width=0;
|
||||
m_height=0;
|
||||
}
|
||||
|
||||
void CGraphicDib::Destroy()
|
||||
{
|
||||
if (m_hBmp) DeleteObject(m_hBmp);
|
||||
if (m_hDC) DeleteDC(m_hDC);
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
bool CGraphicDib::Create(HDC hDC, int width, int height)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
ZeroMemory(&m_bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
|
||||
m_bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
m_bmi.bmiHeader.biWidth = m_width;
|
||||
m_bmi.bmiHeader.biHeight = -m_height;
|
||||
m_bmi.bmiHeader.biPlanes = 1;
|
||||
m_bmi.bmiHeader.biBitCount = 32;
|
||||
m_bmi.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
m_hDC=CreateCompatibleDC(hDC);
|
||||
if (!m_hDC)
|
||||
{
|
||||
assert(!"CGraphicDib::Create CreateCompatibleDC Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hBmp=CreateDIBSection(m_hDC, &m_bmi, DIB_RGB_COLORS, &m_pvBuf, NULL, 0);
|
||||
if (!m_hBmp)
|
||||
{
|
||||
assert(!"CGraphicDib::Create CreateDIBSection Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
SelectObject(m_hDC, m_hBmp);
|
||||
|
||||
::SetTextColor(m_hDC, RGB(255, 255, 255));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
HDC CGraphicDib::GetDCHandle()
|
||||
{
|
||||
return m_hDC;
|
||||
}
|
||||
|
||||
void CGraphicDib::SetBkMode(int iBkMode)
|
||||
{
|
||||
::SetBkMode(m_hDC, iBkMode);
|
||||
}
|
||||
|
||||
void CGraphicDib::TextOut(int ix, int iy, const char * c_szText)
|
||||
{
|
||||
::SetBkColor(m_hDC, 0);
|
||||
::TextOut(m_hDC, ix, iy, c_szText, strlen(c_szText));
|
||||
}
|
||||
|
||||
void CGraphicDib::Put(HDC hDC, int x, int y)
|
||||
{
|
||||
SetDIBitsToDevice(
|
||||
hDC,
|
||||
x,
|
||||
y,
|
||||
m_width,
|
||||
m_height,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
m_height,
|
||||
m_pvBuf,
|
||||
&m_bmi,
|
||||
DIB_RGB_COLORS
|
||||
);
|
||||
}
|
||||
|
||||
void* CGraphicDib::GetPointer()
|
||||
{
|
||||
return m_pvBuf;
|
||||
}
|
||||
|
||||
int CGraphicDib::GetWidth()
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
int CGraphicDib::GetHeight()
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
// Platform skeleton for EterLib/GrpDetector.h (40250 EterLib/GrpDetector.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpDetector.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
auto D3D_SModeInfo::GetString(std::string *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto D3D_CAdapterDisplayModeList::Build(IDirect3D8 &, D3DFORMAT, UINT) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto D3D_CAdapterDisplayModeList::GetDisplayModeNum() -> UINT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
}
|
||||
|
||||
auto D3D_CAdapterDisplayModeList::GetPixelFormatNum() -> UINT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
}
|
||||
|
||||
auto D3D_CAdapterDisplayModeList::GetDisplayModer(UINT) -> const D3DDISPLAYMODE &
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<const D3DDISPLAYMODE &>();
|
||||
}
|
||||
|
||||
auto D3D_CAdapterDisplayModeList::GetPixelFormatr(UINT) -> const D3DFORMAT &
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<const D3DFORMAT &>();
|
||||
}
|
||||
|
||||
auto D3D_CDeviceInfo::Build(IDirect3D8 &, UINT, UINT, D3D_CAdapterDisplayModeList &, PFNCONFIRMDEVICE) -> BOOL
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<BOOL>();
|
||||
}
|
||||
|
||||
auto D3D_CDeviceInfo::Find(UINT, UINT, UINT, BOOL, UINT *) -> BOOL
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<BOOL>();
|
||||
}
|
||||
|
||||
auto D3D_CDeviceInfo::GetD3DModeInfoNum() -> UINT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
}
|
||||
|
||||
auto D3D_CDeviceInfo::GetString(std::string *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto D3D_CDeviceInfo::FindDepthStencilFormat(IDirect3D8 &, UINT, D3DDEVTYPE, D3DFORMAT, D3DFORMAT *) -> BOOL
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<BOOL>();
|
||||
}
|
||||
|
||||
auto D3D_CDeviceInfo::GetD3DModeInfor(UINT) -> D3D_SModeInfo &
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<D3D_SModeInfo &>();
|
||||
}
|
||||
|
||||
auto D3D_CDeviceInfo::GetD3DModeInfop(UINT) -> D3D_SModeInfo *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<D3D_SModeInfo *>();
|
||||
}
|
||||
|
||||
decltype(D3D_CDeviceInfo::msc_aszD3DDevDesc) D3D_CDeviceInfo::msc_aszD3DDevDesc{};
|
||||
|
||||
decltype(D3D_CDeviceInfo::msc_aeD3DDevType) D3D_CDeviceInfo::msc_aeD3DDevType{};
|
||||
|
||||
auto D3D_CAdapterInfo::Find(UINT, UINT, UINT, BOOL, UINT *, UINT *) -> BOOL
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<BOOL>();
|
||||
}
|
||||
|
||||
auto D3D_CAdapterInfo::Build(IDirect3D8 &, UINT, PFNCONFIRMDEVICE) -> BOOL
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<BOOL>();
|
||||
}
|
||||
|
||||
auto D3D_CAdapterInfo::GetString(std::string *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto D3D_CAdapterInfo::GetDesktopD3DDisplayModer() -> D3DDISPLAYMODE &
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<D3DDISPLAYMODE &>();
|
||||
}
|
||||
|
||||
auto D3D_CAdapterInfo::GetDesktopD3DDisplayModep() -> D3DDISPLAYMODE *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<D3DDISPLAYMODE *>();
|
||||
}
|
||||
|
||||
auto D3D_CAdapterInfo::GetD3DDeviceInfop(UINT) -> D3D_CDeviceInfo *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<D3D_CDeviceInfo *>();
|
||||
}
|
||||
|
||||
auto D3D_CAdapterInfo::GetD3DModeInfop(UINT, UINT) -> D3D_SModeInfo *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<D3D_SModeInfo *>();
|
||||
}
|
||||
|
||||
D3D_CDisplayModeAutoDetector::D3D_CDisplayModeAutoDetector()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
D3D_CDisplayModeAutoDetector::~D3D_CDisplayModeAutoDetector()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto D3D_CDisplayModeAutoDetector::Find(UINT, UINT, UINT, BOOL, UINT *, UINT *, UINT *) -> BOOL
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<BOOL>();
|
||||
}
|
||||
|
||||
auto D3D_CDisplayModeAutoDetector::Build(IDirect3D8 &, PFNCONFIRMDEVICE) -> BOOL
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<BOOL>();
|
||||
}
|
||||
|
||||
auto D3D_CDisplayModeAutoDetector::GetD3DAdapterInfop(UINT) -> D3D_CAdapterInfo *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<D3D_CAdapterInfo *>();
|
||||
}
|
||||
|
||||
auto D3D_CDisplayModeAutoDetector::GetD3DModeInfop(UINT, UINT, UINT) -> D3D_SModeInfo *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<D3D_SModeInfo *>();
|
||||
}
|
||||
|
||||
auto D3D_CDisplayModeAutoDetector::GetString(std::string *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
// 40250 EterLib/GrpDevice.cpp over the platform's recording device (RecordingDevice.h): there is no
|
||||
// Direct3D object, adapter detection or window; Create makes the device, CStateManager, the matrix
|
||||
// stack and the default buffers as 40250 does. The remaining MT_PLATFORM_STUB() bodies (device reset,
|
||||
// web-browser mode, driver warnings) have no platform counterpart yet.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpDevice.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
#include "EterBase/Stl.h"
|
||||
|
||||
#include "CpuBuffer.h"
|
||||
#include "RecordingDevice.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
bool GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = false;
|
||||
bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = false;
|
||||
bool GRAPHICS_CAPS_HALF_SIZE_IMAGE = false;
|
||||
bool GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER = false;
|
||||
bool GRAPHICS_CAPS_SOFTWARE_TILING = false;
|
||||
|
||||
CGraphicDevice::CGraphicDevice()
|
||||
: m_uBackBufferCount(0)
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
CGraphicDevice::~CGraphicDevice()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CGraphicDevice::InitBackBufferCount(UINT uBackBufferCount)
|
||||
{
|
||||
m_uBackBufferCount=uBackBufferCount;
|
||||
}
|
||||
|
||||
void CGraphicDevice::Destroy()
|
||||
{
|
||||
__DestroyPDTVertexBufferList();
|
||||
__DestroyDefaultIndexBufferList();
|
||||
|
||||
// PORT: no DC, vertex shader objects or D3DX meshes; the stream "shaders" are FVF codes.
|
||||
ms_ptVS = 0;
|
||||
ms_pntVS = 0;
|
||||
ms_pnt2VS = 0;
|
||||
|
||||
safe_release(ms_lpd3dMatStack);
|
||||
safe_release(ms_lpd3dDevice);
|
||||
|
||||
if (m_pStateManager)
|
||||
{
|
||||
delete m_pStateManager;
|
||||
m_pStateManager = NULL;
|
||||
}
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /*iBit*/, int iReflashRate)
|
||||
{
|
||||
int iRet = CREATE_OK;
|
||||
|
||||
Destroy();
|
||||
|
||||
ms_iWidth = iHres;
|
||||
ms_iHeight = iVres;
|
||||
|
||||
// PORT: in place of Direct3DCreate8, the display-mode detection and CreateDevice: the recording
|
||||
// device renders through Godot, which supports DXT and has no refresh-rate or T&L failures.
|
||||
ms_hWnd = hWnd;
|
||||
ms_lpd3dDevice = MtCreateRecordingDevice(iHres, iVres);
|
||||
ms_dwD3DBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
||||
ms_d3dPresentParameter.BackBufferWidth = iHres;
|
||||
ms_d3dPresentParameter.BackBufferHeight = iVres;
|
||||
ms_d3dPresentParameter.Windowed = Windowed;
|
||||
|
||||
if (FAILED((ms_hLastResult = ms_lpd3dDevice->GetDeviceCaps(&ms_d3dCaps))))
|
||||
{
|
||||
Tracenf("IDirect3DDevice.GetDeviceCaps - ERROR %d", ms_hLastResult);
|
||||
return CREATE_GET_DEVICE_CAPS2;
|
||||
}
|
||||
|
||||
ms_lpd3dDevice->GetViewport(&ms_Viewport);
|
||||
|
||||
m_pStateManager = new CStateManager(ms_lpd3dDevice);
|
||||
|
||||
D3DXCreateMatrixStack(0, &ms_lpd3dMatStack);
|
||||
ms_lpd3dMatStack->LoadIdentity();
|
||||
|
||||
ms_ptVS = CreatePTStreamVertexShader();
|
||||
ms_pntVS = CreatePNTStreamVertexShader();
|
||||
ms_pnt2VS = CreatePNT2StreamVertexShader();
|
||||
|
||||
D3DXMatrixIdentity(&ms_matIdentity);
|
||||
D3DXMatrixIdentity(&ms_matView);
|
||||
D3DXMatrixIdentity(&ms_matProj);
|
||||
D3DXMatrixIdentity(&ms_matInverseView);
|
||||
D3DXMatrixIdentity(&ms_matInverseViewYAxis);
|
||||
D3DXMatrixIdentity(&ms_matWorld);
|
||||
D3DXMatrixIdentity(&ms_matWorldView);
|
||||
D3DXMatrixIdentity(&ms_matScreen0);
|
||||
D3DXMatrixIdentity(&ms_matScreen1);
|
||||
D3DXMatrixIdentity(&ms_matScreen2);
|
||||
|
||||
ms_matScreen0._11 = 1;
|
||||
ms_matScreen0._22 = -1;
|
||||
|
||||
ms_matScreen1._41 = 1;
|
||||
ms_matScreen1._42 = 1;
|
||||
|
||||
ms_matScreen2._11 = (float) iHres / 2;
|
||||
ms_matScreen2._22 = (float) iVres / 2;
|
||||
|
||||
// PORT: no D3DXCreateSphere/D3DXCreateCylinder (debug collision rendering) and no Clear.
|
||||
|
||||
if (!__CreateDefaultIndexBufferList())
|
||||
return false;
|
||||
|
||||
if (!__CreatePDTVertexBufferList())
|
||||
return false;
|
||||
|
||||
DWORD dwTexMemSize = GetAvailableTextureMemory();
|
||||
|
||||
if (dwTexMemSize < 64 * 1024 * 1024)
|
||||
ms_isLowTextureMemory = true;
|
||||
else
|
||||
ms_isLowTextureMemory = false;
|
||||
|
||||
if (dwTexMemSize > 100 * 1024 * 1024)
|
||||
ms_isHighTextureMemory = true;
|
||||
else
|
||||
ms_isHighTextureMemory = false;
|
||||
|
||||
if (ms_d3dCaps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER)
|
||||
GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=false;
|
||||
else
|
||||
GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=true;
|
||||
|
||||
// PORT: the SIS/3dfx driver checks have no adapter identifier to test.
|
||||
return (iRet);
|
||||
}
|
||||
|
||||
auto CGraphicDevice::GetDeviceState() -> EDeviceState
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<EDeviceState>();
|
||||
}
|
||||
|
||||
auto CGraphicDevice::Reset() -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CGraphicDevice::EnableWebBrowserMode(const RECT &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicDevice::DisableWebBrowserMode() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicDevice::MoveWebBrowserRect(const RECT &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicDevice::ResizeBackBuffer(UINT uWidth, UINT uHeight) -> bool
|
||||
{
|
||||
ms_iWidth = uWidth;
|
||||
ms_iHeight = uHeight;
|
||||
ms_d3dPresentParameter.BackBufferWidth = uWidth;
|
||||
ms_d3dPresentParameter.BackBufferHeight = uHeight;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto CGraphicDevice::RegisterWarningString(UINT, const char *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
void CGraphicDevice::__Initialize()
|
||||
{
|
||||
ms_iD3DAdapterInfo=D3DADAPTER_DEFAULT;
|
||||
ms_iD3DDevInfo=D3DADAPTER_DEFAULT;
|
||||
ms_iD3DModeInfo=D3DADAPTER_DEFAULT;
|
||||
|
||||
ms_lpd3d = NULL;
|
||||
ms_lpd3dDevice = NULL;
|
||||
ms_lpd3dMatStack = NULL;
|
||||
|
||||
ms_dwWavingEndTime = 0;
|
||||
ms_dwFlashingEndTime = 0;
|
||||
|
||||
m_pStateManager = NULL;
|
||||
|
||||
__InitializeDefaultIndexBufferList();
|
||||
__InitializePDTVertexBufferList();
|
||||
}
|
||||
|
||||
auto CGraphicDevice::__IsInDriverBlackList(D3D_CAdapterInfo &) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CGraphicDevice::__WarningMessage(HWND, UINT) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
void CGraphicDevice::__InitializeDefaultIndexBufferList()
|
||||
{
|
||||
for (UINT i=0; i<DEFAULT_IB_NUM; ++i)
|
||||
ms_alpd3dDefIB[i]=NULL;
|
||||
}
|
||||
|
||||
void CGraphicDevice::__DestroyDefaultIndexBufferList()
|
||||
{
|
||||
for (UINT i=0; i<DEFAULT_IB_NUM; ++i)
|
||||
if (ms_alpd3dDefIB[i])
|
||||
{
|
||||
delete ms_alpd3dDefIB[i]; // PORT: CPU buffer, no Release
|
||||
ms_alpd3dDefIB[i]=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool CGraphicDevice::__CreateDefaultIndexBufferList()
|
||||
{
|
||||
static const WORD c_awLineIndices[2] = { 0, 1, };
|
||||
static const WORD c_awLineTriIndices[6] = { 0, 1, 0, 2, 1, 2, };
|
||||
static const WORD c_awLineRectIndices[8] = { 0, 1, 0, 2, 1, 3, 2, 3,};
|
||||
static const WORD c_awLineCubeIndices[24] = {
|
||||
0, 1, 0, 2, 1, 3, 2, 3,
|
||||
0, 4, 1, 5, 2, 6, 3, 7,
|
||||
4, 5, 4, 6, 5, 7, 6, 7,
|
||||
};
|
||||
static const WORD c_awFillTriIndices[3]= { 0, 1, 2, };
|
||||
static const WORD c_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, };
|
||||
static const WORD c_awFillCubeIndices[36] = {
|
||||
0, 1, 2, 1, 3, 2,
|
||||
2, 0, 6, 0, 4, 6,
|
||||
0, 1, 4, 1, 5, 4,
|
||||
1, 3, 5, 3, 7, 5,
|
||||
3, 2, 7, 2, 6, 7,
|
||||
4, 5, 6, 5, 7, 6,
|
||||
};
|
||||
|
||||
if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE, 2, c_awLineIndices))
|
||||
return false;
|
||||
if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_TRI, 6, c_awLineTriIndices))
|
||||
return false;
|
||||
if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_RECT, 8, c_awLineRectIndices))
|
||||
return false;
|
||||
if (!__CreateDefaultIndexBuffer(DEFAULT_IB_LINE_CUBE, 24, c_awLineCubeIndices))
|
||||
return false;
|
||||
if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_TRI, 3, c_awFillTriIndices))
|
||||
return false;
|
||||
if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_RECT, 6, c_awFillRectIndices))
|
||||
return false;
|
||||
if (!__CreateDefaultIndexBuffer(DEFAULT_IB_FILL_CUBE, 36, c_awFillCubeIndices))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicDevice::__CreateDefaultIndexBuffer(UINT eDefIB, UINT uIdxCount, const WORD* c_awIndices)
|
||||
{
|
||||
assert(ms_alpd3dDefIB[eDefIB]==NULL);
|
||||
|
||||
// PORT: a CPU buffer in place of CreateIndexBuffer (CpuBuffer.h).
|
||||
MtCpuIndexBuffer* pIB = new MtCpuIndexBuffer;
|
||||
pIB->bytes.resize(sizeof(WORD)*uIdxCount);
|
||||
pIB->format = D3DFMT_INDEX16;
|
||||
ms_alpd3dDefIB[eDefIB] = pIB;
|
||||
|
||||
WORD* dstIndices;
|
||||
if (FAILED(
|
||||
ms_alpd3dDefIB[eDefIB]->Lock(0, 0, (BYTE**)&dstIndices, 0)
|
||||
)) return false;
|
||||
|
||||
memcpy(dstIndices, c_awIndices, sizeof(WORD)*uIdxCount);
|
||||
|
||||
ms_alpd3dDefIB[eDefIB]->Unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicDevice::__InitializePDTVertexBufferList()
|
||||
{
|
||||
for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
|
||||
ms_alpd3dPDTVB[i]=NULL;
|
||||
}
|
||||
|
||||
void CGraphicDevice::__DestroyPDTVertexBufferList()
|
||||
{
|
||||
for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
|
||||
{
|
||||
if (ms_alpd3dPDTVB[i])
|
||||
{
|
||||
delete ms_alpd3dPDTVB[i]; // PORT: CPU buffer, no Release
|
||||
ms_alpd3dPDTVB[i]=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CGraphicDevice::__CreatePDTVertexBufferList()
|
||||
{
|
||||
for (UINT i=0; i<PDT_VERTEXBUFFER_NUM; ++i)
|
||||
{
|
||||
// PORT: a CPU buffer in place of CreateVertexBuffer (CpuBuffer.h).
|
||||
MtCpuVertexBuffer* pVB = new MtCpuVertexBuffer;
|
||||
pVB->bytes.resize(sizeof(TPDTVertex)*PDT_VERTEX_NUM);
|
||||
pVB->fvf = D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1;
|
||||
ms_alpd3dPDTVB[i] = pVB;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// PORT: the stream vertex shaders are declarations for the fixed-function pipeline; the recording
|
||||
// device decodes vertices by FVF, so each returns the FVF matching its declaration. PT keeps its
|
||||
// texture coordinates in stream 1, which the device does not record: stream 0 is position only.
|
||||
DWORD CGraphicDevice::CreatePTStreamVertexShader()
|
||||
{
|
||||
assert(ms_lpd3dDevice != NULL);
|
||||
return D3DFVF_XYZ;
|
||||
}
|
||||
|
||||
DWORD CGraphicDevice::CreatePNTStreamVertexShader()
|
||||
{
|
||||
assert(ms_lpd3dDevice != NULL);
|
||||
return D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1;
|
||||
}
|
||||
|
||||
DWORD CGraphicDevice::CreatePNT2StreamVertexShader()
|
||||
{
|
||||
assert(ms_lpd3dDevice != NULL);
|
||||
return D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX2;
|
||||
}
|
||||
|
||||
auto CGraphicDevice::CreateDoublePNTStreamVertexShader() -> DWORD
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<DWORD>();
|
||||
}
|
||||
|
||||
// 40250 GrpDevice.cpp:298-306; s_MaxTextureWidth/Height come from D3DCAPS8 in __CheckD3DCaps.
|
||||
// PORT: 4096 is the texture size every Godot renderer on the target GPUs supports.
|
||||
static DWORD s_MaxTextureWidth = 4096, s_MaxTextureHeight = 4096;
|
||||
|
||||
DWORD GetMaxTextureWidth()
|
||||
{
|
||||
return s_MaxTextureWidth;
|
||||
}
|
||||
|
||||
DWORD GetMaxTextureHeight()
|
||||
{
|
||||
return s_MaxTextureHeight;
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
// Platform skeleton for EterLib/GrpExpandedImageInstance.h (40250 EterLib/GrpExpandedImageInstance.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpExpandedImageInstance.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
#include "EterBase/CRC32.h"
|
||||
#include "UIRenderCommands.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
auto CGraphicExpandedImageInstance::Type() -> DWORD
|
||||
{
|
||||
static DWORD type = GetCRC32("CGraphicExpandedImageInstance", sizeof("CGraphicExpandedImageInstance") - 1);
|
||||
return type;
|
||||
}
|
||||
|
||||
CGraphicExpandedImageInstance::CGraphicExpandedImageInstance()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CGraphicExpandedImageInstance::~CGraphicExpandedImageInstance()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::Destroy() -> void
|
||||
{
|
||||
CGraphicImageInstance::Destroy();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::SetDepth(float depth) -> void
|
||||
{
|
||||
m_fDepth = depth;
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::SetOrigin() -> void
|
||||
{
|
||||
m_v2Origin = D3DXVECTOR2(GetWidth() * 0.5f, GetHeight() * 0.5f);
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::SetOrigin(float x, float y) -> void
|
||||
{
|
||||
m_v2Origin = D3DXVECTOR2(x, y);
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::SetRotation(float rotation) -> void
|
||||
{
|
||||
m_fRotation = rotation;
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::SetScale(float x, float y) -> void
|
||||
{
|
||||
m_v2Scale = D3DXVECTOR2(x, y);
|
||||
}
|
||||
|
||||
// In 40250, the arguments are fractions of the image size (uiToolTip gauges, SetPercentage).
|
||||
auto CGraphicExpandedImageInstance::SetRenderingRect(float fLeft, float fTop, float fRight, float fBottom) -> void
|
||||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
float fWidth = float(GetWidth());
|
||||
float fHeight = float(GetHeight());
|
||||
|
||||
m_RenderingRect.left = fWidth * fLeft;
|
||||
m_RenderingRect.top = fHeight * fTop;
|
||||
m_RenderingRect.right = fWidth * fRight;
|
||||
m_RenderingRect.bottom = fHeight * fBottom;
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::SetRenderingMode(int mode) -> void
|
||||
{
|
||||
m_iRenderingMode = mode;
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::Initialize() -> void
|
||||
{
|
||||
m_fDepth = 0;
|
||||
m_v2Origin = D3DXVECTOR2(0, 0);
|
||||
m_v2Scale = D3DXVECTOR2(1, 1);
|
||||
m_fRotation = 0;
|
||||
m_RenderingRect = {0, 0, 0, 0};
|
||||
m_iRenderingMode = RENDERING_MODE_NORMAL;
|
||||
}
|
||||
|
||||
// 40250 GrpExpandedImageInstance.cpp:29-142. The vertex and texture-coordinate arithmetic is
|
||||
// verbatim; the D3D stream/blend-state calls become one UIRenderCommand with the four vertices.
|
||||
auto CGraphicExpandedImageInstance::OnRender() -> void
|
||||
{
|
||||
CGraphicImage * pImage = m_roImage.GetPointer();
|
||||
CGraphicTexture * pTexture = pImage->GetTexturePointer();
|
||||
if (pTexture->GetWidth() <= 0 || pTexture->GetHeight() <= 0)
|
||||
return;
|
||||
|
||||
const RECT& c_rRect = pImage->GetRectReference();
|
||||
float texReverseWidth = 1.0f / float(pTexture->GetWidth());
|
||||
float texReverseHeight = 1.0f / float(pTexture->GetHeight());
|
||||
float su = (c_rRect.left - m_RenderingRect.left) * texReverseWidth;
|
||||
float sv = (c_rRect.top - m_RenderingRect.top) * texReverseHeight;
|
||||
float eu = (c_rRect.left + m_RenderingRect.right + (c_rRect.right-c_rRect.left)) * texReverseWidth;
|
||||
float ev = (c_rRect.top + m_RenderingRect.bottom + (c_rRect.bottom-c_rRect.top)) * texReverseHeight;
|
||||
|
||||
float x[4], y[4];
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
x[i] = m_v2Position.x-0.5f;
|
||||
y[i] = m_v2Position.y-0.5f;
|
||||
}
|
||||
|
||||
if (0.0f == m_fRotation)
|
||||
{
|
||||
float fimgWidth = float(pImage->GetWidth()) * m_v2Scale.x;
|
||||
float fimgHeight = float(pImage->GetHeight()) * m_v2Scale.y;
|
||||
|
||||
x[0] -= m_RenderingRect.left;
|
||||
y[0] -= m_RenderingRect.top;
|
||||
x[1] += fimgWidth + m_RenderingRect.right;
|
||||
y[1] -= m_RenderingRect.top;
|
||||
x[2] -= m_RenderingRect.left;
|
||||
y[2] += fimgHeight + m_RenderingRect.bottom;
|
||||
x[3] += fimgWidth + m_RenderingRect.right;
|
||||
y[3] += fimgHeight + m_RenderingRect.bottom;
|
||||
// PORT: 40250 flips D3DRS_CULLMODE for a mirrored scale; the Godot canvas has no culling.
|
||||
}
|
||||
else
|
||||
{
|
||||
float fimgHalfWidth = float(pImage->GetWidth())/2.0f * m_v2Scale.x;
|
||||
float fimgHalfHeight = float(pImage->GetHeight())/2.0f * m_v2Scale.y;
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
x[i] += m_v2Origin.x;
|
||||
y[i] += m_v2Origin.y;
|
||||
}
|
||||
|
||||
float fRadian = D3DXToRadian(m_fRotation);
|
||||
x[0] += (-fimgHalfWidth*cosf(fRadian)) - (-fimgHalfHeight*sinf(fRadian));
|
||||
y[0] += (-fimgHalfWidth*sinf(fRadian)) + (-fimgHalfHeight*cosf(fRadian));
|
||||
x[1] += (+fimgHalfWidth*cosf(fRadian)) - (-fimgHalfHeight*sinf(fRadian));
|
||||
y[1] += (+fimgHalfWidth*sinf(fRadian)) + (-fimgHalfHeight*cosf(fRadian));
|
||||
x[2] += (-fimgHalfWidth*cosf(fRadian)) - (+fimgHalfHeight*sinf(fRadian));
|
||||
y[2] += (-fimgHalfWidth*sinf(fRadian)) + (+fimgHalfHeight*cosf(fRadian));
|
||||
x[3] += (+fimgHalfWidth*cosf(fRadian)) - (+fimgHalfHeight*sinf(fRadian));
|
||||
y[3] += (+fimgHalfWidth*sinf(fRadian)) + (+fimgHalfHeight*cosf(fRadian));
|
||||
}
|
||||
|
||||
UIRenderAddImage(pTexture, x, y, su, sv, eu, ev, UIRenderColor(m_DiffuseColor), m_iRenderingMode);
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::OnSetImagePointer() -> void
|
||||
{
|
||||
if (!IsEmpty()) SetOrigin();
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::OnIsType(DWORD type) -> BOOL
|
||||
{
|
||||
return type == Type() || CGraphicImageInstance::OnIsType(type);
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::CreateSystem(UINT) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::DestroySystem() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::New() -> CGraphicExpandedImageInstance *
|
||||
{
|
||||
return new CGraphicExpandedImageInstance();
|
||||
}
|
||||
|
||||
auto CGraphicExpandedImageInstance::Delete(CGraphicExpandedImageInstance *instance) -> void
|
||||
{
|
||||
if (!instance) return;
|
||||
instance->Destroy();
|
||||
delete instance;
|
||||
}
|
||||
|
||||
decltype(CGraphicExpandedImageInstance::ms_kPool) CGraphicExpandedImageInstance::ms_kPool{};
|
||||
@@ -0,0 +1,386 @@
|
||||
// 40250 EterLib/GrpFontTexture.cpp, verbatim over the GDI emulation in platform/Win32Gdi.cpp. The
|
||||
// A4R4G4B4 page textures are CGraphicImageTexture memory textures the Godot canvas samples.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpText.h"
|
||||
#include "EterBase/Stl.h"
|
||||
|
||||
#include "EterLib/Util.h"
|
||||
#include "UIRenderCommands.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
// PORT: HiDPI glyph pages (UISetFontOversample). With a scale s > 1 the page DIB and texture are
|
||||
// s times larger and each glyph is drawn with an s-times font into the s-scaled cell, while the
|
||||
// 40250 metrics (width, height, advance), the packing and therefore the page UVs stay the logical
|
||||
// 1x values: text layout is unchanged, only the texels get finer.
|
||||
namespace {
|
||||
int g_font_oversample = 1;
|
||||
bool g_font_oversample_latched = false;
|
||||
// The 1x HFONT a CGraphicFontTexture measures with -> its s-times twin that draws.
|
||||
std::unordered_map<HFONT, HFONT> g_oversampled_fonts;
|
||||
|
||||
int FontOversample()
|
||||
{
|
||||
g_font_oversample_latched = true;
|
||||
return g_font_oversample;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void UISetFontOversample(int scale)
|
||||
{
|
||||
if (g_font_oversample_latched)
|
||||
return;
|
||||
g_font_oversample = scale < 1 ? 1 : (scale > 4 ? 4 : scale);
|
||||
}
|
||||
|
||||
int UIFontOversample()
|
||||
{
|
||||
return g_font_oversample;
|
||||
}
|
||||
|
||||
CGraphicFontTexture::CGraphicFontTexture()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CGraphicFontTexture::~CGraphicFontTexture()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CGraphicFontTexture::Initialize()
|
||||
{
|
||||
CGraphicTexture::Initialize();
|
||||
m_hFontOld = NULL;
|
||||
m_hFont = NULL;
|
||||
m_isDirty = false;
|
||||
m_bItalic = false;
|
||||
}
|
||||
|
||||
bool CGraphicFontTexture::IsEmpty() const
|
||||
{
|
||||
return m_fontMap.size() == 0;
|
||||
}
|
||||
|
||||
void CGraphicFontTexture::Destroy()
|
||||
{
|
||||
HDC hDC = m_dib.GetDCHandle();
|
||||
if (hDC)
|
||||
SelectObject(hDC, m_hFontOld);
|
||||
|
||||
m_dib.Destroy();
|
||||
|
||||
m_lpd3dTexture = NULL;
|
||||
CGraphicTexture::Destroy();
|
||||
stl_wipe(m_pFontTextureVector);
|
||||
m_charInfoMap.clear();
|
||||
|
||||
if (m_fontMap.size())
|
||||
{
|
||||
TFontMap::iterator i = m_fontMap.begin();
|
||||
|
||||
while(i != m_fontMap.end())
|
||||
{
|
||||
TFontMap::mapped_type hFont = i->second;
|
||||
auto hi = g_oversampled_fonts.find(hFont);
|
||||
if (hi != g_oversampled_fonts.end())
|
||||
{
|
||||
DeleteObject((HGDIOBJ)hi->second);
|
||||
g_oversampled_fonts.erase(hi);
|
||||
}
|
||||
DeleteObject((HGDIOBJ)i->second);
|
||||
++i;
|
||||
}
|
||||
|
||||
m_fontMap.clear();
|
||||
}
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
bool CGraphicFontTexture::CreateDeviceObjects()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicFontTexture::DestroyDeviceObjects()
|
||||
{
|
||||
}
|
||||
|
||||
bool CGraphicFontTexture::Create(const char* c_szFontName, int fontSize, bool bItalic)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
strncpy(m_fontName, c_szFontName, sizeof(m_fontName)-1);
|
||||
m_fontSize = fontSize;
|
||||
m_bItalic = bItalic;
|
||||
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
m_step = 0;
|
||||
|
||||
DWORD width = 256,height = 256;
|
||||
if (GetMaxTextureWidth() > 512)
|
||||
width = 512;
|
||||
if (GetMaxTextureHeight() > 512)
|
||||
height = 512;
|
||||
|
||||
const int s = FontOversample();
|
||||
if (!m_dib.Create(ms_hDC, width * s, height * s))
|
||||
return false;
|
||||
|
||||
HDC hDC = m_dib.GetDCHandle();
|
||||
|
||||
m_hFont = GetFont(GetDefaultCodePage());
|
||||
|
||||
m_hFontOld=(HFONT)SelectObject(hDC, m_hFont);
|
||||
SetTextColor(hDC, RGB(255, 255, 255));
|
||||
SetBkColor(hDC, 0);
|
||||
|
||||
if (!AppendTexture())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
HFONT CGraphicFontTexture::GetFont(WORD codePage)
|
||||
{
|
||||
HFONT hFont = NULL;
|
||||
TFontMap::iterator i = m_fontMap.find(codePage);
|
||||
|
||||
if(i != m_fontMap.end())
|
||||
{
|
||||
hFont = i->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGFONT logFont;
|
||||
|
||||
memset(&logFont, 0, sizeof(LOGFONT));
|
||||
|
||||
logFont.lfHeight = m_fontSize;
|
||||
logFont.lfEscapement = 0;
|
||||
logFont.lfOrientation = 0;
|
||||
logFont.lfWeight = FW_NORMAL;
|
||||
logFont.lfItalic = (BYTE) m_bItalic;
|
||||
logFont.lfUnderline = FALSE;
|
||||
logFont.lfStrikeOut = FALSE;
|
||||
logFont.lfCharSet = GetCharsetFromCodePage(codePage);
|
||||
logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
|
||||
logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
logFont.lfQuality = ANTIALIASED_QUALITY;
|
||||
logFont.lfPitchAndFamily = DEFAULT_PITCH;
|
||||
//Tracenf("font: %s", GetFontFaceFromCodePage(codePage));
|
||||
strcpy(logFont.lfFaceName, m_fontName); //GetFontFaceFromCodePage(codePage));
|
||||
//strcpy(logFont.lfFaceName, GetFontFaceFromCodePage(codePage));
|
||||
|
||||
hFont = CreateFontIndirect(&logFont);
|
||||
|
||||
m_fontMap.insert(TFontMap::value_type(codePage, hFont));
|
||||
|
||||
if (const int s = FontOversample(); s > 1 && hFont)
|
||||
{
|
||||
logFont.lfHeight = m_fontSize * s;
|
||||
if (HFONT hHiFont = CreateFontIndirect(&logFont))
|
||||
g_oversampled_fonts[hFont] = hHiFont;
|
||||
}
|
||||
}
|
||||
|
||||
return hFont;
|
||||
}
|
||||
|
||||
bool CGraphicFontTexture::AppendTexture()
|
||||
{
|
||||
CGraphicImageTexture * pNewTexture = new CGraphicImageTexture;
|
||||
|
||||
if (!pNewTexture->Create(m_dib.GetWidth(), m_dib.GetHeight(), D3DFMT_A4R4G4B4))
|
||||
{
|
||||
delete pNewTexture;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pFontTextureVector.push_back(pNewTexture);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicFontTexture::UpdateTexture()
|
||||
{
|
||||
if(!m_isDirty)
|
||||
return true;
|
||||
|
||||
m_isDirty = false;
|
||||
|
||||
CGraphicImageTexture * pFontTexture = m_pFontTextureVector.back();
|
||||
|
||||
if (!pFontTexture)
|
||||
return false;
|
||||
|
||||
WORD* pwDst;
|
||||
int pitch;
|
||||
|
||||
if (!pFontTexture->Lock(&pitch, (void**)&pwDst))
|
||||
return false;
|
||||
|
||||
pitch /= 2;
|
||||
|
||||
int width = m_dib.GetWidth();
|
||||
int height = m_dib.GetHeight();
|
||||
|
||||
DWORD * pdwSrc = (DWORD*)m_dib.GetPointer();
|
||||
|
||||
for (int y = 0; y < height; ++y, pwDst += pitch, pdwSrc += width)
|
||||
for (int x = 0; x < width; ++x)
|
||||
pwDst[x]=pdwSrc[x];
|
||||
|
||||
pFontTexture->Unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
CGraphicFontTexture::TCharacterInfomation* CGraphicFontTexture::GetCharacterInfomation(WORD codePage, wchar_t keyValue)
|
||||
{
|
||||
TCharacterKey code(codePage, keyValue);
|
||||
|
||||
TCharacterInfomationMap::iterator f = m_charInfoMap.find(code);
|
||||
|
||||
if (m_charInfoMap.end() == f)
|
||||
{
|
||||
return UpdateCharacterInfomation(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
return &f->second;
|
||||
}
|
||||
}
|
||||
|
||||
CGraphicFontTexture::TCharacterInfomation* CGraphicFontTexture::UpdateCharacterInfomation(TCharacterKey code)
|
||||
{
|
||||
HDC hDC = m_dib.GetDCHandle();
|
||||
HFONT hFont = GetFont(code.first);
|
||||
SelectObject(hDC, hFont);
|
||||
|
||||
wchar_t keyValue = code.second;
|
||||
|
||||
if (keyValue == 0x08)
|
||||
keyValue = L' '; // 탭은 공백으로 바꾼다 (아랍 출력시 탭 사용: NAME:\tTEXT -> TEXT\t:NAME 로 전환됨 )
|
||||
|
||||
ABCFLOAT stABC;
|
||||
SIZE size;
|
||||
|
||||
if (!GetTextExtentPoint32W(hDC, &keyValue, 1, &size) || !GetCharABCWidthsFloatW(hDC, keyValue, keyValue, &stABC))
|
||||
return NULL;
|
||||
|
||||
size.cx = stABC.abcfB;
|
||||
if( stABC.abcfA > 0.0f )
|
||||
size.cx += ceilf(stABC.abcfA);
|
||||
if( stABC.abcfC > 0.0f )
|
||||
size.cx += ceilf(stABC.abcfC);
|
||||
size.cx++;
|
||||
|
||||
LONG lAdvance = ceilf( stABC.abcfA + stABC.abcfB + stABC.abcfC );
|
||||
|
||||
const int s = FontOversample();
|
||||
int width = m_dib.GetWidth() / s;
|
||||
int height = m_dib.GetHeight() / s;
|
||||
|
||||
if (m_x + size.cx >= (width - 1))
|
||||
{
|
||||
m_y += (m_step + 1);
|
||||
m_step = 0;
|
||||
m_x = 0;
|
||||
|
||||
if (m_y + size.cy >= (height - 1))
|
||||
{
|
||||
if (!UpdateTexture())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!AppendTexture())
|
||||
return NULL;
|
||||
|
||||
m_y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
auto hi = s > 1 ? g_oversampled_fonts.find(hFont) : g_oversampled_fonts.end();
|
||||
if (hi != g_oversampled_fonts.end())
|
||||
{
|
||||
// Draw with the s-times font into the s-scaled cell and keep its anti-aliasing as
|
||||
// A4R4G4B4 white with coverage alpha (1x keeps 40250's bilevel threshold below).
|
||||
SelectObject(hDC, hi->second);
|
||||
TextOutW(hDC, m_x * s, m_y * s, &keyValue, 1);
|
||||
SelectObject(hDC, hFont);
|
||||
|
||||
const int nDIBWidth = m_dib.GetWidth();
|
||||
DWORD* pdwRow = (DWORD*)m_dib.GetPointer() + nDIBWidth * (m_y * s) + m_x * s;
|
||||
for (int y = 0; y < size.cy * s; ++y, pdwRow += nDIBWidth)
|
||||
for (int x = 0; x < size.cx * s; ++x)
|
||||
{
|
||||
const DWORD alpha = ((pdwRow[x] & 0xff) * 15 + 127) / 255;
|
||||
pdwRow[x] = alpha ? ((alpha << 12) | 0x0fff) : 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TextOutW(hDC, m_x, m_y, &keyValue, 1);
|
||||
|
||||
int nChrX;
|
||||
int nChrY;
|
||||
int nChrWidth = size.cx;
|
||||
int nChrHeight = size.cy;
|
||||
int nDIBWidth = m_dib.GetWidth();
|
||||
|
||||
|
||||
DWORD*pdwDIBData=(DWORD*)m_dib.GetPointer();
|
||||
DWORD*pdwDIBBase=pdwDIBData+nDIBWidth*m_y+m_x;
|
||||
DWORD*pdwDIBRow;
|
||||
|
||||
pdwDIBRow=pdwDIBBase;
|
||||
for (nChrY=0; nChrY<nChrHeight; ++nChrY, pdwDIBRow+=nDIBWidth)
|
||||
{
|
||||
for (nChrX=0; nChrX<nChrWidth; ++nChrX)
|
||||
{
|
||||
pdwDIBRow[nChrX]=(pdwDIBRow[nChrX]&0xff) ? 0xffff : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float rhwidth = 1.0f / float(width);
|
||||
float rhheight = 1.0f / float(height);
|
||||
|
||||
TCharacterInfomation& rNewCharInfo = m_charInfoMap[code];
|
||||
|
||||
rNewCharInfo.index = static_cast<short>(m_pFontTextureVector.size() - 1);
|
||||
rNewCharInfo.width = size.cx;
|
||||
rNewCharInfo.height = size.cy;
|
||||
rNewCharInfo.left = float(m_x) * rhwidth;
|
||||
rNewCharInfo.top = float(m_y) * rhheight;
|
||||
rNewCharInfo.right = float(m_x+size.cx) * rhwidth;
|
||||
rNewCharInfo.bottom = float(m_y+size.cy) * rhheight;
|
||||
rNewCharInfo.advance = (float) lAdvance;
|
||||
|
||||
m_x += size.cx;
|
||||
|
||||
if (m_step < size.cy)
|
||||
m_step = size.cy;
|
||||
|
||||
m_isDirty = true;
|
||||
|
||||
return &rNewCharInfo;
|
||||
}
|
||||
|
||||
bool CGraphicFontTexture::CheckTextureIndex(DWORD dwTexture)
|
||||
{
|
||||
if (dwTexture >= m_pFontTextureVector.size())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicFontTexture::SelectTexture(DWORD dwTexture)
|
||||
{
|
||||
assert(CheckTextureIndex(dwTexture));
|
||||
m_lpd3dTexture = m_pFontTextureVector[dwTexture]->GetD3DTexture();
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// Platform skeleton for EterLib/GrpImage.h (40250 EterLib/GrpImage.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpImage.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
auto CGraphicImage::Type() -> TType
|
||||
{
|
||||
static TType type = StringToType("CGraphicImage");
|
||||
return type;
|
||||
}
|
||||
|
||||
CGraphicImage::CGraphicImage(const char * c_szFileName, DWORD dwFilter) : CResource(c_szFileName), m_dwFilter(dwFilter) // initializers as in 40250
|
||||
{
|
||||
m_rect = {0, 0, 0, 0};
|
||||
}
|
||||
|
||||
CGraphicImage::~CGraphicImage()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicImage::CreateDeviceObjects() -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CGraphicImage::DestroyDeviceObjects() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicImage::GetWidth() const -> int
|
||||
{
|
||||
return m_rect.right - m_rect.left;
|
||||
}
|
||||
|
||||
auto CGraphicImage::GetHeight() const -> int
|
||||
{
|
||||
return m_rect.bottom - m_rect.top;
|
||||
}
|
||||
|
||||
auto CGraphicImage::GetRectReference() const -> const RECT &
|
||||
{
|
||||
return m_rect;
|
||||
}
|
||||
|
||||
auto CGraphicImage::GetTextureReference() const -> const CGraphicTexture &
|
||||
{
|
||||
return m_imageTexture;
|
||||
}
|
||||
|
||||
auto CGraphicImage::GetTexturePointer() -> CGraphicTexture *
|
||||
{
|
||||
return &m_imageTexture;
|
||||
}
|
||||
|
||||
auto CGraphicImage::OnLoad(int size, const void *data) -> bool
|
||||
{
|
||||
m_imageTexture.SetFileName(GetFileName());
|
||||
if (!m_imageTexture.CreateFromMemoryFile(size, data, D3DFMT_UNKNOWN, m_dwFilter)) return false;
|
||||
m_rect = {0, 0, m_imageTexture.GetWidth(), m_imageTexture.GetHeight()};
|
||||
return true;
|
||||
}
|
||||
|
||||
auto CGraphicImage::OnClear() -> void
|
||||
{
|
||||
m_imageTexture.Destroy();
|
||||
m_rect = {0, 0, 0, 0};
|
||||
}
|
||||
|
||||
auto CGraphicImage::OnIsEmpty() const -> bool
|
||||
{
|
||||
return m_imageTexture.IsEmpty();
|
||||
}
|
||||
|
||||
auto CGraphicImage::OnIsType(TType type) -> bool
|
||||
{
|
||||
return type == Type() || CResource::OnIsType(type);
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
// Platform skeleton for EterLib/GrpImageInstance.h (40250 EterLib/GrpImageInstance.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpImageInstance.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
#include "UIRenderCommands.h"
|
||||
#include "EterBase/CRC32.h"
|
||||
|
||||
auto CGraphicImageInstance::Type() -> DWORD
|
||||
{
|
||||
static DWORD type = GetCRC32("CGraphicImageInstance", sizeof("CGraphicImageInstance") - 1);
|
||||
return type;
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::IsType(DWORD type) -> BOOL
|
||||
{
|
||||
return OnIsType(type);
|
||||
}
|
||||
|
||||
CGraphicImageInstance::CGraphicImageInstance()
|
||||
{
|
||||
m_DiffuseColor = D3DXCOLOR(1, 1, 1, 1);
|
||||
m_v2Position = D3DXVECTOR2(0, 0);
|
||||
}
|
||||
|
||||
CGraphicImageInstance::~CGraphicImageInstance()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
// 40250 Destroy(): drop the image reference, then Initialize() (white, at the origin).
|
||||
auto CGraphicImageInstance::Destroy() -> void
|
||||
{
|
||||
m_roImage.Clear();
|
||||
m_DiffuseColor = D3DXCOLOR(1, 1, 1, 1);
|
||||
m_v2Position = D3DXVECTOR2(0, 0);
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::Render() -> void
|
||||
{
|
||||
if (!IsEmpty()) OnRender();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::SetDiffuseColor(float r, float g, float b, float a) -> void
|
||||
{
|
||||
m_DiffuseColor = D3DXCOLOR(r, g, b, a);
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::SetPosition(float x, float y) -> void
|
||||
{
|
||||
m_v2Position = D3DXVECTOR2(x, y);
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::SetImagePointer(CGraphicImage *image) -> void
|
||||
{
|
||||
m_roImage.SetPointer(image);
|
||||
OnSetImagePointer();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::ReloadImagePointer(CGraphicImage *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::IsEmpty() const -> bool
|
||||
{
|
||||
return m_roImage.IsNull() || m_roImage->IsEmpty();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::GetWidth() -> int
|
||||
{
|
||||
return IsEmpty() ? 0 : m_roImage->GetWidth();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::GetHeight() -> int
|
||||
{
|
||||
return IsEmpty() ? 0 : m_roImage->GetHeight();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::GetTexturePointer() -> CGraphicTexture *
|
||||
{
|
||||
CGraphicImage* pkImage = m_roImage.GetPointer();
|
||||
return pkImage ? pkImage->GetTexturePointer() : NULL;
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::GetTextureReference() const -> const CGraphicTexture &
|
||||
{
|
||||
return m_roImage->GetTextureReference();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::GetGraphicImagePointer() -> CGraphicImage *
|
||||
{
|
||||
return m_roImage.GetPointer();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::operator==(const CGraphicImageInstance &) const -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::Initialize() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
// 40250 GrpImageInstance.cpp:44-96: the image's rect inside its texture (a .sub shares its parent's)
|
||||
// becomes the texture coordinates of one quad.
|
||||
auto CGraphicImageInstance::OnRender() -> void
|
||||
{
|
||||
CGraphicImage * pImage = m_roImage.GetPointer();
|
||||
CGraphicTexture * pTexture = pImage->GetTexturePointer();
|
||||
if (pTexture->GetWidth() <= 0 || pTexture->GetHeight() <= 0)
|
||||
return;
|
||||
|
||||
float fimgWidth = pImage->GetWidth();
|
||||
float fimgHeight = pImage->GetHeight();
|
||||
|
||||
const RECT& c_rRect = pImage->GetRectReference();
|
||||
float texReverseWidth = 1.0f / float(pTexture->GetWidth());
|
||||
float texReverseHeight = 1.0f / float(pTexture->GetHeight());
|
||||
float su = c_rRect.left * texReverseWidth;
|
||||
float sv = c_rRect.top * texReverseHeight;
|
||||
float eu = (c_rRect.left + (c_rRect.right-c_rRect.left)) * texReverseWidth;
|
||||
float ev = (c_rRect.top + (c_rRect.bottom-c_rRect.top)) * texReverseHeight;
|
||||
|
||||
const float x[4] = {m_v2Position.x-0.5f, m_v2Position.x + fimgWidth-0.5f,
|
||||
m_v2Position.x-0.5f, m_v2Position.x + fimgWidth-0.5f};
|
||||
const float y[4] = {m_v2Position.y-0.5f, m_v2Position.y-0.5f,
|
||||
m_v2Position.y + fimgHeight-0.5f, m_v2Position.y + fimgHeight-0.5f};
|
||||
UIRenderAddImage(pTexture, x, y, su, sv, eu, ev, UIRenderColor(m_DiffuseColor));
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::OnSetImagePointer() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::OnIsType(DWORD type) -> BOOL
|
||||
{
|
||||
return type == Type();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::CreateSystem(UINT) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::DestroySystem() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::New() -> CGraphicImageInstance *
|
||||
{
|
||||
return new CGraphicImageInstance();
|
||||
}
|
||||
|
||||
auto CGraphicImageInstance::Delete(CGraphicImageInstance *instance) -> void
|
||||
{
|
||||
if (!instance) return;
|
||||
instance->Destroy();
|
||||
delete instance;
|
||||
}
|
||||
|
||||
decltype(CGraphicImageInstance::ms_kPool) CGraphicImageInstance::ms_kPool{};
|
||||
@@ -0,0 +1,338 @@
|
||||
// Platform skeleton for EterLib/GrpImageTexture.h (40250 EterLib/GrpImageTexture.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpImageTexture.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
#include "UIRenderCommands.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
||||
namespace {
|
||||
unsigned little16(const unsigned char* data) { return data[0] | (unsigned(data[1]) << 8); }
|
||||
unsigned little32(const unsigned char* data) { return little16(data) | (little16(data + 2) << 16); }
|
||||
unsigned big16(const unsigned char* data) { return (unsigned(data[0]) << 8) | data[1]; }
|
||||
unsigned big32(const unsigned char* data) { return (unsigned(data[0]) << 24) | (unsigned(data[1]) << 16) | (unsigned(data[2]) << 8) | data[3]; }
|
||||
|
||||
// Walks the JPEG markers to the first SOFn (the frame header holds the size), as D3DX does when it
|
||||
// sniffs a .jpg; login/loading backgrounds (serverlist.jpg, loading/*.jpg) are JPEGs.
|
||||
bool jpeg_size(const unsigned char* data, unsigned size, unsigned* width, unsigned* height)
|
||||
{
|
||||
if (size < 4 || data[0] != 0xFF || data[1] != 0xD8) return false;
|
||||
unsigned pos = 2;
|
||||
while (pos + 4 <= size) {
|
||||
if (data[pos] != 0xFF) return false;
|
||||
const unsigned char marker = data[pos + 1];
|
||||
if (marker == 0xFF) { ++pos; continue; }
|
||||
if (marker == 0xD8 || marker == 0x01 || (marker >= 0xD0 && marker <= 0xD7)) { pos += 2; continue; }
|
||||
const unsigned length = big16(data + pos + 2);
|
||||
if (length < 2) return false;
|
||||
const bool sof = marker >= 0xC0 && marker <= 0xCF && marker != 0xC4 && marker != 0xC8 && marker != 0xCC;
|
||||
if (sof) {
|
||||
if (pos + 9 > size) return false;
|
||||
*height = big16(data + pos + 5);
|
||||
*width = big16(data + pos + 7);
|
||||
return true;
|
||||
}
|
||||
pos += 2 + length;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// PORT: the IDirect3DTexture8 behind a CGraphicImageTexture::Create texture. Lock hands out the
|
||||
// pixels in the texture's own format (40250 writes A4R4G4B4 words into the font pages); Unlock
|
||||
// converts them to ARGB32 for the canvas and bumps the revision in the texture's name.
|
||||
struct MemoryTexture : IDirect3DTexture8
|
||||
{
|
||||
unsigned id = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
D3DFORMAT format = D3DFMT_UNKNOWN;
|
||||
std::vector<unsigned char> native;
|
||||
std::vector<std::uint32_t> argb;
|
||||
std::uint32_t revision = 0;
|
||||
};
|
||||
|
||||
std::mutex g_memory_mutex;
|
||||
std::map<unsigned, MemoryTexture*> g_memory;
|
||||
unsigned g_memory_next_id = 1;
|
||||
|
||||
int bytes_per_pixel(D3DFORMAT format)
|
||||
{
|
||||
switch (format) {
|
||||
case D3DFMT_A4R4G4B4: case D3DFMT_R5G6B5: case D3DFMT_A1R5G5B5: case D3DFMT_X1R5G5B5: case D3DFMT_X4R4G4B4:
|
||||
return 2;
|
||||
default:
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
std::uint32_t expand(unsigned value, int bits)
|
||||
{
|
||||
return bits == 4 ? value * 0x11 : bits == 5 ? (value << 3) | (value >> 2) : bits == 6 ? (value << 2) | (value >> 4) : value;
|
||||
}
|
||||
|
||||
std::uint32_t native_to_argb(D3DFORMAT format, const unsigned char* p)
|
||||
{
|
||||
const unsigned w = p[0] | (unsigned(p[1]) << 8);
|
||||
switch (format) {
|
||||
case D3DFMT_A4R4G4B4:
|
||||
return (expand(w >> 12, 4) << 24) | (expand((w >> 8) & 15, 4) << 16) | (expand((w >> 4) & 15, 4) << 8) | expand(w & 15, 4);
|
||||
case D3DFMT_X4R4G4B4:
|
||||
return 0xFF000000u | (expand((w >> 8) & 15, 4) << 16) | (expand((w >> 4) & 15, 4) << 8) | expand(w & 15, 4);
|
||||
case D3DFMT_R5G6B5:
|
||||
return 0xFF000000u | (expand(w >> 11, 5) << 16) | (expand((w >> 5) & 63, 6) << 8) | expand(w & 31, 5);
|
||||
case D3DFMT_A1R5G5B5: case D3DFMT_X1R5G5B5:
|
||||
return ((format == D3DFMT_X1R5G5B5 || (w & 0x8000)) ? 0xFF000000u : 0) | (expand((w >> 10) & 31, 5) << 16) |
|
||||
(expand((w >> 5) & 31, 5) << 8) | expand(w & 31, 5);
|
||||
case D3DFMT_X8R8G8B8:
|
||||
return 0xFF000000u | (p[2] << 16) | (p[1] << 8) | p[0];
|
||||
default:
|
||||
return (std::uint32_t(p[3]) << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
|
||||
}
|
||||
}
|
||||
|
||||
MemoryTexture* live_memory_texture(const IDirect3DTexture8* texture)
|
||||
{
|
||||
for (const auto& entry : g_memory)
|
||||
if (entry.second == texture) return entry.second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// PORT: the IDirect3DTexture8 behind a file texture (CreateFromMemoryFile). The canvas and the 3D
|
||||
// renderer decode the file themselves; the handle only carries the pack path so a texture bound
|
||||
// through STATEMANAGER.SetTexture(stage, GetD3DTexture()) can be named.
|
||||
struct FileTexture : IDirect3DTexture8
|
||||
{
|
||||
std::string name;
|
||||
};
|
||||
|
||||
std::set<const FileTexture*> g_file_textures; // guarded by g_memory_mutex
|
||||
|
||||
IDirect3DTexture8* new_file_texture(const std::string& name)
|
||||
{
|
||||
auto* file = new FileTexture();
|
||||
file->name = name;
|
||||
std::lock_guard<std::mutex> lock(g_memory_mutex);
|
||||
g_file_textures.insert(file);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
void UIRenderReleaseMemoryTexture(IDirect3DTexture8* texture)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_memory_mutex);
|
||||
if (MemoryTexture* memory = live_memory_texture(texture)) {
|
||||
g_memory.erase(memory->id);
|
||||
delete memory;
|
||||
} else if (g_file_textures.erase(static_cast<const FileTexture*>(texture))) {
|
||||
delete static_cast<FileTexture*>(texture);
|
||||
}
|
||||
}
|
||||
|
||||
std::string UIRenderTextureNameFromHandle(const IDirect3DBaseTexture8* handle)
|
||||
{
|
||||
if (!handle) return {};
|
||||
const auto* texture = static_cast<const IDirect3DTexture8*>(handle);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_memory_mutex);
|
||||
if (const MemoryTexture* memory = live_memory_texture(texture))
|
||||
return "mem:" + std::to_string(memory->id) + "@" + std::to_string(memory->revision);
|
||||
const auto* file = static_cast<const FileTexture*>(texture);
|
||||
if (g_file_textures.count(file))
|
||||
return file->name;
|
||||
}
|
||||
return MtCpuTextureNameFromHandle(handle);
|
||||
}
|
||||
|
||||
bool UIRenderMemoryTexture(const std::string& name, UIMemoryTexture* out)
|
||||
{
|
||||
if (name.compare(0, 4, "mem:") != 0 || !out) return false;
|
||||
if (name.compare(0, 8, "mem:cpu_") == 0)
|
||||
return MtCpuMemoryTexture(name, out);
|
||||
const unsigned id = unsigned(std::strtoul(name.c_str() + 4, nullptr, 10));
|
||||
std::lock_guard<std::mutex> lock(g_memory_mutex);
|
||||
auto it = g_memory.find(id);
|
||||
if (it == g_memory.end()) return false;
|
||||
out->width = it->second->width;
|
||||
out->height = it->second->height;
|
||||
out->revision = it->second->revision;
|
||||
out->argb = it->second->argb;
|
||||
return true;
|
||||
}
|
||||
|
||||
CGraphicImageTexture::CGraphicImageTexture()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CGraphicImageTexture::~CGraphicImageTexture()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
auto CGraphicImageTexture::Destroy() -> void
|
||||
{
|
||||
CGraphicTexture::Destroy();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
auto CGraphicImageTexture::Create(UINT width, UINT height, D3DFORMAT d3dFmt, DWORD dwFilter) -> bool
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_d3dFmt = d3dFmt;
|
||||
m_dwFilter = dwFilter;
|
||||
|
||||
return CreateDeviceObjects();
|
||||
}
|
||||
|
||||
auto CGraphicImageTexture::CreateDeviceObjects() -> bool
|
||||
{
|
||||
if (m_stFileName.empty())
|
||||
{
|
||||
// PORT: ms_lpd3dDevice->CreateTexture(m_width, m_height, 1, 0, m_d3dFmt, D3DPOOL_MANAGED) becomes a
|
||||
// memory texture the canvas fetches by name.
|
||||
if (m_width <= 0 || m_height <= 0)
|
||||
return false;
|
||||
auto* memory = new MemoryTexture();
|
||||
memory->width = m_width;
|
||||
memory->height = m_height;
|
||||
memory->format = m_d3dFmt;
|
||||
memory->native.assign(size_t(m_width) * size_t(m_height) * size_t(bytes_per_pixel(m_d3dFmt)), 0);
|
||||
memory->argb.assign(size_t(m_width) * size_t(m_height), 0);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_memory_mutex);
|
||||
memory->id = g_memory_next_id++;
|
||||
g_memory[memory->id] = memory;
|
||||
}
|
||||
m_lpd3dTexture = memory;
|
||||
}
|
||||
else
|
||||
{
|
||||
// PORT: file textures are decoded by the canvas from the pack path; only their size is read here
|
||||
// (CreateFromMemoryFile), so there is no device object to recreate.
|
||||
return !m_bEmpty;
|
||||
}
|
||||
|
||||
m_bEmpty = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto CGraphicImageTexture::CreateFromTexturePointer(const CGraphicTexture *source) -> void
|
||||
{
|
||||
if (!source) { Destroy(); return; }
|
||||
m_width = source->GetWidth();
|
||||
m_height = source->GetHeight();
|
||||
m_bEmpty = source->IsEmpty();
|
||||
// 40250 shares the source's D3D texture; the canvas names textures by pack path instead.
|
||||
if (const auto* image = dynamic_cast<const CGraphicImageTexture*>(source))
|
||||
m_stFileName = image->m_stFileName;
|
||||
// PORT: 40250 AddRefs the source's texture; this handle is not reference counted, so the copy gets
|
||||
// its own named handle.
|
||||
DestroyDeviceObjects();
|
||||
if (!m_bEmpty && !m_stFileName.empty())
|
||||
m_lpd3dTexture = new_file_texture(m_stFileName);
|
||||
}
|
||||
|
||||
auto CGraphicImageTexture::CreateFromDiskFile(const char *, D3DFORMAT, DWORD) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CGraphicImageTexture::CreateFromMemoryFile(UINT size, const void *bytes, D3DFORMAT, DWORD) -> bool
|
||||
{
|
||||
if (!bytes) return false;
|
||||
const auto* data = static_cast<const unsigned char*>(bytes);
|
||||
unsigned width = 0, height = 0;
|
||||
if (size >= 20 && std::memcmp(data, "DDS ", 4) == 0) {
|
||||
height = little32(data + 12); width = little32(data + 16);
|
||||
} else if (size >= 24 && std::memcmp(data, "\x89PNG\r\n\x1a\n", 8) == 0) {
|
||||
width = big32(data + 16); height = big32(data + 20);
|
||||
} else if (jpeg_size(data, size, &width, &height)) {
|
||||
} else if (size >= 26 && data[0] == 'B' && data[1] == 'M') {
|
||||
width = little32(data + 18);
|
||||
const int bmp_height = static_cast<int>(little32(data + 22)); // negative: top-down rows
|
||||
height = static_cast<unsigned>(bmp_height < 0 ? -bmp_height : bmp_height);
|
||||
} else if (size >= 18 && (data[2] == 2 || data[2] == 10 || data[2] == 3)) {
|
||||
width = little16(data + 12); height = little16(data + 14);
|
||||
}
|
||||
if (!width || !height || width > 16384 || height > 16384) return false;
|
||||
m_width = static_cast<int>(width); m_height = static_cast<int>(height);
|
||||
m_bEmpty = false;
|
||||
DestroyDeviceObjects();
|
||||
m_lpd3dTexture = new_file_texture(m_stFileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto CGraphicImageTexture::CreateDDSTexture(CDXTCImage &, const BYTE *) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CGraphicImageTexture::SetFileName(const char *name) -> void
|
||||
{
|
||||
m_stFileName = name ? name : "";
|
||||
}
|
||||
|
||||
// PORT: where 40250 binds pTexture->GetD3DTexture(), the canvas gets the pack path of the file the
|
||||
// texture was decoded from (m_stFileName is protected, hence the derived accessor), or the name of the
|
||||
// memory texture bound to it (a CGraphicFontTexture after SelectTexture).
|
||||
std::string UIRenderTextureName(const CGraphicTexture* texture)
|
||||
{
|
||||
if (!texture) return {};
|
||||
if (texture->GetD3DTexture()) {
|
||||
std::lock_guard<std::mutex> lock(g_memory_mutex);
|
||||
if (const MemoryTexture* memory = live_memory_texture(texture->GetD3DTexture()))
|
||||
return "mem:" + std::to_string(memory->id) + "@" + std::to_string(memory->revision);
|
||||
}
|
||||
struct Access : CGraphicImageTexture {
|
||||
static const std::string& name(const CGraphicImageTexture* t) { return t->*(&Access::m_stFileName); }
|
||||
};
|
||||
const auto* image = dynamic_cast<const CGraphicImageTexture*>(texture);
|
||||
return image ? Access::name(image) : std::string();
|
||||
}
|
||||
|
||||
// PORT: LockRect/UnlockRect on the memory texture (one level; the lock is on the whole surface).
|
||||
auto CGraphicImageTexture::Lock(int* pRetPitch, void** ppRetPixels, int) -> bool
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_memory_mutex);
|
||||
MemoryTexture* memory = live_memory_texture(m_lpd3dTexture);
|
||||
if (!memory)
|
||||
return false;
|
||||
|
||||
*pRetPitch = memory->width * bytes_per_pixel(memory->format);
|
||||
*ppRetPixels = memory->native.data();
|
||||
return true;
|
||||
}
|
||||
|
||||
auto CGraphicImageTexture::Unlock(int) -> void
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_memory_mutex);
|
||||
MemoryTexture* memory = live_memory_texture(m_lpd3dTexture);
|
||||
assert(memory != NULL);
|
||||
if (!memory)
|
||||
return;
|
||||
const int bpp = bytes_per_pixel(memory->format);
|
||||
for (size_t i = 0; i < memory->argb.size(); ++i)
|
||||
memory->argb[i] = native_to_argb(memory->format, memory->native.data() + i * size_t(bpp));
|
||||
++memory->revision;
|
||||
}
|
||||
|
||||
auto CGraphicImageTexture::Initialize() -> void
|
||||
{
|
||||
CGraphicTexture::Initialize();
|
||||
|
||||
m_stFileName = "";
|
||||
|
||||
m_d3dFmt=D3DFMT_UNKNOWN;
|
||||
m_dwFilter=0;
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// 40250 EterLib/GrpIndexBuffer.cpp over CPU memory (CpuBuffer.h).
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpIndexBuffer.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
|
||||
#include "CpuBuffer.h"
|
||||
|
||||
namespace {
|
||||
BYTE* index_bytes(LPDIRECT3DINDEXBUFFER8 buffer)
|
||||
{
|
||||
return static_cast<MtCpuIndexBuffer*>(buffer)->bytes.data();
|
||||
}
|
||||
}
|
||||
|
||||
LPDIRECT3DINDEXBUFFER8 CGraphicIndexBuffer::GetD3DIndexBuffer() const
|
||||
{
|
||||
assert(m_lpd3dIdxBuf!=NULL);
|
||||
return m_lpd3dIdxBuf;
|
||||
}
|
||||
|
||||
void CGraphicIndexBuffer::SetIndices(int startIndex) const
|
||||
{
|
||||
STATEMANAGER.SetIndices(m_lpd3dIdxBuf, startIndex);
|
||||
}
|
||||
|
||||
bool CGraphicIndexBuffer::Lock(void** pretIndices) const
|
||||
{
|
||||
assert(m_lpd3dIdxBuf!=NULL);
|
||||
|
||||
*pretIndices = index_bytes(m_lpd3dIdxBuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicIndexBuffer::Unlock() const
|
||||
{
|
||||
assert(m_lpd3dIdxBuf!=NULL);
|
||||
static_cast<MtCpuIndexBuffer*>(m_lpd3dIdxBuf)->revision++;
|
||||
}
|
||||
|
||||
bool CGraphicIndexBuffer::Lock(void** pretIndices)
|
||||
{
|
||||
assert(m_lpd3dIdxBuf!=NULL);
|
||||
|
||||
*pretIndices = index_bytes(m_lpd3dIdxBuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicIndexBuffer::Unlock()
|
||||
{
|
||||
assert(m_lpd3dIdxBuf!=NULL);
|
||||
static_cast<MtCpuIndexBuffer*>(m_lpd3dIdxBuf)->revision++;
|
||||
}
|
||||
|
||||
bool CGraphicIndexBuffer::Copy(int bufSize, const void* srcIndices)
|
||||
{
|
||||
assert(m_lpd3dIdxBuf!=NULL);
|
||||
|
||||
memcpy(index_bytes(m_lpd3dIdxBuf), srcIndices, bufSize);
|
||||
static_cast<MtCpuIndexBuffer*>(m_lpd3dIdxBuf)->revision++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicIndexBuffer::Create(int faceCount, TFace* faces)
|
||||
{
|
||||
int idxCount = faceCount * 3;
|
||||
m_iidxCount = idxCount;
|
||||
if (!Create(idxCount, D3DFMT_INDEX16))
|
||||
return false;
|
||||
|
||||
WORD* dstIndices = reinterpret_cast<WORD*>(index_bytes(m_lpd3dIdxBuf));
|
||||
|
||||
for (int i = 0; i<faceCount; ++i, dstIndices+=3)
|
||||
{
|
||||
TFace * curFace=faces+i;
|
||||
dstIndices[0]=curFace->indices[0];
|
||||
dstIndices[1]=curFace->indices[1];
|
||||
dstIndices[2]=curFace->indices[2];
|
||||
}
|
||||
static_cast<MtCpuIndexBuffer*>(m_lpd3dIdxBuf)->revision++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicIndexBuffer::CreateDeviceObjects()
|
||||
{
|
||||
MtCpuIndexBuffer* buffer = new MtCpuIndexBuffer;
|
||||
buffer->bytes.assign(m_dwBufferSize, 0);
|
||||
buffer->format = m_d3dFmt;
|
||||
m_lpd3dIdxBuf = buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicIndexBuffer::DestroyDeviceObjects()
|
||||
{
|
||||
delete static_cast<MtCpuIndexBuffer*>(m_lpd3dIdxBuf);
|
||||
m_lpd3dIdxBuf = NULL;
|
||||
}
|
||||
|
||||
bool CGraphicIndexBuffer::Create(int idxCount, D3DFORMAT d3dFmt)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_iidxCount = idxCount;
|
||||
m_dwBufferSize = sizeof(WORD) * idxCount;
|
||||
m_d3dFmt = d3dFmt;
|
||||
|
||||
return CreateDeviceObjects();
|
||||
}
|
||||
|
||||
void CGraphicIndexBuffer::Destroy()
|
||||
{
|
||||
DestroyDeviceObjects();
|
||||
}
|
||||
|
||||
void CGraphicIndexBuffer::Initialize()
|
||||
{
|
||||
m_lpd3dIdxBuf=NULL;
|
||||
m_iidxCount=0;
|
||||
m_dwBufferSize=0;
|
||||
}
|
||||
|
||||
CGraphicIndexBuffer::CGraphicIndexBuffer()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CGraphicIndexBuffer::~CGraphicIndexBuffer()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// Platform skeleton for EterLib/GrpMath.h (40250 EterLib/GrpMath.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpMath.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
auto CrossProduct2D(float, float, float, float) -> float
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<float>();
|
||||
}
|
||||
|
||||
auto IsInTriangle2D(float, float, float, float, float, float, float, float) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto D3DXVec3Rotation(D3DXVECTOR3 *, const D3DXVECTOR3 *, const D3DXQUATERNION *) -> D3DXVECTOR3 *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<D3DXVECTOR3 *>();
|
||||
}
|
||||
|
||||
auto D3DXVec3Translation(D3DXVECTOR3 *, const D3DXVECTOR3 *, const D3DXVECTOR3 *) -> D3DXVECTOR3 *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<D3DXVECTOR3 *>();
|
||||
}
|
||||
|
||||
auto GetRotationFromMatrix(D3DXVECTOR3 *, const D3DXMATRIX *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto GetPivotAndRotationFromMatrix(D3DXMATRIX *, D3DXVECTOR3 *, D3DXVECTOR3 *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto ExtractMovement(D3DXMATRIX *, D3DXMATRIX *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
@@ -0,0 +1,435 @@
|
||||
// Platform skeleton for EterLib/GrpScreen.h (40250 EterLib/GrpScreen.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpScreen.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
#include "EterLib/Camera.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
#include "UIRenderCommands.h"
|
||||
#include <algorithm>
|
||||
|
||||
// 40250 GrpScreen.cpp:838
|
||||
CScreen::CScreen()
|
||||
{
|
||||
}
|
||||
|
||||
CScreen::~CScreen()
|
||||
{
|
||||
}
|
||||
|
||||
auto CScreen::ClearDepthBuffer() -> void
|
||||
{
|
||||
if (ms_lpd3dDevice)
|
||||
ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_ZBUFFER, ms_clearColor, ms_clearDepth, ms_clearStencil);
|
||||
}
|
||||
|
||||
auto CScreen::Clear() -> void
|
||||
{
|
||||
if (ms_lpd3dDevice)
|
||||
ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, ms_clearColor, ms_clearDepth, ms_clearStencil);
|
||||
}
|
||||
|
||||
// 40250 GrpScreen.cpp:691. CPythonApplication::Process brackets the frame's render with Begin/End; only
|
||||
// inside the scene does CStateManager hand transforms to the recording device.
|
||||
bool CScreen::Begin()
|
||||
{
|
||||
assert(ms_lpd3dDevice != NULL);
|
||||
ResetFaceCount();
|
||||
|
||||
if (!STATEMANAGER.BeginScene())
|
||||
{
|
||||
Tracenf("BeginScene FAILED\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 40250 GrpScreen.cpp:705
|
||||
void CScreen::End()
|
||||
{
|
||||
STATEMANAGER.EndScene();
|
||||
}
|
||||
|
||||
auto CScreen::Show(HWND) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::Show(RECT *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::Show(RECT *, HWND) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderLine2d(float sx, float sy, float ex, float ey, float) -> void
|
||||
{
|
||||
UIRenderAdd({UIRenderCommand::Line, sx, sy, ex, ey, ms_diffuseColor});
|
||||
}
|
||||
|
||||
auto CScreen::RenderBox2d(float sx, float sy, float ex, float ey, float) -> void
|
||||
{
|
||||
// 40250's four line pairs, including its one-pixel extension of the bottom edge.
|
||||
UIRenderAdd({UIRenderCommand::Line, sx, sy, ex, sy, ms_diffuseColor});
|
||||
UIRenderAdd({UIRenderCommand::Line, sx, sy, sx, ey, ms_diffuseColor});
|
||||
UIRenderAdd({UIRenderCommand::Line, ex, sy, ex, ey, ms_diffuseColor});
|
||||
UIRenderAdd({UIRenderCommand::Line, sx, ey, ex + 1.0f, ey, ms_diffuseColor});
|
||||
}
|
||||
|
||||
auto CScreen::RenderBar2d(float sx, float sy, float ex, float ey, float) -> void
|
||||
{
|
||||
UIRenderAdd({UIRenderCommand::Bar, sx, sy, ex, ey, ms_diffuseColor});
|
||||
}
|
||||
|
||||
auto CScreen::RenderGradationBar2d(float sx, float sy, float ex, float ey, DWORD start, DWORD end, float) -> void
|
||||
{
|
||||
if (sx == ex || sy == ey)
|
||||
return;
|
||||
UIRenderCommand command{UIRenderCommand::GradientBar, sx, sy, ex, ey, start};
|
||||
command.end_argb = end;
|
||||
UIRenderAdd(std::move(command));
|
||||
}
|
||||
|
||||
auto CScreen::RenderCircle2d(float, float, float, float, int) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderCircle3d(float, float, float, float, int) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderLine3d(float, float, float, float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderBox3d(float, float, float, float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderBar3d(float, float, float, float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderBar3d(const D3DXVECTOR3 *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderGradationBar3d(float, float, float, float, float, float, DWORD, DWORD) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderLineCube(float, float, float, float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderCube(float, float, float, float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderCube(float, float, float, float, float, float, D3DXMATRIX) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderTextureBox(float, float, float, float, float, float, float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderBillboard(D3DXVECTOR3 *, D3DXCOLOR &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::DrawMinorGrid(float, float, float, float, float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::DrawGrid(float, float, float, float, float, float, float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderD3DXMesh(LPD3DXMESH, const D3DXMATRIX *, float, float, float, float, D3DFILLMODE) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderSphere(const D3DXMATRIX *, float, float, float, float, D3DFILLMODE) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::RenderCylinder(const D3DXMATRIX *, float, float, float, float, float, D3DFILLMODE) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
// 40250 GrpScreen.cpp
|
||||
void CScreen::SetColorOperation()
|
||||
{
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
}
|
||||
|
||||
// 40250 GrpScreen.cpp
|
||||
void CScreen::SetDiffuseOperation()
|
||||
{
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
}
|
||||
|
||||
// 40250 GrpScreen.cpp
|
||||
void CScreen::SetBlendOperation()
|
||||
{
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
}
|
||||
|
||||
auto CScreen::SetOneColorOperation(D3DXCOLOR &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::SetAddColorOperation(D3DXCOLOR &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::SetDiffuseColor(DWORD color) -> void
|
||||
{
|
||||
ms_diffuseColor = color;
|
||||
}
|
||||
|
||||
auto CScreen::SetDiffuseColor(float r, float g, float b, float a) -> void
|
||||
{
|
||||
auto channel = [](float value) -> DWORD {
|
||||
return static_cast<DWORD>(std::clamp(value, 0.0f, 1.0f) * 255.0f + 0.5f);
|
||||
};
|
||||
ms_diffuseColor = (channel(a) << 24) | (channel(r) << 16) | (channel(g) << 8) | channel(b);
|
||||
}
|
||||
|
||||
auto CScreen::SetClearColor(float, float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::SetClearDepth(float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CScreen::SetClearStencil(DWORD) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
// 40250 GrpScreen.cpp:487, verbatim: the pick ray through the cursor.
|
||||
void CScreen::SetCursorPosition(int x, int y, int hres, int vres)
|
||||
{
|
||||
D3DXVECTOR3 v;
|
||||
v.x = -(((2.0f * x) / hres) - 1) / ms_matProj._11;
|
||||
v.y = (((2.0f * y) / vres) - 1) / ms_matProj._22;
|
||||
v.z = 1.0f;
|
||||
|
||||
D3DXMATRIX matViewInverse=ms_matInverseView;
|
||||
//D3DXMatrixInverse(&matViewInverse, NULL, &ms_matView);
|
||||
|
||||
ms_vtPickRayDir.x = v.x * matViewInverse._11 +
|
||||
v.y * matViewInverse._21 +
|
||||
v.z * matViewInverse._31;
|
||||
|
||||
ms_vtPickRayDir.y = v.x * matViewInverse._12 +
|
||||
v.y * matViewInverse._22 +
|
||||
v.z * matViewInverse._32;
|
||||
|
||||
ms_vtPickRayDir.z = v.x * matViewInverse._13 +
|
||||
v.y * matViewInverse._23 +
|
||||
v.z * matViewInverse._33;
|
||||
|
||||
ms_vtPickRayOrig.x = matViewInverse._41;
|
||||
ms_vtPickRayOrig.y = matViewInverse._42;
|
||||
ms_vtPickRayOrig.z = matViewInverse._43;
|
||||
|
||||
ms_Ray.SetStartPoint(ms_vtPickRayOrig);
|
||||
ms_Ray.SetDirection(-ms_vtPickRayDir, 51200.0f);
|
||||
}
|
||||
|
||||
auto CScreen::GetCursorPosition(float * px, float * py, float * pz) -> bool
|
||||
{
|
||||
if (!GetCursorXYPosition(px, py)) return false;
|
||||
if (!GetCursorZPosition(pz)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto CScreen::GetCursorXYPosition(float * px, float * py) -> bool
|
||||
{
|
||||
D3DXVECTOR3 v3Eye = CCameraManager::Instance().GetCurrentCamera()->GetEye();
|
||||
|
||||
TPosition posVertices[4];
|
||||
posVertices[0] = TPosition(v3Eye.x - 90000000.0f, v3Eye.y + 90000000.0f, 0.0f);
|
||||
posVertices[1] = TPosition(v3Eye.x - 90000000.0f, v3Eye.y - 90000000.0f, 0.0f);
|
||||
posVertices[2] = TPosition(v3Eye.x + 90000000.0f, v3Eye.y + 90000000.0f, 0.0f);
|
||||
posVertices[3] = TPosition(v3Eye.x + 90000000.0f, v3Eye.y - 90000000.0f, 0.0f);
|
||||
|
||||
static const WORD sc_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, };
|
||||
|
||||
float u, v, t;
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
if (IntersectTriangle(ms_vtPickRayOrig, ms_vtPickRayDir,
|
||||
posVertices[sc_awFillRectIndices[i * 3]],
|
||||
posVertices[sc_awFillRectIndices[i * 3 + 1]],
|
||||
posVertices[sc_awFillRectIndices[i * 3 + 2]],
|
||||
&u, &v, &t))
|
||||
{
|
||||
*px = u;
|
||||
*py = v;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto CScreen::GetCursorZPosition(float * pz) -> bool
|
||||
{
|
||||
D3DXVECTOR3 v3Eye = CCameraManager::Instance().GetCurrentCamera()->GetEye();
|
||||
|
||||
TPosition posVertices[4];
|
||||
posVertices[0] = TPosition(v3Eye.x - 90000000.0f, 0.0f, v3Eye.z + 90000000.0f);
|
||||
posVertices[1] = TPosition(v3Eye.x - 90000000.0f, 0.0f, v3Eye.z - 90000000.0f);
|
||||
posVertices[2] = TPosition(v3Eye.x + 90000000.0f, 0.0f, v3Eye.z + 90000000.0f);
|
||||
posVertices[3] = TPosition(v3Eye.x + 90000000.0f, 0.0f, v3Eye.z - 90000000.0f);
|
||||
|
||||
static const WORD sc_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, };
|
||||
|
||||
float u, v, t;
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
if (IntersectTriangle(ms_vtPickRayOrig, ms_vtPickRayDir,
|
||||
posVertices[sc_awFillRectIndices[i * 3]],
|
||||
posVertices[sc_awFillRectIndices[i * 3 + 1]],
|
||||
posVertices[sc_awFillRectIndices[i * 3 + 2]],
|
||||
&u, &v, &t))
|
||||
{
|
||||
*pz = t;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto CScreen::GetPickingPosition(float t, float * x, float * y, float * z) -> void
|
||||
{
|
||||
*x = ms_vtPickRayOrig.x + ms_vtPickRayDir.x * t;
|
||||
*y = ms_vtPickRayOrig.y + ms_vtPickRayDir.y * t;
|
||||
*z = ms_vtPickRayOrig.z + ms_vtPickRayDir.z * t;
|
||||
}
|
||||
|
||||
// 40250 GrpScreen.cpp:749-779.
|
||||
void CScreen::ProjectPosition(float x, float y, float z, float * pfX, float * pfY)
|
||||
{
|
||||
D3DXVECTOR3 Input(x, y, z);
|
||||
D3DXVECTOR3 Output;
|
||||
D3DXVec3Project(&Output, &Input, &ms_Viewport, &ms_matProj, &ms_matView, &ms_matIdentity);
|
||||
|
||||
*pfX = Output.x;
|
||||
*pfY = Output.y;
|
||||
}
|
||||
|
||||
void CScreen::ProjectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ)
|
||||
{
|
||||
D3DXVECTOR3 Input(x, y, z);
|
||||
D3DXVECTOR3 Output;
|
||||
D3DXVec3Project(&Output, &Input, &ms_Viewport, &ms_matProj, &ms_matView, &ms_matIdentity);
|
||||
|
||||
*pfX = Output.x;
|
||||
*pfY = Output.y;
|
||||
*pfZ = Output.z;
|
||||
}
|
||||
|
||||
void CScreen::UnprojectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ)
|
||||
{
|
||||
D3DXVECTOR3 Input(x, y, z);
|
||||
D3DXVECTOR3 Output;
|
||||
D3DXVec3Unproject(&Output, &Input, &ms_Viewport, &ms_matProj, &ms_matView, &ms_matIdentity);
|
||||
|
||||
*pfX = Output.x;
|
||||
*pfY = Output.y;
|
||||
*pfZ = Output.z;
|
||||
}
|
||||
|
||||
auto CScreen::IsLostDevice() -> BOOL
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<BOOL>();
|
||||
}
|
||||
|
||||
auto CScreen::RestoreDevice() -> BOOL
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<BOOL>();
|
||||
}
|
||||
|
||||
auto CScreen::BuildViewFrustum() -> void
|
||||
{
|
||||
CCamera* pkCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pkCamera)
|
||||
return;
|
||||
const D3DXVECTOR3& c_rv3Eye = pkCamera->GetEye();
|
||||
const D3DXVECTOR3& c_rv3View = pkCamera->GetView();
|
||||
auto vv = ms_matView * ms_matProj;
|
||||
ms_frustum.BuildViewFrustum2(
|
||||
vv,
|
||||
ms_fNearY,
|
||||
ms_fFarY,
|
||||
ms_fFieldOfView,
|
||||
ms_fAspect,
|
||||
c_rv3Eye, c_rv3View);
|
||||
}
|
||||
|
||||
auto CScreen::Identity() -> void
|
||||
{
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity);
|
||||
}
|
||||
|
||||
decltype(CScreen::ms_diffuseColor) CScreen::ms_diffuseColor = 0xffffffff;
|
||||
|
||||
decltype(CScreen::ms_clearColor) CScreen::ms_clearColor{};
|
||||
|
||||
decltype(CScreen::ms_clearStencil) CScreen::ms_clearStencil{};
|
||||
|
||||
decltype(CScreen::ms_clearDepth) CScreen::ms_clearDepth = 1.0f;
|
||||
|
||||
decltype(CScreen::ms_frustum) CScreen::ms_frustum{};
|
||||
@@ -0,0 +1,100 @@
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpSubImage.h"
|
||||
#include "EterLib/ResourceManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
char CGraphicSubImage::m_SearchPath[256] = "D:/Ymir Work/UI/";
|
||||
|
||||
auto CGraphicSubImage::Type() -> TType
|
||||
{
|
||||
static TType type = StringToType("CGraphicSubImage");
|
||||
return type;
|
||||
}
|
||||
|
||||
CGraphicSubImage::CGraphicSubImage(const char* name) : CGraphicImage(name) {}
|
||||
CGraphicSubImage::~CGraphicSubImage() { m_roImage.Clear(); }
|
||||
|
||||
bool CGraphicSubImage::CreateDeviceObjects()
|
||||
{
|
||||
if (m_roImage.IsNull()) return false;
|
||||
m_imageTexture.CreateFromTexturePointer(m_roImage->GetTexturePointer());
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicSubImage::SetImagePointer(CGraphicImage* image)
|
||||
{
|
||||
m_roImage.SetPointer(image);
|
||||
CreateDeviceObjects();
|
||||
}
|
||||
|
||||
bool CGraphicSubImage::SetImageFileName(const char* name)
|
||||
{
|
||||
CResource* resource = CResourceManager::Instance().GetResourcePointer(name);
|
||||
if (!resource || !resource->IsType(CGraphicImage::Type())) return false;
|
||||
SetImagePointer(static_cast<CGraphicImage*>(resource));
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicSubImage::SetRectPosition(int left, int top, int right, int bottom)
|
||||
{
|
||||
m_rect = {left, top, right, bottom};
|
||||
}
|
||||
|
||||
void CGraphicSubImage::SetRectReference(const RECT& rect) { m_rect = rect; }
|
||||
|
||||
void CGraphicSubImage::SetSearchPath(const char* path)
|
||||
{
|
||||
if (!path) return;
|
||||
std::strncpy(m_SearchPath, path, sizeof(m_SearchPath) - 1);
|
||||
m_SearchPath[sizeof(m_SearchPath) - 1] = 0;
|
||||
}
|
||||
|
||||
bool CGraphicSubImage::OnLoad(int size, const void* bytes)
|
||||
{
|
||||
if (!bytes || size <= 0) return false;
|
||||
std::istringstream input(std::string(static_cast<const char*>(bytes), static_cast<size_t>(size)));
|
||||
std::map<std::string, std::string> tokens;
|
||||
std::string line;
|
||||
while (std::getline(input, line)) {
|
||||
std::istringstream fields(line);
|
||||
std::string key, value;
|
||||
if (!(fields >> key >> value)) continue;
|
||||
if (!value.empty() && value.front() == '"') {
|
||||
value.erase(0, 1);
|
||||
if (!value.empty() && value.back() == '"') value.pop_back();
|
||||
}
|
||||
std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||
std::transform(value.begin(), value.end(), value.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||
tokens[key] = value;
|
||||
}
|
||||
if (tokens["title"] != "subimage" || tokens["image"].empty()) return false;
|
||||
std::string image_path;
|
||||
if (tokens["version"] == "2.0") {
|
||||
const std::string parent = GetFileNameString();
|
||||
const auto slash = parent.find_last_of("\\/");
|
||||
image_path = slash == std::string::npos ? tokens["image"] : parent.substr(0, slash + 1) + tokens["image"];
|
||||
} else {
|
||||
image_path = std::string(m_SearchPath) + tokens["image"];
|
||||
}
|
||||
if (!SetImageFileName(image_path.c_str())) return false;
|
||||
SetRectPosition(std::atoi(tokens["left"].c_str()), std::atoi(tokens["top"].c_str()),
|
||||
std::atoi(tokens["right"].c_str()), std::atoi(tokens["bottom"].c_str()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicSubImage::OnClear()
|
||||
{
|
||||
m_roImage.Clear();
|
||||
m_imageTexture.Destroy();
|
||||
m_rect = {0, 0, 0, 0};
|
||||
}
|
||||
|
||||
bool CGraphicSubImage::OnIsEmpty() const { return m_roImage.IsNull() || m_roImage->IsEmpty(); }
|
||||
bool CGraphicSubImage::OnIsType(TType type) { return type == Type() || CGraphicImage::OnIsType(type); }
|
||||
@@ -0,0 +1,102 @@
|
||||
// 40250 EterLib/GrpText.cpp, verbatim.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterBase/Utils.h"
|
||||
#include "EterLib/GrpText.h"
|
||||
|
||||
CGraphicText::CGraphicText(const char* c_szFileName) : CResource(c_szFileName)
|
||||
{
|
||||
}
|
||||
|
||||
CGraphicText::~CGraphicText()
|
||||
{
|
||||
}
|
||||
|
||||
bool CGraphicText::CreateDeviceObjects()
|
||||
{
|
||||
return m_fontTexture.CreateDeviceObjects();
|
||||
}
|
||||
|
||||
void CGraphicText::DestroyDeviceObjects()
|
||||
{
|
||||
m_fontTexture.DestroyDeviceObjects();
|
||||
}
|
||||
|
||||
CGraphicFontTexture* CGraphicText::GetFontTexturePointer()
|
||||
{
|
||||
return &m_fontTexture;
|
||||
}
|
||||
|
||||
CGraphicText::TType CGraphicText::Type()
|
||||
{
|
||||
static TType s_type = StringToType("CGraphicText");
|
||||
return s_type;
|
||||
}
|
||||
|
||||
bool CGraphicText::OnLoad(int /*iSize*/, const void* /*c_pvBuf*/)
|
||||
{
|
||||
static char strName[32];
|
||||
int size;
|
||||
bool bItalic = false;
|
||||
|
||||
// format
|
||||
// 굴림.fnt "굴림" 폰트 기본 사이즈 12 로 로딩
|
||||
// 굴림:18.fnt "굴림" 폰트 사이즈 18 로 로딩
|
||||
// 굴림:14i.fnt "굴림" 폰트 사이즈 14 & 이탤릭으로 로딩
|
||||
const char * p = strrchr(GetFileName(), ':');
|
||||
|
||||
if (p)
|
||||
{
|
||||
strncpy(strName, GetFileName(), MIN(31, p - GetFileName()));
|
||||
++p;
|
||||
|
||||
static char num[8];
|
||||
|
||||
int i = 0;
|
||||
while (*p && isdigit(*p))
|
||||
{
|
||||
num[i++] = *(p++);
|
||||
}
|
||||
|
||||
num[i] = '\0';
|
||||
if(*p == 'i')
|
||||
bItalic = true;
|
||||
size = atoi(num);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = strrchr(GetFileName(), '.');
|
||||
|
||||
if (!p)
|
||||
{
|
||||
assert(!"CGraphicText::OnLoadFromFile there is no extension (ie: .fnt)");
|
||||
strName[0] = '\0';
|
||||
}
|
||||
else
|
||||
strncpy(strName, GetFileName(), MIN(31, p - GetFileName()));
|
||||
|
||||
size = 12;
|
||||
}
|
||||
|
||||
if (!m_fontTexture.Create(strName, size, bItalic))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicText::OnClear()
|
||||
{
|
||||
m_fontTexture.Destroy();
|
||||
}
|
||||
|
||||
bool CGraphicText::OnIsEmpty() const
|
||||
{
|
||||
return m_fontTexture.IsEmpty();
|
||||
}
|
||||
|
||||
bool CGraphicText::OnIsType(TType type)
|
||||
{
|
||||
if (CGraphicText::Type() == type)
|
||||
return true;
|
||||
|
||||
return CResource::OnIsType(type);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,64 @@
|
||||
// Platform skeleton for EterLib/GrpTexture.h (40250 EterLib/GrpTexture.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpTexture.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
#include "UIRenderCommands.h"
|
||||
|
||||
auto CGraphicTexture::IsEmpty() const -> bool
|
||||
{
|
||||
return m_bEmpty;
|
||||
}
|
||||
|
||||
auto CGraphicTexture::GetWidth() const -> int
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
auto CGraphicTexture::GetHeight() const -> int
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
auto CGraphicTexture::SetTextureStage(int) const -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CGraphicTexture::GetD3DTexture() const -> LPDIRECT3DTEXTURE8
|
||||
{
|
||||
return m_lpd3dTexture;
|
||||
}
|
||||
|
||||
// PORT: safe_release(m_lpd3dTexture); the platform textures are memory textures and file-texture handles.
|
||||
auto CGraphicTexture::DestroyDeviceObjects() -> void
|
||||
{
|
||||
if (m_lpd3dTexture)
|
||||
UIRenderReleaseMemoryTexture(m_lpd3dTexture);
|
||||
m_lpd3dTexture = NULL;
|
||||
}
|
||||
|
||||
CGraphicTexture::CGraphicTexture()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CGraphicTexture::~CGraphicTexture()
|
||||
{
|
||||
}
|
||||
|
||||
auto CGraphicTexture::Destroy() -> void
|
||||
{
|
||||
DestroyDeviceObjects();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
auto CGraphicTexture::Initialize() -> void
|
||||
{
|
||||
m_lpd3dTexture = NULL;
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
m_bEmpty = true;
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
// 40250 EterLib/GrpVertexBuffer.cpp over CPU memory (CpuBuffer.h): the device buffer is a byte vector
|
||||
// that Lock hands out directly, so Granny vertex loading and deform write real data.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpVertexBuffer.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
|
||||
#include "CpuBuffer.h"
|
||||
|
||||
int CGraphicVertexBuffer::GetVertexStride() const
|
||||
{
|
||||
int retSize = mt_fvf_vertex_size(m_dwFVF);
|
||||
return retSize;
|
||||
}
|
||||
|
||||
DWORD CGraphicVertexBuffer::GetFlexibleVertexFormat() const
|
||||
{
|
||||
return m_dwFVF;
|
||||
}
|
||||
|
||||
int CGraphicVertexBuffer::GetVertexCount() const
|
||||
{
|
||||
return m_vtxCount;
|
||||
}
|
||||
|
||||
void CGraphicVertexBuffer::SetStream(int stride, int layer) const
|
||||
{
|
||||
STATEMANAGER.SetStreamSource(layer, m_lpd3dVB, stride);
|
||||
}
|
||||
|
||||
bool CGraphicVertexBuffer::LockRange(unsigned count, void** pretVertices) const
|
||||
{
|
||||
if (!m_lpd3dVB)
|
||||
return false;
|
||||
|
||||
*pretVertices = static_cast<MtCpuVertexBuffer*>(m_lpd3dVB)->bytes.data();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicVertexBuffer::Lock(void ** pretVertices) const
|
||||
{
|
||||
if (!m_lpd3dVB)
|
||||
return false;
|
||||
|
||||
*pretVertices = static_cast<MtCpuVertexBuffer*>(m_lpd3dVB)->bytes.data();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicVertexBuffer::Unlock() const
|
||||
{
|
||||
if (!m_lpd3dVB)
|
||||
return false;
|
||||
static_cast<MtCpuVertexBuffer*>(m_lpd3dVB)->revision++;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns true when a buffer exists, as 40250 does.
|
||||
bool CGraphicVertexBuffer::IsEmpty() const
|
||||
{
|
||||
if (m_lpd3dVB)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGraphicVertexBuffer::LockDynamic(void** pretVertices)
|
||||
{
|
||||
if (!m_lpd3dVB)
|
||||
return false;
|
||||
|
||||
*pretVertices = static_cast<MtCpuVertexBuffer*>(m_lpd3dVB)->bytes.data();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicVertexBuffer::Lock(void ** pretVertices)
|
||||
{
|
||||
if (!m_lpd3dVB)
|
||||
return false;
|
||||
|
||||
*pretVertices = static_cast<MtCpuVertexBuffer*>(m_lpd3dVB)->bytes.data();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicVertexBuffer::Unlock()
|
||||
{
|
||||
if (!m_lpd3dVB)
|
||||
return false;
|
||||
static_cast<MtCpuVertexBuffer*>(m_lpd3dVB)->revision++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicVertexBuffer::Copy(int bufSize, const void* srcVertices)
|
||||
{
|
||||
void * dstVertices;
|
||||
|
||||
if (!Lock(&dstVertices))
|
||||
return false;
|
||||
|
||||
memcpy(dstVertices, srcVertices, bufSize);
|
||||
|
||||
Unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGraphicVertexBuffer::CreateDeviceObjects()
|
||||
{
|
||||
assert(m_lpd3dVB == NULL);
|
||||
|
||||
MtCpuVertexBuffer* buffer = new MtCpuVertexBuffer;
|
||||
buffer->bytes.assign(m_dwBufferSize, 0);
|
||||
buffer->fvf = m_dwFVF;
|
||||
m_lpd3dVB = buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphicVertexBuffer::DestroyDeviceObjects()
|
||||
{
|
||||
delete static_cast<MtCpuVertexBuffer*>(m_lpd3dVB);
|
||||
m_lpd3dVB = NULL;
|
||||
}
|
||||
|
||||
bool CGraphicVertexBuffer::Create(int vtxCount, DWORD fvf, DWORD usage, D3DPOOL d3dPool)
|
||||
{
|
||||
assert(vtxCount > 0);
|
||||
|
||||
Destroy();
|
||||
|
||||
m_vtxCount = vtxCount;
|
||||
m_dwBufferSize = mt_fvf_vertex_size(fvf) * m_vtxCount;
|
||||
m_d3dPool = d3dPool;
|
||||
m_dwUsage = usage;
|
||||
m_dwFVF = fvf;
|
||||
|
||||
if (usage == D3DUSAGE_WRITEONLY || usage == D3DUSAGE_DYNAMIC)
|
||||
m_dwLockFlag = 0;
|
||||
else
|
||||
m_dwLockFlag = D3DLOCK_READONLY;
|
||||
|
||||
return CreateDeviceObjects();
|
||||
}
|
||||
|
||||
void CGraphicVertexBuffer::Destroy()
|
||||
{
|
||||
DestroyDeviceObjects();
|
||||
}
|
||||
|
||||
void CGraphicVertexBuffer::Initialize()
|
||||
{
|
||||
m_lpd3dVB = NULL;
|
||||
m_vtxCount = 0;
|
||||
m_dwBufferSize = 0;
|
||||
m_dwFVF = 0;
|
||||
}
|
||||
|
||||
CGraphicVertexBuffer::CGraphicVertexBuffer()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CGraphicVertexBuffer::~CGraphicVertexBuffer()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Platform skeleton for EterLib/GrpVertexBufferDynamic.h (40250 EterLib/GrpVertexBufferDynamic.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/GrpVertexBufferDynamic.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CDynamicVertexBuffer::CDynamicVertexBuffer()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CDynamicVertexBuffer::~CDynamicVertexBuffer()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CDynamicVertexBuffer::Create(int, int) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
// The cursor in client coordinates, as the host (Godot) last pushed it. 40250 CMSWindow::GetMousePosition
|
||||
// asks Win32 (GetCursorPos + ScreenToClient); here the host is the only source of mouse input.
|
||||
void MtHostSetCursor(int x, int y);
|
||||
@@ -0,0 +1,752 @@
|
||||
// Platform implementation of EterLib/IME.h (40250 EterLib/IME.cpp).
|
||||
// The edit buffer (m_wText, cursor, SetText/GetText, OnChar/InsertString, IsMax, the colour-tag aware cursor
|
||||
// moves) and WMChar are the 40250 bodies verbatim. What 40250 gets from Win32 IMM/TSF — composition strings,
|
||||
// the candidate list, the reading window, keyboard-layout code pages — has no counterpart under Godot: the
|
||||
// host delivers committed characters only (Metin2PythonHost.ui_char -> WMChar, or InsertString for text the
|
||||
// input code page cannot hold, which is what 40250's ResultProcess does with a GCS_RESULTSTR). Those entry
|
||||
// points keep 40250's "no IME present" behaviour: no composition, empty candidate/reading lists.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/IME.h"
|
||||
#include "EterLib/TextTag.h"
|
||||
#include "EterLib/GrpTextInstance.h"
|
||||
#include "EterLib/Util.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cwctype>
|
||||
|
||||
namespace
|
||||
{
|
||||
// 40250 s_aszIndicator[INDICATOR_NON_IME] (IME.cpp:67); CheckInputLocale overwrites it with the locale's
|
||||
// two-letter abbreviation, which here is the locale code page's language.
|
||||
wchar_t s_aszNonImeIndicator[3] = L"En";
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/ /* Public */
|
||||
CIME::CIME()
|
||||
{
|
||||
ms_hWnd = NULL;
|
||||
|
||||
ms_bCandidateList = false;
|
||||
ms_bReadingInformation = false;
|
||||
|
||||
Clear();
|
||||
|
||||
m_max = 0;
|
||||
m_userMax = 0;
|
||||
|
||||
m_bOnlyNumberMode = FALSE;
|
||||
m_hOrgIMC = NULL;
|
||||
|
||||
m_bEnablePaste = false;
|
||||
m_bUseDefaultIME = false;
|
||||
}
|
||||
|
||||
CIME::~CIME()
|
||||
{
|
||||
}
|
||||
|
||||
// PORT: 40250 loads imm32.dll, disables Cicero, reads the keyboard layout and sets up the TSF sinks. The
|
||||
// Godot host has no IMM context; only the part the edit buffer depends on — the input/output code page from
|
||||
// CheckInputLocale and SetSupportLevel(2) — is kept.
|
||||
bool CIME::Initialize(HWND hWnd)
|
||||
{
|
||||
if(ms_bInitialized)
|
||||
return true;
|
||||
ms_hWnd = hWnd;
|
||||
|
||||
ms_bDisableIMECompletely = true;
|
||||
ms_bInitialized = true;
|
||||
|
||||
CheckInputLocale();
|
||||
ChangeInputLanguageWorker();
|
||||
SetSupportLevel(2);
|
||||
|
||||
ms_bUILessMode = false;
|
||||
CheckToggleState();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CIME::Uninitialize()
|
||||
{
|
||||
if ( !ms_bInitialized )
|
||||
return;
|
||||
ms_hWnd = NULL;
|
||||
m_hOrgIMC = NULL;
|
||||
ms_bInitialized = false;
|
||||
}
|
||||
|
||||
void CIME::UseDefaultIME()
|
||||
{
|
||||
m_bUseDefaultIME = true;
|
||||
}
|
||||
|
||||
bool CIME::IsIMEEnabled()
|
||||
{
|
||||
return ms_bImeEnabled;
|
||||
}
|
||||
|
||||
// PORT: 40250 ImmAssociateContext()s the window; ms_bDisableIMECompletely (no imm32) forces bEnable=false,
|
||||
// which is always the case here.
|
||||
void CIME::EnableIME(bool bEnable)
|
||||
{
|
||||
if (!ms_bInitialized || !ms_hWnd)
|
||||
return;
|
||||
if (ms_bDisableIMECompletely)
|
||||
bEnable = false;
|
||||
ms_bImeEnabled = bEnable;
|
||||
if (bEnable)
|
||||
CheckToggleState();
|
||||
}
|
||||
|
||||
void CIME::DisableIME()
|
||||
{
|
||||
EnableIME(false);
|
||||
}
|
||||
|
||||
void CIME::EnableCaptureInput()
|
||||
{
|
||||
ms_bCaptureInput = true;
|
||||
}
|
||||
|
||||
void CIME::DisableCaptureInput()
|
||||
{
|
||||
ms_bCaptureInput = false;
|
||||
}
|
||||
|
||||
bool CIME::IsCaptureEnabled()
|
||||
{
|
||||
return ms_bCaptureInput;
|
||||
}
|
||||
|
||||
void CIME::Clear()
|
||||
{
|
||||
ms_lastpos = 0;
|
||||
ms_curpos = 0;
|
||||
|
||||
ms_compLen = 0;
|
||||
ms_ulbegin = 0;
|
||||
ms_ulend = 0;
|
||||
}
|
||||
|
||||
int CIME::GetReading(std::string & rstrText)
|
||||
{
|
||||
char reading[IMEREADING_MAXLEN];
|
||||
|
||||
if(ms_wstrReading.size() == 0)
|
||||
return 0;
|
||||
int readingLen = WideCharToMultiByte(ms_uOutputCodePage, 0, &ms_wstrReading[0], ms_wstrReading.size(), reading, sizeof(reading), NULL, NULL);
|
||||
|
||||
rstrText.append(GetCodePageText());
|
||||
rstrText.append(reading, reading + readingLen);
|
||||
|
||||
return rstrText.size();
|
||||
}
|
||||
|
||||
int CIME::GetReadingError()
|
||||
{
|
||||
return ms_iReadingError;
|
||||
}
|
||||
|
||||
void CIME::SetMax(int iMax)
|
||||
{
|
||||
m_max = iMax;
|
||||
}
|
||||
|
||||
void CIME::SetUserMax(int iMax)
|
||||
{
|
||||
m_userMax = iMax;
|
||||
}
|
||||
|
||||
void CIME::SetText(const char* szText, int len)
|
||||
{
|
||||
ms_compLen = 0;
|
||||
ms_ulbegin = 0;
|
||||
ms_ulend = 0;
|
||||
|
||||
const char* begin = szText;
|
||||
const char* end = begin + len;
|
||||
const char* iter = FindToken(begin, end);
|
||||
|
||||
int m_wTextLen = sizeof(m_wText)/sizeof(wchar_t);
|
||||
|
||||
ms_lastpos = MultiByteToWideChar(ms_uInputCodePage, 0, begin, iter-begin, m_wText, m_wTextLen);
|
||||
|
||||
if (iter < end)
|
||||
ms_lastpos += MultiByteToWideChar(ReadToken(iter), 0, (iter+5), end-(iter+5), m_wText+ms_lastpos, m_wTextLen-ms_lastpos);
|
||||
|
||||
ms_curpos = std::min(ms_curpos, ms_lastpos);
|
||||
}
|
||||
|
||||
int CIME::GetText(std::string & rstrText, bool addCodePage)
|
||||
{
|
||||
int outCodePage = ms_uOutputCodePage;
|
||||
int dataCodePage;
|
||||
switch (outCodePage)
|
||||
{
|
||||
//case 1256: // ARABIC
|
||||
case 1268: // VIETNAM
|
||||
dataCodePage = CP_UTF8;
|
||||
break;
|
||||
default:
|
||||
dataCodePage = outCodePage;
|
||||
}
|
||||
|
||||
int len = 0;
|
||||
char text[IMESTR_MAXLEN];
|
||||
|
||||
len += WideCharToMultiByte(dataCodePage, 0, m_wText, ms_curpos, text, sizeof(text)-len, NULL, NULL);
|
||||
len += WideCharToMultiByte(dataCodePage, 0, m_wszComposition, ms_compLen, text+len, sizeof(text)-len, NULL, NULL);
|
||||
len += WideCharToMultiByte(dataCodePage, 0, m_wText+ms_curpos, ms_lastpos-ms_curpos, text+len, sizeof(text)-len, NULL, NULL);
|
||||
|
||||
int i;
|
||||
for(i=0; i<len; ++i)
|
||||
if((BYTE)text[i] > 0x7F) break;
|
||||
|
||||
if(i == len)
|
||||
{
|
||||
rstrText.append(text, text+len);
|
||||
}
|
||||
else
|
||||
{
|
||||
rstrText.append(text, text+i);
|
||||
|
||||
//if (addCodePage)
|
||||
// rstrText.append(GetCodePageText());
|
||||
|
||||
rstrText.append(text+i, text+len);
|
||||
}
|
||||
|
||||
return rstrText.size();
|
||||
}
|
||||
|
||||
const char* CIME::GetCodePageText()
|
||||
{
|
||||
static char szCodePage[16];
|
||||
|
||||
const int defCodePage = GetDefaultCodePage();
|
||||
const int outCodePage = ms_uOutputCodePage;
|
||||
|
||||
if (outCodePage != defCodePage)
|
||||
{
|
||||
sprintf(szCodePage, "@%04d", outCodePage);
|
||||
}
|
||||
else
|
||||
{
|
||||
szCodePage[0] = 0;
|
||||
}
|
||||
|
||||
return szCodePage;
|
||||
}
|
||||
|
||||
int CIME::GetCodePage()
|
||||
{
|
||||
return ms_uOutputCodePage;
|
||||
}
|
||||
|
||||
int CIME::GetCandidatePageCount()
|
||||
{
|
||||
return ms_dwCandidatePageSize;
|
||||
}
|
||||
|
||||
int CIME::GetCandidateCount()
|
||||
{
|
||||
return ms_dwCandidateCount;
|
||||
}
|
||||
|
||||
int CIME::GetCandidate(DWORD index, std::string & rstrText)
|
||||
{
|
||||
if(index >= MAX_CANDLIST)
|
||||
return 0;
|
||||
|
||||
LPCWSTR wszText = ms_wszCandidate[index];
|
||||
if(wszText == NULL)
|
||||
return 0;
|
||||
|
||||
int wTextLen = wcslen(wszText);
|
||||
if(wTextLen == 0)
|
||||
return 0;
|
||||
|
||||
char text[IMESTR_MAXLEN];
|
||||
int len = ::WideCharToMultiByte(CP_UTF8, 0, wszText, wTextLen, text, sizeof(text), 0, 0);
|
||||
|
||||
rstrText.append("@9999");
|
||||
rstrText.append(text, text+len);
|
||||
|
||||
return wTextLen;
|
||||
}
|
||||
|
||||
int CIME::GetCandidateSelection()
|
||||
{
|
||||
return ms_dwCandidateSelection;
|
||||
}
|
||||
|
||||
// PORT: 40250 ImmSetConversionStatus / ImmGetConversionStatus. Without an IMM context the conversion mode is
|
||||
// the alphanumeric one (IME_CMODE_ALPHANUMERIC == 0) and cannot be changed.
|
||||
void CIME::SetInputMode(DWORD)
|
||||
{
|
||||
}
|
||||
|
||||
DWORD CIME::GetInputMode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CIME::SetNumberMode()
|
||||
{
|
||||
m_bOnlyNumberMode = TRUE;
|
||||
}
|
||||
|
||||
void CIME::SetStringMode()
|
||||
{
|
||||
m_bOnlyNumberMode = FALSE;
|
||||
}
|
||||
|
||||
void CIME::AddExceptKey(wchar_t key)
|
||||
{
|
||||
m_exceptKey.push_back(key);
|
||||
}
|
||||
|
||||
void CIME::ClearExceptKey()
|
||||
{
|
||||
m_exceptKey.clear();
|
||||
}
|
||||
|
||||
bool CIME::__IsWritable(wchar_t key)
|
||||
{
|
||||
if ( m_exceptKey.end() == std::find(m_exceptKey.begin(),m_exceptKey.end(),key) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void CIME::EnablePaste(bool bFlag)
|
||||
{
|
||||
m_bEnablePaste = bFlag;
|
||||
}
|
||||
|
||||
// PORT: 40250 reads CF_TEXT from the Win32 clipboard. The host clipboard is not wired to the extension yet,
|
||||
// so this pastes nothing (the same as an empty clipboard).
|
||||
void CIME::PasteTextFromClipBoard()
|
||||
{
|
||||
if (!m_bEnablePaste)
|
||||
return;
|
||||
}
|
||||
|
||||
// PORT: 40250 cancels the IMM composition string and closes the candidate list. There is no composition
|
||||
// here; the candidate-list close (and its event) is kept.
|
||||
void CIME::FinalizeString(bool)
|
||||
{
|
||||
static bool s_bProcessing = false; // to avoid infinite recursion
|
||||
if ( !ms_bInitialized || s_bProcessing )
|
||||
return;
|
||||
s_bProcessing = true;
|
||||
CloseCandidateList();
|
||||
s_bProcessing = false;
|
||||
}
|
||||
|
||||
int CIME::GetCompLen()
|
||||
{
|
||||
return ms_compLen;
|
||||
}
|
||||
|
||||
int CIME::GetULBegin()
|
||||
{
|
||||
return ms_ulbegin;
|
||||
}
|
||||
|
||||
int CIME::GetULEnd()
|
||||
{
|
||||
return ms_ulend;
|
||||
}
|
||||
|
||||
void CIME::CloseCandidateList()
|
||||
{
|
||||
ms_bCandidateList = false;
|
||||
ms_dwCandidateCount = 0;
|
||||
memset(&ms_wszCandidate, 0, sizeof(ms_wszCandidate));
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnCloseCandidateList();
|
||||
}
|
||||
|
||||
void CIME::CloseReadingInformation()
|
||||
{
|
||||
CIME::ms_bReadingInformation = false;
|
||||
if(CIME::ms_pEvent)
|
||||
CIME::ms_pEvent->OnCloseReadingWnd();
|
||||
}
|
||||
|
||||
// PORT: 40250 re-reads the keyboard layout (GETLANG) and re-applies the IME support level when the language
|
||||
// changed. The host has one fixed input locale, so only the toggle check and the code-page event remain.
|
||||
void CIME::ChangeInputLanguage()
|
||||
{
|
||||
CheckToggleState();
|
||||
ChangeInputLanguageWorker();
|
||||
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnChangeCodePage();
|
||||
}
|
||||
|
||||
void CIME::ChangeInputLanguageWorker()
|
||||
{
|
||||
if ( !ms_bUILessMode )
|
||||
ms_iCandListIndexBase = 1;
|
||||
SetupImeApi();
|
||||
}
|
||||
|
||||
// PORT: 40250 forces level 3 for the Korean keyboard layout; there is no keyboard layout here.
|
||||
void CIME::SetSupportLevel( DWORD dwImeLevel )
|
||||
{
|
||||
if ( dwImeLevel < 2 || 3 < dwImeLevel )
|
||||
return;
|
||||
ms_dwIMELevel = dwImeLevel;
|
||||
// cancel current composition string.
|
||||
FinalizeString();
|
||||
}
|
||||
|
||||
LRESULT CIME::WMInputLanguage(HWND, UINT, WPARAM, LPARAM)
|
||||
{
|
||||
ChangeInputLanguage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CIME::WMStartComposition(HWND, UINT, WPARAM, LPARAM)
|
||||
{
|
||||
return 1L;
|
||||
}
|
||||
|
||||
// PORT: 40250 pulls GCS_RESULTSTR/GCS_COMPSTR out of the IMM context. The host never sends compositions.
|
||||
LRESULT CIME::WMComposition(HWND, UINT, WPARAM, LPARAM)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CIME::WMEndComposition(HWND, UINT, WPARAM, LPARAM)
|
||||
{
|
||||
ms_compLen = 0;
|
||||
ms_ulbegin = 0;
|
||||
ms_ulend = 0;
|
||||
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnUpdate();
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
// PORT: 40250 handles IMN_* candidate/reading/toggle notifications from IMM; none are sent here.
|
||||
LRESULT CIME::WMNotify(HWND, UINT, WPARAM, LPARAM)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CIME::WMChar(HWND /*hWnd*/, UINT /*uiMsg*/, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
unsigned char c = (unsigned char)(wParam & 0xff);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 8:
|
||||
if(ms_bCaptureInput == false)
|
||||
return 0;
|
||||
if (ms_curpos > 0)
|
||||
{
|
||||
DecCurPos();
|
||||
DelCurPos();
|
||||
}
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnUpdate();
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
if(ms_pEvent) {
|
||||
if (ms_pEvent->OnWM_CHAR(wParam, lParam))
|
||||
break;
|
||||
}
|
||||
if(ms_bCaptureInput == false)
|
||||
return 0;
|
||||
wchar_t w[10];
|
||||
MultiByteToWideChar(ms_uInputCodePage, 0, (char*)&c, 1, w, 1);
|
||||
|
||||
OnChar(w[0]);
|
||||
if (w[0] == L'|')
|
||||
OnChar(w[0]);
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnUpdate();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/ /* Protected */
|
||||
void CIME::IncCurPos()
|
||||
{
|
||||
if (ms_curpos < ms_lastpos)
|
||||
{
|
||||
int pos = FindColorTagEndPosition(m_wText + ms_curpos, ms_lastpos - ms_curpos);
|
||||
|
||||
if (pos > 0)
|
||||
ms_curpos = std::min(ms_lastpos, std::max(0, ms_curpos + (pos + 1)));
|
||||
else
|
||||
++ms_curpos;
|
||||
//++ms_curpos;
|
||||
}
|
||||
}
|
||||
|
||||
void CIME::DecCurPos()
|
||||
{
|
||||
if (ms_curpos > 0)
|
||||
{
|
||||
int pos = FindColorTagStartPosition(m_wText + ms_curpos - 1, ms_curpos);
|
||||
|
||||
if (pos > 0)
|
||||
ms_curpos = std::min(ms_lastpos, std::max(0, ms_curpos - (pos + 1)));
|
||||
else
|
||||
--ms_curpos;
|
||||
//--ms_curpos;
|
||||
}
|
||||
}
|
||||
|
||||
int CIME::GetCurPos()
|
||||
{
|
||||
int pos = GetTextTagOutputLen(m_wText, ms_curpos);
|
||||
return pos;
|
||||
//return ms_curpos;
|
||||
}
|
||||
|
||||
void CIME::SetCurPos(int offset)
|
||||
{
|
||||
if (offset < 0 || offset > ms_lastpos)
|
||||
{
|
||||
ms_curpos = ms_lastpos;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// offset is a position in the rendered text, so it has to be mapped back to the buffer.
|
||||
//ms_curpos = min(ms_lastpos, offset);
|
||||
ms_curpos = std::min(ms_lastpos, GetTextTagInternalPosFromRenderPos(m_wText, ms_lastpos, offset));
|
||||
}
|
||||
}
|
||||
|
||||
void CIME::DelCurPos()
|
||||
{
|
||||
if (ms_curpos < ms_lastpos)
|
||||
{
|
||||
int eraseCount = FindColorTagEndPosition(m_wText + ms_curpos, ms_lastpos - ms_curpos) + 1;
|
||||
// PORT: 40250 wcscpy()s the overlapping tail down; that is undefined for overlapping buffers, and the
|
||||
// buffer is not guaranteed NUL-terminated at ms_lastpos, so move exactly the live tail.
|
||||
memmove(m_wText + ms_curpos, m_wText + ms_curpos + eraseCount, sizeof(wchar_t) * (ms_lastpos - ms_curpos - eraseCount));
|
||||
ms_lastpos -= eraseCount;
|
||||
ms_curpos = std::min(ms_lastpos, ms_curpos);
|
||||
}
|
||||
}
|
||||
|
||||
void CIME::PasteString(const char * str)
|
||||
{
|
||||
const char * begin = str;
|
||||
const char * end = str + strlen(str);
|
||||
wchar_t m_wText[IMESTR_MAXLEN];
|
||||
int wstrLen = MultiByteToWideChar(ms_uInputCodePage, 0, begin, end - begin, m_wText, IMESTR_MAXLEN);
|
||||
InsertString(m_wText, wstrLen);
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnUpdate();
|
||||
}
|
||||
|
||||
// PORT: 40250 reads the keyboard layout's default ANSI code page (GetLocaleInfoA LOCALE_IDEFAULTANSICODEPAGE).
|
||||
// The host's input locale is the client locale, so its code page (SetDefaultCodePage from locale.cfg) is used.
|
||||
void CIME::CheckInputLocale()
|
||||
{
|
||||
static UINT s_uPrevCodePage = 0xFFFF;
|
||||
|
||||
ms_uInputCodePage = GetDefaultCodePage();
|
||||
if ( s_uPrevCodePage == ms_uInputCodePage )
|
||||
return;
|
||||
s_uPrevCodePage = ms_uInputCodePage;
|
||||
|
||||
ms_bVerticalCandidate = false;
|
||||
ms_wszCurrentIndicator = s_aszNonImeIndicator;
|
||||
|
||||
if(ms_uOutputCodePage != 1256) {
|
||||
ms_uOutputCodePage = ms_uInputCodePage;
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// PORT: 40250 asks IMM whether an IME is open; there is none, so the state is IMEUI_STATE_OFF (0).
|
||||
void CIME::CheckToggleState()
|
||||
{
|
||||
CheckInputLocale();
|
||||
ms_bChineseIME = false;
|
||||
ms_dwImeState = 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/ /* Private */
|
||||
void CIME::InsertString(wchar_t* wString, int iSize)
|
||||
{
|
||||
if (IsMax(wString, iSize))
|
||||
return;
|
||||
|
||||
if (ms_curpos < ms_lastpos)
|
||||
memmove(m_wText+ms_curpos+iSize, m_wText+ms_curpos, sizeof(wchar_t)*(ms_lastpos-ms_curpos));
|
||||
|
||||
memcpy(m_wText+ms_curpos, wString, sizeof(wchar_t)*iSize);
|
||||
|
||||
ms_curpos += iSize;
|
||||
ms_lastpos += iSize;
|
||||
}
|
||||
|
||||
void CIME::OnChar(wchar_t c)
|
||||
{
|
||||
if (m_bOnlyNumberMode)
|
||||
if (!iswdigit(c))
|
||||
return;
|
||||
|
||||
if (!__IsWritable(c))
|
||||
return;
|
||||
|
||||
InsertString(&c, 1);
|
||||
}
|
||||
|
||||
// PORT: 40250 maps a keyboard-layout LANGID to its ANSI code page. Only CheckInputLocale's code page is used
|
||||
// here (see there), so this answers with it.
|
||||
UINT CIME::GetCodePageFromLang(LANGID)
|
||||
{
|
||||
return GetDefaultCodePage();
|
||||
}
|
||||
|
||||
// PORT: the IMM composition/candidate/reading processors (40250 IME.cpp:951-1227). No IMM context exists.
|
||||
void CIME::ResultProcess(HIMC) {}
|
||||
void CIME::CompositionProcessBuilding(HIMC) {}
|
||||
void CIME::CompositionProcess(HIMC) {}
|
||||
void CIME::AttributeProcess(HIMC) {}
|
||||
void CIME::CandidateProcess(HIMC) {}
|
||||
void CIME::ReadingProcess(HIMC) {}
|
||||
|
||||
bool CIME::IsMax(const wchar_t* wInput, int len)
|
||||
{
|
||||
if (ms_lastpos + len > IMESTR_MAXLEN)
|
||||
return true;
|
||||
|
||||
int textLen = WideCharToMultiByte(ms_uOutputCodePage, 0, m_wText, ms_lastpos, 0, 0, NULL, NULL);
|
||||
int inputLen = WideCharToMultiByte(ms_uOutputCodePage, 0, wInput, len, 0, 0, NULL, NULL);
|
||||
//return textLen + inputLen > m_max;
|
||||
|
||||
if (textLen + inputLen > m_max)
|
||||
return true;
|
||||
else if (m_userMax != 0 && m_max != m_userMax)
|
||||
{
|
||||
std::wstring str = GetTextTagOutputString(m_wText, ms_lastpos);
|
||||
std::wstring input = GetTextTagOutputString(wInput, len);
|
||||
int textLen = WideCharToMultiByte(ms_uOutputCodePage, 0, str.c_str(), str.length(), 0, 0, NULL, NULL);
|
||||
int inputLen = WideCharToMultiByte(ms_uOutputCodePage, 0, input.c_str(), input.length(), 0, 0, NULL, NULL);
|
||||
return textLen + inputLen > m_userMax;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// PORT: 40250 identifies the CHT/CHS IME DLL version and the reading-window orientation. No IME DLL here.
|
||||
DWORD CIME::GetImeId(UINT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CIME::GetReadingWindowOrientation()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void CIME::SetupImeApi()
|
||||
{
|
||||
_GetReadingString = NULL;
|
||||
_ShowReadingWindow = NULL;
|
||||
}
|
||||
|
||||
decltype(CIME::_ImmLockIMC) CIME::_ImmLockIMC{};
|
||||
|
||||
decltype(CIME::_ImmUnlockIMC) CIME::_ImmUnlockIMC{};
|
||||
|
||||
decltype(CIME::_ImmLockIMCC) CIME::_ImmLockIMCC{};
|
||||
|
||||
decltype(CIME::_ImmUnlockIMCC) CIME::_ImmUnlockIMCC{};
|
||||
|
||||
decltype(CIME::_GetReadingString) CIME::_GetReadingString{};
|
||||
|
||||
decltype(CIME::_ShowReadingWindow) CIME::_ShowReadingWindow{};
|
||||
|
||||
decltype(CIME::ms_bInitialized) CIME::ms_bInitialized{};
|
||||
|
||||
decltype(CIME::ms_bDisableIMECompletely) CIME::ms_bDisableIMECompletely{};
|
||||
|
||||
decltype(CIME::ms_bUILessMode) CIME::ms_bUILessMode{};
|
||||
|
||||
decltype(CIME::ms_bImeEnabled) CIME::ms_bImeEnabled{};
|
||||
|
||||
decltype(CIME::ms_bCaptureInput) CIME::ms_bCaptureInput{};
|
||||
|
||||
decltype(CIME::ms_bChineseIME) CIME::ms_bChineseIME{};
|
||||
|
||||
decltype(CIME::ms_bUseIMMCandidate) CIME::ms_bUseIMMCandidate{};
|
||||
|
||||
decltype(CIME::ms_hWnd) CIME::ms_hWnd{};
|
||||
|
||||
decltype(CIME::ms_hklCurrent) CIME::ms_hklCurrent{};
|
||||
|
||||
decltype(CIME::ms_szKeyboardLayout) CIME::ms_szKeyboardLayout{};
|
||||
|
||||
decltype(CIME::ms_stOSVI) CIME::ms_stOSVI{};
|
||||
|
||||
decltype(CIME::ms_hImm32Dll) CIME::ms_hImm32Dll{};
|
||||
|
||||
decltype(CIME::ms_hCurrentImeDll) CIME::ms_hCurrentImeDll{};
|
||||
|
||||
decltype(CIME::ms_dwImeState) CIME::ms_dwImeState{};
|
||||
|
||||
decltype(CIME::ms_adwId) CIME::ms_adwId{};
|
||||
|
||||
decltype(CIME::ms_dwIMELevel) CIME::ms_dwIMELevel{};
|
||||
|
||||
decltype(CIME::ms_dwIMELevelSaved) CIME::ms_dwIMELevelSaved{};
|
||||
|
||||
decltype(CIME::ms_bCandidateList) CIME::ms_bCandidateList{};
|
||||
|
||||
decltype(CIME::ms_dwCandidateCount) CIME::ms_dwCandidateCount{};
|
||||
|
||||
decltype(CIME::ms_bVerticalCandidate) CIME::ms_bVerticalCandidate{};
|
||||
|
||||
decltype(CIME::ms_iCandListIndexBase) CIME::ms_iCandListIndexBase{};
|
||||
|
||||
decltype(CIME::ms_wszCandidate) CIME::ms_wszCandidate{};
|
||||
|
||||
decltype(CIME::ms_dwCandidateSelection) CIME::ms_dwCandidateSelection{};
|
||||
|
||||
decltype(CIME::ms_dwCandidatePageSize) CIME::ms_dwCandidatePageSize{};
|
||||
|
||||
decltype(CIME::ms_bReadingInformation) CIME::ms_bReadingInformation{};
|
||||
|
||||
decltype(CIME::ms_iReadingError) CIME::ms_iReadingError{};
|
||||
|
||||
decltype(CIME::ms_bHorizontalReading) CIME::ms_bHorizontalReading{};
|
||||
|
||||
decltype(CIME::ms_wstrReading) CIME::ms_wstrReading{};
|
||||
|
||||
decltype(CIME::ms_wszCurrentIndicator) CIME::ms_wszCurrentIndicator{};
|
||||
|
||||
decltype(CIME::ms_pEvent) CIME::ms_pEvent{};
|
||||
|
||||
decltype(CIME::m_wText) CIME::m_wText{};
|
||||
|
||||
decltype(CIME::ms_compLen) CIME::ms_compLen{};
|
||||
|
||||
decltype(CIME::ms_curpos) CIME::ms_curpos{};
|
||||
|
||||
decltype(CIME::ms_lastpos) CIME::ms_lastpos{};
|
||||
|
||||
decltype(CIME::ms_ulbegin) CIME::ms_ulbegin{};
|
||||
|
||||
decltype(CIME::ms_ulend) CIME::ms_ulend{};
|
||||
|
||||
decltype(CIME::ms_uOutputCodePage) CIME::ms_uOutputCodePage{};
|
||||
|
||||
decltype(CIME::ms_uInputCodePage) CIME::ms_uInputCodePage{};
|
||||
@@ -0,0 +1,81 @@
|
||||
// Platform skeleton for EterLib/Input.h (40250 EterLib/Input.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/Input.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CInputDevice::CInputDevice()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CInputDevice::~CInputDevice()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CInputDevice::CreateDevice(HWND) -> HRESULT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<HRESULT>();
|
||||
}
|
||||
|
||||
decltype(CInputDevice::ms_lpDI) CInputDevice::ms_lpDI{};
|
||||
|
||||
CInputKeyboard::CInputKeyboard()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CInputKeyboard::~CInputKeyboard()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CInputKeyboard::InitializeKeyboard(HWND) -> bool
|
||||
{
|
||||
ResetKeyboard();
|
||||
return true;
|
||||
}
|
||||
|
||||
auto CInputKeyboard::UpdateKeyboard() -> void
|
||||
{
|
||||
}
|
||||
|
||||
auto CInputKeyboard::ResetKeyboard() -> void
|
||||
{
|
||||
memset(ms_bPressedKey, 0, sizeof(ms_bPressedKey));
|
||||
memset(ms_diks, 0, sizeof(ms_diks));
|
||||
}
|
||||
|
||||
auto CInputKeyboard::IsPressed(int iIndex) -> bool
|
||||
{
|
||||
if (iIndex >= 0 && iIndex < 256)
|
||||
return (ms_diks[iIndex] & 0x80) != 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto CInputKeyboard::KeyDown(int iIndex) -> void
|
||||
{
|
||||
if (iIndex >= 0 && iIndex < 256)
|
||||
{
|
||||
ms_bPressedKey[iIndex] = true;
|
||||
ms_diks[iIndex] = (char)0x80;
|
||||
}
|
||||
}
|
||||
|
||||
auto CInputKeyboard::KeyUp(int iIndex) -> void
|
||||
{
|
||||
if (iIndex >= 0 && iIndex < 256)
|
||||
{
|
||||
ms_bPressedKey[iIndex] = false;
|
||||
ms_diks[iIndex] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
decltype(CInputKeyboard::ms_lpKeyboard) CInputKeyboard::ms_lpKeyboard{};
|
||||
|
||||
decltype(CInputKeyboard::ms_bPressedKey) CInputKeyboard::ms_bPressedKey{};
|
||||
|
||||
decltype(CInputKeyboard::ms_diks) CInputKeyboard::ms_diks{};
|
||||
@@ -0,0 +1,49 @@
|
||||
// Platform skeleton for EterLib/MSApplication.h (40250 EterLib/MSApplication.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/MSApplication.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CMSApplication::CMSApplication()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CMSApplication::~CMSApplication()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSApplication::Initialize(HINSTANCE) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSApplication::MessageLoop() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSApplication::IsMessage() -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CMSApplication::MessageProcess() -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CMSApplication::ClearWindowClass() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSApplication::WindowProcedure(HWND, UINT, WPARAM, LPARAM) -> LRESULT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<LRESULT>();
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
// Platform skeleton for EterLib/MSWindow.h (40250 EterLib/MSWindow.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/MSWindow.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
#include "HostCursor.h"
|
||||
|
||||
CMSWindow::CMSWindow()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CMSWindow::~CMSWindow()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::Destroy() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::Create(const char *, int, DWORD, DWORD, HICON, int) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CMSWindow::Show() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::Hide() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::SetVisibleMode(bool) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::SetPosition(int, int) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::SetCenterPosition() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::SetText(const char *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::AdjustSize(int, int) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::SetSize(int, int) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::IsVisible() -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CMSWindow::IsActive() -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
namespace {
|
||||
POINT g_host_cursor = {0, 0};
|
||||
}
|
||||
|
||||
void MtHostSetCursor(int x, int y)
|
||||
{
|
||||
g_host_cursor.x = x;
|
||||
g_host_cursor.y = y;
|
||||
}
|
||||
|
||||
auto CMSWindow::GetMousePosition(POINT * ppt) -> void
|
||||
{
|
||||
*ppt = g_host_cursor;
|
||||
}
|
||||
|
||||
auto CMSWindow::GetClientRect(RECT *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::GetWindowRect(RECT *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::GetScreenWidth() -> int
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
}
|
||||
|
||||
auto CMSWindow::GetScreenHeight() -> int
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
}
|
||||
|
||||
auto CMSWindow::GetWindowHandle() -> HWND
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<HWND>();
|
||||
}
|
||||
|
||||
auto CMSWindow::GetInstance() -> HINSTANCE
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<HINSTANCE>();
|
||||
}
|
||||
|
||||
auto CMSWindow::WindowProcedure(HWND, UINT, WPARAM, LPARAM) -> LRESULT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<LRESULT>();
|
||||
}
|
||||
|
||||
auto CMSWindow::OnSize(WPARAM, LPARAM) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CMSWindow::RegisterWindowClass(DWORD, int, WNDPROC, HICON, int) -> const char *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<const char *>();
|
||||
}
|
||||
|
||||
decltype(CMSWindow::ms_stWCSet) CMSWindow::ms_stWCSet{};
|
||||
|
||||
decltype(CMSWindow::ms_hInstance) CMSWindow::ms_hInstance{};
|
||||
@@ -0,0 +1,32 @@
|
||||
// Platform skeleton for EterLib/Mutex.h (40250 EterLib/Mutex.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/Mutex.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
Mutex::Mutex()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
Mutex::~Mutex()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto Mutex::Lock() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto Mutex::Unlock() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto Mutex::Trylock() -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
// The platform's IDirect3DDevice8: CGraphicDevice::Create hands it to CStateManager, which keeps
|
||||
// 40250's state caching; the device remembers the state it is given and turns every draw call into a
|
||||
// Render3DDraw (RenderCommands3D.h) for the Godot renderer.
|
||||
#include "EterLib/StdAfx.h"
|
||||
|
||||
IDirect3DDevice8* MtCreateRecordingDevice(int width, int height);
|
||||
@@ -0,0 +1,141 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// The 3D draw calls the ported game render (CPythonApplication::RenderGame) issues through
|
||||
// CStateManager, recorded by the platform's IDirect3DDevice8 (RecordingDevice.cpp) and consumed by
|
||||
// Godot. Like UIRenderCommands.h this header stays free of D3D and godot-cpp types.
|
||||
//
|
||||
// Matrices are D3D8's row-vector layout (translation in elements 12..14), exactly as 40250 set them.
|
||||
struct Render3DDraw {
|
||||
// Stable source-buffer identity and content version. Zero key means an immediate-mode draw
|
||||
// without a reusable D3D buffer. Geometry may be reused only while both values match.
|
||||
std::uint64_t geometry_key = 0;
|
||||
std::uint64_t geometry_revision = 0;
|
||||
float world[16];
|
||||
float view[16];
|
||||
float proj[16];
|
||||
float viewport[4] = {}; // x, y, width, height
|
||||
float viewport_z[2] = {0, 1}; // MinZ, MaxZ
|
||||
// PORT: UIRenderOffsetX() when recorded (a draw from a shifted window layer); the host moves the
|
||||
// viewport (and a pretransformed draw's screen positions) right by it.
|
||||
float ui_offset_x = 0;
|
||||
|
||||
// IDirect3DDevice8::Clear on the back buffer, kept in draw order. A clear entry has no geometry;
|
||||
// clear_flags holds D3DCLEAR_TARGET / D3DCLEAR_ZBUFFER / D3DCLEAR_STENCIL.
|
||||
std::uint32_t clear_flags = 0;
|
||||
std::uint32_t clear_color = 0; // 0xAARRGGBB
|
||||
float clear_z = 1;
|
||||
|
||||
// Non-zero: the draw (or clear) targets an offscreen render-target texture instead of the back
|
||||
// buffer -- the 40250 character shadow map. The renderer draws these into the texture named
|
||||
// Render3DRenderTargetName(render_target, ...) ahead of the back-buffer pass, in recorded order.
|
||||
// viewport is then in the target's pixels. Only emitted while GPU render targets are enabled.
|
||||
std::uint32_t render_target = 0;
|
||||
std::uint32_t target_width = 0, target_height = 0;
|
||||
|
||||
// Stage 0/1 textures, named like UIRenderTextureName: the pack path of a file texture or
|
||||
// "mem:<id>@<revision>"; empty when the stage has no texture.
|
||||
std::string texture0;
|
||||
std::string texture1;
|
||||
|
||||
// The referenced vertices, rebased so indices start at 0. normals/uv0/uv1/diffuse are empty when
|
||||
// the vertex format has no such element. pretransformed: D3DFVF_XYZRHW (screen-space x, y, z, rhw
|
||||
// in positions + rhw).
|
||||
bool pretransformed = false;
|
||||
std::vector<float> positions; // x, y, z
|
||||
std::vector<float> rhw;
|
||||
// D3D8 vertex fog of an XYZRHW draw: the D3DFVF_SPECULAR alpha (0..1); empty otherwise.
|
||||
std::vector<float> vertex_fog;
|
||||
std::vector<float> normals; // x, y, z
|
||||
std::vector<float> uv0; // u, v
|
||||
std::vector<float> uv1; // u, v
|
||||
std::vector<std::uint32_t> diffuse; // 0xAARRGGBB
|
||||
std::vector<std::uint32_t> indices; // triangle list (strips and fans are expanded), or line list
|
||||
std::vector<std::uint8_t> bone_indices; // 4 uint8 per vertex (mesh-local bone palette index)
|
||||
std::vector<float> bone_weights; // 4 floats per vertex
|
||||
std::vector<float> bone_matrices; // 16 floats per bone in the mesh's palette (D3D row-vector layout)
|
||||
bool lines = false;
|
||||
|
||||
// D3DRS_* / D3DTSS_* values in effect for the draw.
|
||||
std::uint32_t alpha_blend = 0, src_blend = 0, dest_blend = 0;
|
||||
std::uint32_t alpha_test = 0, alpha_ref = 0, alpha_func = 0;
|
||||
std::uint32_t cull_mode = 0, z_enable = 0, z_write = 0, z_func = 0;
|
||||
std::uint32_t lighting = 0, texture_factor = 0, fog_enable = 0;
|
||||
std::uint32_t fog_color = 0, fog_vertex_mode = 0, fog_table_mode = 0, fog_range_enable = 0;
|
||||
float fog_start = 0, fog_end = 0, fog_density = 0;
|
||||
std::uint32_t color_op[2] = {}, color_arg1[2] = {}, color_arg2[2] = {};
|
||||
std::uint32_t alpha_op[2] = {}, alpha_arg1[2] = {}, alpha_arg2[2] = {};
|
||||
std::uint32_t address_u[2] = {}, address_v[2] = {};
|
||||
std::uint32_t min_filter[2] = {}, mag_filter[2] = {}, mip_filter[2] = {};
|
||||
std::uint32_t border_color[2] = {};
|
||||
// D3DTSS_TEXCOORDINDEX (set index | D3DTSS_TCI_* generation mode), D3DTSS_TEXTURETRANSFORMFLAGS and
|
||||
// D3DTS_TEXTURE0/1 per stage. The renderer generates and transforms texture coordinates from
|
||||
// these the way the D3D8 fixed-function vertex pipeline does; uv0/uv1 stay the raw vertex sets.
|
||||
std::uint32_t texcoord_index[2] = {0, 1};
|
||||
std::uint32_t texture_transform_flags[2] = {};
|
||||
float texture_matrix[2][16] = {{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}};
|
||||
// D3DMATERIAL8 diffuse/ambient/emissive (r, g, b, a) and light 0 when enabled.
|
||||
float material_diffuse[4] = {1, 1, 1, 1};
|
||||
float material_ambient[4] = {};
|
||||
float material_emissive[4] = {};
|
||||
bool light0 = false;
|
||||
float light0_direction[3] = {};
|
||||
float light0_diffuse[4] = {};
|
||||
float light0_ambient[4] = {};
|
||||
std::uint32_t ambient = 0; // D3DRS_AMBIENT
|
||||
struct Light {
|
||||
std::uint32_t type = 0; // zero when disabled; D3DLIGHT_POINT/SPOT/DIRECTIONAL otherwise
|
||||
float position[3] = {};
|
||||
float direction[3] = {};
|
||||
float diffuse[4] = {};
|
||||
float ambient[4] = {};
|
||||
float attenuation[3] = {};
|
||||
float range = 0;
|
||||
float theta = 0, phi = 0, falloff = 0;
|
||||
} lights[8];
|
||||
std::uint32_t diffuse_material_source = 0;
|
||||
std::uint32_t ambient_material_source = 0;
|
||||
std::uint32_t emissive_material_source = 0;
|
||||
std::uint32_t color_vertex = 0;
|
||||
std::uint32_t normalize_normals = 0; // D3DRS_NORMALIZENORMALS
|
||||
std::uint32_t local_viewer = 1; // D3DRS_LOCALVIEWER
|
||||
};
|
||||
|
||||
// The texture coordinates stage 0/1 samples at each vertex, computed on the CPU with the same
|
||||
// D3D8 fixed-function rules the native renderer's vertex shader applies (TEXCOORDINDEX generation,
|
||||
// then D3DTS_TEXTUREn under TEXTURETRANSFORMFLAGS). For consumers without that shader (Godot).
|
||||
void Render3DStageTexcoords(const Render3DDraw& draw, int stage, std::vector<float>& out);
|
||||
|
||||
struct GpuSkinSubrangeView {
|
||||
std::uint64_t source_mesh_key = 0;
|
||||
std::uint32_t mesh_base_vertex = 0;
|
||||
std::uint32_t mesh_vertex_count = 0;
|
||||
const std::uint8_t* bone_indices = nullptr; // mesh_vertex_count * 4
|
||||
const float* bone_weights = nullptr; // mesh_vertex_count * 4
|
||||
const float* bone_matrices = nullptr; // bone_count * 16
|
||||
std::uint32_t bone_count = 0;
|
||||
};
|
||||
|
||||
void SetNativeTerrainRenderEnabled(bool enabled);
|
||||
bool IsNativeTerrainRenderEnabled();
|
||||
|
||||
void SetGpuSkinningEnabled(bool enabled);
|
||||
bool IsGpuSkinningEnabled();
|
||||
bool LookupGpuSkinSubrange(const void* vertex_buffer_base, std::uint32_t stride,
|
||||
std::uint32_t lo_vertex, std::uint32_t hi_vertex,
|
||||
GpuSkinSubrangeView* out_view);
|
||||
|
||||
// GPU render targets: shadow-map draws are recorded with render_target set and sampled as
|
||||
// "rt:<id>:<w>x<h>" instead of being rasterized on the CPU into a "mem:cpu_<id>" texture. Off by
|
||||
// default (the Godot consumer has no offscreen pass); the native Vulkan renderer turns it on.
|
||||
void SetGpuRenderTargetsEnabled(bool enabled);
|
||||
bool IsGpuRenderTargetsEnabled();
|
||||
std::string Render3DRenderTargetName(std::uint32_t id, std::uint32_t width, std::uint32_t height);
|
||||
|
||||
void Render3DBeginFrame();
|
||||
void Render3DAdd(Render3DDraw draw);
|
||||
const std::vector<Render3DDraw>& Render3DDraws();
|
||||
@@ -0,0 +1,787 @@
|
||||
// Platform implementation of EterLib/SkyBox.cpp (40250 EterLib/SkyBox.cpp).
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/SkyBox.h"
|
||||
#include "EterLib/Camera.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
#include "EterLib/ResourceManager.h"
|
||||
#include "EterBase/Timer.h"
|
||||
#include "RenderCommands3D.h"
|
||||
|
||||
CSkyObjectQuad::CSkyObjectQuad()
|
||||
{
|
||||
m_Indices[0] = 0;
|
||||
m_Indices[1] = 2;
|
||||
m_Indices[2] = 1;
|
||||
m_Indices[3] = 3;
|
||||
|
||||
for (unsigned char uci = 0; uci < 4; ++uci)
|
||||
{
|
||||
memset(&m_Vertex[uci], 0, sizeof(TPDTVertex));
|
||||
}
|
||||
}
|
||||
|
||||
CSkyObjectQuad::~CSkyObjectQuad()
|
||||
{
|
||||
}
|
||||
|
||||
void CSkyObjectQuad::Clear(const unsigned char & c_rucNumVertex,
|
||||
const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha)
|
||||
{
|
||||
if (c_rucNumVertex > 3)
|
||||
return;
|
||||
m_Helper[c_rucNumVertex].Clear(c_rfRed, c_rfGreen, c_rfBlue, c_rfAlpha);
|
||||
}
|
||||
|
||||
void CSkyObjectQuad::SetSrcColor(const unsigned char & c_rucNumVertex,
|
||||
const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha)
|
||||
{
|
||||
if (c_rucNumVertex > 3)
|
||||
return;
|
||||
m_Helper[c_rucNumVertex].SetSrcColor(c_rfRed, c_rfGreen, c_rfBlue, c_rfAlpha);
|
||||
}
|
||||
|
||||
void CSkyObjectQuad::SetTransition(const unsigned char & c_rucNumVertex,
|
||||
const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha,
|
||||
DWORD dwDuration)
|
||||
{
|
||||
if (c_rucNumVertex > 3)
|
||||
return;
|
||||
m_Helper[c_rucNumVertex].SetTransition(c_rfRed, c_rfGreen, c_rfBlue, c_rfAlpha, dwDuration);
|
||||
}
|
||||
|
||||
void CSkyObjectQuad::SetVertex(const unsigned char & c_rucNumVertex, const TPDTVertex & c_rPDTVertex)
|
||||
{
|
||||
if (c_rucNumVertex > 3)
|
||||
return;
|
||||
memcpy(&m_Vertex[m_Indices[c_rucNumVertex]], &c_rPDTVertex, sizeof(TPDTVertex));
|
||||
}
|
||||
|
||||
void CSkyObjectQuad::StartTransition()
|
||||
{
|
||||
for (unsigned char uci = 0; uci < 4; ++uci)
|
||||
{
|
||||
m_Helper[uci].StartTransition();
|
||||
}
|
||||
}
|
||||
|
||||
bool CSkyObjectQuad::Update()
|
||||
{
|
||||
bool bResult = false;
|
||||
for (unsigned char uci = 0; uci < 4; ++uci)
|
||||
{
|
||||
bResult = m_Helper[uci].Update() || bResult;
|
||||
m_Vertex[m_Indices[uci]].diffuse = m_Helper[uci].GetCurColor();
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
|
||||
void CSkyObjectQuad::Render()
|
||||
{
|
||||
if (CGraphicBase::SetPDTStream(m_Vertex, 4))
|
||||
STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
}
|
||||
|
||||
CSkyObject::CSkyObject() :
|
||||
m_v3Position(0.0f, 0.0f, 0.0f),
|
||||
m_fScaleX(1.0f),
|
||||
m_fScaleY(1.0f),
|
||||
m_fScaleZ(1.0f)
|
||||
{
|
||||
D3DXMatrixIdentity(&m_matWorld);
|
||||
D3DXMatrixIdentity(&m_matTranslation);
|
||||
D3DXMatrixIdentity(&m_matWorldCloud);
|
||||
D3DXMatrixIdentity(&m_matTranslationCloud);
|
||||
D3DXMatrixIdentity(&m_matTextureCloud);
|
||||
|
||||
m_dwlastTime = CTimer::Instance().GetCurrentMillisecond();
|
||||
|
||||
m_fCloudPositionU = 0.0f;
|
||||
m_fCloudPositionV = 0.0f;
|
||||
m_fCloudScaleX = 1.0f;
|
||||
m_fCloudScaleY = 1.0f;
|
||||
m_fCloudHeight = 0.0f;
|
||||
m_fCloudTextureScaleX = 1.0f;
|
||||
m_fCloudTextureScaleY = 1.0f;
|
||||
m_fCloudScrollSpeedU = 0.0f;
|
||||
m_fCloudScrollSpeedV = 0.0f;
|
||||
m_ucRenderMode = SKY_RENDER_MODE_DEFAULT;
|
||||
|
||||
m_bTransitionStarted = false;
|
||||
m_bSkyMatrixUpdated = false;
|
||||
}
|
||||
|
||||
CSkyObject::~CSkyObject()
|
||||
{
|
||||
}
|
||||
|
||||
void CSkyObject::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
void CSkyObject::Update()
|
||||
{
|
||||
CCamera* pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCamera)
|
||||
return;
|
||||
D3DXVECTOR3 v3Eye = pCamera->GetEye();
|
||||
|
||||
if (m_v3Position == v3Eye)
|
||||
if (m_bSkyMatrixUpdated == false)
|
||||
return;
|
||||
|
||||
m_v3Position = v3Eye;
|
||||
|
||||
m_matWorld._41 = m_v3Position.x;
|
||||
m_matWorld._42 = m_v3Position.y;
|
||||
m_matWorld._43 = m_v3Position.z;
|
||||
|
||||
m_matWorldCloud._41 = m_v3Position.x;
|
||||
m_matWorldCloud._42 = m_v3Position.y;
|
||||
m_matWorldCloud._43 = m_v3Position.z + m_fCloudHeight;
|
||||
|
||||
if (m_bSkyMatrixUpdated)
|
||||
m_bSkyMatrixUpdated = false;
|
||||
}
|
||||
|
||||
void CSkyObject::Render()
|
||||
{
|
||||
}
|
||||
|
||||
void CSkyObject::StartTransition()
|
||||
{
|
||||
}
|
||||
|
||||
CGraphicImageInstance * CSkyObject::GenerateTexture(const char * szfilename)
|
||||
{
|
||||
if (!szfilename || !*szfilename)
|
||||
return NULL;
|
||||
|
||||
CResource * pResource = CResourceManager::Instance().GetResourcePointer(szfilename);
|
||||
if (!pResource || !pResource->IsType(CGraphicImage::Type()))
|
||||
return NULL;
|
||||
|
||||
CGraphicImageInstance * pImageInstance = CGraphicImageInstance::New();
|
||||
pImageInstance->SetImagePointer(static_cast<CGraphicImage *>(pResource));
|
||||
return pImageInstance;
|
||||
}
|
||||
|
||||
void CSkyObject::DeleteTexture(CGraphicImageInstance * pImageInstance)
|
||||
{
|
||||
if (pImageInstance)
|
||||
CGraphicImageInstance::Delete(pImageInstance);
|
||||
}
|
||||
|
||||
void CSkyObject::TSkyObjectFace::StartTransition()
|
||||
{
|
||||
for (unsigned char uci = 0; uci < m_SkyObjectQuadVector.size(); ++uci)
|
||||
{
|
||||
m_SkyObjectQuadVector[uci].StartTransition();
|
||||
}
|
||||
}
|
||||
|
||||
bool CSkyObject::TSkyObjectFace::Update()
|
||||
{
|
||||
bool bResult = false;
|
||||
for (DWORD dwi = 0; dwi < m_SkyObjectQuadVector.size(); ++dwi)
|
||||
bResult = m_SkyObjectQuadVector[dwi].Update() || bResult;
|
||||
return bResult;
|
||||
}
|
||||
|
||||
void CSkyObject::TSkyObjectFace::Render()
|
||||
{
|
||||
for (unsigned char uci = 0; uci < m_SkyObjectQuadVector.size(); ++uci)
|
||||
{
|
||||
m_SkyObjectQuadVector[uci].Render();
|
||||
}
|
||||
}
|
||||
|
||||
CSkyBox::CSkyBox()
|
||||
{
|
||||
m_ucVirticalGradientLevelUpper = 0;
|
||||
m_ucVirticalGradientLevelLower = 0;
|
||||
}
|
||||
|
||||
CSkyBox::~CSkyBox()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CSkyBox::Destroy()
|
||||
{
|
||||
Unload();
|
||||
}
|
||||
|
||||
void CSkyBox::Unload()
|
||||
{
|
||||
TGraphicImageInstanceMap::iterator itor = m_GraphicImageInstanceMap.begin();
|
||||
|
||||
while (itor != m_GraphicImageInstanceMap.end())
|
||||
{
|
||||
DeleteTexture(itor->second);
|
||||
++itor;
|
||||
}
|
||||
|
||||
m_GraphicImageInstanceMap.clear();
|
||||
}
|
||||
|
||||
void CSkyBox::SetSkyBoxScale(const D3DXVECTOR3 & c_rv3Scale)
|
||||
{
|
||||
m_fScaleX = c_rv3Scale.x;
|
||||
m_fScaleY = c_rv3Scale.y;
|
||||
m_fScaleZ = c_rv3Scale.z;
|
||||
|
||||
m_bSkyMatrixUpdated = true;
|
||||
D3DXMatrixScaling(&m_matWorld, m_fScaleX, m_fScaleY, m_fScaleZ);
|
||||
}
|
||||
|
||||
void CSkyBox::SetGradientLevel(BYTE byUpper, BYTE byLower)
|
||||
{
|
||||
m_ucVirticalGradientLevelUpper = byUpper;
|
||||
m_ucVirticalGradientLevelLower = byLower;
|
||||
}
|
||||
|
||||
void CSkyBox::SetFaceTexture(const char* c_szFileName, int iFaceIndex)
|
||||
{
|
||||
if (iFaceIndex < 0 || iFaceIndex > 5 || !c_szFileName || !*c_szFileName)
|
||||
return;
|
||||
|
||||
TGraphicImageInstanceMap::iterator itor = m_GraphicImageInstanceMap.find(c_szFileName);
|
||||
if (m_GraphicImageInstanceMap.end() != itor)
|
||||
return;
|
||||
|
||||
m_Faces[iFaceIndex].m_strFaceTextureFileName = c_szFileName;
|
||||
|
||||
CGraphicImageInstance * pGraphicImageInstance = GenerateTexture(c_szFileName);
|
||||
m_GraphicImageInstanceMap.insert(TGraphicImageInstanceMap::value_type(c_szFileName, pGraphicImageInstance));
|
||||
}
|
||||
|
||||
void CSkyBox::SetCloudTexture(const char * c_szFileName)
|
||||
{
|
||||
if (!c_szFileName || !*c_szFileName)
|
||||
return;
|
||||
|
||||
TGraphicImageInstanceMap::iterator itor = m_GraphicImageInstanceMap.find(c_szFileName);
|
||||
if (m_GraphicImageInstanceMap.end() != itor)
|
||||
return;
|
||||
|
||||
m_FaceCloud.m_strfacename = c_szFileName;
|
||||
CGraphicImageInstance * pGraphicImageInstance = GenerateTexture(c_szFileName);
|
||||
m_GraphicImageInstanceMap.insert(TGraphicImageInstanceMap::value_type(m_FaceCloud.m_strfacename, pGraphicImageInstance));
|
||||
}
|
||||
|
||||
void CSkyBox::SetCloudScale(const D3DXVECTOR2 & c_rv2CloudScale)
|
||||
{
|
||||
m_fCloudScaleX = c_rv2CloudScale.x;
|
||||
m_fCloudScaleY = c_rv2CloudScale.y;
|
||||
|
||||
D3DXMatrixScaling(&m_matWorldCloud, m_fCloudScaleX, m_fCloudScaleY, 1.0f);
|
||||
}
|
||||
|
||||
void CSkyBox::SetCloudHeight(float fHeight)
|
||||
{
|
||||
m_fCloudHeight = fHeight;
|
||||
}
|
||||
|
||||
void CSkyBox::SetCloudTextureScale(const D3DXVECTOR2 & c_rv2CloudTextureScale)
|
||||
{
|
||||
m_fCloudTextureScaleX = c_rv2CloudTextureScale.x;
|
||||
m_fCloudTextureScaleY = c_rv2CloudTextureScale.y;
|
||||
|
||||
m_matTextureCloud._11 = m_fCloudTextureScaleX;
|
||||
m_matTextureCloud._22 = m_fCloudTextureScaleY;
|
||||
}
|
||||
|
||||
void CSkyBox::SetCloudScrollSpeed(const D3DXVECTOR2 & c_rv2CloudScrollSpeed)
|
||||
{
|
||||
m_fCloudScrollSpeedU = c_rv2CloudScrollSpeed.x;
|
||||
m_fCloudScrollSpeedV = c_rv2CloudScrollSpeed.y;
|
||||
}
|
||||
|
||||
void CSkyBox::SetSkyObjectQuadVertical(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR2 * c_pv2QuadPoints)
|
||||
{
|
||||
TPDTVertex aPDTVertex;
|
||||
|
||||
DWORD dwIndex = 0;
|
||||
|
||||
pSkyObjectQuadVector->clear();
|
||||
pSkyObjectQuadVector->resize(m_ucVirticalGradientLevelUpper + m_ucVirticalGradientLevelLower);
|
||||
|
||||
unsigned char ucY;
|
||||
for (ucY = 0; ucY < m_ucVirticalGradientLevelUpper; ++ucY)
|
||||
{
|
||||
CSkyObjectQuad & rSkyObjectQuad = pSkyObjectQuadVector->at(dwIndex++);
|
||||
|
||||
aPDTVertex.position.x = c_pv2QuadPoints[0].x;
|
||||
aPDTVertex.position.y = c_pv2QuadPoints[0].y;
|
||||
aPDTVertex.position.z = 1.0f - (float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper);
|
||||
aPDTVertex.texCoord.x = 0.0f;
|
||||
aPDTVertex.texCoord.y = (float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper) * 0.5f;
|
||||
rSkyObjectQuad.SetVertex(0, aPDTVertex);
|
||||
aPDTVertex.position.x = c_pv2QuadPoints[0].x;
|
||||
aPDTVertex.position.y = c_pv2QuadPoints[0].y;
|
||||
aPDTVertex.position.z = 1.0f - (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper);
|
||||
aPDTVertex.texCoord.x = 0.0f;
|
||||
aPDTVertex.texCoord.y = (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper) * 0.5f;
|
||||
rSkyObjectQuad.SetVertex(1, aPDTVertex);
|
||||
aPDTVertex.position.x = c_pv2QuadPoints[1].x;
|
||||
aPDTVertex.position.y = c_pv2QuadPoints[1].y;
|
||||
aPDTVertex.position.z = 1.0f - (float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper);
|
||||
aPDTVertex.texCoord.x = 1.0f;
|
||||
aPDTVertex.texCoord.y = (float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper) * 0.5f;
|
||||
rSkyObjectQuad.SetVertex(2, aPDTVertex);
|
||||
aPDTVertex.position.x = c_pv2QuadPoints[1].x;
|
||||
aPDTVertex.position.y = c_pv2QuadPoints[1].y;
|
||||
aPDTVertex.position.z = 1.0f - (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper);
|
||||
aPDTVertex.texCoord.x = 1.0f;
|
||||
aPDTVertex.texCoord.y = (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper) * 0.5f;
|
||||
rSkyObjectQuad.SetVertex(3, aPDTVertex);
|
||||
}
|
||||
for (ucY = 0; ucY < m_ucVirticalGradientLevelLower; ++ucY)
|
||||
{
|
||||
CSkyObjectQuad & rSkyObjectQuad = pSkyObjectQuadVector->at(dwIndex++);
|
||||
|
||||
aPDTVertex.position.x = c_pv2QuadPoints[0].x;
|
||||
aPDTVertex.position.y = c_pv2QuadPoints[0].y;
|
||||
aPDTVertex.position.z = -(float)(ucY + 1) / (float)(m_ucVirticalGradientLevelLower);
|
||||
aPDTVertex.texCoord.x = 0.0f;
|
||||
aPDTVertex.texCoord.y = 0.5f + (float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper) * 0.5f;
|
||||
rSkyObjectQuad.SetVertex(0, aPDTVertex);
|
||||
aPDTVertex.position.x = c_pv2QuadPoints[0].x;
|
||||
aPDTVertex.position.y = c_pv2QuadPoints[0].y;
|
||||
aPDTVertex.position.z = -(float)(ucY) / (float)(m_ucVirticalGradientLevelLower);
|
||||
aPDTVertex.texCoord.x = 0.0f;
|
||||
aPDTVertex.texCoord.y = 0.5f + (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper) * 0.5f;
|
||||
rSkyObjectQuad.SetVertex(1, aPDTVertex);
|
||||
aPDTVertex.position.x = c_pv2QuadPoints[1].x;
|
||||
aPDTVertex.position.y = c_pv2QuadPoints[1].y;
|
||||
aPDTVertex.position.z = -(float)(ucY + 1) / (float)(m_ucVirticalGradientLevelLower);
|
||||
aPDTVertex.texCoord.x = 1.0f;
|
||||
aPDTVertex.texCoord.y = 0.5f + (float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper) * 0.5f;
|
||||
rSkyObjectQuad.SetVertex(2, aPDTVertex);
|
||||
aPDTVertex.position.x = c_pv2QuadPoints[1].x;
|
||||
aPDTVertex.position.y = c_pv2QuadPoints[1].y;
|
||||
aPDTVertex.position.z = -(float)(ucY) / (float)(m_ucVirticalGradientLevelLower);
|
||||
aPDTVertex.texCoord.x = 1.0f;
|
||||
aPDTVertex.texCoord.y = 0.5f + (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper) * 0.5f;
|
||||
rSkyObjectQuad.SetVertex(3, aPDTVertex);
|
||||
}
|
||||
}
|
||||
|
||||
void CSkyBox::SetSkyObjectQuadHorizon(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR3 * c_pv3QuadPoints)
|
||||
{
|
||||
pSkyObjectQuadVector->clear();
|
||||
pSkyObjectQuadVector->resize(1);
|
||||
CSkyObjectQuad & rSkyObjectQuad = pSkyObjectQuadVector->at(0);
|
||||
|
||||
TPDTVertex aPDTVertex{};
|
||||
aPDTVertex.position = c_pv3QuadPoints[0];
|
||||
aPDTVertex.texCoord.x = 0.0f;
|
||||
aPDTVertex.texCoord.y = 1.0f;
|
||||
rSkyObjectQuad.SetVertex(0, aPDTVertex);
|
||||
|
||||
aPDTVertex.position = c_pv3QuadPoints[1];
|
||||
aPDTVertex.texCoord.x = 0.0f;
|
||||
aPDTVertex.texCoord.y = 0.0f;
|
||||
rSkyObjectQuad.SetVertex(1, aPDTVertex);
|
||||
|
||||
aPDTVertex.position = c_pv3QuadPoints[2];
|
||||
aPDTVertex.texCoord.x = 1.0f;
|
||||
aPDTVertex.texCoord.y = 1.0f;
|
||||
rSkyObjectQuad.SetVertex(2, aPDTVertex);
|
||||
|
||||
aPDTVertex.position = c_pv3QuadPoints[3];
|
||||
aPDTVertex.texCoord.x = 1.0f;
|
||||
aPDTVertex.texCoord.y = 0.0f;
|
||||
rSkyObjectQuad.SetVertex(3, aPDTVertex);
|
||||
}
|
||||
|
||||
void CSkyBox::Refresh()
|
||||
{
|
||||
D3DXVECTOR3 v3QuadPoints[4];
|
||||
|
||||
if (m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_DEFAULT || m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_DIFFUSE)
|
||||
{
|
||||
if (m_ucVirticalGradientLevelUpper + m_ucVirticalGradientLevelLower <= 0)
|
||||
return;
|
||||
|
||||
D3DXVECTOR2 v2QuadPoints[2];
|
||||
|
||||
v2QuadPoints[0] = D3DXVECTOR2(1.0f, -1.0f);
|
||||
v2QuadPoints[1] = D3DXVECTOR2(-1.0f, -1.0f);
|
||||
SetSkyObjectQuadVertical(&m_Faces[0].m_SkyObjectQuadVector, v2QuadPoints);
|
||||
m_Faces[0].m_strfacename = "front";
|
||||
|
||||
v2QuadPoints[0] = D3DXVECTOR2(-1.0f, 1.0f);
|
||||
v2QuadPoints[1] = D3DXVECTOR2(1.0f, 1.0f);
|
||||
SetSkyObjectQuadVertical(&m_Faces[1].m_SkyObjectQuadVector, v2QuadPoints);
|
||||
m_Faces[1].m_strfacename = "back";
|
||||
|
||||
v2QuadPoints[0] = D3DXVECTOR2(-1.0f, -1.0f);
|
||||
v2QuadPoints[1] = D3DXVECTOR2(-1.0f, 1.0f);
|
||||
SetSkyObjectQuadVertical(&m_Faces[2].m_SkyObjectQuadVector, v2QuadPoints);
|
||||
m_Faces[2].m_strfacename = "left";
|
||||
|
||||
v2QuadPoints[0] = D3DXVECTOR2(1.0f, 1.0f);
|
||||
v2QuadPoints[1] = D3DXVECTOR2(1.0f, -1.0f);
|
||||
SetSkyObjectQuadVertical(&m_Faces[3].m_SkyObjectQuadVector, v2QuadPoints);
|
||||
m_Faces[3].m_strfacename = "right";
|
||||
|
||||
v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
|
||||
v3QuadPoints[1] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
|
||||
v3QuadPoints[2] = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
|
||||
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
|
||||
SetSkyObjectQuadHorizon(&m_Faces[4].m_SkyObjectQuadVector, v3QuadPoints);
|
||||
m_Faces[4].m_strfacename = "top";
|
||||
|
||||
v3QuadPoints[0] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
|
||||
v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
|
||||
v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
|
||||
v3QuadPoints[3] = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
|
||||
SetSkyObjectQuadHorizon(&m_Faces[5].m_SkyObjectQuadVector, v3QuadPoints);
|
||||
m_Faces[5].m_strfacename = "bottom";
|
||||
}
|
||||
else if (m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_TEXTURE)
|
||||
{
|
||||
v3QuadPoints[0] = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
|
||||
v3QuadPoints[1] = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
|
||||
v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
|
||||
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
|
||||
SetSkyObjectQuadHorizon(&m_Faces[0].m_SkyObjectQuadVector, v3QuadPoints);
|
||||
m_Faces[0].m_strfacename = "front";
|
||||
|
||||
v3QuadPoints[0] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
|
||||
v3QuadPoints[1] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
|
||||
v3QuadPoints[2] = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
|
||||
v3QuadPoints[3] = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
|
||||
SetSkyObjectQuadHorizon(&m_Faces[1].m_SkyObjectQuadVector, v3QuadPoints);
|
||||
m_Faces[1].m_strfacename = "back";
|
||||
|
||||
v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
|
||||
v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
|
||||
v3QuadPoints[2] = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
|
||||
v3QuadPoints[3] = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
|
||||
SetSkyObjectQuadHorizon(&m_Faces[2].m_SkyObjectQuadVector, v3QuadPoints);
|
||||
m_Faces[2].m_strfacename = "left";
|
||||
|
||||
v3QuadPoints[0] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
|
||||
v3QuadPoints[1] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
|
||||
v3QuadPoints[2] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
|
||||
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
|
||||
SetSkyObjectQuadHorizon(&m_Faces[3].m_SkyObjectQuadVector, v3QuadPoints);
|
||||
m_Faces[3].m_strfacename = "right";
|
||||
|
||||
v3QuadPoints[0] = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
|
||||
v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
|
||||
v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
|
||||
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
|
||||
SetSkyObjectQuadHorizon(&m_Faces[4].m_SkyObjectQuadVector, v3QuadPoints);
|
||||
m_Faces[4].m_strfacename = "top";
|
||||
|
||||
v3QuadPoints[0] = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
|
||||
v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
|
||||
v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
|
||||
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
|
||||
SetSkyObjectQuadHorizon(&m_Faces[5].m_SkyObjectQuadVector, v3QuadPoints);
|
||||
m_Faces[5].m_strfacename = "bottom";
|
||||
}
|
||||
|
||||
v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, 0.0f);
|
||||
v3QuadPoints[1] = D3DXVECTOR3(-1.0f, 1.0f, 0.0f);
|
||||
v3QuadPoints[2] = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
|
||||
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);
|
||||
SetSkyObjectQuadHorizon(&m_FaceCloud.m_SkyObjectQuadVector, v3QuadPoints);
|
||||
}
|
||||
|
||||
void CSkyBox::SetCloudColor(const TGradientColor & c_rColor, const TGradientColor & c_rNextColor, const DWORD & dwTransitionTime)
|
||||
{
|
||||
TSkyObjectFace & aFaceCloud = m_FaceCloud;
|
||||
for (DWORD dwk = 0; dwk < aFaceCloud.m_SkyObjectQuadVector.size(); ++dwk)
|
||||
{
|
||||
CSkyObjectQuad & aSkyObjectQuad = aFaceCloud.m_SkyObjectQuadVector[dwk];
|
||||
for (unsigned char v = 0; v < 4; ++v)
|
||||
{
|
||||
aSkyObjectQuad.SetSrcColor(v,
|
||||
c_rColor.m_FirstColor.r,
|
||||
c_rColor.m_FirstColor.g,
|
||||
c_rColor.m_FirstColor.b,
|
||||
c_rColor.m_FirstColor.a);
|
||||
aSkyObjectQuad.SetTransition(v,
|
||||
c_rNextColor.m_FirstColor.r,
|
||||
c_rNextColor.m_FirstColor.g,
|
||||
c_rNextColor.m_FirstColor.b,
|
||||
c_rNextColor.m_FirstColor.a,
|
||||
dwTransitionTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSkyBox::SetSkyColor(const TVectorGradientColor & c_rColorVector, const TVectorGradientColor & c_rNextColorVector, long lTransitionTime)
|
||||
{
|
||||
if (c_rColorVector.empty() || c_rNextColorVector.empty())
|
||||
return;
|
||||
|
||||
unsigned long ulVectorGradientColornum = 0;
|
||||
unsigned long uck;
|
||||
for (unsigned char ucj = 0; ucj < 4; ++ucj)
|
||||
{
|
||||
TSkyObjectFace & aFace = m_Faces[ucj];
|
||||
ulVectorGradientColornum = 0;
|
||||
for (uck = 0; uck < aFace.m_SkyObjectQuadVector.size(); ++uck)
|
||||
{
|
||||
if (ulVectorGradientColornum >= c_rColorVector.size() || ulVectorGradientColornum >= c_rNextColorVector.size())
|
||||
break;
|
||||
CSkyObjectQuad & aSkyObjectQuad = aFace.m_SkyObjectQuadVector[uck];
|
||||
|
||||
aSkyObjectQuad.SetSrcColor(0,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.r,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.g,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.b,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.a);
|
||||
aSkyObjectQuad.SetTransition(0,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.r,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.g,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.b,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.a,
|
||||
lTransitionTime);
|
||||
aSkyObjectQuad.SetSrcColor(1,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.r,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.g,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.b,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.a);
|
||||
aSkyObjectQuad.SetTransition(1,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.r,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.g,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.b,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.a,
|
||||
lTransitionTime);
|
||||
aSkyObjectQuad.SetSrcColor(2,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.r,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.g,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.b,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.a);
|
||||
aSkyObjectQuad.SetTransition(2,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.r,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.g,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.b,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.a,
|
||||
lTransitionTime);
|
||||
aSkyObjectQuad.SetSrcColor(3,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.r,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.g,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.b,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.a);
|
||||
aSkyObjectQuad.SetTransition(3,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.r,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.g,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.b,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.a,
|
||||
lTransitionTime);
|
||||
|
||||
ulVectorGradientColornum++;
|
||||
}
|
||||
}
|
||||
|
||||
TSkyObjectFace & aFaceTop = m_Faces[4];
|
||||
ulVectorGradientColornum = 0;
|
||||
for (uck = 0; uck < aFaceTop.m_SkyObjectQuadVector.size(); ++uck)
|
||||
{
|
||||
CSkyObjectQuad & aSkyObjectQuad = aFaceTop.m_SkyObjectQuadVector[uck];
|
||||
for (unsigned char v = 0; v < 4; ++v)
|
||||
{
|
||||
aSkyObjectQuad.SetSrcColor(v,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.r,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.g,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.b,
|
||||
c_rColorVector[ulVectorGradientColornum].m_FirstColor.a);
|
||||
aSkyObjectQuad.SetTransition(v,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.r,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.g,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.b,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_FirstColor.a,
|
||||
lTransitionTime);
|
||||
}
|
||||
}
|
||||
|
||||
TSkyObjectFace & aFaceBottom = m_Faces[5];
|
||||
ulVectorGradientColornum = c_rColorVector.size() - 1;
|
||||
for (uck = 0; uck < aFaceBottom.m_SkyObjectQuadVector.size(); ++uck)
|
||||
{
|
||||
CSkyObjectQuad & aSkyObjectQuad = aFaceBottom.m_SkyObjectQuadVector[uck];
|
||||
for (unsigned char v = 0; v < 4; ++v)
|
||||
{
|
||||
aSkyObjectQuad.SetSrcColor(v,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.r,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.g,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.b,
|
||||
c_rColorVector[ulVectorGradientColornum].m_SecondColor.a);
|
||||
aSkyObjectQuad.SetTransition(v,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.r,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.g,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.b,
|
||||
c_rNextColorVector[ulVectorGradientColornum].m_SecondColor.a,
|
||||
lTransitionTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSkyBox::StartTransition()
|
||||
{
|
||||
m_bTransitionStarted = true;
|
||||
for (unsigned char ucj = 0; ucj < 6; ++ucj)
|
||||
m_Faces[ucj].StartTransition();
|
||||
m_FaceCloud.StartTransition();
|
||||
}
|
||||
|
||||
void CSkyBox::Update()
|
||||
{
|
||||
CSkyObject::Update();
|
||||
|
||||
if (!m_bTransitionStarted)
|
||||
return;
|
||||
|
||||
bool bResult = false;
|
||||
for (unsigned char uci = 0; uci < 6; ++uci)
|
||||
bResult = m_Faces[uci].Update() || bResult;
|
||||
bResult = m_FaceCloud.Update() || bResult;
|
||||
|
||||
m_bTransitionStarted = bResult;
|
||||
}
|
||||
|
||||
void CSkyBox::Render()
|
||||
{
|
||||
if (!IsNativeTerrainRenderEnabled())
|
||||
return;
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
||||
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorld);
|
||||
|
||||
if (m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_TEXTURE)
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
for (unsigned int i = 0; i < 6; ++i)
|
||||
{
|
||||
CGraphicImageInstance * pFaceImageInstance = m_GraphicImageInstanceMap[m_Faces[i].m_strFaceTextureFileName];
|
||||
if (!pFaceImageInstance)
|
||||
break;
|
||||
|
||||
STATEMANAGER.SetTexture(0, pFaceImageInstance->GetTextureReference().GetD3DTexture());
|
||||
m_Faces[i].Render();
|
||||
}
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV);
|
||||
}
|
||||
else
|
||||
{
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
for (unsigned int i = 0; i < 6; ++i)
|
||||
{
|
||||
m_Faces[i].Render();
|
||||
}
|
||||
}
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_FOGENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2);
|
||||
}
|
||||
|
||||
void CSkyBox::RenderCloud()
|
||||
{
|
||||
if (!IsNativeTerrainRenderEnabled())
|
||||
return;
|
||||
|
||||
CGraphicImageInstance * pCloudGraphicImageInstance = m_GraphicImageInstanceMap[m_FaceCloud.m_strfacename];
|
||||
if (!pCloudGraphicImageInstance || pCloudGraphicImageInstance->IsEmpty() || !pCloudGraphicImageInstance->GetTexturePointer())
|
||||
return;
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
|
||||
m_matTextureCloud._31 = m_fCloudPositionU;
|
||||
m_matTextureCloud._32 = m_fCloudPositionV;
|
||||
|
||||
DWORD dwCurTime = CTimer::Instance().GetCurrentMillisecond();
|
||||
|
||||
m_fCloudPositionU += m_fCloudScrollSpeedU * (float)(dwCurTime - m_dwlastTime) * 0.001f;
|
||||
if (m_fCloudPositionU >= 1.0f)
|
||||
m_fCloudPositionU = 0.0f;
|
||||
|
||||
m_fCloudPositionV += m_fCloudScrollSpeedV * (float)(dwCurTime - m_dwlastTime) * 0.001f;
|
||||
if (m_fCloudPositionV >= 1.0f)
|
||||
m_fCloudPositionV = 0.0f;
|
||||
|
||||
m_dwlastTime = dwCurTime;
|
||||
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &m_matTextureCloud);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATEINVALPHA_ADDCOLOR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
|
||||
D3DXMATRIX matProjCloud;
|
||||
D3DXMatrixPerspectiveFovRH(&matProjCloud, D3DX_PI * 0.25f, 1.33333f, 50.0f, 999999.0f);
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldCloud);
|
||||
STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matProjCloud);
|
||||
STATEMANAGER.SetTexture(0, pCloudGraphicImageInstance->GetTexturePointer()->GetD3DTexture());
|
||||
m_FaceCloud.Render();
|
||||
STATEMANAGER.RestoreTransform(D3DTS_PROJECTION);
|
||||
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_FOGENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// Platform skeleton for EterLib/TextBar.h (40250 EterLib/TextBar.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/TextBar.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CTextBar::CTextBar(int, bool)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CTextBar::~CTextBar()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTextBar::TextOut(int, int, const char *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTextBar::SetTextColor(int, int, int) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTextBar::GetTextExtent(const char *, SIZE *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTextBar::__SetFont(int, bool) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTextBar::OnCreate() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Platform skeleton for EterLib/Thread.h (40250 EterLib/Thread.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/Thread.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CThread::CThread()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CThread::Create(void *) -> int
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
}
|
||||
|
||||
auto CThread::EntryPoint(void *) -> UINT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
}
|
||||
|
||||
auto CThread::Run(void *) -> UINT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "UIRenderCommands.h"
|
||||
#include "RenderCommands3D.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
struct Point { float x, y; };
|
||||
std::vector<Point> clip_polygon(std::vector<Point> polygon, int edge, float bound) {
|
||||
std::vector<Point> result;
|
||||
if (polygon.empty()) return result;
|
||||
auto inside = [edge, bound](Point p) {
|
||||
return edge == 0 ? p.x >= bound : edge == 1 ? p.x <= bound
|
||||
: edge == 2 ? p.y >= bound : p.y <= bound;
|
||||
};
|
||||
auto intersect = [edge, bound](Point a, Point b) {
|
||||
const float t = edge < 2 ? (bound - a.x) / (b.x - a.x)
|
||||
: (bound - a.y) / (b.y - a.y);
|
||||
return Point{a.x + t * (b.x - a.x), a.y + t * (b.y - a.y)};
|
||||
};
|
||||
Point previous = polygon.back();
|
||||
for (Point current : polygon) {
|
||||
const bool was_inside = inside(previous), is_inside = inside(current);
|
||||
if (was_inside != is_inside) result.push_back(intersect(previous, current));
|
||||
if (is_inside) result.push_back(current);
|
||||
previous = current;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
std::vector<UIRenderCommand> commands;
|
||||
std::uint64_t frame_id = 0;
|
||||
int canvas_width = 0;
|
||||
int canvas_height = 0;
|
||||
float clip_x1 = 0, clip_y1 = 0, clip_x2 = 0, clip_y2 = 0;
|
||||
float saved_x1 = 0, saved_y1 = 0, saved_x2 = 0, saved_y2 = 0;
|
||||
float offset_x = 0;
|
||||
}
|
||||
|
||||
void UIRenderSetOffsetX(float x) { offset_x = x; }
|
||||
float UIRenderOffsetX() { return offset_x; }
|
||||
|
||||
void UIRenderSetSize(int width, int height) { canvas_width = width; canvas_height = height; }
|
||||
void UIRenderGetSize(unsigned* width, unsigned* height) {
|
||||
if (width) *width = canvas_width;
|
||||
if (height) *height = canvas_height;
|
||||
}
|
||||
void UIRenderBeginFrame() {
|
||||
++frame_id;
|
||||
commands.clear();
|
||||
clip_x1 = clip_y1 = 0;
|
||||
clip_x2 = canvas_width;
|
||||
clip_y2 = canvas_height;
|
||||
}
|
||||
std::uint64_t UIRenderFrameId() { return frame_id; }
|
||||
void UIRenderAdd(UIRenderCommand command) {
|
||||
if (offset_x != 0) {
|
||||
command.x1 += offset_x;
|
||||
command.x2 += offset_x;
|
||||
if (command.quad)
|
||||
for (float& x : command.qx) x += offset_x;
|
||||
}
|
||||
command.clip_x1 = clip_x1; command.clip_y1 = clip_y1;
|
||||
command.clip_x2 = clip_x2; command.clip_y2 = clip_y2;
|
||||
command.behind_3d = Render3DDraws().empty();
|
||||
if (command.kind == UIRenderCommand::Bar && command.quad) {
|
||||
// Cooldown fans are triangles. Clip their geometry before either renderer consumes it.
|
||||
std::vector<Point> polygon{{command.qx[0], command.qy[0]},
|
||||
{command.qx[1], command.qy[1]},
|
||||
{command.qx[2], command.qy[2]}};
|
||||
const float bounds[4] = {clip_x1, clip_x2, clip_y1, clip_y2};
|
||||
for (int edge = 0; edge < 4; ++edge)
|
||||
polygon = clip_polygon(std::move(polygon), edge, bounds[edge]);
|
||||
for (std::size_t i = 1; i + 1 < polygon.size(); ++i) {
|
||||
UIRenderCommand piece = command;
|
||||
const Point tri[3] = {polygon[0], polygon[i], polygon[i + 1]};
|
||||
const float area = (tri[1].x - tri[0].x) * (tri[2].y - tri[0].y) -
|
||||
(tri[1].y - tri[0].y) * (tri[2].x - tri[0].x);
|
||||
if (area == 0.0f) continue;
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
piece.qx[k] = tri[k < 3 ? k : 2].x;
|
||||
piece.qy[k] = tri[k < 3 ? k : 2].y;
|
||||
}
|
||||
piece.x1 = std::min({tri[0].x, tri[1].x, tri[2].x});
|
||||
piece.y1 = std::min({tri[0].y, tri[1].y, tri[2].y});
|
||||
piece.x2 = std::max({tri[0].x, tri[1].x, tri[2].x});
|
||||
piece.y2 = std::max({tri[0].y, tri[1].y, tri[2].y});
|
||||
commands.push_back(std::move(piece));
|
||||
}
|
||||
return;
|
||||
}
|
||||
commands.push_back(command);
|
||||
}
|
||||
const std::vector<UIRenderCommand>& UIRenderCommands() { return commands; }
|
||||
void UIRenderSetClip(float x, float y, float width, float height) {
|
||||
saved_x1 = clip_x1; saved_y1 = clip_y1; saved_x2 = clip_x2; saved_y2 = clip_y2;
|
||||
clip_x1 = x + offset_x; clip_y1 = y;
|
||||
clip_x2 = x + offset_x + width; clip_y2 = y + height;
|
||||
}
|
||||
void UIRenderRestoreClip() {
|
||||
clip_x1 = saved_x1; clip_y1 = saved_y1;
|
||||
clip_x2 = saved_x2; clip_y2 = saved_y2;
|
||||
}
|
||||
|
||||
void UIRenderAddImage(const CGraphicTexture* texture, const float x[4], const float y[4],
|
||||
float su, float sv, float eu, float ev, std::uint32_t argb, int blend) {
|
||||
// 40250 draws the image quad through the device: the UI pass's world transform places it
|
||||
// (identity except where a caller sets one, e.g. CPythonMiniMap::RenderAtlas's window offset) and a
|
||||
// stage-0 MODULATE with D3DTA_TFACTOR tints it (the atlas's NPC/warp/waypoint marks).
|
||||
D3DXMATRIX world;
|
||||
D3DXMatrixIdentity(&world);
|
||||
if (CStateManager* state = CStateManager::InstancePtr()) {
|
||||
state->GetTransform(D3DTS_WORLD, &world);
|
||||
DWORD op = 0, arg1 = 0, arg2 = 0;
|
||||
state->GetTextureStageState(0, D3DTSS_COLOROP, &op);
|
||||
state->GetTextureStageState(0, D3DTSS_COLORARG1, &arg1);
|
||||
state->GetTextureStageState(0, D3DTSS_COLORARG2, &arg2);
|
||||
if (op == D3DTOP_MODULATE && (arg1 == D3DTA_TFACTOR || arg2 == D3DTA_TFACTOR)) {
|
||||
// TFACTOR x TEXTURE drops the vertex colour; TFACTOR x DIFFUSE scales it. The canvas
|
||||
// multiplies the texture in.
|
||||
const std::uint32_t factor = state->GetRenderState(D3DRS_TEXTUREFACTOR) & 0x00FFFFFFu;
|
||||
const DWORD other = arg1 == D3DTA_TFACTOR ? arg2 : arg1;
|
||||
if (other == D3DTA_DIFFUSE) {
|
||||
std::uint32_t tinted = argb & 0xFF000000u;
|
||||
for (int shift = 0; shift < 24; shift += 8)
|
||||
tinted |= ((((argb >> shift) & 255) * ((factor >> shift) & 255) + 127) / 255) << shift;
|
||||
argb = tinted;
|
||||
} else {
|
||||
argb = (argb & 0xFF000000u) | factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
UIRenderCommand command{UIRenderCommand::Image, 0, 0, 0, 0, argb};
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
command.qx[i] = x[i] * world._11 + y[i] * world._21 + world._41 + 0.5f;
|
||||
command.qy[i] = x[i] * world._12 + y[i] * world._22 + world._42 + 0.5f;
|
||||
}
|
||||
command.x1 = std::min({command.qx[0], command.qx[1], command.qx[2], command.qx[3]});
|
||||
command.y1 = std::min({command.qy[0], command.qy[1], command.qy[2], command.qy[3]});
|
||||
command.x2 = std::max({command.qx[0], command.qx[1], command.qx[2], command.qx[3]});
|
||||
command.y2 = std::max({command.qy[0], command.qy[1], command.qy[2], command.qy[3]});
|
||||
command.text = UIRenderTextureName(texture);
|
||||
command.quad = true;
|
||||
command.su = su; command.sv = sv; command.eu = eu; command.ev = ev;
|
||||
command.blend = blend;
|
||||
UIRenderAdd(std::move(command));
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Commands emitted by the 40250 UI drawing calls, consumed by Godot's CanvasItem.
|
||||
// The port layer stays independent of godot-cpp.
|
||||
struct UIRenderCommand {
|
||||
enum Kind { Bar, Line, Text, Image, GradientBar } kind;
|
||||
float x1, y1, x2, y2;
|
||||
std::uint32_t argb;
|
||||
std::uint32_t end_argb = 0; // GradientBar only: colour on the bottom edge.
|
||||
float clip_x1 = 0, clip_y1 = 0, clip_x2 = 0, clip_y2 = 0;
|
||||
std::string text;
|
||||
// Image only: text is the texture's file, drawn as the quad (vertices 0..3 = TL, TR, BL, BR)
|
||||
// with texture coordinates su,sv..eu,ev; x1..y2 is the quad's bounding box.
|
||||
bool quad = false;
|
||||
float qx[4] = {}, qy[4] = {};
|
||||
float su = 0, sv = 0, eu = 1, ev = 1;
|
||||
int blend = 0; // CGraphicExpandedImageInstance::RENDERING_MODE_*
|
||||
// A second texture stage that modulates the colour and replaces the alpha (40250 CPythonMiniMap's
|
||||
// circular minimap_image_filter): the mask's texture coordinates at the quad's four corners.
|
||||
std::string mask;
|
||||
float mu[4] = {}, mv[4] = {};
|
||||
bool behind_3d = false;
|
||||
};
|
||||
|
||||
// D3DXCOLOR (0..1 floats) -> the 0xAARRGGBB the commands carry.
|
||||
template <class Color>
|
||||
std::uint32_t UIRenderColor(const Color& color) {
|
||||
auto channel = [](float value) -> std::uint32_t {
|
||||
return static_cast<std::uint32_t>((value < 0 ? 0 : value > 1 ? 1 : value) * 255.0f + 0.5f);
|
||||
};
|
||||
return (channel(color.a) << 24) | (channel(color.r) << 16) | (channel(color.g) << 8) | channel(color.b);
|
||||
}
|
||||
|
||||
class CGraphicTexture;
|
||||
// A file-backed texture is named by its pack path; a memory texture (CGraphicImageTexture::Create,
|
||||
// filled through Lock/Unlock: the CGraphicFontTexture glyph pages) by "mem:<id>@<revision>", the
|
||||
// revision counting Unlocks so the canvas knows when to fetch the pixels again.
|
||||
std::string UIRenderTextureName(const CGraphicTexture* texture);
|
||||
|
||||
// The pixels of memory texture "mem:<id>" (the part of the name before '@'), as 0xAARRGGBB.
|
||||
struct UIMemoryTexture {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
std::uint32_t revision = 0;
|
||||
std::vector<std::uint32_t> argb;
|
||||
};
|
||||
bool UIRenderMemoryTexture(const std::string& name, UIMemoryTexture* out);
|
||||
struct IDirect3DTexture8;
|
||||
struct IDirect3DBaseTexture8;
|
||||
// Frees the platform texture behind a CGraphicTexture: a memory texture or a file texture's handle.
|
||||
void UIRenderReleaseMemoryTexture(IDirect3DTexture8* texture);
|
||||
// The name (as UIRenderTextureName) of the texture a D3D handle belongs to; "" for null or unknown.
|
||||
std::string UIRenderTextureNameFromHandle(const IDirect3DBaseTexture8* handle);
|
||||
std::string MtCpuTextureNameFromHandle(const IDirect3DBaseTexture8* handle);
|
||||
bool MtCpuMemoryTexture(const std::string& name, UIMemoryTexture* out);
|
||||
|
||||
// A textured quad from 40250's TPDTVertex[4] (TL, TR, BL, BR) positions and texture coordinates.
|
||||
// PORT: D3D8 puts pixel centres on integers, which is why 40250 subtracts 0.5 from every vertex; the
|
||||
// Godot canvas puts them on .5, so the quad is shifted back by +0.5 here.
|
||||
void UIRenderAddImage(const CGraphicTexture* texture, const float x[4], const float y[4],
|
||||
float su, float sv, float eu, float ev, std::uint32_t argb, int blend = 0);
|
||||
|
||||
void UIRenderSetSize(int width, int height);
|
||||
void UIRenderGetSize(unsigned* width, unsigned* height);
|
||||
void UIRenderBeginFrame();
|
||||
std::uint64_t UIRenderFrameId();
|
||||
void UIRenderAdd(UIRenderCommand command);
|
||||
const std::vector<UIRenderCommand>& UIRenderCommands();
|
||||
void UIRenderSetClip(float x, float y, float width, float height);
|
||||
// PORT (mobile safe area): shifts the commands (and clips) recorded after it right by x canvas
|
||||
// pixels, so the 40250 window layers can sit inside the rounded screen corners while the GAME layer
|
||||
// (3D world, text tails) keeps the full canvas. 0 is the verbatim 40250 path.
|
||||
void UIRenderSetOffsetX(float x);
|
||||
float UIRenderOffsetX();
|
||||
void UIRenderRestoreClip();
|
||||
|
||||
// HiDPI text: CGraphicFontTexture rasterises its glyph pages at this multiple of the logical font
|
||||
// size (the swapchain's pixels per UI pixel) while keeping the 40250 glyph metrics and page UVs in
|
||||
// logical pixels. 1 (the default) is the verbatim 40250 path. Latched when the first font page is
|
||||
// created, so set it before the game creates fonts.
|
||||
void UISetFontOversample(int scale);
|
||||
int UIFontOversample();
|
||||
@@ -0,0 +1,109 @@
|
||||
// 40250 EterLib/Util.cpp:140-297, the default code page and font face.
|
||||
//
|
||||
// The rest of Util.cpp (LoadTextData / base64 / TokenTo*) is logic and not here. The 9x face table has
|
||||
// CP949/Shift-JIS/GBK/Big5 literals, so this block is copied by hand instead of port_copy.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/Util.h"
|
||||
#include "EterLocale/CodePageId.h"
|
||||
|
||||
static std::string gs_fontFace="";
|
||||
static DWORD gs_codePage=0;
|
||||
|
||||
int GetCharsetFromCodePage(WORD codePage)
|
||||
{
|
||||
switch( codePage )
|
||||
{
|
||||
case CP_932:
|
||||
return SHIFTJIS_CHARSET;
|
||||
case CP_949:
|
||||
return HANGUL_CHARSET;
|
||||
case CP_936:
|
||||
return GB2312_CHARSET;
|
||||
case CP_950:
|
||||
return CHINESEBIG5_CHARSET;
|
||||
case CP_1253:
|
||||
return GREEK_CHARSET;
|
||||
case CP_1254:
|
||||
return TURKISH_CHARSET;
|
||||
case CP_1255:
|
||||
return HEBREW_CHARSET;
|
||||
case CP_1256:
|
||||
return ARABIC_CHARSET;
|
||||
case CP_1257:
|
||||
return BALTIC_CHARSET;
|
||||
case CP_1258:
|
||||
return VIETNAMESE_CHARSET;
|
||||
case CP_874:
|
||||
return THAI_CHARSET;
|
||||
case CP_1250:
|
||||
return EASTEUROPE_CHARSET;
|
||||
case CP_1251:
|
||||
return RUSSIAN_CHARSET;
|
||||
default:
|
||||
return DEFAULT_CHARSET;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char* GetFontFaceFromCodePageNT(WORD codePage)
|
||||
{
|
||||
switch( codePage )
|
||||
{
|
||||
case CP_932:
|
||||
return "MS PGothic";
|
||||
case CP_949:
|
||||
return "GulimChe";
|
||||
case CP_936:
|
||||
return "SimSun";
|
||||
case CP_950:
|
||||
return "MingLiU";
|
||||
case CP_874:
|
||||
return "Tahoma";
|
||||
case CP_1252:
|
||||
return "Arial";
|
||||
case CP_1256:
|
||||
return "Tahoma";
|
||||
case CP_1258:
|
||||
return "Tahoma";
|
||||
case CP_65001:
|
||||
return "Arial";
|
||||
default:
|
||||
return "Arial";
|
||||
}
|
||||
}
|
||||
|
||||
DWORD GetDefaultCodePage()
|
||||
{
|
||||
return gs_codePage;
|
||||
}
|
||||
|
||||
const char * GetDefaultFontFace()
|
||||
{
|
||||
return gs_fontFace.c_str();
|
||||
}
|
||||
|
||||
// PORT: 40250 asks EnumFontFamiliesEx for the 9x (native-script) face name, then the NT one. The native
|
||||
// names never match a font file here; CreateFontIndirect (platform/Win32Gdi.cpp) substitutes a missing
|
||||
// face, so the NT name is the answer.
|
||||
const char* GetFontFaceFromCodePage(WORD codePage)
|
||||
{
|
||||
return GetFontFaceFromCodePageNT(codePage);
|
||||
}
|
||||
|
||||
void SetDefaultFontFace(const char* fontFace)
|
||||
{
|
||||
gs_fontFace=fontFace;
|
||||
}
|
||||
|
||||
bool SetDefaultCodePage(DWORD codePage)
|
||||
{
|
||||
gs_codePage=codePage;
|
||||
|
||||
std::string fontFace=GetFontFaceFromCodePage(codePage);
|
||||
if (fontFace.empty())
|
||||
return false;
|
||||
|
||||
SetDefaultFontFace(fontFace.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user