atom0s
6 years ago
24 changed files with 1973 additions and 1 deletions
@ -0,0 +1,136 @@ |
|||||||
|
#include "DxRender.h" |
||||||
|
|
||||||
|
DxRender::DxRender() |
||||||
|
{ |
||||||
|
g_pD3D = NULL; |
||||||
|
g_pD3DDevice = NULL; |
||||||
|
pDxFont = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
DxRender::~DxRender() |
||||||
|
{ |
||||||
|
this->Release(); |
||||||
|
} |
||||||
|
|
||||||
|
bool DxRender::Init(HWND hWnd, MapManager* mMapManager) |
||||||
|
{ |
||||||
|
HRESULT hr; |
||||||
|
D3DDISPLAYMODE disp_mode; |
||||||
|
D3DPRESENT_PARAMETERS pp; |
||||||
|
if(!g_pD3D) |
||||||
|
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); |
||||||
|
if(!g_pD3D) return false; |
||||||
|
|
||||||
|
hr = g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &disp_mode); |
||||||
|
if (FAILED(hr)) |
||||||
|
{ |
||||||
|
g_pD3D->Release(); |
||||||
|
g_pD3D = NULL; |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
ZeroMemory(&pp, sizeof(D3DPRESENT_PARAMETERS)); |
||||||
|
pp.Windowed = true; |
||||||
|
pp.SwapEffect = D3DSWAPEFFECT_DISCARD; |
||||||
|
pp.BackBufferFormat = disp_mode.Format; |
||||||
|
pp.EnableAutoDepthStencil = TRUE; |
||||||
|
pp.AutoDepthStencilFormat = D3DFMT_D16; |
||||||
|
pp.BackBufferCount = 1; |
||||||
|
|
||||||
|
hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,&pp,&g_pD3DDevice); |
||||||
|
if (FAILED(hr)) |
||||||
|
{ |
||||||
|
hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&pp,&g_pD3DDevice); |
||||||
|
if (FAILED(hr)) |
||||||
|
{ |
||||||
|
hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&pp,&g_pD3DDevice); |
||||||
|
if (FAILED(hr)) |
||||||
|
{ |
||||||
|
g_pD3D->Release(); |
||||||
|
g_pD3D = NULL; |
||||||
|
return FALSE; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
D3DCAPS9 DX9DCaps; |
||||||
|
g_pD3DDevice->GetDeviceCaps(&DX9DCaps); |
||||||
|
|
||||||
|
ZeroMemory( &light, sizeof(light) ); |
||||||
|
light.Type = D3DLIGHT_DIRECTIONAL; |
||||||
|
light.Diffuse.r = 1.0f; |
||||||
|
light.Diffuse.g = 1.0f; |
||||||
|
light.Diffuse.b = 1.0f; |
||||||
|
light.Ambient.r = 1.0f; |
||||||
|
light.Ambient.g = 1.0f; |
||||||
|
light.Ambient.b = 1.0f; |
||||||
|
|
||||||
|
D3DXVECTOR3 vector = D3DXVECTOR3(0.0f,1.0f,2.0f); |
||||||
|
D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction,&vector); |
||||||
|
|
||||||
|
g_pD3DDevice->SetLight(0, &light); |
||||||
|
|
||||||
|
QueryPerformanceFrequency(&m_PerformanceFrequency); |
||||||
|
QueryPerformanceCounter(&m_LastFPSUpdateTick); |
||||||
|
m_FramesRendered = 0; |
||||||
|
|
||||||
|
D3DXCreateFontA(g_pD3DDevice, 30, 10, FW_NORMAL, 0, false, 1, 0, 0, DEFAULT_PITCH|FF_MODERN, "Arial", &pDxFont); |
||||||
|
|
||||||
|
m_MapManager = mMapManager; |
||||||
|
m_MapManager->SetDevice(g_pD3DDevice); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
void DxRender::Release() |
||||||
|
{ |
||||||
|
if(pDxFont) |
||||||
|
{ |
||||||
|
pDxFont->Release(); |
||||||
|
pDxFont = NULL; |
||||||
|
} |
||||||
|
if (g_pD3DDevice) |
||||||
|
{ |
||||||
|
g_pD3DDevice->Release(); |
||||||
|
g_pD3DDevice = NULL; |
||||||
|
} |
||||||
|
if (g_pD3D) |
||||||
|
{ |
||||||
|
g_pD3D->Release(); |
||||||
|
g_pD3D = NULL; |
||||||
|
} |
||||||
|
//TODO: Clear buffers
|
||||||
|
} |
||||||
|
|
||||||
|
void DxRender::onTick() |
||||||
|
{ |
||||||
|
if(g_pD3DDevice) |
||||||
|
{ |
||||||
|
g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(128,0,0), 1.0f, 0L ); |
||||||
|
|
||||||
|
DWORD CurrentTick = GetTickCount(); |
||||||
|
LARGE_INTEGER CurrentPerformanceTick; |
||||||
|
QueryPerformanceCounter(&CurrentPerformanceTick); |
||||||
|
double TimeElapsedSeconds = (double)(CurrentPerformanceTick.QuadPart - m_LastFPSUpdateTick.QuadPart) / (double)(m_PerformanceFrequency.QuadPart); |
||||||
|
if(TimeElapsedSeconds >= 1) |
||||||
|
{ |
||||||
|
m_CurrentFPS = ((double)m_FramesRendered) / TimeElapsedSeconds; |
||||||
|
m_FramesRendered = 0; |
||||||
|
m_LastFPSUpdateTick = CurrentPerformanceTick; |
||||||
|
} |
||||||
|
|
||||||
|
g_pD3DDevice->BeginScene(); |
||||||
|
m_MapManager->Render(); |
||||||
|
|
||||||
|
if(pDxFont) |
||||||
|
{ |
||||||
|
char buffer[128]; |
||||||
|
RECT rc={0,0,100,100}; |
||||||
|
sprintf(buffer, "FPS: %.1lf", m_CurrentFPS); |
||||||
|
pDxFont->DrawTextA(NULL, buffer, lstrlenA(buffer), &rc, DT_TOP | DT_LEFT, D3DCOLOR_XRGB(255,255,0)); |
||||||
|
} |
||||||
|
g_pD3DDevice->EndScene(); |
||||||
|
|
||||||
|
g_pD3DDevice->Present( NULL, NULL, NULL, NULL ); |
||||||
|
m_FramesRendered++; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
#pragma once |
||||||
|
#define DIRECT3D_VERSION 0x0900 |
||||||
|
#include "stdafx.h" |
||||||
|
#include <d3d9.h> |
||||||
|
#include <d3dx9math.h> |
||||||
|
#pragma comment(lib,"d3d9") |
||||||
|
#pragma comment(lib,"D3dx9") |
||||||
|
|
||||||
|
#pragma comment(lib, "winmm.lib") |
||||||
|
#include <mmsystem.h> |
||||||
|
|
||||||
|
#include "MapManager.h" |
||||||
|
|
||||||
|
class DxRender |
||||||
|
{ |
||||||
|
private: |
||||||
|
LPDIRECT3D9 g_pD3D; |
||||||
|
LPDIRECT3DDEVICE9 g_pD3DDevice; |
||||||
|
|
||||||
|
D3DLIGHT9 light; |
||||||
|
|
||||||
|
MapManager* m_MapManager; |
||||||
|
|
||||||
|
LARGE_INTEGER m_PerformanceFrequency; |
||||||
|
LARGE_INTEGER m_LastFPSUpdateTick; |
||||||
|
double m_CurrentFPS; |
||||||
|
int m_FramesRendered; |
||||||
|
|
||||||
|
LPD3DXFONT pDxFont; |
||||||
|
LPD3DXSPRITE pDxSprite; |
||||||
|
public: |
||||||
|
DxRender(); |
||||||
|
~DxRender(); |
||||||
|
bool Init(HWND hWnd, MapManager* mMapManager); |
||||||
|
void Release(); |
||||||
|
void onTick(); |
||||||
|
}; |
Binary file not shown.
@ -0,0 +1,178 @@ |
|||||||
|
#ifndef FFACE_H |
||||||
|
#define FFACE_H |
||||||
|
#include <Windows.h> |
||||||
|
#include "structures.h" |
||||||
|
#define FFACE_API __declspec( dllimport ) |
||||||
|
/*!\file FFACE4.h
|
||||||
|
\brief version 4 import header. */ |
||||||
|
|
||||||
|
//!Main Constructor.
|
||||||
|
/*!
|
||||||
|
\param PID A valid FFXI process ID. |
||||||
|
\return Pointer to the created instance of FFACE. |
||||||
|
*/ |
||||||
|
FFACE_API void* CreateInstance(DWORD PID); |
||||||
|
//!Main Destructor.
|
||||||
|
/*!
|
||||||
|
\param Instance - A vailid FFACE instance. |
||||||
|
\return nothing. |
||||||
|
*/ |
||||||
|
FFACE_API void DeleteInstance(void* Instance); |
||||||
|
/*!Used to check if Contrubtor functions are active.
|
||||||
|
\param Instance - A vailid FFACE instance. |
||||||
|
\return An bool indacating current function access. |
||||||
|
*/ |
||||||
|
FFACE_API bool Access(void* Instance); |
||||||
|
/*Windower*/ |
||||||
|
/*!
|
||||||
|
\param Instance - A vailid FFACE instance. |
||||||
|
\param name - A name to reference the text object. |
||||||
|
\return nothing. |
||||||
|
*/ |
||||||
|
FFACE_API void CTHCreateTextObject(void* Instance, char* name); |
||||||
|
/*!
|
||||||
|
\param Instance - A vailid FFACE instance. |
||||||
|
\param name - The name used to reference the text object. |
||||||
|
\return nothing. |
||||||
|
*/ |
||||||
|
FFACE_API void CTHDeleteTextObject(void* Instance, char* name); |
||||||
|
/*!
|
||||||
|
\param Instance - A vailid FFACE instance. |
||||||
|
\param name - The name used to reference the text object. |
||||||
|
\param text - The text to be set. |
||||||
|
\return nothing. |
||||||
|
*/ |
||||||
|
FFACE_API void CTHSetText(void* Instance, char* name, char* text); |
||||||
|
/*!
|
||||||
|
\param Instance - A vailid FFACE instance. |
||||||
|
\param name - The name used to reference the text object. |
||||||
|
\param visible |
||||||
|
\return nothing. |
||||||
|
*/ |
||||||
|
FFACE_API void CTHSetVisibility(void* Instance, char* name, bool visible); |
||||||
|
FFACE_API void CTHSetFont(void* Instance, char* name, char* font, int height); |
||||||
|
FFACE_API void CTHSetColor(void* Instance, char* name, unsigned char a, unsigned char r, unsigned char g, unsigned char b); |
||||||
|
FFACE_API void CTHSetLocation(void* Instance, char* name, float x, float y); |
||||||
|
FFACE_API void CTHSetBold(void* Instance, char* name, bool bold); |
||||||
|
FFACE_API void CTHSetItalic(void* Instance, char* name, bool italic); |
||||||
|
FFACE_API void CTHSetBGColor(void* Instance, char* name, unsigned char a, unsigned char r, unsigned char g, unsigned char b); |
||||||
|
FFACE_API void CTHSetBGBorderSize(void* Instance, char* name, float pixels); |
||||||
|
FFACE_API void CTHSetBGVisibility(void* Instance, char* name, bool visible); |
||||||
|
FFACE_API void CTHSetRightJustified(void* Instance, char* name, bool justified); |
||||||
|
FFACE_API void CTHFlushCommands(void* Instance); |
||||||
|
FFACE_API void CKHSetKey(void* Instance, unsigned char key, bool down); |
||||||
|
FFACE_API void CKHBlockInput(void* Instance, bool block); |
||||||
|
FFACE_API void CKHSendString(void* Instance, char* string); |
||||||
|
FFACE_API int CCHIsNewCommand(void* Instance); |
||||||
|
FFACE_API int CCHGetArgCount(void* Instance); |
||||||
|
FFACE_API void CCHGetArg(void* Instance, int index, char* buffer); |
||||||
|
|
||||||
|
/*Player Class*/ |
||||||
|
FFACE_API void GetPlayerInfo(void* Instance, PLAYERINFO* PLAYER); |
||||||
|
FFACE_API float GetCastMax(void* Instance); |
||||||
|
FFACE_API float GetCastCountDown(void* Instance); |
||||||
|
FFACE_API float GetCastPercent(void* Instance); |
||||||
|
FFACE_API short GetCastPercentEx(void* Instance); |
||||||
|
FFACE_API char GetViewMode(void* Instance); |
||||||
|
FFACE_API char GetPlayerStatus(void* Instance); |
||||||
|
FFACE_API char GetPLayerServerID(void *Instanceance); |
||||||
|
|
||||||
|
/*Party*/ |
||||||
|
FFACE_API void GetAllianceInfo(void* Instance, ALLIANCEINFO* AI); |
||||||
|
FFACE_API void GetPartyMembers(void* Instance, PARTYMEMBERS* ptm); |
||||||
|
FFACE_API void GetPartyMember(void* Instance, char index, PARTYMEMBER* ptm); |
||||||
|
|
||||||
|
/*chat*/ |
||||||
|
FFACE_API BOOL IsNewLine(void* Instance); |
||||||
|
FFACE_API void GetChatLineR(void* Instance, int index, void *buffer, int* size); |
||||||
|
FFACE_API void GetChatLine(void* Instance, int index, void *buffer, int* size); |
||||||
|
FFACE_API void GetChatLineEx(void* Instance, int index, void *buffer, int* size, CHATEXTRAINFO* ExtraInfo); |
||||||
|
FFACE_API int GetChatLineCount(void* Instance); |
||||||
|
|
||||||
|
/*Timers*/ |
||||||
|
FFACE_API short GetSpellRecast(void* Instance, short id); |
||||||
|
FFACE_API char GetAbilityID(void* Instance, char index); |
||||||
|
FFACE_API int GetAbilityRecast(void* Instance, char index); |
||||||
|
FFACE_API int GetVanaUTC(void* Instance); |
||||||
|
|
||||||
|
/*NPC*/ |
||||||
|
FFACE_API bool IsNPCclaimed(void* Instance, int index); |
||||||
|
FFACE_API int GetNPCclaimID(void* Instance, int index); |
||||||
|
FFACE_API char GetNPCType(void* Instance, int index); |
||||||
|
FFACE_API BOOL NPCIsActive(void* Instance, int index); |
||||||
|
FFACE_API void GetNPCName(void* Instance, int index, void *buffer, int* size); |
||||||
|
FFACE_API float GetNPCPosX(void* Instance, int index); |
||||||
|
FFACE_API float GetNPCPosY(void* Instance, int index); |
||||||
|
FFACE_API float GetNPCPosZ(void* Instance, int index); |
||||||
|
FFACE_API float GetNPCPosH(void* Instance, int index); |
||||||
|
FFACE_API float SetNPCPosH(void* Instance, int index, float value); |
||||||
|
FFACE_API char GetNPCHPP(void* Instance, int index); |
||||||
|
FFACE_API short GetNPCTP(void* Instance, int index); |
||||||
|
FFACE_API char GetNPCStatus(void* Instance, int index); |
||||||
|
FFACE_API int GetNPCPetID(void* Instance, int index); |
||||||
|
FFACE_API float GetNPCDistance(void* Instance, int index); |
||||||
|
FFACE_API char GetNPCBit(void* Instance, int index); |
||||||
|
FFACE_API double GetNPCHeadingToNPC(void* Instance, int index0, int index1); |
||||||
|
|
||||||
|
/*Target*/ |
||||||
|
FFACE_API void GetTargetInfo(void* Instance, TARGETINFO* Target); |
||||||
|
FFACE_API BOOL SetTargetName(void* Instance, char name[], int Size); |
||||||
|
FFACE_API BOOL SetTarget(void* Instance, int index); |
||||||
|
|
||||||
|
/*Inventory*/ |
||||||
|
FFACE_API char GetInventoryMax(void* Instance) ; |
||||||
|
FFACE_API char GetSafeMax(void* Instance); |
||||||
|
FFACE_API char GetStorageMax(void* Instance); |
||||||
|
FFACE_API char GetTempMax(void* Instance); |
||||||
|
FFACE_API char GetLockerMax(void* Instance); |
||||||
|
FFACE_API char GetSatchelMax(void* Instance); |
||||||
|
FFACE_API char GetSackMax(void* Instance); |
||||||
|
FFACE_API INVENTORYITEM GetInventoryItem(void* Instance, int index); |
||||||
|
FFACE_API INVENTORYITEM GetSafeItem(void* Instance, int index); |
||||||
|
FFACE_API INVENTORYITEM GetStorageItem(void* Instance, int index); |
||||||
|
FFACE_API INVENTORYITEM GetTempItem(void* Instance, int index); |
||||||
|
FFACE_API INVENTORYITEM GetLockerItem(void* Instance, int index); |
||||||
|
FFACE_API INVENTORYITEM GetSatchelItem(void* Instance, int index); |
||||||
|
FFACE_API INVENTORYITEM GetSackItem(void* Instance, int index); |
||||||
|
FFACE_API void GetSelectedItemName(void* Instance, void *buffer, int* maxlength); |
||||||
|
FFACE_API int GetSelectedItemNum(void* Instance); |
||||||
|
FFACE_API char GetSelectedItemIndex(void* Instance); |
||||||
|
FFACE_API char GetEquippedItemIndex(void* Instance, char slot); |
||||||
|
FFACE_API TREASUREITEM GetTreasureItem(void* Instance, char index); |
||||||
|
|
||||||
|
/*Fishing*/ |
||||||
|
FFACE_API BOOL FishOnLine(void* Instance); |
||||||
|
FFACE_API char GetRodPosition(void* Instance); |
||||||
|
FFACE_API int GetFishHPMax(void* Instance); |
||||||
|
FFACE_API int GetFishHP(void* Instance); |
||||||
|
FFACE_API short GetFishOnlineTime(void* Instance); |
||||||
|
FFACE_API short GetFishTimeout(void* Instance); |
||||||
|
FFACE_API int GetFishID1(void* Instance); |
||||||
|
FFACE_API int GetFishID2(void* Instance); |
||||||
|
FFACE_API int GetFishID3(void* Instance); |
||||||
|
FFACE_API int GetFishID4(void* Instance); |
||||||
|
|
||||||
|
/*MENU*/ |
||||||
|
FFACE_API short GetDialogID(void* Instance); |
||||||
|
FFACE_API int GetDialogIndexCount(void* Instance); |
||||||
|
FFACE_API short GetDialogIndex(void* Instance); |
||||||
|
FFACE_API void GetDialogStrings(void* Instance, void* buffer, int* size); |
||||||
|
FFACE_API BOOL MenuIsOpen(void* Instance); |
||||||
|
FFACE_API void MenuName(void* Instance, void* buffer, int* size); |
||||||
|
FFACE_API void MenuSelection(void* Instance, void* buffer, int* size); |
||||||
|
FFACE_API void MenuHelp(void* Instance, void* buffer, int* size); |
||||||
|
FFACE_API char ShopQuantityMax(void* Instance); |
||||||
|
FFACE_API void GetNPCTradeInfo(void* Instance, TRADEINFO* TI); |
||||||
|
FFACE_API BOOL IsSynthesis(void* Instance); |
||||||
|
/*MENU*/ |
||||||
|
/*SEARCH*/ |
||||||
|
FFACE_API int GetSearchTotalCount(void* Instance); |
||||||
|
FFACE_API char GetSearchPageCount(void* Instance); |
||||||
|
FFACE_API char GetSearchZone(void* Instance, short index); |
||||||
|
FFACE_API char GetSearchMainJob(void* Instance, short index); |
||||||
|
FFACE_API char GetSearchSubJob(void* Instance, short index); |
||||||
|
FFACE_API char GetSearchMainlvl(void* Instance, short index); |
||||||
|
FFACE_API char GetSearchSublvl(void* Instance, short index); |
||||||
|
FFACE_API void GetSearchName(void* Instance, short index, void* Buffer, int* BufferSize); |
||||||
|
/*SEARCH*/ |
||||||
|
#endif // FFACE_H
|
@ -0,0 +1,181 @@ |
|||||||
|
// FFXIMapViewer.cpp : Defines the entry point for the application.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "stdafx.h" |
||||||
|
#include "FFXIMapViewer.h" |
||||||
|
#include "DxRender.h" |
||||||
|
#include "MapManager.h" |
||||||
|
#include <process.h> |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_LOADSTRING 100 |
||||||
|
|
||||||
|
// Global Variables:
|
||||||
|
MapManager m_MapManager; |
||||||
|
bool ThreadRun = true; |
||||||
|
HANDLE m_hThread; |
||||||
|
unsigned int m_uiThread; |
||||||
|
HINSTANCE hInst; // current instance
|
||||||
|
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
|
||||||
|
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
|
||||||
|
|
||||||
|
// Forward declarations of functions included in this code module:
|
||||||
|
ATOM MyRegisterClass(HINSTANCE hInstance); |
||||||
|
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); |
||||||
|
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); |
||||||
|
|
||||||
|
|
||||||
|
unsigned int WINAPI ThreadProc(void* lParam) |
||||||
|
{ |
||||||
|
DxRender* m_Render = (DxRender*)lParam; |
||||||
|
while(ThreadRun) |
||||||
|
{ |
||||||
|
m_Render->onTick(); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) |
||||||
|
{ |
||||||
|
UNREFERENCED_PARAMETER(hPrevInstance); |
||||||
|
UNREFERENCED_PARAMETER(lpCmdLine); |
||||||
|
|
||||||
|
// TODO: Place code here.
|
||||||
|
MSG msg; |
||||||
|
HACCEL hAccelTable; |
||||||
|
HWND hWnd; |
||||||
|
DxRender m_Render; |
||||||
|
|
||||||
|
hInst = hInstance; // Store instance handle in our global variable
|
||||||
|
|
||||||
|
// Initialize global strings
|
||||||
|
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); |
||||||
|
LoadString(hInstance, IDC_FFXIMAPVIEWER, szWindowClass, MAX_LOADSTRING); |
||||||
|
MyRegisterClass(hInstance); |
||||||
|
|
||||||
|
hWnd = CreateWindow(szWindowClass, |
||||||
|
szTitle, |
||||||
|
WS_OVERLAPPEDWINDOW, |
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, |
||||||
|
1024, 768, |
||||||
|
0, |
||||||
|
NULL, |
||||||
|
hInstance, |
||||||
|
NULL); |
||||||
|
|
||||||
|
if (!hWnd) |
||||||
|
{ |
||||||
|
return FALSE; |
||||||
|
} |
||||||
|
|
||||||
|
m_MapManager.LoadMap(126); |
||||||
|
if(!m_Render.Init(hWnd, &m_MapManager)) |
||||||
|
{ |
||||||
|
MessageBoxA(0, "DirectX9Create failed.", "Error", MB_OK | MB_ICONEXCLAMATION); |
||||||
|
} |
||||||
|
ShowWindow(hWnd, nCmdShow); |
||||||
|
UpdateWindow(hWnd); |
||||||
|
SetFocus(hWnd); |
||||||
|
|
||||||
|
m_hThread = (HANDLE)_beginthreadex( NULL, 0, &ThreadProc, &m_Render, 0, &m_uiThread ); |
||||||
|
|
||||||
|
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_FFXIMAPVIEWER)); |
||||||
|
|
||||||
|
// Main message loop:
|
||||||
|
while (GetMessage(&msg, NULL, 0, 0)) |
||||||
|
{ |
||||||
|
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) |
||||||
|
{ |
||||||
|
TranslateMessage(&msg); |
||||||
|
DispatchMessage(&msg); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
ThreadRun = false; |
||||||
|
WaitForSingleObject(m_hThread, 4000); |
||||||
|
m_Render.Release(); |
||||||
|
|
||||||
|
return (int) msg.wParam; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// FUNCTION: MyRegisterClass()
|
||||||
|
//
|
||||||
|
// PURPOSE: Registers the window class.
|
||||||
|
//
|
||||||
|
// COMMENTS:
|
||||||
|
//
|
||||||
|
// This function and its usage are only necessary if you want this code
|
||||||
|
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
|
||||||
|
// function that was added to Windows 95. It is important to call this function
|
||||||
|
// so that the application will get 'well formed' small icons associated
|
||||||
|
// with it.
|
||||||
|
//
|
||||||
|
ATOM MyRegisterClass(HINSTANCE hInstance) |
||||||
|
{ |
||||||
|
WNDCLASSEX wcex; |
||||||
|
|
||||||
|
wcex.cbSize = sizeof(WNDCLASSEX); |
||||||
|
|
||||||
|
wcex.style = CS_HREDRAW | CS_VREDRAW; |
||||||
|
wcex.lpfnWndProc = WndProc; |
||||||
|
wcex.cbClsExtra = 0; |
||||||
|
wcex.cbWndExtra = 0; |
||||||
|
wcex.hInstance = hInstance; |
||||||
|
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FFXIMAPVIEWER)); |
||||||
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); |
||||||
|
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); |
||||||
|
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_FFXIMAPVIEWER); |
||||||
|
wcex.lpszClassName = szWindowClass; |
||||||
|
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); |
||||||
|
|
||||||
|
return RegisterClassEx(&wcex); |
||||||
|
} |
||||||
|
|
||||||
|
//
|
||||||
|
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
|
||||||
|
//
|
||||||
|
// PURPOSE: Processes messages for the main window.
|
||||||
|
//
|
||||||
|
// WM_COMMAND - process the application menu
|
||||||
|
// WM_PAINT - Paint the main window
|
||||||
|
// WM_DESTROY - post a quit message and return
|
||||||
|
//
|
||||||
|
//
|
||||||
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
||||||
|
{ |
||||||
|
int wmId, wmEvent; |
||||||
|
PAINTSTRUCT ps; |
||||||
|
HDC hdc; |
||||||
|
|
||||||
|
switch (message) |
||||||
|
{ |
||||||
|
case WM_COMMAND: |
||||||
|
wmId = LOWORD(wParam); |
||||||
|
wmEvent = HIWORD(wParam); |
||||||
|
// Parse the menu selections:
|
||||||
|
switch (wmId) |
||||||
|
{ |
||||||
|
case IDM_EXIT: |
||||||
|
DestroyWindow(hWnd); |
||||||
|
break; |
||||||
|
default: |
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam); |
||||||
|
} |
||||||
|
break; |
||||||
|
case WM_PAINT: |
||||||
|
hdc = BeginPaint(hWnd, &ps); |
||||||
|
// TODO: Add any drawing code here...
|
||||||
|
EndPaint(hWnd, &ps); |
||||||
|
break; |
||||||
|
case WM_DESTROY: |
||||||
|
PostQuitMessage(0); |
||||||
|
break; |
||||||
|
default: |
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "resource.h" |
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
@ -0,0 +1,364 @@ |
|||||||
|
#include "MapFile.h" |
||||||
|
#define REGISTRY_KEYS {"SOFTWARE\\PlayOnline\\InstallFolder","SOFTWARE\\PlayOnlineEU\\InstallFolder","SOFTWARE\\PlayOnlineUS\\InstallFolder"} |
||||||
|
static BYTE key_table[0x100] = |
||||||
|
{ |
||||||
|
0xE2, 0xE5, 0x06, 0xA9, 0xED, 0x26, 0xF4, 0x42, 0x15, 0xF4, 0x81, 0x7F, 0xDE, 0x9A, 0xDE, 0xD0, |
||||||
|
0x1A, 0x98, 0x20, 0x91, 0x39, 0x49, 0x48, 0xA4, 0x0A, 0x9F, 0x40, 0x69, 0xEC, 0xBD, 0x81, 0x81, |
||||||
|
0x8D, 0xAD, 0x10, 0xB8, 0xC1, 0x88, 0x15, 0x05, 0x11, 0xB1, 0xAA, 0xF0, 0x0F, 0x1E, 0x34, 0xE6, |
||||||
|
0x81, 0xAA, 0xCD, 0xAC, 0x02, 0x84, 0x33, 0x0A, 0x19, 0x38, 0x9E, 0xE6, 0x73, 0x4A, 0x11, 0x5D, |
||||||
|
0xBF, 0x85, 0x77, 0x08, 0xCD, 0xD9, 0x96, 0x0D, 0x79, 0x78, 0xCC, 0x35, 0x06, 0x8E, 0xF9, 0xFE, |
||||||
|
0x66, 0xB9, 0x21, 0x03, 0x20, 0x29, 0x1E, 0x27, 0xCA, 0x86, 0x82, 0xE6, 0x45, 0x07, 0xDD, 0xA9, |
||||||
|
0xB6, 0xD5, 0xA2, 0x03, 0xEC, 0xAD, 0x62, 0x45, 0x2D, 0xCE, 0x79, 0xBD, 0x8F, 0x2D, 0x10, 0x18, |
||||||
|
0xE6, 0x0A, 0x6F, 0xAA, 0x6F, 0x46, 0x84, 0x32, 0x9F, 0x29, 0x2C, 0xC2, 0xF0, 0xEB, 0x18, 0x6F, |
||||||
|
0xF2, 0x3A, 0xDC, 0xEA, 0x7B, 0x0C, 0x81, 0x2D, 0xCC, 0xEB, 0xA1, 0x51, 0x77, 0x2C, 0xFB, 0x49, |
||||||
|
0xE8, 0x90, 0xF7, 0x90, 0xCE, 0x5C, 0x01, 0xF3, 0x5C, 0xF4, 0x41, 0xAB, 0x04, 0xE7, 0x16, 0xCC, |
||||||
|
0x3A, 0x05, 0x54, 0x55, 0xDC, 0xED, 0xA4, 0xD6, 0xBF, 0x3F, 0x9E, 0x08, 0x93, 0xB5, 0x63, 0x38, |
||||||
|
0x90, 0xF7, 0x5A, 0xF0, 0xA2, 0x5F, 0x56, 0xC8, 0x08, 0x70, 0xCB, 0x24, 0x16, 0xDD, 0xD2, 0x74, |
||||||
|
0x95, 0x3A, 0x1A, 0x2A, 0x74, 0xC4, 0x9D, 0xEB, 0xAF, 0x69, 0xAA, 0x51, 0x39, 0x65, 0x94, 0xA2, |
||||||
|
0x4B, 0x1F, 0x1A, 0x60, 0x52, 0x39, 0xE8, 0x23, 0xEE, 0x58, 0x39, 0x06, 0x3D, 0x22, 0x6A, 0x2D, |
||||||
|
0xD2, 0x91, 0x25, 0xA5, 0x2E, 0x71, 0x62, 0xA5, 0x0B, 0xC1, 0xE5, 0x6E, 0x43, 0x49, 0x7C, 0x58, |
||||||
|
0x46, 0x19, 0x9F, 0x45, 0x49, 0xC6, 0x40, 0x09, 0xA2, 0x99, 0x5B, 0x7B, 0x98, 0x7F, 0xA0, 0xD0, |
||||||
|
}; |
||||||
|
|
||||||
|
static BYTE key_table2[0x100] = |
||||||
|
{ |
||||||
|
0xB8, 0xC5, 0xF7, 0x84, 0xE4, 0x5A, 0x23, 0x7B, 0xC8, 0x90, 0x1D, 0xF6, 0x5D, 0x09, 0x51, 0xC1, |
||||||
|
0x07, 0x24, 0xEF, 0x5B, 0x1D, 0x73, 0x90, 0x08, 0xA5, 0x70, 0x1C, 0x22, 0x5F, 0x6B, 0xEB, 0xB0, |
||||||
|
0x06, 0xC7, 0x2A, 0x3A, 0xD2, 0x66, 0x81, 0xDB, 0x41, 0x62, 0xF2, 0x97, 0x17, 0xFE, 0x05, 0xEF, |
||||||
|
0xA3, 0xDC, 0x22, 0xB3, 0x45, 0x70, 0x3E, 0x18, 0x2D, 0xB4, 0xBA, 0x0A, 0x65, 0x1D, 0x87, 0xC3, |
||||||
|
0x12, 0xCE, 0x8F, 0x9D, 0xF7, 0x0D, 0x50, 0x24, 0x3A, 0xF3, 0xCA, 0x70, 0x6B, 0x67, 0x9C, 0xB2, |
||||||
|
0xC2, 0x4D, 0x6A, 0x0C, 0xA8, 0xFA, 0x81, 0xA6, 0x79, 0xEB, 0xBE, 0xFE, 0x89, 0xB7, 0xAC, 0x7F, |
||||||
|
0x65, 0x43, 0xEC, 0x56, 0x5B, 0x35, 0xDA, 0x81, 0x3C, 0xAB, 0x6D, 0x28, 0x60, 0x2C, 0x5F, 0x31, |
||||||
|
0xEB, 0xDF, 0x8E, 0x0F, 0x4F, 0xFA, 0xA3, 0xDA, 0x12, 0x7E, 0xF1, 0xA5, 0xD2, 0x22, 0xA0, 0x0C, |
||||||
|
0x86, 0x8C, 0x0A, 0x0C, 0x06, 0xC7, 0x65, 0x18, 0xCE, 0xF2, 0xA3, 0x68, 0xFE, 0x35, 0x96, 0x95, |
||||||
|
0xA6, 0xFA, 0x58, 0x63, 0x41, 0x59, 0xEA, 0xDD, 0x7F, 0xD3, 0x1B, 0xA8, 0x48, 0x44, 0xAB, 0x91, |
||||||
|
0xFD, 0x13, 0xB1, 0x68, 0x01, 0xAC, 0x3A, 0x11, 0x78, 0x30, 0x33, 0xD8, 0x4E, 0x6A, 0x89, 0x05, |
||||||
|
0x7B, 0x06, 0x8E, 0xB0, 0x86, 0xFD, 0x9F, 0xD7, 0x48, 0x54, 0x04, 0xAE, 0xF3, 0x06, 0x17, 0x36, |
||||||
|
0x53, 0x3F, 0xA8, 0x11, 0x53, 0xCA, 0xA1, 0x95, 0xC2, 0xCD, 0xE6, 0x1F, 0x57, 0xB4, 0x7F, 0xAA, |
||||||
|
0xF3, 0x6B, 0xF9, 0xA0, 0x27, 0xD0, 0x09, 0xEF, 0xF6, 0x68, 0x73, 0x60, 0xDC, 0x50, 0x2A, 0x25, |
||||||
|
0x0F, 0x77, 0xB9, 0xB0, 0x04, 0x0B, 0xE1, 0xCC, 0x35, 0x31, 0x84, 0xE6, 0x22, 0xF9, 0xC2, 0xAB, |
||||||
|
0x95, 0x91, 0x61, 0xD9, 0x2B, 0xB9, 0x72, 0x4E, 0x10, 0x76, 0x31, 0x66, 0x0A, 0x0B, 0x2E, 0x83, |
||||||
|
}; |
||||||
|
|
||||||
|
MapFile::MapFile() |
||||||
|
{ |
||||||
|
RenderReady = false; |
||||||
|
TexListCount = 0; |
||||||
|
NumMMB = 0; |
||||||
|
pdat = NULL; |
||||||
|
pData = NULL; |
||||||
|
dwSize = 0; |
||||||
|
nobj = 0; |
||||||
|
obj = NULL; |
||||||
|
GetRegistryKey(); |
||||||
|
} |
||||||
|
|
||||||
|
MapFile::~MapFile() |
||||||
|
{ |
||||||
|
Free(); |
||||||
|
} |
||||||
|
|
||||||
|
BOOL MapFile::Free() |
||||||
|
{ |
||||||
|
RenderReady = false; |
||||||
|
dwSize = 0; |
||||||
|
if( pdat ) |
||||||
|
{ |
||||||
|
delete []pdat; |
||||||
|
pdat = NULL; |
||||||
|
} |
||||||
|
pData=NULL; |
||||||
|
|
||||||
|
for (int i = 0; i < TexListCount; ++i) |
||||||
|
{ |
||||||
|
if (TexList[i].pTex) |
||||||
|
{ |
||||||
|
TexList[i].pTex->Release(); |
||||||
|
TexList[i].pTex = NULL; |
||||||
|
} |
||||||
|
} |
||||||
|
TexListCount = 0; |
||||||
|
NumMMB = 0; |
||||||
|
nobj = 0; |
||||||
|
obj = NULL; |
||||||
|
return TRUE; |
||||||
|
} |
||||||
|
|
||||||
|
void MapFile::decode_ObjectMap(BYTE* p) |
||||||
|
{ |
||||||
|
if (p[3] >= 0x1B) |
||||||
|
{ |
||||||
|
int decode_length = (p[0] << 0) | (p[1] << 8) | (p[2] << 16); |
||||||
|
DWORD key = key_table[p[7] ^ 0xFF]; |
||||||
|
int key_counter = 0; |
||||||
|
|
||||||
|
for (int pos = 8; pos < decode_length; ) |
||||||
|
{ |
||||||
|
int xor_length = ((key >> 4) & 7) + 16; |
||||||
|
|
||||||
|
if ((key & 1) && (pos + xor_length < decode_length)) |
||||||
|
{ |
||||||
|
for (int i = 0; i < xor_length; i++) |
||||||
|
{ |
||||||
|
p[pos+i] ^= 0xFF; |
||||||
|
} |
||||||
|
} |
||||||
|
key += ++key_counter; |
||||||
|
pos += xor_length; |
||||||
|
} |
||||||
|
int node_count = (p[4] << 0) | (p[5] << 8) | (p[6] << 16); |
||||||
|
OBJINFO *node = (OBJINFO *)(p+32); |
||||||
|
for(int i = 0; i < node_count; i++) |
||||||
|
{ |
||||||
|
for(int i = 0; i < 16; i++) |
||||||
|
{ |
||||||
|
node->id[i] ^= 0x55; |
||||||
|
} |
||||||
|
node++; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void MapFile::decode_mmb(BYTE*p) |
||||||
|
{ |
||||||
|
if(p[3] >= 5) |
||||||
|
{ |
||||||
|
int decode_length = (p[0] << 0) | (p[1] << 8) | (p[2] << 16); |
||||||
|
DWORD key = key_table[p[5] ^ 0xF0]; |
||||||
|
int key_counter = 0; |
||||||
|
|
||||||
|
for(int pos = 8; pos < decode_length; pos++) |
||||||
|
{ |
||||||
|
DWORD x = ((key & 0xFF) << 8) | (key & 0xFF); |
||||||
|
key += ++key_counter; |
||||||
|
|
||||||
|
p[pos] ^= (x >> (key & 7)); |
||||||
|
key += ++key_counter; |
||||||
|
} |
||||||
|
} |
||||||
|
decode_mmb2(p); |
||||||
|
} |
||||||
|
|
||||||
|
void MapFile::decode_mmb2(BYTE *p) |
||||||
|
{ |
||||||
|
if(p[6] == 0xFF && p[7] == 0xFF) { |
||||||
|
int decode_length = (p[0] << 0) | (p[1] << 8) | (p[2] << 16); |
||||||
|
DWORD key1 = p[5] ^ 0xF0; |
||||||
|
DWORD key2 = key_table2[key1] ; |
||||||
|
int key_counter = 0; |
||||||
|
|
||||||
|
DWORD decode_count = ((decode_length - 8) & ~0xf) / 2; |
||||||
|
|
||||||
|
DWORD *data1 = (DWORD *)(p + 8 + 0); |
||||||
|
DWORD *data2 = (DWORD *)(p + 8 + decode_count); |
||||||
|
for(DWORD pos = 0; pos < decode_count; pos += 8) |
||||||
|
{ |
||||||
|
if(key2 & 1) |
||||||
|
{ |
||||||
|
DWORD tmp; |
||||||
|
|
||||||
|
tmp = data1[0]; |
||||||
|
data1[0] = data2[0]; |
||||||
|
data2[0] = tmp; |
||||||
|
|
||||||
|
tmp = data1[1]; |
||||||
|
data1[1] = data2[1]; |
||||||
|
data2[1] = tmp; |
||||||
|
} |
||||||
|
key1 += 9; |
||||||
|
key2 += key1; |
||||||
|
data1 += 2; |
||||||
|
data2 += 2; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
LPSTR MapFile::FistData(DATHEAD *phd) |
||||||
|
{ |
||||||
|
if( !pdat ) return NULL; |
||||||
|
*phd = *(DATHEAD *)pdat; |
||||||
|
pData = pdat; |
||||||
|
return pData; |
||||||
|
} |
||||||
|
|
||||||
|
LPSTR MapFile::NextData(DATHEAD *phd) |
||||||
|
{ |
||||||
|
if(!pData) return NULL; |
||||||
|
*phd = *(DATHEAD *)pData; |
||||||
|
int next = phd->next; |
||||||
|
if( next<=0 ) return NULL; |
||||||
|
if( pdat+dwSize<=pData+next*16 ) return NULL; |
||||||
|
pData += next*16; |
||||||
|
*phd = *(DATHEAD *)pData; |
||||||
|
return pData; |
||||||
|
} |
||||||
|
|
||||||
|
BOOL MapFile::ParseFile() |
||||||
|
{ |
||||||
|
char *p; |
||||||
|
DATHEAD hd; |
||||||
|
for( p=FistData(&hd); p; p=NextData(&hd) ) |
||||||
|
{ |
||||||
|
int type = (int)hd.type; |
||||||
|
|
||||||
|
switch (type) |
||||||
|
{ |
||||||
|
case 0x1c: //MZB
|
||||||
|
{ |
||||||
|
decode_ObjectMap((BYTE*)(p+16)); |
||||||
|
obj = (OBJINFO *)(p+16+32); |
||||||
|
nobj = (*(int*)(p+16+4) )&0xffffff; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 0x2e: //MMB
|
||||||
|
{ |
||||||
|
decode_mmb((BYTE*)(p+16)); |
||||||
|
MMBlist[NumMMB++] = p+16; |
||||||
|
if( NumMMB >= sizeof(MMBlist)/sizeof(MMBlist[0]) ) |
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
case 0x20: //IMG
|
||||||
|
{ |
||||||
|
/*if( IsImg(p+16) )
|
||||||
|
{ |
||||||
|
AddList(p+16); |
||||||
|
}*/ |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
RenderReady = true; |
||||||
|
return TRUE; |
||||||
|
} |
||||||
|
|
||||||
|
/*File functions*/ |
||||||
|
void MapFile::GetRegistryKey() |
||||||
|
{ |
||||||
|
HKEY hKey = NULL; |
||||||
|
DWORD dType; |
||||||
|
DWORD dSize = 1024; |
||||||
|
char *includes[] = REGISTRY_KEYS; |
||||||
|
for (int i=0;i<sizeof(includes)/sizeof(*includes);i++) |
||||||
|
{ |
||||||
|
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE,includes[i], 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS) |
||||||
|
{ |
||||||
|
if( RegQueryValueExA(hKey, "0001", NULL, &dType, (LPBYTE)ffxidir, &dSize) != ERROR_SUCCESS ) |
||||||
|
{ |
||||||
|
ffxidir[0] = '\0'; |
||||||
|
RegCloseKey(hKey); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
RegCloseKey(hKey); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (lstrlenA(ffxidir) > 0) |
||||||
|
{ |
||||||
|
if (ffxidir[lstrlenA(ffxidir)-1] != '\\') |
||||||
|
{ |
||||||
|
lstrcatA(ffxidir,"\\"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
DWORD MapFile::GetFileIDFromIDsub(DWORD dwV,DWORD dwID) |
||||||
|
{ |
||||||
|
HANDLE hFile; |
||||||
|
char fname[512]; |
||||||
|
DWORD dwRead; |
||||||
|
BYTE v; |
||||||
|
WORD f; |
||||||
|
|
||||||
|
if( dwID >= 51439 ) return 0; |
||||||
|
|
||||||
|
lstrcpyA(fname,ffxidir); // ROM2‚𒲂ׂé
|
||||||
|
|
||||||
|
switch (dwV) |
||||||
|
{ |
||||||
|
case 1: lstrcatA(fname,"VTABLE.DAT"); break; |
||||||
|
case 2: lstrcatA(fname,"ROM2\\VTABLE2.DAT"); break; |
||||||
|
case 3: lstrcatA(fname,"ROM3\\VTABLE3.DAT"); break; |
||||||
|
default: return 0; |
||||||
|
} |
||||||
|
|
||||||
|
hFile = CreateFileA(fname,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL); |
||||||
|
if (hFile == INVALID_HANDLE_VALUE) return 0; |
||||||
|
|
||||||
|
SetFilePointer(hFile,dwID,NULL,FILE_BEGIN); |
||||||
|
ReadFile(hFile,&v,1,&dwRead,NULL); |
||||||
|
CloseHandle(hFile); |
||||||
|
|
||||||
|
if (dwRead != 1 || v == 0) return 0; |
||||||
|
|
||||||
|
lstrcpyA(fname,ffxidir); |
||||||
|
|
||||||
|
switch (dwV) |
||||||
|
{ |
||||||
|
case 1: lstrcatA(fname,"FTABLE.DAT"); break; |
||||||
|
case 2: lstrcatA(fname,"ROM2\\FTABLE2.DAT"); break; |
||||||
|
case 3: lstrcatA(fname,"ROM3\\FTABLE3.DAT"); break; |
||||||
|
default: return 0; |
||||||
|
} |
||||||
|
|
||||||
|
hFile = CreateFileA(fname,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL); |
||||||
|
if (hFile == INVALID_HANDLE_VALUE) return 0; |
||||||
|
|
||||||
|
SetFilePointer(hFile,dwID*2,NULL,FILE_BEGIN); |
||||||
|
ReadFile(hFile,&f,2,&dwRead,NULL); |
||||||
|
CloseHandle(hFile); |
||||||
|
|
||||||
|
if(dwRead != 2) return 0; |
||||||
|
|
||||||
|
return (DWORD)MAKELONG(f,v); |
||||||
|
} |
||||||
|
|
||||||
|
BOOL MapFile::GetFileNameFromFileID(LPSTR filename,DWORD dwID) |
||||||
|
{ |
||||||
|
DWORD id; |
||||||
|
DWORD no; |
||||||
|
|
||||||
|
id = GetFileIDFromIDsub(3,dwID); |
||||||
|
if (id == 0) id = GetFileIDFromIDsub(2,dwID); |
||||||
|
if (id == 0) id = GetFileIDFromIDsub(1,dwID); |
||||||
|
if (id == 0) return FALSE; |
||||||
|
|
||||||
|
no = id & 0xffff; |
||||||
|
|
||||||
|
switch (HIWORD(id)) |
||||||
|
{ |
||||||
|
case 1: wsprintfA(filename,"%sROM\\%d\\%d.dat",ffxidir,no/0x80,no%0x80); break; |
||||||
|
case 2: wsprintfA(filename,"%sROM2\\%d\\%d.dat",ffxidir,no/0x80,no%0x80); break; |
||||||
|
case 3: wsprintfA(filename,"%sROM3\\%d\\%d.dat",ffxidir,no/0x80,no%0x80); break; |
||||||
|
default: return FALSE; |
||||||
|
} |
||||||
|
return TRUE; |
||||||
|
} |
||||||
|
|
||||||
|
bool MapFile::LoadMap(int ZoneID) |
||||||
|
{ |
||||||
|
Free(); |
||||||
|
|
||||||
|
if (!GetFileNameFromFileID(filename,ZoneID)) |
||||||
|
{ |
||||||
|
return FALSE; |
||||||
|
} |
||||||
|
|
||||||
|
HANDLE hFile = CreateFileA(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL); |
||||||
|
|
||||||
|
if( hFile!=INVALID_HANDLE_VALUE ) |
||||||
|
{ |
||||||
|
DWORD dmy; |
||||||
|
dwSize = GetFileSize(hFile,NULL); |
||||||
|
pdat = new char[dwSize]; |
||||||
|
ReadFile(hFile,pdat,dwSize,&dmy,NULL); |
||||||
|
CloseHandle(hFile); |
||||||
|
return ParseFile(); |
||||||
|
} |
||||||
|
return FALSE; |
||||||
|
} |
||||||
|
/*File functions*/ |
@ -0,0 +1,77 @@ |
|||||||
|
#pragma once |
||||||
|
#include "stdafx.h" |
||||||
|
|
||||||
|
#pragma pack(push,1) |
||||||
|
typedef struct |
||||||
|
{ |
||||||
|
char id[16]; |
||||||
|
float fTransX,fTransY,fTransZ; |
||||||
|
float fRotX,fRotY,fRotZ; |
||||||
|
float fScaleX,fScaleY,fScaleZ; |
||||||
|
float fa,fb,fc,fd; |
||||||
|
long fe,ff,fg,fh,fi,fj,fk,fl; |
||||||
|
} OBJINFO; |
||||||
|
|
||||||
|
typedef struct |
||||||
|
{ |
||||||
|
float x1,x2,y1,y2,z1,z2; |
||||||
|
} OOO; |
||||||
|
|
||||||
|
typedef struct |
||||||
|
{ |
||||||
|
DWORD id; |
||||||
|
long type:7; |
||||||
|
long next:19; |
||||||
|
long is_shadow:1; |
||||||
|
long is_extracted:1; |
||||||
|
long ver_num:3; |
||||||
|
long is_virtual:1; |
||||||
|
} DATHEAD; |
||||||
|
#pragma pack(pop) |
||||||
|
|
||||||
|
typedef struct |
||||||
|
{ |
||||||
|
char ID[17]; |
||||||
|
LPDIRECT3DTEXTURE9 pTex; |
||||||
|
} TEXTEX; |
||||||
|
|
||||||
|
|
||||||
|
class MapFile |
||||||
|
{ |
||||||
|
private: |
||||||
|
bool RenderReady; |
||||||
|
|
||||||
|
|
||||||
|
char ffxidir[1024]; |
||||||
|
char filename[1024]; |
||||||
|
char *pdat; |
||||||
|
DWORD dwSize; |
||||||
|
LPSTR pData; |
||||||
|
|
||||||
|
void decode_ObjectMap(BYTE* p); |
||||||
|
void decode_mmb(BYTE*p); |
||||||
|
void decode_mmb2(BYTE *p); |
||||||
|
|
||||||
|
void GetRegistryKey(); |
||||||
|
DWORD GetFileIDFromIDsub(DWORD dwV,DWORD dwID); |
||||||
|
BOOL GetFileNameFromFileID(LPSTR filename,DWORD dwID); |
||||||
|
BOOL ParseFile(); |
||||||
|
LPSTR FistData(DATHEAD *phd); |
||||||
|
LPSTR NextData(DATHEAD *phd); |
||||||
|
public: |
||||||
|
OBJINFO* obj; |
||||||
|
int nobj; |
||||||
|
|
||||||
|
int TexListCount; |
||||||
|
TEXTEX TexList[4096]; |
||||||
|
LPSTR MMBlist[4096]; |
||||||
|
int NumMMB; |
||||||
|
|
||||||
|
bool Ready() { return RenderReady; } |
||||||
|
MapFile(); |
||||||
|
~MapFile(); |
||||||
|
bool LoadMap(int ZoneID); |
||||||
|
|
||||||
|
BOOL Free(void); |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,366 @@ |
|||||||
|
#include "MapManager.h" |
||||||
|
|
||||||
|
MapManager::MapManager() |
||||||
|
{ |
||||||
|
g_pD3DDevice = NULL; |
||||||
|
m_MapFile = NULL; |
||||||
|
m_Zone = 0; |
||||||
|
pos = D3DXVECTOR3(0.0f, 0.0f, 0.0f); |
||||||
|
#ifdef USE_FFACE |
||||||
|
Instance = NULL; |
||||||
|
Instance = CreateInstance(POL_PID); |
||||||
|
if(Instance) |
||||||
|
{ |
||||||
|
ptm = new PARTYMEMBER(); |
||||||
|
GetPartyMember(Instance, 0, ptm); |
||||||
|
} |
||||||
|
#endif |
||||||
|
} |
||||||
|
MapManager::~MapManager() |
||||||
|
{ |
||||||
|
#ifdef USE_FFACE |
||||||
|
/*if(Instance)
|
||||||
|
DeleteInstance(Instance);*/ |
||||||
|
delete ptm; |
||||||
|
#endif |
||||||
|
if(m_MapFile) |
||||||
|
{ |
||||||
|
delete m_MapFile; |
||||||
|
m_MapFile = NULL; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool MapManager::LoadMap(int ZoneID) |
||||||
|
{ |
||||||
|
m_Zone = ZoneID; |
||||||
|
if(m_MapFile) |
||||||
|
return m_MapFile->LoadMap(ZoneID); |
||||||
|
else |
||||||
|
{ |
||||||
|
m_MapFile = new MapFile(); |
||||||
|
return m_MapFile->LoadMap(ZoneID); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void MapManager::Render() |
||||||
|
{ |
||||||
|
#ifdef USE_FFACE |
||||||
|
GetPartyMember(Instance, 0, ptm); |
||||||
|
if((ptm->Zone + 100) != m_Zone) |
||||||
|
LoadMap(ptm->Zone + 100); |
||||||
|
#endif |
||||||
|
|
||||||
|
if(!m_MapFile) |
||||||
|
return; |
||||||
|
if(!m_MapFile->Ready()) |
||||||
|
return; |
||||||
|
if(!g_pD3DDevice) |
||||||
|
return; |
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
//Begin Input Ctrl & View Matrix Setup
|
||||||
|
------------------------------------------------------------------------------*/ |
||||||
|
static float angle = 0.0f; |
||||||
|
static float view = -240.0f; |
||||||
|
D3DXMATRIX matView; |
||||||
|
static float mawari = 0.0f; |
||||||
|
|
||||||
|
#ifdef USE_FFACE |
||||||
|
if(ptm->ID) |
||||||
|
{ |
||||||
|
pos.x = GetNPCPosX(Instance, ptm->ID); |
||||||
|
pos.y = GetNPCPosY(Instance, ptm->ID) - 1; |
||||||
|
pos.z = GetNPCPosZ(Instance, ptm->ID); |
||||||
|
mawari = GetNPCPosH(Instance, ptm->ID); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
//view = -view;
|
||||||
|
D3DXMATRIX matWorld; |
||||||
|
D3DXMATRIX matWorld2; |
||||||
|
D3DXMatrixTranslation(&matWorld2,0.0f,0.0f,angle/1500.0f); |
||||||
|
//D3DXMatrixRotationX(&matWorld, DEGtoRAD(angle/1.0069));
|
||||||
|
//DXMatrixRotationY(&matWorld, DEGtoRAD(angle));
|
||||||
|
D3DXMatrixRotationYawPitchRoll(&matWorld,DEGtoRAD(angle/20.0f),DEGtoRAD(angle/15.0f),DEGtoRAD(angle/10.0f)); |
||||||
|
matWorld*=matWorld2; |
||||||
|
angle += 1.0f; |
||||||
|
//g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
|
||||||
|
|
||||||
|
|
||||||
|
float delta; |
||||||
|
delta = 0.02f; |
||||||
|
if( GetKeyState(VK_CONTROL)&0x8000 ){ delta = 0.1f; }; |
||||||
|
if( GetKeyState(VK_RIGHT) & 0x8000 ) mawari-=delta; |
||||||
|
if( GetKeyState(VK_LEFT) & 0x8000 ) mawari+=delta; |
||||||
|
|
||||||
|
delta = 2.0f; |
||||||
|
if( GetKeyState(VK_CONTROL)&0x8000 ){ delta = 5.0f; }; |
||||||
|
if( GetKeyState(VK_UP) & 0x8000 ){ pos.x+=cos(mawari)*delta; pos.z+=sin(mawari)*delta; } |
||||||
|
if( GetKeyState(VK_DOWN) & 0x8000 ){ pos.x+=cos(mawari+3.1415926f)*delta; pos.z+=sin(mawari+3.1415926f)*delta; } |
||||||
|
if( GetKeyState(VK_PRIOR) & 0x8000 ){ pos.y+=delta; } |
||||||
|
if( GetKeyState(VK_NEXT) & 0x8000 ){ pos.y-=delta; } |
||||||
|
if( GetKeyState(VK_HOME) & 0x8000 ){ mawari=pos.x=pos.y=pos.z=0.0f; } |
||||||
|
D3DXVECTOR3 pnt(pos.x+cos(mawari), pos.y+0.0f, pos.z+sin(mawari)); |
||||||
|
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); |
||||||
|
D3DXMatrixLookAtRH(&matView, &pos, &pnt, &up); |
||||||
|
g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView); |
||||||
|
|
||||||
|
D3DXMATRIX matProj; |
||||||
|
D3DXMatrixPerspectiveFovRH(&matProj, DEGtoRAD(45.0f), 4.0f / 3.0f, 1.0f, 500.0f); |
||||||
|
g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj); |
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
//End Input Ctrl & View Matrix Setup
|
||||||
|
------------------------------------------------------------------------------*/ |
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
//Begin RenderState
|
||||||
|
------------------------------------------------------------------------------*/ |
||||||
|
//g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW/*/D3DCULL_NONE*/ );
|
||||||
|
g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW/*/D3DCULL_NONE*/ ); |
||||||
|
g_pD3DDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); |
||||||
|
//g_pD3DDevice->SetLight(0,&light);
|
||||||
|
//g_pD3DDevice->LightEnable(0,TRUE);
|
||||||
|
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING,FALSE); |
||||||
|
//g_pD3DDevice->SetRenderState(D3DRS_AMBIENT, 0xF0F0F0F0);
|
||||||
|
g_pD3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD ); |
||||||
|
|
||||||
|
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); |
||||||
|
g_pD3DDevice->SetRenderState( D3DRS_STENCILENABLE, TRUE ); |
||||||
|
g_pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE , TRUE ); |
||||||
|
g_pD3DDevice->SetRenderState( D3DRS_ALPHAREF , 0x80 ); |
||||||
|
g_pD3DDevice->SetRenderState( D3DRS_ALPHAFUNC , D3DCMP_GREATER ); |
||||||
|
//g_pD3DDevice->SetRenderState(D3DRS_EDGEANTIALIAS,TRUE);
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
//End RenderState
|
||||||
|
------------------------------------------------------------------------------*/ |
||||||
|
|
||||||
|
for( int i=0; i< m_MapFile->nobj; i++ ) |
||||||
|
{ |
||||||
|
D3DXMATRIX matWorld; |
||||||
|
D3DXMATRIX matWorld2; |
||||||
|
D3DXMATRIX matWorld3; |
||||||
|
D3DXMATRIX matWorld4; |
||||||
|
D3DXMATRIX matWorldR4; |
||||||
|
D3DXMATRIX matWorldR5; |
||||||
|
D3DXMATRIX matWorldR6; |
||||||
|
ZeroMemory(&matWorld,sizeof(D3DXMATRIX)); |
||||||
|
D3DXMatrixScaling(&matWorld3,m_MapFile->obj[i].fScaleX,m_MapFile->obj[i].fScaleY,m_MapFile->obj[i].fScaleZ); |
||||||
|
D3DXMatrixTranslation(&matWorld,m_MapFile->obj[i].fTransX,m_MapFile->obj[i].fTransY,m_MapFile->obj[i].fTransZ); |
||||||
|
D3DXMatrixRotationX(&matWorldR4,m_MapFile->obj[i].fRotX); |
||||||
|
D3DXMatrixRotationY(&matWorldR5,m_MapFile->obj[i].fRotY); |
||||||
|
D3DXMatrixRotationZ(&matWorldR6,m_MapFile->obj[i].fRotZ); |
||||||
|
matWorld2 = matWorldR4 * matWorldR5 * matWorldR6; |
||||||
|
matWorld=((matWorld3*matWorld2)/**matWorld4*/)*matWorld; |
||||||
|
g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld); |
||||||
|
if( m_MapFile->obj[i].fScaleX*m_MapFile->obj[i].fScaleY*m_MapFile->obj[i].fScaleZ < 0.0f ) |
||||||
|
{ |
||||||
|
g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); |
||||||
|
} |
||||||
|
if(0) |
||||||
|
{ |
||||||
|
float pp[]={-20,0,0,20,0,0, 0,-20,0,0,20,0, 0,0,-20,0,0,20}; |
||||||
|
//float pp[]={-10,0,0,10,0,0, 0,-10,0,0,10,0, 0,0,-10,0,0,10};
|
||||||
|
g_pD3DDevice->SetFVF(D3DFVF_XYZ); |
||||||
|
g_pD3DDevice->DrawPrimitiveUP(D3DPT_LINELIST,3,pp,12); |
||||||
|
} |
||||||
|
|
||||||
|
for( int j=0; j< m_MapFile->NumMMB; j++ ) |
||||||
|
{ |
||||||
|
if( memcmp(m_MapFile->MMBlist[j]+16, m_MapFile->obj[i].id, 16) ) |
||||||
|
continue; |
||||||
|
DrawMMB(m_MapFile->MMBlist[j]); |
||||||
|
}//End For MumMMB
|
||||||
|
}//End For Noj
|
||||||
|
} |
||||||
|
|
||||||
|
void MapManager::DrawMMB(char *pp) |
||||||
|
{ |
||||||
|
float *ff = (float*)pp; |
||||||
|
|
||||||
|
char *p = pp; |
||||||
|
p+=0x020; |
||||||
|
for(;;) |
||||||
|
{ |
||||||
|
OOO * oo = (OOO*)(p+4); |
||||||
|
|
||||||
|
D3DXMATRIX mat; |
||||||
|
D3DXMATRIX mat1; |
||||||
|
g_pD3DDevice->GetTransform(D3DTS_WORLD, &mat1); mat = mat1; |
||||||
|
g_pD3DDevice->GetTransform(D3DTS_VIEW, &mat1); mat *= mat1; |
||||||
|
g_pD3DDevice->GetTransform(D3DTS_PROJECTION, &mat1); mat *= mat1; |
||||||
|
D3DXVECTOR3 Vec; |
||||||
|
D3DXVECTOR4 v; |
||||||
|
|
||||||
|
Vec.x=oo->x1; |
||||||
|
Vec.y=oo->y1; |
||||||
|
Vec.z=oo->z1; |
||||||
|
D3DXVec3Transform(&v,&Vec,&mat); |
||||||
|
v.x/=v.w; |
||||||
|
v.y/=v.w; |
||||||
|
v.z/=v.w; |
||||||
|
if( v.x<=2.2 && v.x>=-2.2 && v.y<=2.2 && v.y>=-2.2 && v.z<=2.2 && v.z>=-1.2 ) |
||||||
|
break; |
||||||
|
Vec.x=oo->x1;Vec.y=oo->y1; |
||||||
|
Vec.z=oo->z2; |
||||||
|
D3DXVec3Transform(&v,&Vec,&mat); |
||||||
|
v.x/=v.w; v.y/=v.w; v.z/=v.w; |
||||||
|
if( v.x<=2.2 && v.x>=-2.2 && v.y<=2.2 && v.y>=-2.2 && v.z<=2.2 && v.z>=-1.2 ) |
||||||
|
break; |
||||||
|
Vec.x=oo->x1; |
||||||
|
Vec.y=oo->y2; |
||||||
|
Vec.z=oo->z1; |
||||||
|
D3DXVec3Transform(&v,&Vec,&mat); |
||||||
|
v.x/=v.w; v.y/=v.w; v.z/=v.w; |
||||||
|
if( v.x<=2.2 && v.x>=-2.2 && v.y<=2.2 && v.y>=-2.2 && v.z<=2.2 && v.z>=-1.2 ) |
||||||
|
break; |
||||||
|
Vec.x=oo->x1; |
||||||
|
Vec.y=oo->y2; |
||||||
|
Vec.z=oo->z2; |
||||||
|
D3DXVec3Transform(&v,&Vec,&mat); |
||||||
|
v.x/=v.w; |
||||||
|
v.y/=v.w; |
||||||
|
v.z/=v.w; |
||||||
|
if( v.x<=2.2 && v.x>=-2.2 && v.y<=2.2 && v.y>=-2.2 && v.z<=2.2 && v.z>=-1.2 ) |
||||||
|
break; |
||||||
|
Vec.x=oo->x2;Vec.y=oo->y1;Vec.z=oo->z1; D3DXVec3Transform(&v,&Vec,&mat); v.x/=v.w; v.y/=v.w; v.z/=v.w; |
||||||
|
if( v.x<=2.2 && v.x>=-2.2 && v.y<=2.2 && v.y>=-2.2 && v.z<=2.2 && v.z>=-1.2 ) break; |
||||||
|
Vec.x=oo->x2;Vec.y=oo->y1;Vec.z=oo->z2; D3DXVec3Transform(&v,&Vec,&mat); v.x/=v.w; v.y/=v.w; v.z/=v.w; |
||||||
|
if( v.x<=2.2 && v.x>=-2.2 && v.y<=2.2 && v.y>=-2.2 && v.z<=2.2 && v.z>=-1.2 ) break; |
||||||
|
Vec.x=oo->x2;Vec.y=oo->y2;Vec.z=oo->z1; D3DXVec3Transform(&v,&Vec,&mat); v.x/=v.w; v.y/=v.w; v.z/=v.w; |
||||||
|
if( v.x<=2.2 && v.x>=-2.2 && v.y<=2.2 && v.y>=-2.2 && v.z<=2.2 && v.z>=-1.2 ) break; |
||||||
|
Vec.x=oo->x2;Vec.y=oo->y2;Vec.z=oo->z2; D3DXVec3Transform(&v,&Vec,&mat); v.x/=v.w; v.y/=v.w; v.z/=v.w; |
||||||
|
if( v.x<=2.2 && v.x>=-2.2 && v.y<=2.2 && v.y>=-2.2 && v.z<=2.2 && v.z>=-1.2 ) break; |
||||||
|
return; |
||||||
|
|
||||||
|
if(1) |
||||||
|
{ |
||||||
|
//float pp[]={-20,0,0,20,0,0, 0,-20,0,0,20,0, 0,0,-20,0,0,20};
|
||||||
|
float pp[]={ |
||||||
|
oo->x1,oo->y1,oo->z1, oo->x2,oo->y1,oo->z1, |
||||||
|
oo->x1,oo->y2,oo->z1, oo->x2,oo->y2,oo->z1, |
||||||
|
oo->x1,oo->y1,oo->z2, oo->x2,oo->y1,oo->z2, |
||||||
|
oo->x1,oo->y2,oo->z2, oo->x2,oo->y2,oo->z2, |
||||||
|
|
||||||
|
oo->x1,oo->y1,oo->z1, oo->x1,oo->y2,oo->z1, |
||||||
|
oo->x2,oo->y1,oo->z1, oo->x2,oo->y2,oo->z1, |
||||||
|
oo->x1,oo->y1,oo->z2, oo->x1,oo->y2,oo->z2, |
||||||
|
oo->x2,oo->y1,oo->z2, oo->x2,oo->y2,oo->z2, |
||||||
|
|
||||||
|
oo->x1,oo->y1,oo->z1, oo->x1,oo->y1,oo->z2, |
||||||
|
oo->x1,oo->y2,oo->z1, oo->x1,oo->y2,oo->z2, |
||||||
|
oo->x2,oo->y1,oo->z1, oo->x2,oo->y1,oo->z2, |
||||||
|
oo->x2,oo->y2,oo->z1, oo->x2,oo->y2,oo->z2, |
||||||
|
}; |
||||||
|
g_pD3DDevice->SetFVF(D3DFVF_XYZ); |
||||||
|
g_pD3DDevice->DrawPrimitiveUP(D3DPT_LINELIST,12,pp,12); |
||||||
|
} |
||||||
|
} |
||||||
|
g_pD3DDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_NORMAL|D3DFVF_TEX1); |
||||||
|
int kai = *(int*)p; |
||||||
|
if( kai<=0 ) |
||||||
|
return; |
||||||
|
if( kai==1 ) |
||||||
|
p+=32; |
||||||
|
if( kai>=2 && kai<=16 ) |
||||||
|
{ |
||||||
|
p+=16*4; |
||||||
|
} |
||||||
|
if( kai>16 ) |
||||||
|
p+=kai*4; |
||||||
|
|
||||||
|
if( kai>0xff ) |
||||||
|
return; |
||||||
|
int i,j; |
||||||
|
while(kai) |
||||||
|
{ |
||||||
|
j = *(int*)p; |
||||||
|
if( j > 0xffff || j<0 ) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
p += 32; |
||||||
|
for( i=0; i<j; i++ ) |
||||||
|
{ |
||||||
|
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); |
||||||
|
g_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); |
||||||
|
|
||||||
|
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); |
||||||
|
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); |
||||||
|
g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); |
||||||
|
g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); |
||||||
|
|
||||||
|
//g_pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
||||||
|
//g_pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||||
|
//g_pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||||
|
int k; |
||||||
|
/*for( k=0; k<NumTexList; k++ )
|
||||||
|
{ |
||||||
|
if( !memcmp(p,TexList[k].ID,16) ) |
||||||
|
{ |
||||||
|
|
||||||
|
if( flgFirst ) |
||||||
|
logprintf("Finded Textur: %s",sstr(TexList[k].ID,16)); |
||||||
|
|
||||||
|
g_pD3DDevice->SetTexture(0, TexList[k].pTex); |
||||||
|
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE2X); |
||||||
|
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); |
||||||
|
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); |
||||||
|
D3DSURFACE_DESC Desc; |
||||||
|
|
||||||
|
TexList[k].pTex->GetLevelDesc( 0, &Desc ); |
||||||
|
if( Desc.Format == D3DFMT_DXT1 ) |
||||||
|
{ |
||||||
|
//g_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
|
||||||
|
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); |
||||||
|
//typedef enum _D3DTEXTUREOP
|
||||||
|
//g_pD3DDevice->SetRenderState( D3DRS_ALPHAREF,0x7f) ;
|
||||||
|
//g_pD3DDevice->SetRenderState( D3DRS_ALPHAFUNC,D3DCMP_NOTEQUAL) ;
|
||||||
|
g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE4X ); |
||||||
|
g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); |
||||||
|
g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); |
||||||
|
|
||||||
|
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); |
||||||
|
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); |
||||||
|
g_pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE ); |
||||||
|
} |
||||||
|
|
||||||
|
break; |
||||||
|
} |
||||||
|
}*/ |
||||||
|
int nVer = (int)*(short*)(p+16); |
||||||
|
int nVerReal = (int)*(int*)(p+16); |
||||||
|
if( nVer > 0xffff || nVer<0 ) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
int nIdx = (*(int*)(p+16+4+nVer*36)); |
||||||
|
if( nIdx > 0xffff || nIdx < 0 ) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
k = 16 + 4+ nVer*36+ 4+ nIdx*2; |
||||||
|
k = 4*((k+3)/4); |
||||||
|
for( int ii=0; ii<nIdx; ii++ ) |
||||||
|
{ |
||||||
|
WORD *pidx = (WORD*)(p+16+4+nVer*36+4); |
||||||
|
if( (int)(UINT)pidx[ii]>=nVer ) |
||||||
|
{ |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
g_pD3DDevice->BeginScene(); |
||||||
|
g_pD3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP,0,nIdx,nIdx-2,p+16+4+nVer*36+4,D3DFMT_INDEX16, (p+16+4) ,36 ); |
||||||
|
g_pD3DDevice->EndScene(); |
||||||
|
|
||||||
|
g_pD3DDevice->SetTexture(0,NULL); |
||||||
|
p += k; |
||||||
|
} |
||||||
|
kai--; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
#pragma once |
||||||
|
#include "stdafx.h" |
||||||
|
#include <d3d9.h> |
||||||
|
#include <d3dx9math.h> |
||||||
|
#include "MapFile.h" |
||||||
|
|
||||||
|
#ifdef USE_FFACE |
||||||
|
#include "FFACE4.h" |
||||||
|
#pragma comment(lib, "FFACE.lib") |
||||||
|
#define POL_PID 12668 |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MapManager |
||||||
|
{ |
||||||
|
private: |
||||||
|
#ifdef USE_FFACE |
||||||
|
PARTYMEMBER* ptm; |
||||||
|
int PlayerID; |
||||||
|
void* Instance; |
||||||
|
#endif |
||||||
|
|
||||||
|
LPDIRECT3DDEVICE9 g_pD3DDevice; |
||||||
|
MapFile* m_MapFile; |
||||||
|
int m_Zone; |
||||||
|
D3DXVECTOR3 pos; |
||||||
|
inline FLOAT DEGtoRAD(float angle) |
||||||
|
{ |
||||||
|
return (angle-90.0f)*3.1415926f/180.0f; |
||||||
|
} |
||||||
|
|
||||||
|
void DrawMMB(char *pp); |
||||||
|
public: |
||||||
|
MapManager(); |
||||||
|
~MapManager(); |
||||||
|
void SetDevice(LPDIRECT3DDEVICE9 pD3DDevice){ g_pD3DDevice = pD3DDevice; } |
||||||
|
bool LoadMap(int ZoneID); |
||||||
|
void Render(); |
||||||
|
}; |
@ -0,0 +1,62 @@ |
|||||||
|
======================================================================== |
||||||
|
WIN32 APPLICATION : FFXIMapViewer Project Overview |
||||||
|
======================================================================== |
||||||
|
|
||||||
|
AppWizard has created this FFXIMapViewer application for you. |
||||||
|
|
||||||
|
This file contains a summary of what you will find in each of the files that |
||||||
|
make up your FFXIMapViewer application. |
||||||
|
|
||||||
|
|
||||||
|
FFXIMapViewer.vcxproj |
||||||
|
This is the main project file for VC++ projects generated using an Application Wizard. |
||||||
|
It contains information about the version of Visual C++ that generated the file, and |
||||||
|
information about the platforms, configurations, and project features selected with the |
||||||
|
Application Wizard. |
||||||
|
|
||||||
|
FFXIMapViewer.vcxproj.filters |
||||||
|
This is the filters file for VC++ projects generated using an Application Wizard. |
||||||
|
It contains information about the association between the files in your project |
||||||
|
and the filters. This association is used in the IDE to show grouping of files with |
||||||
|
similar extensions under a specific node (for e.g. ".cpp" files are associated with the |
||||||
|
"Source Files" filter). |
||||||
|
|
||||||
|
FFXIMapViewer.cpp |
||||||
|
This is the main application source file. |
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////// |
||||||
|
AppWizard has created the following resources: |
||||||
|
|
||||||
|
FFXIMapViewer.rc |
||||||
|
This is a listing of all of the Microsoft Windows resources that the |
||||||
|
program uses. It includes the icons, bitmaps, and cursors that are stored |
||||||
|
in the RES subdirectory. This file can be directly edited in Microsoft |
||||||
|
Visual C++. |
||||||
|
|
||||||
|
Resource.h |
||||||
|
This is the standard header file, which defines new resource IDs. |
||||||
|
Microsoft Visual C++ reads and updates this file. |
||||||
|
|
||||||
|
FFXIMapViewer.ico |
||||||
|
This is an icon file, which is used as the application's icon (32x32). |
||||||
|
This icon is included by the main resource file FFXIMapViewer.rc. |
||||||
|
|
||||||
|
small.ico |
||||||
|
This is an icon file, which contains a smaller version (16x16) |
||||||
|
of the application's icon. This icon is included by the main resource |
||||||
|
file FFXIMapViewer.rc. |
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////// |
||||||
|
Other standard files: |
||||||
|
|
||||||
|
StdAfx.h, StdAfx.cpp |
||||||
|
These files are used to build a precompiled header (PCH) file |
||||||
|
named FFXIMapViewer.pch and a precompiled types file named StdAfx.obj. |
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////// |
||||||
|
Other notes: |
||||||
|
|
||||||
|
AppWizard uses "TODO:" comments to indicate parts of the source code you |
||||||
|
should add to or customize. |
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////// |
@ -0,0 +1,31 @@ |
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by FFXIMapViewer.rc
|
||||||
|
//
|
||||||
|
|
||||||
|
#define IDS_APP_TITLE 103 |
||||||
|
|
||||||
|
#define IDR_MAINFRAME 128 |
||||||
|
#define IDD_FFXIMAPVIEWER_DIALOG 102 |
||||||
|
#define IDD_ABOUTBOX 103 |
||||||
|
#define IDM_ABOUT 104 |
||||||
|
#define IDM_EXIT 105 |
||||||
|
#define IDI_FFXIMAPVIEWER 107 |
||||||
|
#define IDI_SMALL 108 |
||||||
|
#define IDC_FFXIMAPVIEWER 109 |
||||||
|
#define IDC_MYICON 2 |
||||||
|
#ifndef IDC_STATIC |
||||||
|
#define IDC_STATIC -1 |
||||||
|
#endif |
||||||
|
// Next default values for new objects
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED |
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS |
||||||
|
|
||||||
|
#define _APS_NO_MFC 130 |
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 129 |
||||||
|
#define _APS_NEXT_COMMAND_VALUE 32771 |
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1000 |
||||||
|
#define _APS_NEXT_SYMED_VALUE 110 |
||||||
|
#endif |
||||||
|
#endif |
After Width: | Height: | Size: 23 KiB |
@ -0,0 +1,8 @@ |
|||||||
|
// stdafx.cpp : source file that includes just the standard includes
|
||||||
|
// FFXIMapViewer.pch will be the pre-compiled header
|
||||||
|
// stdafx.obj will contain the pre-compiled type information
|
||||||
|
|
||||||
|
#include "stdafx.h" |
||||||
|
|
||||||
|
// TODO: reference any additional headers you need in STDAFX.H
|
||||||
|
// and not in this file
|
@ -0,0 +1,21 @@ |
|||||||
|
// stdafx.h : include file for standard system include files,
|
||||||
|
// or project specific include files that are used frequently, but
|
||||||
|
// are changed infrequently
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "targetver.h" |
||||||
|
|
||||||
|
#include <windows.h> |
||||||
|
#include <stdio.h> |
||||||
|
// C RunTime Header Files
|
||||||
|
#include <stdlib.h> |
||||||
|
#include <malloc.h> |
||||||
|
#include <memory.h> |
||||||
|
#include <tchar.h> |
||||||
|
|
||||||
|
#include <d3d9.h> |
||||||
|
#pragma comment(lib, "d3d9.lib") |
||||||
|
|
||||||
|
// TODO: reference additional headers your program requires here
|
@ -0,0 +1,252 @@ |
|||||||
|
/*!\file structures.h
|
||||||
|
\brief version 4 structure header. */ |
||||||
|
#pragma once |
||||||
|
#define FFACE_LOAD_OK 0xB001 |
||||||
|
#define FFACE_LOAD_FAIL 0xB002 |
||||||
|
#define FFACE_LOAD_LOCK 0xB003 |
||||||
|
#define FFACE_LOAD_INIT 0xB004 |
||||||
|
#define FFACE_LOAD_INIT_ERROR 0xB005 |
||||||
|
#define FFACE_LOAD_ACCESS 0xB006 |
||||||
|
#define WINDOWER_FILEMAP_FAIL 0xB011 |
||||||
|
#define WINDOWER_FILEVIEW_FAIL 0xB012 |
||||||
|
#define WINDOWER_NULL_HANDLE 0xB013 |
||||||
|
#define WINDOWER_QUEUE_EMPTY 0xB014 |
||||||
|
#define WINDOWER_COMMAND_TIMEOUT 0xB015 |
||||||
|
#define WINDOWER_INDEX_OUT_SCOPE 0xB016 |
||||||
|
|
||||||
|
#define FFACE_READ 0xB021 /*wparam bool success*/ |
||||||
|
#define FFACE_WRITE 0xB026 /*wparam bool success*/ |
||||||
|
|
||||||
|
struct TRADEITEM |
||||||
|
{ |
||||||
|
unsigned short ItemID; |
||||||
|
char Index; |
||||||
|
char Count; |
||||||
|
}; |
||||||
|
struct TRADEINFO |
||||||
|
{ |
||||||
|
unsigned int Gil; |
||||||
|
int TargetID; |
||||||
|
char SelectedBox; |
||||||
|
TRADEITEM Items[8]; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
struct TREASUREITEM |
||||||
|
{ |
||||||
|
char Flag; //3=no item, 2=item
|
||||||
|
short ItemID; |
||||||
|
char Count; |
||||||
|
char Status; //0=no action, 1=pass, 2=lot
|
||||||
|
short MyLot; |
||||||
|
short WinLot; |
||||||
|
int WinPlayerSrvID; |
||||||
|
int WinPLayerID; |
||||||
|
int TimeStamp; //utc timestamp
|
||||||
|
}; |
||||||
|
|
||||||
|
struct INVENTORYITEM |
||||||
|
{ |
||||||
|
unsigned short id; |
||||||
|
unsigned char index; |
||||||
|
unsigned int count; |
||||||
|
unsigned int Flag; //5=equiped 25=baraar
|
||||||
|
unsigned int Price; |
||||||
|
unsigned short extra;//ws points, charges
|
||||||
|
}; |
||||||
|
|
||||||
|
struct CHATEXTRAINFO |
||||||
|
{ |
||||||
|
short MessageType; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
struct ALLIANCEINFO |
||||||
|
{ |
||||||
|
int AllianceLeaderID; |
||||||
|
int Party0LeaderID; |
||||||
|
int Party1LeaderID; |
||||||
|
int Party2LeaderID; |
||||||
|
char Party0Visible; |
||||||
|
char Party1Visible; |
||||||
|
char Party2Visible; |
||||||
|
char Party0Count; |
||||||
|
char Party1Count; |
||||||
|
char Party2Count; |
||||||
|
char Invited; |
||||||
|
char unknown; |
||||||
|
}; |
||||||
|
|
||||||
|
struct PARTYMEMBER |
||||||
|
{ |
||||||
|
int pad0; |
||||||
|
char Index; |
||||||
|
char MemberNumber; |
||||||
|
char Name[18]; |
||||||
|
int SvrID; |
||||||
|
int ID; |
||||||
|
int unknown0; |
||||||
|
int CurrentHP; |
||||||
|
int CurrentMP; |
||||||
|
int CurrentTP; |
||||||
|
char CurrentHPP; |
||||||
|
char CurrentMPP; |
||||||
|
short Zone; |
||||||
|
int pad1; |
||||||
|
unsigned int FlagMask; |
||||||
|
char pad2[20]; |
||||||
|
int SvrIDDupe; |
||||||
|
char CurrentHPPDupe; |
||||||
|
char CurrentMPPDupe; |
||||||
|
char Active; |
||||||
|
char pad3; |
||||||
|
}; |
||||||
|
struct PARTYMEMBERS |
||||||
|
{ |
||||||
|
PARTYMEMBER Member[17]; |
||||||
|
}; |
||||||
|
|
||||||
|
struct SkillLevel |
||||||
|
{ |
||||||
|
bool capped; |
||||||
|
unsigned short level; |
||||||
|
}; |
||||||
|
struct CraftSkillLevel |
||||||
|
{ |
||||||
|
bool capped; |
||||||
|
char level; |
||||||
|
char rank; |
||||||
|
}; |
||||||
|
struct PlayerStats |
||||||
|
{ |
||||||
|
short Str; |
||||||
|
short Dex; |
||||||
|
short Vit; |
||||||
|
short Agi; |
||||||
|
short Int; |
||||||
|
short Mnd; |
||||||
|
short Chr; |
||||||
|
}; |
||||||
|
struct PlayerElements |
||||||
|
{ |
||||||
|
short Fire; |
||||||
|
short Ice; |
||||||
|
short Wind; |
||||||
|
short Earth; |
||||||
|
short Lightning; |
||||||
|
short Water; |
||||||
|
short Light; |
||||||
|
short Dark; |
||||||
|
}; |
||||||
|
struct PlayerCombatSkills |
||||||
|
{ |
||||||
|
unsigned short HandToHand; |
||||||
|
unsigned short Dagger; |
||||||
|
unsigned short Sword; |
||||||
|
unsigned short GreatSword; |
||||||
|
unsigned short Axe; |
||||||
|
unsigned short GreatAxe; |
||||||
|
unsigned short Scythe; |
||||||
|
unsigned short Polearm; |
||||||
|
unsigned short Katana; |
||||||
|
unsigned short GreatKatana; |
||||||
|
unsigned short Club; |
||||||
|
unsigned short Staff; |
||||||
|
unsigned short unkweap0; |
||||||
|
unsigned short unkweap1; |
||||||
|
unsigned short unkweap2; |
||||||
|
unsigned short unkweap3; |
||||||
|
unsigned short unkweap4; |
||||||
|
unsigned short unkweap5; |
||||||
|
unsigned short unkweap6; |
||||||
|
unsigned short unkweap7; |
||||||
|
unsigned short unkweap8; |
||||||
|
unsigned short unkweap9; |
||||||
|
unsigned short unkweap10; |
||||||
|
unsigned short unkweap11; |
||||||
|
unsigned short Archery; |
||||||
|
unsigned short Marksmanship; |
||||||
|
unsigned short Throwing; |
||||||
|
unsigned short Guarding; |
||||||
|
unsigned short Evasion; |
||||||
|
unsigned short Shield; |
||||||
|
unsigned short Parrying; |
||||||
|
}; |
||||||
|
struct PlayerMagicSkills |
||||||
|
{ |
||||||
|
unsigned short Divine; |
||||||
|
unsigned short Healing; |
||||||
|
unsigned short Enhancing; |
||||||
|
unsigned short Enfeebling; |
||||||
|
unsigned short Elemental; |
||||||
|
unsigned short Dark; |
||||||
|
unsigned short Summon; |
||||||
|
unsigned short Ninjitsu; |
||||||
|
unsigned short Singing; |
||||||
|
unsigned short String; |
||||||
|
unsigned short Wind; |
||||||
|
unsigned short BlueMagic; |
||||||
|
unsigned short unkmagic0; |
||||||
|
unsigned short unkmagic1; |
||||||
|
unsigned short unkmagic2; |
||||||
|
unsigned short unkmagic3; |
||||||
|
}; |
||||||
|
|
||||||
|
struct PlayerCraftLevels |
||||||
|
{ |
||||||
|
unsigned short Fishing; |
||||||
|
unsigned short Woodworking; |
||||||
|
unsigned short Smithing; |
||||||
|
unsigned short Goldsmithing; |
||||||
|
unsigned short Clothcraft; |
||||||
|
unsigned short Leathercraft; |
||||||
|
unsigned short Bonecraft; |
||||||
|
unsigned short Alchemy; |
||||||
|
unsigned short Cooking; |
||||||
|
}; |
||||||
|
|
||||||
|
struct PLAYERINFO |
||||||
|
{ |
||||||
|
int HPMax; |
||||||
|
int MPMax; |
||||||
|
char MainJob; |
||||||
|
char MainJobLVL; |
||||||
|
char SubJob; |
||||||
|
char SubJobLVL; |
||||||
|
unsigned short EXPIntoLVL; |
||||||
|
unsigned short EXPForLVL; |
||||||
|
PlayerStats Stats; |
||||||
|
PlayerStats StatModifiers; |
||||||
|
short Attack; |
||||||
|
short Defense; |
||||||
|
PlayerElements Elements; |
||||||
|
short Title; |
||||||
|
short Rank; |
||||||
|
short RankPts; |
||||||
|
char Nation; |
||||||
|
char Residence; |
||||||
|
int HomePoint; |
||||||
|
PlayerCombatSkills CombatSkills; |
||||||
|
PlayerMagicSkills MagicSkills; |
||||||
|
PlayerCraftLevels CraftLevels; |
||||||
|
char null0[146]; |
||||||
|
unsigned short LimitPoints; |
||||||
|
unsigned char MeritPoints; |
||||||
|
unsigned char LimitMode; |
||||||
|
char null1[78]; |
||||||
|
unsigned short Buffs[32]; |
||||||
|
}; |
||||||
|
|
||||||
|
struct TARGETINFO |
||||||
|
{ |
||||||
|
int cID; |
||||||
|
int sID; |
||||||
|
int cSvrID; |
||||||
|
int sSrvID; |
||||||
|
unsigned short cMask; |
||||||
|
unsigned short sMask; |
||||||
|
char Locked; |
||||||
|
char IsSub; |
||||||
|
char HPP; |
||||||
|
char Name[20]; |
||||||
|
}; |
@ -0,0 +1,8 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||||
|
|
||||||
|
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||||
|
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||||
|
|
||||||
|
#include <SDKDDKVer.h> |
@ -1,3 +1,5 @@ |
|||||||
# MapViewer |
# MapViewer |
||||||
|
|
||||||
Source code to the MapViewer project by RZN. |
Source code to the MapViewer project by RZN. |
||||||
|
|
||||||
|
Permission was granted by RZN to allow atom0s to share this source code on Dec. 28, 2018. The source code in this repository is (c) 2015-2018 to RZN. |
Loading…
Reference in new issue