The Quake 2 tools as originally released under the GPL license.

This commit is contained in:
Travis Bradshaw
2012-01-31 15:22:13 -06:00
commit 707e849167
132 changed files with 52073 additions and 0 deletions

38
texpaint/docs.txt Normal file
View File

@@ -0,0 +1,38 @@
Texpaint works with three data types:
Skin textures
Model frames
S/T mappings
Skin textures can be either lbm or pcx files, and they will allways be
saved out the same size as loaded in, even if it is larger than the
active texture area.
Model frames are alias .tri files. Adding support for 3ds would not
be difficult, but it is likely that there would be coordinate problems
unless the entire model was done completely in 3ds.
S/T mappings allow a skin to be mapped onto any model frame. A mapping is
generated from a base frame and a texture size. If a coords.txt file is
not present, texpaint will generate a default mapping that is compatable
with the output of the old texmake. New skin or remap to skin will
generate a new coords.txt file.
Usage
-----
A three button mouse is required.
The left button paints with the current color in either the skin window
or the camera window, or selects colors in the palette view. Ctrl-left
click picks up the color clicked on in any view, making it current.
Right button dragging slides the object or skin around. Ctrl-right drag
to move in or out on the object.
Middle button dragging rotates the object in the camera view. Ctrl-middle
drag to change the roll angle.

58
texpaint/resource.h Normal file
View File

@@ -0,0 +1,58 @@
/*
===========================================================================
Copyright (C) 1997-2006 Id Software, Inc.
This file is part of Quake 2 Tools source code.
Quake 2 Tools source code 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.
Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by texmake.rc
//
#define IDR_MENU1 101
#define IDR_MENU2 102
#define IDR_ACCELERATOR1 104
#define IDD_NEWSKIN 105
#define IDC_WIDTH 1000
#define IDC_HEIGHT 1001
#define ID_FILE_SAVEAS 4003
#define ID_VIEW_MODELLINES 4006
#define ID_VIEW_MODELLIGHTING 4008
#define ID_FILE_OPENSKIN 4009
#define ID_FILE_SAVESKIN 4010
#define ID_FILE_SAVESKINAS 4011
#define ID_FILE_EXIT 4012
#define ID_FILE_OPENMODEL 4013
#define ID_FILE_RELOADSKIN 4014
#define ID_FILE_NEWSKIN 4016
#define ID_FILE_OPENFRAME 4017
#define ID_VIEW_SKINLINES 4018
#define ID_VIEW_MODELINES 4019
#define ID_VIEW_TEXTURELINES 4020
#define ID_FILE_RESAMPLESKIN 4024
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 106
#define _APS_NEXT_COMMAND_VALUE 4025
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

BIN
texpaint/texmake.aps Normal file

Binary file not shown.

156
texpaint/texmake.rc Normal file
View File

@@ -0,0 +1,156 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU2 MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New skin\tCtrl-n", ID_FILE_NEWSKIN
MENUITEM "&Open skin\tCtrl-o", ID_FILE_OPENSKIN
MENUITEM "&Reload skin\tCtrl-r", ID_FILE_RELOADSKIN
MENUITEM "&Save skin\tCtrl-s", ID_FILE_SAVESKIN
MENUITEM "Save skin &as\tCtrl-a", ID_FILE_SAVESKINAS
MENUITEM "Resample skin", ID_FILE_RESAMPLESKIN
MENUITEM SEPARATOR
MENUITEM "Open &frame\tCtrl-f", ID_FILE_OPENFRAME
MENUITEM SEPARATOR
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&Edit"
BEGIN
MENUITEM "&Undo\tCtrl-z", ID_EDIT_UNDO
MENUITEM "&Redo\tCtrl-y", ID_EDIT_REDO
END
POPUP "&View"
BEGIN
MENUITEM "&Model lines\tCtrl-m", ID_VIEW_MODELLINES
MENUITEM "&Texture lines\tCtrl-t", ID_VIEW_TEXTURELINES
MENUITEM "Model &lighting\tCtrl-l", ID_VIEW_MODELLIGHTING
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE
BEGIN
"A", ID_FILE_SAVESKINAS, VIRTKEY, CONTROL, NOINVERT
"F", ID_FILE_OPENFRAME, VIRTKEY, CONTROL, NOINVERT
"L", ID_VIEW_MODELLIGHTING, VIRTKEY, CONTROL, NOINVERT
"M", ID_VIEW_MODELLINES, VIRTKEY, CONTROL, NOINVERT
"N", ID_FILE_NEWSKIN, VIRTKEY, CONTROL, NOINVERT
"O", ID_FILE_OPENSKIN, VIRTKEY, CONTROL, NOINVERT
"R", ID_FILE_RELOADSKIN, VIRTKEY, CONTROL, NOINVERT
"S", ID_FILE_SAVESKIN, VIRTKEY, CONTROL, NOINVERT
"T", ID_VIEW_TEXTURELINES, VIRTKEY, CONTROL, NOINVERT
"Y", ID_EDIT_REDO, VIRTKEY, CONTROL, NOINVERT
"Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_NEWSKIN DIALOG DISCARDABLE 0, 0, 186, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "New Skin"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14
EDITTEXT IDC_WIDTH,51,14,40,14,ES_AUTOHSCROLL
LTEXT "Width",IDC_STATIC,20,17,20,8
EDITTEXT IDC_HEIGHT,51,37,40,14,ES_AUTOHSCROLL
LTEXT "height",IDC_STATIC,19,40,20,8
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_NEWSKIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 88
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

311
texpaint/texpaint.c Normal file
View File

@@ -0,0 +1,311 @@
/*
===========================================================================
Copyright (C) 1997-2006 Id Software, Inc.
This file is part of Quake 2 Tools source code.
Quake 2 Tools source code 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.
Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "texpaint.h"
triangle_t *faces;
int numfaces;
int skinwidth, skinheight;
int picwidth, picheight;
int width, height;
int iwidth, iheight;
int width2, height2; // padded to ^2
float tmcoords[10000][3][2];
byte pic[1024*512];
unsigned rgb[1024*512];
float scale;
float s_scale, t_scale;
char filename[1024];
char picfilename[1024];
/*
================
BoundFaces
================
*/
vec3_t mins, maxs;
void BoundFaces (void)
{
int i,j,k;
triangle_t *pol;
float v;
for (i=0 ; i<3 ; i++)
{
mins[i] = 9999;
maxs[i] = -9999;
}
for (i=0 ; i<numfaces ; i++)
{
pol = &faces[i];
for (j=0 ; j<3 ; j++)
for (k=0 ; k<3 ; k++)
{
v = pol->verts[j][k];
if (v<mins[k])
mins[k] = v;
if (v>maxs[k])
maxs[k] = v;
}
}
for (i=0 ; i<3 ; i++)
{
mins[i] = floor(mins[i]);
maxs[i] = ceil(maxs[i]);
}
width = maxs[0] - mins[0];
height = maxs[2] - mins[2];
printf ("width: %i height: %i\n",width, height);
if (!skinwidth)
{ // old way
scale = 8;
if (width*scale >= 150)
scale = 150.0 / width;
if (height*scale >= 190)
scale = 190.0 / height;
s_scale = t_scale = scale;
iwidth = ceil(width*scale) + 4;
iheight = ceil(height*scale) + 4;
}
else
{ // new way
s_scale = (skinwidth/2-4)/(float)width;
t_scale = (skinheight-4)/(float)height;
iwidth = skinwidth/2;
iheight = skinheight;
}
printf ("scale: %f\n",scale);
printf ("iwidth: %i iheight: %i\n",iwidth, iheight);
}
/*
============
AddFace
============
*/
void AddFace (int facenum, triangle_t *f)
{
vec3_t v1, v2, normal;
int basex, basey;
int i, j;
int coords[3][2];
//
// determine which side to map the teture to
//
VectorSubtract (f->verts[0], f->verts[1], v1);
VectorSubtract (f->verts[2], f->verts[1], v2);
CrossProduct (v1, v2, normal);
if (normal[1] > 0)
basex = iwidth + 2;
else
basex = 2;
basey = 2;
for (i=0 ; i<3 ; i++)
{
coords[i][0] = Q_rint((f->verts[i][0] - mins[0])*s_scale + basex);
coords[i][1] = Q_rint( (maxs[2] - f->verts[i][2])*t_scale + basey);
tmcoords[facenum][i][0] = coords[i][0]/(float)width2;
tmcoords[facenum][i][1] = coords[i][1]/(float)height2;
}
}
void CalcTmCoords (void)
{
int j;
BoundFaces ();
for (j=0 ; j<numfaces ; j++)
AddFace (j, &faces[j]);
printf ("numfaces: %i\n",numfaces);
}
//===============================================================================
#define MAX_NUM_ARGVS 32
int argc;
char *argv[MAX_NUM_ARGVS];
/*
============
ParseCommandLine
============
*/
void ParseCommandLine (char *lpCmdLine)
{
argc = 1;
argv[0] = "programname";
while (*lpCmdLine && (argc < MAX_NUM_ARGVS))
{
while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126)))
lpCmdLine++;
if (*lpCmdLine)
{
argv[argc] = lpCmdLine;
argc++;
while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126)))
lpCmdLine++;
if (*lpCmdLine)
{
*lpCmdLine = 0;
lpCmdLine++;
}
}
}
}
/*
=================
LoadTriFile
=================
*/
void LoadTriFile (char *name)
{
strcpy (tri_filename, name);
SetWindowText (camerawindow, tri_filename);
LoadTriangleList (tri_filename, &faces, &numfaces);
InvalidateRect (camerawindow, NULL, false);
}
/*
==================
TimerProc
==================
*/
int CALLBACK TimerProc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time
)
{
static int counter;
char name[1024];
if (!skin_filename[0])
return 0;
if (!modified_past_autosave)
{
counter = 0;
return 0;
}
counter++;
if (counter < 3*5)
return 0; // save every five minutes
strcpy (name, skin_filename);
StripExtension (name);
strcat (name, "_autosave.lbm");
Skin_SaveFile (name);
modified_past_autosave = false;
counter = 0;
return 0;
}
/*
==================
WinMain
==================
*/
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance
,LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HACCEL accelerators;
main_instance = hInstance;
ParseCommandLine (lpCmdLine);
screen_width = GetSystemMetrics (SM_CXFULLSCREEN);
screen_height = GetSystemMetrics (SM_CYFULLSCREEN);
// hack for broken NT 4.0 dual screen
if (screen_width > 2*screen_height)
screen_width /= 2;
accelerators = LoadAccelerators (hInstance
, MAKEINTRESOURCE(IDR_ACCELERATOR1));
if (!accelerators)
Sys_Error ("LoadAccelerators failed");
Main_Create (hInstance);
WCam_Create (hInstance);
WPal_Create (hInstance);
WSkin_Create (hInstance);
if (argc == 2)
Skin_LoadFile (argv[1]);
SetTimer ( mainwindow, 1, 1000*20, TimerProc );
while (1)
{
if (!GetMessage (&msg, mainwindow, 0, 0))
break;
if (!TranslateAccelerator(mainwindow, accelerators, &msg) )
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
/* return success of application */
return TRUE;
}

88
texpaint/texpaint.h Normal file
View File

@@ -0,0 +1,88 @@
/*
===========================================================================
Copyright (C) 1997-2006 Id Software, Inc.
This file is part of Quake 2 Tools source code.
Quake 2 Tools source code 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.
Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "cmdlib.h"
#include "mathlib.h"
#include "lbmlib.h"
#include "trilib.h"
#include "l3dslib.h"
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include "resource.h"
#include "afxres.h"
extern HINSTANCE main_instance;
extern HGLRC baseRC;
extern HWND mainwindow;
extern HWND camerawindow;
extern HWND palettewindow;
extern HWND skinwindow;
extern int screen_width, screen_height;
#define QE3_STYLE (WS_OVERLAPPED| WS_CAPTION | WS_THICKFRAME | \
/* WS_MINIMIZEBOX | */ WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | \
WS_CLIPCHILDREN | WS_CHILD)
extern byte pic[1024*512];
extern unsigned rgb[1024*512];
extern unsigned index_texture[1024*512];
extern byte palette[768];
extern triangle_t *faces;
extern int numfaces;
extern float tmcoords[10000][3][2];
extern int skinwidth, skinheight;
extern int picwidth, picheight;
extern int width, height;
extern int iwidth, iheight;
extern int width2, height2; // padded to ^2
extern char tri_filename[1024];
extern char skin_filename[1024];
extern int selected_index;
extern unsigned selected_rgb;
extern qboolean model_lines;
extern qboolean skin_lines;
extern qboolean modified;
extern qboolean modified_past_autosave;
#define TEXTURE_SKIN 1
#define TEXTURE_INDEX 2
#define MENU_VIEW 2
#define MODEL_DISPLAYLIST 1
typedef void (APIENTRY *BINDTEXFUNCPTR)(GLenum, GLuint);
extern BINDTEXFUNCPTR BindTextureEXT;

468
texpaint/texpaint.mak Normal file
View File

@@ -0,0 +1,468 @@
# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
!IF "$(CFG)" == ""
CFG=texpaint - Win32 Debug
!MESSAGE No configuration specified. Defaulting to texpaint - Win32 Debug.
!ENDIF
!IF "$(CFG)" != "texpaint - Win32 Release" && "$(CFG)" !=\
"texpaint - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "texpaint.mak" CFG="texpaint - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "texpaint - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "texpaint - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "texpaint - Win32 Debug"
MTL=mktyplib.exe
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "texpaint - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
OUTDIR=.\Release
INTDIR=.\Release
ALL : "$(OUTDIR)\texpaint.exe"
CLEAN :
-@erase "$(INTDIR)\cmdlib.obj"
-@erase "$(INTDIR)\l3dslib.obj"
-@erase "$(INTDIR)\lbmlib.obj"
-@erase "$(INTDIR)\mathlib.obj"
-@erase "$(INTDIR)\scriplib.obj"
-@erase "$(INTDIR)\texmake.res"
-@erase "$(INTDIR)\texpaint.obj"
-@erase "$(INTDIR)\trilib.obj"
-@erase "$(INTDIR)\win_cam.obj"
-@erase "$(INTDIR)\win_main.obj"
-@erase "$(INTDIR)\win_pal.obj"
-@erase "$(INTDIR)\win_skin.obj"
-@erase "$(OUTDIR)\texpaint.exe"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /GX /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
CPP_PROJ=/nologo /ML /GX /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D\
"_WINDOWS" /Fp"$(INTDIR)/texpaint.pch" /YX /Fo"$(INTDIR)/" /c
CPP_OBJS=.\Release/
CPP_SBRS=.\.
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /win32
MTL_PROJ=/nologo /D "NDEBUG" /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
RSC_PROJ=/l 0x409 /fo"$(INTDIR)/texmake.res" /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/texpaint.bsc"
BSC32_SBRS= \
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib\
winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\
uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:no\
/pdb:"$(OUTDIR)/texpaint.pdb" /machine:I386 /out:"$(OUTDIR)/texpaint.exe"
LINK32_OBJS= \
"$(INTDIR)\cmdlib.obj" \
"$(INTDIR)\l3dslib.obj" \
"$(INTDIR)\lbmlib.obj" \
"$(INTDIR)\mathlib.obj" \
"$(INTDIR)\scriplib.obj" \
"$(INTDIR)\texmake.res" \
"$(INTDIR)\texpaint.obj" \
"$(INTDIR)\trilib.obj" \
"$(INTDIR)\win_cam.obj" \
"$(INTDIR)\win_main.obj" \
"$(INTDIR)\win_pal.obj" \
"$(INTDIR)\win_skin.obj"
"$(OUTDIR)\texpaint.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "texpaint - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "texpaint"
# PROP BASE Intermediate_Dir "texpaint"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
OUTDIR=.\Debug
INTDIR=.\Debug
ALL : "$(OUTDIR)\texpaint.exe"
CLEAN :
-@erase "$(INTDIR)\cmdlib.obj"
-@erase "$(INTDIR)\l3dslib.obj"
-@erase "$(INTDIR)\lbmlib.obj"
-@erase "$(INTDIR)\mathlib.obj"
-@erase "$(INTDIR)\scriplib.obj"
-@erase "$(INTDIR)\texmake.res"
-@erase "$(INTDIR)\texpaint.obj"
-@erase "$(INTDIR)\trilib.obj"
-@erase "$(INTDIR)\vc40.idb"
-@erase "$(INTDIR)\vc40.pdb"
-@erase "$(INTDIR)\win_cam.obj"
-@erase "$(INTDIR)\win_main.obj"
-@erase "$(INTDIR)\win_pal.obj"
-@erase "$(INTDIR)\win_skin.obj"
-@erase "$(OUTDIR)\texpaint.exe"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN_ERROR" /YX /c
CPP_PROJ=/nologo /MLd /Gm /GX /Zi /Od /I "..\common" /D "WIN32" /D "_DEBUG" /D\
"_WINDOWS" /D "WIN_ERROR" /Fp"$(INTDIR)/texpaint.pch" /YX /Fo"$(INTDIR)/"\
/Fd"$(INTDIR)/" /c
CPP_OBJS=.\Debug/
CPP_SBRS=.\.
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /win32
MTL_PROJ=/nologo /D "_DEBUG" /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
RSC_PROJ=/l 0x409 /fo"$(INTDIR)/texmake.res" /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/texpaint.bsc"
BSC32_SBRS= \
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /pdb:none /debug /machine:I386
LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib\
winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\
uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /pdb:none /debug\
/machine:I386 /out:"$(OUTDIR)/texpaint.exe"
LINK32_OBJS= \
"$(INTDIR)\cmdlib.obj" \
"$(INTDIR)\l3dslib.obj" \
"$(INTDIR)\lbmlib.obj" \
"$(INTDIR)\mathlib.obj" \
"$(INTDIR)\scriplib.obj" \
"$(INTDIR)\texmake.res" \
"$(INTDIR)\texpaint.obj" \
"$(INTDIR)\trilib.obj" \
"$(INTDIR)\win_cam.obj" \
"$(INTDIR)\win_main.obj" \
"$(INTDIR)\win_pal.obj" \
"$(INTDIR)\win_skin.obj"
"$(OUTDIR)\texpaint.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.c{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Target
# Name "texpaint - Win32 Release"
# Name "texpaint - Win32 Debug"
!IF "$(CFG)" == "texpaint - Win32 Release"
!ELSEIF "$(CFG)" == "texpaint - Win32 Debug"
!ENDIF
################################################################################
# Begin Source File
SOURCE=.\texpaint.c
DEP_CPP_TEXPA=\
"..\common\cmdlib.h"\
"..\common\l3dslib.h"\
"..\common\lbmlib.h"\
"..\common\mathlib.h"\
"..\common\trilib.h"\
".\texpaint.h"\
{$(INCLUDE)}"\gl\GL.H"\
{$(INCLUDE)}"\gl\GLAUX.H"\
{$(INCLUDE)}"\gl\GLU.H"\
"$(INTDIR)\texpaint.obj" : $(SOURCE) $(DEP_CPP_TEXPA) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=\quake\utils2\common\mathlib.c
DEP_CPP_MATHL=\
"..\..\..\quake\utils2\common\cmdlib.h"\
"..\..\..\quake\utils2\common\mathlib.h"\
"$(INTDIR)\mathlib.obj" : $(SOURCE) $(DEP_CPP_MATHL) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=\quake\utils2\common\l3dslib.c
DEP_CPP_L3DSL=\
"..\..\..\quake\utils2\common\cmdlib.h"\
"..\..\..\quake\utils2\common\l3dslib.h"\
"..\..\..\quake\utils2\common\mathlib.h"\
"..\..\..\quake\utils2\common\trilib.h"\
"$(INTDIR)\l3dslib.obj" : $(SOURCE) $(DEP_CPP_L3DSL) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=\quake\utils2\common\lbmlib.c
DEP_CPP_LBMLI=\
"..\..\..\quake\utils2\common\cmdlib.h"\
"..\..\..\quake\utils2\common\lbmlib.h"\
"$(INTDIR)\lbmlib.obj" : $(SOURCE) $(DEP_CPP_LBMLI) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=\quake\utils2\common\scriplib.c
DEP_CPP_SCRIP=\
"..\..\..\quake\utils2\common\cmdlib.h"\
"..\..\..\quake\utils2\common\scriplib.h"\
"$(INTDIR)\scriplib.obj" : $(SOURCE) $(DEP_CPP_SCRIP) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=\quake\utils2\common\trilib.c
DEP_CPP_TRILI=\
"..\..\..\quake\utils2\common\cmdlib.h"\
"..\..\..\quake\utils2\common\mathlib.h"\
"..\..\..\quake\utils2\common\trilib.h"\
"$(INTDIR)\trilib.obj" : $(SOURCE) $(DEP_CPP_TRILI) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\win_skin.c
DEP_CPP_WIN_S=\
"..\common\cmdlib.h"\
"..\common\l3dslib.h"\
"..\common\lbmlib.h"\
"..\common\mathlib.h"\
"..\common\trilib.h"\
".\texpaint.h"\
{$(INCLUDE)}"\gl\GL.H"\
{$(INCLUDE)}"\gl\GLAUX.H"\
{$(INCLUDE)}"\gl\GLU.H"\
"$(INTDIR)\win_skin.obj" : $(SOURCE) $(DEP_CPP_WIN_S) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\win_main.c
DEP_CPP_WIN_M=\
"..\common\cmdlib.h"\
"..\common\l3dslib.h"\
"..\common\lbmlib.h"\
"..\common\mathlib.h"\
"..\common\trilib.h"\
".\texpaint.h"\
{$(INCLUDE)}"\gl\GL.H"\
{$(INCLUDE)}"\gl\GLAUX.H"\
{$(INCLUDE)}"\gl\GLU.H"\
"$(INTDIR)\win_main.obj" : $(SOURCE) $(DEP_CPP_WIN_M) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\win_pal.c
DEP_CPP_WIN_P=\
"..\common\cmdlib.h"\
"..\common\l3dslib.h"\
"..\common\lbmlib.h"\
"..\common\mathlib.h"\
"..\common\trilib.h"\
".\texpaint.h"\
{$(INCLUDE)}"\gl\GL.H"\
{$(INCLUDE)}"\gl\GLAUX.H"\
{$(INCLUDE)}"\gl\GLU.H"\
"$(INTDIR)\win_pal.obj" : $(SOURCE) $(DEP_CPP_WIN_P) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\win_cam.c
DEP_CPP_WIN_C=\
"..\common\cmdlib.h"\
"..\common\l3dslib.h"\
"..\common\lbmlib.h"\
"..\common\mathlib.h"\
"..\common\trilib.h"\
".\texpaint.h"\
{$(INCLUDE)}"\gl\GL.H"\
{$(INCLUDE)}"\gl\GLAUX.H"\
{$(INCLUDE)}"\gl\GLU.H"\
"$(INTDIR)\win_cam.obj" : $(SOURCE) $(DEP_CPP_WIN_C) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\texmake.rc
"$(INTDIR)\texmake.res" : $(SOURCE) "$(INTDIR)"
$(RSC) $(RSC_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\texpaint.h
!IF "$(CFG)" == "texpaint - Win32 Release"
!ELSEIF "$(CFG)" == "texpaint - Win32 Debug"
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=\quake\utils2\common\lbmlib.h
!IF "$(CFG)" == "texpaint - Win32 Release"
!ELSEIF "$(CFG)" == "texpaint - Win32 Debug"
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=\quake\utils2\common\cmdlib.h
!IF "$(CFG)" == "texpaint - Win32 Release"
!ELSEIF "$(CFG)" == "texpaint - Win32 Debug"
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=\quake\utils2\common\cmdlib.c
DEP_CPP_CMDLI=\
"..\..\..\quake\utils2\common\cmdlib.h"\
{$(INCLUDE)}"\sys\stat.h"\
{$(INCLUDE)}"\sys\types.h"\
"$(INTDIR)\cmdlib.obj" : $(SOURCE) $(DEP_CPP_CMDLI) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
# End Target
# End Project
################################################################################

414
texpaint/win_cam.c Normal file
View File

@@ -0,0 +1,414 @@
/*
===========================================================================
Copyright (C) 1997-2006 Id Software, Inc.
This file is part of Quake 2 Tools source code.
Quake 2 Tools source code 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.
Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "texpaint.h"
#define CAMERA_WINDOW_CLASS "TPCamera"
HDC camdc;
HGLRC baseRC;
float pitch, yaw, roll;
qboolean model_lines = false;
float cam_x, cam_y=-64, cam_z=32;
int cam_width, cam_height;
BINDTEXFUNCPTR BindTextureEXT;
void InitIndexTexture (void)
{
int i;
BindTextureEXT (GL_TEXTURE_2D, TEXTURE_INDEX);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
for (i=0 ; i<sizeof(index_texture)/4 ; i++)
index_texture[i] = i+1;
glTexImage2D (GL_TEXTURE_2D, 0, 3, width2, height2, 0, GL_RGBA, GL_UNSIGNED_BYTE, index_texture);
BindTextureEXT (GL_TEXTURE_2D, TEXTURE_SKIN);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
void CreateDisplaylist (void)
{
}
void DrawModel (void)
{
int i, j;
glColor4f (1,1,1,1);
glBegin (GL_TRIANGLES);
for (i=0 ; i<numfaces ; i++)
{
for (j=0 ; j<3 ; j++)
{
glTexCoord2f (tmcoords[i][j][0], tmcoords[i][j][1]);
glVertex3fv (faces[i].verts[j]);
}
}
glEnd ();
}
/*
=============
Cam_Click
=============
*/
int cam_last_index;
void Cam_Click (int x, int y, qboolean shift)
{
int index;
index = 0;
glReadBuffer (GL_BACK);
glReadPixels (x, y, 1,1, GL_RGB, GL_UNSIGNED_BYTE, &index);
index--;
if (index == -1)
return;
if (index >= width2*height2)
return;
if (index == cam_last_index)
return; // in same pixel
cam_last_index = index;
if (shift)
{
Pal_SetIndex (pic[index]);
return;
}
SetSkin (index, selected_rgb);
UpdateWindow (camerawindow);
}
void Cam_DrawSetup (void)
{
glViewport (0,0,cam_width, cam_height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (90, (float)cam_width/cam_height, 2, 1024);
gluLookAt (cam_x, cam_y, cam_z, cam_x, cam_y+1, cam_z, 0, 0, 1);
glRotated (-roll*0.3, 0, 1, 0);
glRotated (-pitch*0.3, 1, 0, 0);
glRotated (yaw*0.3, 0, 0, 1);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable (GL_DEPTH_TEST);
glEnable (GL_CULL_FACE);
glEnable (GL_TEXTURE_2D);
glCullFace (GL_FRONT);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
void Cam_Draw (void)
{
if (!cam_width || !cam_height)
return;
glClearColor (0.3,0.3,0.3,1);
Cam_DrawSetup ();
BindTextureEXT (GL_TEXTURE_2D, TEXTURE_SKIN);
DrawModel ();
if (model_lines)
{
glDisable (GL_TEXTURE_2D);
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glDepthFunc (GL_LEQUAL);
glDepthRange (0, 0.999); // nudge depth to avoid dropouts
DrawModel ();
glDepthRange (0, 1);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glEnable (GL_TEXTURE_2D);
}
SwapBuffers(camdc);
// now fill the back buffer with the index texture
glClearColor (0,0,0,0);
glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
BindTextureEXT (GL_TEXTURE_2D, TEXTURE_INDEX);
DrawModel ();
BindTextureEXT (GL_TEXTURE_2D, TEXTURE_SKIN);
}
/*
============
CameraWndProc
============
*/
LONG WINAPI WCam_WndProc (
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
LONG lRet = 1;
int fwKeys, xPos, yPos;
RECT rect;
static int oldx, oldy;
POINT pt;
GetClientRect(hWnd, &rect);
cam_width = rect.right-rect.left;
cam_height = rect.bottom-rect.top;
switch (uMsg)
{
case WM_CREATE:
camdc = GetDC(hWnd);
bSetupPixelFormat(camdc);
baseRC = wglCreateContext( camdc );
if (!baseRC)
Sys_Error ("wglCreateContext failed");
if (!wglMakeCurrent( camdc, baseRC ))
Sys_Error ("wglMakeCurrent failed");
BindTextureEXT = (void *)wglGetProcAddress((LPCSTR) "glBindTextureEXT");
if (!BindTextureEXT)
Sys_Error ("GetProcAddress for BindTextureEXT failed");
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
if (!wglMakeCurrent( camdc, baseRC ))
Sys_Error ("wglMakeCurrent failed");
Cam_Draw ();
EndPaint(hWnd, &ps);
}
break;
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
if (GetTopWindow(mainwindow) != hWnd)
BringWindowToTop(hWnd);
SetFocus (camerawindow);
SetCapture (camerawindow);
GetCursorPos (&pt);
xPos = pt.x;
yPos = pt.y;
oldx = xPos;
oldy = yPos;
break;
case WM_LBUTTONDOWN:
cam_last_index = -1;
draw:
if (GetTopWindow(mainwindow) != hWnd)
BringWindowToTop(hWnd);
SetFocus (camerawindow);
SetCapture (camerawindow);
fwKeys = wParam; // key flags
xPos = (short)LOWORD(lParam); // horizontal position of cursor
yPos = (short)HIWORD(lParam); // vertical position of cursor
yPos = (int)rect.bottom - 1 - yPos;
if (!wglMakeCurrent( camdc, baseRC ))
Sys_Error ("wglMakeCurrent failed");
Cam_Click (xPos, yPos, !!(wParam&(MK_SHIFT|MK_CONTROL)) );
// Cam_MouseDown (xPos, yPos, fwKeys);
break;
case WM_MBUTTONUP:
case WM_RBUTTONUP:
case WM_LBUTTONUP:
if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON)))
ReleaseCapture ();
break;
case WM_MOUSEMOVE:
{
int dx, dy;
if (wParam & MK_LBUTTON)
goto draw;
GetCursorPos (&pt);
xPos = pt.x;
yPos = pt.y;
if (!(wParam & (MK_RBUTTON|MK_MBUTTON)))
{
oldx = xPos;
oldy = yPos;
break;
}
dx = xPos-oldx;
dy = oldy-yPos;
if (!dx && !dy)
break;
SetCursorPos (oldx, oldy);
if (wParam == (MK_RBUTTON|MK_CONTROL) )
{
if (abs(dx) > abs(dy))
cam_y -= 0.1*dx;
else
cam_y -= 0.1*dy;
InvalidateRect (camerawindow, NULL, false);
}
if (wParam == MK_RBUTTON)
{
cam_x -= 0.1*dx;
cam_z -= 0.1*dy;
InvalidateRect (camerawindow, NULL, false);
}
if (wParam == (MK_MBUTTON|MK_CONTROL) )
{
if (abs(dx) > abs(dy))
roll -= dx;
else
roll -= dy;
InvalidateRect (camerawindow, NULL, false);
}
if (wParam == MK_MBUTTON)
{
yaw += dx;
pitch += dy;
InvalidateRect (camerawindow, NULL, false);
}
}
break;
case WM_SIZE:
// camera.width = rect.right;
// camera.height = rect.bottom;
InvalidateRect(camerawindow, NULL, false);
break;
case WM_NCCALCSIZE:// don't let windows copy pixels
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
return WVR_REDRAW;
case WM_CLOSE:
/* call destroy window to cleanup and go away */
DestroyWindow (hWnd);
break;
case WM_DESTROY:
{
HGLRC hRC;
HDC hDC;
/* release and free the device context and rendering context */
hRC = wglGetCurrentContext();
hDC = wglGetCurrentDC();
wglMakeCurrent(NULL, NULL);
if (hRC)
wglDeleteContext(hRC);
if (hDC)
ReleaseDC(hWnd, hDC);
}
break;
default:
/* pass all unhandled messages to DefWindowProc */
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
break;
}
/* return 1 if handled message, 0 if not */
return lRet;
}
/*
==============
WCam_Register
==============
*/
void WCam_Register (HINSTANCE hInstance)
{
WNDCLASS wc;
/* Register the camera class */
memset (&wc, 0, sizeof(wc));
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)WCam_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = 0;
wc.lpszClassName = CAMERA_WINDOW_CLASS;
if (!RegisterClass (&wc) )
Sys_Error ("WCam_Register: failed");
}
void WCam_Create (HINSTANCE hInstance)
{
WCam_Register (hInstance);
camerawindow = CreateWindow (CAMERA_WINDOW_CLASS ,
"Camera View",
QE3_STYLE,
0,
0,
(int)(screen_width*0.5),
(int)(screen_height-20), // size
mainwindow, // parent window
0, // no menu
hInstance,
0);
if (!camerawindow)
Sys_Error ("Couldn't create camerawindow");
RestoreWindowState(camerawindow, "camerawindow");
ShowWindow (camerawindow, SW_SHOWDEFAULT);
}

496
texpaint/win_main.c Normal file
View File

@@ -0,0 +1,496 @@
/*
===========================================================================
Copyright (C) 1997-2006 Id Software, Inc.
This file is part of Quake 2 Tools source code.
Quake 2 Tools source code 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.
Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "texpaint.h"
HINSTANCE main_instance;
int screen_width, screen_height;
HWND mainwindow;
HWND camerawindow;
HWND palettewindow;
HWND skinwindow;
/*
=================
Sys_Error
For abnormal program terminations
=================
*/
void Sys_Error (char *error, ...)
{
va_list argptr;
char text[1024];
char text2[1024];
int err;
err = GetLastError ();
va_start (argptr,error);
vsprintf (text, error,argptr);
va_end (argptr);
sprintf (text2, "%s\nGetLastError() = %i", text, err);
MessageBox(mainwindow, text2, "Error", 0 /* MB_OK */ );
exit (1);
}
/*
======================================================================
FILE DIALOGS
======================================================================
*/
qboolean modified;
qboolean modified_past_autosave;
qboolean ConfirmModified (void)
{
if (!modified)
return true;
if (MessageBox (mainwindow, "This will lose changes to the skin"
, "warning", MB_OKCANCEL) == IDCANCEL)
return false;
return true;
}
OPENFILENAME ofn; /* common dialog box structure */
char szDirName[MAX_PATH]; /* directory string */
char szFile[260]; /* filename string */
char szFileTitle[260]; /* file title string */
char szSkinFilter[260] = /* filter string */
"Skin texture (*.lbm *.pcx)\0*.lbm;*.pcx\0\0";
char szFrameFilter[260] = /* filter string */
"Model frame (*.tri)\0*.tri\0\0";
char chReplace; /* string separator for szFilter */
int i, cbString; /* integer count variables */
HANDLE hf; /* file handle */
void OpenSkinDialog (void)
{
// strcpy (szDirName, ValueForKey (project_entity, "basepath") );
// strcat (szDirName, "\\maps");
/* Place the terminating null character in the szFile. */
szFile[0] = '\0';
/* Set the members of the OPENFILENAME structure. */
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = mainwindow;
ofn.lpstrFilter = szSkinFilter;
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.lpstrInitialDir = szDirName;
ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
OFN_FILEMUSTEXIST;
/* Display the Open dialog box. */
if (!GetOpenFileName(&ofn))
return; // canceled
Skin_LoadFile (ofn.lpstrFile);
}
void OpenFrameDialog (void)
{
// strcpy (szDirName, ValueForKey (project_entity, "basepath") );
// strcat (szDirName, "\\maps");
/* Place the terminating null character in the szFile. */
szFile[0] = '\0';
/* Set the members of the OPENFILENAME structure. */
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = mainwindow;
ofn.lpstrFilter = szFrameFilter;
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.lpstrInitialDir = szDirName;
ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
OFN_FILEMUSTEXIST;
/* Display the Open dialog box. */
if (!GetOpenFileName(&ofn))
return; // canceled
LoadTriFile (ofn.lpstrFile);
}
void SaveSkinDialog (void)
{
// strcpy (szDirName, ValueForKey (project_entity, "basepath") );
// strcat (szDirName, "\\maps");
/* Place the terminating null character in the szFile. */
szFile[0] = '\0';
/* Set the members of the OPENFILENAME structure. */
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = mainwindow;
ofn.lpstrFilter = szSkinFilter;
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.lpstrInitialDir = szDirName;
ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
OFN_FILEMUSTEXIST;
/* Display the Open dialog box. */
if (!GetSaveFileName(&ofn))
return; // canceled
DefaultExtension (ofn.lpstrFile, ".lbm");
Skin_SaveFile (ofn.lpstrFile);
strcpy (skin_filename, ofn.lpstrFile);
}
//==========================================================================
BOOL bSetupPixelFormat(HDC hDC)
{
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelformat = 0;
PIXELFORMATDESCRIPTOR newp;
if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 )
{
printf("%d",GetLastError());
Error ("ChoosePixelFormat failed");
}
if (!SetPixelFormat(hDC, pixelformat, &pfd))
Error ("SetPixelFormat failed");
return TRUE;
}
/*
==============================================================================
MENU
==============================================================================
*/
/* handle all WM_COMMAND messages here */
LONG WINAPI CommandHandler (
HWND hWnd,
WPARAM wParam,
LPARAM lParam)
{
unsigned short cmd;
cmd = LOWORD(wParam);
switch (cmd)
{
//
// file menu
//
case ID_FILE_RESAMPLESKIN:
ResampleSkin ();
break;
case ID_FILE_NEWSKIN:
NewSkin ();
break;
case ID_FILE_OPENFRAME:
OpenFrameDialog ();
break;
case ID_FILE_OPENSKIN:
if (!ConfirmModified())
break;
OpenSkinDialog ();
break;
case ID_FILE_RELOADSKIN:
if (!ConfirmModified())
break;
Skin_LoadFile (skin_filename);
break;
case ID_FILE_SAVESKIN:
Skin_SaveFile (skin_filename);
break;
case ID_FILE_SAVESKINAS:
SaveSkinDialog ();
break;
case ID_FILE_EXIT:
if (!ConfirmModified())
break;
PostQuitMessage (0);
break;
//
// edit menu
//
case ID_EDIT_UNDO:
Undo();
break;
case ID_EDIT_REDO:
Redo();
break;
//
// view menu
//
case ID_VIEW_MODELLINES:
model_lines ^= 1;
CheckMenuItem ( GetSubMenu (GetMenu(mainwindow), MENU_VIEW)
, ID_VIEW_MODELLINES
, MF_BYCOMMAND | (model_lines ? MF_CHECKED : MF_UNCHECKED) );
InvalidateRect (camerawindow, NULL, false);
break;
case ID_VIEW_TEXTURELINES:
skin_lines ^= 1;
CheckMenuItem ( GetSubMenu (GetMenu(mainwindow), MENU_VIEW)
, ID_VIEW_TEXTURELINES
, MF_BYCOMMAND | (skin_lines ? MF_CHECKED : MF_UNCHECKED) );
InvalidateRect (skinwindow, NULL, false);
break;
default:
return FALSE;
}
return TRUE;
}
/*
============
WMAIN_WndProc
============
*/
LONG WINAPI WMAIN_WndProc (
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
LONG lRet = 1;
RECT rect;
HDC maindc;
GetClientRect(hWnd, &rect);
switch (uMsg)
{
case WM_CREATE:
maindc = GetDC(hWnd);
bSetupPixelFormat(maindc);
break;
case WM_COMMAND:
lRet = CommandHandler (hWnd, wParam, lParam);
break;
case WM_CLOSE:
if (!ConfirmModified())
break;
PostQuitMessage (0);
break;
default:
/* pass all unhandled messages to DefWindowProc */
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
break;
}
/* return 1 if handled message, 0 if not */
return lRet;
}
/*
==============
Main_Create
==============
*/
void Main_Create (HINSTANCE hInstance)
{
WNDCLASS wc;
/* Register the class */
memset (&wc, 0, sizeof(wc));
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)WMAIN_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU2);
wc.lpszClassName = "TEXPAINT_MAIN";
if (!RegisterClass (&wc) )
Error ("WCam_Register: failed");
mainwindow = CreateWindow ("TEXPAINT_MAIN" ,
"Texpaint",
WS_OVERLAPPEDWINDOW |
WS_CLIPSIBLINGS |
WS_CLIPCHILDREN,
0,0,screen_width,screen_height, // size
0,
NULL, // no menu
hInstance,
NULL);
if (!mainwindow)
Error ("Couldn't create main window");
// GetWindowInfo("mainwindow", &SavedInfo, NULL);
ShowWindow (mainwindow, SW_SHOWDEFAULT);
}
BOOL SaveWindowInfo(const char *pszName, void *pvBuf, long lSize)
{
LONG lres;
DWORD dwDisp;
HKEY hKeyId;
lres = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\id\\Texpaint", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyId, &dwDisp);
if (lres != ERROR_SUCCESS)
return FALSE;
lres = RegSetValueEx(hKeyId, pszName, 0, REG_BINARY, pvBuf, lSize);
RegCloseKey(hKeyId);
if (lres != ERROR_SUCCESS)
return FALSE;
return TRUE;
}
BOOL GetWindowInfo(const char *pszName, void *pvBuf, long *plSize)
{
HKEY hKey;
long lres, lType, lSize;
if (plSize == NULL)
plSize = &lSize;
lres = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\id\\Texpaint", 0, KEY_READ, &hKey);
if (lres != ERROR_SUCCESS)
return FALSE;
lres = RegQueryValueEx(hKey, pszName, NULL, &lType, pvBuf, plSize);
RegCloseKey(hKey);
if (lres != ERROR_SUCCESS)
return FALSE;
return TRUE;
}
BOOL SaveWindowState(HWND hWnd, const char *pszName)
{
RECT rc;
GetWindowRect(hWnd, &rc);
MapWindowPoints(NULL, mainwindow, (POINT *)&rc, 2);
return SaveWindowInfo(pszName, &rc, sizeof(rc));
}
BOOL RestoreWindowState(HWND hWnd, const char *pszName)
{
RECT rc;
LONG lSize = sizeof(rc);
if (GetWindowInfo(pszName, &rc, &lSize))
{
if (rc.left < 0)
rc.left = 0;
if (rc.top < 0)
rc.top = 0;
if (rc.right < rc.left + 16)
rc.right = rc.left + 16;
if (rc.bottom < rc.top + 16)
rc.bottom = rc.top + 16;
MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left,
rc.bottom - rc.top, FALSE);
return TRUE;
}
return FALSE;
}

257
texpaint/win_pal.c Normal file
View File

@@ -0,0 +1,257 @@
/*
===========================================================================
Copyright (C) 1997-2006 Id Software, Inc.
This file is part of Quake 2 Tools source code.
Quake 2 Tools source code 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.
Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "texpaint.h"
#define PALETTE_WINDOW_CLASS "TPPalette"
HDC paldc;
int pal_width, pal_height;
int blocks_x, blocks_y;
int selected_index;
unsigned selected_rgb;
byte palette[768];
float SnapAspect (float aspect)
{
if (aspect > 128)
return 256;
if (aspect > 32)
return 128;
if (aspect > 8)
return 64;
if (aspect > 2)
return 32;
return 16;
}
void Pal_SetIndex (int index)
{
selected_index = index;
selected_rgb = palette[index*3] + (palette[index*3+1]<<8) + (palette[index*3+2]<<16);
InvalidateRect (palettewindow, NULL, false);
}
void Pal_Draw (void)
{
int x, y;
float aspect;
float xs, ys;
int c;
if (pal_width < 1 || pal_height < 1)
return;
//
// determine the block arrangement
//
if (pal_width > pal_height)
{
aspect = SnapAspect (pal_width / pal_height);
blocks_x = aspect;
blocks_y = 256/blocks_x;
}
else
{
aspect = SnapAspect (pal_height / pal_width);
blocks_y = aspect;
blocks_x = 256/blocks_y;
}
//
// draw it
//
glViewport (0,0,pal_width, pal_height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0,1,0,1,-100,100);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glClear (GL_COLOR_BUFFER_BIT);
glDisable (GL_DEPTH_TEST);
glDisable (GL_CULL_FACE);
glDisable (GL_TEXTURE_2D);
xs = 1.0/blocks_x;
ys = 1.0/blocks_y;
for (x=0 ; x<blocks_x ; x++)
{
for (y=0 ; y<blocks_y ; y++)
{
c = x*blocks_y+(blocks_y-1-y);
glColor3ubv (palette+c*3);
glRectf (x*xs, y*ys, (x+1)*xs, (y+1)*ys);
}
}
// highlight the selected texture
y = selected_index % blocks_y;
x = selected_index / blocks_y;
y = blocks_y-1-y;
glColor3f (0,0,0);
glRectf ( (x+0.4)*xs, (y+0.4)*ys, (x+0.6)*xs, (y+0.6)*ys);
}
void Pal_Click (int x, int y)
{
int index;
x = x*blocks_x/pal_width;
y = y*blocks_y/pal_height;
y = blocks_y-1-y;
index = x*blocks_y + y;
Pal_SetIndex (index);
}
/*
============
Palette_WndProc
============
*/
LONG WINAPI Palette_WndProc (
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
LONG lRet = 1;
int fwKeys, xPos, yPos;
RECT rect;
GetClientRect(hWnd, &rect);
pal_width = rect.right-rect.left;
pal_height = rect.bottom-rect.top;
switch (uMsg)
{
case WM_CREATE:
paldc = GetDC(hWnd);
bSetupPixelFormat(paldc);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
if (!wglMakeCurrent( paldc, baseRC ))
Error ("wglMakeCurrent failed");
Pal_Draw ();
EndPaint(hWnd, &ps);
SwapBuffers(paldc);
}
break;
case WM_MOUSEMOVE:
if (wParam != MK_LBUTTON)
break;
case WM_LBUTTONDOWN:
if (GetTopWindow(mainwindow) != hWnd)
BringWindowToTop(hWnd);
xPos = (short)LOWORD(lParam); // horizontal position of cursor
yPos = (short)HIWORD(lParam); // vertical position of cursor
yPos = (int)rect.bottom - 1 - yPos;
Pal_Click (xPos, yPos);
break;
case WM_MBUTTONUP:
case WM_RBUTTONUP:
case WM_LBUTTONUP:
fwKeys = wParam; // key flags
xPos = (short)LOWORD(lParam); // horizontal position of cursor
yPos = (short)HIWORD(lParam); // vertical position of cursor
yPos = (int)rect.bottom - 1 - yPos;
ReleaseCapture ();
break;
case WM_SIZE:
InvalidateRect(skinwindow, NULL, false);
break;
case WM_NCCALCSIZE:// don't let windows copy pixels
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
return WVR_REDRAW;
case WM_CLOSE:
/* call destroy window to cleanup and go away */
DestroyWindow (hWnd);
break;
default:
/* pass all unhandled messages to DefWindowProc */
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
break;
}
/* return 1 if handled message, 0 if not */
return lRet;
}
/*
==============
WPal_Create
==============
*/
void WPal_Create (HINSTANCE hInstance)
{
WNDCLASS wc;
/* Register the skin class */
memset (&wc, 0, sizeof(wc));
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)Palette_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = 0;
wc.lpszClassName = PALETTE_WINDOW_CLASS;
if (!RegisterClass (&wc) )
Error ("RegisterClass failed");
palettewindow = CreateWindow (PALETTE_WINDOW_CLASS ,
"Palette View",
QE3_STYLE,
(int)(screen_width*0.5),
0,
(int)(screen_width*0.5),
(int)(screen_height*.2), // size
mainwindow, // parent window
0, // no menu
hInstance,
0);
if (!palettewindow)
Error ("Couldn't create palettewindow");
// RestoreWindowState(palettewindow, "palettewindow");
ShowWindow (palettewindow, SW_SHOWDEFAULT);
}

946
texpaint/win_skin.c Normal file
View File

@@ -0,0 +1,946 @@
/*
===========================================================================
Copyright (C) 1997-2006 Id Software, Inc.
This file is part of Quake 2 Tools source code.
Quake 2 Tools source code 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.
Quake 2 Tools source code 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 Quake 2 Tools source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "texpaint.h"
#define SKIN_WINDOW_CLASS "TPSkin"
HDC skindc;
int skinw_width, skinw_height; // size of the window
float skin_x = 128, skin_y = 128, skin_z = 100;
qboolean skin_lines = false;
char tri_filename[1024];
char skin_filename[1024];
int skin_width, skin_height; // size of the .lbm image
unsigned index_texture[1024*512];
void UpdateTexture (int offset)
{
int x, y;
y = offset / width2;
x = offset % width2;
BindTextureEXT (GL_TEXTURE_2D, TEXTURE_SKIN);
// glTexImage2D (GL_TEXTURE_2D, 0, 3, width2, height2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgb);
glTexSubImage2D (GL_TEXTURE_2D, 0, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, rgb+offset);
}
/*
===================================================================
TEXEL MODIFICATION
===================================================================
*/
#define MAX_MODIFY 8192
typedef struct
{
int offset;
int oldvalue;
} modify_t;
int modify_index;
int undo_index;
modify_t modify[MAX_MODIFY];
void SetSkinModified (void)
{
char text[1024];
if (modified && modified_past_autosave)
return;
modified = true;
modified_past_autosave = true;
sprintf (text, "%s *", skin_filename);
SetWindowText (skinwindow, text);
}
void SetSkin (int index, int pixel)
{
modify_t *m;
if (!modified)
SetSkinModified ();
// save undo info
m = &modify[undo_index];
m->offset = index;
m->oldvalue = pic[index];
modify_index = (++undo_index)&(MAX_MODIFY-1);
// modify it
rgb[index] = selected_rgb;
pic[index] = selected_index;
UpdateTexture (index);
InvalidateRect (skinwindow, NULL, false);
InvalidateRect (camerawindow, NULL, false);
}
void Undo (void)
{
modify_t *m;
int temp;
if (!undo_index)
return;
if (!--undo_index)
{ // back to unmodified state
modified = false;
SetWindowText (skinwindow, skin_filename);
}
m = &modify[undo_index];
// modify it
temp = pic[m->offset];
pic[m->offset] = m->oldvalue;
rgb[m->offset] = palette[m->oldvalue*3] +
(palette[m->oldvalue*3+1]<<8) + (palette[m->oldvalue*3+2]<<16);
m->oldvalue = temp;
UpdateTexture (m->offset);
InvalidateRect (skinwindow, NULL, false);
InvalidateRect (camerawindow, NULL, false);
}
void Redo (void)
{
modify_t *m;
int temp;
if (undo_index == modify_index)
return;
m = &modify[undo_index];
// modify it
temp = pic[m->offset];
pic[m->offset] = m->oldvalue;
rgb[m->offset] = palette[m->oldvalue*3] +
(palette[m->oldvalue*3+1]<<8) + (palette[m->oldvalue*3+2]<<16);
m->oldvalue = temp;
UpdateTexture (m->offset);
InvalidateRect (skinwindow, NULL, false);
InvalidateRect (camerawindow, NULL, false);
if (!undo_index++)
{ // modified again
char text[1024];
modified = true;
sprintf (text, "%s *", skin_filename);
SetWindowText (skinwindow, text);
}
}
//===================================================================
/*
=============
Skin_SaveFile
Load a skin texture and the base.tri from the same directory
=============
*/
void Skin_SaveFile (char *name)
{
byte *data;
int i, j;
char backup[1024];
// back up the current file if it exists
sprintf (backup, "%s.bak", name);
remove (backup);
rename (name, backup);
modified = false;
modified_past_autosave = false;
modify_index = undo_index = 0;
SetWindowText (skinwindow, skin_filename);
data = malloc(skin_width*skin_height);
for (i=0 ; i<skin_height ; i++)
memcpy (data + i*skin_width, pic + i*width2, skin_width);
Save256Image (name, data, palette, skin_width, skin_height);
free(data);
}
/*
=============
Expand256Texture
=============
*/
void Expand256Texture (void)
{
int i, j;
int p;
memset (rgb, 0, sizeof(rgb));
for (i=0 ; i<skin_height ; i++)
{
for (j=0 ; j<skin_width ; j++)
{
p = pic[i*width2+j];
rgb[i*width2+j] = (palette[p*3+0]<<0) + (palette[p*3+1]<<8) + (palette[p*3+2]<<16);
}
}
BindTextureEXT (GL_TEXTURE_2D, TEXTURE_SKIN);
glTexImage2D (GL_TEXTURE_2D, 0, 3, width2, height2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgb);
}
void SetSizes (int width, int height)
{
int i;
if (width < 32)
width = 16;
if (height < 32)
height = 16;
skin_width = width;
skin_height = height;
if (skin_width > 1024 || skin_height > 512)
Sys_Error ("Skin file is too large");
width2 = 1;
height2 = 1;
for (i=0 ; i<12 ; i++)
{
if (width2 < skin_width)
width2<<=1;
if (height2 < skin_height)
height2<<=1;
}
// compatability shit for auto sizing of old skins
if (skin_width != 320 || skin_height != 200)
{
skinwidth = skin_width;
skinheight = skin_height;
}
else
{
skinwidth = 0;
skinheight = 0;
}
}
/*
=============
Skin_LoadFile
Load a skin texture and the base.tri from the same directory
=============
*/
void Skin_LoadFile (char *name)
{
int i, j, p;
byte *lbmpic;
byte *lbmpal;
char trifile[1024];
int width, height;
modified = false;
modified_past_autosave = false;
modify_index = undo_index = 0;
strcpy (skin_filename, name);
SetWindowText (skinwindow, skin_filename);
//
// read the texture
//
Load256Image (skin_filename, &lbmpic, &lbmpal, &width, &height);
memcpy (palette, lbmpal, sizeof(palette));
free (lbmpal);
SetSizes (width, height);
memset (pic, 0, sizeof(pic));
for (i=0 ; i<skin_height ; i++)
{
for (j=0 ; j<skin_width ; j++)
{
p = lbmpic[i*skin_width + j];
pic[i*width2+j] = p;
}
}
free (lbmpic);
Expand256Texture ();
InitIndexTexture ();
Pal_SetIndex (selected_index);
//
// read the polfile and
// generate the texture coordinates
//
strcpy (trifile, skin_filename);
StripExtension (trifile);
strcat (trifile, ".tri");
if (FileExists (trifile))
{
LoadTriFile (trifile);
CalcTmCoords ();
}
else
{
ExtractFilePath (name, trifile);
strcat (trifile, "base.tri");
if (FileExists (trifile))
{
LoadTriFile (trifile);
CalcTmCoords ();
}
}
InvalidateRect (palettewindow, NULL, false);
InvalidateRect (skinwindow, NULL, false);
InvalidateRect (camerawindow, NULL, false);
}
/*
=============
Skin_Click
=============
*/
int skin_last_index;
void Skin_Click (int x, int y, qboolean shift)
{
int index;
index = 0;
glReadBuffer (GL_BACK);
glReadPixels (x, y, 1,1, GL_RGB, GL_UNSIGNED_BYTE, &index);
index--;
if (index == -1)
return;
if (index >= width2*height2)
return;
if (index == skin_last_index)
return; // in same pixel
skin_last_index = index;
if (shift)
{
Pal_SetIndex (pic[index]);
return;
}
SetSkin (index, selected_index);
UpdateWindow (skinwindow);
}
void DrawModelST (void)
{
int i, j;
glColor4f (1,1,1,1);
glBegin (GL_TRIANGLES);
for (i=0 ; i<numfaces ; i++)
{
for (j=0 ; j<3 ; j++)
{
glVertex2f (tmcoords[i][j][0]*width2, (1-tmcoords[i][j][1])*height2);
}
}
glEnd ();
}
void DrawSkin (void)
{
glBegin (GL_POLYGON);
glTexCoord2f (0,1);
glVertex2f (0,0);
glTexCoord2f (0,0);
glVertex2f (0,height2);
glTexCoord2f (1,0);
glVertex2f (width2,height2);
glTexCoord2f (1,1);
glVertex2f (width2,0);
glEnd ();
}
void Skin_Draw (void)
{
int x, y;
float aspect;
float xs, ys;
int c;
//
// draw it
//
if (skin_z < 20)
skin_z = 20;
glViewport (0,0,skinw_width, skinw_height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (90, (float)skinw_width/skinw_height, 2, 16384);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt (skin_x, skin_y, skin_z, skin_x, skin_y, skin_z-1, 0, 1, 0);
glClearColor (0.3,0.3,0.3,1);
glClear (GL_COLOR_BUFFER_BIT);
glDisable (GL_DEPTH_TEST);
glDisable (GL_CULL_FACE);
glEnable (GL_TEXTURE_2D);
glColor4f (1,1,1,1);
DrawSkin ();
if (skin_lines)
{
glDisable (GL_TEXTURE_2D);
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
DrawModelST ();
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glEnable (GL_TEXTURE_2D);
}
SwapBuffers(skindc);
// now fill the back buffer with the index texture
glClearColor (0,0,0,0);
glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
BindTextureEXT (GL_TEXTURE_2D, TEXTURE_INDEX);
DrawSkin ();
BindTextureEXT (GL_TEXTURE_2D, TEXTURE_SKIN);
}
/*
============
Skin_WndProc
============
*/
LONG WINAPI Skin_WndProc (
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
LONG lRet = 1;
int fwKeys, xPos, yPos;
RECT rect;
GetClientRect(hWnd, &rect);
skinw_width = rect.right-rect.left;
skinw_height = rect.bottom-rect.top;
switch (uMsg)
{
case WM_CREATE:
skindc = GetDC(hWnd);
bSetupPixelFormat(skindc);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
if (!wglMakeCurrent( skindc, baseRC ))
Sys_Error ("wglMakeCurrent failed");
Skin_Draw ();
EndPaint(hWnd, &ps);
}
break;
case WM_LBUTTONDOWN:
skin_last_index = -1;
draw:
if (GetTopWindow(mainwindow) != hWnd)
BringWindowToTop(hWnd);
SetFocus (skinwindow);
SetCapture (skinwindow);
fwKeys = wParam; // key flags
xPos = (short)LOWORD(lParam); // horizontal position of cursor
yPos = (short)HIWORD(lParam); // vertical position of cursor
yPos = (int)rect.bottom - 1 - yPos;
if (!wglMakeCurrent( skindc, baseRC ))
Sys_Error ("wglMakeCurrent failed");
Skin_Click (xPos, yPos, !!(wParam&(MK_SHIFT|MK_CONTROL)) );
break;
case WM_MBUTTONUP:
case WM_RBUTTONUP:
case WM_LBUTTONUP:
fwKeys = wParam; // key flags
if (! (fwKeys & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON)))
ReleaseCapture ();
break;
case WM_MOUSEMOVE:
{
static int oldx, oldy;
int dx, dy;
POINT pt;
if (wParam & MK_LBUTTON)
goto draw;
GetCursorPos (&pt);
xPos = pt.x;
yPos = pt.y;
if (!(wParam & (MK_RBUTTON|MK_MBUTTON)))
{
oldx = xPos;
oldy = yPos;
break;
}
dx = xPos-oldx;
dy = oldy-yPos;
if (!dx && !dy)
break;
SetCursorPos (oldx, oldy);
if (wParam == (MK_RBUTTON|MK_CONTROL) )
{
if (abs(dx) > abs(dy))
skin_z += 0.25*dx;
else
skin_z += 0.25*dy;
InvalidateRect (skinwindow, NULL, false);
}
if (wParam == MK_RBUTTON)
{
skin_x -= 0.25*dx;
skin_y -= 0.25*dy;
InvalidateRect (skinwindow, NULL, false);
}
}
break;
case WM_SIZE:
InvalidateRect(camerawindow, NULL, false);
break;
case WM_NCCALCSIZE:// don't let windows copy pixels
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
return WVR_REDRAW;
case WM_CLOSE:
DestroyWindow (hWnd);
break;
default:
/* pass all unhandled messages to DefWindowProc */
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
break;
}
/* return 1 if handled message, 0 if not */
return lRet;
}
/*
==============
WSkin_Create
==============
*/
void WSkin_Create (HINSTANCE hInstance)
{
WNDCLASS wc;
/* Register the camera class */
memset (&wc, 0, sizeof(wc));
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)Skin_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = 0;
wc.lpszClassName = SKIN_WINDOW_CLASS;
if (!RegisterClass (&wc) )
Sys_Error ("RegisterClass failed");
skinwindow = CreateWindow (SKIN_WINDOW_CLASS ,
"Skin View",
QE3_STYLE,
(int)(screen_width*0.5),
(int)(screen_height*0.2),
(int)(screen_width*0.5),
(int)(screen_height*0.8), // size
mainwindow, // parent window
0, // no menu
hInstance,
0);
if (!skinwindow)
Error ("Couldn't create skinwindow");
// RestoreWindowState(palettewindow, "palettewindow");
ShowWindow (skinwindow, SW_SHOWDEFAULT);
}
/*
===================================================================
SKIN RESAMPLING
===================================================================
*/
HWND resamplewindow;
HDC resampledc;
#define RESAMPLE_WINDOW_CLASS "TPResample"
/*
============
Resample_WndProc
============
*/
LONG WINAPI Resample_WndProc (
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
resampledc = GetDC(hWnd);
bSetupPixelFormat(resampledc);
break;
}
return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
/*
==============
ResampleWindow
==============
*/
void ResampleWindow (HINSTANCE hInstance)
{
WNDCLASS wc;
static qboolean registered;
if (!registered)
{
registered = true;
/* Register the camera class */
memset (&wc, 0, sizeof(wc));
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)Resample_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = 0;
wc.lpszClassName = RESAMPLE_WINDOW_CLASS;
if (!RegisterClass (&wc) )
Sys_Error ("RegisterClass failed");
}
resamplewindow = CreateWindow (RESAMPLE_WINDOW_CLASS ,
"ResampleWindow",
WS_OVERLAPPED,
0, 0, width2+32, height2+32, // size
NULL, // parent window
0, // no menu
hInstance,
0);
if (!resamplewindow)
Error ("Couldn't create skinwindow");
ShowWindow (resamplewindow, SW_SHOWDEFAULT);
}
void OutlineTexture (byte *pic)
{
int i, j;
int x, y;
int empty;
byte oldpic[1024*512];
memcpy (oldpic, pic, width2*height2);
empty = oldpic[0];
for (i=0 ; i<height2 ; i++)
{
for (j=0 ; j<width2 ; j++)
{
if (oldpic[i*width2+j] != empty)
continue;
for (x=-1 ; x<=1 ; x++)
{
for (y=-1 ; y<=1 ; y++)
{
if (i+y < 0 || i+y >= height2)
continue;
if (j+x < 0 || j+x >= width2)
continue;
if (oldpic[(i+y)*width2 + j+x] != empty)
{
pic[i*width2+j] = oldpic[(i+y)*width2 + j+x];
goto done;
}
}
}
done: ;
}
}
}
void ResampleSkin (void)
{
int i, j;
static float oldtmcoords[10000][3][2];
static int newindex[1024*512];
static byte oldpic[1024*512];
// open a window of the texture size
ResampleWindow (main_instance);
// get new S/T from current frame
memcpy (oldtmcoords, tmcoords, numfaces*3*2*4);
CalcTmCoords ();
// draw all the triangles with the index texture
if (!wglMakeCurrent( resampledc, baseRC ))
Sys_Error ("wglMakeCurrent failed");
glViewport (0,0,width2, height2);
glClearColor (0,0,0,0);
glClear (GL_COLOR_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, width2, 0, height2, -100, 100);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glColor4f (1,1,1,1);
glDisable (GL_DEPTH_TEST);
glDisable (GL_CULL_FACE);
BindTextureEXT (GL_TEXTURE_2D, TEXTURE_INDEX);
#if 0
glDisable(GL_TEXTURE_2D);
glBegin (GL_LINE_LOOP);
glVertex3f (1,1,10);
glVertex3f (skin_width-1,0,10);
glVertex3f (skin_width-1,skin_height-1,10);
glVertex3f (1,skin_height-1,10);
glEnd ();
glEnable(GL_TEXTURE_2D);
#endif
glBegin (GL_TRIANGLES);
for (i=0 ; i<numfaces ; i++)
{
for (j=0 ; j<3 ; j++)
{
glTexCoord2f (oldtmcoords[i][j][0], oldtmcoords[i][j][1]);
glVertex3f (tmcoords[i][j][0]*width2, tmcoords[i][j][1]*height2, 10);
}
}
glEnd ();
SwapBuffers (resampledc);
// build the new color texture
memcpy (oldpic, pic, width2*height2);
glReadBuffer (GL_FRONT);
glReadPixels (0,0,width2,height2,GL_RGBA,GL_UNSIGNED_BYTE, &newindex);
for (i=0 ; i<height2 ; i++)
for (j=0 ; j<width2 ; j++)
pic[i*width2+j] = oldpic[newindex[i*width2+j]&0xffffff];
// outline it
OutlineTexture (pic);
Expand256Texture ();
InvalidateRect (skinwindow, NULL, false);
InvalidateRect (camerawindow, NULL, false);
// change name
strcpy (skin_filename, tri_filename);
StripExtension (skin_filename);
strcat (skin_filename, ".lbm");
SetSkinModified ();
wglMakeCurrent (NULL, NULL);
DestroyWindow (resamplewindow);
}
/*
===================================================================
NEW SKIN
===================================================================
*/
BOOL CALLBACK NewSkinDlgProc (
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
char sz[256];
int width, height;
switch (uMsg)
{
case WM_INITDIALOG:
SetWindowText(GetDlgItem(hwndDlg, IDC_WIDTH), "320");
SetWindowText(GetDlgItem(hwndDlg, IDC_HEIGHT), "200");
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
GetWindowText(GetDlgItem(hwndDlg, IDC_WIDTH), sz, 255);
width = atoi(sz);
GetWindowText(GetDlgItem(hwndDlg, IDC_HEIGHT), sz, 255);
height = atoi(sz);
SetSizes (width, height);
EndDialog(hwndDlg, 1);
return TRUE;
case IDCANCEL:
EndDialog(hwndDlg, 0);
return TRUE;
}
}
return FALSE;
}
void NewSkin (void)
{
int i, j;
byte *buf;
if (!DialogBox(main_instance, (char *)IDD_NEWSKIN, mainwindow, NewSkinDlgProc))
return;
// open a window of the texture size
ResampleWindow (main_instance);
// get new S/T from current frame
CalcTmCoords ();
// draw all the triangles
if (!wglMakeCurrent( resampledc, baseRC ))
Sys_Error ("wglMakeCurrent failed");
glViewport (0,0,width2, height2);
glClearColor (0,0,0,0);
glClear (GL_COLOR_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, width2, 0, height2, -100, 100);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glColor4f (1,1,1,1);
glDisable (GL_DEPTH_TEST);
glDisable (GL_CULL_FACE);
glDisable (GL_TEXTURE_2D);
for (i=0 ; i<numfaces ; i++)
{
glColor3f ((i&255)/255.0, (i&255)/255.0, (i&255)/255.0);
glBegin (GL_TRIANGLES);
for (j=0 ; j<3 ; j++)
glVertex3f (tmcoords[i][j][0]*width2, tmcoords[i][j][1]*height2, 10);
glEnd ();
}
SwapBuffers (resampledc);
// build the new color texture
glReadBuffer (GL_FRONT);
buf = malloc(width2*height2*4);
glReadPixels (0,0,width2,height2,GL_RGBA,GL_UNSIGNED_BYTE, buf);
for (i=0 ; i<width2*height2 ; i++)
pic[i] = buf[i*4];
free (buf);
// outline it
OutlineTexture (pic);
Expand256Texture ();
InitIndexTexture ();
InvalidateRect (skinwindow, NULL, false);
InvalidateRect (camerawindow, NULL, false);
// change name
strcpy (skin_filename, tri_filename);
StripExtension (skin_filename);
strcat (skin_filename, ".lbm");
SetSkinModified ();
wglMakeCurrent (NULL, NULL);
DestroyWindow (resamplewindow);
}