📄 main.cpp
字号:
/********************************************************************************
Warcraft 3 Viewer - Utility to view models and textures from Warcraft 3
Copyright (C) 2002 David GRIMBICHLER (theprophet@wanadoo.Fr)
http://www.xeberon.net
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
********************************************************************************/
//#define USEGLFONT
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <stdio.h>
#include <conio.h>
#include <io.h>
#include <math.h>
#include <time.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <shellapi.h>
#include "math.h"
#include "mdx.h"
#include "blp.h"
#include "resource.h"
#include "SHLOBJ.H"
#include "SFmpq_static.h"
#include "utility.h"
#include "about.h"
#include <SHLWAPI.H>
#include <vfw.h>
char szAppName[] = "Warcraft 3 Viewer v2.2";
extern "C" DWORD IJGRead (unsigned char *buf, unsigned long buflen, long *w, long *h, long *bpp, unsigned char *destbuf);
extern "C" DWORD IJGWrite (unsigned char *buf, unsigned long buflen, unsigned char *destbuf, unsigned long destbuflen, int quality, long image_width, long image_height, long image_planes);
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "SFmpq_static.lib")
#pragma comment(lib, "MyJPEGLib.lib")
#define ISMODELT(str) ( TAG(*(DWORD*)&(str[strlen(str)-4])) == '.MDX' )
#define ISBLPT(str) ( TAG(*(DWORD*)&(str[strlen(str)-4])) == '.BLP' )
#define ISBMPT(str) ( TAG(*(DWORD*)&(str[strlen(str)-4])) == '.BMP' )
#define ISTGAT(str) ( TAG(*(DWORD*)&(str[strlen(str)-4])) == '.TGA' )
#define ISJPGT(str) ( TAG(*(DWORD*)&(str[strlen(str)-4])) == '.JPG' )
#define WAR3DATA_REGKEY "Software\\TheProphet\\MDX Viewer"
#define INSTALL_REGKEY "Software\\Blizzard Entertainment\\Warcraft III"
#define VK_ALPHA(x) (0x41 + (x-'a'))
struct BLPHeader
{
char ident[4];
unsigned long compress, nummipmaps, sizex, sizey, pictype, picsubtype;
unsigned long poffs[16], psize[16];
};
struct BLPHeader2
{
char ident[4];
unsigned long compress, nummipmaps, sizex, sizey, pictype, picsubtype;
unsigned long poffs[16], psize[16];
unsigned long JPEGHeaderSize;
};
struct RGBAPix
{
unsigned char R;
unsigned char G;
unsigned char B;
unsigned char A;
};
struct PAPix
{
unsigned char i;
unsigned char A;
};
struct PPix
{
unsigned char i;
};
struct TGAHeader
{
unsigned char imageIDLength;
unsigned char colorMapType;
unsigned char imageType;
unsigned short colorMapFirstEntryIndex;
unsigned char colorMapLength;
unsigned char colorMapEntrySize;
unsigned short xOrigin;
unsigned short yOrigin;
unsigned short width;
unsigned short height;
unsigned char bpp;
unsigned char reserved1 : 2;
unsigned char imageOrigin : 2;
unsigned char alphaChannelBits : 4;
};
#define WM_MOUSEWHEEL 0x020A
/*
GLfloat light0_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f};
GLfloat light0_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat light0_position[] = { .5f, .5f, 1.0f, 0.0f};
*/
GLfloat light0_ambient[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat light0_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat light0_position[] = { 200.0f, 200.0f, 200.0f};
GLfloat light1_ambient[] = { 0.9f, 0.9f, 0.9f, 1.0f};
GLfloat light1_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat light1_position[] = {0.0f,0.0f, 1.0f, 0.0f};
static HANDLE gHeap=NULL;
HIMAGELIST ghimg;
float bgwidth = 250.0f, bgheight = 250.0f, bgdepth = -500.0f;
BOOL lbuttondown = false;
BOOL rbuttondown = false;
BOOL mbuttondown = false;
BOOL ctrldown = false;
int bCmdProcessed = 0;
POINTS oldpoints;
HDC hdc;
HGLRC glrc;
DWORD width;
DWORD height;
HWND dlg;
HWND dlgregistre = 0, dlgtree = 0, dlgjpegqual = 0, dlgextract=0, dlgfind =0, dlgconvert = 0;
HWND dlgabout=0, dlgbatch = 0;
HWND ghtb = 0;
HIMAGELIST ghil = 0;
HMENU hmenu, hMDXPopup, hBLPPopup;
HACCEL hAccel;
GLuint gList=0;
GLuint texID = 0;
BOOL bgloaded = FALSE;
long gAnim = -1, bCam = -1;
BOOL gTextured = true, gShadows = true;
BOOL gAllGeom = false;
BOOL gRegistre = false, gTree = true, gToolBar = true;
BOOL bShowingMDX = true;
BOOL bShowCameras = TRUE, bShowAxis = TRUE;
HINSTANCE gInstance;
WarCraft_ModelX gModel;
WarCraft_BLP gTex;
long gRightClickedItem = 0, gLoadedItem = 0;
DWORD wxPos, wyPos, wWidth, wHeight, txPos, tyPos;
DWORD tinterval = 30;
PAVIFILE gaf;
COMPVARS compvars;
BITMAPINFOHEADER birgb;
AVICOMPRESSOPTIONS opts;
AVISTREAMINFO strinfo;
PAVISTREAM ps, psCompressed;
char mpqname[1024], gLoadedExternFile[1024], gLoadedExternFilePath[1024], mpqpath[1024];
char gInitialDir[1024];
char rIDTable[50][256];
char fprevtext[1024];
char *gCmdLine=NULL;
MyMPQ gmpq;
MPQHANDLE ghMPQ=NULL, ghMPQ1=NULL;
DWORD currentlanguage=0;
unsigned short currentlangid=0;
UINT_PTR gtimerid = 0;
long gzDepth = 16;
BOOL bLoadingAnim = FALSE;
Vec3 angles(90,0,0);
Vec3 shift(-0.15f,-0.46f,-0.90f);
float zoom = 6.21f; // 0.005
Vec3 BGColor(0.2f,0.2f,0.7f);
Vec3 MColor(1.0f, 0.0f, 0.0f);
BOOL bAviSaving = FALSE, bAviDone = FALSE, bSeqSaving = FALSE;
long frame_count = 0, gseqsavefmt = 0;
char gseqsavedir[1024], gseqsavename[1024];
long glastqual = 85;
BOOL bActive = TRUE;
BOOL g_showmeshes[MAX_CHUNKS];
MaChaine gLoadedTextures[128];
float myEPSILON = 0.001f;
LRESULT CALLBACK DialogProcTree(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
LRESULT CALLBACK DialogProcTextures(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
LRESULT CALLBACK DialogProcJPEGQuality(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
LRESULT CALLBACK DialogProcExtract(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
LRESULT CALLBACK DialogProcFind(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
DWORD ConvertBLP(char *srcBuf, char *destBuf, DWORD *width, DWORD *height, DWORD *type, DWORD *subtype);
void RGBA2RGB(char *bufsrc, DWORD srcsize, char *bufdest, DWORD destsize);
void *malloc_func(const size_t size);
void free_func(void* ptr);
BOOL FillMyMPQData(char *szFichier, MyMPQ *mpqstruct);
void AddTexturesToTree(HWND dlg);
void AddModelsToTree(HWND dlg);
void UpdateMeshes();
void Display( void );
DWORD FromMPQ(char*szFichier, char*& buffer);
void AddMeshesToTree(HWND dlg);
void RGBA2BGR(char *bufsrc, DWORD srcsize, char *bufdest, DWORD destsize);
void HorizFlip(char *bufsrc, long rowsize, long numlines);
BOOL ISBLP(char *s);
BOOL ISBMP(char *s);
BOOL ISJPG(char *s);
BOOL ISTGA(char *s);
BOOL ISMODEL(char *s);
DWORD GetItemPathWithoutRoot(HWND htree, HTREEITEM hit, char *buf);
void Resize(HWND wnd);
unsigned long LoadTGA(char *srcbuf, long *w, long *h, long *bp, char *destbuf, long *type);
DWORD BuildBLP(char *srcBuf, long width, long height, long bpp, char *destBuf, int quality);
DWORD LoadBMP(char *srcbuf, long *w, long *h, long *bp, char *destbuf);
void RGB2BGR(char *bufsrc, DWORD srcsize);
void RGBA2BGRA(char *bufsrc, DWORD srcsize);
DWORD MakeBMP(char* srcBuf, long width, long height, long bpp, char* destBuf);
DWORD MakeTGA(unsigned char* srcBuf, long width, long height, long bpp, unsigned char* destBuf);
DWORD ResizePicture(char* srcBuf, long width, long height, long bpp, char* destBuf, long newwidth, long newheight);
extern float Rad2Deg(float a);
GLuint fonttexture;
GLuint fontbase;
BOOL gFontLoaded = FALSE;
void LoadAnims(char *s)
{
bLoadingAnim = TRUE;
gAnim = -1;
HWND hw;
bCam = -1;
hw = GetDlgItem(dlgtree, IDC_COMBO2);
SendMessage(hw, CB_RESETCONTENT, 0, 0);
switch(currentlanguage)
{
case LANG_FRENCH:
SendMessage(hw, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"(Par d閒aut)");
break;
case LANG_ENGLISH:
SendMessage(hw, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"(Default)");
break;
case LANG_PORTUGUESE:
SendMessage(hw, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"(Padr鉶)");
break;
case LANG_GERMAN:
SendMessage(hw, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"(Default)");
break;
default:
SendMessage(hw, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"(Default)");
break;
}
long k,l = gModel.mCameras.mNumCameras;
for(k=0; k<l; ++k)
{
char *s = gModel.mCameras.mCameras[k].cName;
SendMessage(hw, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)s);
}
SendMessage(hw, CB_SETCURSEL, 0, 0);
}
VOID CALLBACK RefreshProc(HWND hwnd,
UINT uMsg,
UINT_PTR idEvent,
DWORD dwTime
)
{
if(bActive)
Display();
}
int MyDialogBoxParam(HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
{
HRSRC hr;
hr = FindResourceEx(hInstance, RT_DIALOG, lpTemplate, currentlangid);
return DialogBoxIndirectParam(hInstance, (LPCDLGTEMPLATE)LoadResource(hInstance, hr), hWndParent, lpDialogFunc, dwInitParam);
}
int MyDialogBox(HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc)
{
HRSRC hr;
hr = FindResourceEx(hInstance, RT_DIALOG, lpTemplate, currentlangid);
return DialogBoxIndirect(hInstance, (LPCDLGTEMPLATE)LoadResource(hInstance, hr), hWndParent, lpDialogFunc);
}
HWND MyCreateDialog(HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc)
{
HRSRC hr;
hr = FindResourceEx(hInstance, RT_DIALOG, lpTemplate, currentlangid);
return CreateDialogIndirect(hInstance, (LPCDLGTEMPLATE)LoadResource(hInstance, hr), hWndParent, lpDialogFunc);
}
void LoadFontTexture()
{
DWORD nn /*,r*/;
long w, h, bpp;
char *filedat, *fdata;
/*
HANDLE hFile = CreateFile("font.bmp", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
nn = GetFileSize(hFile, NULL);
filedat = (char*)malloc_func(nn);
ReadFile(hFile, filedat, nn, &r, NULL);
CloseHandle(hFile);
*/
HRSRC hr;
hr = FindResourceEx(NULL, RT_RCDATA, MAKEINTRESOURCE(IDR_DATA2), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
HGLOBAL hg = LoadResource(NULL, hr);
LockResource(hr);
nn = SizeofResource(NULL, hr);
filedat = (char*)hg;
nn = LoadBMP(filedat, &w, &h, &bpp, NULL);
fdata = (char*)malloc_func(nn);
LoadBMP(filedat, &w, &h, &bpp, fdata);
// free_func(filedat);
glGenTextures(1, &fonttexture);
glBindTexture(GL_TEXTURE_2D, fonttexture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, fdata);
}
GLvoid BuildFont(GLvoid) // Build Our Font Display List
{
float cx; // Holds Our X Character Coord
float cy; // Holds Our Y Character Coord
int loop;
fontbase=glGenLists(256); // Creating 256 Display Lists
glBindTexture(GL_TEXTURE_2D, fonttexture); // Select Our Font Texture
for (loop=0; loop<256; loop++) // Loop Through All 256 Lists
{
cx=float(loop%16)/16.0f; // X Position Of Current Character
cy=float(loop/16)/16.0f; // Y Position Of Current Character
glNewList(fontbase+loop,GL_COMPILE); // Start Building A List
glBegin(GL_QUADS); // Use A Quad For Each Character
glTexCoord2f(cx,1-cy-0.0625f); // Texture Coord (Bottom Left)
glVertex2i(0,0); // Vertex Coord (Bottom Left)
glTexCoord2f(cx+0.0625f,1-cy-0.0625f); // Texture Coord (Bottom Right)
glVertex2i(16,0); // Vertex Coord (Bottom Right)
glTexCoord2f(cx+0.0625f,1-cy); // Texture Coord (Top Right)
glVertex2i(16,16); // Vertex Coord (Top Right)
glTexCoord2f(cx,1-cy); // Texture Coord (Top Left)
glVertex2i(0,16); // Vertex Coord (Top Left)
glEnd(); // Done Building Our Quad (Character)
glTranslated(10,0,0); // Move To The Right Of The Character
glEndList(); // Done Building The Display List
} // Loop Until All 256 Are Built
}
GLvoid glPrint(GLint x, GLint y, char *string, int set) // Where The Printing Happens
{
if (set>1)
{
set=1;
}
glBindTexture(GL_TEXTURE_2D, fonttexture); // Select Our Font Texture
glDisable(GL_DEPTH_TEST); // Disables Depth Testing
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPushMatrix(); // Store The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
glOrtho(0,width,0,height,-1,1); // Set Up An Ortho Screen
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glPushMatrix(); // Store The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
glTranslated(x,y,0); // Position The Text (0,0 - Bottom Left)
glListBase(fontbase-32+(128*set)); // Choose The Font Set (0 or 1)
glCallLists(strlen(string),GL_BYTE,string); // Write The Text To The Screen
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPopMatrix(); // Restore The Old Projection Matrix
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glPopMatrix(); // Restore The Old Projection Matrix
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
}
void *malloc_func(const size_t size)
{
/*
void *ptr=VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
if (ptr==NULL)
{
MessageBox(0, "!!!!! Memory Error !!!!!", "!!!!! Memory Error (Alloc) !!!!!", MB_ICONSTOP+MB_SYSTEMMODAL);
return NULL;
}
else
return ptr;
*/
//return malloc(size);
void *ptr=HeapAlloc(gHeap, HEAP_GENERATE_EXCEPTIONS, size);
if (ptr==NULL)
{
MessageBox(0, "!!!!! Memory Error !!!!!", szAppName, MB_ICONSTOP+MB_SYSTEMMODAL);
return NULL;
}
else
return ptr;
}
void free_func(void* ptr)
{
/*
if (VirtualFree(ptr, 0, MEM_RELEASE)==FALSE)
MessageBox(0, "!!!!! Memory Error !!!!!", "!!!!! Memory Error (Free) !!!!!", MB_ICONSTOP+MB_SYSTEMMODAL);
*/
//free(ptr);
HeapFree(gHeap, 0, ptr);
return;
}
LPTSTR MyStrStrI(LPCTSTR lpFirst, LPCTSTR lpSrch)
{
char *lpf = (char*)malloc_func(lstrlen(lpFirst)+1),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -