port: CMapOutdoor + PythonBackground + minimap (1:1 40250)
GameLib map/area/terrain units, PRTerrainLib Terrain/TextureSet, PythonBackground(+Module) and ColorTransitionHelper ported verbatim; pending stand-ins and background module stubs removed. Hand edits: BeginEnvironment's pointer tag via uintptr_t, LoadWaterMap reads the file's 32-bit longs. Terrain draw passes stay platform no-ops (Godot draws the terrain). RecordingDevice gains textures, buffers and render targets; orthographic draws become UI commands so CPythonMiniMap's masked tiles show through minimap_image_filter in python_ui_surface. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b69116992c
commit
2ead95756e
@@ -0,0 +1,107 @@
|
||||
// Platform implementation of EterBase/FileDir.h (40250 EterBase/FileDir.cpp): the 40250 code as is, over the
|
||||
// FindFirstFile/FindNextFile/FindClose of common/Win32Crt.h.
|
||||
#include "EterBase/StdAfx.h"
|
||||
#include "EterBase/FileDir.h"
|
||||
#include <string>
|
||||
|
||||
CDir::CDir()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CDir::~CDir()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CDir::Destroy()
|
||||
{
|
||||
if (m_hFind)
|
||||
FindClose(m_hFind);
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
bool CDir::Create(const char * c_szFilter, const char* c_szPath, BOOL bCheckedExtension)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
std::string stPath = c_szPath;
|
||||
|
||||
if (stPath.length())
|
||||
{
|
||||
char end = stPath[stPath.length() - 1];
|
||||
|
||||
if (end != '\\')
|
||||
stPath+='\\';
|
||||
}
|
||||
|
||||
std::string stQuery;
|
||||
stQuery += stPath;
|
||||
stQuery += "*.*";
|
||||
|
||||
m_wfd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
m_hFind = FindFirstFile(stQuery.c_str(), &m_wfd);
|
||||
|
||||
if (m_hFind == INVALID_HANDLE_VALUE)
|
||||
return true;
|
||||
|
||||
do
|
||||
{
|
||||
if (*m_wfd.cFileName == '.')
|
||||
continue;
|
||||
|
||||
if (IsFolder())
|
||||
{
|
||||
if (!OnFolder(c_szFilter, stPath.c_str(), m_wfd.cFileName))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char * c_szExtension = strchr(m_wfd.cFileName, '.');
|
||||
if (!c_szExtension)
|
||||
continue;
|
||||
|
||||
// NOTE : 임시 변수 - [levites]
|
||||
// 최종적으로는 무조건 TRUE 형태로 만든다.
|
||||
// 그전에 전 프로젝트의 CDir을 사용하는 곳에서 Extension을 "wav", "gr2" 이런식으로 넣게끔 한다. - [levites]
|
||||
if (bCheckedExtension)
|
||||
{
|
||||
std::string strFilter = c_szFilter;
|
||||
int iPos = strFilter.find_first_of(';', 0);
|
||||
if (iPos > 0)
|
||||
{
|
||||
std::string strFirstFilter = std::string(c_szFilter).substr(0, iPos);
|
||||
std::string strSecondFilter = std::string(c_szFilter).substr(iPos+1, strlen(c_szFilter));
|
||||
if (0 != strFirstFilter.compare(c_szExtension+1) && 0 != strSecondFilter.compare(c_szExtension+1))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != stricmp(c_szExtension+1, c_szFilter))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!OnFile(stPath.c_str(), m_wfd.cFileName))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while (FindNextFile(m_hFind, &m_wfd));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDir::IsFolder()
|
||||
{
|
||||
if (m_wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDir::Initialize()
|
||||
{
|
||||
memset(&m_wfd, 0, sizeof(m_wfd));
|
||||
m_hFind = NULL;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Platform implementation of EterBase/TempFile.h (40250 EterBase/TempFile.cpp): the 40250 code as is; the file
|
||||
// name comes from the platform CreateTempFileName and DeleteFile is the common/Win32Crt.h shim.
|
||||
#include "EterBase/StdAfx.h"
|
||||
#include "EterBase/TempFile.h"
|
||||
#include "EterBase/Utils.h"
|
||||
#include "EterBase/Debug.h"
|
||||
|
||||
CTempFile::~CTempFile()
|
||||
{
|
||||
Destroy();
|
||||
DeleteFile(m_szFileName);
|
||||
}
|
||||
|
||||
CTempFile::CTempFile(const char * c_pszPrefix)
|
||||
{
|
||||
strncpy(m_szFileName, CreateTempFileName(c_pszPrefix), MAX_PATH);
|
||||
|
||||
if (!Create(m_szFileName, CFileBase::FILEMODE_WRITE))
|
||||
{
|
||||
TraceError("CTempFile::CTempFile cannot create temporary file. (filename: %s)", m_szFileName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "UIRenderCommands.h"
|
||||
#include "CpuBuffer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
|
||||
@@ -52,6 +54,148 @@ void copy_color(float out[4], const D3DCOLORVALUE& c)
|
||||
out[0] = c.r; out[1] = c.g; out[2] = c.b; out[3] = c.a;
|
||||
}
|
||||
|
||||
int format_bytes(D3DFORMAT format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case D3DFMT_A4R4G4B4: case D3DFMT_R5G6B5: case D3DFMT_A1R5G5B5: case D3DFMT_X1R5G5B5: case D3DFMT_X4R4G4B4:
|
||||
case D3DFMT_D16: case D3DFMT_D16_LOCKABLE:
|
||||
return 2;
|
||||
case D3DFMT_A8: case D3DFMT_L8:
|
||||
return 1;
|
||||
default:
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
// PORT: device-created resources live in CPU memory with D3D reference counting. Textures made by
|
||||
// CreateTexture (CTerrain's splat alpha maps and attribute marks, CSnowEnvironment's blur targets)
|
||||
// keep their mip levels as bytes; nothing samples them because terrain and offscreen passes are
|
||||
// drawn by the Godot side.
|
||||
struct CpuTexture;
|
||||
|
||||
struct CpuSurface final : IDirect3DSurface8
|
||||
{
|
||||
ULONG refs = 1;
|
||||
CpuTexture* parent = nullptr; // a texture level, or null for a standalone surface
|
||||
UINT level = 0;
|
||||
D3DSURFACE_DESC desc = {};
|
||||
std::vector<uint8_t> bytes; // standalone surfaces only
|
||||
|
||||
ULONG AddRef() override { return ++refs; }
|
||||
ULONG Release() override;
|
||||
HRESULT GetDesc(D3DSURFACE_DESC* out) override { *out = desc; return S_OK; }
|
||||
HRESULT LockRect(D3DLOCKED_RECT* locked, const RECT*, DWORD) override;
|
||||
HRESULT UnlockRect() override { return S_OK; }
|
||||
};
|
||||
|
||||
struct CpuTexture final : IDirect3DTexture8
|
||||
{
|
||||
struct Level { D3DSURFACE_DESC desc; std::vector<uint8_t> bytes; };
|
||||
|
||||
ULONG refs = 1;
|
||||
std::vector<Level> levels;
|
||||
|
||||
ULONG AddRef() override { return ++refs; }
|
||||
ULONG Release() override
|
||||
{
|
||||
const ULONG left = --refs;
|
||||
if (!left)
|
||||
delete this;
|
||||
return left;
|
||||
}
|
||||
DWORD GetLevelCount() override { return DWORD(levels.size()); }
|
||||
HRESULT GetLevelDesc(UINT level, D3DSURFACE_DESC* out) override
|
||||
{
|
||||
if (level >= levels.size())
|
||||
return E_FAIL;
|
||||
*out = levels[level].desc;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT GetSurfaceLevel(UINT level, IDirect3DSurface8** out) override
|
||||
{
|
||||
if (level >= levels.size())
|
||||
return E_FAIL;
|
||||
auto* surface = new CpuSurface();
|
||||
surface->parent = this;
|
||||
surface->level = level;
|
||||
surface->desc = levels[level].desc;
|
||||
AddRef();
|
||||
*out = surface;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT LockRect(UINT level, D3DLOCKED_RECT* locked, const RECT*, DWORD) override
|
||||
{
|
||||
if (level >= levels.size())
|
||||
return E_FAIL;
|
||||
locked->Pitch = INT(levels[level].desc.Width * format_bytes(levels[level].desc.Format));
|
||||
locked->pBits = levels[level].bytes.data();
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT UnlockRect(UINT level) override { return level < levels.size() ? S_OK : E_FAIL; }
|
||||
};
|
||||
|
||||
ULONG CpuSurface::Release()
|
||||
{
|
||||
const ULONG left = --refs;
|
||||
if (!left)
|
||||
{
|
||||
if (parent)
|
||||
parent->Release();
|
||||
delete this;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
HRESULT CpuSurface::LockRect(D3DLOCKED_RECT* locked, const RECT* rect, DWORD flags)
|
||||
{
|
||||
if (parent)
|
||||
return parent->LockRect(level, locked, rect, flags);
|
||||
locked->Pitch = INT(desc.Width * format_bytes(desc.Format));
|
||||
locked->pBits = bytes.data();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
D3DSURFACE_DESC surface_desc(UINT width, UINT height, D3DFORMAT format, DWORD usage, D3DPOOL pool)
|
||||
{
|
||||
D3DSURFACE_DESC desc = {};
|
||||
desc.Format = format;
|
||||
desc.Type = D3DRTYPE_SURFACE;
|
||||
desc.Usage = usage;
|
||||
desc.Pool = pool;
|
||||
desc.Size = width * height * format_bytes(format);
|
||||
desc.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
return desc;
|
||||
}
|
||||
|
||||
struct DeviceVertexBuffer final : MtCpuVertexBuffer
|
||||
{
|
||||
ULONG refs = 1;
|
||||
ULONG AddRef() override { return ++refs; }
|
||||
ULONG Release() override
|
||||
{
|
||||
const ULONG left = --refs;
|
||||
if (!left)
|
||||
delete this;
|
||||
return left;
|
||||
}
|
||||
};
|
||||
|
||||
struct DeviceIndexBuffer final : MtCpuIndexBuffer
|
||||
{
|
||||
ULONG refs = 1;
|
||||
ULONG AddRef() override { return ++refs; }
|
||||
ULONG Release() override
|
||||
{
|
||||
const ULONG left = --refs;
|
||||
if (!left)
|
||||
delete this;
|
||||
return left;
|
||||
}
|
||||
};
|
||||
|
||||
class RecordingDevice final : public IDirect3DDevice8
|
||||
{
|
||||
public:
|
||||
@@ -63,6 +207,23 @@ public:
|
||||
std::memset(&m_material, 0, sizeof(m_material));
|
||||
m_material.Diffuse = { 1, 1, 1, 1 };
|
||||
std::memset(m_lights, 0, sizeof(m_lights));
|
||||
auto* backBuffer = new CpuSurface();
|
||||
backBuffer->desc = surface_desc(width, height, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT);
|
||||
m_backBuffer = backBuffer;
|
||||
auto* depthBuffer = new CpuSurface();
|
||||
depthBuffer->desc = surface_desc(width, height, D3DFMT_D16, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT);
|
||||
m_depthBuffer = depthBuffer;
|
||||
m_renderTarget = m_backBuffer;
|
||||
m_renderTarget->AddRef();
|
||||
m_depthStencil = m_depthBuffer;
|
||||
m_depthStencil->AddRef();
|
||||
}
|
||||
~RecordingDevice() override
|
||||
{
|
||||
m_renderTarget->Release();
|
||||
m_depthStencil->Release();
|
||||
m_backBuffer->Release();
|
||||
m_depthBuffer->Release();
|
||||
}
|
||||
|
||||
ULONG AddRef() override { return ++m_refs; }
|
||||
@@ -120,6 +281,84 @@ public:
|
||||
m_lights[index] = *light;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT LightEnable(DWORD index, BOOL enable) override
|
||||
{
|
||||
if (index < 8)
|
||||
m_lightEnabled[index] = enable != FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CreateTexture(UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DTexture8** out) override
|
||||
{
|
||||
if (!width || !height)
|
||||
return E_FAIL;
|
||||
auto* texture = new CpuTexture();
|
||||
// Levels == 0 builds the full chain down to 1x1.
|
||||
for (UINT w = width, h = height; ; w = std::max(1u, w / 2), h = std::max(1u, h / 2))
|
||||
{
|
||||
CpuTexture::Level level;
|
||||
level.desc = surface_desc(w, h, format, usage, pool);
|
||||
level.bytes.resize(level.desc.Size);
|
||||
texture->levels.push_back(std::move(level));
|
||||
if ((levels && texture->levels.size() == levels) || (w == 1 && h == 1))
|
||||
break;
|
||||
}
|
||||
*out = texture;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CreateVertexBuffer(UINT length, DWORD, DWORD fvf, D3DPOOL, IDirect3DVertexBuffer8** out) override
|
||||
{
|
||||
auto* buffer = new DeviceVertexBuffer();
|
||||
buffer->bytes.resize(length);
|
||||
buffer->fvf = fvf;
|
||||
*out = buffer;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CreateIndexBuffer(UINT length, DWORD, D3DFORMAT format, D3DPOOL, IDirect3DIndexBuffer8** out) override
|
||||
{
|
||||
auto* buffer = new DeviceIndexBuffer();
|
||||
buffer->bytes.resize(length);
|
||||
buffer->format = format;
|
||||
*out = buffer;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CreateDepthStencilSurface(UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE, IDirect3DSurface8** out) override
|
||||
{
|
||||
auto* surface = new CpuSurface();
|
||||
surface->desc = surface_desc(width, height, format, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT);
|
||||
*out = surface;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT GetRenderTarget(IDirect3DSurface8** out) override
|
||||
{
|
||||
m_renderTarget->AddRef();
|
||||
*out = m_renderTarget;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT GetDepthStencilSurface(IDirect3DSurface8** out) override
|
||||
{
|
||||
m_depthStencil->AddRef();
|
||||
*out = m_depthStencil;
|
||||
return S_OK;
|
||||
}
|
||||
// PORT: an offscreen target (CSnowEnvironment's blur pass) swallows its draws; only the back
|
||||
// buffer's draws are recorded for the Godot renderer.
|
||||
HRESULT SetRenderTarget(IDirect3DSurface8* target, IDirect3DSurface8* depth) override
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
target->AddRef();
|
||||
m_renderTarget->Release();
|
||||
m_renderTarget = target;
|
||||
}
|
||||
if (depth)
|
||||
{
|
||||
depth->AddRef();
|
||||
m_depthStencil->Release();
|
||||
m_depthStencil = depth;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT Clear(DWORD, const D3DRECT*, DWORD, D3DCOLOR, float, DWORD) override { return S_OK; }
|
||||
HRESULT SetRenderState(D3DRENDERSTATETYPE state, DWORD value) override
|
||||
{
|
||||
if (unsigned(state) < kRenderStates)
|
||||
@@ -237,10 +476,118 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
static void transform_point(const float v[4], const float m[16], float out[4])
|
||||
{
|
||||
for (int c = 0; c < 4; ++c)
|
||||
out[c] = v[0] * m[c] + v[1] * m[4 + c] + v[2] * m[8 + c] + v[3] * m[12 + c];
|
||||
}
|
||||
|
||||
static void multiply(const float a[16], const float b[16], float out[16])
|
||||
{
|
||||
for (int r = 0; r < 4; ++r)
|
||||
transform_point(&a[r * 4], b, &out[r * 4]);
|
||||
}
|
||||
|
||||
// Each two-triangle quad of a UI-space draw becomes an image command: its screen corners through
|
||||
// world * view * projection, its stage-0 texture (or D3DTA_TFACTOR colour when stage 0 selects it)
|
||||
// and, when stage 1 generates coordinates from the camera-space position through D3DTS_TEXTURE1
|
||||
// (the minimap's circular filter), the mask's coordinates at the corners.
|
||||
void record_ui_quads(D3DPRIMITIVETYPE type, const uint8_t* vertices, size_t vertexBytes, UINT stride,
|
||||
const VertexLayout& layout, const std::vector<std::uint32_t>& indices)
|
||||
{
|
||||
if (layout.uv0 < 0)
|
||||
return;
|
||||
unsigned width = 0, height = 0;
|
||||
UIRenderGetSize(&width, &height);
|
||||
float worldView[16], worldViewProj[16];
|
||||
multiply(m_transforms[256], m_transforms[D3DTS_VIEW], worldView);
|
||||
multiply(worldView, m_transforms[D3DTS_PROJECTION], worldViewProj);
|
||||
|
||||
const DWORD* stage0 = m_stageStates[0];
|
||||
const DWORD* stage1 = m_stageStates[1];
|
||||
const bool factorColor = stage0[D3DTSS_COLOROP] == D3DTOP_SELECTARG1 && stage0[D3DTSS_COLORARG1] == D3DTA_TFACTOR;
|
||||
const std::uint32_t argb = factorColor ? (0xFF000000u | (m_renderStates[D3DRS_TEXTUREFACTOR] & 0x00FFFFFFu)) : 0xFFFFFFFFu;
|
||||
const bool masked = m_textures[1] && (stage1[D3DTSS_TEXCOORDINDEX] & 0xFFFF0000u) == D3DTSS_TCI_CAMERASPACEPOSITION &&
|
||||
stage1[D3DTSS_TEXTURETRANSFORMFLAGS] == D3DTTFF_COUNT2 && stage1[D3DTSS_COLOROP] == D3DTOP_MODULATE &&
|
||||
stage1[D3DTSS_ALPHAOP] == D3DTOP_SELECTARG1 && stage1[D3DTSS_ALPHAARG1] == D3DTA_TEXTURE;
|
||||
const std::string texture = factorColor ? std::string() : UIRenderTextureNameFromHandle(m_textures[0]);
|
||||
const std::string mask = masked ? UIRenderTextureNameFromHandle(m_textures[1]) : std::string();
|
||||
|
||||
std::vector<std::vector<std::uint32_t>> quads;
|
||||
if (type == D3DPT_TRIANGLELIST)
|
||||
for (size_t i = 0; i + 6 <= indices.size(); i += 6)
|
||||
quads.push_back({ indices.begin() + i, indices.begin() + i + 6 });
|
||||
else if (type == D3DPT_TRIANGLESTRIP && indices.size() == 4)
|
||||
quads.push_back(indices);
|
||||
|
||||
for (const auto& quad : quads)
|
||||
{
|
||||
std::vector<std::uint32_t> corners;
|
||||
for (std::uint32_t index : quad)
|
||||
if (std::find(corners.begin(), corners.end(), index) == corners.end())
|
||||
corners.push_back(index);
|
||||
if (corners.size() != 4)
|
||||
continue;
|
||||
float sx[4], sy[4], u[4], v[4], mu[4] = {}, mv[4] = {};
|
||||
bool inside = true;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
const size_t offset = size_t(corners[i]) * stride;
|
||||
if (offset + stride > vertexBytes) { inside = false; break; }
|
||||
const uint8_t* vertex = vertices + offset;
|
||||
float position[4] = { 0, 0, 0, 1 }, clip[4], camera[4], coord[4];
|
||||
std::memcpy(position, vertex, 12);
|
||||
std::memcpy(&u[i], vertex + layout.uv0, 4);
|
||||
std::memcpy(&v[i], vertex + layout.uv0 + 4, 4);
|
||||
transform_point(position, worldViewProj, clip);
|
||||
if (clip[3] == 0.0f) { inside = false; break; }
|
||||
sx[i] = (clip[0] / clip[3] * 0.5f + 0.5f) * float(width);
|
||||
sy[i] = (0.5f - clip[1] / clip[3] * 0.5f) * float(height);
|
||||
if (masked)
|
||||
{
|
||||
transform_point(position, worldView, camera);
|
||||
camera[3] = 1.0f;
|
||||
transform_point(camera, m_transforms[D3DTS_TEXTURE1], coord);
|
||||
mu[i] = coord[0];
|
||||
mv[i] = coord[1];
|
||||
}
|
||||
}
|
||||
if (!inside)
|
||||
continue;
|
||||
|
||||
UIRenderCommand command{UIRenderCommand::Image, 0, 0, 0, 0, argb};
|
||||
command.su = *std::min_element(u, u + 4); command.eu = *std::max_element(u, u + 4);
|
||||
command.sv = *std::min_element(v, v + 4); command.ev = *std::max_element(v, v + 4);
|
||||
// Corners in the command's TL, TR, BL, BR order, by texture coordinate.
|
||||
const float cu[4] = { command.su, command.eu, command.su, command.eu };
|
||||
const float cv[4] = { command.sv, command.sv, command.ev, command.ev };
|
||||
for (int c = 0; c < 4; ++c)
|
||||
{
|
||||
int best = 0;
|
||||
float bestDistance = INFINITY;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
const float distance = std::fabs(u[i] - cu[c]) + std::fabs(v[i] - cv[c]);
|
||||
if (distance < bestDistance) { bestDistance = distance; best = i; }
|
||||
}
|
||||
command.qx[c] = sx[best]; command.qy[c] = sy[best];
|
||||
command.mu[c] = mu[best]; command.mv[c] = mv[best];
|
||||
}
|
||||
command.x1 = *std::min_element(command.qx, command.qx + 4);
|
||||
command.y1 = *std::min_element(command.qy, command.qy + 4);
|
||||
command.x2 = *std::max_element(command.qx, command.qx + 4);
|
||||
command.y2 = *std::max_element(command.qy, command.qy + 4);
|
||||
command.text = texture;
|
||||
command.quad = true;
|
||||
command.mask = mask;
|
||||
UIRenderAdd(std::move(command));
|
||||
}
|
||||
}
|
||||
|
||||
void record(D3DPRIMITIVETYPE type, UINT primitives, const uint8_t* vertices, size_t vertexBytes, UINT stride,
|
||||
const std::vector<std::uint32_t>& indices)
|
||||
{
|
||||
if (type == D3DPT_POINTLIST || indices.empty() || !vertices)
|
||||
if (type == D3DPT_POINTLIST || indices.empty() || !vertices || m_renderTarget != m_backBuffer)
|
||||
return;
|
||||
VertexLayout layout = fvf_layout(m_fvf);
|
||||
if (!stride)
|
||||
@@ -253,6 +600,14 @@ private:
|
||||
if (layout.uv0 + 8 > int(stride)) layout.uv0 = -1;
|
||||
if (layout.uv1 + 8 > int(stride)) layout.uv1 = -1;
|
||||
|
||||
// An orthographic projection over untransformed vertices is a UI-space draw (CPythonMiniMap's
|
||||
// terrain tiles under CPythonGraphic::SetOrtho2D): it joins the UI command stream in order.
|
||||
if (!layout.rhw && m_transforms[D3DTS_PROJECTION][11] == 0.0f)
|
||||
{
|
||||
record_ui_quads(type, vertices, vertexBytes, stride, layout, indices);
|
||||
return;
|
||||
}
|
||||
|
||||
Render3DDraw draw;
|
||||
std::memcpy(draw.world, m_transforms[256], sizeof(draw.world)); // D3DTS_WORLD
|
||||
std::memcpy(draw.view, m_transforms[D3DTS_VIEW], sizeof(draw.view));
|
||||
@@ -340,7 +695,7 @@ private:
|
||||
copy_color(draw.material_diffuse, m_material.Diffuse);
|
||||
copy_color(draw.material_ambient, m_material.Ambient);
|
||||
copy_color(draw.material_emissive, m_material.Emissive);
|
||||
if (m_lights[0].Type == D3DLIGHT_DIRECTIONAL)
|
||||
if (m_lightEnabled[0] && m_lights[0].Type == D3DLIGHT_DIRECTIONAL)
|
||||
{
|
||||
draw.light0 = true;
|
||||
draw.light0_direction[0] = m_lights[0].Direction.x;
|
||||
@@ -360,6 +715,11 @@ private:
|
||||
IDirect3DBaseTexture8* m_textures[kStages] = {};
|
||||
D3DMATERIAL8 m_material;
|
||||
D3DLIGHT8 m_lights[8];
|
||||
bool m_lightEnabled[8] = {};
|
||||
IDirect3DSurface8* m_backBuffer = nullptr;
|
||||
IDirect3DSurface8* m_depthBuffer = nullptr;
|
||||
IDirect3DSurface8* m_renderTarget = nullptr;
|
||||
IDirect3DSurface8* m_depthStencil = nullptr;
|
||||
DWORD m_fvf = 0;
|
||||
MtCpuVertexBuffer* m_stream = nullptr;
|
||||
UINT m_streamStride = 0;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "UIRenderCommands.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -39,10 +41,36 @@ void UIRenderRestoreClip() {
|
||||
|
||||
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] + 0.5f;
|
||||
command.qy[i] = y[i] + 0.5f;
|
||||
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]});
|
||||
|
||||
@@ -18,6 +18,10 @@ struct UIRenderCommand {
|
||||
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] = {};
|
||||
};
|
||||
|
||||
// D3DXCOLOR (0..1 floats) -> the 0xAARRGGBB the commands carry.
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
// Platform implementation of 40250 GameLib/MapOutdoorCharacterShadow.cpp. The render-target lifecycle is
|
||||
// the 40250 code as is; the shadow-map pass is not run (BeginRenderCharacterShadowToTexture reports it
|
||||
// cannot render) because the terrain that samples the map is drawn by Godot, which casts its own
|
||||
// character shadows (PORT-PLAN §3).
|
||||
#include "GameLib/StdAfx.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
#include "EterLib/Camera.h"
|
||||
|
||||
#include "GameLib/MapOutdoor.h"
|
||||
|
||||
static int recreate = false;
|
||||
|
||||
void CMapOutdoor::SetShadowTextureSize(WORD size)
|
||||
{
|
||||
if (m_wShadowMapSize != size)
|
||||
{
|
||||
recreate = true;
|
||||
Tracenf("ShadowTextureSize changed %d -> %d", m_wShadowMapSize, size);
|
||||
}
|
||||
|
||||
m_wShadowMapSize = size;
|
||||
}
|
||||
|
||||
void CMapOutdoor::CreateCharacterShadowTexture()
|
||||
{
|
||||
extern bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW;
|
||||
|
||||
if (GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW)
|
||||
return;
|
||||
|
||||
ReleaseCharacterShadowTexture();
|
||||
|
||||
if (IsLowTextureMemory())
|
||||
SetShadowTextureSize(128);
|
||||
|
||||
m_ShadowMapViewport.X = 1;
|
||||
m_ShadowMapViewport.Y = 1;
|
||||
m_ShadowMapViewport.Width = m_wShadowMapSize - 2;
|
||||
m_ShadowMapViewport.Height = m_wShadowMapSize - 2;
|
||||
m_ShadowMapViewport.MinZ = 0.0f;
|
||||
m_ShadowMapViewport.MaxZ = 1.0f;
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateTexture(m_wShadowMapSize, m_wShadowMapSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &m_lpCharacterShadowMapTexture)))
|
||||
{
|
||||
TraceError("CMapOutdoor Unable to create Character Shadow render target texture\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(m_lpCharacterShadowMapTexture->GetSurfaceLevel(0, &m_lpCharacterShadowMapRenderTargetSurface)))
|
||||
{
|
||||
TraceError("CMapOutdoor Unable to GetSurfaceLevel Character Shadow render target texture\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wShadowMapSize, m_wShadowMapSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpCharacterShadowMapDepthSurface)))
|
||||
{
|
||||
TraceError("CMapOutdoor Unable to create Character Shadow depth Surface\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CMapOutdoor::ReleaseCharacterShadowTexture()
|
||||
{
|
||||
SAFE_RELEASE(m_lpCharacterShadowMapRenderTargetSurface);
|
||||
SAFE_RELEASE(m_lpCharacterShadowMapDepthSurface);
|
||||
SAFE_RELEASE(m_lpCharacterShadowMapTexture);
|
||||
}
|
||||
|
||||
// PORT: no shadow-map pass (see the file comment); CPythonBackground::RenderCharacterShadowToTexture
|
||||
// then skips the shadow instances.
|
||||
bool CMapOutdoor::BeginRenderCharacterShadowToTexture()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// PORT: nothing to restore when the pass did not begin.
|
||||
void CMapOutdoor::EndRenderCharacterShadowToTexture()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Platform implementation of 40250 GameLib/MapOutdoorRenderHTP.cpp (hardware-transform terrain patches).
|
||||
// PORT: the Godot Metin2World adapter draws the terrain from the same .raw/.tga/tile data (PORT-PLAN §3):
|
||||
// the recorder has no texture-coordinate generation or texture transforms, so the patch splat passes are
|
||||
// not replayed through the D3D8 device.
|
||||
#include "GameLib/StdAfx.h"
|
||||
#include "GameLib/MapOutdoor.h"
|
||||
|
||||
void CMapOutdoor::__RenderTerrain_RenderHardwareTransformPatch()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// Platform implementation of 40250 GameLib/MapOutdoorRenderSTP.cpp (software-transform terrain patches).
|
||||
// The vertex-buffer lifecycle is the 40250 code as is; the patch drawing is left to the Godot terrain
|
||||
// (see MapOutdoorRenderHTP.cpp).
|
||||
#include "GameLib/StdAfx.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
#include "GameLib/MapOutdoor.h"
|
||||
#include "GameLib/TerrainPatch.h"
|
||||
|
||||
struct SoftwareTransformPatch_SSplatVertex
|
||||
{
|
||||
D3DXVECTOR4 kPosition;
|
||||
DWORD dwDiffuse;
|
||||
DWORD dwSpecular;
|
||||
D3DXVECTOR2 kTex1;
|
||||
D3DXVECTOR2 kTex2;
|
||||
};
|
||||
|
||||
// PORT: Godot draws the terrain (PORT-PLAN §3).
|
||||
void CMapOutdoor::__RenderTerrain_RenderSoftwareTransformPatch()
|
||||
{
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_Initialize()
|
||||
{
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::SPLAT_VB_NUM; ++uIndex)
|
||||
m_kSTPD.m_pkVBSplat[uIndex]=NULL;
|
||||
m_kSTPD.m_dwSplatPos=0;
|
||||
}
|
||||
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::NONE_VB_NUM; ++uIndex)
|
||||
m_kSTPD.m_pkVBNone[uIndex]=NULL;
|
||||
m_kSTPD.m_dwNonePos=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CMapOutdoor::__SoftwareTransformPatch_Create()
|
||||
{
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::SPLAT_VB_NUM; ++uIndex)
|
||||
{
|
||||
assert(NULL==m_kSTPD.m_pkVBSplat[uIndex]);
|
||||
if (FAILED(
|
||||
ms_lpd3dDevice->CreateVertexBuffer(
|
||||
sizeof(SoftwareTransformPatch_SSplatVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT,
|
||||
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,
|
||||
D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX2,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
&m_kSTPD.m_pkVBSplat[uIndex]
|
||||
)
|
||||
)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::NONE_VB_NUM; ++uIndex)
|
||||
{
|
||||
assert(NULL==m_kSTPD.m_pkVBNone[uIndex]);
|
||||
if (FAILED(
|
||||
ms_lpd3dDevice->CreateVertexBuffer(
|
||||
sizeof(SoftwareTransformPatch_STVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT,
|
||||
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,
|
||||
D3DFVF_XYZRHW,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
&m_kSTPD.m_pkVBNone[uIndex]
|
||||
)
|
||||
)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_Destroy()
|
||||
{
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::SPLAT_VB_NUM; ++uIndex)
|
||||
{
|
||||
if (m_kSTPD.m_pkVBSplat[uIndex])
|
||||
m_kSTPD.m_pkVBSplat[uIndex]->Release();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::NONE_VB_NUM; ++uIndex)
|
||||
{
|
||||
if (m_kSTPD.m_pkVBNone[uIndex])
|
||||
m_kSTPD.m_pkVBNone[uIndex]->Release();
|
||||
}
|
||||
}
|
||||
__SoftwareTransformPatch_Initialize();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Platform implementation of 40250 GameLib/MapOutdoorWater.cpp. The water texture set is loaded as in
|
||||
// 40250; the water surface itself is drawn by the Godot water adapter (PORT-PLAN §3).
|
||||
#include "GameLib/StdAfx.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
#include "EterLib/ResourceManager.h"
|
||||
|
||||
#include "GameLib/MapOutdoor.h"
|
||||
#include "GameLib/TerrainPatch.h"
|
||||
|
||||
void CMapOutdoor::LoadWaterTexture()
|
||||
{
|
||||
UnloadWaterTexture();
|
||||
char buf[256];
|
||||
for (int i = 0; i < 30; ++i)
|
||||
{
|
||||
sprintf(buf, "d:/ymir Work/special/water/%02d.dds", i+1);
|
||||
m_WaterInstances[i].SetImagePointer((CGraphicImage *) CResourceManager::Instance().GetResourcePointer(buf));
|
||||
}
|
||||
}
|
||||
|
||||
void CMapOutdoor::UnloadWaterTexture()
|
||||
{
|
||||
for (int i = 0; i < 30; ++i)
|
||||
m_WaterInstances[i].Destroy();
|
||||
}
|
||||
|
||||
// PORT: the water patches are drawn by the Godot side.
|
||||
void CMapOutdoor::RenderWater()
|
||||
{
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
// Platform skeleton for GameLib/SnowEnvironment.h (40250 GameLib/SnowEnvironment.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "GameLib/StdAfx.h"
|
||||
#include "GameLib/SnowEnvironment.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CSnowEnvironment::CSnowEnvironment()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CSnowEnvironment::~CSnowEnvironment()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::Create() -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::Destroy() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::Enable() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::Disable() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::Update(const D3DXVECTOR3 &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::Deform() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::Render() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::__Initialize() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::__CreateBlurTexture() -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::__CreateGeometry() -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::__BeginBlur() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CSnowEnvironment::__ApplyBlur() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Platform skeleton for GameLib/TerrainDecal.h (40250 GameLib/TerrainDecal.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "GameLib/StdAfx.h"
|
||||
#include "GameLib/TerrainDecal.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CTerrainDecal::CTerrainDecal(CMapOutdoor *)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CTerrainDecal::~CTerrainDecal()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainDecal::Make(D3DXVECTOR3, D3DXVECTOR3, D3DXVECTOR3, float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainDecal::Render() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainDecal::SearchAffectedTerrainMesh(float, float, float, float, DWORD *, D3DXVECTOR3 *, D3DXVECTOR3 *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
// Platform skeleton for GameLib/TerrainPatch.h (40250 GameLib/TerrainPatch.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "GameLib/StdAfx.h"
|
||||
#include "GameLib/TerrainPatch.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
decltype(CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE) CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE{};
|
||||
|
||||
auto CTerrainPatch::Clear() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainPatch::GetWaterFaceCount() -> UINT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
}
|
||||
|
||||
auto CTerrainPatch::SoftwareTransformPatch_UpdateTerrainLighting(DWORD, const D3DLIGHT8 &, const D3DMATERIAL8 &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainPatch::BuildTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainPatch::BuildWaterVertexBuffer(SWaterVertex *, UINT) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainPatch::__BuildHardwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainPatch::__BuildSoftwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CTerrainPatch::SSoftwareTransformPatch::SSoftwareTransformPatch()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CTerrainPatch::SSoftwareTransformPatch::~SSoftwareTransformPatch()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainPatch::SSoftwareTransformPatch::Create() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainPatch::SSoftwareTransformPatch::Destroy() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainPatch::SSoftwareTransformPatch::__Initialize() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CTerrainPatchProxy::CTerrainPatchProxy()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CTerrainPatchProxy::~CTerrainPatchProxy()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainPatchProxy::Clear() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainPatchProxy::SetCenterPosition(const D3DXVECTOR3 &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainPatchProxy::IsIn(const D3DXVECTOR3 &, float) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CTerrainPatchProxy::GetWaterFaceCount() -> UINT
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
}
|
||||
|
||||
auto CTerrainPatchProxy::SoftwareTransformPatch_GetTerrainVertexDataPtr() -> SoftwareTransformPatch_SSourceVertex *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<SoftwareTransformPatch_SSourceVertex *>();
|
||||
}
|
||||
|
||||
auto CTerrainPatchProxy::HardwareTransformPatch_GetVertexBufferPtr() -> CGraphicVertexBuffer *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<CGraphicVertexBuffer *>();
|
||||
}
|
||||
|
||||
auto CTerrainPatchProxy::SoftwareTransformPatch_UpdateTerrainLighting(DWORD, const D3DLIGHT8 &, const D3DMATERIAL8 &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
// Platform skeleton for PRTerrainLib/Terrain.h (40250 PRTerrainLib/Terrain.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "PRTerrainLib/StdAfx.h"
|
||||
#include "PRTerrainLib/Terrain.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
auto CTerrainImpl::SetTextureSet(CTextureSet *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainImpl::GetTextureSet() -> CTextureSet *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<CTextureSet *>();
|
||||
}
|
||||
|
||||
decltype(CTerrainImpl::ms_pTextureSet) CTerrainImpl::ms_pTextureSet{};
|
||||
|
||||
CTerrainImpl::CTerrainImpl()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CTerrainImpl::~CTerrainImpl()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainImpl::LoadWaterMap(const char *) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CTerrainImpl::LoadWaterMapFile(const char *) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CTerrainImpl::GetShadowMapColor(float, float) -> DWORD
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<DWORD>();
|
||||
}
|
||||
|
||||
auto CTerrainImpl::Initialize() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainImpl::Clear() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainImpl::LoadTextures() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTerrainImpl::LoadHeightMap(const char *) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CTerrainImpl::RAW_LoadTileMap(const char *) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CTerrainImpl::LoadAttrMap(const char *) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
// Platform skeleton for PRTerrainLib/TextureSet.h (40250 PRTerrainLib/TextureSet.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
#include "PRTerrainLib/StdAfx.h"
|
||||
#include "PRTerrainLib/TextureSet.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
|
||||
CTextureSet::CTextureSet()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CTextureSet::~CTextureSet()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTextureSet::Initialize() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTextureSet::Clear() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTextureSet::Create() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTextureSet::Load(const char *, float) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CTextureSet::Save(const char *) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CTextureSet::GetTextureCount() -> unsigned long
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<unsigned long>();
|
||||
}
|
||||
|
||||
auto CTextureSet::GetTexture(unsigned long) -> TTerrainTexture &
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<TTerrainTexture &>();
|
||||
}
|
||||
|
||||
auto CTextureSet::RemoveTexture(unsigned long) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CTextureSet::SetTexture(unsigned long, const char *, float, float, float, float, bool, unsigned short, unsigned short, float) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CTextureSet::Reload(float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CTextureSet::AddTexture(const char *, float, float, float, float, bool, unsigned short, unsigned short, float) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CTextureSet::AddEmptyTexture() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
@@ -35,36 +35,6 @@
|
||||
#include "UserInterface/PythonTextTail.h"
|
||||
|
||||
// 40250 UserInterface/PythonBackgroundModule.cpp
|
||||
void AddStubConstants_background(PyObject* poModule)
|
||||
{
|
||||
(void) poModule;
|
||||
PyModule_AddIntConstant(poModule, "PART_SKY", CMapOutdoor::PART_SKY);
|
||||
PyModule_AddIntConstant(poModule, "PART_TREE", CMapOutdoor::PART_TREE);
|
||||
PyModule_AddIntConstant(poModule, "PART_CLOUD", CMapOutdoor::PART_CLOUD);
|
||||
PyModule_AddIntConstant(poModule, "PART_WATER", CMapOutdoor::PART_WATER);
|
||||
PyModule_AddIntConstant(poModule, "PART_OBJECT", CMapOutdoor::PART_OBJECT);
|
||||
PyModule_AddIntConstant(poModule, "PART_TERRAIN", CMapOutdoor::PART_TERRAIN);
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_DEFAULT", CSkyObject::SKY_RENDER_MODE_DEFAULT);
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_DIFFUSE", CSkyObject::SKY_RENDER_MODE_DIFFUSE);
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_TEXTURE", CSkyObject::SKY_RENDER_MODE_TEXTURE);
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE", CSkyObject::SKY_RENDER_MODE_MODULATE);
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE2X", CSkyObject::SKY_RENDER_MODE_MODULATE2X);
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE4X", CSkyObject::SKY_RENDER_MODE_MODULATE4X);
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_NONE", CPythonBackground::SHADOW_NONE);
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_GROUND", CPythonBackground::SHADOW_GROUND);
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_GROUND_AND_SOLO", CPythonBackground::SHADOW_GROUND_AND_SOLO);
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_ALL", CPythonBackground::SHADOW_ALL);
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_ALL_HIGH", CPythonBackground::SHADOW_ALL_HIGH);
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_ALL_MAX", CPythonBackground::SHADOW_ALL_MAX);
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE0", CPythonBackground::DISTANCE0);
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE1", CPythonBackground::DISTANCE1);
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE2", CPythonBackground::DISTANCE2);
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE3", CPythonBackground::DISTANCE3);
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE4", CPythonBackground::DISTANCE4);
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE_SORT", CMapOutdoor::DISTANCE_SORT);
|
||||
PyModule_AddIntConstant(poModule, "TEXTURE_SORT", CMapOutdoor::TEXTURE_SORT);
|
||||
}
|
||||
|
||||
// 40250 UserInterface/PythonEventManagerMoudle.cpp
|
||||
void AddStubConstants_event(PyObject* poModule)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "../EterLib/UIRenderCommands.h"
|
||||
|
||||
// GameplayModuleConstants.cpp: each module's 40250 constants.
|
||||
void AddStubConstants_background(PyObject* poModule);
|
||||
void AddStubConstants_event(PyObject* poModule);
|
||||
void AddStubConstants_eventMgr(PyObject* poModule);
|
||||
void AddStubConstants_guild(PyObject* poModule);
|
||||
@@ -27,106 +26,6 @@ PyObject* stub_call_named(const char* name, PyObject* result = nullptr) {
|
||||
return result ? result : Py_BuildValue("i", 0);
|
||||
}
|
||||
|
||||
// 40250 UserInterface/PythonBackgroundModule.cpp: background export names.
|
||||
PyObject* stub_background_IsSoftwareTiling(PyObject*, PyObject*) { return stub_call_named("background.IsSoftwareTiling", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_background_EnableSoftwareTiling(PyObject*, PyObject*) { return stub_call_named("background.EnableSoftwareTiling", Py_BuildNone()); }
|
||||
PyObject* stub_background_EnableSnow(PyObject*, PyObject*) { return stub_call_named("background.EnableSnow", Py_BuildNone()); }
|
||||
PyObject* stub_background_GlobalPositionToLocalPosition(PyObject*, PyObject*) { return stub_call_named("background.GlobalPositionToLocalPosition", Py_BuildValue("ii", 0, 0)); }
|
||||
PyObject* stub_background_GlobalPositionToMapInfo(PyObject*, PyObject*) { return stub_call_named("background.GlobalPositionToMapInfo", Py_BuildValue("sii", "", 0, 0)); }
|
||||
PyObject* stub_background_GetRenderShadowTime(PyObject*, PyObject*) { return stub_call_named("background.GetRenderShadowTime", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_background_LoadMap(PyObject*, PyObject*) { return stub_call_named("background.LoadMap", Py_BuildNone()); }
|
||||
PyObject* stub_background_Destroy(PyObject*, PyObject*) { return stub_call_named("background.Destroy", Py_BuildNone()); }
|
||||
PyObject* stub_background_RegisterEnvironmentData(PyObject*, PyObject*) { return stub_call_named("background.RegisterEnvironmentData", Py_BuildNone()); }
|
||||
PyObject* stub_background_SetEnvironmentData(PyObject*, PyObject*) { return stub_call_named("background.SetEnvironmentData", Py_BuildNone()); }
|
||||
PyObject* stub_background_GetCurrentMapName(PyObject*, PyObject*) { return stub_call_named("background.GetCurrentMapName", Py_BuildValue("s", "")); }
|
||||
PyObject* stub_background_GetPickingPoint(PyObject*, PyObject*) { return stub_call_named("background.GetPickingPoint", Py_BuildValue("fff", 0.0, 0.0, 0.0)); }
|
||||
PyObject* stub_background_BeginEnvironment(PyObject*, PyObject*) { return stub_call_named("background.BeginEnvironment", Py_BuildNone()); }
|
||||
PyObject* stub_background_EndEnvironment(PyObject*, PyObject*) { return stub_call_named("background.EndEnvironment", Py_BuildNone()); }
|
||||
PyObject* stub_background_SetCharacterDirLight(PyObject*, PyObject*) { return stub_call_named("background.SetCharacterDirLight", Py_BuildNone()); }
|
||||
PyObject* stub_background_SetBackgroundDirLight(PyObject*, PyObject*) { return stub_call_named("background.SetBackgroundDirLight", Py_BuildNone()); }
|
||||
PyObject* stub_background_Initialize(PyObject*, PyObject*) { return stub_call_named("background.Initialize", Py_BuildNone()); }
|
||||
PyObject* stub_background_Update(PyObject*, PyObject*) { return stub_call_named("background.Update", Py_BuildNone()); }
|
||||
PyObject* stub_background_Render(PyObject*, PyObject*) { return stub_call_named("background.Render", Py_BuildNone()); }
|
||||
PyObject* stub_background_RenderPCBlocker(PyObject*, PyObject*) { return stub_call_named("background.RenderPCBlocker", Py_BuildNone()); }
|
||||
PyObject* stub_background_RenderCollision(PyObject*, PyObject*) { return stub_call_named("background.RenderCollision", Py_BuildNone()); }
|
||||
PyObject* stub_background_RenderSky(PyObject*, PyObject*) { return stub_call_named("background.RenderSky", Py_BuildNone()); }
|
||||
PyObject* stub_background_RenderCloud(PyObject*, PyObject*) { return stub_call_named("background.RenderCloud", Py_BuildNone()); }
|
||||
PyObject* stub_background_RenderWater(PyObject*, PyObject*) { return stub_call_named("background.RenderWater", Py_BuildNone()); }
|
||||
PyObject* stub_background_RenderEffect(PyObject*, PyObject*) { return stub_call_named("background.RenderEffect", Py_BuildNone()); }
|
||||
PyObject* stub_background_RenderBeforeLensFlare(PyObject*, PyObject*) { return stub_call_named("background.RenderBeforeLensFlare", Py_BuildNone()); }
|
||||
PyObject* stub_background_RenderAfterLensFlare(PyObject*, PyObject*) { return stub_call_named("background.RenderAfterLensFlare", Py_BuildNone()); }
|
||||
PyObject* stub_background_RenderCharacterShadowToTexture(PyObject*, PyObject*) { return stub_call_named("background.RenderCharacterShadowToTexture", Py_BuildNone()); }
|
||||
PyObject* stub_background_RenderDungeon(PyObject*, PyObject*) { return stub_call_named("background.RenderDungeon", Py_BuildNone()); }
|
||||
PyObject* stub_background_GetHeight(PyObject*, PyObject*) { return stub_call_named("background.GetHeight", Py_BuildValue("f", 0.0)); }
|
||||
PyObject* stub_background_SetShadowLevel(PyObject*, PyObject*) { return stub_call_named("background.SetShadowLevel", Py_BuildNone()); }
|
||||
PyObject* stub_background_SetVisiblePart(PyObject*, PyObject*) { return stub_call_named("background.SetVisiblePart", Py_BuildNone()); }
|
||||
PyObject* stub_background_GetShadowMapColor(PyObject*, PyObject*) { return stub_call_named("background.GetShadowMapColor", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_background_SetSplatLimit(PyObject*, PyObject*) { return stub_call_named("background.SetSplatLimit", Py_BuildNone()); }
|
||||
PyObject* stub_background_GetRenderedSplatNum(PyObject*, PyObject*) { return stub_call_named("background.GetRenderedSplatNum", Py_BuildValue("iifs", 0, 0, 0.0, "")); }
|
||||
PyObject* stub_background_GetRenderedGraphicThingInstanceNum(PyObject*, PyObject*) { return stub_call_named("background.GetRenderedGraphicThingInstanceNum", Py_BuildValue("ii", 0, 0)); }
|
||||
PyObject* stub_background_SelectViewDistanceNum(PyObject*, PyObject*) { return stub_call_named("background.SelectViewDistanceNum", Py_BuildNone()); }
|
||||
PyObject* stub_background_SetViewDistanceSet(PyObject*, PyObject*) { return stub_call_named("background.SetViewDistanceSet", Py_BuildNone()); }
|
||||
PyObject* stub_background_GetFarClip(PyObject*, PyObject*) { return stub_call_named("background.GetFarClip", Py_BuildValue("f", 0.0)); }
|
||||
PyObject* stub_background_GetDistanceSetInfo(PyObject*, PyObject*) { return stub_call_named("background.GetDistanceSetInfo", Py_BuildValue("ifff", 0, 0.0, 0.0, 0.0)); }
|
||||
PyObject* stub_background_SetBGLoading(PyObject*, PyObject*) { return stub_call_named("background.SetBGLoading", Py_BuildNone()); }
|
||||
PyObject* stub_background_SetRenderSort(PyObject*, PyObject*) { return stub_call_named("background.SetRenderSort", Py_BuildNone()); }
|
||||
PyObject* stub_background_SetTransparentTree(PyObject*, PyObject*) { return stub_call_named("background.SetTransparentTree", Py_BuildNone()); }
|
||||
PyObject* stub_background_SetXMasTree(PyObject*, PyObject*) { return stub_call_named("background.SetXMasTree", Py_BuildNone()); }
|
||||
PyObject* stub_background_RegisterDungeonMapName(PyObject*, PyObject*) { return stub_call_named("background.RegisterDungeonMapName", Py_BuildNone()); }
|
||||
PyObject* stub_background_VisibleGuildArea(PyObject*, PyObject*) { return stub_call_named("background.VisibleGuildArea", Py_BuildNone()); }
|
||||
PyObject* stub_background_DisableGuildArea(PyObject*, PyObject*) { return stub_call_named("background.DisableGuildArea", Py_BuildNone()); }
|
||||
PyObject* stub_background_WarpTest(PyObject*, PyObject*) { return stub_call_named("background.WarpTest", Py_BuildNone()); }
|
||||
PyMethodDef methods_background[] = {
|
||||
{ "IsSoftwareTiling", stub_background_IsSoftwareTiling, METH_VARARGS },
|
||||
{ "EnableSoftwareTiling", stub_background_EnableSoftwareTiling, METH_VARARGS },
|
||||
{ "EnableSnow", stub_background_EnableSnow, METH_VARARGS },
|
||||
{ "GlobalPositionToLocalPosition", stub_background_GlobalPositionToLocalPosition, METH_VARARGS },
|
||||
{ "GlobalPositionToMapInfo", stub_background_GlobalPositionToMapInfo, METH_VARARGS },
|
||||
{ "GetRenderShadowTime", stub_background_GetRenderShadowTime, METH_VARARGS },
|
||||
{ "LoadMap", stub_background_LoadMap, METH_VARARGS },
|
||||
{ "Destroy", stub_background_Destroy, METH_VARARGS },
|
||||
{ "RegisterEnvironmentData", stub_background_RegisterEnvironmentData, METH_VARARGS },
|
||||
{ "SetEnvironmentData", stub_background_SetEnvironmentData, METH_VARARGS },
|
||||
{ "GetCurrentMapName", stub_background_GetCurrentMapName, METH_VARARGS },
|
||||
{ "GetPickingPoint", stub_background_GetPickingPoint, METH_VARARGS },
|
||||
{ "BeginEnvironment", stub_background_BeginEnvironment, METH_VARARGS },
|
||||
{ "EndEnvironment", stub_background_EndEnvironment, METH_VARARGS },
|
||||
{ "SetCharacterDirLight", stub_background_SetCharacterDirLight, METH_VARARGS },
|
||||
{ "SetBackgroundDirLight", stub_background_SetBackgroundDirLight, METH_VARARGS },
|
||||
{ "Initialize", stub_background_Initialize, METH_VARARGS },
|
||||
{ "Update", stub_background_Update, METH_VARARGS },
|
||||
{ "Render", stub_background_Render, METH_VARARGS },
|
||||
{ "RenderPCBlocker", stub_background_RenderPCBlocker, METH_VARARGS },
|
||||
{ "RenderCollision", stub_background_RenderCollision, METH_VARARGS },
|
||||
{ "RenderSky", stub_background_RenderSky, METH_VARARGS },
|
||||
{ "RenderCloud", stub_background_RenderCloud, METH_VARARGS },
|
||||
{ "RenderWater", stub_background_RenderWater, METH_VARARGS },
|
||||
{ "RenderEffect", stub_background_RenderEffect, METH_VARARGS },
|
||||
{ "RenderBeforeLensFlare", stub_background_RenderBeforeLensFlare, METH_VARARGS },
|
||||
{ "RenderAfterLensFlare", stub_background_RenderAfterLensFlare, METH_VARARGS },
|
||||
{ "RenderCharacterShadowToTexture", stub_background_RenderCharacterShadowToTexture, METH_VARARGS },
|
||||
{ "RenderDungeon", stub_background_RenderDungeon, METH_VARARGS },
|
||||
{ "GetHeight", stub_background_GetHeight, METH_VARARGS },
|
||||
{ "SetShadowLevel", stub_background_SetShadowLevel, METH_VARARGS },
|
||||
{ "SetVisiblePart", stub_background_SetVisiblePart, METH_VARARGS },
|
||||
{ "GetShadowMapColor", stub_background_GetShadowMapColor, METH_VARARGS },
|
||||
{ "SetSplatLimit", stub_background_SetSplatLimit, METH_VARARGS },
|
||||
{ "GetRenderedSplatNum", stub_background_GetRenderedSplatNum, METH_VARARGS },
|
||||
{ "GetRenderedGraphicThingInstanceNum", stub_background_GetRenderedGraphicThingInstanceNum, METH_VARARGS },
|
||||
{ "SelectViewDistanceNum", stub_background_SelectViewDistanceNum, METH_VARARGS },
|
||||
{ "SetViewDistanceSet", stub_background_SetViewDistanceSet, METH_VARARGS },
|
||||
{ "GetFarClip", stub_background_GetFarClip, METH_VARARGS },
|
||||
{ "GetDistanceSetInfo", stub_background_GetDistanceSetInfo, METH_VARARGS },
|
||||
{ "SetBGLoading", stub_background_SetBGLoading, METH_VARARGS },
|
||||
{ "SetRenderSort", stub_background_SetRenderSort, METH_VARARGS },
|
||||
{ "SetTransparentTree", stub_background_SetTransparentTree, METH_VARARGS },
|
||||
{ "SetXMasTree", stub_background_SetXMasTree, METH_VARARGS },
|
||||
{ "RegisterDungeonMapName", stub_background_RegisterDungeonMapName, METH_VARARGS },
|
||||
{ "VisibleGuildArea", stub_background_VisibleGuildArea, METH_VARARGS },
|
||||
{ "DisableGuildArea", stub_background_DisableGuildArea, METH_VARARGS },
|
||||
{ "WarpTest", stub_background_WarpTest, METH_VARARGS },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
// 40250 UserInterface/PythonEventManagerMoudle.cpp: event export names.
|
||||
PyObject* stub_event_RegisterEventSet(PyObject*, PyObject*) { return stub_call_named("event.RegisterEventSet", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_event_RegisterEventSetFromString(PyObject*, PyObject*) { return stub_call_named("event.RegisterEventSetFromString", Py_BuildValue("i", 0)); }
|
||||
@@ -557,11 +456,6 @@ PyMethodDef methods_udp[] = {
|
||||
} // namespace
|
||||
|
||||
void init_2v0_gameplay_stubs() {
|
||||
{
|
||||
PyObject* module = Py_InitModule("background", methods_background);
|
||||
PyModule_AddIntConstant(module, "__port_stub__", 1);
|
||||
AddStubConstants_background(module);
|
||||
}
|
||||
{
|
||||
PyObject* module = Py_InitModule("event", methods_event);
|
||||
PyModule_AddIntConstant(module, "__port_stub__", 1);
|
||||
|
||||
@@ -359,6 +359,7 @@ bool run_main_script_body(const char* lpCmdLine, std::string* error)
|
||||
initeffect();
|
||||
initfly();
|
||||
initskill();
|
||||
initBackground();
|
||||
initServerStateChecker();
|
||||
init_2v0_gameplay_stubs();
|
||||
|
||||
|
||||
@@ -1,362 +0,0 @@
|
||||
// Stand-in for the 40250 logic unit GameLib/MapManager.cpp, not ported yet: the members the ported units
|
||||
// reference, as platform_stub.py stubs. Delete this file in the commit that ports the unit into port/
|
||||
// (docs/PORT-PLAN.md).
|
||||
#include "GameLib/StdAfx.h"
|
||||
#include "GameLib/MapManager.h"
|
||||
#include "EterPack/EterPackManager.h"
|
||||
#include "EterBase/MappedFile.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
#include "GameLib/MapUtil.h"
|
||||
|
||||
#include <map_setting.h>
|
||||
#include <terrain_files.h>
|
||||
#include <terrain_mesh.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "../../PlatformStub.h"
|
||||
|
||||
namespace {
|
||||
// PORT: The Godot terrain adapter owns drawing until CMapOutdoor is ported. This
|
||||
// pack-backed state supplies its 40250 callers with the same height and .msenv
|
||||
// data during that transition; it is not a CMapOutdoor port.
|
||||
struct NativeMapState {
|
||||
fmt::MapSetting setting;
|
||||
std::string name;
|
||||
std::map<std::pair<int, int>, fmt::HeightMap> heights;
|
||||
std::map<std::pair<int, int>, std::vector<BYTE>> attrs; // attr.atr payload, empty when unreadable
|
||||
bool ready = false;
|
||||
};
|
||||
std::map<const CMapManager *, NativeMapState> s_native_maps;
|
||||
|
||||
bool pack_bytes(const std::string &name, std::string &out)
|
||||
{
|
||||
CMappedFile file;
|
||||
LPCVOID data = nullptr;
|
||||
if (!CEterPackManager::Instance().Get(file, name.c_str(), &data))
|
||||
return false;
|
||||
out.assign(static_cast<const char *>(data), file.Size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool load_height_tile(NativeMapState &state, int tx, int ty)
|
||||
{
|
||||
if (tx < 0 || ty < 0 || tx >= state.setting.map_size_x || ty >= state.setting.map_size_y)
|
||||
return false;
|
||||
const auto key = std::make_pair(tx, ty);
|
||||
if (state.heights.find(key) != state.heights.end())
|
||||
return true;
|
||||
char tile[16];
|
||||
snprintf(tile, sizeof(tile), "%03d%03d", tx, ty);
|
||||
std::string bytes;
|
||||
if (!pack_bytes(state.name + "/" + tile + "/height.raw", bytes) || bytes.size() != 131 * 131 * 2)
|
||||
return false;
|
||||
fmt::HeightMap map;
|
||||
map.raw.resize(131 * 131);
|
||||
for (size_t i = 0; i < map.raw.size(); ++i)
|
||||
map.raw[i] = static_cast<unsigned char>(bytes[i * 2]) |
|
||||
(static_cast<unsigned char>(bytes[i * 2 + 1]) << 8);
|
||||
state.heights.emplace(key, std::move(map));
|
||||
return true;
|
||||
}
|
||||
|
||||
// attr.atr: {u16 magic=2634, u16 w=256, u16 h=256} + 256*256 bytes (40250 CTerrainImpl::LoadAttrMap).
|
||||
const std::vector<BYTE> *attr_tile(NativeMapState &state, int tx, int ty)
|
||||
{
|
||||
if (tx < 0 || ty < 0 || tx >= state.setting.map_size_x || ty >= state.setting.map_size_y)
|
||||
return nullptr;
|
||||
const auto key = std::make_pair(tx, ty);
|
||||
auto found = state.attrs.find(key);
|
||||
if (found == state.attrs.end())
|
||||
{
|
||||
char tile[16];
|
||||
snprintf(tile, sizeof(tile), "%03d%03d", tx, ty);
|
||||
std::string bytes;
|
||||
std::vector<BYTE> attr;
|
||||
const size_t payload = size_t(CTerrainImpl::ATTRMAP_XSIZE) * CTerrainImpl::ATTRMAP_YSIZE;
|
||||
if (pack_bytes(state.name + "/" + tile + "/attr.atr", bytes) && bytes.size() == 6 + payload &&
|
||||
(static_cast<unsigned char>(bytes[0]) | (static_cast<unsigned char>(bytes[1]) << 8)) == 2634)
|
||||
attr.assign(bytes.begin() + 6, bytes.end());
|
||||
found = state.attrs.emplace(key, std::move(attr)).first;
|
||||
}
|
||||
return found->second.empty() ? nullptr : &found->second;
|
||||
}
|
||||
}
|
||||
|
||||
// CMapOutdoor::GetHeight is max(terrain, object height under CCullingManager); no map objects are registered
|
||||
// until CMapOutdoor is ported, so it is the terrain height.
|
||||
auto CMapManager::GetHeight(float fx, float fy) -> float
|
||||
{
|
||||
return GetTerrainHeight(fx, fy);
|
||||
}
|
||||
|
||||
// CMapOutdoor::GetTerrainHeight over the native height tiles.
|
||||
auto CMapManager::GetTerrainHeight(float fx, float fy) -> float
|
||||
{
|
||||
auto found = s_native_maps.find(this);
|
||||
if (found == s_native_maps.end() || !found->second.ready)
|
||||
return 0.0f;
|
||||
NativeMapState &state = found->second;
|
||||
const double x = fx, y = std::abs(double(fy));
|
||||
if (x < 0 || y < 0)
|
||||
return 0.0f;
|
||||
const int tx = int(x / 25600.0), ty = int(y / 25600.0);
|
||||
if (!load_height_tile(state, tx, ty))
|
||||
return 0.0f;
|
||||
const float height = float(fmt::terrain_height_at(state.heights.at({tx, ty}), x - tx * 25600.0,
|
||||
y - ty * 25600.0, state.setting.height_scale));
|
||||
return height;
|
||||
}
|
||||
|
||||
// CMapOutdoor::GetNormal → CTerrain::GetNormal. 40250 fills CTerrain::m_acNormalMap at LoadHeightMap with
|
||||
// CTerrain::CalculateNormal and reads the cell's byte triple; the same formula runs here per call on the
|
||||
// cached height tile (GetHeightMapValue = raw[(y+1)*131 + x+1]).
|
||||
bool CMapManager::GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal)
|
||||
{
|
||||
auto found = s_native_maps.find(this);
|
||||
if (found == s_native_maps.end() || !found->second.ready)
|
||||
return false;
|
||||
NativeMapState &state = found->second;
|
||||
const int count_x = state.setting.map_size_x, count_y = state.setting.map_size_y;
|
||||
ix = std::clamp(ix, 0, count_x * CTerrainImpl::TERRAIN_XSIZE);
|
||||
iy = std::clamp(iy, 0, count_y * CTerrainImpl::TERRAIN_YSIZE);
|
||||
const int tx = std::min(ix / CTerrainImpl::TERRAIN_XSIZE, count_x - 1);
|
||||
const int ty = std::min(iy / CTerrainImpl::TERRAIN_YSIZE, count_y - 1);
|
||||
if (!load_height_tile(state, tx, ty))
|
||||
return false;
|
||||
while (ix >= CTerrainImpl::TERRAIN_XSIZE)
|
||||
ix -= CTerrainImpl::TERRAIN_XSIZE;
|
||||
while (iy >= CTerrainImpl::TERRAIN_YSIZE)
|
||||
iy -= CTerrainImpl::TERRAIN_YSIZE;
|
||||
const int x = ix / CTerrainImpl::CELLSCALE, y = iy / CTerrainImpl::CELLSCALE;
|
||||
|
||||
const std::vector<uint16_t> &raw = state.heights.at({tx, ty}).raw;
|
||||
auto height = [&](int sx, int sy) {
|
||||
return float(raw[(sy + 1) * CTerrainImpl::HEIGHTMAP_RAW_XSIZE + sx + 1]);
|
||||
};
|
||||
D3DXVECTOR3 normal;
|
||||
normal.x = -state.setting.height_scale * (height(x - 1, y) - height(x + 1, y));
|
||||
normal.y = -state.setting.height_scale * (height(x, y - 1) - height(x, y + 1));
|
||||
normal.z = 2.0f * static_cast<float>(CTerrainImpl::CELLSCALE);
|
||||
normal *= 127.0f / D3DXVec3Length(&normal);
|
||||
// PR_FLOAT_TO_INT (fistp, then one down when it rounded up) into the char normal map.
|
||||
const signed char n[3] = {
|
||||
static_cast<signed char>(int(std::floor(normal.x))),
|
||||
static_cast<signed char>(int(std::floor(normal.y))),
|
||||
static_cast<signed char>(int(std::floor(normal.z))),
|
||||
};
|
||||
pv3Normal->x = -((float)n[0]) * 0.007874016f;
|
||||
pv3Normal->y = ((float)n[1]) * 0.007874016f;
|
||||
pv3Normal->z = ((float)n[2]) * 0.007874016f;
|
||||
return true;
|
||||
}
|
||||
|
||||
CMapManager::CMapManager() : mc_pcurEnvironmentData(NULL)
|
||||
{
|
||||
m_pkMap = NULL;
|
||||
m_isSoftwareTilingEnableReserved=false;
|
||||
|
||||
// Initialize();
|
||||
}
|
||||
|
||||
CMapManager::~CMapManager()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CMapManager::Initialize()
|
||||
{
|
||||
mc_pcurEnvironmentData = NULL;
|
||||
__LoadMapInfoVector();
|
||||
}
|
||||
|
||||
void CMapManager::Create()
|
||||
{
|
||||
// PORT: CMapOutdoor is still rendered by Metin2World, not this native object.
|
||||
}
|
||||
|
||||
void CMapManager::Destroy()
|
||||
{
|
||||
Clear();
|
||||
for (auto &entry : m_EnvironmentDataMap)
|
||||
delete entry.second;
|
||||
m_EnvironmentDataMap.clear();
|
||||
}
|
||||
|
||||
void CMapManager::__LoadMapInfoVector()
|
||||
{
|
||||
std::string bytes;
|
||||
if (!pack_bytes(m_stAtlasInfoFileName, bytes) && !pack_bytes("AtlasInfo.txt", bytes))
|
||||
return;
|
||||
std::istringstream lines(bytes);
|
||||
std::string line;
|
||||
m_kVct_kMapInfo.clear();
|
||||
while (std::getline(lines, line)) {
|
||||
std::istringstream fields(line);
|
||||
TMapInfo info{};
|
||||
if (!(fields >> info.m_strName >> info.m_dwBaseX >> info.m_dwBaseY >> info.m_dwSizeX >> info.m_dwSizeY))
|
||||
continue;
|
||||
info.m_dwEndX = info.m_dwBaseX + info.m_dwSizeX * 25600;
|
||||
info.m_dwEndY = info.m_dwBaseY + info.m_dwSizeY * 25600;
|
||||
m_kVct_kMapInfo.push_back(info);
|
||||
}
|
||||
}
|
||||
|
||||
auto CMapManager::Clear() -> void
|
||||
{
|
||||
s_native_maps.erase(this);
|
||||
mc_pcurEnvironmentData = NULL;
|
||||
}
|
||||
|
||||
auto CMapManager::AllocMap() -> CMapBase *
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<CMapBase *>();
|
||||
}
|
||||
|
||||
auto CMapManager::LoadMap(const std::string &name, float x, float y, float) -> bool
|
||||
{
|
||||
NativeMapState next;
|
||||
next.name = name;
|
||||
std::string bytes, error;
|
||||
if (!pack_bytes(name + "/setting.txt", bytes) || !fmt::parse_map_setting(bytes, next.setting, &error)) {
|
||||
TraceError("native map setting failed: %s (%s)", name.c_str(), error.c_str());
|
||||
return false;
|
||||
}
|
||||
if (!load_height_tile(next, int(x / 25600.0f), int(y / 25600.0f))) {
|
||||
TraceError("native map height tile failed: %s (%d,%d)", name.c_str(), int(x / 25600.0f), int(y / 25600.0f));
|
||||
return false;
|
||||
}
|
||||
for (auto &entry : m_EnvironmentDataMap)
|
||||
delete entry.second;
|
||||
m_EnvironmentDataMap.clear();
|
||||
mc_pcurEnvironmentData = NULL;
|
||||
if (!next.setting.environment.empty()) {
|
||||
auto env = std::make_unique<TEnvironmentData>();
|
||||
Environment_Init(*env);
|
||||
const std::string env_path = "d:/ymir work/environment/" + next.setting.environment;
|
||||
if (Environment_Load(*env, env_path.c_str())) {
|
||||
m_EnvironmentDataMap[0] = env.release();
|
||||
mc_pcurEnvironmentData = m_EnvironmentDataMap[0];
|
||||
} else {
|
||||
TraceError("native map environment failed: %s", env_path.c_str());
|
||||
}
|
||||
}
|
||||
next.ready = true;
|
||||
s_native_maps[this] = std::move(next);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto CMapManager::isPhysicalCollision(const D3DXVECTOR3 &) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CMapManager::GetWaterHeight(int, int, long *) -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CMapManager::GetShadowMapColor(float, float) -> DWORD
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<DWORD>();
|
||||
}
|
||||
|
||||
// 40250 MapManager.cpp:506 → CMapOutdoor::isAttrOn (MapOutdoor.cpp:1202).
|
||||
bool CMapManager::isAttrOn(float fX, float fY, BYTE byAttr)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
// PORT: PR_FLOAT_TO_INT is x87 fistp (round to nearest) corrected down, i.e. floor.
|
||||
return isAttrOn(int(std::floor(fX)), int(std::floor(fY)), byAttr);
|
||||
}
|
||||
|
||||
// 40250 MapManager.cpp:524 → CMapOutdoor::isAttrOn (MapOutdoor.cpp:1220) → CTerrain::isAttrOn (AreaTerrain.cpp:487).
|
||||
// PORT: CMapOutdoor/CTerrain are not ported; the terrain count and the attribute map come from the native map
|
||||
// state (Setting.txt MapSize, <map>/<xxxyyy>/attr.atr) instead of the loaded CTerrain list.
|
||||
bool CMapManager::isAttrOn(int iX, int iY, BYTE byAttr)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
auto state = s_native_maps.find(this);
|
||||
if (state == s_native_maps.end() || !state->second.ready)
|
||||
return false;
|
||||
const int countX = state->second.setting.map_size_x, countY = state->second.setting.map_size_y;
|
||||
if (iX < 0 || iY < 0 || iX > countX * CTerrainImpl::TERRAIN_XSIZE || iY > countY * CTerrainImpl::TERRAIN_YSIZE)
|
||||
return false;
|
||||
|
||||
WORD wTerrainCoordX, wTerrainCoordY;
|
||||
wTerrainCoordX = iX / CTerrainImpl::TERRAIN_XSIZE;
|
||||
wTerrainCoordY = iY / CTerrainImpl::TERRAIN_YSIZE;
|
||||
|
||||
const std::vector<BYTE> *attr = attr_tile(state->second, wTerrainCoordX, wTerrainCoordY);
|
||||
if (!attr)
|
||||
return false;
|
||||
|
||||
WORD wLocalX, wLocalY;
|
||||
wLocalX = (iX - wTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE) / (CTerrainImpl::HALF_CELLSCALE);
|
||||
wLocalY = (iY - wTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE) / (CTerrainImpl::HALF_CELLSCALE);
|
||||
|
||||
if (wLocalX >= CTerrainImpl::ATTRMAP_XSIZE || wLocalY >= CTerrainImpl::ATTRMAP_YSIZE)
|
||||
return false;
|
||||
|
||||
BYTE byMapAttr = (*attr)[wLocalY * CTerrainImpl::ATTRMAP_XSIZE + wLocalX];
|
||||
|
||||
if ( byAttr < 16 )
|
||||
return (byMapAttr & byAttr) ? true : false;
|
||||
else
|
||||
{
|
||||
if ( byAttr/16 == byMapAttr/16)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto CMapManager::BeginEnvironment() -> void
|
||||
{
|
||||
if (!IsMapReady() || !mc_pcurEnvironmentData)
|
||||
return;
|
||||
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, TRUE);
|
||||
STATEMANAGER.SetMaterial(&mc_pcurEnvironmentData->Material);
|
||||
STATEMANAGER.SetLight(0, &mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND]);
|
||||
// PORT: RecordingDevice stores SetLight but has no D3D LightEnable slot yet.
|
||||
}
|
||||
|
||||
auto CMapManager::EndEnvironment() -> void
|
||||
{
|
||||
if (IsMapReady() && mc_pcurEnvironmentData)
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
|
||||
}
|
||||
|
||||
// PORT: MapOutdoor is not allocated yet; report the pack-backed transition map's readiness.
|
||||
bool CMapManager::IsMapReady()
|
||||
{
|
||||
auto found = s_native_maps.find(this);
|
||||
return found != s_native_maps.end() && found->second.ready;
|
||||
}
|
||||
|
||||
// 40250 MapManager.cpp: true when the current map is a CMapOutdoor. PORT: CMapOutdoor is not ported (the Godot
|
||||
// terrain adapter draws the map), so there is no outdoor map object to hand out; false keeps the 40250 callers
|
||||
// (CPythonMiniMap::Update/Render/LoadAtlas) on their "no outdoor map" path instead of reaching into one.
|
||||
auto CMapManager::IsMapOutdoor() -> bool
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto CMapManager::GetMapOutdoorRef() -> CMapOutdoor &
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
// Never constructed (CMapOutdoor's constructor is not ported either); unreachable while IsMapOutdoor() is false.
|
||||
alignas(CMapOutdoor) static unsigned char storage[sizeof(CMapOutdoor)];
|
||||
return *reinterpret_cast<CMapOutdoor *>(storage);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// Stand-in for the 40250 logic unit GameLib/MapOutdoor.cpp, not ported yet: the members the ported units
|
||||
// reference, as platform_stub.py stubs. Only reached behind CMapManager::IsMapOutdoor(), which is false until
|
||||
// CMapOutdoor is ported. Delete this file in the commit that ports the unit into port/ (docs/PORT-PLAN.md).
|
||||
#include "GameLib/StdAfx.h"
|
||||
#include "GameLib/MapOutdoor.h"
|
||||
|
||||
#include "../../PlatformStub.h"
|
||||
|
||||
auto CMapOutdoor::GetTerrainPointer(BYTE, CTerrain **) -> BOOL
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto CMapOutdoor::GetBaseXY(DWORD *, DWORD *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// Pending MapType.cpp dependency of InstanceBase; the full unit is not ported yet.
|
||||
#include "GameLib/StdAfx.h"
|
||||
#include "GameLib/MapType.h"
|
||||
|
||||
float SPixelPosition_CalculateDistanceSq3d(const TPixelPosition& left, const TPixelPosition& right)
|
||||
{
|
||||
float dx = left.x - right.x;
|
||||
float dy = left.y - right.y;
|
||||
float dz = left.z - right.z;
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Stand-in for the 40250 logic unit GameLib/PropertyManager.cpp, not ported yet: the members the ported units
|
||||
// reference, as platform_stub.py stubs. Delete this file in the commit that ports the unit into port/
|
||||
// (docs/PORT-PLAN.md).
|
||||
#include "GameLib/StdAfx.h"
|
||||
#include "GameLib/PropertyManager.h"
|
||||
|
||||
#include "../../PlatformStub.h"
|
||||
|
||||
CPropertyManager::CPropertyManager()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CPropertyManager::~CPropertyManager()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
@@ -1,342 +0,0 @@
|
||||
// Stand-in for the 40250 logic unit UserInterface/PythonBackground.cpp, not ported yet: the members the ported units
|
||||
// reference, as platform_stub.py stubs. Delete this file in the commit that ports the unit into port/
|
||||
// (docs/PORT-PLAN.md).
|
||||
#include "UserInterface/StdAfx.h"
|
||||
#include "UserInterface/PythonBackground.h"
|
||||
#include "UserInterface/InstanceBase.h"
|
||||
#include "EterLib/StateManager.h"
|
||||
|
||||
#include "../../PlatformStub.h"
|
||||
|
||||
auto CPythonBackground::Destroy() -> void
|
||||
{
|
||||
CMapManager::Destroy();
|
||||
m_bVisibleGuildArea = FALSE;
|
||||
}
|
||||
|
||||
auto CPythonBackground::Create() -> void
|
||||
{
|
||||
CMapManager::Create();
|
||||
}
|
||||
|
||||
auto CPythonBackground::GlobalPositionToLocalPosition(LONG &x, LONG &y) -> void
|
||||
{
|
||||
x -= m_dwBaseX;
|
||||
y -= m_dwBaseY;
|
||||
}
|
||||
|
||||
auto CPythonBackground::LocalPositionToGlobalPosition(LONG &x, LONG &y) -> void
|
||||
{
|
||||
x += m_dwBaseX;
|
||||
y += m_dwBaseY;
|
||||
}
|
||||
|
||||
auto CPythonBackground::RefreshShadowLevel() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::Update(float, float, float) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::ClearGuildArea() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RegisterGuildArea(int, int, int, int) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::CreateTargetEffect(DWORD, DWORD) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::CreateTargetEffect(DWORD, long, long) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::DeleteTargetEffect(DWORD) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::Warp(DWORD x, DWORD y) -> void
|
||||
{
|
||||
if (m_kVct_kMapInfo.empty())
|
||||
Initialize();
|
||||
auto found = std::find_if(m_kVct_kMapInfo.begin(), m_kVct_kMapInfo.end(),
|
||||
[x, y](const TMapInfo &info) {
|
||||
return x >= info.m_dwBaseX && x < info.m_dwEndX &&
|
||||
y >= info.m_dwBaseY && y < info.m_dwEndY;
|
||||
});
|
||||
if (found == m_kVct_kMapInfo.end()) {
|
||||
TraceError("NOT_FOUND_GLOBAL_POSITION(%u, %u)", x, y);
|
||||
return;
|
||||
}
|
||||
if (!LoadMap(found->m_strName, float(x - found->m_dwBaseX),
|
||||
float(y - found->m_dwBaseY), 0.0f)) {
|
||||
TraceError("CPythonBackground::Warp map load failed: %s", found->m_strName.c_str());
|
||||
return;
|
||||
}
|
||||
m_dwBaseX = found->m_dwBaseX;
|
||||
m_dwBaseY = found->m_dwBaseY;
|
||||
m_strMapName = found->m_strName;
|
||||
}
|
||||
|
||||
auto CPythonBackground::GetWarpMapName() -> const char *
|
||||
{
|
||||
return m_strMapName.c_str();
|
||||
}
|
||||
|
||||
CPythonBackground::CPythonBackground()
|
||||
{
|
||||
m_eViewDistanceNum=0;
|
||||
m_dwBaseX=0;
|
||||
m_dwBaseY=0;
|
||||
m_bVisibleGuildArea=FALSE;
|
||||
m_iXMasTreeGrade=0;
|
||||
}
|
||||
|
||||
CPythonBackground::~CPythonBackground()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
// 40250 PythonBackground.cpp:547-608, verbatim. No map objects are registered with CCullingManager until
|
||||
// CMapOutdoor is ported, so the checkers see no opponent and advancing is never blocked.
|
||||
struct CollisionChecker
|
||||
{
|
||||
bool isBlocked;
|
||||
CInstanceBase* pInstance;
|
||||
CollisionChecker(CInstanceBase* pInstance) : pInstance(pInstance), isBlocked(false) {}
|
||||
void operator () (CGraphicObjectInstance* pOpponent)
|
||||
{
|
||||
if (isBlocked)
|
||||
return;
|
||||
|
||||
if (!pOpponent)
|
||||
return;
|
||||
|
||||
if (pInstance->IsBlockObject(*pOpponent))
|
||||
isBlocked=true;
|
||||
}
|
||||
};
|
||||
|
||||
struct CollisionAdjustChecker
|
||||
{
|
||||
bool isBlocked;
|
||||
CInstanceBase* pInstance;
|
||||
CollisionAdjustChecker(CInstanceBase* pInstance) : pInstance(pInstance), isBlocked(false) {}
|
||||
void operator () (CGraphicObjectInstance* pOpponent)
|
||||
{
|
||||
if (!pOpponent)
|
||||
return;
|
||||
|
||||
if (pInstance->AvoidObject(*pOpponent))
|
||||
isBlocked=true;
|
||||
}
|
||||
};
|
||||
|
||||
bool CPythonBackground::CheckAdvancing(CInstanceBase * pInstance)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return true;
|
||||
|
||||
Vector3d center;
|
||||
float radius;
|
||||
pInstance->GetGraphicThingInstanceRef().GetBoundingSphere(center,radius);
|
||||
|
||||
CCullingManager & rkCullingMgr = CCullingManager::Instance();
|
||||
|
||||
CollisionAdjustChecker kCollisionAdjustChecker(pInstance);
|
||||
rkCullingMgr.ForInRange(center, radius, &kCollisionAdjustChecker);
|
||||
if (kCollisionAdjustChecker.isBlocked)
|
||||
{
|
||||
CollisionChecker kCollisionChecker(pInstance);
|
||||
rkCullingMgr.ForInRange(center, radius, &kCollisionChecker);
|
||||
if (kCollisionChecker.isBlocked)
|
||||
{
|
||||
pInstance->BlockMovement();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pInstance->NEW_MoveToDestPixelPositionDirection(pInstance->NEW_GetDstPixelPositionRef());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// 40250 CMapOutdoor::__PickTerrainHeight (MapOutdoor.cpp:448), marching the ray against the terrain height.
|
||||
// PORT: CMapOutdoor is not ported; the terrain is the native CMapManager height map, and GetTerrainNum/
|
||||
// GetTerrainPointer become "the map is ready" (GetHeight reads the height tile under the point).
|
||||
bool PickTerrainHeight(CMapManager& rkMap, float& fPos, const D3DXVECTOR3& v3Start, const D3DXVECTOR3& v3End, float fStep,
|
||||
float fRayRange, float fLimitRange, D3DXVECTOR3* pv3Pick)
|
||||
{
|
||||
D3DXVECTOR3 v3CurPos;
|
||||
|
||||
float fRayRangeInv=1.0f/fRayRange;
|
||||
while (fPos < fRayRange && fPos<fLimitRange)
|
||||
{
|
||||
D3DXVec3Lerp(&v3CurPos, &v3Start, &v3End, fPos*fRayRangeInv);
|
||||
float fMultiplier = 1.0f;
|
||||
if (rkMap.IsMapReady())
|
||||
{
|
||||
// PORT: PR_FLOAT_TO_INT is x87 fistp (round to nearest) corrected down, i.e. floor.
|
||||
int ix = int(std::floor(v3CurPos.x)), iy = int(std::floor(fabs(v3CurPos.y)));
|
||||
float fMapHeight = rkMap.GetHeight(float(ix), float(iy));
|
||||
if ( fMapHeight >= v3CurPos.z)
|
||||
{
|
||||
*pv3Pick = v3CurPos;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fMultiplier = fMAX(1.0f, 0.01f * ( v3CurPos.z - fMapHeight ) );
|
||||
}
|
||||
}
|
||||
fPos += fStep * fMultiplier;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 40250 CMapOutdoor::GetPickingPointWithRayOnlyTerrain (MapOutdoor.cpp:549).
|
||||
bool CPythonBackground::GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
|
||||
{
|
||||
bool bTerrainPick = false;
|
||||
D3DXVECTOR3 v3TerrainPick;
|
||||
|
||||
D3DXVECTOR3 v3Start, v3End, v3Dir;
|
||||
float fRayRange;
|
||||
rRay.GetStartPoint(&v3Start);
|
||||
rRay.GetDirection(&v3Dir, &fRayRange);
|
||||
rRay.GetEndPoint(&v3End);
|
||||
|
||||
float fPos = 0.0f;
|
||||
bTerrainPick=true;
|
||||
if (!PickTerrainHeight(*this, fPos, v3Start, v3End, 5.0f, fRayRange, 5000.0f, &v3TerrainPick))
|
||||
if (!PickTerrainHeight(*this, fPos, v3Start, v3End, 10.0f, fRayRange, 10000.0f, &v3TerrainPick))
|
||||
if (!PickTerrainHeight(*this, fPos, v3Start, v3End, 100.0f, fRayRange, 100000.0f, &v3TerrainPick))
|
||||
bTerrainPick=false;
|
||||
|
||||
if (bTerrainPick)
|
||||
{
|
||||
*v3IntersectPt = v3TerrainPick;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 40250 CMapOutdoor::GetPickingPointWithRay (MapOutdoor.cpp:484).
|
||||
// PORT: the object pick (FGetPickingPoint over CCullingManager) needs CMapOutdoor's area objects; only the
|
||||
// terrain half runs until the map is ported.
|
||||
bool CPythonBackground::GetPickingPointWithRay(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
|
||||
{
|
||||
return GetPickingPointWithRayOnlyTerrain(rRay, v3IntersectPt);
|
||||
}
|
||||
|
||||
// 40250 PythonBackground.cpp:173 (CPythonApplication::RenderGame's SetPerspective); m_pkMap stays null
|
||||
// until the map is ported, so this is the 50000 far clip.
|
||||
float CPythonBackground::GetFarClip()
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return 50000.0f;
|
||||
|
||||
if (m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip==0.0f)
|
||||
{
|
||||
TraceError("CPythonBackground::GetFarClip m_eViewDistanceNum=%d", m_eViewDistanceNum);
|
||||
m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip=25600.0f;
|
||||
}
|
||||
|
||||
return m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip;
|
||||
}
|
||||
|
||||
auto CPythonBackground::Render() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderAfterLensFlare() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderBeforeLensFlare() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderCharacterShadowToTexture() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderCloud() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderEffect() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderPCBlocker() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderSky() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderSnow() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::RenderWater() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonBackground::SetBackgroundDirLight() -> void
|
||||
{
|
||||
if (!IsMapReady() || !mc_pcurEnvironmentData)
|
||||
return;
|
||||
STATEMANAGER.SetLight(0, &mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND]);
|
||||
}
|
||||
|
||||
auto CPythonBackground::SetCharacterDirLight() -> void
|
||||
{
|
||||
if (!IsMapReady() || !mc_pcurEnvironmentData)
|
||||
return;
|
||||
STATEMANAGER.SetLight(0, &mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_CHARACTER]);
|
||||
}
|
||||
|
||||
void CPythonBackground::Initialize()
|
||||
{
|
||||
std::string atlas(LocaleService_GetLocalePath());
|
||||
atlas += "/AtlasInfo.txt";
|
||||
SetAtlasInfoFileName(atlas.c_str());
|
||||
CMapManager::Initialize();
|
||||
}
|
||||
|
||||
// 40250 PythonBackground.cpp:263 → CMapOutdoor::GetPickingPoint (MapOutdoor.cpp:443): the cursor ray.
|
||||
bool CPythonBackground::GetPickingPoint(D3DXVECTOR3 * v3IntersectPt)
|
||||
{
|
||||
return GetPickingPointWithRay(ms_Ray, v3IntersectPt);
|
||||
}
|
||||
@@ -21,3 +21,14 @@ auto CPythonSystem::IsShowDamage() -> bool
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
|
||||
auto CPythonSystem::GetShadowLevel() -> int
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
}
|
||||
|
||||
auto CPythonSystem::SetSoftwareTiling(bool isEnable) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef __ETER_FILE_DIR__
|
||||
#define __ETER_FILE_DIR__
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class CDir
|
||||
{
|
||||
public:
|
||||
CDir();
|
||||
virtual ~CDir();
|
||||
|
||||
void Destroy();
|
||||
bool Create(const char* c_szFilter, const char* c_szPath="", BOOL bCheckedExtension = FALSE);
|
||||
|
||||
protected:
|
||||
virtual bool OnFolder(const char* c_szFilter, const char* c_szPath, const char* c_szName) = 0;
|
||||
virtual bool OnFile(const char* c_szPath, const char* c_szName) = 0;
|
||||
|
||||
protected:
|
||||
bool IsFolder();
|
||||
|
||||
void Initialize();
|
||||
|
||||
protected:
|
||||
WIN32_FIND_DATA m_wfd;
|
||||
HANDLE m_hFind;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef __INC_ETERBASE_TEMPFILE_H__
|
||||
#define __INC_ETERBASE_TEMPFILE_H__
|
||||
|
||||
#include "FileBase.h"
|
||||
|
||||
class CTempFile : public CFileBase
|
||||
{
|
||||
public:
|
||||
CTempFile(const char * c_pszPrefix = NULL);
|
||||
virtual ~CTempFile();
|
||||
|
||||
protected:
|
||||
char m_szFileName[MAX_PATH+1];
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ColorTransitionHelper.h"
|
||||
|
||||
void CColorTransitionHelper::Clear(const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha)
|
||||
{
|
||||
|
||||
m_fSrcRed = c_rfRed;
|
||||
m_fSrcGreen = c_rfGreen;
|
||||
m_fSrcBlue = c_rfBlue;
|
||||
m_fSrcAlpha = c_rfAlpha;
|
||||
|
||||
m_fDstRed = c_rfRed;
|
||||
m_fDstGreen = c_rfGreen;
|
||||
m_fDstBlue = c_rfBlue;
|
||||
m_fDstAlpha = c_rfAlpha;
|
||||
|
||||
m_dwCurColor = 0x00000000;
|
||||
|
||||
m_dwStartTime = m_dwDuration = 0;
|
||||
}
|
||||
|
||||
void CColorTransitionHelper::SetSrcColor(const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha)
|
||||
{
|
||||
m_fSrcRed = c_rfRed;
|
||||
m_fSrcGreen = c_rfGreen;
|
||||
m_fSrcBlue = c_rfBlue;
|
||||
m_fSrcAlpha = c_rfAlpha;
|
||||
}
|
||||
|
||||
void CColorTransitionHelper::SetTransition(const float & c_rfRed,
|
||||
const float & c_rfGreen,
|
||||
const float & c_rfBlue,
|
||||
const float & c_rfAlpha,
|
||||
const DWORD & dwDuration)
|
||||
{
|
||||
m_fDstRed = c_rfRed;
|
||||
m_fDstGreen = c_rfGreen;
|
||||
m_fDstBlue = c_rfBlue;
|
||||
m_fDstAlpha = c_rfAlpha;
|
||||
|
||||
m_dwDuration = dwDuration;
|
||||
}
|
||||
|
||||
void CColorTransitionHelper::StartTransition()
|
||||
{
|
||||
m_bTransitionStarted = true;
|
||||
m_dwStartTime = GetCurrentTime();
|
||||
}
|
||||
|
||||
bool CColorTransitionHelper::Update()
|
||||
{
|
||||
// if (!m_bTransitionStarted)
|
||||
// return false;
|
||||
|
||||
DWORD dwCurTime = GetCurrentTime();
|
||||
DWORD dwElapsedTime = dwCurTime - m_dwStartTime;
|
||||
|
||||
float fpercent = (float)(dwElapsedTime) / (float)(m_dwDuration);
|
||||
if (fpercent <= 0.0f)
|
||||
fpercent = 0.0f;
|
||||
if (fpercent >= 1.0f)
|
||||
fpercent = 1.0f;
|
||||
float fCurRed, fCurGreen, fCurBlue, fCurAlpha;
|
||||
fCurRed = m_fSrcRed + (m_fDstRed - m_fSrcRed) * fpercent;
|
||||
fCurGreen = m_fSrcGreen + (m_fDstGreen - m_fSrcGreen) * fpercent;
|
||||
fCurBlue = m_fSrcBlue + (m_fDstBlue - m_fSrcBlue) * fpercent;
|
||||
fCurAlpha = m_fSrcAlpha + (m_fDstAlpha - m_fSrcAlpha) * fpercent;
|
||||
|
||||
// Tracef("%f, %f, %f, %f\n", fCurRed, fCurGreen, fCurBlue, fCurAlpha);
|
||||
|
||||
m_dwCurColor = (((DWORD)(fCurAlpha * 255.0f)&0xff)<< 24) |
|
||||
(((DWORD)(fCurRed * 255.0f)&0xff) << 16) |
|
||||
(((DWORD)(fCurGreen * 255.0f)&0xff) << 8) |
|
||||
((DWORD)(fCurBlue * 255.0f)&0xff);
|
||||
|
||||
if ( (1.0f == fpercent) && (fCurAlpha == m_fDstAlpha) && (fCurRed == m_fDstRed) && (fCurGreen == m_fDstGreen) && (fCurBlue == m_fDstBlue) )
|
||||
{
|
||||
m_bTransitionStarted = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const D3DCOLOR & CColorTransitionHelper::GetCurColor()
|
||||
{
|
||||
return m_dwCurColor;
|
||||
}
|
||||
|
||||
CColorTransitionHelper::CColorTransitionHelper():m_bTransitionStarted(false)
|
||||
{
|
||||
Clear(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
CColorTransitionHelper::~CColorTransitionHelper()
|
||||
{
|
||||
Clear(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,265 @@
|
||||
#include "StdAfx.h"
|
||||
#include "DungeonBlock.h"
|
||||
|
||||
#include "../EterLib/StateManager.h"
|
||||
|
||||
class CDungeonModelInstance : public CGrannyModelInstance
|
||||
{
|
||||
public:
|
||||
CDungeonModelInstance() {}
|
||||
virtual ~CDungeonModelInstance() {}
|
||||
|
||||
void RenderDungeonBlock()
|
||||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
STATEMANAGER.SetVertexShader(ms_pnt2VS);
|
||||
LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer();
|
||||
if (lpd3dRigidPNTVtxBuf)
|
||||
{
|
||||
STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNT2Vertex));
|
||||
RenderMeshNodeListWithTwoTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_BLEND_PNT);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDungeonBlockShadow()
|
||||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
|
||||
|
||||
STATEMANAGER.SetVertexShader(ms_pnt2VS);
|
||||
LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer();
|
||||
if (lpd3dRigidPNTVtxBuf)
|
||||
{
|
||||
STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNT2Vertex));
|
||||
RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_BLEND_PNT);
|
||||
}
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct FUpdate
|
||||
{
|
||||
float fElapsedTime;
|
||||
D3DXMATRIX * pmatWorld;
|
||||
void operator() (CGrannyModelInstance * pInstance)
|
||||
{
|
||||
pInstance->Update(CGrannyModelInstance::ANIFPS_MIN);
|
||||
pInstance->UpdateLocalTime(fElapsedTime);
|
||||
pInstance->Deform(pmatWorld);
|
||||
}
|
||||
};
|
||||
|
||||
void CDungeonBlock::Update()
|
||||
{
|
||||
Transform();
|
||||
|
||||
FUpdate Update;
|
||||
Update.fElapsedTime = 0.0f;
|
||||
Update.pmatWorld = &m_worldMatrix;
|
||||
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), Update);
|
||||
}
|
||||
|
||||
struct FRender
|
||||
{
|
||||
void operator() (CDungeonModelInstance * pInstance)
|
||||
{
|
||||
pInstance->RenderDungeonBlock();
|
||||
}
|
||||
};
|
||||
|
||||
void CDungeonBlock::Render()
|
||||
{
|
||||
// if (!isShow())
|
||||
// return;
|
||||
|
||||
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FRender());
|
||||
}
|
||||
|
||||
struct FRenderShadow
|
||||
{
|
||||
void operator() (CDungeonModelInstance * pInstance)
|
||||
{
|
||||
pInstance->RenderDungeonBlockShadow();
|
||||
}
|
||||
};
|
||||
|
||||
void CDungeonBlock::OnRenderShadow()
|
||||
{
|
||||
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FRenderShadow());
|
||||
}
|
||||
|
||||
struct FBoundBox
|
||||
{
|
||||
D3DXVECTOR3 * m_pv3Min;
|
||||
D3DXVECTOR3 * m_pv3Max;
|
||||
|
||||
FBoundBox(D3DXVECTOR3 * pv3Min, D3DXVECTOR3 * pv3Max)
|
||||
{
|
||||
m_pv3Min = pv3Min;
|
||||
m_pv3Max = pv3Max;
|
||||
}
|
||||
void operator() (CGrannyModelInstance * pInstance)
|
||||
{
|
||||
pInstance->GetBoundBox(m_pv3Min, m_pv3Max);
|
||||
}
|
||||
};
|
||||
|
||||
bool CDungeonBlock::GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius)
|
||||
{
|
||||
v3Center = m_v3Center;
|
||||
fRadius = m_fRadius;
|
||||
D3DXVec3TransformCoord(&v3Center, &v3Center, &GetTransform());
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDungeonBlock::OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector)
|
||||
{
|
||||
assert(pscdVector);
|
||||
CStaticCollisionDataVector::const_iterator it;
|
||||
for(it = pscdVector->begin();it!=pscdVector->end();++it)
|
||||
{
|
||||
AddCollision(&(*it),&GetTransform());
|
||||
}
|
||||
}
|
||||
|
||||
void CDungeonBlock::OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance)
|
||||
{
|
||||
assert(pAttributeInstance);
|
||||
SetHeightInstance(pAttributeInstance);
|
||||
}
|
||||
|
||||
bool CDungeonBlock::OnGetObjectHeight(float fX, float fY, float * pfHeight)
|
||||
{
|
||||
if (m_pHeightAttributeInstance && m_pHeightAttributeInstance->GetHeight(fX, fY, pfHeight))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDungeonBlock::BuildBoundingSphere()
|
||||
{
|
||||
D3DXVECTOR3 v3Min, v3Max;
|
||||
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FBoundBox(&v3Min, &v3Max));
|
||||
|
||||
m_v3Center = (v3Min+v3Max) * 0.5f;
|
||||
const auto vv = (v3Max - v3Min);
|
||||
m_fRadius = D3DXVec3Length(&vv)*0.5f + 150.0f; // extra length for attached objects
|
||||
}
|
||||
|
||||
bool CDungeonBlock::Intersect(float * pfu, float * pfv, float * pft)
|
||||
{
|
||||
TModelInstanceContainer::iterator itor = m_ModelInstanceContainer.begin();
|
||||
for (; itor != m_ModelInstanceContainer.end(); ++itor)
|
||||
{
|
||||
CDungeonModelInstance * pInstance = *itor;
|
||||
if (pInstance->Intersect(&CGraphicObjectInstance::GetTransform(), pfu, pfv, pft))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDungeonBlock::GetBoundBox(D3DXVECTOR3 * pv3Min, D3DXVECTOR3 * pv3Max)
|
||||
{
|
||||
pv3Min->x = +10000000.0f;
|
||||
pv3Min->y = +10000000.0f;
|
||||
pv3Min->z = +10000000.0f;
|
||||
pv3Max->x = -10000000.0f;
|
||||
pv3Max->y = -10000000.0f;
|
||||
pv3Max->z = -10000000.0f;
|
||||
|
||||
TModelInstanceContainer::iterator itor = m_ModelInstanceContainer.begin();
|
||||
for (; itor != m_ModelInstanceContainer.end(); ++itor)
|
||||
{
|
||||
CDungeonModelInstance * pInstance = *itor;
|
||||
|
||||
D3DXVECTOR3 v3Min;
|
||||
D3DXVECTOR3 v3Max;
|
||||
pInstance->GetBoundBox(&v3Min, &v3Max);
|
||||
|
||||
pv3Min->x = min(v3Min.x, pv3Min->x);
|
||||
pv3Min->y = min(v3Min.x, pv3Min->y);
|
||||
pv3Min->z = min(v3Min.x, pv3Min->z);
|
||||
pv3Max->x = max(v3Max.x, pv3Max->x);
|
||||
pv3Max->y = max(v3Max.x, pv3Max->y);
|
||||
pv3Max->z = max(v3Max.x, pv3Max->z);
|
||||
}
|
||||
}
|
||||
|
||||
bool CDungeonBlock::Load(const char * c_szFileName)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_pThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(c_szFileName);
|
||||
|
||||
m_pThing->AddReference();
|
||||
if (m_pThing->GetModelCount() <= 0)
|
||||
{
|
||||
TraceError("CDungeonBlock::Load(filename=%s) - model count is %d\n", c_szFileName, m_pThing->GetModelCount());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ModelInstanceContainer.reserve(m_pThing->GetModelCount());
|
||||
|
||||
for (int i = 0; i < m_pThing->GetModelCount(); ++i)
|
||||
{
|
||||
CDungeonModelInstance * pModelInstance = new CDungeonModelInstance;
|
||||
pModelInstance->SetMainModelPointer(m_pThing->GetModelPointer(i), &m_kDeformableVertexBuffer);
|
||||
DWORD dwVertexCount = pModelInstance->GetVertexCount();
|
||||
m_kDeformableVertexBuffer.Destroy();
|
||||
m_kDeformableVertexBuffer.Create(
|
||||
dwVertexCount,
|
||||
D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1,
|
||||
D3DUSAGE_WRITEONLY,
|
||||
D3DPOOL_MANAGED);
|
||||
m_ModelInstanceContainer.push_back(pModelInstance);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDungeonBlock::__Initialize()
|
||||
{
|
||||
m_v3Center = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
m_fRadius = 0.0f;
|
||||
|
||||
m_pThing = NULL;
|
||||
}
|
||||
|
||||
void CDungeonBlock::Destroy()
|
||||
{
|
||||
if (m_pThing)
|
||||
{
|
||||
m_pThing->Release();
|
||||
m_pThing = NULL;
|
||||
}
|
||||
|
||||
stl_wipe(m_ModelInstanceContainer);
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
CDungeonBlock::CDungeonBlock()
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
CDungeonBlock::~CDungeonBlock()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapBase.h"
|
||||
|
||||
CMapBase::CMapBase()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CMapBase::~CMapBase()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CMapBase::Clear()
|
||||
{
|
||||
m_strName = "";
|
||||
m_eType = MAPTYPE_INVALID;
|
||||
mc_pEnvironmentData = NULL;
|
||||
Leave();
|
||||
}
|
||||
|
||||
bool CMapBase::Enter()
|
||||
{
|
||||
m_bReady = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapBase::Leave()
|
||||
{
|
||||
m_bReady = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapBase::SetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
|
||||
{
|
||||
mc_pEnvironmentData = c_pEnvironmentData;
|
||||
OnSetEnvironmentDataPtr();
|
||||
}
|
||||
|
||||
void CMapBase::ResetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
|
||||
{
|
||||
mc_pEnvironmentData = c_pEnvironmentData;
|
||||
OnResetEnvironmentDataPtr();
|
||||
}
|
||||
|
||||
void CMapBase::Render()
|
||||
{
|
||||
if (IsReady())
|
||||
OnRender();
|
||||
}
|
||||
|
||||
bool CMapBase::LoadProperty()
|
||||
{
|
||||
std::string strFileName = GetName() + "\\MapProperty.txt";
|
||||
|
||||
CTokenVectorMap stTokenVectorMap;
|
||||
|
||||
if (!LoadMultipleTextData(strFileName.c_str(), stTokenVectorMap))
|
||||
{
|
||||
TraceError("CMapBase::LoadProperty(FileName=%s) - LoadMultipleTextData ERROR \306\304\300\317\300\314 \276\370\300\273 \260\241\264\311\274\272\300\314 \270\271\275\300\264\317\264\331.", strFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype"))
|
||||
{
|
||||
TraceError("CMapBase::LoadProperty(FileName=%s) - FIND 'scripttype' - FAILED", strFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("maptype"))
|
||||
{
|
||||
TraceError("CMapBase::LoadProperty(FileName=%s) - FIND 'maptype' - FAILED", strFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: 이미 존재하는 맵 데이터와 동일한 데이터를 사용하는 맵을 새로 추가할 때, 맵 배포 용량을 줄이기 위한 작업.
|
||||
// MapProperty.txt 파일에 ParentMapName 값이 설정되어 있다면, 실제 모든 데이터는 ParentMap에서 읽어온다.
|
||||
// 데이터의 부분공유(부분 오버라이트?) 기능은 필요 없대서, Parent Map에서 모든 데이터를 읽어옴.
|
||||
if (stTokenVectorMap.end() != stTokenVectorMap.find("parentmapname"))
|
||||
{
|
||||
m_strParentMapName = stTokenVectorMap["parentmapname"][0];
|
||||
}
|
||||
|
||||
const std::string & c_rstrType = stTokenVectorMap["scripttype"][0];
|
||||
const std::string & c_rstrMapType = stTokenVectorMap["maptype"][0];
|
||||
|
||||
if (0 != c_rstrType.compare("MapProperty"))
|
||||
{
|
||||
TraceError("CMapBase::LoadProperty(FileName=%s) - Resourse Type ERROR", strFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 == c_rstrMapType.compare("Indoor"))
|
||||
SetType(MAPTYPE_INDOOR);
|
||||
else if (0 == c_rstrMapType.compare("Outdoor"))
|
||||
SetType(MAPTYPE_OUTDOOR);
|
||||
else if (0 == c_rstrMapType.compare("Invalid"))
|
||||
SetType(MAPTYPE_OUTDOOR);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,638 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EterLib/StateManager.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
|
||||
#include "MapManager.h"
|
||||
#include "MapOutdoor.h"
|
||||
|
||||
#include "PropertyLoader.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 기본 함수
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool CMapManager::IsMapOutdoor()
|
||||
{
|
||||
if (m_pkMap)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CMapOutdoor& CMapManager::GetMapOutdoorRef()
|
||||
{
|
||||
assert(NULL!=m_pkMap);
|
||||
return *m_pkMap;
|
||||
}
|
||||
|
||||
|
||||
CMapManager::CMapManager() : mc_pcurEnvironmentData(NULL)
|
||||
{
|
||||
m_pkMap = NULL;
|
||||
m_isSoftwareTilingEnableReserved=false;
|
||||
|
||||
// Initialize();
|
||||
}
|
||||
|
||||
CMapManager::~CMapManager()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool CMapManager::IsSoftwareTilingEnable()
|
||||
{
|
||||
return CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE;
|
||||
}
|
||||
|
||||
void CMapManager::ReserveSoftwareTilingEnable(bool isEnable)
|
||||
{
|
||||
m_isSoftwareTilingEnableReserved=isEnable;
|
||||
}
|
||||
|
||||
|
||||
void CMapManager::Initialize()
|
||||
{
|
||||
mc_pcurEnvironmentData = NULL;
|
||||
__LoadMapInfoVector();
|
||||
}
|
||||
|
||||
void CMapManager::Create()
|
||||
{
|
||||
assert(NULL==m_pkMap && "CMapManager::Create");
|
||||
if (m_pkMap)
|
||||
{
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE=m_isSoftwareTilingEnableReserved;
|
||||
|
||||
m_pkMap = (CMapOutdoor*)AllocMap();
|
||||
|
||||
assert(NULL!=m_pkMap && "CMapManager::Create MAP is NULL");
|
||||
|
||||
}
|
||||
|
||||
void CMapManager::Destroy()
|
||||
{
|
||||
stl_wipe_second(m_EnvironmentDataMap);
|
||||
|
||||
if (m_pkMap)
|
||||
{
|
||||
m_pkMap->Clear();
|
||||
delete m_pkMap;
|
||||
m_pkMap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CMapManager::Clear()
|
||||
{
|
||||
if (m_pkMap)
|
||||
m_pkMap->Clear();
|
||||
}
|
||||
|
||||
CMapBase * CMapManager::AllocMap()
|
||||
{
|
||||
return new CMapOutdoor;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Map
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CMapManager::LoadProperty()
|
||||
{
|
||||
CPropertyLoader PropertyLoader;
|
||||
PropertyLoader.SetPropertyManager(&m_PropertyManager);
|
||||
PropertyLoader.Create("*.*", "Property");
|
||||
}
|
||||
|
||||
bool CMapManager::LoadMap(const std::string & c_rstrMapName, float x, float y, float z)
|
||||
{
|
||||
CMapOutdoor& rkMap = GetMapOutdoorRef();
|
||||
|
||||
rkMap.Leave();
|
||||
rkMap.SetName(c_rstrMapName);
|
||||
rkMap.LoadProperty();
|
||||
|
||||
if ( CMapBase::MAPTYPE_INDOOR == rkMap.GetType())
|
||||
{
|
||||
TraceError("CMapManager::LoadMap() Indoor Map Load Failed");
|
||||
return false;
|
||||
}
|
||||
else if (CMapBase::MAPTYPE_OUTDOOR == rkMap.GetType())
|
||||
{
|
||||
if (!rkMap.Load(x, y, z))
|
||||
{
|
||||
TraceError("CMapManager::LoadMap() Outdoor Map Load Failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
RegisterEnvironmentData(0, rkMap.GetEnvironmentDataName().c_str());
|
||||
|
||||
SetEnvironmentData(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceError("CMapManager::LoadMap() Invalid Map Type");
|
||||
return false;
|
||||
}
|
||||
|
||||
rkMap.Enter();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapManager::IsMapReady()
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return false;
|
||||
|
||||
return m_pkMap->IsReady();
|
||||
}
|
||||
|
||||
bool CMapManager::UnloadMap(const std::string c_strMapName)
|
||||
{
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
if (c_strMapName != rkMap.GetName() && "" != rkMap.GetName())
|
||||
{
|
||||
LogBoxf("%s: Unload Map Failed", c_strMapName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapManager::UpdateMap(float fx, float fy, float fz)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.Update(fx, -fy, fz);
|
||||
}
|
||||
|
||||
void CMapManager::UpdateAroundAmbience(float fx, float fy, float fz)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.UpdateAroundAmbience(fx, -fy, fz);
|
||||
}
|
||||
|
||||
float CMapManager::GetHeight(float fx, float fy)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
{
|
||||
TraceError("CMapManager::GetHeight(%f, %f) - \270\312\300\314 \273\375\274\272\265\307\301\366 \276\312\300\272 \273\363\305\302\277\241\274\255 \301\242\261\331", fx, fy);
|
||||
return 0.0f;
|
||||
}
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetHeight(fx, fy);
|
||||
}
|
||||
|
||||
float CMapManager::GetTerrainHeight(float fx, float fy)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
{
|
||||
TraceError("CMapManager::GetTerrainHeight(%f, %f) - \270\312\300\314 \273\375\274\272\265\307\301\366 \276\312\300\272 \273\363\305\302\277\241\274\255 \301\242\261\331", fx, fy);
|
||||
return 0.0f;
|
||||
}
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetTerrainHeight(fx, fy);
|
||||
}
|
||||
|
||||
bool CMapManager::GetWaterHeight(int iX, int iY, long * plWaterHeight)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
{
|
||||
TraceError("CMapManager::GetTerrainHeight(%f, %f) - \270\312\300\314 \273\375\274\272\265\307\301\366 \276\312\300\272 \273\363\305\302\277\241\274\255 \301\242\261\331", iX, iY);
|
||||
return false;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetWaterHeight(iX, iY, plWaterHeight);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Environment
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CMapManager::BeginEnvironment()
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
if (!mc_pcurEnvironmentData)
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
|
||||
// Light always on
|
||||
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, TRUE);
|
||||
|
||||
// Fog
|
||||
STATEMANAGER.SaveRenderState(D3DRS_FOGENABLE, mc_pcurEnvironmentData->bFogEnable);
|
||||
|
||||
// Material
|
||||
STATEMANAGER.SetMaterial(&mc_pcurEnvironmentData->Material);
|
||||
|
||||
// Directional Light
|
||||
if (mc_pcurEnvironmentData->bDirLightsEnable[ENV_DIRLIGHT_BACKGROUND])
|
||||
{
|
||||
ms_lpd3dDevice->LightEnable(0, TRUE);
|
||||
|
||||
rkMap.ApplyLight((DWORD)(uintptr_t)mc_pcurEnvironmentData, mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND]); // PORT: 64-bit pointer tag
|
||||
}
|
||||
else
|
||||
ms_lpd3dDevice->LightEnable(0, FALSE);
|
||||
|
||||
if (mc_pcurEnvironmentData->bFogEnable)
|
||||
{
|
||||
DWORD dwFogColor = mc_pcurEnvironmentData->FogColor;
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, dwFogColor);
|
||||
|
||||
if (mc_pcurEnvironmentData->bDensityFog)
|
||||
{
|
||||
float fDensity = 0.00015f;
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP); // pixel fog
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGDENSITY, *((DWORD *) &fDensity)); // vertex fog
|
||||
}
|
||||
else
|
||||
{
|
||||
CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance();
|
||||
rkForest.SetFog(
|
||||
mc_pcurEnvironmentData->GetFogNearDistance(),
|
||||
mc_pcurEnvironmentData->GetFogFarDistance()
|
||||
);
|
||||
|
||||
float fFogNear=mc_pcurEnvironmentData->GetFogNearDistance();
|
||||
float fFogFar=mc_pcurEnvironmentData->GetFogFarDistance();
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); // vertex fox
|
||||
STATEMANAGER.SetRenderState(D3DRS_RANGEFOGENABLE, TRUE); // vertex fox
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGSTART, *((DWORD *) &fFogNear)); // USED BY D3DFOG_LINEAR
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGEND, *((DWORD *) &fFogFar)); // USED BY D3DFOG_LINEAR
|
||||
}
|
||||
}
|
||||
|
||||
rkMap.OnBeginEnvironment();
|
||||
}
|
||||
|
||||
void CMapManager::EndEnvironment()
|
||||
{
|
||||
if (!mc_pcurEnvironmentData)
|
||||
return;
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_FOGENABLE);
|
||||
}
|
||||
|
||||
void CMapManager::SetEnvironmentData(int nEnvDataIndex)
|
||||
{
|
||||
const TEnvironmentData * c_pEnvironmenData;
|
||||
|
||||
if (GetEnvironmentData(nEnvDataIndex, &c_pEnvironmenData))
|
||||
SetEnvironmentDataPtr(c_pEnvironmenData);
|
||||
}
|
||||
|
||||
void CMapManager::SetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
if (!c_pEnvironmentData)
|
||||
{
|
||||
assert(!"null environment data");
|
||||
TraceError("null environment data");
|
||||
return;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
|
||||
|
||||
mc_pcurEnvironmentData = c_pEnvironmentData;
|
||||
|
||||
|
||||
rkMap.SetEnvironmentDataPtr(mc_pcurEnvironmentData);
|
||||
}
|
||||
|
||||
void CMapManager::ResetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
if (!c_pEnvironmentData)
|
||||
{
|
||||
assert(!"null environment data");
|
||||
TraceError("null environment data");
|
||||
return;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
|
||||
mc_pcurEnvironmentData = c_pEnvironmentData;
|
||||
rkMap.ResetEnvironmentDataPtr(mc_pcurEnvironmentData);
|
||||
}
|
||||
|
||||
void CMapManager::BlendEnvironmentData(const TEnvironmentData * c_pEnvironmentData, int iTransitionTime)
|
||||
{
|
||||
}
|
||||
|
||||
bool CMapManager::RegisterEnvironmentData(DWORD dwIndex, const char * c_szFileName)
|
||||
{
|
||||
TEnvironmentData * pEnvironmentData = AllocEnvironmentData();
|
||||
|
||||
if (!LoadEnvironmentData(c_szFileName, pEnvironmentData))
|
||||
{
|
||||
DeleteEnvironmentData(pEnvironmentData);
|
||||
return false;
|
||||
}
|
||||
|
||||
TEnvironmentDataMap::iterator f=m_EnvironmentDataMap.find(dwIndex);
|
||||
if (m_EnvironmentDataMap.end()==f)
|
||||
{
|
||||
m_EnvironmentDataMap.insert(TEnvironmentDataMap::value_type(dwIndex, pEnvironmentData));
|
||||
}
|
||||
else
|
||||
{
|
||||
delete f->second;
|
||||
f->second=pEnvironmentData;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapManager::GetCurrentEnvironmentData(const TEnvironmentData ** c_ppEnvironmentData)
|
||||
{
|
||||
*c_ppEnvironmentData = mc_pcurEnvironmentData;
|
||||
}
|
||||
|
||||
bool CMapManager::GetEnvironmentData(DWORD dwIndex, const TEnvironmentData ** c_ppEnvironmentData)
|
||||
{
|
||||
TEnvironmentDataMap::iterator itor = m_EnvironmentDataMap.find(dwIndex);
|
||||
|
||||
if (m_EnvironmentDataMap.end() == itor)
|
||||
{
|
||||
*c_ppEnvironmentData = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
*c_ppEnvironmentData = itor->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapManager::RefreshPortal()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor & rMap = GetMapOutdoorRef();
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (!rMap.GetAreaPointer(i, &pArea))
|
||||
continue;
|
||||
|
||||
pArea->RefreshPortal();
|
||||
}
|
||||
}
|
||||
|
||||
void CMapManager::ClearPortal()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor & rMap = GetMapOutdoorRef();
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (!rMap.GetAreaPointer(i, &pArea))
|
||||
continue;
|
||||
|
||||
pArea->ClearPortal();
|
||||
}
|
||||
}
|
||||
|
||||
void CMapManager::AddShowingPortalID(int iID)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor & rMap = GetMapOutdoorRef();
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (!rMap.GetAreaPointer(i, &pArea))
|
||||
continue;
|
||||
|
||||
pArea->AddShowingPortalID(iID);
|
||||
}
|
||||
}
|
||||
|
||||
TEnvironmentData * CMapManager::AllocEnvironmentData()
|
||||
{
|
||||
TEnvironmentData * pEnvironmentData = new TEnvironmentData;
|
||||
Environment_Init(*pEnvironmentData);
|
||||
return pEnvironmentData;
|
||||
}
|
||||
|
||||
void CMapManager::DeleteEnvironmentData(TEnvironmentData * pEnvironmentData)
|
||||
{
|
||||
delete pEnvironmentData;
|
||||
pEnvironmentData = NULL;
|
||||
}
|
||||
|
||||
BOOL CMapManager::LoadEnvironmentData(const char * c_szFileName, TEnvironmentData * pEnvironmentData)
|
||||
{
|
||||
if (!pEnvironmentData)
|
||||
return FALSE;
|
||||
|
||||
return (BOOL)Environment_Load(*pEnvironmentData, c_szFileName);
|
||||
}
|
||||
|
||||
DWORD CMapManager::GetShadowMapColor(float fx, float fy)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetShadowMapColor(fx, fy);
|
||||
}
|
||||
|
||||
std::vector<int> & CMapManager::GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
{
|
||||
static std::vector<int> s_emptyVector;
|
||||
*piPatch = 0;
|
||||
*piSplat = 0;
|
||||
return s_emptyVector;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetRenderedSplatNum(piPatch, piSplat, pfSplatRatio);
|
||||
}
|
||||
|
||||
CArea::TCRCWithNumberVector & CMapManager::GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
{
|
||||
static CArea::TCRCWithNumberVector s_emptyVector;
|
||||
*pdwGraphicThingInstanceNum = 0;
|
||||
*pdwCRCNum = 0;
|
||||
return s_emptyVector;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetRenderedGraphicThingInstanceNum(pdwGraphicThingInstanceNum, pdwCRCNum);
|
||||
}
|
||||
|
||||
bool CMapManager::GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetNormal(ix, iy, pv3Normal);
|
||||
}
|
||||
|
||||
bool CMapManager::isPhysicalCollision(const D3DXVECTOR3 & c_rvCheckPosition)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.isAttrOn(c_rvCheckPosition.x, -c_rvCheckPosition.y, CTerrainImpl::ATTRIBUTE_BLOCK);
|
||||
}
|
||||
|
||||
bool CMapManager::isAttrOn(float fX, float fY, BYTE byAttr)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.isAttrOn(fX, fY, byAttr);
|
||||
}
|
||||
|
||||
bool CMapManager::GetAttr(float fX, float fY, BYTE * pbyAttr)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetAttr(fX, fY, pbyAttr);
|
||||
}
|
||||
|
||||
bool CMapManager::isAttrOn(int iX, int iY, BYTE byAttr)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.isAttrOn(iX, iY, byAttr);
|
||||
}
|
||||
|
||||
bool CMapManager::GetAttr(int iX, int iY, BYTE * pbyAttr)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetAttr(iX, iY, pbyAttr);
|
||||
}
|
||||
|
||||
// 2004.10.14.myevan.TEMP_CAreaLoaderThread
|
||||
/*
|
||||
bool CMapManager::BGLoadingEnable()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
return ((CMapOutdoor*)m_pMap)->BGLoadingEnable();
|
||||
}
|
||||
|
||||
void CMapManager::BGLoadingEnable(bool bBGLoadingEnable)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
((CMapOutdoor*)m_pMap)->BGLoadingEnable(bBGLoadingEnable);
|
||||
}
|
||||
*/
|
||||
|
||||
void CMapManager::SetTerrainRenderSort(CMapOutdoor::ETerrainRenderSort eTerrainRenderSort)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.SetTerrainRenderSort(eTerrainRenderSort);
|
||||
}
|
||||
|
||||
void CMapManager::SetTransparentTree(bool bTransparenTree)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.SetTransparentTree(bTransparenTree);
|
||||
}
|
||||
|
||||
CMapOutdoor::ETerrainRenderSort CMapManager::GetTerrainRenderSort()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return CMapOutdoor::DISTANCE_SORT;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetTerrainRenderSort();
|
||||
}
|
||||
|
||||
void CMapManager::GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
{
|
||||
*pdwBaseX = 0;
|
||||
*pdwBaseY = 0;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.GetBaseXY(pdwBaseX, pdwBaseY);
|
||||
}
|
||||
|
||||
void CMapManager::__LoadMapInfoVector()
|
||||
{
|
||||
CMappedFile kFile;
|
||||
LPCVOID pData;
|
||||
if (!CEterPackManager::Instance().Get(kFile, m_stAtlasInfoFileName.c_str(), &pData))
|
||||
if (!CEterPackManager::Instance().Get(kFile, "AtlasInfo.txt", &pData))
|
||||
return;
|
||||
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
textFileLoader.Bind(kFile.Size(), pData);
|
||||
|
||||
char szMapName[256];
|
||||
int x, y;
|
||||
int width, height;
|
||||
for (UINT uLineIndex=0; uLineIndex<textFileLoader.GetLineCount(); ++uLineIndex)
|
||||
{
|
||||
const std::string& c_rstLine=textFileLoader.GetLineString(uLineIndex);
|
||||
sscanf(c_rstLine.c_str(), "%s %d %d %d %d",
|
||||
szMapName,
|
||||
&x, &y, &width, &height);
|
||||
|
||||
if ('\0'==szMapName[0])
|
||||
continue;
|
||||
|
||||
TMapInfo kMapInfo;
|
||||
kMapInfo.m_strName = szMapName;
|
||||
kMapInfo.m_dwBaseX = x;
|
||||
kMapInfo.m_dwBaseY = y;
|
||||
|
||||
kMapInfo.m_dwSizeX = width;
|
||||
kMapInfo.m_dwSizeY = height;
|
||||
|
||||
kMapInfo.m_dwEndX = kMapInfo.m_dwBaseX + kMapInfo.m_dwSizeX * CTerrainImpl::TERRAIN_XSIZE;
|
||||
kMapInfo.m_dwEndY = kMapInfo.m_dwBaseY + kMapInfo.m_dwSizeY * CTerrainImpl::TERRAIN_YSIZE;
|
||||
|
||||
m_kVct_kMapInfo.push_back(kMapInfo);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,529 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapOutdoor.h"
|
||||
|
||||
void CMapOutdoor::SetIndexBuffer()
|
||||
{
|
||||
void * pIndices;
|
||||
long x, y;
|
||||
|
||||
DWORD dwIndexNum = TERRAIN_PATCHSIZE * TERRAIN_PATCHSIZE * 4;
|
||||
|
||||
#ifdef WORLD_EDITOR
|
||||
m_pwIndices = new WORD[dwIndexNum];
|
||||
if (!m_pwIndices)
|
||||
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer is NULL");
|
||||
|
||||
memset(m_pwIndices, 0, sizeof(WORD) * dwIndexNum);
|
||||
if (!m_IndexBuffer.Create(dwIndexNum, D3DFMT_INDEX16))
|
||||
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Create Error");
|
||||
|
||||
WORD count = 0;
|
||||
WORD count2 = 0;
|
||||
long ry = 0;
|
||||
|
||||
BYTE ucNumLineWarp = TERRAIN_PATCHSIZE + 1;
|
||||
|
||||
for (y = 0; y < TERRAIN_PATCHSIZE; y++)
|
||||
{
|
||||
if (ry % 2 == 0)
|
||||
{
|
||||
m_pwIndices[count++] = count2;
|
||||
m_pwIndices[count++] = count2+ucNumLineWarp;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pwIndices[count++] = count2+ucNumLineWarp;
|
||||
m_pwIndices[count++] = count2;
|
||||
}
|
||||
|
||||
for (x = 0; x < TERRAIN_PATCHSIZE; x++)
|
||||
{
|
||||
if (ry % 2 == 1)
|
||||
{
|
||||
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp-1);
|
||||
m_pwIndices[count++] = (WORD) (count2-1);
|
||||
count2 -= (short) 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pwIndices[count++] = (WORD) (count2+1);
|
||||
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp+1);
|
||||
count2 += (short) 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (y < TERRAIN_PATCHSIZE-1)
|
||||
{
|
||||
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp);
|
||||
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp);
|
||||
count2 += ucNumLineWarp;
|
||||
}
|
||||
ry++;
|
||||
}
|
||||
|
||||
m_wNumIndices = count;
|
||||
if (!m_IndexBuffer.Lock((void **) &pIndices))
|
||||
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Unlock Error");
|
||||
memcpy(pIndices, m_pwIndices, count * sizeof(WORD));
|
||||
m_IndexBuffer.Unlock();
|
||||
|
||||
delete [] m_pwIndices;
|
||||
m_pwIndices = NULL;
|
||||
#else
|
||||
WORD count[TERRAINPATCH_LODMAX], count2[TERRAINPATCH_LODMAX];
|
||||
BYTE uci;
|
||||
for (uci = 0; uci < TERRAINPATCH_LODMAX; ++uci)
|
||||
{
|
||||
m_pwaIndices[uci] = new WORD[dwIndexNum];
|
||||
memset(m_pwaIndices[uci], 0, sizeof(WORD) * dwIndexNum);
|
||||
count[uci] = 0;
|
||||
count2[uci] = 0;
|
||||
if ( !m_IndexBuffer[uci].Create(dwIndexNum, D3DFMT_INDEX16) )
|
||||
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Create Error");
|
||||
}
|
||||
|
||||
BYTE ucNumLineWarp = TERRAIN_PATCHSIZE + 1;
|
||||
|
||||
for (y = 0; y < TERRAIN_PATCHSIZE; y++)
|
||||
{
|
||||
if (y%2 == 0)
|
||||
{
|
||||
m_pwaIndices[0][(count[0])++] = count2[0];
|
||||
m_pwaIndices[0][(count[0])++] = count2[0]+ucNumLineWarp;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pwaIndices[0][(count[0])++] = count2[0]+ucNumLineWarp;
|
||||
m_pwaIndices[0][(count[0])++] = count2[0];
|
||||
}
|
||||
|
||||
for (x = 0; x < TERRAIN_PATCHSIZE; x++)
|
||||
{
|
||||
if (y%2 == 0)
|
||||
{
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+1);
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp+1);
|
||||
count2[0] += (short) 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp-1);
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]-1);
|
||||
count2[0] -= (short) 1;
|
||||
}
|
||||
|
||||
if (0 == x%2)
|
||||
{
|
||||
if (0 == y)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl1TL(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 2) == x)
|
||||
ADDLvl1TR(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl1T(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
}
|
||||
else if ((TERRAIN_PATCHSIZE - 2) == y)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl1BL(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 2) == x)
|
||||
ADDLvl1BR(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl1B(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
}
|
||||
else if (0 == y%2)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl1L(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 2) == x)
|
||||
ADDLvl1R(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl1M(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
}
|
||||
count2[1] += 2;
|
||||
}
|
||||
|
||||
if (0 == x%4)
|
||||
{
|
||||
if (0 == y)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl2TL(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 4) == x)
|
||||
ADDLvl2TR(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl2T(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
}
|
||||
else if ((TERRAIN_PATCHSIZE - 4) == y)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl2BL(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 4) == x)
|
||||
ADDLvl2BR(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl2B(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
}
|
||||
else if (0 == y%4)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl2L(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 4) == x)
|
||||
ADDLvl2R(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl2M(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
}
|
||||
count2[2] += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (y < TERRAIN_PATCHSIZE-1)
|
||||
{
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp);
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp);
|
||||
count2[0] += ucNumLineWarp;
|
||||
if (0 == y%2)
|
||||
count2[1] += 2;
|
||||
if (0 == y%4)
|
||||
count2[2] += 4;
|
||||
}
|
||||
}
|
||||
|
||||
for (uci = 0; uci < TERRAINPATCH_LODMAX; ++uci)
|
||||
{
|
||||
m_wNumIndices[uci] = count[uci];
|
||||
if( !m_IndexBuffer[uci].Lock((void **) &pIndices) )
|
||||
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Unlock Error");
|
||||
memcpy(pIndices, m_pwaIndices[uci], count[uci] * sizeof(WORD));
|
||||
m_IndexBuffer[uci].Unlock();
|
||||
delete [] m_pwaIndices[uci];
|
||||
m_pwaIndices[uci] = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1TL(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1T(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
ADDLvl1L(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
ADDLvl1M(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1T(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1T(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1T(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1TR(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
ADDLvl1M(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
ADDLvl1R(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1L(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1L(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 2;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1R(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
ADDLvl1R(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 2;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1L(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1M(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
ADDLvl1BL(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 4;
|
||||
|
||||
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1M(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1R(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
ADDLvl1BR(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
}
|
||||
@@ -0,0 +1,544 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapOutdoor.h"
|
||||
#include "AreaTerrain.h"
|
||||
#include "AreaLoaderThread.h"
|
||||
#include "../EterLib/ResourceManager.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
|
||||
//CAreaLoaderThread CMapOutdoor::ms_AreaLoaderThread;
|
||||
|
||||
bool CMapOutdoor::Load(float x, float y, float z)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
CEterPackManager& rkPackMgr=CEterPackManager::Instance();
|
||||
{
|
||||
static std::string s_strOldPathName="";
|
||||
|
||||
// 2004.08.09.myevan.Pack파일을 찾을때.. 폴더명만으로는 그냥 리턴되는 부분이 있다
|
||||
std::string c_rstrNewPathName=GetName()+"\\cache";
|
||||
|
||||
s_strOldPathName=c_rstrNewPathName;
|
||||
}
|
||||
|
||||
std::string strFileName = GetMapDataDirectory() + "\\Setting.txt";
|
||||
|
||||
if (!LoadSetting(strFileName.c_str()))
|
||||
TraceError("CMapOutdoor::Load : LoadSetting(%s) Failed", strFileName.c_str());
|
||||
|
||||
#ifdef WORLD_EDITOR
|
||||
if (!LoadMonsterAreaInfo())
|
||||
TraceError("CMapOutdoor::Load - LoadMonsterAreaInfo ERROR");
|
||||
#endif
|
||||
|
||||
CreateTerrainPatchProxyList();
|
||||
BuildQuadTree();
|
||||
LoadWaterTexture();
|
||||
CreateCharacterShadowTexture();
|
||||
|
||||
m_lOldReadX = -1;
|
||||
|
||||
// TODO: SetRenderingDevice에서 Environment로 부터 라이트 속성을 넘겨줘야 스태틱 라이트가 제대로 작동한다.
|
||||
CSpeedTreeForestDirectX8::Instance().SetRenderingDevice(ms_lpd3dDevice);
|
||||
|
||||
Update(x, y, z);
|
||||
|
||||
__HeightCache_Init();
|
||||
|
||||
// LOCAL_ENVIRONMENT_DATA
|
||||
std::string local_envDataName = GetMapDataDirectory() + "\\" + m_settings_envDataName;
|
||||
if (rkPackMgr.isExist(local_envDataName.c_str()))
|
||||
{
|
||||
m_envDataName = local_envDataName;
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string& c_rstrEnvironmentRoot = "d:/ymir work/environment/";
|
||||
const std::string& c_rstrMapName = GetName();
|
||||
m_envDataName = c_rstrEnvironmentRoot + m_settings_envDataName;
|
||||
|
||||
if (0 == m_envDataName.compare(c_rstrEnvironmentRoot))
|
||||
{
|
||||
const std::string& strAppendName = c_rstrMapName.substr(c_rstrMapName.size() - 2, 2);
|
||||
m_envDataName = c_rstrEnvironmentRoot + strAppendName + ".msenv";
|
||||
}
|
||||
}
|
||||
// LOCAL_ENVIRONMENT_DATA_END
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string& CMapOutdoor::GetEnvironmentDataName()
|
||||
{
|
||||
return m_envDataName;
|
||||
}
|
||||
|
||||
|
||||
bool CMapOutdoor::isTerrainLoaded(WORD wX, WORD wY)
|
||||
{
|
||||
for (DWORD i = 0; i < m_TerrainVector.size(); ++i)
|
||||
{
|
||||
CTerrain * pTerrain = m_TerrainVector[i];
|
||||
WORD usCoordX, usCoordY;
|
||||
pTerrain->GetCoordinate(&usCoordX, &usCoordY);
|
||||
|
||||
if (usCoordX == wX && usCoordY == wY)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMapOutdoor::isAreaLoaded(WORD wX, WORD wY)
|
||||
{
|
||||
for (DWORD i = 0; i < m_AreaVector.size(); ++i)
|
||||
{
|
||||
CArea * pArea = m_AreaVector[i];
|
||||
WORD usCoordX, usCoordY;
|
||||
pArea->GetCoordinate(&usCoordX, &usCoordY);
|
||||
|
||||
if (usCoordX == wX && usCoordY == wY)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// 현재 좌표를 기반으로 주위(ex. 3x3)에 있는 Terrain과 Area포인터를
|
||||
// m_pTerrain과 m_pArea에 연결한다.
|
||||
void CMapOutdoor::AssignTerrainPtr()
|
||||
{
|
||||
// 월드에디터에서 화면을 죽죽죽 넘길 때 터레인을 저장해야 하기
|
||||
// 때문에 이 virtual method를 호출 한다. 이 메소드는 CMapOutDoor에서는 아무 행동도
|
||||
// 하지 않는다.
|
||||
OnPreAssignTerrainPtr();
|
||||
|
||||
short sReferenceCoordMinX, sReferenceCoordMaxX, sReferenceCoordMinY, sReferenceCoordMaxY;
|
||||
sReferenceCoordMinX = max(m_CurCoordinate.m_sTerrainCoordX - LOAD_SIZE_WIDTH, 0);
|
||||
sReferenceCoordMaxX = min(m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH, m_sTerrainCountX - 1);
|
||||
sReferenceCoordMinY = max(m_CurCoordinate.m_sTerrainCoordY - LOAD_SIZE_WIDTH, 0);
|
||||
sReferenceCoordMaxY = min(m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH, m_sTerrainCountY - 1);
|
||||
|
||||
DWORD i;
|
||||
for (i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
m_pArea[i] = NULL;
|
||||
m_pTerrain[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < m_TerrainVector.size(); ++i)
|
||||
{
|
||||
CTerrain * pTerrain = m_TerrainVector[i];
|
||||
WORD usCoordX, usCoordY;
|
||||
pTerrain->GetCoordinate(&usCoordX, &usCoordY);
|
||||
|
||||
if (usCoordX >= sReferenceCoordMinX &&
|
||||
usCoordX <= sReferenceCoordMaxX &&
|
||||
usCoordY >= sReferenceCoordMinY &&
|
||||
usCoordY <= sReferenceCoordMaxY)
|
||||
{
|
||||
m_pTerrain[(usCoordY - m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH) * 3 +
|
||||
(usCoordX - m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH) ] = pTerrain;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < m_AreaVector.size(); ++i)
|
||||
{
|
||||
CArea * pArea = m_AreaVector[i];
|
||||
WORD usCoordX, usCoordY;
|
||||
pArea->GetCoordinate(&usCoordX, &usCoordY);
|
||||
|
||||
if (usCoordX >= sReferenceCoordMinX &&
|
||||
usCoordX <= sReferenceCoordMaxX &&
|
||||
usCoordY >= sReferenceCoordMinY &&
|
||||
usCoordY <= sReferenceCoordMaxY)
|
||||
{
|
||||
m_pArea[(usCoordY - m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH) * 3 +
|
||||
(usCoordX - m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH) ] = pArea;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CMapOutdoor::LoadArea(WORD wAreaCoordX, WORD wAreaCoordY, WORD wCellCoordX, WORD wCellCoordY)
|
||||
{
|
||||
if (isAreaLoaded(wAreaCoordX, wAreaCoordY))
|
||||
return true;
|
||||
#ifdef _DEBUG
|
||||
DWORD dwStartTime = ELTimer_GetMSec();
|
||||
#endif
|
||||
unsigned long ulID = (unsigned long) (wAreaCoordX) * 1000L + (unsigned long) (wAreaCoordY);
|
||||
char szAreaPathName[64+1];
|
||||
_snprintf(szAreaPathName, sizeof(szAreaPathName), "%s\\%06u\\", GetMapDataDirectory().c_str(), ulID);
|
||||
|
||||
CArea * pArea = CArea::New();
|
||||
pArea->SetMapOutDoor(this);
|
||||
#ifdef _DEBUG
|
||||
Tracef("CMapOutdoor::LoadArea1 %d\n", ELTimer_GetMSec() - dwStartTime);
|
||||
dwStartTime = ELTimer_GetMSec();
|
||||
#endif
|
||||
|
||||
pArea->SetCoordinate(wAreaCoordX, wAreaCoordY);
|
||||
if ( !pArea->Load(szAreaPathName) )
|
||||
TraceError(" CMapOutdoor::LoadArea(%d, %d) LoadShadowMap ERROR", wAreaCoordX, wAreaCoordY);
|
||||
#ifdef _DEBUG
|
||||
Tracef("CMapOutdoor::LoadArea2 %d\n", ELTimer_GetMSec() - dwStartTime);
|
||||
dwStartTime = ELTimer_GetMSec();
|
||||
#endif
|
||||
|
||||
m_AreaVector.push_back(pArea);
|
||||
|
||||
pArea->EnablePortal(m_bEnablePortal);
|
||||
#ifdef _DEBUG
|
||||
Tracef("CMapOutdoor::LoadArea3 %d\n", ELTimer_GetMSec() - dwStartTime);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapOutdoor::LoadTerrain(WORD wTerrainCoordX, WORD wTerrainCoordY, WORD wCellCoordX, WORD wCellCoordY)
|
||||
{
|
||||
if (isTerrainLoaded(wTerrainCoordX, wTerrainCoordY))
|
||||
return true;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
DWORD dwStartTime = ELTimer_GetMSec();
|
||||
|
||||
unsigned long ulID = (unsigned long) (wTerrainCoordX) * 1000L + (unsigned long) (wTerrainCoordY);
|
||||
char filename[256];
|
||||
sprintf(filename, "%s\\%06u\\AreaProperty.txt", GetMapDataDirectory().c_str(), ulID);
|
||||
|
||||
CTokenVectorMap stTokenVectorMap;
|
||||
|
||||
if (!LoadMultipleTextData(filename, stTokenVectorMap))
|
||||
{
|
||||
TraceError("CMapOutdoor::LoadTerrain AreaProperty Read Error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype"))
|
||||
{
|
||||
TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 1\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("areaname"))
|
||||
{
|
||||
TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 2\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string & c_rstrType = stTokenVectorMap["scripttype"][0];
|
||||
const std::string & c_rstrAreaName = stTokenVectorMap["areaname"][0];
|
||||
|
||||
if (c_rstrType != "AreaProperty")
|
||||
{
|
||||
TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 3\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CTerrain * pTerrain = CTerrain::New();
|
||||
|
||||
pTerrain->Clear();
|
||||
pTerrain->SetMapOutDoor(this);
|
||||
|
||||
pTerrain->SetCoordinate(wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
pTerrain->CopySettingFromGlobalSetting();
|
||||
|
||||
char szRawHeightFieldname[64+1];
|
||||
char szWaterMapName[64+1];
|
||||
char szAttrMapName[64+1];
|
||||
char szShadowTexName[64+1];
|
||||
char szShadowMapName[64+1];
|
||||
char szMiniMapTexName[64+1];
|
||||
char szSplatName[64+1];
|
||||
|
||||
_snprintf(szRawHeightFieldname, sizeof(szRawHeightFieldname), "%s\\%06u\\height.raw", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szSplatName, sizeof(szSplatName), "%s\\%06u\\tile.raw", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szAttrMapName, sizeof(szAttrMapName), "%s\\%06u\\attr.atr", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szWaterMapName, sizeof(szWaterMapName), "%s\\%06u\\water.wtr", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szShadowTexName, sizeof(szShadowTexName), "%s\\%06u\\shadowmap.dds", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szShadowMapName, sizeof(szShadowMapName), "%s\\%06u\\shadowmap.raw", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szMiniMapTexName, sizeof(szMiniMapTexName), "%s\\%06u\\minimap.dds", GetMapDataDirectory().c_str(), ulID);
|
||||
|
||||
if(!pTerrain->LoadWaterMap(szWaterMapName))
|
||||
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadWaterMap ERROR", wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
if (!pTerrain->LoadHeightMap(szRawHeightFieldname))
|
||||
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadHeightMap ERROR", wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
if (!pTerrain->LoadAttrMap(szAttrMapName))
|
||||
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadAttrMap ERROR", wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
if (!pTerrain->RAW_LoadTileMap(szSplatName))
|
||||
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) RAW_LoadTileMap ERROR", wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
pTerrain->LoadShadowTexture(szShadowTexName);
|
||||
|
||||
if (!pTerrain->LoadShadowMap(szShadowMapName))
|
||||
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadShadowMap ERROR", wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
pTerrain->LoadMiniMapTexture(szMiniMapTexName);
|
||||
pTerrain->SetName(c_rstrAreaName.c_str());
|
||||
pTerrain->CalculateTerrainPatch();
|
||||
|
||||
pTerrain->SetReady();
|
||||
|
||||
Tracef("CMapOutdoor::LoadTerrain %d\n", ELTimer_GetMSec() - dwStartTime);
|
||||
|
||||
m_TerrainVector.push_back(pTerrain);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapOutdoor::LoadSetting(const char * c_szFileName)
|
||||
{
|
||||
NANOBEGIN
|
||||
CTokenVectorMap stTokenVectorMap;
|
||||
|
||||
if (!LoadMultipleTextData(c_szFileName, stTokenVectorMap))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - LoadMultipleTextData", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'scripttype' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("viewradius"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'viewradius' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("cellscale"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'cellscale' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("heightscale"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'heightscale' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("mapsize"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'mapsize' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("textureset"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'textureset' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() != stTokenVectorMap.find("terrainvisible"))
|
||||
{
|
||||
m_bSettingTerrainVisible = (bool) (atoi(stTokenVectorMap["terrainvisible"][0].c_str()) != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bSettingTerrainVisible = true;
|
||||
}
|
||||
|
||||
const std::string & c_rstrType = stTokenVectorMap["scripttype"][0];
|
||||
const std::string & c_rstrViewRadius = stTokenVectorMap["viewradius"][0];
|
||||
//const std::string & c_rstrCellScale = stTokenVectorMap["cellscale"][0];
|
||||
const std::string & c_rstrHeightScale = stTokenVectorMap["heightscale"][0];
|
||||
const std::string & c_rstrMapSizeX = stTokenVectorMap["mapsize"][0];
|
||||
const std::string & c_rstrMapSizeY = stTokenVectorMap["mapsize"][1];
|
||||
|
||||
std::string strTextureSet;
|
||||
TTokenVector & rkVec_strToken = stTokenVectorMap["textureset"];
|
||||
if (!rkVec_strToken.empty())
|
||||
{
|
||||
strTextureSet = rkVec_strToken[0];
|
||||
}
|
||||
|
||||
if (c_rstrType != "MapSetting")
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - Resourse Type ERROR", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_lViewRadius = atol(c_rstrViewRadius.c_str());
|
||||
|
||||
#ifdef WORLD_EDITOR
|
||||
m_lViewRadius <<= 1;
|
||||
#endif
|
||||
|
||||
if (0L >= m_lViewRadius)
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - VIEWRADIUS IS NOT GREATER THAN 0", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_fHeightScale = atof(c_rstrHeightScale.c_str());
|
||||
|
||||
SetTerrainCount(atoi(c_rstrMapSizeX.c_str()), atoi(c_rstrMapSizeY.c_str()));
|
||||
|
||||
m_fTerrainTexCoordBase = 1.0f / (float) (CTerrainImpl::PATCH_XSIZE * CTerrainImpl::CELLSCALE);
|
||||
|
||||
if (stTokenVectorMap.end() != stTokenVectorMap.find("baseposition"))
|
||||
{
|
||||
const std::string & c_rstrMapBaseX = stTokenVectorMap["baseposition"][0];
|
||||
const std::string & c_rstrMapBaseY = stTokenVectorMap["baseposition"][1];
|
||||
SetBaseXY((DWORD)atol(c_rstrMapBaseX.c_str()), (DWORD)atol(c_rstrMapBaseY.c_str()));
|
||||
}
|
||||
|
||||
std::string stTextureSetFileName = strTextureSet;
|
||||
|
||||
// TextureSet 이 이미 붙어 있을 경우 안붙인다.
|
||||
if (0 != stTextureSetFileName.find_first_of("textureset", 0))
|
||||
stTextureSetFileName = "textureset\\"+strTextureSet;
|
||||
|
||||
if (!m_TextureSet.Load(stTextureSetFileName.c_str(), m_fTerrainTexCoordBase))
|
||||
{
|
||||
#ifdef WORLD_EDITOR
|
||||
// TextureSet 이 적용되어 있지 않아도 진행
|
||||
LogBox("TextureSet \300\314 \300\373\277\353\265\307\276\356\300\326\301\366 \276\312\300\272 \270\312 \300\324\264\317\264\331.\n\301\366\307\374 \305\330\275\272\303\347 \300\333\276\367\277\241 \301\326\300\307\307\317\275\303\261\342 \271\331\266\370\264\317\264\331.");
|
||||
#else
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - LOAD TEXTURE SET(%s) ERROR", c_szFileName, stTextureSetFileName.c_str());
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
CTerrain::SetTextureSet(&m_TextureSet);
|
||||
|
||||
if (stTokenVectorMap.end() != stTokenVectorMap.find("environment"))
|
||||
{
|
||||
const CTokenVector & c_rEnvironmentVector = stTokenVectorMap["environment"];
|
||||
if (!c_rEnvironmentVector.empty())
|
||||
m_settings_envDataName = c_rEnvironmentVector[0];
|
||||
else
|
||||
TraceError("CMapOutdoor::LoadSetting(c_szFileName=%s) - Failed to load environment data\n", c_szFileName);
|
||||
}
|
||||
|
||||
m_fWaterTexCoordBase = 1.0f / (float)(CTerrainImpl::CELLSCALE * 4);
|
||||
|
||||
D3DXMatrixScaling(&m_matSplatAlpha,
|
||||
+m_fTerrainTexCoordBase * 2.0f * (float)(CTerrainImpl::PATCH_XSIZE) / (float)(CTerrainImpl::SPLATALPHA_RAW_XSIZE-2),
|
||||
-m_fTerrainTexCoordBase * 2.0f * (float)(CTerrainImpl::PATCH_YSIZE) / (float)(CTerrainImpl::SPLATALPHA_RAW_XSIZE-2),
|
||||
0.0f);
|
||||
m_matSplatAlpha._41 = m_fTerrainTexCoordBase * 4.6f;
|
||||
m_matSplatAlpha._42 = m_fTerrainTexCoordBase * 4.6f;
|
||||
|
||||
D3DXMatrixScaling(&m_matStaticShadow,
|
||||
+m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_XSIZE / static_cast<float>(CTerrainImpl::XSIZE)),
|
||||
-m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_YSIZE / static_cast<float>(CTerrainImpl::XSIZE)),
|
||||
0.0f);
|
||||
m_matStaticShadow._41 = 0.0f;
|
||||
m_matStaticShadow._42 = 0.0f;
|
||||
|
||||
D3DXMatrixScaling(&m_matDynamicShadowScale, 1.0f / 2550.0f, -1.0f / 2550.0f, 1.0f);
|
||||
m_matDynamicShadowScale._41 = 0.5f;
|
||||
m_matDynamicShadowScale._42 = 0.5f;
|
||||
|
||||
// Transform
|
||||
D3DXMatrixScaling(&m_matBuildingTransparent, 1.0f / ((float)ms_iWidth), -1.0f / ((float)ms_iHeight), 1.0f);
|
||||
m_matBuildingTransparent._41 = 0.5f;
|
||||
m_matBuildingTransparent._42 = 0.5f;
|
||||
NANOEND
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CMapOutdoor::LoadMonsterAreaInfo()
|
||||
{
|
||||
RemoveAllMonsterAreaInfo();
|
||||
|
||||
char c_szFileName[256];
|
||||
sprintf(c_szFileName, "%s\\regen.txt", GetMapDataDirectory().c_str());
|
||||
|
||||
LPCVOID pModelData;
|
||||
CMappedFile File;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pModelData))
|
||||
{
|
||||
//TraceError(" CMapOutdoorAccessor::LoadMonsterAreaInfo Load File %s ERROR", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
CTokenVector stTokenVector;
|
||||
|
||||
textFileLoader.Bind(File.Size(), pModelData);
|
||||
|
||||
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
if (!textFileLoader.SplitLine(i, &stTokenVector))
|
||||
continue;
|
||||
|
||||
stl_lowers(stTokenVector[0]);
|
||||
|
||||
// Start or End
|
||||
if (0 == stTokenVector[0].compare("m") || 0 == stTokenVector[0].compare("g"))
|
||||
{
|
||||
if (stTokenVector.size() < 11)
|
||||
{
|
||||
TraceError("CMapOutdoorAccessor::LoadMonsterAreaInfo Get MonsterInfo File Format ERROR! continue....");
|
||||
continue;
|
||||
}
|
||||
|
||||
CMonsterAreaInfo::EMonsterAreaInfoType eMonsterAreaInfoType;
|
||||
if (0 == stTokenVector[0].compare("m"))
|
||||
{
|
||||
eMonsterAreaInfoType = CMonsterAreaInfo::MONSTERAREAINFOTYPE_MONSTER;
|
||||
}
|
||||
else if (0 == stTokenVector[0].compare("g"))
|
||||
{
|
||||
eMonsterAreaInfoType = CMonsterAreaInfo::MONSTERAREAINFOTYPE_GROUP;
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceError("CMapOutdoorAccessor::LoadMonsterAreaInfo Get MonsterInfo Data ERROR! continue....");
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string & c_rstrOriginX = stTokenVector[1].c_str();
|
||||
const std::string & c_rstrOriginY = stTokenVector[2].c_str();
|
||||
const std::string & c_rstrSizeX = stTokenVector[3].c_str();
|
||||
const std::string & c_rstrSizeY = stTokenVector[4].c_str();
|
||||
const std::string & c_rstrZ = stTokenVector[5].c_str();
|
||||
const std::string & c_rstrDir = stTokenVector[6].c_str();
|
||||
const std::string & c_rstrTime = stTokenVector[7].c_str();
|
||||
const std::string & c_rstrPercent = stTokenVector[8].c_str();
|
||||
const std::string & c_rstrCount = stTokenVector[9].c_str();
|
||||
const std::string & c_rstrVID = stTokenVector[10].c_str();
|
||||
|
||||
long lOriginX, lOriginY, lSizeX, lSizeY, lZ, lTime, lPercent;
|
||||
CMonsterAreaInfo::EMonsterDir eMonsterDir;
|
||||
DWORD dwMonsterCount;
|
||||
DWORD dwMonsterVID;
|
||||
|
||||
lOriginX = atol(c_rstrOriginX.c_str());
|
||||
lOriginY = atol(c_rstrOriginY.c_str());
|
||||
lSizeX = atol(c_rstrSizeX.c_str());
|
||||
lSizeY = atol(c_rstrSizeY.c_str());
|
||||
lZ = atol(c_rstrZ.c_str());
|
||||
eMonsterDir = (CMonsterAreaInfo::EMonsterDir) atoi(c_rstrDir.c_str());
|
||||
lTime = atol(c_rstrTime.c_str());
|
||||
lPercent = atol(c_rstrPercent.c_str());
|
||||
dwMonsterCount = (DWORD) atoi(c_rstrCount.c_str());
|
||||
dwMonsterVID = (DWORD) atoi(c_rstrVID.c_str());
|
||||
|
||||
// lOriginX -= m_dwBaseX / 100;
|
||||
// lOriginY -= m_dwBaseY / 100;
|
||||
|
||||
CMonsterAreaInfo * pMonsterAreaInfo = AddMonsterAreaInfo(lOriginX, lOriginY, lSizeX, lSizeY);
|
||||
pMonsterAreaInfo->SetMonsterAreaInfoType(eMonsterAreaInfoType);
|
||||
if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_MONSTER == eMonsterAreaInfoType)
|
||||
pMonsterAreaInfo->SetMonsterVID(dwMonsterVID);
|
||||
else if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_GROUP == eMonsterAreaInfoType)
|
||||
pMonsterAreaInfo->SetMonsterGroupID(dwMonsterVID);
|
||||
pMonsterAreaInfo->SetMonsterCount(dwMonsterCount);
|
||||
pMonsterAreaInfo->SetMonsterDirection(eMonsterDir);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapOutdoor.h"
|
||||
#include "TerrainQuadtree.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// QuadTree
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CMapOutdoor::BuildQuadTree()
|
||||
{
|
||||
FreeQuadTree();
|
||||
|
||||
// m_wPatchCount는 ConvertPatchSplat에서도 정한다, 안전을 위해 여기서 체크한다.
|
||||
if (0 == m_wPatchCount)
|
||||
{
|
||||
TraceError("MapOutdoor::BuildQuadTree : m_wPatchCount is zero, you must call ConvertPatchSplat before call this method.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_pRootNode = AllocQuadTreeNode(0, 0, m_wPatchCount - 1, m_wPatchCount - 1);
|
||||
if (!m_pRootNode)
|
||||
TraceError("CMapOutdoor::BuildQuadTree() RootNode is NULL");
|
||||
|
||||
if (m_pRootNode->Size > 1)
|
||||
SubDivideNode(m_pRootNode);
|
||||
}
|
||||
|
||||
CTerrainQuadtreeNode * CMapOutdoor::AllocQuadTreeNode(long x0, long y0, long x1, long y1)
|
||||
{
|
||||
CTerrainQuadtreeNode * Node;
|
||||
long xsize, ysize;
|
||||
|
||||
xsize = x1-x0+1;
|
||||
ysize = y1-y0+1;
|
||||
if ((xsize == 0) || (ysize == 0))
|
||||
return NULL;
|
||||
|
||||
Node = new CTerrainQuadtreeNode;
|
||||
Node->x0 = x0;
|
||||
Node->y0 = y0;
|
||||
Node->x1 = x1;
|
||||
Node->y1 = y1;
|
||||
|
||||
if (ysize > xsize)
|
||||
Node->Size = ysize;
|
||||
else
|
||||
Node->Size = xsize;
|
||||
|
||||
Node->PatchNum = y0 * m_wPatchCount + x0;
|
||||
|
||||
/*
|
||||
const float fTerrainMin = -(float) (m_lViewRadius * m_lCellScale);
|
||||
|
||||
minx = fTerrainMin + x0 * c_byPatchSize * m_lCellScale;
|
||||
maxx = fTerrainMin + (x1 + 1) * c_byPatchSize * m_lCellScale;
|
||||
miny = fTerrainMin + y0 * c_byPatchSize * m_lCellScale;
|
||||
maxy = fTerrainMin + (y1 + 1) * c_byPatchSize * m_lCellScale;
|
||||
minz = 0.0f;
|
||||
maxz = 0.0f;
|
||||
|
||||
/ * Set up 8 vertices that belong to the bounding box * /
|
||||
Node->center.x = minx + (maxx - minx) * 0.5f;
|
||||
Node->center.y = miny + (maxy - miny) * 0.5f;
|
||||
Node->center.z = minz + (maxz - minz) * 0.5f;
|
||||
|
||||
Node->radius = sqrtf(
|
||||
(maxx-minx)*(maxx-minx)+
|
||||
(maxy-miny)*(maxy-miny)+
|
||||
(maxz-minz)*(maxz-minz)
|
||||
)/2.0f;
|
||||
*/
|
||||
|
||||
Node->center.x = 0.0f;
|
||||
Node->center.y = 0.0f;
|
||||
Node->center.z = 0.0f;
|
||||
|
||||
Node->radius = 0.0f;
|
||||
|
||||
return Node;
|
||||
}
|
||||
|
||||
|
||||
void CMapOutdoor::SubDivideNode(CTerrainQuadtreeNode * Node)
|
||||
{
|
||||
long nw_size;
|
||||
CTerrainQuadtreeNode * tempnode;
|
||||
|
||||
nw_size = Node->Size / 2;
|
||||
|
||||
Node->NW_Node = AllocQuadTreeNode (Node->x0, Node->y0, Node->x0 + nw_size-1, Node->y0 + nw_size-1);
|
||||
Node->NE_Node = AllocQuadTreeNode (Node->x0 + nw_size, Node->y0, Node->x1, Node->y0 + nw_size-1);
|
||||
Node->SW_Node = AllocQuadTreeNode (Node->x0, Node->y0 + nw_size, Node->x0 + nw_size-1, Node->y1);
|
||||
Node->SE_Node = AllocQuadTreeNode (Node->x0 + nw_size, Node->y0 + nw_size, Node->x1, Node->y1);
|
||||
|
||||
tempnode = (CTerrainQuadtreeNode *) Node->NW_Node;
|
||||
if ((tempnode != NULL) && (tempnode->Size > 1))
|
||||
SubDivideNode (tempnode);
|
||||
tempnode = (CTerrainQuadtreeNode *) Node->NE_Node;
|
||||
if ((tempnode != NULL) && (tempnode->Size > 1))
|
||||
SubDivideNode (tempnode);
|
||||
tempnode = (CTerrainQuadtreeNode *) Node->SW_Node;
|
||||
if ((tempnode != NULL) && (tempnode->Size > 1))
|
||||
SubDivideNode (tempnode);
|
||||
tempnode = (CTerrainQuadtreeNode *) Node->SE_Node;
|
||||
if ((tempnode != NULL) && (tempnode->Size > 1))
|
||||
SubDivideNode (tempnode);
|
||||
}
|
||||
|
||||
/*
|
||||
void CMapOutdoor::RecurseDeleteQuadTree(CTerrainQuadtreeNode *Node)
|
||||
{
|
||||
if (Node == NULL)
|
||||
return;
|
||||
|
||||
if (Node->NW_Node != NULL)
|
||||
{
|
||||
RecurseDeleteQuadTree(Node->NW_Node);
|
||||
Node->NW_Node = NULL;
|
||||
}
|
||||
if (Node->NE_Node != NULL)
|
||||
{
|
||||
RecurseDeleteQuadTree(Node->NE_Node);
|
||||
Node->NE_Node = NULL;
|
||||
}
|
||||
if (Node->SW_Node != NULL)
|
||||
{
|
||||
RecurseDeleteQuadTree(Node->SW_Node);
|
||||
Node->SW_Node = NULL;
|
||||
}
|
||||
if (Node->SE_Node != NULL)
|
||||
{
|
||||
RecurseDeleteQuadTree(Node->SE_Node);
|
||||
Node->SE_Node = NULL;
|
||||
}
|
||||
|
||||
free(Node);
|
||||
}
|
||||
*/
|
||||
|
||||
void CMapOutdoor::FreeQuadTree()
|
||||
{
|
||||
if (NULL == m_pRootNode)
|
||||
return;
|
||||
|
||||
if (m_pRootNode->NW_Node)
|
||||
{
|
||||
delete m_pRootNode->NW_Node;
|
||||
m_pRootNode->NW_Node = NULL;
|
||||
}
|
||||
if (m_pRootNode->NE_Node)
|
||||
{
|
||||
delete m_pRootNode->NE_Node;
|
||||
m_pRootNode->NE_Node = NULL;
|
||||
}
|
||||
if (m_pRootNode->SW_Node)
|
||||
{
|
||||
delete m_pRootNode->SW_Node;
|
||||
m_pRootNode->SW_Node = NULL;
|
||||
}
|
||||
if (m_pRootNode->SE_Node)
|
||||
{
|
||||
delete m_pRootNode->SE_Node;
|
||||
m_pRootNode->SE_Node = NULL;
|
||||
}
|
||||
|
||||
delete m_pRootNode;
|
||||
m_pRootNode = NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,964 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapOutdoor.h"
|
||||
#include "TerrainPatch.h"
|
||||
#include "AreaTerrain.h"
|
||||
#include "TerrainQuadtree.h"
|
||||
|
||||
#include "../EterLib/Camera.h"
|
||||
#include "../EterLib/StateManager.h"
|
||||
|
||||
|
||||
#define MAX_RENDER_SPALT 150
|
||||
|
||||
CArea::TCRCWithNumberVector m_dwRenderedCRCWithNumberVector;
|
||||
|
||||
CMapOutdoor::TTerrainNumVector CMapOutdoor::FSortPatchDrawStructWithTerrainNum::m_TerrainNumVector;
|
||||
|
||||
void CMapOutdoor::RenderTerrain()
|
||||
{
|
||||
if (!IsVisiblePart(PART_TERRAIN))
|
||||
return;
|
||||
|
||||
if (!m_bSettingTerrainVisible)
|
||||
return;
|
||||
|
||||
// Inserted by levites
|
||||
if (!m_pTerrainPatchProxyList)
|
||||
return;
|
||||
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCamera)
|
||||
return;
|
||||
|
||||
auto vv = ms_matView * ms_matProj;
|
||||
BuildViewFrustum(vv);
|
||||
|
||||
D3DXVECTOR3 v3Eye = pCamera->GetEye();
|
||||
m_fXforDistanceCaculation = -v3Eye.x;
|
||||
m_fYforDistanceCaculation = -v3Eye.y;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Push
|
||||
m_PatchVector.clear();
|
||||
|
||||
__RenderTerrain_RecurseRenderQuadTree(m_pRootNode);
|
||||
|
||||
// 거리순 정렬
|
||||
std::sort(m_PatchVector.begin(),m_PatchVector.end());
|
||||
|
||||
// 그리기 위한 벡터 세팅
|
||||
if (CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE)
|
||||
__RenderTerrain_RenderSoftwareTransformPatch();
|
||||
else
|
||||
__RenderTerrain_RenderHardwareTransformPatch();
|
||||
}
|
||||
|
||||
void CMapOutdoor::__RenderTerrain_RecurseRenderQuadTree(CTerrainQuadtreeNode *Node, bool bCullCheckNeed)
|
||||
{
|
||||
if (bCullCheckNeed)
|
||||
{
|
||||
switch (__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(Node->center, Node->radius))
|
||||
{
|
||||
case VIEW_ALL:
|
||||
// all child nodes need not cull check
|
||||
bCullCheckNeed = false;
|
||||
break;
|
||||
case VIEW_PART:
|
||||
break;
|
||||
case VIEW_NONE:
|
||||
// no need to render
|
||||
return;
|
||||
}
|
||||
// if no need cull check more
|
||||
// -> bCullCheckNeed = false;
|
||||
}
|
||||
|
||||
if (Node->Size == 1)
|
||||
{
|
||||
D3DXVECTOR3 v3Center = Node->center;
|
||||
float fDistance = fMAX(fabs(v3Center.x + m_fXforDistanceCaculation), fabs(-v3Center.y + m_fYforDistanceCaculation));
|
||||
__RenderTerrain_AppendPatch(v3Center, fDistance, Node->PatchNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Node->NW_Node != NULL)
|
||||
__RenderTerrain_RecurseRenderQuadTree(Node->NW_Node, bCullCheckNeed);
|
||||
if (Node->NE_Node != NULL)
|
||||
__RenderTerrain_RecurseRenderQuadTree(Node->NE_Node, bCullCheckNeed);
|
||||
if (Node->SW_Node != NULL)
|
||||
__RenderTerrain_RecurseRenderQuadTree(Node->SW_Node, bCullCheckNeed);
|
||||
if (Node->SE_Node != NULL)
|
||||
__RenderTerrain_RecurseRenderQuadTree(Node->SE_Node, bCullCheckNeed);
|
||||
}
|
||||
}
|
||||
|
||||
int CMapOutdoor::__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(const D3DXVECTOR3 & c_v3Center, const float & c_fRadius)
|
||||
{
|
||||
const int count = 6;
|
||||
|
||||
D3DXVECTOR3 center = c_v3Center;
|
||||
center.y = -center.y;
|
||||
|
||||
int i;
|
||||
|
||||
float distance[count];
|
||||
for(i = 0; i < count; ++i)
|
||||
{
|
||||
distance[i] = D3DXPlaneDotCoord(&m_plane[i], ¢er);
|
||||
if (distance[i] <= -c_fRadius)
|
||||
return VIEW_NONE;
|
||||
}
|
||||
|
||||
for(i = 0; i < count;++i)
|
||||
{
|
||||
if (distance[i] <= c_fRadius)
|
||||
return VIEW_PART;
|
||||
}
|
||||
|
||||
return VIEW_ALL;
|
||||
}
|
||||
|
||||
void CMapOutdoor::__RenderTerrain_AppendPatch(const D3DXVECTOR3& c_rv3Center, float fDistance, long lPatchNum)
|
||||
{
|
||||
assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__RenderTerrain_AppendPatch");
|
||||
if (!m_pTerrainPatchProxyList[lPatchNum].isUsed())
|
||||
return;
|
||||
|
||||
m_pTerrainPatchProxyList[lPatchNum].SetCenterPosition(c_rv3Center);
|
||||
m_PatchVector.push_back(std::make_pair(fDistance, lPatchNum));
|
||||
}
|
||||
|
||||
void CMapOutdoor::ApplyLight(DWORD dwVersion, const D3DLIGHT8& c_rkLight)
|
||||
{
|
||||
m_kSTPD.m_dwLightVersion=dwVersion;
|
||||
STATEMANAGER.SetLight(0, &c_rkLight);
|
||||
}
|
||||
|
||||
// 2004. 2. 17. myevan. 모든 부분을 보이게 초기화 한다
|
||||
void CMapOutdoor::InitializeVisibleParts()
|
||||
{
|
||||
m_dwVisiblePartFlags=0xffffffff;
|
||||
}
|
||||
|
||||
// 2004. 2. 17. myevan. 특정 부분을 보이게 하거나 감추는 함수
|
||||
void CMapOutdoor::SetVisiblePart(int ePart, bool isVisible)
|
||||
{
|
||||
DWORD dwMask=(1<<ePart);
|
||||
if (isVisible)
|
||||
{
|
||||
m_dwVisiblePartFlags|=dwMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwReverseMask=~dwMask;
|
||||
m_dwVisiblePartFlags&=dwReverseMask;
|
||||
}
|
||||
}
|
||||
|
||||
// 2004. 2. 17. myevan. 특정 부분이 보이는지 알아내는 함수
|
||||
bool CMapOutdoor::IsVisiblePart(int ePart)
|
||||
{
|
||||
DWORD dwMask=(1<<ePart);
|
||||
if (dwMask & m_dwVisiblePartFlags)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Splat 개수 제한
|
||||
void CMapOutdoor::SetSplatLimit(int iSplatNum)
|
||||
{
|
||||
m_iSplatLimit = iSplatNum;
|
||||
}
|
||||
|
||||
std::vector<int> & CMapOutdoor::GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio)
|
||||
{
|
||||
*piPatch = m_iRenderedPatchNum;
|
||||
*piSplat = m_iRenderedSplatNum;
|
||||
*pfSplatRatio = m_iRenderedSplatNumSqSum/float(m_iRenderedPatchNum);
|
||||
|
||||
return m_RenderedTextureNumVector;
|
||||
}
|
||||
|
||||
CArea::TCRCWithNumberVector & CMapOutdoor::GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum)
|
||||
{
|
||||
*pdwGraphicThingInstanceNum = m_dwRenderedGraphicThingInstanceNum;
|
||||
*pdwCRCNum = m_dwRenderedCRCNum;
|
||||
|
||||
return m_dwRenderedCRCWithNumberVector;
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderBeforeLensFlare()
|
||||
{
|
||||
m_LensFlare.DrawBeforeFlare();
|
||||
|
||||
if (!mc_pEnvironmentData)
|
||||
{
|
||||
TraceError("CMapOutdoor::RenderBeforeLensFlare mc_pEnvironmentData is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
m_LensFlare.Compute(mc_pEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction);
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderAfterLensFlare()
|
||||
{
|
||||
m_LensFlare.AdjustBrightness();
|
||||
m_LensFlare.DrawFlare();
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderCollision()
|
||||
{
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(i, &pArea))
|
||||
pArea->RenderCollision();
|
||||
}
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderScreenFiltering()
|
||||
{
|
||||
m_ScreenFilter.Render();
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderSky()
|
||||
{
|
||||
if (IsVisiblePart(PART_SKY))
|
||||
m_SkyBox.Render();
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderCloud()
|
||||
{
|
||||
if (IsVisiblePart(PART_CLOUD))
|
||||
m_SkyBox.RenderCloud();
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderTree()
|
||||
{
|
||||
if (IsVisiblePart(PART_TREE))
|
||||
CSpeedTreeForestDirectX8::Instance().Render();
|
||||
}
|
||||
|
||||
void CMapOutdoor::SetInverseViewAndDynamicShaodwMatrices()
|
||||
{
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
|
||||
if (!pCamera)
|
||||
return;
|
||||
|
||||
m_matViewInverse = pCamera->GetInverseViewMatrix();
|
||||
|
||||
D3DXVECTOR3 v3Target = pCamera->GetTarget();
|
||||
|
||||
D3DXVECTOR3 v3LightEye(v3Target.x - 1.732f * 1250.0f,
|
||||
v3Target.y - 1250.0f,
|
||||
v3Target.z + 2.0f * 1.732f * 1250.0f);
|
||||
|
||||
const auto vv = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
D3DXMatrixLookAtRH(&m_matLightView, &v3LightEye, &v3Target, &vv);
|
||||
m_matDynamicShadow = m_matViewInverse * m_matLightView * m_matDynamicShadowScale;
|
||||
}
|
||||
|
||||
void CMapOutdoor::OnRender()
|
||||
{
|
||||
#ifdef __PERFORMANCE_CHECKER__
|
||||
DWORD t1=ELTimer_GetMSec();
|
||||
SetInverseViewAndDynamicShaodwMatrices();
|
||||
|
||||
SetBlendOperation();
|
||||
DWORD t2=ELTimer_GetMSec();
|
||||
RenderArea();
|
||||
DWORD t3=ELTimer_GetMSec();
|
||||
if (!m_bEnableTerrainOnlyForHeight)
|
||||
RenderTerrain();
|
||||
DWORD t4=ELTimer_GetMSec();
|
||||
RenderTree();
|
||||
DWORD t5=ELTimer_GetMSec();
|
||||
DWORD tEnd=ELTimer_GetMSec();
|
||||
|
||||
if (tEnd-t1<7)
|
||||
return;
|
||||
|
||||
static FILE* fp=fopen("perf_map_render.txt", "w");
|
||||
fprintf(fp, "MAP.Total %d (Time %d)\n", tEnd-t1, ELTimer_GetMSec());
|
||||
fprintf(fp, "MAP.ENV %d\n", t2-t1);
|
||||
fprintf(fp, "MAP.OBJ %d\n", t3-t2);
|
||||
fprintf(fp, "MAP.TRN %d\n", t4-t3);
|
||||
fprintf(fp, "MAP.TRE %d\n", t5-t4);
|
||||
|
||||
#else
|
||||
SetInverseViewAndDynamicShaodwMatrices();
|
||||
|
||||
SetBlendOperation();
|
||||
RenderArea();
|
||||
RenderTree();
|
||||
if (!m_bEnableTerrainOnlyForHeight)
|
||||
RenderTerrain();
|
||||
RenderBlendArea();
|
||||
#endif
|
||||
}
|
||||
|
||||
struct FAreaRenderShadow
|
||||
{
|
||||
void operator () (CGraphicObjectInstance * pInstance)
|
||||
{
|
||||
pInstance->RenderShadow();
|
||||
pInstance->Hide();
|
||||
}
|
||||
};
|
||||
|
||||
struct FPCBlockerHide
|
||||
{
|
||||
void operator () (CGraphicObjectInstance * pInstance)
|
||||
{
|
||||
pInstance->Hide();
|
||||
}
|
||||
};
|
||||
|
||||
struct FRenderPCBlocker
|
||||
{
|
||||
void operator () (CGraphicObjectInstance * pInstance)
|
||||
{
|
||||
pInstance->Show();
|
||||
CGraphicThingInstance* pThingInstance = dynamic_cast <CGraphicThingInstance*> (pInstance);
|
||||
if (pThingInstance != NULL)
|
||||
{
|
||||
if (pThingInstance->HaveBlendThing())
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
pThingInstance->BlendRender();
|
||||
return;
|
||||
}
|
||||
}
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
pInstance->RenderPCBlocker();
|
||||
}
|
||||
};
|
||||
|
||||
void CMapOutdoor::RenderEffect()
|
||||
{
|
||||
if (!IsVisiblePart(PART_OBJECT))
|
||||
return;
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(i, &pArea))
|
||||
{
|
||||
pArea->RenderEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CMapOutdoor_LessThingInstancePtrRenderOrder
|
||||
{
|
||||
bool operator() (CGraphicThingInstance* pkLeft, CGraphicThingInstance* pkRight)
|
||||
{
|
||||
//TODO : Camera위치기반으로 소팅
|
||||
CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
const D3DXVECTOR3 & c_rv3CameraPos = pCurrentCamera->GetEye();
|
||||
const D3DXVECTOR3 & c_v3LeftPos = pkLeft->GetPosition();
|
||||
const D3DXVECTOR3 & c_v3RightPos = pkRight->GetPosition();
|
||||
const auto vv = D3DXVECTOR3(c_rv3CameraPos - c_v3RightPos);
|
||||
const auto vv2 = D3DXVECTOR3(c_rv3CameraPos - c_v3LeftPos);
|
||||
|
||||
return D3DXVec3LengthSq(&vv2) < D3DXVec3LengthSq(&vv);
|
||||
}
|
||||
};
|
||||
|
||||
struct CMapOutdoor_FOpaqueThingInstanceRender
|
||||
{
|
||||
inline void operator () (CGraphicThingInstance * pkThingInst)
|
||||
{
|
||||
pkThingInst->Render();
|
||||
}
|
||||
};
|
||||
struct CMapOutdoor_FBlendThingInstanceRender
|
||||
{
|
||||
inline void operator () (CGraphicThingInstance * pkThingInst)
|
||||
{
|
||||
pkThingInst->BlendRender();
|
||||
}
|
||||
};
|
||||
|
||||
void CMapOutdoor::RenderArea(bool bRenderAmbience)
|
||||
{
|
||||
if (!IsVisiblePart(PART_OBJECT))
|
||||
return;
|
||||
|
||||
m_dwRenderedCRCNum = 0;
|
||||
m_dwRenderedGraphicThingInstanceNum = 0;
|
||||
m_dwRenderedCRCWithNumberVector.clear();
|
||||
|
||||
// NOTE - 20041201.levites.던젼 그림자 추가
|
||||
for (int j = 0; j < AROUND_AREA_NUM; ++j)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(j, &pArea))
|
||||
{
|
||||
pArea->RenderDungeon();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WORLD_EDITOR
|
||||
// PCBlocker
|
||||
std::for_each(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), FPCBlockerHide());
|
||||
|
||||
// Shadow Receiver
|
||||
if (m_bDrawShadow && m_bDrawChrShadow)
|
||||
{
|
||||
if (mc_pEnvironmentData != NULL)
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, 0xFFFFFFFF);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
|
||||
// Transform
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matDynamicShadow);
|
||||
STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_BORDER);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_BORDERCOLOR, 0xFFFFFFFF);
|
||||
|
||||
std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), FAreaRenderShadow());
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_BORDERCOLOR);
|
||||
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
|
||||
|
||||
if (mc_pEnvironmentData != NULL)
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, mc_pEnvironmentData->FogColor);
|
||||
}
|
||||
#endif
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, TRUE);
|
||||
|
||||
bool m_isDisableSortRendering=false;
|
||||
|
||||
if (m_isDisableSortRendering)
|
||||
{
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(i, &pArea))
|
||||
{
|
||||
pArea->Render();
|
||||
|
||||
m_dwRenderedCRCNum += pArea->DEBUG_GetRenderedCRCNum();
|
||||
m_dwRenderedGraphicThingInstanceNum += pArea->DEBUG_GetRenderedGrapphicThingInstanceNum();
|
||||
|
||||
CArea::TCRCWithNumberVector & rCRCWithNumberVector = pArea->DEBUG_GetRenderedCRCWithNumVector();
|
||||
|
||||
CArea::TCRCWithNumberVector::iterator aIterator = rCRCWithNumberVector.begin();
|
||||
while (aIterator != rCRCWithNumberVector.end())
|
||||
{
|
||||
DWORD dwCRC = (*aIterator++).dwCRC;
|
||||
|
||||
CArea::TCRCWithNumberVector::iterator aCRCWithNumberVectorIterator =
|
||||
std::find_if(m_dwRenderedCRCWithNumberVector.begin(), m_dwRenderedCRCWithNumberVector.end(), CArea::FFindIfCRC(dwCRC));
|
||||
|
||||
if ( m_dwRenderedCRCWithNumberVector.end() == aCRCWithNumberVectorIterator)
|
||||
{
|
||||
CArea::TCRCWithNumber aCRCWithNumber;
|
||||
aCRCWithNumber.dwCRC = dwCRC;
|
||||
aCRCWithNumber.dwNumber = 1;
|
||||
m_dwRenderedCRCWithNumberVector.push_back(aCRCWithNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
CArea::TCRCWithNumber & rCRCWithNumber = *aCRCWithNumberVectorIterator;
|
||||
rCRCWithNumber.dwNumber += 1;
|
||||
}
|
||||
}
|
||||
#ifdef WORLD_EDITOR
|
||||
if (bRenderAmbience)
|
||||
pArea->RenderAmbience();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(m_dwRenderedCRCWithNumberVector.begin(), m_dwRenderedCRCWithNumberVector.end(), CArea::CRCNumComp());
|
||||
}
|
||||
else
|
||||
{
|
||||
static std::vector<CGraphicThingInstance*> s_kVct_pkOpaqueThingInstSort;
|
||||
s_kVct_pkOpaqueThingInstSort.clear();
|
||||
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(i, &pArea))
|
||||
{
|
||||
pArea->CollectRenderingObject(s_kVct_pkOpaqueThingInstSort);
|
||||
#ifdef WORLD_EDITOR
|
||||
if (bRenderAmbience)
|
||||
pArea->RenderAmbience();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::sort(s_kVct_pkOpaqueThingInstSort.begin(), s_kVct_pkOpaqueThingInstSort.end(), CMapOutdoor_LessThingInstancePtrRenderOrder());
|
||||
std::for_each(s_kVct_pkOpaqueThingInstSort.begin(), s_kVct_pkOpaqueThingInstSort.end(), CMapOutdoor_FOpaqueThingInstanceRender());
|
||||
}
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
|
||||
#ifndef WORLD_EDITOR
|
||||
// Shadow Receiver
|
||||
if (m_bDrawShadow && m_bDrawChrShadow)
|
||||
{
|
||||
std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), std::mem_fn(&CGraphicObjectInstance::Show));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderBlendArea()
|
||||
{
|
||||
if (!IsVisiblePart(PART_OBJECT))
|
||||
return;
|
||||
|
||||
static std::vector<CGraphicThingInstance*> s_kVct_pkBlendThingInstSort;
|
||||
s_kVct_pkBlendThingInstSort.clear();
|
||||
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(i, &pArea))
|
||||
{
|
||||
pArea->CollectBlendRenderingObject(s_kVct_pkBlendThingInstSort);
|
||||
}
|
||||
}
|
||||
|
||||
if (s_kVct_pkBlendThingInstSort.size() != 0)
|
||||
{
|
||||
|
||||
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
|
||||
//// Transform
|
||||
//STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matDynamicShadow);
|
||||
//STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture);
|
||||
|
||||
//STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
//STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
//STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
//STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_BORDER);
|
||||
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER);
|
||||
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_BORDERCOLOR, 0xFFFFFFFF);
|
||||
|
||||
////std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), FAreaRenderShadow());
|
||||
|
||||
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
|
||||
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
|
||||
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
|
||||
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_BORDERCOLOR);
|
||||
|
||||
//STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
|
||||
|
||||
|
||||
std::sort(s_kVct_pkBlendThingInstSort.begin(), s_kVct_pkBlendThingInstSort.end(), CMapOutdoor_LessThingInstancePtrRenderOrder());
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
std::for_each(s_kVct_pkBlendThingInstSort.begin(), s_kVct_pkBlendThingInstSort.end(), CMapOutdoor_FBlendThingInstanceRender());
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
}
|
||||
}
|
||||
void CMapOutdoor::RenderDungeon()
|
||||
{
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (!GetAreaPointer(i, &pArea))
|
||||
continue;
|
||||
pArea->RenderDungeon();
|
||||
}
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderPCBlocker()
|
||||
{
|
||||
#ifndef WORLD_EDITOR
|
||||
// PCBlocker
|
||||
if (m_PCBlockerVector.size() != 0)
|
||||
{
|
||||
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_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matBuildingTransparent);
|
||||
STATEMANAGER.SetTexture(1, m_BuildingTransparentImageInstance.GetTexturePointer()->GetD3DTexture());
|
||||
|
||||
std::for_each(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), FRenderPCBlocker());
|
||||
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CMapOutdoor::SelectIndexBuffer(BYTE byLODLevel, WORD * pwPrimitiveCount, D3DPRIMITIVETYPE * pePrimitiveType)
|
||||
{
|
||||
#ifdef WORLD_EDITOR
|
||||
*pwPrimitiveCount = m_wNumIndices - 2;
|
||||
*pePrimitiveType = D3DPT_TRIANGLESTRIP;
|
||||
STATEMANAGER.SetIndices(m_IndexBuffer.GetD3DIndexBuffer(), 0);
|
||||
#else
|
||||
if (0 == byLODLevel)
|
||||
{
|
||||
*pwPrimitiveCount = m_wNumIndices[byLODLevel] - 2;
|
||||
*pePrimitiveType = D3DPT_TRIANGLESTRIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pwPrimitiveCount = m_wNumIndices[byLODLevel]/3;
|
||||
*pePrimitiveType = D3DPT_TRIANGLELIST;
|
||||
}
|
||||
STATEMANAGER.SetIndices(m_IndexBuffer[byLODLevel].GetD3DIndexBuffer(), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CMapOutdoor::SetPatchDrawVector()
|
||||
{
|
||||
assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__SetPatchDrawVector");
|
||||
|
||||
m_PatchDrawStructVector.clear();
|
||||
|
||||
std::vector<std::pair<float, long> >::iterator aDistancePatchVectorIterator;
|
||||
|
||||
TPatchDrawStruct aPatchDrawStruct;
|
||||
|
||||
aDistancePatchVectorIterator = m_PatchVector.begin();
|
||||
while(aDistancePatchVectorIterator != m_PatchVector.end())
|
||||
{
|
||||
std::pair<float, long> adistancePatchPair = *aDistancePatchVectorIterator;
|
||||
|
||||
CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[adistancePatchPair.second];
|
||||
|
||||
if (!pTerrainPatchProxy->isUsed())
|
||||
{
|
||||
++aDistancePatchVectorIterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
long lPatchNum = pTerrainPatchProxy->GetPatchNum();
|
||||
if (lPatchNum < 0)
|
||||
{
|
||||
++aDistancePatchVectorIterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
BYTE byTerrainNum = pTerrainPatchProxy->GetTerrainNum();
|
||||
if (0xFF == byTerrainNum)
|
||||
{
|
||||
++aDistancePatchVectorIterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
CTerrain * pTerrain;
|
||||
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
|
||||
{
|
||||
++aDistancePatchVectorIterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
aPatchDrawStruct.fDistance = adistancePatchPair.first;
|
||||
aPatchDrawStruct.byTerrainNum = byTerrainNum;
|
||||
aPatchDrawStruct.lPatchNum = lPatchNum;
|
||||
aPatchDrawStruct.pTerrainPatchProxy = pTerrainPatchProxy;
|
||||
|
||||
m_PatchDrawStructVector.push_back(aPatchDrawStruct);
|
||||
|
||||
++aDistancePatchVectorIterator;
|
||||
}
|
||||
|
||||
std::stable_sort(m_PatchDrawStructVector.begin(), m_PatchDrawStructVector.end(), FSortPatchDrawStructWithTerrainNum());
|
||||
}
|
||||
|
||||
float CMapOutdoor::__GetNoFogDistance()
|
||||
{
|
||||
return (float)(CTerrainImpl::CELLSCALE * m_lViewRadius) * 0.5f;
|
||||
}
|
||||
|
||||
float CMapOutdoor::__GetFogDistance()
|
||||
{
|
||||
return (float)(CTerrainImpl::CELLSCALE * m_lViewRadius) * 0.75f;
|
||||
}
|
||||
|
||||
struct FPatchNumMatch
|
||||
{
|
||||
long m_lPatchNumToCheck;
|
||||
FPatchNumMatch(long lPatchNum)
|
||||
{
|
||||
m_lPatchNumToCheck = lPatchNum;
|
||||
}
|
||||
bool operator() (std::pair<long, BYTE> aPair)
|
||||
{
|
||||
return m_lPatchNumToCheck == aPair.first;
|
||||
}
|
||||
};
|
||||
|
||||
void CMapOutdoor::NEW_DrawWireFrame(CTerrainPatchProxy * pTerrainPatchProxy, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType)
|
||||
{
|
||||
DWORD dwFillMode = STATEMANAGER.GetRenderState(D3DRS_FILLMODE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
|
||||
|
||||
DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, dwFillMode);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
}
|
||||
|
||||
void CMapOutdoor::DrawWireFrame(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType)
|
||||
{
|
||||
assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::DrawWireFrame");
|
||||
|
||||
CTerrainPatchProxy * pTerrainPatchProxy= &m_pTerrainPatchProxyList[patchnum];
|
||||
|
||||
if (!pTerrainPatchProxy->isUsed())
|
||||
return;
|
||||
|
||||
long sPatchNum = pTerrainPatchProxy->GetPatchNum();
|
||||
if (sPatchNum < 0)
|
||||
return;
|
||||
BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum();
|
||||
if (0xFF == ucTerrainNum)
|
||||
return;
|
||||
|
||||
DWORD dwFillMode = STATEMANAGER.GetRenderState(D3DRS_FILLMODE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
|
||||
|
||||
DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, dwFillMode);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
}
|
||||
|
||||
// Attr
|
||||
void CMapOutdoor::RenderMarkedArea()
|
||||
{
|
||||
if (!m_pTerrainPatchProxyList)
|
||||
return;
|
||||
|
||||
m_matWorldForCommonUse._41 = 0.0f;
|
||||
m_matWorldForCommonUse._42 = 0.0f;
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse);
|
||||
|
||||
WORD wPrimitiveCount;
|
||||
D3DPRIMITIVETYPE eType;
|
||||
SelectIndexBuffer(0, &wPrimitiveCount, &eType);
|
||||
|
||||
D3DXMATRIX matTexTransform, matTexTransformTemp;
|
||||
|
||||
D3DXMatrixScaling(&matTexTransform, m_fTerrainTexCoordBase * 32.0f, -m_fTerrainTexCoordBase * 32.0f, 0.0f);
|
||||
D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &matTexTransform);
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &matTexTransform);
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &matTexTransform);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
static long lStartTime = timeGetTime();
|
||||
float fTime = float((timeGetTime() - lStartTime)%3000) / 3000.0f;
|
||||
float fAlpha = fabs(fTime - 0.5f) / 2.0f + 0.1f;
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(1.0f, 1.0f, 1.0f, fAlpha));
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
STATEMANAGER.SetTexture(0, m_attrImageInstance.GetTexturePointer()->GetD3DTexture());
|
||||
|
||||
RecurseRenderAttr(m_pRootNode);
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MINFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MAGFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MIPFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
|
||||
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0);
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
}
|
||||
|
||||
void CMapOutdoor::RecurseRenderAttr(CTerrainQuadtreeNode *Node, bool bCullEnable)
|
||||
{
|
||||
if (bCullEnable)
|
||||
{
|
||||
if (__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(Node->center, Node->radius)==VIEW_NONE)
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
if (Node->Size == 1)
|
||||
{
|
||||
DrawPatchAttr(Node->PatchNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Node->NW_Node != NULL)
|
||||
RecurseRenderAttr(Node->NW_Node, bCullEnable);
|
||||
if (Node->NE_Node != NULL)
|
||||
RecurseRenderAttr(Node->NE_Node, bCullEnable);
|
||||
if (Node->SW_Node != NULL)
|
||||
RecurseRenderAttr(Node->SW_Node, bCullEnable);
|
||||
if (Node->SE_Node != NULL)
|
||||
RecurseRenderAttr(Node->SE_Node, bCullEnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMapOutdoor::DrawPatchAttr(long patchnum)
|
||||
{
|
||||
CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum];
|
||||
if (!pTerrainPatchProxy->isUsed())
|
||||
return;
|
||||
|
||||
long sPatchNum = pTerrainPatchProxy->GetPatchNum();
|
||||
if (sPatchNum < 0)
|
||||
return;
|
||||
|
||||
BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum();
|
||||
if (0xFF == ucTerrainNum)
|
||||
return;
|
||||
|
||||
// Deal with this material buffer
|
||||
CTerrain * pTerrain;
|
||||
if (!GetTerrainPointer(ucTerrainNum, &pTerrain))
|
||||
return;
|
||||
|
||||
if (!pTerrain->IsMarked())
|
||||
return;
|
||||
|
||||
WORD wCoordX, wCoordY;
|
||||
pTerrain->GetCoordinate(&wCoordX, &wCoordY);
|
||||
|
||||
m_matWorldForCommonUse._41 = -(float) (wCoordX * CTerrainImpl::XSIZE * CTerrainImpl::CELLSCALE);
|
||||
m_matWorldForCommonUse._42 = (float) (wCoordY * CTerrainImpl::YSIZE * CTerrainImpl::CELLSCALE);
|
||||
|
||||
D3DXMATRIX matTexTransform, matTexTransformTemp;
|
||||
D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &m_matWorldForCommonUse);
|
||||
D3DXMatrixMultiply(&matTexTransform, &matTexTransform, &m_matStaticShadow);
|
||||
STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &matTexTransform);
|
||||
|
||||
TTerrainSplatPatch & rAttrSplatPatch = pTerrain->GetMarkedSplatPatch();
|
||||
STATEMANAGER.SetTexture(1, rAttrSplatPatch.Splats[0].pd3dTexture);
|
||||
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL);
|
||||
STATEMANAGER.SetStreamSource(0, pTerrainPatchProxy->HardwareTransformPatch_GetVertexBufferPtr()->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize);
|
||||
|
||||
#ifdef WORLD_EDITOR
|
||||
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_iPatchTerrainVertexCount, 0, m_wNumIndices - 2);
|
||||
#else
|
||||
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_iPatchTerrainVertexCount, 0, m_wNumIndices[0] - 2);
|
||||
#endif
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,299 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EterBase/Filename.h"
|
||||
#include "Property.h"
|
||||
|
||||
float SEnvironmentData::GetFogNearDistance() const
|
||||
{
|
||||
return m_fFogNearDistance;
|
||||
}
|
||||
|
||||
float SEnvironmentData::GetFogFarDistance() const
|
||||
{
|
||||
return m_fFogFarDistance;
|
||||
}
|
||||
|
||||
float SPixelPosition_CalculateDistanceSq3d(const TPixelPosition& c_rkPPosLeft, const TPixelPosition& c_rkPPosRight)
|
||||
{
|
||||
float dx=c_rkPPosLeft.x-c_rkPPosRight.x;
|
||||
float dy=c_rkPPosLeft.y-c_rkPPosRight.y;
|
||||
float dz=c_rkPPosLeft.z-c_rkPPosRight.z;
|
||||
|
||||
return dx*dx+dy*dy+dz*dz;
|
||||
}
|
||||
|
||||
namespace prt
|
||||
{
|
||||
|
||||
DWORD GetPropertyType(const char * c_szTypeName)
|
||||
{
|
||||
for (DWORD i = 0; i < PROPERTY_TYPE_MAX_NUM; ++i)
|
||||
{
|
||||
if (!strcmp(c_szPropertyTypeName[i], c_szTypeName))
|
||||
return i;
|
||||
}
|
||||
|
||||
return PROPERTY_TYPE_NONE;
|
||||
}
|
||||
|
||||
const char * GetPropertyExtension(DWORD dwType)
|
||||
{
|
||||
if (dwType >= PROPERTY_TYPE_MAX_NUM)
|
||||
return c_szPropertyExtension[0];
|
||||
|
||||
return c_szPropertyExtension[dwType];
|
||||
}
|
||||
|
||||
const char * IntegerNumberToString(int iNumber)
|
||||
{
|
||||
static char szString[16+1];
|
||||
_snprintf(szString, sizeof(szString), "%d", iNumber);
|
||||
return szString;
|
||||
}
|
||||
|
||||
const char * FloatNumberToString(float fNumber)
|
||||
{
|
||||
static char szString[16+1];
|
||||
_snprintf(szString, sizeof(szString), "%f", fNumber);
|
||||
return szString;
|
||||
}
|
||||
|
||||
bool PropertyTreeDataToString(TPropertyTree * pData, CProperty * pProperty)
|
||||
{
|
||||
pProperty->Clear();
|
||||
|
||||
pProperty->PutString("PropertyType", "Tree");
|
||||
pProperty->PutString("PropertyName", pData->strName.c_str());
|
||||
|
||||
pProperty->PutString("TreeFile", pData->strFileName.c_str());
|
||||
pProperty->PutString("TreeSize", FloatNumberToString(pData->fSize));
|
||||
pProperty->PutString("TreeVariance", FloatNumberToString(pData->fVariance));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyTreeStringToData(CProperty * pProperty, TPropertyTree * pData)
|
||||
{
|
||||
const char * c_pszPropertyType;
|
||||
const char * c_pszPropertyName;
|
||||
|
||||
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
|
||||
return false;
|
||||
|
||||
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
|
||||
return false;
|
||||
|
||||
if (strcmp(c_pszPropertyType, "Tree"))
|
||||
return false;
|
||||
|
||||
pData->strName = c_pszPropertyName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char * c_pszTreeName;
|
||||
const char * c_pszTreeSize;
|
||||
const char * c_pszTreeVariance;
|
||||
if (!pProperty->GetString("TreeFile", &c_pszTreeName))
|
||||
return false;
|
||||
if (!pProperty->GetString("TreeSize", &c_pszTreeSize))
|
||||
return false;
|
||||
if (!pProperty->GetString("TreeVariance", &c_pszTreeVariance))
|
||||
return false;
|
||||
|
||||
pData->strFileName = c_pszTreeName;
|
||||
pData->fSize = atof(c_pszTreeSize);
|
||||
pData->fVariance = atof(c_pszTreeVariance);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyBuildingDataToString(TPropertyBuilding * pData, CProperty * pProperty)
|
||||
{
|
||||
pProperty->Clear();
|
||||
|
||||
pProperty->PutString("PropertyType", "Building");
|
||||
pProperty->PutString("PropertyName", pData->strName.c_str());
|
||||
pProperty->PutString("BuildingFile", pData->strFileName.c_str());
|
||||
pProperty->PutString("ShadowFlag", IntegerNumberToString(pData->isShadowFlag));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyBuildingStringToData(CProperty * pProperty, TPropertyBuilding * pData)
|
||||
{
|
||||
const char * c_pszPropertyType;
|
||||
const char * c_pszPropertyName;
|
||||
|
||||
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
|
||||
return false;
|
||||
|
||||
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
|
||||
return false;
|
||||
|
||||
if (strcmp(c_pszPropertyType, "Building"))
|
||||
return false;
|
||||
|
||||
pData->strName = c_pszPropertyName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char * c_pszBuildingName;
|
||||
if (!pProperty->GetString("BuildingFile", &c_pszBuildingName))
|
||||
return false;
|
||||
|
||||
pData->strFileName = c_pszBuildingName;
|
||||
pData->strAttributeDataFileName = CFileNameHelper::NoExtension(pData->strFileName) + ".mdatr";
|
||||
|
||||
const char * c_pszShadowFlag;
|
||||
if (!pProperty->GetString("ShadowFlag", &c_pszShadowFlag))
|
||||
{
|
||||
pData->isShadowFlag = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->isShadowFlag = atoi(c_pszShadowFlag);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PropertyEffectDataToString(TPropertyEffect * pData, CProperty * pProperty)
|
||||
{
|
||||
pProperty->Clear();
|
||||
|
||||
pProperty->PutString("PropertyType", "Effect");
|
||||
pProperty->PutString("PropertyName", pData->strName.c_str());
|
||||
pProperty->PutString("EffectFile", pData->strFileName.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyEffectStringToData(CProperty * pProperty, TPropertyEffect * pData)
|
||||
{
|
||||
const char * c_pszPropertyType;
|
||||
const char * c_pszPropertyName;
|
||||
|
||||
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
|
||||
return false;
|
||||
|
||||
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
|
||||
return false;
|
||||
|
||||
if (strcmp(c_pszPropertyType, "Effect"))
|
||||
return false;
|
||||
|
||||
pData->strName = c_pszPropertyName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char * c_pszEffectName;
|
||||
if (!pProperty->GetString("EffectFile", &c_pszEffectName))
|
||||
return false;
|
||||
|
||||
pData->strFileName = c_pszEffectName;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyAmbienceDataToString(TPropertyAmbience * pData, CProperty * pProperty)
|
||||
{
|
||||
pProperty->Clear();
|
||||
pProperty->PutString("PropertyType", "Ambience");
|
||||
pProperty->PutString("PropertyName", pData->strName.c_str());
|
||||
pProperty->PutString("PlayType", pData->strPlayType.c_str());
|
||||
pProperty->PutString("PlayInterval", FloatNumberToString(pData->fPlayInterval));
|
||||
pProperty->PutString("PlayIntervalVariation", FloatNumberToString(pData->fPlayIntervalVariation));
|
||||
pProperty->PutString("MaxVolumeAreaPercentage", FloatNumberToString(pData->fMaxVolumeAreaPercentage));
|
||||
|
||||
CTokenVector AmbienceSoundVector;
|
||||
std::vector<std::string>::iterator itor = pData->AmbienceSoundVector.begin();
|
||||
for (; itor != pData->AmbienceSoundVector.end(); ++itor)
|
||||
{
|
||||
std::string & rstrToken = *itor;
|
||||
AmbienceSoundVector.push_back(rstrToken.c_str());
|
||||
}
|
||||
pProperty->PutVector("AmbienceSoundVector", AmbienceSoundVector);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyAmbienceStringToData(CProperty * pProperty, TPropertyAmbience * pData)
|
||||
{
|
||||
const char * c_pszPropertyType;
|
||||
const char * c_pszPropertyName;
|
||||
|
||||
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
|
||||
return false;
|
||||
|
||||
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
|
||||
return false;
|
||||
|
||||
if (strcmp(c_pszPropertyType, "Ambience"))
|
||||
return false;
|
||||
|
||||
pData->strName = c_pszPropertyName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char * c_pszPlayType;
|
||||
const char * c_pszPlayInterval;
|
||||
const char * c_pszPlayIntervalVariation;
|
||||
const char * c_pszMaxVolumeAreaPercentage = NULL;
|
||||
CTokenVector AmbienceSoundVector;
|
||||
if (!pProperty->GetString("PlayType", &c_pszPlayType))
|
||||
return false;
|
||||
if (!pProperty->GetString("PlayInterval", &c_pszPlayInterval))
|
||||
return false;
|
||||
if (!pProperty->GetString("PlayIntervalVariation", &c_pszPlayIntervalVariation))
|
||||
return false;
|
||||
if (!pProperty->GetString("MaxVolumeAreaPercentage", &c_pszMaxVolumeAreaPercentage))
|
||||
{
|
||||
pData->fMaxVolumeAreaPercentage = 0.0f;
|
||||
}
|
||||
if (!pProperty->GetVector("AmbienceSoundVector", AmbienceSoundVector))
|
||||
return false;
|
||||
|
||||
pData->strPlayType = c_pszPlayType;
|
||||
pData->fPlayInterval = atof(c_pszPlayInterval);
|
||||
pData->fPlayIntervalVariation = atof(c_pszPlayIntervalVariation);
|
||||
if (c_pszMaxVolumeAreaPercentage)
|
||||
pData->fMaxVolumeAreaPercentage = atof(c_pszMaxVolumeAreaPercentage);
|
||||
for (CTokenVector::iterator itor = AmbienceSoundVector.begin(); itor != AmbienceSoundVector.end(); ++itor)
|
||||
pData->AmbienceSoundVector.push_back(*itor);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyDungeonBlockDataToString(TPropertyDungeonBlock * pData, CProperty * pProperty)
|
||||
{
|
||||
pProperty->Clear();
|
||||
pProperty->PutString("PropertyType", "DungeonBlock");
|
||||
pProperty->PutString("PropertyName", pData->strName.c_str());
|
||||
pProperty->PutString("DungeonBlockFile", pData->strFileName.c_str());
|
||||
return true;
|
||||
}
|
||||
bool PropertyDungeonBlockStringToData(CProperty * pProperty, TPropertyDungeonBlock * pData)
|
||||
{
|
||||
const char * c_pszPropertyType;
|
||||
const char * c_pszPropertyName;
|
||||
|
||||
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
|
||||
return false;
|
||||
|
||||
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
|
||||
return false;
|
||||
|
||||
if (strcmp(c_pszPropertyType, "DungeonBlock"))
|
||||
return false;
|
||||
|
||||
pData->strName = c_pszPropertyName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char * c_pszDungeonBlockFileName = NULL;
|
||||
if (!pProperty->GetString("dungeonblockfile", &c_pszDungeonBlockFileName))
|
||||
return false;
|
||||
|
||||
pData->strFileName = c_pszDungeonBlockFileName;
|
||||
pData->strAttributeDataFileName = CFileNameHelper::NoExtension(pData->strFileName) + std::string(".mdatr");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // namespace prt;
|
||||
@@ -0,0 +1,148 @@
|
||||
// MonsterAreaInfo.cpp: implementation of the CMonsterAreaInfo class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "MonsterAreaInfo.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CMonsterAreaInfo::CMonsterAreaInfo()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CMonsterAreaInfo::~CMonsterAreaInfo()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::Clear()
|
||||
{
|
||||
SetOrigin(-1, -1);
|
||||
SetSize(-1, -1);
|
||||
RemoveAllMonsters();
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::SetOrigin(long lOriginX, long lOriginY)
|
||||
{
|
||||
m_lOriginX = lOriginX;
|
||||
m_lOriginY = lOriginY;
|
||||
SetLRTB();
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::SetSize(long lSizeX, long lSizeY)
|
||||
{
|
||||
m_lSizeX = lSizeX;
|
||||
m_lSizeY = lSizeY;
|
||||
SetLRTB();
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::GetOrigin(long * plOriginX, long * plOriginY)
|
||||
{
|
||||
*plOriginX = m_lOriginX;
|
||||
*plOriginY = m_lOriginY;
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::GetSize(long * plSizeX, long * plSizeY)
|
||||
{
|
||||
*plSizeX = m_lSizeX;
|
||||
*plSizeY = m_lSizeY;
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::SetLRTB()
|
||||
{
|
||||
m_lLeft = m_lOriginX - m_lSizeX;
|
||||
m_lTop = m_lOriginY - m_lSizeY;
|
||||
m_lRight = m_lOriginX + m_lSizeX;
|
||||
m_lBottom = m_lOriginY + m_lSizeY;
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::SetMonsterCount(DWORD dwCount)
|
||||
{
|
||||
m_dwMonsterCount = dwCount;
|
||||
|
||||
if (m_TempMonsterPosVector.size() == dwCount)
|
||||
return;
|
||||
|
||||
m_TempMonsterPosVector.clear();
|
||||
m_TempMonsterPosVector.resize(dwCount);
|
||||
|
||||
for (DWORD dwI = 0; dwI < dwCount; ++dwI)
|
||||
{
|
||||
m_TempMonsterPosVector[dwI].x = (float)random_range(m_lLeft, m_lRight);
|
||||
m_TempMonsterPosVector[dwI].y = (float)random_range(m_lTop, m_lBottom);
|
||||
}
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::SetMonsterDirection(EMonsterDir eMonsterDir)
|
||||
{
|
||||
m_eMonsterDir = eMonsterDir;
|
||||
D3DXMATRIX matRotation;
|
||||
D3DXVECTOR3 v3Direction(0.0f, 1.0f, 0.0f);
|
||||
float fDegree = 0.0f;
|
||||
switch(m_eMonsterDir)
|
||||
{
|
||||
case DIR_RANDOM:
|
||||
fDegree = (float) random_range(0, 7) * 45.0f;
|
||||
break;
|
||||
case DIR_NORTH:
|
||||
fDegree = 0.0f;
|
||||
break;
|
||||
case DIR_NORTHEAST:
|
||||
fDegree = 45.0f;
|
||||
break;
|
||||
case DIR_EAST:
|
||||
fDegree = 90.0f;
|
||||
break;
|
||||
case DIR_SOUTHEAST:
|
||||
fDegree = 135.0f;
|
||||
break;
|
||||
case DIR_SOUTH:
|
||||
fDegree = 180.0f;
|
||||
break;
|
||||
case DIR_SOUTHWEST:
|
||||
fDegree = 225.0f;
|
||||
break;
|
||||
case DIR_WEST:
|
||||
fDegree = 270.0f;
|
||||
break;
|
||||
case DIR_NORTHWEST:
|
||||
fDegree = 315.0f;
|
||||
break;
|
||||
}
|
||||
D3DXMatrixRotationZ(&matRotation, -D3DXToRadian(fDegree));
|
||||
D3DXVec3TransformCoord(&v3Direction, &v3Direction, &matRotation);
|
||||
m_v2Monsterdirection.x = v3Direction.x;
|
||||
m_v2Monsterdirection.y = v3Direction.y;
|
||||
D3DXVec2Normalize(&m_v2Monsterdirection, &m_v2Monsterdirection);
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::RemoveAllMonsters()
|
||||
{
|
||||
SetMonsterAreaInfoType(MONSTERAREAINFOTYPE_INVALID);
|
||||
|
||||
SetMonsterGroupID(0);
|
||||
|
||||
m_strGroupName.assign("\300\314\270\247\276\370\300\275");
|
||||
m_strLeaderName.assign("\300\314\270\247\276\370\300\275");
|
||||
SetMonsterGroupFollowerCount(0);
|
||||
|
||||
SetMonsterVID(0);
|
||||
m_strMonsterName.assign("\300\314\270\247\276\370\300\275");
|
||||
|
||||
SetMonsterCount(0);
|
||||
SetMonsterDirection(DIR_NORTH);
|
||||
|
||||
m_TempMonsterPosVector.clear();
|
||||
}
|
||||
|
||||
D3DXVECTOR2 CMonsterAreaInfo::GetTempMonsterPos(DWORD dwIndex)
|
||||
{
|
||||
if (dwIndex >= m_TempMonsterPosVector.size())
|
||||
return D3DXVECTOR2(0.0f, 0.0f);
|
||||
return m_TempMonsterPosVector[dwIndex];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
#include "StdAfx.h"
|
||||
#include <string.h>
|
||||
#include "../EterBase/TempFile.h"
|
||||
|
||||
#include "PropertyManager.h"
|
||||
#include "Property.h"
|
||||
/*
|
||||
* CProperty 파일 포맷
|
||||
*
|
||||
* 0 ~ 4 bytes: fourcc
|
||||
* 5 ~ 6 bytes: \r\n
|
||||
*
|
||||
* 그 이후의 바이트들은 텍스트 파일 로더와 같은 구조
|
||||
*/
|
||||
CProperty::CProperty(const char * c_pszFileName) : mc_pFileName(NULL), m_dwCRC(0)
|
||||
{
|
||||
m_stFileName = c_pszFileName;
|
||||
StringPath(m_stFileName);
|
||||
|
||||
mc_pFileName = strrchr(m_stFileName.c_str(), '/');
|
||||
|
||||
if (!mc_pFileName)
|
||||
mc_pFileName = m_stFileName.c_str();
|
||||
else
|
||||
++mc_pFileName;
|
||||
}
|
||||
|
||||
CProperty::~CProperty()
|
||||
{
|
||||
}
|
||||
|
||||
DWORD CProperty::GetCRC()
|
||||
{
|
||||
return m_dwCRC;
|
||||
}
|
||||
|
||||
const char * CProperty::GetFileName()
|
||||
{
|
||||
return (m_stFileName.c_str());
|
||||
}
|
||||
|
||||
bool CProperty::GetString(const char * c_pszKey, const char ** c_ppString)
|
||||
{
|
||||
std::string stTempKey = c_pszKey;
|
||||
stl_lowers(stTempKey);
|
||||
CTokenVectorMap::iterator it = m_stTokenMap.find(stTempKey.c_str());
|
||||
|
||||
// printf("GetString %s %d\n", stTempKey.c_str(), m_stTokenMap.size());
|
||||
|
||||
if (m_stTokenMap.end() == it)
|
||||
return false;
|
||||
|
||||
*c_ppString = it->second[0].c_str();
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD CProperty::GetSize()
|
||||
{
|
||||
return m_stTokenMap.size();
|
||||
}
|
||||
|
||||
bool CProperty::GetVector(const char * c_pszKey, CTokenVector & rTokenVector)
|
||||
{
|
||||
std::string stTempKey = c_pszKey;
|
||||
stl_lowers(stTempKey);
|
||||
CTokenVectorMap::iterator it = m_stTokenMap.find(stTempKey.c_str());
|
||||
|
||||
if (m_stTokenMap.end() == it)
|
||||
return false;
|
||||
|
||||
// NOTE : 튕김 현상 발견
|
||||
// std::copy(rTokenVector.begin(), it->second.begin(), it->second.end());
|
||||
// NOTE : 레퍼런스에는 이런 식으로 하게끔 되어 있음
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// template <class InputIterator, class OutputIterator>
|
||||
// OutputIterator copy(InputIterator first, InputIterator last,
|
||||
// OutputIterator result);
|
||||
//
|
||||
// vector<int> V(5);
|
||||
// iota(V.begin(), V.end(), 1);
|
||||
// list<int> L(V.size());
|
||||
// copy(V.begin(), V.end(), L.begin());
|
||||
// assert(equal(V.begin(), V.end(), L.begin()));
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 헌데 그래도 튕김. - [levites]
|
||||
// std::copy(it->second.begin(), it->second.end(), rTokenVector.begin());
|
||||
|
||||
// 결국 이렇게.. - [levites]
|
||||
// 현재 사용하는 곳 : WorldEditor/Dialog/MapObjectPropertyPageBuilding.cpp
|
||||
CTokenVector & rSourceTokenVector = it->second;
|
||||
CTokenVector::iterator itor = rSourceTokenVector.begin();
|
||||
for (; itor != rSourceTokenVector.end(); ++itor)
|
||||
{
|
||||
rTokenVector.push_back(*itor);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CProperty::PutString(const char * c_pszKey, const char * c_pszString)
|
||||
{
|
||||
std::string stTempKey = c_pszKey;
|
||||
stl_lowers(stTempKey);
|
||||
|
||||
// 이미 있는걸 지움
|
||||
CTokenVectorMap::iterator itor = m_stTokenMap.find(stTempKey);
|
||||
|
||||
if (itor != m_stTokenMap.end())
|
||||
m_stTokenMap.erase(itor);
|
||||
|
||||
CTokenVector tokenVector;
|
||||
tokenVector.push_back(c_pszString);
|
||||
|
||||
m_stTokenMap.insert(CTokenVectorMap::value_type(stTempKey, tokenVector));
|
||||
}
|
||||
|
||||
void CProperty::PutVector(const char * c_pszKey, const CTokenVector & c_rTokenVector)
|
||||
{
|
||||
std::string stTempKey = c_pszKey;
|
||||
stl_lowers(stTempKey);
|
||||
|
||||
m_stTokenMap.insert(CTokenVectorMap::value_type(stTempKey, c_rTokenVector));
|
||||
}
|
||||
|
||||
void GetTimeString(char * str, time_t ct)
|
||||
{
|
||||
struct tm tm;
|
||||
tm = *localtime(&ct);
|
||||
|
||||
_snprintf(str, 15, "%04d%02d%02d%02d%02d%02d",
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec);
|
||||
}
|
||||
|
||||
bool CProperty::Save(const char * c_pszFileName)
|
||||
{
|
||||
CTempFile file;
|
||||
|
||||
DWORD fourcc = MAKEFOURCC('Y', 'P', 'R', 'T');
|
||||
file.Write(&fourcc, sizeof(DWORD));
|
||||
file.Write("\r\n", 2);
|
||||
|
||||
if (0 == m_stCRC.length())
|
||||
{
|
||||
char szCRC[MAX_PATH + 16 + 1];
|
||||
|
||||
GetTimeString(szCRC, time(0));
|
||||
strcpy(szCRC + strlen(szCRC), c_pszFileName);
|
||||
|
||||
m_dwCRC = CPropertyManager::Instance().GetUniqueCRC(szCRC);
|
||||
_snprintf(szCRC, sizeof(szCRC), "%u", m_dwCRC);
|
||||
|
||||
m_stCRC.assign(szCRC);
|
||||
}
|
||||
|
||||
file.Write(m_stCRC.c_str(), m_stCRC.length());
|
||||
file.Write("\r\n", 2);
|
||||
|
||||
CTokenVectorMap::iterator itor = m_stTokenMap.begin();
|
||||
char buf[4096 + 1];
|
||||
|
||||
while (itor != m_stTokenMap.end())
|
||||
{
|
||||
CTokenVector & tokenVector = itor->second;
|
||||
|
||||
int len = _snprintf(buf, sizeof(buf), "%s\t", itor->first.c_str());
|
||||
file.Write(buf, len);
|
||||
|
||||
for (DWORD i = 0; i < tokenVector.size(); ++i)
|
||||
{
|
||||
len = _snprintf(buf, sizeof(buf), "\t\"%s\"", tokenVector[i].c_str());
|
||||
file.Write(buf, len);
|
||||
}
|
||||
|
||||
file.Write("\r\n", 2);
|
||||
++itor;
|
||||
}
|
||||
|
||||
file.Close();
|
||||
return CPropertyManager::Instance().Put(c_pszFileName, file.GetFileName());
|
||||
}
|
||||
|
||||
bool CProperty::ReadFromMemory(const void * c_pvData, int iLen, const char * c_pszFileName)
|
||||
{
|
||||
const char * pcData = (const char *) c_pvData;
|
||||
|
||||
if (*(DWORD *) pcData != MAKEFOURCC('Y', 'P', 'R', 'T'))
|
||||
return false;
|
||||
|
||||
pcData += sizeof(DWORD);
|
||||
|
||||
if (*pcData != '\r' || *(pcData + 1) != '\n')
|
||||
{
|
||||
TraceError("CProperty::ReadFromMemory: File format error after FourCC: %s\n", c_pszFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
pcData += 2;
|
||||
|
||||
CTokenVector stTokenVector;
|
||||
/*
|
||||
char szTimeStamp[64];
|
||||
memcpy(szTimeStamp, pcData, 14);
|
||||
szTimeStamp[14] = '\0';
|
||||
pcData += 14;
|
||||
|
||||
if (*pcData != '\r' || *(pcData + 1) != '\n')
|
||||
{
|
||||
TraceError("CProperty::ReadFromMemory: File format error after TimeStamp: %s\n", c_pszFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string m_stTimeStamp;
|
||||
|
||||
m_stTimeStamp = szTimeStamp;
|
||||
|
||||
int iTimeStampLen = 14 + _snprintf(szTimeStamp + 14, 64 - 14, "%s", mc_pFileName);
|
||||
m_dwCRC = GetCRC32(szTimeStamp, iTimeStampLen);
|
||||
|
||||
char tmp[64];
|
||||
sprintf(tmp, "%u", m_dwCRC);
|
||||
m_stCRC.assign(tmp);
|
||||
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
textFileLoader.Bind(iLen - (sizeof(DWORD) + 2 + 14 + 2), pcData);
|
||||
|
||||
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
if (!textFileLoader.SplitLine(i, &stTokenVector))
|
||||
continue;
|
||||
|
||||
stl_lowers(stTokenVector[0]);
|
||||
std::string stKey = stTokenVector[0];
|
||||
|
||||
stTokenVector.erase(stTokenVector.begin());
|
||||
PutVector(stKey.c_str(), stTokenVector);
|
||||
}
|
||||
return true;
|
||||
*/
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
textFileLoader.Bind(iLen - (sizeof(DWORD) + 2), pcData);
|
||||
|
||||
m_stCRC = textFileLoader.GetLineString(0);
|
||||
m_dwCRC = atoi(m_stCRC.c_str());
|
||||
|
||||
for (DWORD i = 1; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
if (!textFileLoader.SplitLine(i, &stTokenVector))
|
||||
continue;
|
||||
|
||||
stl_lowers(stTokenVector[0]);
|
||||
std::string stKey = stTokenVector[0];
|
||||
|
||||
stTokenVector.erase(stTokenVector.begin());
|
||||
PutVector(stKey.c_str(), stTokenVector);
|
||||
}
|
||||
|
||||
//Tracef("Property: %s\n", c_pszFileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CProperty::Clear()
|
||||
{
|
||||
m_stTokenMap.clear();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class CProperty
|
||||
{
|
||||
public:
|
||||
CProperty(const char * c_pszFileName);
|
||||
~CProperty();
|
||||
|
||||
void Clear();
|
||||
bool ReadFromMemory(const void * c_pvData, int iLen, const char * c_pszFileName);
|
||||
|
||||
const char * GetFileName();
|
||||
|
||||
bool GetVector(const char * c_pszKey, CTokenVector & rTokenVector);
|
||||
bool GetString(const char * c_pszKey, const char ** c_ppString);
|
||||
|
||||
void PutVector(const char * c_pszKey, const CTokenVector & c_rTokenVector);
|
||||
void PutString(const char * c_pszKey, const char * c_pszString);
|
||||
|
||||
bool Save(const char * c_pszFileName);
|
||||
|
||||
DWORD GetSize();
|
||||
DWORD GetCRC();
|
||||
|
||||
protected:
|
||||
std::string m_stFileName;
|
||||
std::string m_stCRC;
|
||||
const char * mc_pFileName;
|
||||
DWORD m_dwCRC;
|
||||
|
||||
CTokenVectorMap m_stTokenMap;
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
#include "StdAfx.h"
|
||||
#include "PropertyLoader.h"
|
||||
#include "PropertyManager.h"
|
||||
#include "Property.h"
|
||||
|
||||
bool CPropertyLoader::OnFolder(const char* c_szFilter, const char* c_szPathName, const char* c_szFileName)
|
||||
{
|
||||
std::string stPathName = "";
|
||||
stPathName += c_szPathName;
|
||||
stPathName += c_szFileName;
|
||||
|
||||
CPropertyLoader PropertyLoader;
|
||||
PropertyLoader.SetPropertyManager(m_pPropertyManager);
|
||||
PropertyLoader.Create(c_szFilter, stPathName.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyLoader::OnFile(const char* c_szPathName, const char* c_szFileName)
|
||||
{
|
||||
RegisterFile(c_szPathName, c_szFileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD CPropertyLoader::RegisterFile(const char * c_szPathName, const char * c_szFileName)
|
||||
{
|
||||
std::string strFileName = "";
|
||||
strFileName += c_szPathName;
|
||||
strFileName += c_szFileName;
|
||||
|
||||
std::string stExt;
|
||||
GetFileExtension(strFileName.c_str(), strFileName.length(), &stExt);
|
||||
|
||||
stl_lowers(stExt);
|
||||
stl_lowers(strFileName);
|
||||
|
||||
// 패스를 소문자로 만들고 \\ 는 / 로 바꾼다.
|
||||
StringPath(strFileName);
|
||||
|
||||
// 예약된 CRC 처리 (지워진 CRC)
|
||||
if (0 == strFileName.compare("property/reserve"))
|
||||
{
|
||||
m_pPropertyManager->LoadReservedCRC(strFileName.c_str());
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CProperty * pProperty;
|
||||
|
||||
if (m_pPropertyManager->Register(strFileName.c_str(), &pProperty))
|
||||
return pProperty->GetCRC();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CPropertyLoader::SetPropertyManager(CPropertyManager * pPropertyManager)
|
||||
{
|
||||
m_pPropertyManager = pPropertyManager;
|
||||
}
|
||||
|
||||
CPropertyLoader::CPropertyLoader()
|
||||
{
|
||||
m_pPropertyManager = NULL;
|
||||
}
|
||||
|
||||
CPropertyLoader::~CPropertyLoader()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "../EterBase/FileDir.h"
|
||||
|
||||
class CPropertyManager;
|
||||
|
||||
class CPropertyLoader : public CDir
|
||||
{
|
||||
public:
|
||||
CPropertyLoader();
|
||||
virtual ~CPropertyLoader();
|
||||
|
||||
void SetPropertyManager(CPropertyManager * pPropertyManager);
|
||||
DWORD RegisterFile(const char* c_szPathName, const char* c_szFileName);
|
||||
|
||||
virtual bool OnFolder(const char* c_szFilter, const char* c_szPathName, const char* c_szFileName);
|
||||
virtual bool OnFile(const char* c_szPathName, const char* c_szFileName);
|
||||
|
||||
protected:
|
||||
CPropertyManager * m_pPropertyManager;
|
||||
};
|
||||
@@ -0,0 +1,255 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
|
||||
#include "PropertyManager.h"
|
||||
#include "Property.h"
|
||||
|
||||
CPropertyManager::CPropertyManager() : m_isFileMode(true)
|
||||
{
|
||||
}
|
||||
|
||||
CPropertyManager::~CPropertyManager()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
bool CPropertyManager::Initialize(const char * c_pszPackFileName)
|
||||
{
|
||||
if (c_pszPackFileName)
|
||||
{
|
||||
if (!m_pack.Create(m_fileDict, c_pszPackFileName, "", true))
|
||||
{
|
||||
LogBoxf("Cannot open property pack file (filename %s)", c_pszPackFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_isFileMode = false;
|
||||
|
||||
TDataPositionMap & indexMap = m_pack.GetIndexMap();
|
||||
|
||||
TDataPositionMap::iterator itor = indexMap.begin();
|
||||
|
||||
typedef std::map<DWORD, TEterPackIndex *> TDataPositionMap;
|
||||
|
||||
int i = 0;
|
||||
|
||||
while (indexMap.end() != itor)
|
||||
{
|
||||
TEterPackIndex * pIndex = itor->second;
|
||||
++itor;
|
||||
|
||||
if (!stricmp("property/reserve", pIndex->filename))
|
||||
{
|
||||
LoadReservedCRC(pIndex->filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Register(pIndex->filename))
|
||||
continue;
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_isFileMode = true;
|
||||
// NOTE : 여기서 Property를 등록시키면 WorldEditor에서 이상이 생김 ;
|
||||
// 또한, Property Tree List에도 등록을 시켜야 되기 때문에 바깥쪽에서.. - [levites]
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::BuildPack()
|
||||
{
|
||||
if (!m_pack.Create(m_fileDict, "property", ""))
|
||||
return false;
|
||||
|
||||
WIN32_FIND_DATA fdata;
|
||||
HANDLE hFind = FindFirstFile("property\\*", &fdata);
|
||||
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
continue;
|
||||
|
||||
char szSourceFileName[256 + 1];
|
||||
_snprintf(szSourceFileName, sizeof(szSourceFileName), "property\\%s", fdata.cFileName);
|
||||
|
||||
m_pack.Put(fdata.cFileName, szSourceFileName,COMPRESSED_TYPE_NONE,"");
|
||||
}
|
||||
while (FindNextFile(hFind, &fdata));
|
||||
|
||||
FindClose(hFind);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::LoadReservedCRC(const char * c_pszFileName)
|
||||
{
|
||||
CMappedFile file;
|
||||
LPCVOID c_pvData;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData))
|
||||
return false;
|
||||
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
textFileLoader.Bind(file.Size(), c_pvData);
|
||||
|
||||
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
const char * pszLine = textFileLoader.GetLineString(i).c_str();
|
||||
|
||||
if (!pszLine || !*pszLine)
|
||||
continue;
|
||||
|
||||
ReserveCRC(atoi(pszLine));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPropertyManager::ReserveCRC(DWORD dwCRC)
|
||||
{
|
||||
m_ReservedCRCSet.insert(dwCRC);
|
||||
}
|
||||
|
||||
DWORD CPropertyManager::GetUniqueCRC(const char * c_szSeed)
|
||||
{
|
||||
std::string stTmp = c_szSeed;
|
||||
|
||||
while (1)
|
||||
{
|
||||
DWORD dwCRC = GetCRC32(stTmp.c_str(), stTmp.length());
|
||||
|
||||
if (m_ReservedCRCSet.find(dwCRC) == m_ReservedCRCSet.end() &&
|
||||
m_PropertyByCRCMap.find(dwCRC) == m_PropertyByCRCMap.end())
|
||||
return dwCRC;
|
||||
|
||||
char szAdd[2];
|
||||
_snprintf(szAdd, sizeof(szAdd), "%d", random() % 10);
|
||||
stTmp += szAdd;
|
||||
}
|
||||
}
|
||||
|
||||
bool CPropertyManager::Register(const char * c_pszFileName, CProperty ** ppProperty)
|
||||
{
|
||||
CMappedFile file;
|
||||
LPCVOID c_pvData;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData))
|
||||
return false;
|
||||
|
||||
CProperty * pProperty = new CProperty(c_pszFileName);
|
||||
|
||||
if (!pProperty->ReadFromMemory(c_pvData, file.Size(), c_pszFileName))
|
||||
{
|
||||
delete pProperty;
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD dwCRC = pProperty->GetCRC();
|
||||
|
||||
TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC);
|
||||
|
||||
if (m_PropertyByCRCMap.end() != itor)
|
||||
{
|
||||
Tracef("Property already registered, replace %s to %s\n",
|
||||
itor->second->GetFileName(),
|
||||
c_pszFileName);
|
||||
|
||||
delete itor->second;
|
||||
itor->second = pProperty;
|
||||
}
|
||||
else
|
||||
m_PropertyByCRCMap.insert(TPropertyCRCMap::value_type(dwCRC, pProperty));
|
||||
|
||||
if (ppProperty)
|
||||
*ppProperty = pProperty;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::Get(const char * c_pszFileName, CProperty ** ppProperty)
|
||||
{
|
||||
return Register(c_pszFileName, ppProperty);
|
||||
}
|
||||
|
||||
bool CPropertyManager::Get(DWORD dwCRC, CProperty ** ppProperty)
|
||||
{
|
||||
TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC);
|
||||
|
||||
if (m_PropertyByCRCMap.end() == itor)
|
||||
return false;
|
||||
|
||||
*ppProperty = itor->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::Put(const char * c_pszFileName, const char * c_pszSourceFileName)
|
||||
{
|
||||
if (!CopyFile(c_pszSourceFileName, c_pszFileName, FALSE))
|
||||
return false;
|
||||
|
||||
if (!m_isFileMode) // 팩 파일에도 넣음
|
||||
{
|
||||
if (!m_pack.Put(c_pszFileName, NULL, COMPRESSED_TYPE_NONE,""))
|
||||
{
|
||||
assert(!"CPropertyManager::Put cannot write to pack file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Register(c_pszFileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::Erase(DWORD dwCRC)
|
||||
{
|
||||
TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC);
|
||||
|
||||
if (m_PropertyByCRCMap.end() == itor)
|
||||
return false;
|
||||
|
||||
CProperty * pProperty = itor->second;
|
||||
m_PropertyByCRCMap.erase(itor);
|
||||
|
||||
DeleteFile(pProperty->GetFileName());
|
||||
ReserveCRC(pProperty->GetCRC());
|
||||
|
||||
if (!m_isFileMode) // 파일 모드가 아니면 팩에서도 지움
|
||||
m_pack.Delete(pProperty->GetFileName());
|
||||
|
||||
FILE * fp = fopen("property/reserve", "a+");
|
||||
|
||||
if (!fp)
|
||||
LogBox("\277\271\276\340 CRC \306\304\300\317\300\273 \277\255 \274\366 \276\370\275\300\264\317\264\331.");
|
||||
else
|
||||
{
|
||||
char szCRC[64 + 1];
|
||||
_snprintf(szCRC, sizeof(szCRC), "%u\r\n", pProperty->GetCRC());
|
||||
|
||||
fputs(szCRC, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
delete pProperty;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::Erase(const char * c_pszFileName)
|
||||
{
|
||||
CProperty * pProperty = NULL;
|
||||
|
||||
if (Get(c_pszFileName, &pProperty))
|
||||
return Erase(pProperty->GetCRC());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CPropertyManager::Clear()
|
||||
{
|
||||
stl_wipe_second(m_PropertyByCRCMap);
|
||||
}
|
||||
@@ -0,0 +1,353 @@
|
||||
#include "StdAfx.h"
|
||||
#include "SnowEnvironment.h"
|
||||
|
||||
#include "../EterLib/StateManager.h"
|
||||
#include "../EterLib/Camera.h"
|
||||
#include "../EterLib/ResourceManager.h"
|
||||
#include "SnowParticle.h"
|
||||
|
||||
void CSnowEnvironment::Enable()
|
||||
{
|
||||
if (!m_bSnowEnable)
|
||||
{
|
||||
Create();
|
||||
}
|
||||
|
||||
m_bSnowEnable = TRUE;
|
||||
}
|
||||
|
||||
void CSnowEnvironment::Disable()
|
||||
{
|
||||
m_bSnowEnable = FALSE;
|
||||
}
|
||||
|
||||
void CSnowEnvironment::Update(const D3DXVECTOR3 & c_rv3Pos)
|
||||
{
|
||||
if (!m_bSnowEnable)
|
||||
{
|
||||
if (m_kVct_pkParticleSnow.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
m_v3Center=c_rv3Pos;
|
||||
}
|
||||
|
||||
void CSnowEnvironment::Deform()
|
||||
{
|
||||
if (!m_bSnowEnable)
|
||||
{
|
||||
if (m_kVct_pkParticleSnow.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
const D3DXVECTOR3 & c_rv3Pos=m_v3Center;
|
||||
|
||||
static long s_lLastTime = CTimer::Instance().GetCurrentMillisecond();
|
||||
long lcurTime = CTimer::Instance().GetCurrentMillisecond();
|
||||
float fElapsedTime = float(lcurTime - s_lLastTime) / 1000.0f;
|
||||
s_lLastTime = lcurTime;
|
||||
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCamera)
|
||||
return;
|
||||
|
||||
const D3DXVECTOR3 & c_rv3View = pCamera->GetView();
|
||||
|
||||
D3DXVECTOR3 v3ChangedPos = c_rv3View * 3500.0f + c_rv3Pos;
|
||||
v3ChangedPos.z = c_rv3Pos.z;
|
||||
|
||||
std::vector<CSnowParticle*>::iterator itor = m_kVct_pkParticleSnow.begin();
|
||||
for (; itor != m_kVct_pkParticleSnow.end();)
|
||||
{
|
||||
CSnowParticle * pSnow = *itor;
|
||||
pSnow->Update(fElapsedTime, v3ChangedPos);
|
||||
|
||||
if (!pSnow->IsActivate())
|
||||
{
|
||||
CSnowParticle::Delete(pSnow);
|
||||
|
||||
itor = m_kVct_pkParticleSnow.erase(itor);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itor;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bSnowEnable)
|
||||
{
|
||||
for (int p = 0; p < min(10, m_dwParticleMaxNum - m_kVct_pkParticleSnow.size()); ++p)
|
||||
{
|
||||
CSnowParticle * pSnowParticle = CSnowParticle::New();
|
||||
pSnowParticle->Init(v3ChangedPos);
|
||||
m_kVct_pkParticleSnow.push_back(pSnowParticle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSnowEnvironment::__BeginBlur()
|
||||
{
|
||||
if (!m_bBlurEnable)
|
||||
return;
|
||||
|
||||
ms_lpd3dDevice->GetRenderTarget(&m_lpOldSurface);
|
||||
ms_lpd3dDevice->GetDepthStencilSurface(&m_lpOldDepthStencilSurface);
|
||||
ms_lpd3dDevice->SetRenderTarget(m_lpSnowRenderTargetSurface, m_lpSnowDepthSurface);
|
||||
ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
|
||||
}
|
||||
|
||||
void CSnowEnvironment::__ApplyBlur()
|
||||
{
|
||||
if (!m_bBlurEnable)
|
||||
return;
|
||||
|
||||
// {
|
||||
// STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
|
||||
// STATEMANAGER.SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
||||
// STATEMANAGER.SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||||
// STATEMANAGER.SetRenderState( D3DRS_COLORVERTEX ,TRUE);
|
||||
// STATEMANAGER.SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE , D3DMCS_COLOR1 );
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
// DWORD alphaColor = 0xFFFFFF | ((DWORD)(0.6f*255.0f) << 24);
|
||||
//
|
||||
// BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f, alphaColor, 0,0) ,
|
||||
// BlurVertex(D3DXVECTOR3(wTextureSize,0.0f,0.0f),1.0f, alphaColor, 1,0) ,
|
||||
// BlurVertex(D3DXVECTOR3(0.0f,wTextureSize,0.0f),1.0f, alphaColor, 0,1) ,
|
||||
// BlurVertex(D3DXVECTOR3(wTextureSize,wTextureSize,0.0f),1.0f, alphaColor, 1,1) };
|
||||
// //누적 블러 텍스쳐를 찍는다.
|
||||
// STATEMANAGER.SetTexture(0,m_lpAccumTexture);
|
||||
// STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
|
||||
// STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// STATEMANAGER.SetRenderTarget(m_lpAccumRenderTargetSurface, m_lpAccumDepthSurface);
|
||||
//
|
||||
// BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f, 0xFFFFFF, 0,0) ,
|
||||
// BlurVertex(D3DXVECTOR3(wTextureSize,0.0f,0.0f),1.0f, 0xFFFFFF, 1,0) ,
|
||||
// BlurVertex(D3DXVECTOR3(0.0f,wTextureSize,0.0f),1.0f, 0xFFFFFF, 0,1) ,
|
||||
// BlurVertex(D3DXVECTOR3(wTextureSize,wTextureSize,0.0f),1.0f, 0xFFFFFF, 1,1) };
|
||||
//
|
||||
// STATEMANAGER.SetTexture(0,m_lpSnowTexture);
|
||||
// STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
// STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
|
||||
// STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
|
||||
// }
|
||||
|
||||
///////////////
|
||||
{
|
||||
ms_lpd3dDevice->SetRenderTarget(m_lpOldSurface, m_lpOldDepthStencilSurface);
|
||||
|
||||
STATEMANAGER.SetTexture(0,m_lpSnowTexture);
|
||||
STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
m_lpOldSurface->GetDesc(&desc);
|
||||
float sx = (float)desc.Width ;
|
||||
float sy = (float)desc.Height;
|
||||
SAFE_RELEASE( m_lpOldSurface );
|
||||
SAFE_RELEASE( m_lpOldDepthStencilSurface );
|
||||
|
||||
BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f ,0xFFFFFF, 0,0) ,
|
||||
BlurVertex(D3DXVECTOR3(sx,0.0f,0.0f),1.0f ,0xFFFFFF, 1,0) ,
|
||||
BlurVertex(D3DXVECTOR3(0.0f,sy,0.0f),1.0f ,0xFFFFFF, 0,1) ,
|
||||
BlurVertex(D3DXVECTOR3(sx,sy,0.0f),1.0f ,0xFFFFFF, 1,1) };
|
||||
|
||||
STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
|
||||
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
|
||||
}
|
||||
}
|
||||
|
||||
void CSnowEnvironment::Render()
|
||||
{
|
||||
if (!m_bSnowEnable)
|
||||
{
|
||||
if (m_kVct_pkParticleSnow.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
__BeginBlur();
|
||||
|
||||
DWORD dwParticleCount = min(m_dwParticleMaxNum, m_kVct_pkParticleSnow.size());
|
||||
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCamera)
|
||||
return;
|
||||
|
||||
const D3DXVECTOR3 & c_rv3Up = pCamera->GetUp();
|
||||
const D3DXVECTOR3 & c_rv3Cross = pCamera->GetCross();
|
||||
|
||||
SParticleVertex * pv3Verticies;
|
||||
if (SUCCEEDED(m_pVB->Lock(0, sizeof(SParticleVertex)*dwParticleCount*4, (BYTE **) &pv3Verticies, D3DLOCK_DISCARD)))
|
||||
{
|
||||
int i = 0;
|
||||
std::vector<CSnowParticle*>::iterator itor = m_kVct_pkParticleSnow.begin();
|
||||
for (; i < dwParticleCount && itor != m_kVct_pkParticleSnow.end(); ++i, ++itor)
|
||||
{
|
||||
CSnowParticle * pSnow = *itor;
|
||||
pSnow->SetCameraVertex(c_rv3Up, c_rv3Cross);
|
||||
pSnow->GetVerticies(pv3Verticies[i*4+0],
|
||||
pv3Verticies[i*4+1],
|
||||
pv3Verticies[i*4+2],
|
||||
pv3Verticies[i*4+3]);
|
||||
}
|
||||
m_pVB->Unlock();
|
||||
}
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
m_pImageInstance->GetGraphicImagePointer()->GetTextureReference().SetTextureStage(0);
|
||||
STATEMANAGER.SetIndices(m_pIB, 0);
|
||||
STATEMANAGER.SetStreamSource(0, m_pVB, sizeof(SParticleVertex));
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1);
|
||||
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, dwParticleCount*4, 0, dwParticleCount*2);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
||||
|
||||
__ApplyBlur();
|
||||
}
|
||||
|
||||
bool CSnowEnvironment::__CreateBlurTexture()
|
||||
{
|
||||
if (!m_bBlurEnable)
|
||||
return true;
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateTexture(m_wBlurTextureSize, m_wBlurTextureSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_lpSnowTexture)))
|
||||
return false;
|
||||
if (FAILED(m_lpSnowTexture->GetSurfaceLevel(0, &m_lpSnowRenderTargetSurface)))
|
||||
return false;
|
||||
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wBlurTextureSize, m_wBlurTextureSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpSnowDepthSurface)))
|
||||
return false;
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateTexture(m_wBlurTextureSize, m_wBlurTextureSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_lpAccumTexture)))
|
||||
return false;
|
||||
if (FAILED(m_lpAccumTexture->GetSurfaceLevel(0, &m_lpAccumRenderTargetSurface)))
|
||||
return false;
|
||||
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wBlurTextureSize, m_wBlurTextureSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpAccumDepthSurface)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSnowEnvironment::__CreateGeometry()
|
||||
{
|
||||
if (FAILED(ms_lpd3dDevice->CreateVertexBuffer(sizeof(SParticleVertex)*m_dwParticleMaxNum*4,
|
||||
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,
|
||||
D3DFVF_XYZ | D3DFVF_TEX1,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
&m_pVB)))
|
||||
return false;
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateIndexBuffer(sizeof(WORD)*m_dwParticleMaxNum*6,
|
||||
D3DUSAGE_WRITEONLY,
|
||||
D3DFMT_INDEX16,
|
||||
D3DPOOL_MANAGED,
|
||||
&m_pIB)))
|
||||
return false;
|
||||
|
||||
WORD* dstIndices;
|
||||
if (FAILED(m_pIB->Lock(0, sizeof(WORD)*m_dwParticleMaxNum*6, (BYTE**)&dstIndices, 0)))
|
||||
return false;
|
||||
|
||||
const WORD c_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, };
|
||||
for (int i = 0; i < m_dwParticleMaxNum; ++i)
|
||||
{
|
||||
for (int j = 0; j < 6; ++j)
|
||||
{
|
||||
dstIndices[i*6 + j] = i*4 + c_awFillRectIndices[j];
|
||||
}
|
||||
}
|
||||
|
||||
m_pIB->Unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSnowEnvironment::Create()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
if (!__CreateBlurTexture())
|
||||
return false;
|
||||
|
||||
if (!__CreateGeometry())
|
||||
return false;
|
||||
|
||||
CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir work/special/snow.dds");
|
||||
m_pImageInstance = CGraphicImageInstance::New();
|
||||
m_pImageInstance->SetImagePointer(pImage);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSnowEnvironment::Destroy()
|
||||
{
|
||||
SAFE_RELEASE(m_lpSnowTexture);
|
||||
SAFE_RELEASE(m_lpSnowRenderTargetSurface);
|
||||
SAFE_RELEASE(m_lpSnowDepthSurface);
|
||||
SAFE_RELEASE(m_lpAccumTexture);
|
||||
SAFE_RELEASE(m_lpAccumRenderTargetSurface);
|
||||
SAFE_RELEASE(m_lpAccumDepthSurface);
|
||||
SAFE_RELEASE(m_pVB);
|
||||
SAFE_RELEASE(m_pIB);
|
||||
|
||||
stl_wipe(m_kVct_pkParticleSnow);
|
||||
CSnowParticle::DestroyPool();
|
||||
|
||||
if (m_pImageInstance)
|
||||
{
|
||||
CGraphicImageInstance::Delete(m_pImageInstance);
|
||||
m_pImageInstance = NULL;
|
||||
}
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
void CSnowEnvironment::__Initialize()
|
||||
{
|
||||
m_bSnowEnable = FALSE;
|
||||
m_lpSnowTexture = NULL;
|
||||
m_lpSnowRenderTargetSurface = NULL;
|
||||
m_lpSnowDepthSurface = NULL;
|
||||
m_lpAccumTexture = NULL;
|
||||
m_lpAccumRenderTargetSurface = NULL;
|
||||
m_lpAccumDepthSurface = NULL;
|
||||
m_pVB = NULL;
|
||||
m_pIB = NULL;
|
||||
m_pImageInstance = NULL;
|
||||
|
||||
m_kVct_pkParticleSnow.reserve(m_dwParticleMaxNum);
|
||||
}
|
||||
|
||||
CSnowEnvironment::CSnowEnvironment()
|
||||
{
|
||||
m_bBlurEnable = FALSE;
|
||||
m_dwParticleMaxNum = 3000;
|
||||
m_wBlurTextureSize = 512;
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
CSnowEnvironment::~CSnowEnvironment()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
#include "StdAfx.h"
|
||||
#include "SnowParticle.h"
|
||||
|
||||
const float c_fSnowDistance = 70000.0f;
|
||||
|
||||
std::vector<CSnowParticle*> CSnowParticle::ms_kVct_SnowParticlePool;
|
||||
|
||||
void CSnowParticle::SetCameraVertex(const D3DXVECTOR3 & rv3Up, const D3DXVECTOR3 & rv3Cross)
|
||||
{
|
||||
m_v3Up = rv3Up*m_fHalfWidth;
|
||||
m_v3Cross = rv3Cross*m_fHalfHeight;
|
||||
}
|
||||
|
||||
bool CSnowParticle::IsActivate()
|
||||
{
|
||||
return m_bActivate;
|
||||
}
|
||||
|
||||
void CSnowParticle::Update(float fElapsedTime, const D3DXVECTOR3 & c_rv3Pos)
|
||||
{
|
||||
m_v3Position += m_v3Velocity * fElapsedTime;
|
||||
|
||||
m_v3Position.x += m_v3Cross.x * sin(m_fcurRadian) / 10.0f;
|
||||
m_v3Position.y += m_v3Cross.y * sin(m_fcurRadian) / 10.0f;
|
||||
m_fcurRadian += m_fPeriod * fElapsedTime;
|
||||
|
||||
if (m_v3Position.z < c_rv3Pos.z - 500.0f)
|
||||
m_bActivate = false;
|
||||
else if (abs(m_v3Position.x - c_rv3Pos.x) > c_fSnowDistance)
|
||||
m_bActivate = false;
|
||||
else if (abs(m_v3Position.y - c_rv3Pos.y) > c_fSnowDistance)
|
||||
m_bActivate = false;
|
||||
}
|
||||
|
||||
void CSnowParticle::GetVerticies(SParticleVertex & rv3Vertex1, SParticleVertex & rv3Vertex2,
|
||||
SParticleVertex & rv3Vertex3, SParticleVertex & rv3Vertex4)
|
||||
{
|
||||
rv3Vertex1.v3Pos = m_v3Position - m_v3Cross - m_v3Up;
|
||||
rv3Vertex1.u = 0.0f;
|
||||
rv3Vertex1.v = 0.0f;
|
||||
|
||||
rv3Vertex2.v3Pos = m_v3Position + m_v3Cross - m_v3Up;
|
||||
rv3Vertex2.u = 1.0f;
|
||||
rv3Vertex2.v = 0.0f;
|
||||
|
||||
rv3Vertex3.v3Pos = m_v3Position - m_v3Cross + m_v3Up;
|
||||
rv3Vertex3.u = 0.0f;
|
||||
rv3Vertex3.v = 1.0f;
|
||||
|
||||
rv3Vertex4.v3Pos = m_v3Position + m_v3Cross + m_v3Up;
|
||||
rv3Vertex4.u = 1.0f;
|
||||
rv3Vertex4.v = 1.0f;
|
||||
}
|
||||
|
||||
void CSnowParticle::Init(const D3DXVECTOR3 & c_rv3Pos)
|
||||
{
|
||||
float fRot = frandom(0.0f, 36000.0f) / 100.0f;
|
||||
float fDistance = frandom(0.0f, c_fSnowDistance) / 10.0f;
|
||||
|
||||
m_v3Position.x = c_rv3Pos.x + fDistance*sin((double)D3DXToRadian(fRot));
|
||||
m_v3Position.y = c_rv3Pos.y + fDistance*cos((double)D3DXToRadian(fRot));
|
||||
m_v3Position.z = c_rv3Pos.z + frandom(1500.0f, 2000.0f);
|
||||
m_v3Velocity.x = 0.0f;
|
||||
m_v3Velocity.y = 0.0f;
|
||||
m_v3Velocity.z = frandom(-50.0f, -200.0f);
|
||||
m_fHalfWidth = frandom(2.0f, 7.0f);
|
||||
m_fHalfHeight = m_fHalfWidth;
|
||||
m_bActivate = true;
|
||||
m_bChangedSize = false;
|
||||
|
||||
m_fPeriod = frandom(1.5f, 5.0f);
|
||||
m_fcurRadian = frandom(-1.6f, 1.6f);
|
||||
m_fAmplitude = frandom(1.0f, 3.0f);
|
||||
}
|
||||
|
||||
CSnowParticle * CSnowParticle::New()
|
||||
{
|
||||
if (ms_kVct_SnowParticlePool.empty())
|
||||
{
|
||||
return new CSnowParticle;
|
||||
}
|
||||
|
||||
CSnowParticle * pParticle = ms_kVct_SnowParticlePool.back();
|
||||
ms_kVct_SnowParticlePool.pop_back();
|
||||
return pParticle;
|
||||
}
|
||||
|
||||
void CSnowParticle::Delete(CSnowParticle * pSnowParticle)
|
||||
{
|
||||
ms_kVct_SnowParticlePool.push_back(pSnowParticle);
|
||||
}
|
||||
|
||||
void CSnowParticle::DestroyPool()
|
||||
{
|
||||
stl_wipe(ms_kVct_SnowParticlePool);
|
||||
}
|
||||
|
||||
CSnowParticle::CSnowParticle()
|
||||
{
|
||||
}
|
||||
CSnowParticle::~CSnowParticle()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
struct SParticleVertex
|
||||
{
|
||||
D3DXVECTOR3 v3Pos;
|
||||
float u, v;
|
||||
};
|
||||
|
||||
struct BlurVertex
|
||||
{
|
||||
D3DXVECTOR3 pos;
|
||||
FLOAT rhw;
|
||||
DWORD color;
|
||||
FLOAT tu, tv;
|
||||
|
||||
static const DWORD FVF;
|
||||
|
||||
BlurVertex(D3DXVECTOR3 p, float w,DWORD c,float u,float v):pos(p),rhw(w),color(c),tu(u),tv(v) {}
|
||||
~BlurVertex(){};
|
||||
};
|
||||
|
||||
class CSnowParticle
|
||||
{
|
||||
public:
|
||||
CSnowParticle();
|
||||
~CSnowParticle();
|
||||
|
||||
static CSnowParticle * New();
|
||||
static void Delete(CSnowParticle * pSnowParticle);
|
||||
static void DestroyPool();
|
||||
|
||||
void Init(const D3DXVECTOR3 & c_rv3Pos);
|
||||
|
||||
void SetCameraVertex(const D3DXVECTOR3 & rv3Up, const D3DXVECTOR3 & rv3Cross);
|
||||
bool IsActivate();
|
||||
|
||||
void Update(float fElapsedTime, const D3DXVECTOR3 & c_rv3Pos);
|
||||
void GetVerticies(SParticleVertex & rv3Vertex1, SParticleVertex & rv3Vertex2,
|
||||
SParticleVertex & rv3Vertex3, SParticleVertex & rv3Vertex4);
|
||||
|
||||
protected:
|
||||
bool m_bActivate;
|
||||
bool m_bChangedSize;
|
||||
float m_fHalfWidth;
|
||||
float m_fHalfHeight;
|
||||
|
||||
D3DXVECTOR3 m_v3Velocity;
|
||||
D3DXVECTOR3 m_v3Position;
|
||||
|
||||
D3DXVECTOR3 m_v3Up;
|
||||
D3DXVECTOR3 m_v3Cross;
|
||||
|
||||
float m_fPeriod;
|
||||
float m_fcurRadian;
|
||||
float m_fAmplitude;
|
||||
|
||||
public:
|
||||
static std::vector<CSnowParticle*> ms_kVct_SnowParticlePool;
|
||||
};
|
||||
@@ -0,0 +1,180 @@
|
||||
// TerrainDecal.cpp: implementation of the CTerrainDecal class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "../EterLib/StateManager.h"
|
||||
#include "../PRTerrainLib/StdAfx.h"
|
||||
|
||||
#include "TerrainDecal.h"
|
||||
#include "MapOutdoor.h"
|
||||
#include "AreaTerrain.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CTerrainDecal::CTerrainDecal(CMapOutdoor * pMapOutdoor):m_pMapOutdoor(pMapOutdoor)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CTerrainDecal::~CTerrainDecal()
|
||||
{
|
||||
CDecal::Clear();
|
||||
}
|
||||
|
||||
void CTerrainDecal::Make(D3DXVECTOR3 v3Center, D3DXVECTOR3 v3Normal, D3DXVECTOR3 v3Tangent, float fWidth, float fHeight, float fDepth)
|
||||
{
|
||||
Clear();
|
||||
m_v3Center = v3Center;
|
||||
m_v3Normal = v3Normal;
|
||||
|
||||
D3DXVECTOR3 v3Binormal;
|
||||
D3DXVec3Normalize(&v3Normal, &v3Normal);
|
||||
D3DXVec3Normalize(&v3Tangent, &v3Tangent);
|
||||
D3DXVec3Cross(&v3Binormal, &m_v3Normal, &v3Tangent);
|
||||
D3DXVec3Normalize(&v3Binormal, &v3Binormal);
|
||||
|
||||
// Calculate boundary planes
|
||||
float fd = D3DXVec3Dot(&m_v3Center, &v3Tangent);
|
||||
m_v4LeftPlane = D3DXPLANE(v3Tangent.x, v3Tangent.y, v3Tangent.z, fWidth * 0.5f - fd);
|
||||
m_v4RightPlane = D3DXPLANE(-v3Tangent.x, -v3Tangent.y, -v3Tangent.z, fWidth * 0.5f + fd);
|
||||
|
||||
fd = D3DXVec3Dot(&m_v3Center, &v3Binormal);
|
||||
m_v4BottomPlane = D3DXPLANE(v3Binormal.x, v3Binormal.y, v3Binormal.z, fHeight * 0.5f - fd);
|
||||
m_v4TopPlane = D3DXPLANE(-v3Binormal.x, -v3Binormal.y, -v3Binormal.z, fHeight * 0.5f + fd);
|
||||
|
||||
fd = D3DXVec3Dot(&m_v3Center, &m_v3Normal);
|
||||
m_v4FrontPlane = D3DXPLANE(-m_v3Normal.x, -m_v3Normal.y, -m_v3Normal.z, fDepth + fd);
|
||||
m_v4BackPlane = D3DXPLANE(m_v3Normal.x, m_v3Normal.y, m_v3Normal.z, fDepth - fd);
|
||||
|
||||
// Begin with empty mesh
|
||||
m_dwVertexCount = 0;
|
||||
m_dwPrimitiveCount = 0;
|
||||
|
||||
// Add this point, determine which surfaces may be affected by this decal and call ClipMesh().
|
||||
|
||||
float fSearchRadius = fMAX(fWidth, fHeight);// 0.75f >= sqrtf(2)/2;
|
||||
float fMinX = v3Center.x - fSearchRadius;
|
||||
float fMaxX = v3Center.x + fSearchRadius;
|
||||
float fMinY = fabs(v3Center.y) - fSearchRadius;
|
||||
float fMaxY = fabs(v3Center.y) + fSearchRadius;
|
||||
|
||||
DWORD dwAffectedPrimitiveCount = 0;
|
||||
D3DXVECTOR3 v3AffectedVertex[MAX_SEARCH_VERTICES];
|
||||
D3DXVECTOR3 v3AffectedNormal[MAX_SEARCH_VERTICES];
|
||||
memset(v3AffectedVertex, 0, sizeof(v3AffectedVertex));
|
||||
memset(v3AffectedNormal, 0, sizeof(v3AffectedNormal));
|
||||
|
||||
SearchAffectedTerrainMesh(fMinX, fMaxX, fMinY, fMaxY, &dwAffectedPrimitiveCount, v3AffectedVertex, v3AffectedNormal);
|
||||
|
||||
ClipMesh(dwAffectedPrimitiveCount, v3AffectedVertex, v3AffectedNormal);
|
||||
|
||||
// Assign texture mapping coordinates
|
||||
float fOne_over_w = 1.0f / fWidth;
|
||||
float fOne_over_h = 1.0f / fHeight;
|
||||
for (DWORD dwi = 0; dwi < m_dwVertexCount; ++dwi)
|
||||
{
|
||||
D3DXVECTOR3 v3 = m_Vertices[dwi].position - m_v3Center;
|
||||
float fu = -D3DXVec3Dot(&v3, &v3Binormal) * fOne_over_w + 0.5f;
|
||||
float fv = -D3DXVec3Dot(&v3, &v3Tangent) * fOne_over_h + 0.5f;
|
||||
m_Vertices[dwi].texCoord = D3DXVECTOR2(fu, fv);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void CTerrainDecal::Update()
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
void CTerrainDecal::Render()
|
||||
{
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
CDecal::Render();
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
}
|
||||
|
||||
void CTerrainDecal::SearchAffectedTerrainMesh(float fMinX,
|
||||
float fMaxX,
|
||||
float fMinY,
|
||||
float fMaxY,
|
||||
DWORD * pdwAffectedPrimitiveCount,
|
||||
D3DXVECTOR3 * pv3AffectedVertex,
|
||||
D3DXVECTOR3 * pv3AffectedNormal)
|
||||
{
|
||||
if (!m_pMapOutdoor)
|
||||
return;
|
||||
int iMinX, iMaxX, iMinY, iMaxY;
|
||||
PR_FLOAT_TO_INT(fMinX, iMinX);
|
||||
PR_FLOAT_TO_INT(fMaxX, iMaxX);
|
||||
PR_FLOAT_TO_INT(fMinY, iMinY);
|
||||
PR_FLOAT_TO_INT(fMaxY, iMaxY);
|
||||
|
||||
iMinX -= iMinX % CTerrainImpl::CELLSCALE;
|
||||
iMaxX -= iMaxX % CTerrainImpl::CELLSCALE;
|
||||
iMinY -= iMinY % CTerrainImpl::CELLSCALE;
|
||||
iMaxY -= iMaxY % CTerrainImpl::CELLSCALE;
|
||||
|
||||
for(int iy = iMinY; iy <= iMaxY; iy += CTerrainImpl::CELLSCALE)
|
||||
{
|
||||
if (iy < 0)
|
||||
continue;
|
||||
WORD wTerrainNumY = iy / CTerrainImpl::TERRAIN_YSIZE;
|
||||
for(int ix = iMinX; ix <= iMaxX; ix += CTerrainImpl::CELLSCALE)
|
||||
{
|
||||
if (ix < 0)
|
||||
continue;
|
||||
WORD wTerrainNumX = ix / CTerrainImpl::TERRAIN_YSIZE;
|
||||
|
||||
BYTE byTerrainNum;
|
||||
if (!m_pMapOutdoor->GetTerrainNumFromCoord(wTerrainNumX, wTerrainNumY, &byTerrainNum))
|
||||
continue;
|
||||
CTerrain * pTerrain;
|
||||
if (!m_pMapOutdoor->GetTerrainPointer(byTerrainNum, &pTerrain))
|
||||
continue;
|
||||
|
||||
float fHeightLT = pTerrain->GetHeight(ix, iy) + m_cfDecalEpsilon;
|
||||
float fHeightRT = pTerrain->GetHeight(ix + CTerrainImpl::CELLSCALE, iy) + m_cfDecalEpsilon;
|
||||
float fHeightLB = pTerrain->GetHeight(ix, iy + CTerrainImpl::CELLSCALE) + m_cfDecalEpsilon;
|
||||
float fHeightRB = pTerrain->GetHeight(ix + CTerrainImpl::CELLSCALE, iy + CTerrainImpl::CELLSCALE) + m_cfDecalEpsilon;
|
||||
|
||||
*pdwAffectedPrimitiveCount += 2;
|
||||
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy), fHeightLT);
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy - CTerrainImpl::CELLSCALE), fHeightLB);
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy), fHeightRT);
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy), fHeightRT);
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy - CTerrainImpl::CELLSCALE), fHeightLB);
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy - CTerrainImpl::CELLSCALE), fHeightRB);
|
||||
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
// TerrainPatch.cpp: implementation of the CTerrainPatch class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "TerrainPatch.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CTerrainPatch::SSoftwareTransformPatch::SSoftwareTransformPatch()
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
CTerrainPatch::SSoftwareTransformPatch::~SSoftwareTransformPatch()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CTerrainPatch::SSoftwareTransformPatch::Create()
|
||||
{
|
||||
assert(NULL==m_akTerrainVertex);
|
||||
m_akTerrainVertex=new SoftwareTransformPatch_SSourceVertex[TERRAIN_VERTEX_COUNT];
|
||||
}
|
||||
|
||||
void CTerrainPatch::SSoftwareTransformPatch::Destroy()
|
||||
{
|
||||
if (m_akTerrainVertex)
|
||||
delete [] m_akTerrainVertex;
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
void CTerrainPatch::SSoftwareTransformPatch::__Initialize()
|
||||
{
|
||||
m_akTerrainVertex=NULL;
|
||||
}
|
||||
|
||||
bool CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE=TRUE;
|
||||
|
||||
void CTerrainPatch::Clear()
|
||||
{
|
||||
m_kHT.m_kVB.Destroy();
|
||||
m_kST.Destroy();
|
||||
|
||||
m_WaterVertexBuffer.Destroy();
|
||||
ClearID();
|
||||
SetUse(false);
|
||||
|
||||
m_bWaterExist = false;
|
||||
m_bNeedUpdate = true;
|
||||
|
||||
m_dwWaterPriCount = 0;
|
||||
m_byType = PATCH_TYPE_PLAIN;
|
||||
|
||||
m_fMinX = m_fMaxX = m_fMinY = m_fMaxY = m_fMinZ = m_fMaxZ = 0.0f;
|
||||
|
||||
m_dwVersion=0;
|
||||
}
|
||||
|
||||
void CTerrainPatch::BuildWaterVertexBuffer(SWaterVertex* akSrcVertex, UINT uWaterVertexCount)
|
||||
{
|
||||
CGraphicVertexBuffer& rkVB=m_WaterVertexBuffer;
|
||||
|
||||
if (!rkVB.Create(uWaterVertexCount, D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
|
||||
return;
|
||||
|
||||
SWaterVertex* akDstWaterVertex;
|
||||
if (rkVB.Lock((void **) &akDstWaterVertex))
|
||||
{
|
||||
UINT uVBSize=sizeof(SWaterVertex)*uWaterVertexCount;
|
||||
memcpy(akDstWaterVertex, akSrcVertex, uVBSize);
|
||||
m_dwWaterPriCount=uWaterVertexCount/3;
|
||||
|
||||
rkVB.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void CTerrainPatch::BuildTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
|
||||
{
|
||||
if (SOFTWARE_TRANSFORM_PATCH_ENABLE)
|
||||
__BuildSoftwareTerrainVertexBuffer(akSrcVertex);
|
||||
else
|
||||
__BuildHardwareTerrainVertexBuffer(akSrcVertex);
|
||||
}
|
||||
|
||||
void CTerrainPatch::__BuildSoftwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
|
||||
{
|
||||
//DWORD dwVBSize=sizeof(HardwareTransformPatch_SSourceVertex)*TERRAIN_VERTEX_COUNT;
|
||||
|
||||
m_kST.Create();
|
||||
|
||||
SoftwareTransformPatch_SSourceVertex* akDstVertex=SoftwareTransformPatch_GetTerrainVertexDataPtr();
|
||||
for (UINT uIndex=0; uIndex!=TERRAIN_VERTEX_COUNT; ++uIndex)
|
||||
{
|
||||
*((HardwareTransformPatch_SSourceVertex*)(akDstVertex+uIndex))=*(akSrcVertex+uIndex);
|
||||
akDstVertex[uIndex].dwDiffuse=0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
void CTerrainPatch::__BuildHardwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
|
||||
{
|
||||
|
||||
CGraphicVertexBuffer& rkVB=m_kHT.m_kVB;
|
||||
if (!rkVB.Create(TERRAIN_VERTEX_COUNT, D3DFVF_XYZ | D3DFVF_NORMAL, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
|
||||
return;
|
||||
|
||||
HardwareTransformPatch_SSourceVertex* akDstVertex;
|
||||
if (rkVB.Lock((void **) &akDstVertex))
|
||||
{
|
||||
UINT uVBSize=sizeof(HardwareTransformPatch_SSourceVertex)*TERRAIN_VERTEX_COUNT;
|
||||
|
||||
memcpy(akDstVertex, akSrcVertex, uVBSize);
|
||||
rkVB.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void CTerrainPatch::SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl)
|
||||
{
|
||||
if (m_dwVersion==dwVersion)
|
||||
return;
|
||||
|
||||
m_dwVersion=dwVersion;
|
||||
|
||||
SoftwareTransformPatch_SSourceVertex* akSrcVertex=SoftwareTransformPatch_GetTerrainVertexDataPtr();
|
||||
if (!akSrcVertex)
|
||||
return;
|
||||
|
||||
D3DXVECTOR3 kLightDir=c_rkLight.Direction;
|
||||
|
||||
|
||||
DWORD dwDot;
|
||||
DWORD dwAmbientR=(c_rkMtrl.Ambient.r*c_rkLight.Ambient.r+c_rkMtrl.Emissive.r)*255.0f;
|
||||
DWORD dwAmbientG=(c_rkMtrl.Ambient.g*c_rkLight.Ambient.g+c_rkMtrl.Emissive.g)*255.0f;
|
||||
DWORD dwAmbientB=(c_rkMtrl.Ambient.b*c_rkLight.Ambient.b+c_rkMtrl.Emissive.b)*255.0f;
|
||||
DWORD dwDiffuseR=(c_rkMtrl.Diffuse.r*c_rkLight.Diffuse.r)*255.0f;
|
||||
DWORD dwDiffuseG=(c_rkMtrl.Diffuse.g*c_rkLight.Diffuse.g)*255.0f;
|
||||
DWORD dwDiffuseB=(c_rkMtrl.Diffuse.b*c_rkLight.Diffuse.b)*255.0f;
|
||||
|
||||
if (dwDiffuseR>255-dwAmbientR)
|
||||
dwDiffuseR=255-dwAmbientR;
|
||||
|
||||
if (dwDiffuseG+dwAmbientG>255)
|
||||
dwDiffuseG=255-dwAmbientG;
|
||||
|
||||
if (dwDiffuseB+dwAmbientB>255)
|
||||
dwDiffuseB=255-dwAmbientB;
|
||||
|
||||
for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex)
|
||||
{
|
||||
float fDot=D3DXVec3Dot(&akSrcVertex[uIndex].kNormal, &kLightDir);
|
||||
|
||||
const float N=0xffffff;
|
||||
const int S=24;
|
||||
if (fDot<0.0f)
|
||||
dwDot=(N*-fDot);
|
||||
else
|
||||
dwDot=(N*+fDot);
|
||||
|
||||
akSrcVertex[uIndex].dwDiffuse=(0xff000000)|
|
||||
(((dwDiffuseR*dwDot>>S)+dwAmbientR)<<16)|
|
||||
(((dwDiffuseG*dwDot>>S)+dwAmbientG)<<8)|
|
||||
((dwDiffuseB*dwDot>>S)+dwAmbientB);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UINT CTerrainPatch::GetWaterFaceCount()
|
||||
{
|
||||
return m_dwWaterPriCount;
|
||||
}
|
||||
|
||||
CTerrainPatchProxy::CTerrainPatchProxy()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CTerrainPatchProxy::~CTerrainPatchProxy()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CTerrainPatchProxy::SetCenterPosition(const D3DXVECTOR3& c_rv3Center)
|
||||
{
|
||||
m_v3Center=c_rv3Center;
|
||||
}
|
||||
|
||||
bool CTerrainPatchProxy::IsIn(const D3DXVECTOR3& c_rv3Target, float fRadius)
|
||||
{
|
||||
float dx=m_v3Center.x-c_rv3Target.x;
|
||||
float dy=m_v3Center.y-c_rv3Target.y;
|
||||
float fDist=dx*dx+dy*dy;
|
||||
float fCheck=fRadius*fRadius;
|
||||
|
||||
if (fDist<fCheck)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CTerrainPatchProxy::SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl)
|
||||
{
|
||||
if (m_pTerrainPatch)
|
||||
m_pTerrainPatch->SoftwareTransformPatch_UpdateTerrainLighting(dwVersion, c_rkLight, c_rkMtrl);
|
||||
}
|
||||
|
||||
CGraphicVertexBuffer* CTerrainPatchProxy::HardwareTransformPatch_GetVertexBufferPtr()
|
||||
{
|
||||
if (m_pTerrainPatch)
|
||||
return m_pTerrainPatch->HardwareTransformPatch_GetVertexBufferPtr();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SoftwareTransformPatch_SSourceVertex* CTerrainPatchProxy::SoftwareTransformPatch_GetTerrainVertexDataPtr()
|
||||
{
|
||||
if (m_pTerrainPatch)
|
||||
return m_pTerrainPatch->SoftwareTransformPatch_GetTerrainVertexDataPtr();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UINT CTerrainPatchProxy::GetWaterFaceCount()
|
||||
{
|
||||
if (m_pTerrainPatch)
|
||||
return m_pTerrainPatch->GetWaterFaceCount();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CTerrainPatchProxy::Clear()
|
||||
{
|
||||
m_bUsed = false;
|
||||
m_sPatchNum = 0;
|
||||
m_byTerrainNum = 0xFF;
|
||||
|
||||
m_pTerrainPatch = NULL;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// TerrainQuadtreeNode.cpp: implementation of the CTerrainQuadtreeNode class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "TerrainQuadtree.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CTerrainQuadtree
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CTerrainQuadtreeNode
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
CTerrainQuadtreeNode::CTerrainQuadtreeNode():NW_Node(NULL), NE_Node(NULL), SW_Node(NULL), SE_Node(NULL), center(-1.0f, -1.0f, -1.0f)
|
||||
{
|
||||
x0 = y0 = x1 = y1 = 0;
|
||||
Size = 0;
|
||||
PatchNum = 0;
|
||||
radius = 0.0f;
|
||||
m_byLODLevel = 0;
|
||||
}
|
||||
|
||||
CTerrainQuadtreeNode::~CTerrainQuadtreeNode()
|
||||
{
|
||||
if (NW_Node)
|
||||
{
|
||||
delete NW_Node;
|
||||
NW_Node = NULL;
|
||||
}
|
||||
if (NE_Node)
|
||||
{
|
||||
delete NE_Node;
|
||||
NE_Node = NULL;
|
||||
}
|
||||
if (SW_Node)
|
||||
{
|
||||
delete SW_Node;
|
||||
SW_Node = NULL;
|
||||
}
|
||||
if (SE_Node)
|
||||
{
|
||||
delete SE_Node;
|
||||
SE_Node = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// TerrainQuadtreeNode.h: interface for the CTerrainQuadtreeNode class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_)
|
||||
#define AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
class CTerrainQuadtreeNode
|
||||
{
|
||||
public:
|
||||
CTerrainQuadtreeNode();
|
||||
virtual ~CTerrainQuadtreeNode();
|
||||
|
||||
public:
|
||||
long x0, y0, x1, y1;
|
||||
CTerrainQuadtreeNode * NW_Node;
|
||||
CTerrainQuadtreeNode * NE_Node;
|
||||
CTerrainQuadtreeNode * SW_Node;
|
||||
CTerrainQuadtreeNode * SE_Node;
|
||||
long Size;
|
||||
long PatchNum;
|
||||
D3DXVECTOR3 center;
|
||||
float radius;
|
||||
BYTE m_byLODLevel;
|
||||
};
|
||||
|
||||
|
||||
#endif // !defined(AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_)
|
||||
@@ -19,8 +19,7 @@
|
||||
|
||||
#include "../EterLib/StdAfx.h"
|
||||
#include "../EterGrnLib/StdAfx.h"
|
||||
// PORT: dropped #include "../ScriptLib/StdAfx.h": no PRTerrainLib file uses Python, and it would pull
|
||||
// CPython headers into every terrain translation unit.
|
||||
#include "../ScriptLib/StdAfx.h"
|
||||
|
||||
/* Fast Float<->Integer conversion */
|
||||
extern float PR_FCNV;
|
||||
|
||||
@@ -0,0 +1,329 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
|
||||
#include "Terrain.h"
|
||||
#include <math.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Texture Set
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CTextureSet * CTerrainImpl::ms_pTextureSet = NULL;
|
||||
|
||||
void CTerrainImpl::SetTextureSet(CTextureSet * pTextureSet)
|
||||
{
|
||||
static CTextureSet s_EmptyTextureSet;
|
||||
|
||||
if (!pTextureSet)
|
||||
ms_pTextureSet = &s_EmptyTextureSet;
|
||||
else
|
||||
ms_pTextureSet = pTextureSet;
|
||||
}
|
||||
|
||||
CTextureSet * CTerrainImpl::GetTextureSet()
|
||||
{
|
||||
if (!ms_pTextureSet)
|
||||
SetTextureSet(NULL);
|
||||
|
||||
return ms_pTextureSet;
|
||||
}
|
||||
|
||||
CTerrainImpl::CTerrainImpl()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CTerrainImpl::~CTerrainImpl()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CTerrainImpl::Initialize()
|
||||
{
|
||||
memset(m_lWaterHeight, -1, sizeof(m_lWaterHeight));
|
||||
|
||||
m_byNumWater = 0;
|
||||
memset(&m_HeightMapHeader, 0, sizeof(TGA_HEADER));
|
||||
memset(&m_awShadowMap, 0xFFFF, sizeof(m_awShadowMap));
|
||||
memset(&m_lpAlphaTexture, NULL, sizeof(m_lpAlphaTexture));
|
||||
|
||||
m_lViewRadius = 0;
|
||||
|
||||
m_wTileMapVersion = 8976;
|
||||
|
||||
m_fHeightScale = 0.0f;
|
||||
|
||||
m_lpShadowTexture = NULL;
|
||||
|
||||
m_lSplatTilesX = 0;
|
||||
m_lSplatTilesY = 0;
|
||||
}
|
||||
|
||||
void CTerrainImpl::Clear()
|
||||
{
|
||||
for (DWORD i = 0; i < GetTextureSet()->GetTextureCount(); ++i)
|
||||
{
|
||||
if (m_lpAlphaTexture[i])
|
||||
{
|
||||
m_lpAlphaTexture[i]->Release();
|
||||
m_lpAlphaTexture[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
bool CTerrainImpl::LoadHeightMap(const char*c_szFileName)
|
||||
{
|
||||
Tracef("LoadRawHeightMapFile %s ", c_szFileName);
|
||||
|
||||
CMappedFile kMappedFile;
|
||||
LPCVOID lpcvFileData;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
|
||||
{
|
||||
Tracen("Error");
|
||||
TraceError("CTerrainImpl::LoadHeightMap - %s OPEN ERROR", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(m_awRawHeightMap, lpcvFileData, sizeof(WORD)*HEIGHTMAP_RAW_XSIZE*HEIGHTMAP_RAW_YSIZE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTerrainImpl::LoadAttrMap(const char *c_szFileName)
|
||||
{
|
||||
DWORD dwStart = ELTimer_GetMSec();
|
||||
Tracef("LoadAttrMapFile %s ", c_szFileName);
|
||||
|
||||
CMappedFile kMappedFile;
|
||||
LPCVOID lpcvFileData;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
|
||||
{
|
||||
TraceError("CTerrainImpl::LoadAttrMap - %s OPEN ERROR", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD dwFileSize = kMappedFile.Size();
|
||||
BYTE * abFileData = (BYTE *) lpcvFileData;
|
||||
|
||||
// LoadAttrMap
|
||||
{
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct SAttrMapHeader
|
||||
{
|
||||
WORD m_wMagic;
|
||||
WORD m_wWidth;
|
||||
WORD m_wHeight;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
if (dwFileSize < sizeof(SAttrMapHeader))
|
||||
{
|
||||
TraceError(" CTerrainImpl::LoadAttrMap - %s FILE SIZE ERROR", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
SAttrMapHeader kAttrMapHeader;
|
||||
memcpy(&kAttrMapHeader, abFileData, sizeof(kAttrMapHeader));
|
||||
|
||||
const WORD c_wAttrMapMagic = 2634;
|
||||
if (c_wAttrMapMagic != kAttrMapHeader.m_wMagic)
|
||||
{
|
||||
TraceError("CTerrainImpl::LoadAttrMap - %s MAGIC NUMBER(%d!=MAGIC[%d]) ERROR", c_szFileName, kAttrMapHeader.m_wMagic, kAttrMapHeader.m_wMagic);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ATTRMAP_XSIZE != kAttrMapHeader.m_wWidth)
|
||||
{
|
||||
TraceError("CTerrainImpl::LoadAttrMap - kAttrMapHeader(%s).m_width(%d)!=ATTRMAP_XSIZE(%d)", c_szFileName, kAttrMapHeader.m_wWidth, ATTRMAP_XSIZE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ATTRMAP_YSIZE != kAttrMapHeader.m_wHeight)
|
||||
{
|
||||
TraceError("CTerrainImpl::LoadAttrMap - kAttrMapHeader(%s).m_height(%d)!=ATTRMAP_YSIZE(%d)", c_szFileName, kAttrMapHeader.m_wHeight, ATTRMAP_YSIZE);
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD dwFileRestSize=dwFileSize-sizeof(kAttrMapHeader);
|
||||
DWORD dwFileNeedSize=sizeof(m_abyAttrMap);
|
||||
if (dwFileRestSize != dwFileNeedSize)
|
||||
{
|
||||
TraceError("CTerrainImpl::LoadAttrMap - %s FILE DATA SIZE(rest %d != need %d) ERROR", c_szFileName, dwFileRestSize, dwFileNeedSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
BYTE* abSrcAttrData= abFileData+sizeof(kAttrMapHeader);
|
||||
memcpy(m_abyAttrMap, abSrcAttrData, sizeof(m_abyAttrMap));
|
||||
}
|
||||
|
||||
Tracef("%d\n", ELTimer_GetMSec() - dwStart);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTerrainImpl::RAW_LoadTileMap(const char * c_szFileName)
|
||||
{
|
||||
Tracef("LoadSplatFile %s ", c_szFileName);
|
||||
|
||||
CMappedFile kMappedFile;
|
||||
LPCVOID lpcvFileData;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
|
||||
{
|
||||
Tracen("Error");
|
||||
TraceError("CTerrainImpl::RAW_LoadTileMap - %s OPEN ERROR", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(m_abyTileMap, lpcvFileData, sizeof(BYTE)*(TILEMAP_RAW_XSIZE)*(TILEMAP_RAW_YSIZE));
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool CTerrainImpl::LoadWaterMap(const char * c_szFileName)
|
||||
{
|
||||
DWORD dwStart = ELTimer_GetMSec();
|
||||
|
||||
if (!LoadWaterMapFile(c_szFileName))
|
||||
{
|
||||
memset(m_abyWaterMap, 0xFF, sizeof(m_abyWaterMap));
|
||||
|
||||
m_byNumWater = 0;
|
||||
memset(m_lWaterHeight, -1, sizeof(m_lWaterHeight));
|
||||
|
||||
TraceError("CMapOutdoor::LoadWaterMap LoadWaterMapFile(%s) Failed", c_szFileName);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracef("LoadWaterMapFile %s %d\n", c_szFileName, ELTimer_GetMSec() - dwStart);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTerrainImpl::LoadWaterMapFile(const char * c_szFileName)
|
||||
{
|
||||
CMappedFile kMappedFile;
|
||||
LPCVOID lpcvFileData;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
|
||||
{
|
||||
Tracen("Error");
|
||||
TraceError("CTerrainImpl::LoadWaterMap - %s OPEN ERROR", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD dwFileSize = kMappedFile.Size();
|
||||
BYTE* abFileData = (BYTE*)lpcvFileData;
|
||||
|
||||
{
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct SWaterMapHeader
|
||||
{
|
||||
WORD m_wMagic;
|
||||
WORD m_wWidth;
|
||||
WORD m_wHeight;
|
||||
BYTE m_byLayerCount;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
if (dwFileSize < sizeof(SWaterMapHeader))
|
||||
{
|
||||
TraceError("CTerrainImpl::LoadWaterMap - %s FILE SIZE ERROR", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
SWaterMapHeader kWaterMapHeader;
|
||||
memcpy(&kWaterMapHeader, abFileData, sizeof(kWaterMapHeader));
|
||||
|
||||
const WORD c_wWaterMapMagic = 5426;
|
||||
|
||||
if (c_wWaterMapMagic != kWaterMapHeader.m_wMagic)
|
||||
{
|
||||
TraceError("CTerrainImpl::LoadWaterMap - %s MAGIC NUMBER(%d!=MAGIC[%d]) ERROR", c_szFileName, kWaterMapHeader.m_wMagic, c_wWaterMapMagic);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WATERMAP_XSIZE != kWaterMapHeader.m_wWidth)
|
||||
{
|
||||
TraceError("CTerrainImpl::LoadWaterMap - kWaterMapHeader(%s).m_width(%d)!=WATERMAP_XSIZE(%d)", c_szFileName, kWaterMapHeader.m_wWidth, WATERMAP_XSIZE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WATERMAP_YSIZE != kWaterMapHeader.m_wHeight)
|
||||
{
|
||||
TraceError("CTerrainImpl::LoadWaterMap - kWaterMapHeader(%s).m_height(%d)!=WATERMAP_YSIZE(%d)", c_szFileName, kWaterMapHeader.m_wHeight, WATERMAP_YSIZE);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_byNumWater = kWaterMapHeader.m_byLayerCount;
|
||||
|
||||
DWORD dwFileRestSize = dwFileSize - sizeof(kWaterMapHeader);
|
||||
DWORD dwFileNeedSize = sizeof(m_abyWaterMap) + sizeof(int32_t) * m_byNumWater; // PORT: the file's long is 32-bit
|
||||
DWORD dwFileNeedSize2 = sizeof(m_abyWaterMap) + sizeof(WORD) * m_byNumWater;
|
||||
if (dwFileRestSize == dwFileNeedSize2)
|
||||
{
|
||||
WORD wWaterHeight[MAX_WATER_NUM + 1];
|
||||
|
||||
BYTE * abSrcWaterData = abFileData + sizeof(kWaterMapHeader);
|
||||
memcpy(m_abyWaterMap, abSrcWaterData, sizeof(m_abyWaterMap));
|
||||
|
||||
BYTE * abSrcWaterHeight = abSrcWaterData + sizeof(m_abyWaterMap);
|
||||
|
||||
m_byNumWater = MIN(MAX_WATER_NUM, m_byNumWater);
|
||||
if (m_byNumWater)
|
||||
{
|
||||
memcpy(wWaterHeight, abSrcWaterHeight, sizeof(WORD) * m_byNumWater);
|
||||
|
||||
for (int i = 0; i < m_byNumWater; ++i)
|
||||
m_lWaterHeight[i] = wWaterHeight[i];
|
||||
}
|
||||
}
|
||||
else if (dwFileRestSize != dwFileNeedSize)
|
||||
{
|
||||
TraceError("CTerrainImpl::LoadWaterMap - %s FILE DATA SIZE(rest %d != need %d) ERROR", c_szFileName, dwFileRestSize, dwFileNeedSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
BYTE * abSrcWaterData = abFileData + sizeof(kWaterMapHeader);
|
||||
memcpy(m_abyWaterMap, abSrcWaterData, sizeof(m_abyWaterMap));
|
||||
|
||||
BYTE * abSrcWaterHeight = abSrcWaterData + sizeof(m_abyWaterMap);
|
||||
|
||||
if (m_byNumWater)
|
||||
for (int i = 0; i < m_byNumWater; ++i) // PORT: widen the file's 32-bit longs (LP64 long is 64-bit)
|
||||
{
|
||||
int32_t lHeight;
|
||||
memcpy(&lHeight, abSrcWaterHeight + sizeof(int32_t) * i, sizeof(int32_t));
|
||||
m_lWaterHeight[i] = lHeight;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD CTerrainImpl::GetShadowMapColor(float fx, float fy)
|
||||
{
|
||||
float fMapSize = (float)(TERRAIN_XSIZE);
|
||||
float fooMapSize = 1.0f / fMapSize;
|
||||
if (fx < 0 || fy < 0 || fx >= fMapSize || fy >= fMapSize)
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
fx = fx * fooMapSize * (float)(SHADOWMAP_XSIZE - 1);
|
||||
fy = fy * fooMapSize * (float)(SHADOWMAP_YSIZE - 1);
|
||||
int ix, iy;
|
||||
PR_FLOAT_TO_INT(fx, ix);
|
||||
PR_FLOAT_TO_INT(fy, iy);
|
||||
|
||||
WORD w = *(m_awShadowMap + (iy * SHADOWMAP_XSIZE) + ix);
|
||||
|
||||
int b = w & 0x1f; w >>= 5; b <<= 3;
|
||||
int g = w & 0x1f; w >>= 5; g <<= 3;
|
||||
int r = w & 0x1f; r <<= 3;
|
||||
|
||||
return (DWORD) (0xff << 24) | (g << 16) | (g << 8) | r;
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
#include "StdAfx.h"
|
||||
#include "TextureSet.h"
|
||||
|
||||
CTextureSet::CTextureSet()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CTextureSet::~CTextureSet()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CTextureSet::Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
void CTextureSet::Create()
|
||||
{
|
||||
CResource * pResource = CResourceManager::Instance().GetResourcePointer("d:/ymir work/special/error.tga");
|
||||
m_ErrorTexture.ImageInstance.SetImagePointer(static_cast<CGraphicImage *> (pResource));
|
||||
AddEmptyTexture(); // 지우개 텍스춰를 처음에 추가 해야 함
|
||||
}
|
||||
|
||||
bool CTextureSet::Load(const char * c_szTextureSetFileName, float fTerrainTexCoordBase)
|
||||
{
|
||||
NANOBEGIN
|
||||
Clear();
|
||||
|
||||
CTokenVectorMap stTokenVectorMap;
|
||||
|
||||
if (!LoadMultipleTextData(c_szTextureSetFileName, stTokenVectorMap))
|
||||
{
|
||||
TraceError("TextureSet::Load : cannot load %s", c_szTextureSetFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("textureset"))
|
||||
{
|
||||
TraceError("TextureSet::Load : syntax error, TextureSet (filename: %s)", c_szTextureSetFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("texturecount"))
|
||||
{
|
||||
TraceError("TextureSet::Load : syntax error, TextureCount (filename: %s)", c_szTextureSetFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Create();
|
||||
|
||||
const std::string & c_rstrCount = stTokenVectorMap["texturecount"][0];
|
||||
|
||||
long lCount = atol(c_rstrCount.c_str());
|
||||
char szTextureName[32 + 1];
|
||||
|
||||
m_Textures.resize(lCount + 1);
|
||||
|
||||
for (long i = 0; i < lCount; ++i)
|
||||
{
|
||||
_snprintf(szTextureName, sizeof(szTextureName), "texture%03d", i + 1);
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find(szTextureName))
|
||||
continue;
|
||||
|
||||
const CTokenVector & rVector = stTokenVectorMap[szTextureName];
|
||||
|
||||
const std::string & c_rstrFileName = rVector[0].c_str();
|
||||
const std::string & c_rstrUScale = rVector[1].c_str();
|
||||
const std::string & c_rstrVScale = rVector[2].c_str();
|
||||
const std::string & c_rstrUOffset = rVector[3].c_str();
|
||||
const std::string & c_rstrVOffset = rVector[4].c_str();
|
||||
const std::string & c_rstrbSplat = rVector[5].c_str();
|
||||
const std::string & c_rstrBegin = rVector[6].c_str();
|
||||
const std::string & c_rstrEnd = rVector[7].c_str();
|
||||
|
||||
float fuScale, fvScale, fuOffset, fvOffset;
|
||||
bool bSplat;
|
||||
unsigned short usBegin, usEnd;
|
||||
|
||||
fuScale = atof(c_rstrUScale.c_str());
|
||||
fvScale = atof(c_rstrVScale.c_str());
|
||||
fuOffset = atof(c_rstrUOffset.c_str());
|
||||
fvOffset = atof(c_rstrVOffset.c_str());
|
||||
bSplat = 0 != atoi(c_rstrbSplat.c_str());
|
||||
usBegin = static_cast<unsigned short>(atoi(c_rstrBegin.c_str()));
|
||||
usEnd = static_cast<unsigned short>(atoi(c_rstrEnd.c_str()));
|
||||
|
||||
if (!SetTexture(i + 1, c_rstrFileName.c_str(), fuScale, fvScale, fuOffset, fvOffset, bSplat, usBegin, usEnd, fTerrainTexCoordBase))
|
||||
TraceError("CTextureSet::Load : SetTexture failed : Filename: %s", c_rstrFileName.c_str());
|
||||
}
|
||||
|
||||
m_stFileName.assign(c_szTextureSetFileName);
|
||||
NANOEND
|
||||
return true;
|
||||
}
|
||||
|
||||
void CTextureSet::Clear()
|
||||
{
|
||||
m_ErrorTexture.ImageInstance.Destroy();
|
||||
m_Textures.clear();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void CTextureSet::AddEmptyTexture()
|
||||
{
|
||||
TTerrainTexture eraser;
|
||||
m_Textures.push_back(eraser);
|
||||
}
|
||||
|
||||
unsigned long CTextureSet::GetTextureCount()
|
||||
{
|
||||
return m_Textures.size();
|
||||
}
|
||||
|
||||
TTerrainTexture & CTextureSet::GetTexture(unsigned long ulIndex)
|
||||
{
|
||||
if (GetTextureCount() <= ulIndex)
|
||||
return m_ErrorTexture;
|
||||
|
||||
return m_Textures[ulIndex];
|
||||
}
|
||||
|
||||
bool CTextureSet::SetTexture(unsigned long ulIndex,
|
||||
const char * c_szFileName,
|
||||
float fuScale,
|
||||
float fvScale,
|
||||
float fuOffset,
|
||||
float fvOffset,
|
||||
bool bSplat,
|
||||
unsigned short usBegin,
|
||||
unsigned short usEnd,
|
||||
float fTerrainTexCoordBase)
|
||||
{
|
||||
|
||||
if (ulIndex >= m_Textures.size())
|
||||
{
|
||||
TraceError("CTextureSet::SetTexture : Index Error : Index(%d) is Larger than TextureSet Size(%d)", ulIndex, m_Textures.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName);
|
||||
|
||||
if (!pResource->IsType(CGraphicImage::Type()))
|
||||
{
|
||||
TraceError("CTerrainImpl::GenerateTexture : %s is NOT Image File", pResource->GetFileName());
|
||||
return false;
|
||||
}
|
||||
|
||||
TTerrainTexture & tex = m_Textures[ulIndex];
|
||||
|
||||
tex.stFilename = c_szFileName;
|
||||
tex.UScale = fuScale;
|
||||
tex.VScale = fvScale;
|
||||
tex.UOffset = fuOffset;
|
||||
tex.VOffset = fvOffset;
|
||||
tex.bSplat = bSplat;
|
||||
tex.Begin = usBegin;
|
||||
tex.End = usEnd;
|
||||
tex.ImageInstance.SetImagePointer(static_cast<CGraphicImage *>(pResource));
|
||||
tex.pd3dTexture = tex.ImageInstance.GetTexturePointer()->GetD3DTexture();
|
||||
|
||||
|
||||
D3DXMatrixScaling(&tex.m_matTransform, fTerrainTexCoordBase * tex.UScale, -fTerrainTexCoordBase * tex.VScale, 0.0f);
|
||||
tex.m_matTransform._41 = tex.UOffset;
|
||||
tex.m_matTransform._42 = -tex.VOffset;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CTextureSet::Reload(float fTerrainTexCoordBase)
|
||||
{
|
||||
for (DWORD dwIndex = 1; dwIndex < GetTextureCount(); ++dwIndex)
|
||||
{
|
||||
TTerrainTexture & tex = m_Textures[dwIndex];
|
||||
|
||||
tex.ImageInstance.ReloadImagePointer((CGraphicImage *) CResourceManager::Instance().GetResourcePointer(tex.stFilename.c_str()));
|
||||
tex.pd3dTexture = tex.ImageInstance.GetTexturePointer()->GetD3DTexture();
|
||||
|
||||
D3DXMatrixScaling(&tex.m_matTransform, fTerrainTexCoordBase * tex.UScale, -fTerrainTexCoordBase * tex.VScale, 0.0f);
|
||||
tex.m_matTransform._41 = tex.UOffset;
|
||||
tex.m_matTransform._42 = -tex.VOffset;
|
||||
}
|
||||
}
|
||||
|
||||
bool CTextureSet::AddTexture(const char * c_szFileName,
|
||||
float fuScale,
|
||||
float fvScale,
|
||||
float fuOffset,
|
||||
float fvOffset,
|
||||
bool bSplat,
|
||||
unsigned short usBegin,
|
||||
unsigned short usEnd,
|
||||
float fTerrainTexCoordBase)
|
||||
{
|
||||
if (GetTextureCount() >= 256)
|
||||
{
|
||||
LogBox("\305\330\275\272\303\263\270\246 \264\365 \300\314\273\363 \303\337\260\241\307\322 \274\366 \276\370\275\300\264\317\264\331.", "\303\326\264\353 \305\330\275\272\303\263 \260\263\274\366 255\260\263");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned long i = 1; i < GetTextureCount(); ++i)
|
||||
{
|
||||
if (0 == m_Textures[i].stFilename.compare(c_szFileName))
|
||||
{
|
||||
LogBox("\265\277\300\317\307\321 \300\314\270\247\300\307 \305\330\275\272\303\263\260\241 \300\314\271\314 \300\326\275\300\264\317\264\331.", "\301\337\272\271");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName);
|
||||
|
||||
if (!pResource->IsType(CGraphicImage::Type()))
|
||||
{
|
||||
LogBox("CTerrainImpl::GenerateTexture : \300\314\271\314\301\366 \306\304\300\317\300\314 \276\306\264\325\264\317\264\331. %s", pResource->GetFileName());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Textures.reserve(m_Textures.size() + 1);
|
||||
|
||||
SetTexture(m_Textures.size() - 1,
|
||||
c_szFileName,
|
||||
fuScale,
|
||||
fvScale,
|
||||
fuOffset,
|
||||
fvOffset,
|
||||
bSplat,
|
||||
usBegin,
|
||||
usEnd,
|
||||
fTerrainTexCoordBase);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTextureSet::RemoveTexture(unsigned long ulIndex)
|
||||
{
|
||||
if (GetTextureCount() <= ulIndex)
|
||||
return false;
|
||||
|
||||
TTextureVector::iterator itor = m_Textures.begin() + ulIndex;
|
||||
m_Textures.erase(itor);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTextureSet::Save(const char * c_pszFileName)
|
||||
{
|
||||
FILE * pFile = fopen(c_pszFileName, "w");
|
||||
|
||||
if (!pFile)
|
||||
return false;
|
||||
|
||||
fprintf(pFile, "TextureSet\n");
|
||||
fprintf(pFile, "\n");
|
||||
|
||||
fprintf(pFile, "TextureCount %ld\n", GetTextureCount() - 1); // -1 을 하는 이유는 지우개 때문임
|
||||
fprintf(pFile, "\n");
|
||||
|
||||
for (DWORD i = 1; i < GetTextureCount(); ++i)
|
||||
{
|
||||
TTerrainTexture & rTex = m_Textures[i];
|
||||
|
||||
fprintf(pFile, "Start Texture%03d\n", i);
|
||||
fprintf(pFile, " \"%s\"\n", rTex.stFilename.c_str());
|
||||
fprintf(pFile, " %f\n", rTex.UScale);
|
||||
fprintf(pFile, " %f\n", rTex.VScale);
|
||||
fprintf(pFile, " %f\n", rTex.UOffset);
|
||||
fprintf(pFile, " %f\n", rTex.VOffset);
|
||||
fprintf(pFile, " %d\n", rTex.bSplat);
|
||||
fprintf(pFile, " %hu\n", rTex.Begin);
|
||||
fprintf(pFile, " %hu\n", rTex.End);
|
||||
fprintf(pFile, "End Texture%03d\n", i);
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,921 @@
|
||||
// PythonBackground.cpp: implementation of the CPythonBackground class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "../EterLib/CullingManager.h"
|
||||
#include "../EterLib/Camera.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
#include "../GameLib/MapOutdoor.h"
|
||||
#include "../GameLib/PropertyLoader.h"
|
||||
|
||||
#include "PythonBackground.h"
|
||||
#include "PythonCharacterManager.h"
|
||||
#include "PythonNetworkStream.h"
|
||||
#include "PythonMiniMap.h"
|
||||
#include "PythonSystem.h"
|
||||
|
||||
std::string g_strEffectName = "d:/ymir work/effect/etc/direction/direction_land.mse";
|
||||
|
||||
DWORD CPythonBackground::GetRenderShadowTime()
|
||||
{
|
||||
return m_dwRenderShadowTime;
|
||||
}
|
||||
|
||||
bool CPythonBackground::SetVisiblePart(int eMapOutDoorPart, bool isVisible)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.SetVisiblePart(eMapOutDoorPart, isVisible);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPythonBackground::EnableTerrainOnlyForHeight()
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.EnableTerrainOnlyForHeight(TRUE);
|
||||
}
|
||||
|
||||
bool CPythonBackground::SetSplatLimit(int iSplatNum)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap = GetMapOutdoorRef();
|
||||
rkMap.SetSplatLimit(iSplatNum);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPythonBackground::CreateCharacterShadowTexture()
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap = GetMapOutdoorRef();
|
||||
rkMap.CreateCharacterShadowTexture();
|
||||
}
|
||||
|
||||
void CPythonBackground::ReleaseCharacterShadowTexture()
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap = GetMapOutdoorRef();
|
||||
rkMap.ReleaseCharacterShadowTexture();
|
||||
}
|
||||
|
||||
void CPythonBackground::RefreshShadowLevel()
|
||||
{
|
||||
SetShadowLevel(CPythonSystem::Instance().GetShadowLevel());
|
||||
}
|
||||
|
||||
bool CPythonBackground::SetShadowLevel(int eLevel)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return false;
|
||||
|
||||
if (m_eShadowLevel == eLevel)
|
||||
return true;
|
||||
|
||||
CMapOutdoor& rkMap = GetMapOutdoorRef();
|
||||
|
||||
m_eShadowLevel = eLevel;
|
||||
|
||||
switch (m_eShadowLevel)
|
||||
{
|
||||
case SHADOW_NONE:
|
||||
rkMap.SetDrawShadow(false);
|
||||
rkMap.SetShadowTextureSize(512);
|
||||
break;
|
||||
|
||||
case SHADOW_GROUND:
|
||||
rkMap.SetDrawShadow(true);
|
||||
rkMap.SetDrawCharacterShadow(false);
|
||||
rkMap.SetShadowTextureSize(512);
|
||||
break;
|
||||
|
||||
case SHADOW_GROUND_AND_SOLO:
|
||||
rkMap.SetDrawShadow(true);
|
||||
rkMap.SetDrawCharacterShadow(true);
|
||||
rkMap.SetShadowTextureSize(512);
|
||||
break;
|
||||
|
||||
case SHADOW_ALL:
|
||||
rkMap.SetDrawShadow(true);
|
||||
rkMap.SetDrawCharacterShadow(true);
|
||||
rkMap.SetShadowTextureSize(512);
|
||||
break;
|
||||
|
||||
case SHADOW_ALL_HIGH:
|
||||
rkMap.SetDrawShadow(true);
|
||||
rkMap.SetDrawCharacterShadow(true);
|
||||
rkMap.SetShadowTextureSize(1024);
|
||||
break;
|
||||
|
||||
case SHADOW_ALL_MAX:
|
||||
rkMap.SetDrawShadow(true);
|
||||
rkMap.SetDrawCharacterShadow(true);
|
||||
rkMap.SetShadowTextureSize(2048);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPythonBackground::SelectViewDistanceNum(int eNum)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
|
||||
if (!mc_pcurEnvironmentData)
|
||||
{
|
||||
TraceError("CPythonBackground::SelectViewDistanceNum(int eNum=%d) mc_pcurEnvironmentData is NULL", eNum);
|
||||
return;
|
||||
}
|
||||
|
||||
m_eViewDistanceNum = eNum;
|
||||
|
||||
TEnvironmentData * env = ((TEnvironmentData *) mc_pcurEnvironmentData);
|
||||
|
||||
// 게임 분위기를 바꿔놓을 수 있으므로 reserve로 되어있으면 고치지 않는다.
|
||||
if (env->bReserve)
|
||||
{
|
||||
env->m_fFogNearDistance = m_ViewDistanceSet[m_eViewDistanceNum].m_fFogStart;
|
||||
env->m_fFogFarDistance = m_ViewDistanceSet[m_eViewDistanceNum].m_fFogEnd;
|
||||
env->v3SkyBoxScale = m_ViewDistanceSet[m_eViewDistanceNum].m_v3SkyBoxScale;
|
||||
rkMap.SetEnvironmentSkyBox();
|
||||
}
|
||||
}
|
||||
|
||||
void CPythonBackground::SetViewDistanceSet(int eNum, float fFarClip)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
m_ViewDistanceSet[eNum].m_fFogStart = fFarClip * 0.5f;//0.3333333f;
|
||||
m_ViewDistanceSet[eNum].m_fFogEnd = fFarClip * 0.7f;//0.6666667f;
|
||||
|
||||
float fSkyBoxScale = fFarClip * 0.6f;//0.5773502f;
|
||||
m_ViewDistanceSet[eNum].m_v3SkyBoxScale = D3DXVECTOR3(fSkyBoxScale, fSkyBoxScale, fSkyBoxScale);
|
||||
m_ViewDistanceSet[eNum].m_fFarClip = fFarClip;
|
||||
|
||||
if (eNum == m_eViewDistanceNum)
|
||||
SelectViewDistanceNum(eNum);
|
||||
}
|
||||
|
||||
float CPythonBackground::GetFarClip()
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return 50000.0f;
|
||||
|
||||
if (m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip==0.0f)
|
||||
{
|
||||
TraceError("CPythonBackground::GetFarClip m_eViewDistanceNum=%d", m_eViewDistanceNum);
|
||||
m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip=25600.0f;
|
||||
}
|
||||
|
||||
return m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip;
|
||||
}
|
||||
|
||||
void CPythonBackground::GetDistanceSetInfo(int * peNum, float * pfStart, float * pfEnd, float * pfFarClip)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
{
|
||||
*peNum = 4;
|
||||
*pfStart= 10000.0f;
|
||||
*pfEnd= 15000.0f;
|
||||
*pfFarClip = 50000.0f;
|
||||
return;
|
||||
}
|
||||
*peNum = m_eViewDistanceNum;
|
||||
*pfStart = m_ViewDistanceSet[m_eViewDistanceNum].m_fFogStart;
|
||||
*pfEnd= m_ViewDistanceSet[m_eViewDistanceNum].m_fFogEnd;
|
||||
*pfFarClip = m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CPythonBackground::CPythonBackground()
|
||||
{
|
||||
m_dwRenderShadowTime=0;
|
||||
m_eViewDistanceNum=0;
|
||||
m_eViewDistanceNum=0;
|
||||
m_eViewDistanceNum=0;
|
||||
m_eShadowLevel=SHADOW_NONE;
|
||||
m_dwBaseX=0;
|
||||
m_dwBaseY=0;
|
||||
m_strMapName="";
|
||||
m_iDayMode = DAY_MODE_LIGHT;
|
||||
m_iXMasTreeGrade = 0;
|
||||
m_bVisibleGuildArea = FALSE;
|
||||
|
||||
SetViewDistanceSet(4, 25600.0f);
|
||||
SetViewDistanceSet(3, 25600.0f);
|
||||
SetViewDistanceSet(2, 25600.0f);
|
||||
SetViewDistanceSet(1, 25600.0f);
|
||||
SetViewDistanceSet(0, 25600.0f);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CPythonBackground::~CPythonBackground()
|
||||
{
|
||||
Tracen("CPythonBackground Clear");
|
||||
}
|
||||
|
||||
void CPythonBackground::Initialize()
|
||||
{
|
||||
std::string stAtlasInfoFileName (LocaleService_GetLocalePath());
|
||||
stAtlasInfoFileName += "/AtlasInfo.txt";
|
||||
SetAtlasInfoFileName(stAtlasInfoFileName.c_str());
|
||||
CMapManager::Initialize();
|
||||
}
|
||||
|
||||
void CPythonBackground::__CreateProperty()
|
||||
{
|
||||
if (CEterPackManager::SEARCH_FILE_FIRST == CEterPackManager::Instance().GetSearchMode() &&
|
||||
_access("property", 0) == 0)
|
||||
{
|
||||
m_PropertyManager.Initialize(NULL);
|
||||
|
||||
CPropertyLoader PropertyLoader;
|
||||
PropertyLoader.SetPropertyManager(&m_PropertyManager);
|
||||
PropertyLoader.Create("*.*", "Property");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PropertyManager.Initialize("pack/property");
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Normal Functions
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool CPythonBackground::GetPickingPoint(D3DXVECTOR3 * v3IntersectPt)
|
||||
{
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetPickingPoint(v3IntersectPt);
|
||||
}
|
||||
|
||||
bool CPythonBackground::GetPickingPointWithRay(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
|
||||
{
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetPickingPointWithRay(rRay, v3IntersectPt);
|
||||
}
|
||||
|
||||
bool CPythonBackground::GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
|
||||
{
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetPickingPointWithRayOnlyTerrain(rRay, v3IntersectPt);
|
||||
}
|
||||
|
||||
BOOL CPythonBackground::GetLightDirection(D3DXVECTOR3 & rv3LightDirection)
|
||||
{
|
||||
if (!mc_pcurEnvironmentData)
|
||||
return FALSE;
|
||||
|
||||
rv3LightDirection.x = mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction.x;
|
||||
rv3LightDirection.y = mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction.y;
|
||||
rv3LightDirection.z = mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction.z;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
void CPythonBackground::Destroy()
|
||||
{
|
||||
CMapManager::Destroy();
|
||||
m_SnowEnvironment.Destroy();
|
||||
m_bVisibleGuildArea = FALSE;
|
||||
}
|
||||
|
||||
void CPythonBackground::Create()
|
||||
{
|
||||
static int s_isCreateProperty=false;
|
||||
|
||||
if (!s_isCreateProperty)
|
||||
{
|
||||
s_isCreateProperty=true;
|
||||
__CreateProperty();
|
||||
}
|
||||
|
||||
CMapManager::Create();
|
||||
|
||||
m_SnowEnvironment.Create();
|
||||
}
|
||||
|
||||
struct FGetPortalID
|
||||
{
|
||||
float m_fRequestX, m_fRequestY;
|
||||
std::set<int> m_kSet_iPortalID;
|
||||
FGetPortalID(float fRequestX, float fRequestY)
|
||||
{
|
||||
m_fRequestX=fRequestX;
|
||||
m_fRequestY=fRequestY;
|
||||
}
|
||||
void operator () (CGraphicObjectInstance * pObject)
|
||||
{
|
||||
for (int i = 0; i < PORTAL_ID_MAX_NUM; ++i)
|
||||
{
|
||||
int iID = pObject->GetPortal(i);
|
||||
if (0 == iID)
|
||||
break;
|
||||
|
||||
m_kSet_iPortalID.insert(iID);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void CPythonBackground::Update(float fCenterX, float fCenterY, float fCenterZ)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
#ifdef __PERFORMANCE_CHECKER__
|
||||
DWORD t1=ELTimer_GetMSec();
|
||||
#endif
|
||||
UpdateMap(fCenterX, fCenterY, fCenterZ);
|
||||
#ifdef __PERFORMANCE_CHECKER__
|
||||
DWORD t2=ELTimer_GetMSec();
|
||||
#endif
|
||||
UpdateAroundAmbience(fCenterX, fCenterY, fCenterZ);
|
||||
#ifdef __PERFORMANCE_CHECKER__
|
||||
DWORD t3=ELTimer_GetMSec();
|
||||
#endif
|
||||
m_SnowEnvironment.Update(D3DXVECTOR3(fCenterX, -fCenterY, fCenterZ));
|
||||
|
||||
#ifdef __PERFORMANCE_CHECKER__
|
||||
{
|
||||
static FILE* fp=fopen("perf_bg_update.txt", "w");
|
||||
if (t3-t1>5)
|
||||
{
|
||||
fprintf(fp, "BG.Total %d (Time %f)\n", t3-t1, ELTimer_GetMSec()/1000.0f);
|
||||
fprintf(fp, "BG.UpdateMap %d\n", t2-t1);
|
||||
fprintf(fp, "BG.UpdateAmb %d\n", t3-t2);
|
||||
fflush(fp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Portal Process
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
if (rkMap.IsEnablePortal())
|
||||
{
|
||||
CCullingManager & rkCullingMgr = CCullingManager::Instance();
|
||||
FGetPortalID kGetPortalID(fCenterX, -fCenterY);
|
||||
|
||||
Vector3d aVector3d;
|
||||
aVector3d.Set(fCenterX, -fCenterY, fCenterZ);
|
||||
|
||||
Vector3d toTop;
|
||||
toTop.Set(0, 0, 25000.0f);
|
||||
|
||||
rkCullingMgr.ForInRay(aVector3d, toTop, &kGetPortalID);
|
||||
|
||||
std::set<int>::iterator itor = kGetPortalID.m_kSet_iPortalID.begin();
|
||||
if (!__IsSame(kGetPortalID.m_kSet_iPortalID, m_kSet_iShowingPortalID))
|
||||
{
|
||||
ClearPortal();
|
||||
std::set<int>::iterator itor=kGetPortalID.m_kSet_iPortalID.begin();
|
||||
for (; itor!=kGetPortalID.m_kSet_iPortalID.end(); ++itor)
|
||||
{
|
||||
AddShowingPortalID(*itor);
|
||||
}
|
||||
RefreshPortal();
|
||||
|
||||
m_kSet_iShowingPortalID = kGetPortalID.m_kSet_iPortalID;
|
||||
}
|
||||
}
|
||||
|
||||
// Target Effect Process
|
||||
{
|
||||
std::map<DWORD, DWORD>::iterator itor = m_kMap_dwTargetID_dwChrID.begin();
|
||||
for (; itor != m_kMap_dwTargetID_dwChrID.end(); ++itor)
|
||||
{
|
||||
DWORD dwTargetID = itor->first;
|
||||
DWORD dwChrID = itor->second;
|
||||
|
||||
CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(dwChrID);
|
||||
|
||||
if (!pInstance)
|
||||
continue;
|
||||
|
||||
TPixelPosition kPixelPosition;
|
||||
pInstance->NEW_GetPixelPosition(&kPixelPosition);
|
||||
|
||||
CreateSpecialEffect(dwTargetID,
|
||||
+kPixelPosition.x,
|
||||
-kPixelPosition.y,
|
||||
+kPixelPosition.z,
|
||||
g_strEffectName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Reserve Target Effect
|
||||
{
|
||||
std::map<DWORD, SReserveTargetEffect>::iterator itor = m_kMap_dwID_kReserveTargetEffect.begin();
|
||||
for (; itor != m_kMap_dwID_kReserveTargetEffect.end();)
|
||||
{
|
||||
DWORD dwID = itor->first;
|
||||
SReserveTargetEffect & rReserveTargetEffect = itor->second;
|
||||
|
||||
float ilx = float(rReserveTargetEffect.ilx);
|
||||
float ily = float(rReserveTargetEffect.ily);
|
||||
|
||||
float fHeight = rkMap.GetHeight(ilx, ily);
|
||||
if (0.0f == fHeight)
|
||||
{
|
||||
++itor;
|
||||
continue;
|
||||
}
|
||||
|
||||
CreateSpecialEffect(dwID, ilx, ily, fHeight, g_strEffectName.c_str());
|
||||
|
||||
itor = m_kMap_dwID_kReserveTargetEffect.erase(itor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CPythonBackground::__IsSame(std::set<int> & rleft, std::set<int> & rright)
|
||||
{
|
||||
std::set<int>::iterator itor_l;
|
||||
std::set<int>::iterator itor_r;
|
||||
|
||||
for (itor_l=rleft.begin(); itor_l!=rleft.end(); ++itor_l)
|
||||
{
|
||||
if (rright.end() == rright.find(*itor_l))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (itor_r=rright.begin(); itor_r!=rright.end(); ++itor_r)
|
||||
{
|
||||
if (rleft.end() == rleft.find(*itor_r))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPythonBackground::Render()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
m_SnowEnvironment.Deform();
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.Render();
|
||||
if (m_bVisibleGuildArea)
|
||||
rkMap.RenderMarkedArea();
|
||||
}
|
||||
|
||||
void CPythonBackground::RenderSnow()
|
||||
{
|
||||
m_SnowEnvironment.Render();
|
||||
}
|
||||
|
||||
void CPythonBackground::RenderPCBlocker()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.RenderPCBlocker();
|
||||
}
|
||||
|
||||
void CPythonBackground::RenderCollision()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.RenderCollision();
|
||||
}
|
||||
|
||||
void CPythonBackground::RenderCharacterShadowToTexture()
|
||||
{
|
||||
extern bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW;
|
||||
if (GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW)
|
||||
return;
|
||||
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
DWORD t1=ELTimer_GetMSec();
|
||||
|
||||
if (m_eShadowLevel == SHADOW_ALL ||
|
||||
m_eShadowLevel == SHADOW_ALL_HIGH ||
|
||||
m_eShadowLevel == SHADOW_ALL_MAX ||
|
||||
m_eShadowLevel == SHADOW_GROUND_AND_SOLO)
|
||||
{
|
||||
D3DXMATRIX matWorld;
|
||||
STATEMANAGER.GetTransform(D3DTS_WORLD, &matWorld);
|
||||
|
||||
bool canRender=rkMap.BeginRenderCharacterShadowToTexture();
|
||||
if (canRender)
|
||||
{
|
||||
CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance();
|
||||
|
||||
if (m_eShadowLevel == SHADOW_GROUND_AND_SOLO)
|
||||
rkChrMgr.RenderShadowMainInstance();
|
||||
else
|
||||
rkChrMgr.RenderShadowAllInstances();
|
||||
}
|
||||
rkMap.EndRenderCharacterShadowToTexture();
|
||||
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld);
|
||||
}
|
||||
|
||||
DWORD t2=ELTimer_GetMSec();
|
||||
|
||||
m_dwRenderShadowTime=t2-t1;
|
||||
}
|
||||
|
||||
inline float Interpolate(float fStart, float fEnd, float fPercent)
|
||||
{
|
||||
return fStart + (fEnd - fStart) * fPercent;
|
||||
}
|
||||
struct CollisionChecker
|
||||
{
|
||||
bool isBlocked;
|
||||
CInstanceBase* pInstance;
|
||||
CollisionChecker(CInstanceBase* pInstance) : pInstance(pInstance), isBlocked(false) {}
|
||||
void operator () (CGraphicObjectInstance* pOpponent)
|
||||
{
|
||||
if (isBlocked)
|
||||
return;
|
||||
|
||||
if (!pOpponent)
|
||||
return;
|
||||
|
||||
if (pInstance->IsBlockObject(*pOpponent))
|
||||
isBlocked=true;
|
||||
}
|
||||
};
|
||||
|
||||
struct CollisionAdjustChecker
|
||||
{
|
||||
bool isBlocked;
|
||||
CInstanceBase* pInstance;
|
||||
CollisionAdjustChecker(CInstanceBase* pInstance) : pInstance(pInstance), isBlocked(false) {}
|
||||
void operator () (CGraphicObjectInstance* pOpponent)
|
||||
{
|
||||
if (!pOpponent)
|
||||
return;
|
||||
|
||||
if (pInstance->AvoidObject(*pOpponent))
|
||||
isBlocked=true;
|
||||
}
|
||||
};
|
||||
|
||||
bool CPythonBackground::CheckAdvancing(CInstanceBase * pInstance)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return true;
|
||||
|
||||
Vector3d center;
|
||||
float radius;
|
||||
pInstance->GetGraphicThingInstanceRef().GetBoundingSphere(center,radius);
|
||||
|
||||
CCullingManager & rkCullingMgr = CCullingManager::Instance();
|
||||
|
||||
CollisionAdjustChecker kCollisionAdjustChecker(pInstance);
|
||||
rkCullingMgr.ForInRange(center, radius, &kCollisionAdjustChecker);
|
||||
if (kCollisionAdjustChecker.isBlocked)
|
||||
{
|
||||
CollisionChecker kCollisionChecker(pInstance);
|
||||
rkCullingMgr.ForInRange(center, radius, &kCollisionChecker);
|
||||
if (kCollisionChecker.isBlocked)
|
||||
{
|
||||
pInstance->BlockMovement();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pInstance->NEW_MoveToDestPixelPositionDirection(pInstance->NEW_GetDstPixelPositionRef());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CPythonBackground::RenderSky()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.RenderSky();
|
||||
}
|
||||
|
||||
void CPythonBackground::RenderCloud()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.RenderCloud();
|
||||
}
|
||||
|
||||
void CPythonBackground::RenderWater()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.RenderWater();
|
||||
}
|
||||
|
||||
void CPythonBackground::RenderEffect()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.RenderEffect();
|
||||
}
|
||||
|
||||
void CPythonBackground::RenderBeforeLensFlare()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.RenderBeforeLensFlare();
|
||||
}
|
||||
|
||||
void CPythonBackground::RenderAfterLensFlare()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.RenderAfterLensFlare();
|
||||
}
|
||||
|
||||
void CPythonBackground::ClearGuildArea()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.ClearGuildArea();
|
||||
}
|
||||
|
||||
void CPythonBackground::RegisterGuildArea(int isx, int isy, int iex, int iey)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.RegisterGuildArea(isx, isy, iex, iey);
|
||||
}
|
||||
|
||||
void CPythonBackground::SetCharacterDirLight()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
if (!mc_pcurEnvironmentData)
|
||||
return;
|
||||
|
||||
STATEMANAGER.SetLight(0, &mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_CHARACTER]);
|
||||
}
|
||||
|
||||
void CPythonBackground::SetBackgroundDirLight()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
if (!mc_pcurEnvironmentData)
|
||||
return;
|
||||
|
||||
STATEMANAGER.SetLight(0, &mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND]);
|
||||
}
|
||||
|
||||
void CPythonBackground::GlobalPositionToLocalPosition(LONG& rGlobalX, LONG& rGlobalY)
|
||||
{
|
||||
rGlobalX-=m_dwBaseX;
|
||||
rGlobalY-=m_dwBaseY;
|
||||
}
|
||||
|
||||
void CPythonBackground::LocalPositionToGlobalPosition(LONG& rLocalX, LONG& rLocalY)
|
||||
{
|
||||
rLocalX+=m_dwBaseX;
|
||||
rLocalY+=m_dwBaseY;
|
||||
}
|
||||
|
||||
void CPythonBackground::RegisterDungeonMapName(const char * c_szMapName)
|
||||
{
|
||||
m_kSet_strDungeonMapName.insert(c_szMapName);
|
||||
}
|
||||
|
||||
CPythonBackground::TMapInfo* CPythonBackground::GlobalPositionToMapInfo(DWORD dwGlobalX, DWORD dwGlobalY)
|
||||
{
|
||||
TMapInfoVector::iterator f = std::find_if(m_kVct_kMapInfo.begin(), m_kVct_kMapInfo.end(), FFindWarpMapName(dwGlobalX, dwGlobalY));
|
||||
if (f == m_kVct_kMapInfo.end())
|
||||
return NULL;
|
||||
|
||||
return &(*f);
|
||||
}
|
||||
|
||||
void CPythonBackground::Warp(DWORD dwX, DWORD dwY)
|
||||
{
|
||||
TMapInfo* pkMapInfo = GlobalPositionToMapInfo(dwX, dwY);
|
||||
if (!pkMapInfo)
|
||||
{
|
||||
TraceError("NOT_FOUND_GLOBAL_POSITION(%d, %d)", dwX, dwY);
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshShadowLevel();
|
||||
TMapInfo & rMapInfo = *pkMapInfo;
|
||||
assert( (dwX >= rMapInfo.m_dwBaseX) && (dwY >= rMapInfo.m_dwBaseY) );
|
||||
|
||||
if (!LoadMap(rMapInfo.m_strName, float(dwX - rMapInfo.m_dwBaseX), float(dwY - rMapInfo.m_dwBaseY), 0))
|
||||
{
|
||||
// LOAD_MAP_ERROR_HANDLING
|
||||
PostQuitMessage(0);
|
||||
// END_OF_LOAD_MAP_ERROR_HANDLING
|
||||
return;
|
||||
}
|
||||
|
||||
CPythonMiniMap::Instance().LoadAtlas();
|
||||
|
||||
m_dwBaseX=rMapInfo.m_dwBaseX;
|
||||
m_dwBaseY=rMapInfo.m_dwBaseY;
|
||||
|
||||
m_strMapName = rMapInfo.m_strName;
|
||||
|
||||
SetXMaxTree(m_iXMasTreeGrade);
|
||||
|
||||
if (m_kSet_strDungeonMapName.end() != m_kSet_strDungeonMapName.find(m_strMapName))
|
||||
{
|
||||
EnableTerrainOnlyForHeight();
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.EnablePortal(TRUE);
|
||||
}
|
||||
|
||||
m_kSet_iShowingPortalID.clear();
|
||||
m_kMap_dwTargetID_dwChrID.clear();
|
||||
m_kMap_dwID_kReserveTargetEffect.clear();
|
||||
}
|
||||
|
||||
void CPythonBackground::VisibleGuildArea()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.VisibleMarkedArea();
|
||||
|
||||
m_bVisibleGuildArea = TRUE;
|
||||
}
|
||||
|
||||
void CPythonBackground::DisableGuildArea()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.DisableMarkedArea();
|
||||
|
||||
m_bVisibleGuildArea = FALSE;
|
||||
}
|
||||
|
||||
const char * CPythonBackground::GetWarpMapName()
|
||||
{
|
||||
return m_strMapName.c_str();
|
||||
}
|
||||
|
||||
void CPythonBackground::ChangeToDay()
|
||||
{
|
||||
m_iDayMode = DAY_MODE_LIGHT;
|
||||
}
|
||||
|
||||
void CPythonBackground::ChangeToNight()
|
||||
{
|
||||
m_iDayMode = DAY_MODE_DARK;
|
||||
}
|
||||
|
||||
void CPythonBackground::EnableSnowEnvironment()
|
||||
{
|
||||
m_SnowEnvironment.Enable();
|
||||
}
|
||||
|
||||
void CPythonBackground::DisableSnowEnvironment()
|
||||
{
|
||||
m_SnowEnvironment.Disable();
|
||||
}
|
||||
|
||||
const D3DXVECTOR3 c_v3TreePos = D3DXVECTOR3(76500.0f, -60900.0f, 20215.0f);
|
||||
|
||||
void CPythonBackground::SetXMaxTree(int iGrade)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
assert(iGrade >= 0 && iGrade <= 3);
|
||||
m_iXMasTreeGrade = iGrade;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
|
||||
if ("map_n_snowm_01" != m_strMapName)
|
||||
{
|
||||
rkMap.XMasTree_Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 == iGrade)
|
||||
{
|
||||
rkMap.XMasTree_Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
iGrade -= 1;
|
||||
iGrade = max(iGrade, 0);
|
||||
iGrade = min(iGrade, 2);
|
||||
|
||||
static std::string s_strTreeName[3] = {
|
||||
"d:/ymir work/tree/christmastree1.spt",
|
||||
"d:/ymir work/tree/christmastree2.spt",
|
||||
"d:/ymir work/tree/christmastree3.spt"
|
||||
};
|
||||
static std::string s_strEffectName[3] = {
|
||||
"d:/ymir work/effect/etc/christmas_tree/tree_1s.mse",
|
||||
"d:/ymir work/effect/etc/christmas_tree/tree_2s.mse",
|
||||
"d:/ymir work/effect/etc/christmas_tree/tree_3s.mse",
|
||||
};
|
||||
rkMap.XMasTree_Set(c_v3TreePos.x, c_v3TreePos.y, c_v3TreePos.z, s_strTreeName[iGrade].c_str(), s_strEffectName[iGrade].c_str());
|
||||
}
|
||||
|
||||
void CPythonBackground::CreateTargetEffect(DWORD dwID, DWORD dwChrVID)
|
||||
{
|
||||
m_kMap_dwTargetID_dwChrID.insert(std::make_pair(dwID, dwChrVID));
|
||||
}
|
||||
|
||||
void CPythonBackground::CreateTargetEffect(DWORD dwID, long lx, long ly)
|
||||
{
|
||||
if (m_kMap_dwTargetID_dwChrID.end() != m_kMap_dwTargetID_dwChrID.find(dwID))
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
|
||||
DWORD dwBaseX;
|
||||
DWORD dwBaseY;
|
||||
rkMap.GetBaseXY(&dwBaseX, &dwBaseY);
|
||||
|
||||
int ilx = +(lx-int(dwBaseX));
|
||||
int ily = -(ly-int(dwBaseY));
|
||||
|
||||
float fHeight = rkMap.GetHeight(float(ilx), float(ily));
|
||||
|
||||
if (0.0f == fHeight)
|
||||
{
|
||||
SReserveTargetEffect ReserveTargetEffect;
|
||||
ReserveTargetEffect.ilx = ilx;
|
||||
ReserveTargetEffect.ily = ily;
|
||||
m_kMap_dwID_kReserveTargetEffect.insert(std::make_pair(dwID, ReserveTargetEffect));
|
||||
return;
|
||||
}
|
||||
|
||||
CreateSpecialEffect(dwID, ilx, ily, fHeight, g_strEffectName.c_str());
|
||||
}
|
||||
|
||||
void CPythonBackground::DeleteTargetEffect(DWORD dwID)
|
||||
{
|
||||
if (m_kMap_dwID_kReserveTargetEffect.end() != m_kMap_dwID_kReserveTargetEffect.find(dwID))
|
||||
{
|
||||
m_kMap_dwID_kReserveTargetEffect.erase(dwID);
|
||||
}
|
||||
if (m_kMap_dwTargetID_dwChrID.end() != m_kMap_dwTargetID_dwChrID.find(dwID))
|
||||
{
|
||||
m_kMap_dwTargetID_dwChrID.erase(dwID);
|
||||
}
|
||||
|
||||
DeleteSpecialEffect(dwID);
|
||||
}
|
||||
|
||||
void CPythonBackground::CreateSpecialEffect(DWORD dwID, float fx, float fy, float fz, const char * c_szFileName)
|
||||
{
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.SpecialEffect_Create(dwID, fx, fy, fz, c_szFileName);
|
||||
}
|
||||
|
||||
void CPythonBackground::DeleteSpecialEffect(DWORD dwID)
|
||||
{
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.SpecialEffect_Delete(dwID);
|
||||
}
|
||||
@@ -0,0 +1,619 @@
|
||||
#include "StdAfx.h"
|
||||
#include "PythonSystem.h"
|
||||
#include "PythonBackground.h"
|
||||
#include "../EterLib/StateManager.h"
|
||||
#include "../GameLib/MapOutdoor.h"
|
||||
|
||||
PyObject * backgroundIsSoftwareTiling(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
return Py_BuildValue("i", rkBG.IsSoftwareTilingEnable());
|
||||
}
|
||||
|
||||
PyObject * backgroundEnableSoftwareTiling(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int nIsEnable;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &nIsEnable))
|
||||
return Py_BadArgument();
|
||||
|
||||
bool isEnable=nIsEnable ? true : false;
|
||||
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
rkBG.ReserveSoftwareTilingEnable(isEnable);
|
||||
|
||||
CPythonSystem& rkSystem=CPythonSystem::Instance();
|
||||
rkSystem.SetSoftwareTiling(isEnable);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundEnableSnow(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int nIsEnable;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &nIsEnable))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
if (nIsEnable)
|
||||
rkBG.EnableSnowEnvironment();
|
||||
else
|
||||
rkBG.DisableSnowEnvironment();
|
||||
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundLoadMap(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
char * pszMapPathName;
|
||||
|
||||
if (!PyTuple_GetString(poArgs, 0, &pszMapPathName))
|
||||
return Py_BadArgument();
|
||||
|
||||
float x, y, z;
|
||||
|
||||
if (!PyTuple_GetFloat(poArgs, 1, &x))
|
||||
return Py_BadArgument();
|
||||
|
||||
if (!PyTuple_GetFloat(poArgs, 2, &y))
|
||||
return Py_BadArgument();
|
||||
|
||||
if (!PyTuple_GetFloat(poArgs, 3, &z))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
rkBG.LoadMap(pszMapPathName, x, y, z);
|
||||
|
||||
//#ifdef _DEBUG
|
||||
// CMapOutdoor& rkMap=rkBG.GetMapOutdoorRef();
|
||||
// rkMap.EnablePortal(TRUE);
|
||||
// rkBG.EnableTerrainOnlyForHeight();
|
||||
//#endif
|
||||
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundDestroy(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
rkBG.SetShadowLevel(CPythonBackground::SHADOW_NONE);
|
||||
rkBG.Destroy();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRegisterEnvironmentData(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
|
||||
return Py_BadArgument();
|
||||
|
||||
char * pszEnvironmentFileName;
|
||||
if (!PyTuple_GetString(poArgs, 1, &pszEnvironmentFileName))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
if (!rkBG.RegisterEnvironmentData(iIndex, pszEnvironmentFileName))
|
||||
{
|
||||
TraceError("background.RegisterEnvironmentData(iIndex=%d, szEnvironmentFileName=%s)", iIndex, pszEnvironmentFileName);
|
||||
|
||||
// TODO:
|
||||
// 디폴트 환경 설정 작업을 해주자
|
||||
}
|
||||
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundSetEnvironmentData(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
|
||||
return Py_BadArgument();
|
||||
|
||||
const TEnvironmentData * c_pEnvironmenData;
|
||||
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
if (rkBG.GetEnvironmentData(iIndex, &c_pEnvironmenData))
|
||||
rkBG.ResetEnvironmentDataPtr(c_pEnvironmenData);
|
||||
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundGetCurrentMapName(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
return Py_BuildValue("s", rkBG.GetWarpMapName());
|
||||
}
|
||||
|
||||
PyObject * backgroundGetPickingPoint(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
TPixelPosition kPPosPicked(0.0f, 0.0f, 0.0f);
|
||||
if (rkBG.GetPickingPoint(&kPPosPicked))
|
||||
{
|
||||
kPPosPicked.y=-kPPosPicked.y;
|
||||
}
|
||||
return Py_BuildValue("fff", kPPosPicked.x, kPPosPicked.y, kPPosPicked.z);
|
||||
}
|
||||
|
||||
PyObject * backgroundBeginEnvironment(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
rkBG.BeginEnvironment();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundEndEnvironemt(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
rkBG.EndEnvironment();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundSetCharacterDirLight(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground& rkBG = CPythonBackground::Instance();
|
||||
rkBG.SetCharacterDirLight();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundSetBackgroundDirLight(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground& rkBG = CPythonBackground::Instance();
|
||||
rkBG.SetBackgroundDirLight();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundInitialize(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
rkBG.Create();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundUpdate(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
float fCameraX;
|
||||
if (!PyTuple_GetFloat(poArgs, 0, &fCameraX))
|
||||
return Py_BadArgument();
|
||||
|
||||
float fCameraY;
|
||||
if (!PyTuple_GetFloat(poArgs, 1, &fCameraY))
|
||||
return Py_BadArgument();
|
||||
|
||||
float fCameraZ;
|
||||
if (!PyTuple_GetFloat(poArgs, 2, &fCameraZ))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground::Instance().Update(fCameraX, fCameraY, fCameraZ);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRender(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().Render();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRenderPCBlocker(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().RenderPCBlocker();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRenderCollision(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().RenderCollision();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRenderSky(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().RenderSky();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRenderCloud(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().RenderCloud();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRenderWater(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().RenderWater();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRenderEffect(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().RenderEffect();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRenderBeforeLensFlare(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().RenderBeforeLensFlare();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRenderAfterLensFlare(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().RenderAfterLensFlare();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRenderCharacterShadowToTexture(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().RenderCharacterShadowToTexture();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRenderDungeon(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
assert(!"background.RenderDungeon() - \273\347\277\353\307\317\301\366 \276\312\264\302 \307\324\274\366\300\324\264\317\264\331 - [levites]");
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundGetHeight(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
float fx;
|
||||
if (!PyTuple_GetFloat(poArgs, 0, &fx))
|
||||
return Py_BadArgument();
|
||||
|
||||
float fy;
|
||||
if (!PyTuple_GetFloat(poArgs, 1, &fy))
|
||||
return Py_BadArgument();
|
||||
|
||||
float fz = CPythonBackground::Instance().GetHeight(fx, fy);
|
||||
return Py_BuildValue("f", fz);
|
||||
}
|
||||
|
||||
PyObject * backgroundGetRenderedSplatNum(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iPatch;
|
||||
int iSplat;
|
||||
float fSplatRatio;
|
||||
|
||||
std::vector<int> & aTextureNumVector = CPythonBackground::Instance().GetRenderedSplatNum(&iPatch, &iSplat, &fSplatRatio);
|
||||
|
||||
char szOutput[MAX_PATH] = "";
|
||||
int iOutput = 0;
|
||||
for( std::vector<int>::iterator it = aTextureNumVector.begin(); it != aTextureNumVector.end(); it++ ) {
|
||||
iOutput += snprintf(szOutput + iOutput, sizeof(szOutput) - iOutput, "%d ", *it);
|
||||
}
|
||||
//std::copy(aTextureNumVector.begin(),aTextureNumVector.end(),std::ostream_iterator<int>(ostr," "));
|
||||
|
||||
return Py_BuildValue("iifs", iPatch, iSplat, fSplatRatio, szOutput);
|
||||
}
|
||||
|
||||
PyObject * backgroundGetRenderedGTINum(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
DWORD dwGraphicThingInstanceNum;
|
||||
DWORD dwCRCNum;
|
||||
|
||||
/*CArea::TCRCWithNumberVector & rCRCWithNumberVector = */
|
||||
CPythonBackground::Instance().GetRenderedGraphicThingInstanceNum(&dwGraphicThingInstanceNum, &dwCRCNum);
|
||||
|
||||
/*
|
||||
std::ostringstream ostr;
|
||||
|
||||
std::for_each(rCRCWithNumberVector.begin(),rCRCWithNumberVector.end(),std::ostream_iterator<CArea::TCRCWithNumberVector>(ostr," "));
|
||||
*/
|
||||
|
||||
return Py_BuildValue("ii", dwGraphicThingInstanceNum, dwCRCNum);
|
||||
}
|
||||
|
||||
PyObject * backgroundGetRenderShadowTime(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
return Py_BuildValue("i", rkBG.GetRenderShadowTime());
|
||||
}
|
||||
|
||||
PyObject * backgroundGetShadowMapcolor(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
float fx;
|
||||
if (!PyTuple_GetFloat(poArgs, 0, &fx))
|
||||
return Py_BadArgument();
|
||||
|
||||
float fy;
|
||||
if (!PyTuple_GetFloat(poArgs, 1, &fy))
|
||||
return Py_BadArgument();
|
||||
|
||||
DWORD dwColor = CPythonBackground::Instance().GetShadowMapColor(fx, fy);
|
||||
return Py_BuildValue("i", dwColor);
|
||||
}
|
||||
|
||||
PyObject * backgroundSetShadowLevel(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iLevel;
|
||||
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iLevel))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground& rkBG = CPythonBackground::Instance();
|
||||
rkBG.SetShadowLevel(iLevel);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundSetVisiblePart(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int ePart;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &ePart))
|
||||
return Py_BadArgument();
|
||||
|
||||
int isVisible;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &isVisible))
|
||||
return Py_BadArgument();
|
||||
|
||||
if (ePart>=CMapOutdoor::PART_NUM)
|
||||
return Py_BuildException("ePart(%d)<background.PART_NUM(%d)", ePart, CMapOutdoor::PART_NUM);
|
||||
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
rkBG.SetVisiblePart(ePart, isVisible ? true : false);
|
||||
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundSetSpaltLimit(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iSplatNum;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iSplatNum))
|
||||
return Py_BadArgument();
|
||||
|
||||
if (iSplatNum<0)
|
||||
return Py_BuildException("background.SetSplatLimit(iSplatNum(%d)>=0)", iSplatNum);
|
||||
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
rkBG.SetSplatLimit(iSplatNum);
|
||||
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundSelectViewDistanceNum(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iNum;
|
||||
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iNum))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
rkBG.SelectViewDistanceNum(iNum);
|
||||
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundSetViewDistanceSet(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iNum;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iNum))
|
||||
return Py_BadArgument();
|
||||
|
||||
float fFarClip;
|
||||
if (!PyTuple_GetFloat(poArgs, 1, &fFarClip))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
rkBG.SetViewDistanceSet(iNum, fFarClip);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundGetFarClip(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
float fFarClip = CPythonBackground::Instance().GetFarClip();
|
||||
return Py_BuildValue("f", fFarClip);
|
||||
}
|
||||
|
||||
PyObject * backgroundGetDistanceSetInfo(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iNum;
|
||||
float fStart, fEnd, fFarClip;
|
||||
CPythonBackground::Instance().GetDistanceSetInfo(&iNum, &fStart, &fEnd, &fFarClip);
|
||||
return Py_BuildValue("ifff", iNum, fStart, fEnd, fFarClip);
|
||||
}
|
||||
|
||||
PyObject * backgroundSetBGLoading(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
bool bBGLoading;
|
||||
if (!PyTuple_GetBoolean(poArgs, 0, &bBGLoading))
|
||||
return Py_BadArgument();
|
||||
|
||||
//CPythonBackground::Instance().BGLoadingEnable(bBGLoading);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundSetRenderSort(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int eSort;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &eSort))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground::Instance().SetTerrainRenderSort((CMapOutdoor::ETerrainRenderSort) eSort);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundSetTransparentTree(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int bTransparent;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &bTransparent))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground::Instance().SetTransparentTree(bTransparent ? true : false);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundGlobalPositionToLocalPosition(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iX;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iX))
|
||||
return Py_BadArgument();
|
||||
|
||||
int iY;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &iY))
|
||||
return Py_BadArgument();
|
||||
|
||||
LONG lX=iX;
|
||||
LONG lY=iY;
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
rkBG.GlobalPositionToLocalPosition(lX, lY);
|
||||
|
||||
return Py_BuildValue("ii", lX, lY);
|
||||
}
|
||||
|
||||
PyObject * backgroundGlobalPositionToMapInfo(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iX;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iX))
|
||||
return Py_BadArgument();
|
||||
|
||||
int iY;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &iY))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground& rkBG=CPythonBackground::Instance();
|
||||
CPythonBackground::TMapInfo* pkMapInfo=rkBG.GlobalPositionToMapInfo(iX, iY);
|
||||
|
||||
if (pkMapInfo)
|
||||
return Py_BuildValue("sii", pkMapInfo->m_strName.c_str(), pkMapInfo->m_dwBaseX, pkMapInfo->m_dwBaseY);
|
||||
else
|
||||
return Py_BuildValue("sii", "", 0, 0);
|
||||
}
|
||||
|
||||
|
||||
PyObject * backgroundWarpTest(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iX;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iX))
|
||||
return Py_BadArgument();
|
||||
|
||||
int iY;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &iY))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground::Instance().Warp((DWORD)iX * 100 , (DWORD)iY * 100);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundSetXMasTree(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iGrade;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iGrade))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground::Instance().SetXMaxTree(iGrade);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundRegisterDungeonMapName(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
char * szName;
|
||||
if (!PyTuple_GetString(poArgs, 0, &szName))
|
||||
return Py_BadArgument();
|
||||
|
||||
CPythonBackground::Instance().RegisterDungeonMapName(szName);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundVisibleGuildArea(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().VisibleGuildArea();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * backgroundDisableGuildArea(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonBackground::Instance().DisableGuildArea();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
void initBackground()
|
||||
{
|
||||
static PyMethodDef s_methods[] =
|
||||
{
|
||||
{ "IsSoftwareTiling", backgroundIsSoftwareTiling, METH_VARARGS },
|
||||
{ "EnableSoftwareTiling", backgroundEnableSoftwareTiling, METH_VARARGS },
|
||||
{ "EnableSnow", backgroundEnableSnow, METH_VARARGS },
|
||||
{ "GlobalPositionToLocalPosition", backgroundGlobalPositionToLocalPosition, METH_VARARGS },
|
||||
{ "GlobalPositionToMapInfo", backgroundGlobalPositionToMapInfo, METH_VARARGS },
|
||||
{ "GetRenderShadowTime", backgroundGetRenderShadowTime, METH_VARARGS },
|
||||
{ "LoadMap", backgroundLoadMap, METH_VARARGS },
|
||||
{ "Destroy", backgroundDestroy, METH_VARARGS },
|
||||
{ "RegisterEnvironmentData", backgroundRegisterEnvironmentData, METH_VARARGS },
|
||||
{ "SetEnvironmentData", backgroundSetEnvironmentData, METH_VARARGS },
|
||||
{ "GetCurrentMapName", backgroundGetCurrentMapName, METH_VARARGS },
|
||||
{ "GetPickingPoint", backgroundGetPickingPoint, METH_VARARGS },
|
||||
|
||||
{ "BeginEnvironment", backgroundBeginEnvironment, METH_VARARGS },
|
||||
{ "EndEnvironment", backgroundEndEnvironemt, METH_VARARGS },
|
||||
{ "SetCharacterDirLight", backgroundSetCharacterDirLight, METH_VARARGS },
|
||||
{ "SetBackgroundDirLight", backgroundSetBackgroundDirLight, METH_VARARGS },
|
||||
|
||||
{ "Initialize", backgroundInitialize, METH_VARARGS },
|
||||
{ "Update", backgroundUpdate, METH_VARARGS },
|
||||
{ "Render", backgroundRender, METH_VARARGS },
|
||||
{ "RenderPCBlocker", backgroundRenderPCBlocker, METH_VARARGS },
|
||||
{ "RenderCollision", backgroundRenderCollision, METH_VARARGS },
|
||||
{ "RenderSky", backgroundRenderSky, METH_VARARGS },
|
||||
{ "RenderCloud", backgroundRenderCloud, METH_VARARGS },
|
||||
{ "RenderWater", backgroundRenderWater, METH_VARARGS },
|
||||
{ "RenderEffect", backgroundRenderEffect, METH_VARARGS },
|
||||
{ "RenderBeforeLensFlare", backgroundRenderBeforeLensFlare, METH_VARARGS },
|
||||
{ "RenderAfterLensFlare", backgroundRenderAfterLensFlare, METH_VARARGS },
|
||||
{ "RenderCharacterShadowToTexture", backgroundRenderCharacterShadowToTexture, METH_VARARGS },
|
||||
{ "RenderDungeon", backgroundRenderDungeon, METH_VARARGS },
|
||||
{ "GetHeight", backgroundGetHeight, METH_VARARGS },
|
||||
|
||||
{ "SetShadowLevel", backgroundSetShadowLevel, METH_VARARGS },
|
||||
|
||||
{ "SetVisiblePart", backgroundSetVisiblePart, METH_VARARGS },
|
||||
{ "GetShadowMapColor", backgroundGetShadowMapcolor, METH_VARARGS },
|
||||
{ "SetSplatLimit", backgroundSetSpaltLimit, METH_VARARGS },
|
||||
{ "GetRenderedSplatNum", backgroundGetRenderedSplatNum, METH_VARARGS },
|
||||
{ "GetRenderedGraphicThingInstanceNum", backgroundGetRenderedGTINum, METH_VARARGS },
|
||||
{ "SelectViewDistanceNum", backgroundSelectViewDistanceNum, METH_VARARGS },
|
||||
{ "SetViewDistanceSet", backgroundSetViewDistanceSet, METH_VARARGS },
|
||||
{ "GetFarClip", backgroundGetFarClip, METH_VARARGS },
|
||||
{ "GetDistanceSetInfo", backgroundGetDistanceSetInfo, METH_VARARGS },
|
||||
{ "SetBGLoading", backgroundSetBGLoading, METH_VARARGS },
|
||||
{ "SetRenderSort", backgroundSetRenderSort, METH_VARARGS },
|
||||
{ "SetTransparentTree", backgroundSetTransparentTree, METH_VARARGS },
|
||||
{ "SetXMasTree", backgroundSetXMasTree, METH_VARARGS },
|
||||
{ "RegisterDungeonMapName", backgroundRegisterDungeonMapName, METH_VARARGS },
|
||||
|
||||
{ "VisibleGuildArea", backgroundVisibleGuildArea, METH_VARARGS },
|
||||
{ "DisableGuildArea", backgroundDisableGuildArea, METH_VARARGS },
|
||||
|
||||
{ "WarpTest", backgroundWarpTest, METH_VARARGS },
|
||||
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
PyObject * poModule = Py_InitModule("background", s_methods);
|
||||
|
||||
PyModule_AddIntConstant(poModule, "PART_SKY", CMapOutdoor::PART_SKY);
|
||||
PyModule_AddIntConstant(poModule, "PART_TREE", CMapOutdoor::PART_TREE);
|
||||
PyModule_AddIntConstant(poModule, "PART_CLOUD", CMapOutdoor::PART_CLOUD);
|
||||
PyModule_AddIntConstant(poModule, "PART_WATER", CMapOutdoor::PART_WATER);
|
||||
PyModule_AddIntConstant(poModule, "PART_OBJECT", CMapOutdoor::PART_OBJECT);
|
||||
PyModule_AddIntConstant(poModule, "PART_TERRAIN", CMapOutdoor::PART_TERRAIN);
|
||||
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_DEFAULT", CSkyObject::SKY_RENDER_MODE_DEFAULT);
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_DIFFUSE", CSkyObject::SKY_RENDER_MODE_DIFFUSE);
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_TEXTURE", CSkyObject::SKY_RENDER_MODE_TEXTURE);
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE", CSkyObject::SKY_RENDER_MODE_MODULATE);
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE2X", CSkyObject::SKY_RENDER_MODE_MODULATE2X);
|
||||
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE4X", CSkyObject::SKY_RENDER_MODE_MODULATE4X);
|
||||
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_NONE", CPythonBackground::SHADOW_NONE);
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_GROUND", CPythonBackground::SHADOW_GROUND);
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_GROUND_AND_SOLO", CPythonBackground::SHADOW_GROUND_AND_SOLO);
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_ALL", CPythonBackground::SHADOW_ALL);
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_ALL_HIGH", CPythonBackground::SHADOW_ALL_HIGH);
|
||||
PyModule_AddIntConstant(poModule, "SHADOW_ALL_MAX", CPythonBackground::SHADOW_ALL_MAX);
|
||||
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE0", CPythonBackground::DISTANCE0);
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE1", CPythonBackground::DISTANCE1);
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE2", CPythonBackground::DISTANCE2);
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE3", CPythonBackground::DISTANCE3);
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE4", CPythonBackground::DISTANCE4);
|
||||
|
||||
PyModule_AddIntConstant(poModule, "DISTANCE_SORT", CMapOutdoor::DISTANCE_SORT);
|
||||
PyModule_AddIntConstant(poModule, "TEXTURE_SORT", CMapOutdoor::TEXTURE_SORT);
|
||||
}
|
||||
@@ -58,6 +58,7 @@ void initnet();
|
||||
void initeffect();
|
||||
void initfly();
|
||||
void initskill();
|
||||
void initBackground();
|
||||
void initServerStateChecker();
|
||||
|
||||
extern const std::string& ApplicationStringTable_GetString(DWORD dwID);
|
||||
|
||||
@@ -662,10 +662,71 @@ typedef struct _D3DCAPS8
|
||||
// upcasts 40250 relies on (texture -> base texture) compile; of the resources only the buffers carry
|
||||
// methods (Lock/Unlock, platform/EterLib/CpuBuffer.h).
|
||||
struct IDirect3D8;
|
||||
struct IDirect3DResource8 {};
|
||||
struct IDirect3DBaseTexture8 : IDirect3DResource8 {};
|
||||
struct IDirect3DTexture8 : IDirect3DBaseTexture8 {};
|
||||
struct IDirect3DSurface8 : IDirect3DResource8 {};
|
||||
typedef enum _D3DRESOURCETYPE
|
||||
{
|
||||
D3DRTYPE_SURFACE = 1,
|
||||
D3DRTYPE_VOLUME = 2,
|
||||
D3DRTYPE_TEXTURE = 3,
|
||||
D3DRTYPE_VOLUMETEXTURE = 4,
|
||||
D3DRTYPE_CUBETEXTURE = 5,
|
||||
D3DRTYPE_VERTEXBUFFER = 6,
|
||||
D3DRTYPE_INDEXBUFFER = 7,
|
||||
D3DRTYPE_FORCE_DWORD = 0x7fffffff
|
||||
} D3DRESOURCETYPE;
|
||||
|
||||
typedef struct _D3DLOCKED_RECT
|
||||
{
|
||||
INT Pitch;
|
||||
void* pBits;
|
||||
} D3DLOCKED_RECT;
|
||||
|
||||
typedef struct _D3DSURFACE_DESC
|
||||
{
|
||||
D3DFORMAT Format;
|
||||
D3DRESOURCETYPE Type;
|
||||
DWORD Usage;
|
||||
D3DPOOL Pool;
|
||||
UINT Size;
|
||||
D3DMULTISAMPLE_TYPE MultiSampleType;
|
||||
UINT Width;
|
||||
UINT Height;
|
||||
} D3DSURFACE_DESC;
|
||||
|
||||
typedef struct _D3DRECT
|
||||
{
|
||||
LONG x1, y1, x2, y2;
|
||||
} D3DRECT;
|
||||
|
||||
#define D3DCLEAR_TARGET 0x00000001l
|
||||
#define D3DCLEAR_ZBUFFER 0x00000002l
|
||||
#define D3DCLEAR_STENCIL 0x00000004l
|
||||
|
||||
// PORT: the resource interfaces carry virtual defaults so the platform's texture handles
|
||||
// (GrpImageTexture's MemoryTexture/FileTexture, owned by their own registries) need not implement
|
||||
// them; device-created resources (RecordingDevice CreateTexture/...) override AddRef/Release.
|
||||
struct IDirect3DResource8
|
||||
{
|
||||
virtual ~IDirect3DResource8() = default;
|
||||
virtual ULONG AddRef() { return 1; }
|
||||
virtual ULONG Release() { return 1; }
|
||||
};
|
||||
struct IDirect3DSurface8 : IDirect3DResource8
|
||||
{
|
||||
virtual HRESULT GetDesc(D3DSURFACE_DESC* pDesc) { return E_FAIL; }
|
||||
virtual HRESULT LockRect(D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) { return E_FAIL; }
|
||||
virtual HRESULT UnlockRect() { return E_FAIL; }
|
||||
};
|
||||
struct IDirect3DBaseTexture8 : IDirect3DResource8
|
||||
{
|
||||
virtual DWORD GetLevelCount() { return 1; }
|
||||
};
|
||||
struct IDirect3DTexture8 : IDirect3DBaseTexture8
|
||||
{
|
||||
virtual HRESULT GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) { return E_FAIL; }
|
||||
virtual HRESULT GetSurfaceLevel(UINT Level, IDirect3DSurface8** ppSurfaceLevel) { return E_FAIL; }
|
||||
virtual HRESULT LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) { return E_FAIL; }
|
||||
virtual HRESULT UnlockRect(UINT Level) { return E_FAIL; }
|
||||
};
|
||||
struct IDirect3DVertexBuffer8 : IDirect3DResource8
|
||||
{
|
||||
virtual ~IDirect3DVertexBuffer8() = default;
|
||||
@@ -695,6 +756,15 @@ struct IDirect3DDevice8
|
||||
virtual HRESULT GetTransform(D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) = 0;
|
||||
virtual HRESULT SetMaterial(const D3DMATERIAL8* pMaterial) = 0;
|
||||
virtual HRESULT SetLight(DWORD Index, const D3DLIGHT8* pLight) = 0;
|
||||
virtual HRESULT LightEnable(DWORD Index, BOOL Enable) = 0;
|
||||
virtual HRESULT CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture8** ppTexture) = 0;
|
||||
virtual HRESULT CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) = 0;
|
||||
virtual HRESULT CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer8** ppIndexBuffer) = 0;
|
||||
virtual HRESULT CreateDepthStencilSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) = 0;
|
||||
virtual HRESULT GetRenderTarget(IDirect3DSurface8** ppRenderTarget) = 0;
|
||||
virtual HRESULT GetDepthStencilSurface(IDirect3DSurface8** ppZStencilSurface) = 0;
|
||||
virtual HRESULT SetRenderTarget(IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) = 0;
|
||||
virtual HRESULT Clear(DWORD Count, const D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) = 0;
|
||||
virtual HRESULT SetRenderState(D3DRENDERSTATETYPE State, DWORD Value) = 0;
|
||||
virtual HRESULT SetTexture(DWORD Stage, IDirect3DBaseTexture8* pTexture) = 0;
|
||||
virtual HRESULT SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) = 0;
|
||||
|
||||
@@ -411,6 +411,16 @@ inline FLOAT D3DXPlaneDotCoord(const D3DXPLANE* pP, const D3DXVECTOR3* pV)
|
||||
{
|
||||
return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z + pP->d;
|
||||
}
|
||||
inline D3DXPLANE* D3DXPlaneNormalize(D3DXPLANE* pOut, const D3DXPLANE* pP)
|
||||
{
|
||||
const FLOAT length = sqrtf(pP->a * pP->a + pP->b * pP->b + pP->c * pP->c);
|
||||
const FLOAT inv = length > 0.0f ? 1.0f / length : 0.0f;
|
||||
pOut->a = pP->a * inv;
|
||||
pOut->b = pP->b * inv;
|
||||
pOut->c = pP->c * inv;
|
||||
pOut->d = pP->d * inv;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
// --- ID3DXMatrixStack --- (the D3DX8 interface, as a plain class: the Local variants pre-multiply)
|
||||
struct ID3DXMatrixStack
|
||||
|
||||
@@ -65,9 +65,37 @@ void fill_find_data(const std::string& path, WIN32_FIND_DATA* data)
|
||||
const size_t slash = path.find_last_of('/');
|
||||
const std::string name = path.substr(slash == std::string::npos ? 0 : slash + 1);
|
||||
std::snprintf(data->cFileName, sizeof(data->cFileName), "%s", name.c_str());
|
||||
struct stat st{};
|
||||
data->dwFileAttributes = stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode) ? FILE_ATTRIBUTE_DIRECTORY
|
||||
: FILE_ATTRIBUTE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CopyFile(LPCSTR existing_path, LPCSTR new_path, BOOL fail_if_exists)
|
||||
{
|
||||
if (!existing_path || !new_path)
|
||||
return FALSE;
|
||||
if (fail_if_exists && _access(new_path, 0) == 0)
|
||||
return FALSE;
|
||||
FILE* in = std::fopen(existing_path, "rb");
|
||||
if (!in)
|
||||
return FALSE;
|
||||
FILE* out = std::fopen(new_path, "wb");
|
||||
if (!out)
|
||||
{
|
||||
std::fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
char buffer[65536];
|
||||
size_t n;
|
||||
bool ok = true;
|
||||
while ((n = std::fread(buffer, 1, sizeof(buffer), in)) > 0)
|
||||
ok = ok && std::fwrite(buffer, 1, n, out) == n;
|
||||
std::fclose(in);
|
||||
ok = std::fclose(out) == 0 && ok;
|
||||
return ok ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
HANDLE FindFirstFile(const char* pattern, WIN32_FIND_DATA* data)
|
||||
{
|
||||
if (!pattern || !data)
|
||||
|
||||
@@ -61,8 +61,11 @@ int _snprintf(char* buf, size_t count, const char* fmt, ...)
|
||||
// the MSVC modes 0 (exists), 2 (write), 4 (read), 6 (read/write).
|
||||
BOOL CreateDirectory(LPCSTR path, void* security_attributes);
|
||||
BOOL DeleteFile(LPCSTR path);
|
||||
BOOL CopyFile(LPCSTR existing_path, LPCSTR new_path, BOOL fail_if_exists);
|
||||
int _access(const char* path, int mode);
|
||||
struct WIN32_FIND_DATA { char cFileName[MAX_PATH]; };
|
||||
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
|
||||
#define FILE_ATTRIBUTE_NORMAL 0x00000080
|
||||
struct WIN32_FIND_DATA { DWORD dwFileAttributes; char cFileName[MAX_PATH]; };
|
||||
#define INVALID_HANDLE_VALUE (reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1)))
|
||||
HANDLE FindFirstFile(const char* pattern, WIN32_FIND_DATA* data);
|
||||
BOOL FindNextFile(HANDLE handle, WIN32_FIND_DATA* data);
|
||||
@@ -72,6 +75,8 @@ void Sleep(DWORD milliseconds);
|
||||
// winmm `timeGetTime`: milliseconds since system start, wrapping at 2^32.
|
||||
DWORD timeGetTime();
|
||||
DWORD GetTickCount();
|
||||
// winbase.h: #define GetCurrentTime() GetTickCount()
|
||||
#define GetCurrentTime() GetTickCount()
|
||||
|
||||
// Recursive, like the Win32 critical section. Storage holds a std::recursive_mutex.
|
||||
struct CRITICAL_SECTION
|
||||
|
||||
@@ -99,6 +99,13 @@ Array Metin2PythonHost::ui_render_commands() {
|
||||
item["uv"] = PackedVector2Array({Vector2(command.su, command.sv), Vector2(command.eu, command.sv),
|
||||
Vector2(command.su, command.ev), Vector2(command.eu, command.ev)});
|
||||
item["blend"] = command.blend;
|
||||
if (!command.mask.empty()) {
|
||||
item["mask"] = String::utf8(command.mask.c_str());
|
||||
PackedVector2Array mask_uv;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
mask_uv.push_back(Vector2(command.mu[i], command.mv[i]));
|
||||
item["mask_uv"] = mask_uv;
|
||||
}
|
||||
}
|
||||
out.push_back(item);
|
||||
}
|
||||
|
||||
@@ -542,13 +542,16 @@ int main(int argc, char** argv)
|
||||
"assert _icon != 0\n"
|
||||
"skill.DeleteIconInstance(_icon)"));
|
||||
|
||||
// miniMap module (PythonMiniMapModule.cpp): uiminimap.MiniMap created and showed it. CMapOutdoor is not
|
||||
// ported, so CMapManager::IsMapOutdoor() is false and the atlas reports "not loaded" as 40250 does off an
|
||||
// outdoor map.
|
||||
CHECK(py("import miniMap\n"
|
||||
// miniMap module (PythonMiniMapModule.cpp): uiminimap.MiniMap created and showed it. The warp loaded the
|
||||
// outdoor map through CPythonBackground::Warp -> CMapManager::LoadMap -> CMapOutdoor, so the map is outdoor
|
||||
// and CPythonMiniMap::LoadAtlas found the map's atlas image (its size is the atlas bitmap's).
|
||||
CHECK(CPythonBackground::Instance().IsMapOutdoor());
|
||||
CHECK(py("import miniMap, background\n"
|
||||
"assert miniMap.isShow()\n"
|
||||
"(bGet, x, y) = miniMap.GetAtlasSize()\n"
|
||||
"assert not bGet, (bGet, x, y)"));
|
||||
"assert bGet and x > 0 and y > 0, (bGet, x, y)\n"
|
||||
"print 'port_login_flow_test: atlas %dx%d' % (x, y)\n"
|
||||
"assert background.GetCurrentMapName() != '', background.GetCurrentMapName()"));
|
||||
|
||||
// Ground items (CPythonItem): the fake server put vnum 19 next to the actor at entergame (GC_ITEM_GROUND_ADD
|
||||
// + GC_ITEM_OWNERSHIP). player.PickCloseItem finds it within __GetPickableDistance, sends CG_ITEM_PICKUP,
|
||||
|
||||
Reference in New Issue
Block a user