Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

SurfaceDlg.cpp (24415B)


      1 /*
      2 ===========================================================================
      3 Copyright (C) 1999-2005 Id Software, Inc.
      4 
      5 This file is part of Quake III Arena source code.
      6 
      7 Quake III Arena source code is free software; you can redistribute it
      8 and/or modify it under the terms of the GNU General Public License as
      9 published by the Free Software Foundation; either version 2 of the License,
     10 or (at your option) any later version.
     11 
     12 Quake III Arena source code is distributed in the hope that it will be
     13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with Foobar; if not, write to the Free Software
     19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     20 ===========================================================================
     21 */
     22 // SurfaceDlg.cpp : implementation file
     23 //
     24 
     25 #include "stdafx.h"
     26 #include "Radiant.h"
     27 #include "SurfaceDlg.h"
     28 #include "PrefsDlg.h"
     29 #include "mainfrm.h"
     30 #include "TextureLayout.h"
     31 
     32 #ifdef _DEBUG
     33 #define new DEBUG_NEW
     34 #undef THIS_FILE
     35 static char THIS_FILE[] = __FILE__;
     36 #endif
     37 
     38 /////////////////////////////////////////////////////////////////////////////
     39 // surface properties plugin
     40 // global flag for surface properties plugin is g_qeglobals.bSurfacePropertiesPlugin
     41 _QERPlugSurfaceTable g_SurfaceTable;
     42 
     43 /////////////////////////////////////////////////////////////////////////////
     44 // CSurfaceDlg dialog
     45 
     46 CSurfaceDlg g_dlgSurface;
     47 
     48 
     49 CSurfaceDlg::CSurfaceDlg(CWnd* pParent /*=NULL*/)
     50 	: CDialog(CSurfaceDlg::IDD, pParent)
     51 {
     52 	//{{AFX_DATA_INIT(CSurfaceDlg)
     53 	m_nHeight = 1;
     54 	m_nWidth = 1;
     55 	//}}AFX_DATA_INIT
     56 }
     57 
     58 
     59 void CSurfaceDlg::DoDataExchange(CDataExchange* pDX)
     60 {
     61 	CDialog::DoDataExchange(pDX);
     62 	//{{AFX_DATA_MAP(CSurfaceDlg)
     63 	DDX_Control(pDX, IDC_SPIN_WIDTH, m_wndWidth);
     64 	DDX_Control(pDX, IDC_SPIN_HEIGHT, m_wndHeight);
     65 	DDX_Control(pDX, IDC_SPIN_VSHIFT, m_wndVShift);
     66 	DDX_Control(pDX, IDC_SPIN_VSCALE, m_wndVScale);
     67 	DDX_Control(pDX, IDC_SPIN_ROTATE, m_wndRotate);
     68 	DDX_Control(pDX, IDC_SPIN_HSHIFT, m_wndHShift);
     69 	DDX_Control(pDX, IDC_SPIN_HSCALE, m_wndHScale);
     70 	DDX_Text(pDX, IDC_EDIT_HEIGHT, m_nHeight);
     71 	DDV_MinMaxInt(pDX, m_nHeight, 1, 32);
     72 	DDX_Text(pDX, IDC_EDIT_WIDTH, m_nWidth);
     73 	DDV_MinMaxInt(pDX, m_nWidth, 1, 32);
     74 	//}}AFX_DATA_MAP
     75 }
     76 
     77 
     78 BEGIN_MESSAGE_MAP(CSurfaceDlg, CDialog)
     79 	//{{AFX_MSG_MAP(CSurfaceDlg)
     80 	ON_WM_HSCROLL()
     81 	ON_WM_KEYDOWN()
     82 	ON_WM_VSCROLL()
     83 	ON_BN_CLICKED(IDAPPLY, OnApply)
     84 	ON_WM_CLOSE()
     85 	ON_WM_DESTROY()
     86 	ON_BN_CLICKED(ID_BTN_CANCEL, OnBtnCancel)
     87 	ON_BN_CLICKED(IDC_BTN_COLOR, OnBtnColor)
     88 	ON_WM_CTLCOLOR()
     89 	ON_WM_CREATE()
     90 	ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HSHIFT, OnDeltaPosSpin)
     91 	ON_BN_CLICKED(IDC_BTN_PATCHDETAILS, OnBtnPatchdetails)
     92 	ON_BN_CLICKED(IDC_BTN_PATCHNATURAL, OnBtnPatchnatural)
     93 	ON_BN_CLICKED(IDC_BTN_PATCHRESET, OnBtnPatchreset)
     94 	ON_BN_CLICKED(IDC_BTN_PATCHFIT, OnBtnPatchfit)
     95 	ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HSCALE, OnDeltaPosSpin)
     96 	ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_ROTATE, OnDeltaPosSpin)
     97 	ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_VSCALE, OnDeltaPosSpin)
     98 	ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_VSHIFT, OnDeltaPosSpin)
     99 	ON_BN_CLICKED(IDC_BTN_AXIAL, OnBtnAxial)
    100 	ON_BN_CLICKED(IDC_BTN_BRUSHFIT, OnBtnBrushfit)
    101 	ON_BN_CLICKED(IDC_BTN_FACEFIT, OnBtnFacefit)
    102 	//}}AFX_MSG_MAP
    103 END_MESSAGE_MAP()
    104 
    105 /////////////////////////////////////////////////////////////////////////////
    106 // CSurfaceDlg message handlers
    107 
    108 
    109 /*
    110 ===================================================
    111 
    112   SURFACE INSPECTOR
    113 
    114 ===================================================
    115 */
    116 
    117 texdef_t	g_old_texdef;
    118 texdef_t	g_patch_texdef;
    119 HWND		g_surfwin = NULL;
    120 qboolean	g_changed_surface;
    121 
    122 int	g_checkboxes[64] = { 
    123 	IDC_CHECK1, IDC_CHECK2, IDC_CHECK3, IDC_CHECK4, 
    124 	IDC_CHECK5, IDC_CHECK6, IDC_CHECK7, IDC_CHECK8, 
    125 	IDC_CHECK9, IDC_CHECK10, IDC_CHECK11, IDC_CHECK12, 
    126 	IDC_CHECK13, IDC_CHECK14, IDC_CHECK15, IDC_CHECK16,
    127 	IDC_CHECK17, IDC_CHECK18, IDC_CHECK19, IDC_CHECK20,
    128 	IDC_CHECK21, IDC_CHECK22, IDC_CHECK23, IDC_CHECK24,
    129 	IDC_CHECK25, IDC_CHECK26, IDC_CHECK27, IDC_CHECK28,
    130 	IDC_CHECK29, IDC_CHECK30, IDC_CHECK31, IDC_CHECK32,
    131 
    132 	IDC_CHECK33, IDC_CHECK34, IDC_CHECK35, IDC_CHECK36,
    133 	IDC_CHECK37, IDC_CHECK38, IDC_CHECK39, IDC_CHECK40,
    134 	IDC_CHECK41, IDC_CHECK42, IDC_CHECK43, IDC_CHECK44,
    135 	IDC_CHECK45, IDC_CHECK46, IDC_CHECK47, IDC_CHECK48,
    136 	IDC_CHECK49, IDC_CHECK50, IDC_CHECK51, IDC_CHECK52,
    137 	IDC_CHECK53, IDC_CHECK54, IDC_CHECK55, IDC_CHECK56,
    138 	IDC_CHECK57, IDC_CHECK58, IDC_CHECK59, IDC_CHECK60,
    139 	IDC_CHECK61, IDC_CHECK62, IDC_CHECK63, IDC_CHECK64
    140  };
    141 
    142 /*
    143 ==============
    144 SetTexMods
    145 
    146 Set the fields to the current texdef
    147 if one face selected -> will read this face texdef, else current texdef
    148 if only patches selected, will read the patch texdef
    149 ===============
    150 */
    151 
    152 bool g_bNewFace = false;
    153 bool g_bNewApplyHandling = false;
    154 bool g_bGatewayhack = false;
    155 
    156 void CSurfaceDlg::SetTexMods()
    157 {
    158 	char	sz[128];
    159 	texdef_t *pt;
    160 	brushprimit_texdef_t	*bpt;
    161 	// local copy if a width=2 height=2 qtetxture_t is needed
    162 	brushprimit_texdef_t	local_bp;
    163 	int		i;
    164 
    165 	if (!g_surfwin)
    166 		return;
    167 
    168 	m_bPatchMode = false;
    169 
    170 	if (OnlyPatchesSelected())
    171 	{
    172 		pt = &g_qeglobals.d_texturewin.texdef;
    173 		if (QE_SingleBrush())
    174     {
    175 			//strcpy(g_patch_texdef.name, Patch_GetTextureName());
    176 			g_patch_texdef.SetName(Patch_GetTextureName());
    177     }
    178 		else
    179     {
    180 			//strcpy(g_patch_texdef.name, pt->name);
    181 			g_patch_texdef.SetName(pt->name);
    182     }
    183 		g_patch_texdef.contents = pt->contents;
    184 		g_patch_texdef.flags = pt->flags;
    185 		g_patch_texdef.value = pt->value;
    186 		pt = &g_patch_texdef;
    187 		m_bPatchMode = true;
    188 	}
    189 	else
    190 	{
    191 		if (g_bNewFace && g_ptrSelectedFaces.GetSize() > 0)
    192 		{
    193       face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
    194 			pt = &selFace->texdef;
    195 			if (g_qeglobals.m_bBrushPrimitMode)
    196 			{
    197 				// compute a texture matrix related to the default matrix width=2 height=2
    198 				ConvertTexMatWithQTexture( &selFace->brushprimit_texdef, selFace->d_texture, &local_bp, NULL );
    199 				bpt = &local_bp;
    200 			}
    201 		}
    202 		else
    203 		{
    204 			pt = &g_qeglobals.d_texturewin.texdef;
    205 			if (g_qeglobals.m_bBrushPrimitMode)
    206 			{
    207 				bpt = &g_qeglobals.d_texturewin.brushprimit_texdef;
    208 			}
    209 		}
    210 		// brush primitive mode : compute fake shift scale rot representation
    211 		if (g_qeglobals.m_bBrushPrimitMode)
    212 			TexMatToFakeTexCoords( bpt->coords, m_shift, &m_rotate, m_scale );
    213 	}
    214 
    215 	SendMessage (WM_SETREDRAW, 0, 0);
    216 
    217 	::SetWindowText(GetDlgItem(IDC_TEXTURE)->GetSafeHwnd(), pt->name);
    218 
    219 	if (m_bPatchMode)
    220 		sprintf(sz, "%4.6f", pt->shift[0]);
    221 	else
    222 		if (g_qeglobals.m_bBrushPrimitMode)
    223 			sprintf(sz, "%d", (int)m_shift[0]);
    224 		else
    225 			sprintf(sz, "%d", (int)pt->shift[0]);
    226 	::SetWindowText(GetDlgItem(IDC_HSHIFT)->GetSafeHwnd(), sz);
    227 
    228 	if (m_bPatchMode)
    229 		sprintf(sz, "%4.6f", pt->shift[1]);
    230 	else
    231 		if (g_qeglobals.m_bBrushPrimitMode)
    232 			sprintf(sz, "%d", (int)m_shift[1]);
    233 		else
    234 			sprintf(sz, "%d", (int)pt->shift[1]);
    235 	::SetWindowText(GetDlgItem(IDC_VSHIFT)->GetSafeHwnd(), sz);
    236 
    237 	sprintf(sz, m_bPatchMode ? "%4.6f" : "%4.6f", g_qeglobals.m_bBrushPrimitMode ? m_scale[0] : pt->scale[0]);
    238 	::SetWindowText(GetDlgItem(IDC_HSCALE)->GetSafeHwnd(), sz);
    239 
    240 	sprintf(sz, m_bPatchMode ? "%4.6f" : "%4.6f", g_qeglobals.m_bBrushPrimitMode ? m_scale[1] : pt->scale[1]);
    241 	::SetWindowText(GetDlgItem(IDC_VSCALE)->GetSafeHwnd(), sz);
    242 
    243 	//++timo compute BProtate as int ..
    244 	sprintf(sz, "%d", g_qeglobals.m_bBrushPrimitMode ? (int)m_rotate : (int)pt->rotate);
    245 	::SetWindowText(GetDlgItem(IDC_ROTATE)->GetSafeHwnd(), sz);
    246 
    247 	sprintf(sz, "%d", (int)pt->value);
    248 	::SetWindowText(GetDlgItem(IDC_VALUE)->GetSafeHwnd(), sz);
    249 
    250 	for (i=0 ; i<32 ; i++)
    251 		::SendMessage(GetDlgItem(g_checkboxes[i])->GetSafeHwnd(), BM_SETCHECK, !!(pt->flags&(1<<i)), 0 );
    252 	for (i=0 ; i<32 ; i++)
    253 		::SendMessage(GetDlgItem(g_checkboxes[32+i])->GetSafeHwnd(), BM_SETCHECK, !!(pt->contents&(1<<i)), 0 );
    254 
    255 	SendMessage (WM_SETREDRAW, 1, 0);
    256 	InvalidateRect (NULL, true);
    257 }
    258 
    259 void CSurfaceDlg::GrabPatchMods()
    260 {
    261 	char	sz[128];
    262 	int i;
    263 	bool b;
    264 	texdef_t *pt = & g_patch_texdef;
    265 
    266   ::GetWindowText (GetDlgItem(IDC_HSHIFT)->GetSafeHwnd(), sz, 127);
    267 	pt->shift[0] = atof(sz);
    268 
    269   ::GetWindowText (GetDlgItem(IDC_VSHIFT)->GetSafeHwnd(), sz, 127);
    270 	pt->shift[1] = atof(sz);
    271 
    272   ::GetWindowText(GetDlgItem(IDC_HSCALE)->GetSafeHwnd(), sz, 127);
    273 	pt->scale[0] = atof(sz);
    274 
    275   ::GetWindowText(GetDlgItem(IDC_VSCALE)->GetSafeHwnd(), sz, 127);
    276 	pt->scale[1] = atof(sz);
    277 
    278   ::GetWindowText(GetDlgItem(IDC_ROTATE)->GetSafeHwnd(), sz, 127);
    279 	pt->rotate = atof(sz);
    280 
    281   ::GetWindowText(GetDlgItem(IDC_VALUE)->GetSafeHwnd(), sz, 127);
    282 	pt->value = atof(sz);
    283 
    284 	pt->flags = 0;
    285 	for (i=0 ; i<32 ; i++)
    286 	{
    287     b = ::SendMessage(GetDlgItem(g_checkboxes[i])->GetSafeHwnd(), BM_GETCHECK, 0, 0);
    288 		if (b != 1 && b != 0)
    289 			continue;
    290 		pt->flags |= b<<i;
    291 	}
    292 
    293 	pt->contents = 0;
    294 	for (i=0 ; i<32 ; i++)
    295 	{
    296     b = ::SendMessage(GetDlgItem(g_checkboxes[32+i])->GetSafeHwnd(), BM_GETCHECK, 0, 0);
    297 		if (b != 1 && b != 0)
    298 			continue;
    299 		pt->contents |= b<<i;
    300 	}
    301 
    302 }
    303 
    304 /*
    305 ==============
    306 GetTexMods
    307 
    308 Reads the fields to get the current texdef
    309 in brush primitive mode, grab the fake shift scale rot and compute a new texture matrix
    310 ===============
    311 */
    312 void CSurfaceDlg::GetTexMods()
    313 {
    314 	char	sz[128];
    315 	texdef_t *pt;
    316 	int		b;
    317 	int		i;
    318 
    319 	m_bPatchMode = false;
    320 
    321 	if (OnlyPatchesSelected())
    322 	{
    323 		pt = &g_qeglobals.d_texturewin.texdef;
    324 		m_bPatchMode = true;
    325 	}
    326 	else
    327 	{
    328 		if (g_bNewFace && g_ptrSelectedFaces.GetSize() > 0)
    329     {
    330       face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
    331 			pt = &selFace->texdef;
    332     }
    333 		else
    334     {
    335 			pt = &g_qeglobals.d_texturewin.texdef;
    336     }
    337 	}
    338 
    339 	::GetWindowText (GetDlgItem(IDC_TEXTURE)->GetSafeHwnd(), sz, 127);
    340 	//strncpy (pt->name, sz, sizeof(pt->name)-1);
    341 	pt->SetName(sz);
    342 	if (pt->name[0] <= ' ')
    343 	{
    344 		//strcpy (pt->name, "none");
    345 		pt->SetName("none");
    346 		::SetWindowText(GetDlgItem(IDC_TEXTURE)->GetSafeHwnd(), pt->name);
    347 	}
    348 
    349 	::GetWindowText (GetDlgItem(IDC_HSHIFT)->GetSafeHwnd(), sz, 127);
    350 	( g_qeglobals.m_bBrushPrimitMode ? m_shift[0] : pt->shift[0] ) = atof(sz);
    351 
    352 	::GetWindowText (GetDlgItem(IDC_VSHIFT)->GetSafeHwnd(), sz, 127);
    353 	( g_qeglobals.m_bBrushPrimitMode ? m_shift[1] : pt->shift[1] ) = atof(sz);
    354 
    355 	::GetWindowText(GetDlgItem(IDC_HSCALE)->GetSafeHwnd(), sz, 127);
    356 	( g_qeglobals.m_bBrushPrimitMode ? m_scale[0] : pt->scale[0] ) = atof(sz);
    357 
    358 	::GetWindowText(GetDlgItem(IDC_VSCALE)->GetSafeHwnd(), sz, 127);
    359 	( g_qeglobals.m_bBrushPrimitMode ? m_scale[1] : pt->scale[1] ) = atof(sz);
    360 
    361 	::GetWindowText(GetDlgItem(IDC_ROTATE)->GetSafeHwnd(), sz, 127);
    362 	( g_qeglobals.m_bBrushPrimitMode ? m_rotate : pt->rotate ) = atof(sz);
    363 
    364 	::GetWindowText(GetDlgItem(IDC_VALUE)->GetSafeHwnd(), sz, 127);
    365 	pt->value = atof(sz);
    366 
    367 	pt->flags = 0;
    368 	for (i=0 ; i<32 ; i++)
    369 	{
    370 		b = ::SendMessage(GetDlgItem(g_checkboxes[i])->GetSafeHwnd(), BM_GETCHECK, 0, 0);
    371 		if (b != 1 && b != 0)
    372 			continue;
    373 		pt->flags |= b<<i;
    374 	}
    375 
    376 	pt->contents = 0;
    377 	for (i=0 ; i<32 ; i++)
    378 	{
    379 		b = ::SendMessage(GetDlgItem(g_checkboxes[32+i])->GetSafeHwnd(), BM_GETCHECK, 0, 0);
    380 		if (b != 1 && b != 0)
    381 			continue;
    382 		pt->contents |= b<<i;
    383 	}
    384 
    385 	g_changed_surface = true;
    386 
    387 	// a local copy of the texture matrix, given for a qtexture_t with width=2 height=2
    388 	brushprimit_texdef_t	local_bp;
    389 	brushprimit_texdef_t	*bpt;
    390 	if (g_qeglobals.m_bBrushPrimitMode)
    391 	{
    392     face_t *selFace = NULL;
    393 		if (g_bNewFace && g_ptrSelectedFaces.GetSize() > 0)
    394     {
    395       selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
    396 			bpt = &selFace->brushprimit_texdef;
    397     }
    398 		else
    399     {
    400 			bpt = &g_qeglobals.d_texturewin.brushprimit_texdef;
    401     }
    402 		// compute texture matrix
    403 		// the matrix returned must be understood as a qtexture_t with width=2 height=2
    404 		FakeTexCoordsToTexMat( m_shift, m_rotate, m_scale, local_bp.coords );
    405 		// copy the texture matrix in the global struct
    406 		// fit the qtexture if we have a face selected, otherwise g_qeglobals.d_texturewin.brushprimit_texdef uses the basic qtexture_t with width=2 height=2
    407 
    408 		ConvertTexMatWithQTexture( &local_bp, NULL, bpt, ( ( g_bNewFace && selFace ) ? selFace->d_texture : NULL ) );
    409 	}
    410 	Select_SetTexture(pt,&local_bp);
    411 
    412   //if (m_bPatchMode)
    413   //{
    414   //  Patch_SetTextureInfo(pt);
    415   //}
    416 
    417 }
    418 
    419 /*
    420 =================
    421 UpdateSpinners
    422 =================
    423 */
    424 
    425 void CSurfaceDlg::UpdateSpinners(bool bUp, int nID)
    426 {
    427 	texdef_t *pt;
    428   texdef_t td;
    429 
    430   if (m_bPatchMode)
    431   {
    432     td.rotate = 0.0;
    433     td.scale[0] = td.scale[1] = 0.0;
    434     td.shift[0] = td.shift[1] = 0.0;
    435     GrabPatchMods();
    436 
    437     pt = &g_patch_texdef;
    438     td.contents = pt->contents;
    439     td.flags = pt->flags;
    440     td.value = pt->value;
    441 
    442     if (nID == IDC_SPIN_ROTATE)
    443 	  {
    444 		  if (bUp)
    445 			  td.rotate = pt->rotate;
    446 		  else
    447 			  td.rotate = -pt->rotate;
    448 	  }
    449     else if (nID == IDC_SPIN_HSCALE)
    450 	  {
    451 		  if (bUp)
    452 			  td.scale[0] = 1-pt->scale[0];
    453 		  else
    454 			  td.scale[0] = 1+pt->scale[0];
    455 	  }
    456     else if (nID == IDC_SPIN_VSCALE)
    457 	  {
    458 		  if (bUp)
    459 			  td.scale[1] = 1-pt->scale[1];
    460 		  else
    461 			  td.scale[1] = 1+pt->scale[1];
    462 	  } 
    463 	  
    464     else if (nID == IDC_SPIN_HSHIFT)
    465 	  {
    466 		  if (bUp)
    467 			  td.shift[0] = pt->shift[0];
    468 		  else
    469 			  td.shift[0] = -pt->shift[0];
    470 	  }
    471     else if (nID == IDC_SPIN_VSHIFT)
    472 	  {
    473 		  if (bUp)
    474 			  td.shift[1] = pt->shift[1];
    475 		  else
    476 			  td.shift[1] = -pt->shift[1];
    477 	  }
    478     pt = &g_qeglobals.d_texturewin.texdef;
    479     Patch_SetTextureInfo(&td);
    480   }
    481 	else
    482 	{
    483 		// in brush primitive mode, will read up-to-date m_shift m_rotate m_scale
    484 		GetTexMods ();
    485 		if (g_bNewFace && g_ptrSelectedFaces.GetSize() > 0)
    486     {
    487       face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
    488 			pt = &selFace->texdef;
    489     }
    490 		else
    491     {
    492 			pt = &g_qeglobals.d_texturewin.texdef;
    493     }
    494 		if (nID == IDC_SPIN_ROTATE)
    495 		{
    496 			if (g_qeglobals.m_bBrushPrimitMode)
    497 			{
    498 				if (bUp)
    499 					m_rotate += 45;
    500 				else
    501 					m_rotate -= 45;
    502 			}
    503 			else
    504 			{
    505 				if (bUp)
    506 					pt->rotate += 45;
    507 				else
    508 					pt->rotate -= 45;
    509 				if (pt->rotate < 0)
    510 					pt->rotate += 360;
    511 				if (pt->rotate >= 360)
    512 					pt->rotate -= 360;
    513 			}
    514 		}
    515 		else if (nID == IDC_SPIN_HSCALE)
    516 		{
    517 			if (g_qeglobals.m_bBrushPrimitMode)
    518 			{
    519 				if (bUp)
    520 					m_scale[0] += 0.1;
    521 				else
    522 					m_scale[0] -= 0.1;
    523 			}
    524 			else
    525 			{
    526 				if (bUp)
    527 					pt->scale[0] += 0.1;
    528 				else
    529 					pt->scale[0] -= 0.1;
    530 			}
    531 		}
    532 		else if (nID == IDC_SPIN_VSCALE)
    533 		{
    534 			if (g_qeglobals.m_bBrushPrimitMode)
    535 			{
    536 				if (bUp)
    537 					m_scale[1] += 0.1;
    538 				else
    539 					m_scale[1] -= 0.1;
    540 			}
    541 			else
    542 			{
    543 				if (bUp)
    544 					pt->scale[1] += 0.1;
    545 				else
    546 					pt->scale[1] -= 0.1;
    547 			}
    548 		}
    549 		else if (nID == IDC_SPIN_HSHIFT)
    550 		{
    551 			if (g_qeglobals.m_bBrushPrimitMode)
    552 			{
    553 				if (bUp)
    554 					m_shift[0] += 8;
    555 				else
    556 					m_shift[0] -= 8;
    557 			}
    558 			else
    559 			{
    560 				if (bUp)
    561 					pt->shift[0] += 8;
    562 				else
    563 					pt->shift[0] -= 8;
    564 			}
    565 		}
    566 		else if (nID == IDC_SPIN_VSHIFT)
    567 		{
    568 			if (g_qeglobals.m_bBrushPrimitMode)
    569 			{
    570 				if (bUp)
    571 					m_shift[1] += 8;
    572 				else
    573 					m_shift[1] -= 8;
    574 			}
    575 			else
    576 			{
    577 				if (bUp)
    578 					pt->shift[1] += 8;
    579 				else
    580 					pt->shift[1] -= 8;
    581 			}
    582 		}
    583 	}
    584 	// a local copy of the texture matrix, given for a qtexture_t with width=2 height=2
    585 	brushprimit_texdef_t	local_bp;
    586 	brushprimit_texdef_t	*bpt;
    587 	if (g_qeglobals.m_bBrushPrimitMode)
    588 	{
    589     face_t *selFace = NULL;
    590 		if (g_bNewFace && g_ptrSelectedFaces.GetSize() > 0)
    591     {
    592       selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
    593 			bpt = &selFace->brushprimit_texdef;
    594     }
    595 		else
    596     {
    597 			bpt = &g_qeglobals.d_texturewin.brushprimit_texdef;
    598     }
    599 		// compute texture matrix
    600 		// the matrix returned must be understood as a qtexture_t with width=2 height=2
    601 		FakeTexCoordsToTexMat( m_shift, m_rotate, m_scale, local_bp.coords );
    602 		// copy the texture matrix in the global struct
    603 		// fit the qtexture if we have a face selected, otherwise g_qeglobals.d_texturewin.brushprimit_texdef uses the basic qtexture_t with width=2 height=2
    604 		ConvertTexMatWithQTexture( &local_bp, NULL, bpt, ( ( g_bNewFace && selFace ) ? selFace->d_texture : NULL ) );
    605 	}
    606 	// brush primit : will update the widgets after reading back texture matrix and computing fake shift scale rot
    607 	SetTexMods();
    608 	g_changed_surface = true;
    609 	Select_SetTexture(pt,&local_bp);
    610 }
    611 
    612 void CSurfaceDlg::UpdateSpinners(int nScrollCode, int nPos, CScrollBar* pBar)
    613 {
    614 	texdef_t *pt;
    615 
    616 	GetTexMods ();
    617   if (g_bNewFace && g_ptrSelectedFaces.GetSize() > 0)
    618   {
    619     face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(0));
    620 		pt = &selFace->texdef;
    621   }
    622   else
    623   {
    624 	  pt = &g_qeglobals.d_texturewin.texdef;
    625   }
    626 
    627 	if ((nScrollCode != SB_LINEUP) && (nScrollCode != SB_LINEDOWN))
    628 		return;
    629 	
    630   if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_ROTATEA))
    631 	{
    632 		if (nScrollCode == SB_LINEUP)
    633 			pt->rotate += 45;
    634 		else
    635 			pt->rotate -= 45;
    636 
    637 		if (pt->rotate < 0)
    638 			pt->rotate += 360;
    639 
    640 		if (pt->rotate >= 360)
    641 			pt->rotate -= 360;
    642 	}
    643 
    644   else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_HSCALEA))
    645 	{
    646 		if (nScrollCode == SB_LINEDOWN)
    647 			pt->scale[0] -= 0.1;
    648 		else
    649 			pt->scale[0] += 0.1;
    650 	}
    651 	
    652   else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_VSCALEA))
    653 	{
    654 		if (nScrollCode == SB_LINEUP)
    655 			pt->scale[1] += 0.1;
    656 		else
    657 			pt->scale[1] -= 0.1;
    658 	} 
    659 	
    660   else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_HSHIFTA))
    661 	{
    662 		if (nScrollCode == SB_LINEDOWN)
    663 			pt->shift[0] -= 8;
    664 		else
    665 			pt->shift[0] += 8;
    666 	}
    667 	
    668   else if (pBar->GetSafeHwnd() == ::GetDlgItem(GetSafeHwnd(), IDC_VSHIFTA))
    669 	{
    670 		if (nScrollCode == SB_LINEUP)
    671 			pt->shift[1] += 8;
    672 		else
    673 			pt->shift[1] -= 8;
    674 	}
    675 
    676 	SetTexMods();
    677 	g_changed_surface = true;
    678 	//++timo if !g_qeglobals.m_bBrushPrimitMode send a NULL brushprimit_texdef
    679 	if (!g_qeglobals.m_bBrushPrimitMode)
    680 	{
    681 		Sys_Printf("Warning : non brush primitive mode call to CSurfaceDlg::GetTexMods broken\n");
    682 		Sys_Printf("          ( Select_SetTexture not called )\n");
    683 	}
    684 //	Select_SetTexture(pt);
    685 }
    686 
    687 void UpdateSurfaceDialog()
    688 {
    689 	if (g_qeglobals.bSurfacePropertiesPlugin)
    690 	{
    691 		g_SurfaceTable.m_pfnUpdateSurfaceDialog();
    692 	}
    693 	else
    694 	{
    695 		if (g_surfwin)
    696 			g_dlgSurface.SetTexMods();
    697 	}
    698 	g_pParentWnd->UpdateTextureBar();
    699 }
    700 
    701 bool ByeByeSurfaceDialog();
    702 
    703 void DoSurface (void)
    704 {
    705 	// surface properties plugin ?
    706 	if (g_qeglobals.bSurfacePropertiesPlugin)
    707 	{
    708 		g_SurfaceTable.m_pfnDoSurface();
    709 		return;
    710 	}
    711 
    712   g_bNewFace = g_PrefsDlg.m_bFace;
    713   g_bNewApplyHandling = g_PrefsDlg.m_bNewApplyHandling;
    714   g_bGatewayhack = g_PrefsDlg.m_bGatewayHack;
    715 	// save current state for cancel
    716 	g_old_texdef = g_qeglobals.d_texturewin.texdef;
    717 	g_changed_surface = false;
    718 
    719   if (g_surfwin == NULL && g_dlgSurface.GetSafeHwnd() == NULL)
    720   {
    721     g_patch_texdef.scale[0] = 0.05;
    722     g_patch_texdef.scale[1] = 0.05;
    723     g_patch_texdef.shift[0] = 0.05;
    724     g_patch_texdef.shift[1] = 0.05;
    725 	// use rotation increment from preferences
    726     g_patch_texdef.rotate = g_PrefsDlg.m_nRotation;
    727 
    728     g_dlgSurface.Create(IDD_SURFACE);
    729     CRect rct;
    730 	  LONG lSize = sizeof(rct);
    731 	  if (LoadRegistryInfo("Radiant::SurfaceWindow", &rct, &lSize))
    732       g_dlgSurface.SetWindowPos(NULL, rct.left, rct.top, 0,0, SWP_NOSIZE | SWP_SHOWWINDOW);
    733 
    734     Sys_UpdateWindows(W_ALL);
    735   }
    736   else
    737   {
    738     g_surfwin = g_dlgSurface.GetSafeHwnd();
    739 	  g_dlgSurface.SetTexMods ();
    740     g_dlgSurface.ShowWindow(SW_SHOW);
    741   }
    742 }		
    743 
    744 bool ByeByeSurfaceDialog()
    745 {
    746 	// surface properties plugin ?
    747 	if (g_qeglobals.bSurfacePropertiesPlugin)
    748 	{
    749 		return g_SurfaceTable.m_pfnByeByeSurfaceDialog();
    750 	}
    751 
    752   if (g_surfwin)
    753   {
    754     if (g_bGatewayhack)
    755       PostMessage(g_surfwin, WM_COMMAND, IDAPPLY, 0);
    756     else
    757       PostMessage(g_surfwin, WM_COMMAND, IDCANCEL, 0);
    758     return true;
    759   }
    760   else return false;
    761 }
    762 
    763 BOOL CSurfaceDlg::OnInitDialog() 
    764 {
    765 	CDialog::OnInitDialog();
    766 	
    767   g_surfwin = GetSafeHwnd();
    768 	SetTexMods ();
    769 
    770 #ifdef QUAKE3
    771   GetDlgItem(IDC_CHECK32)->SetWindowText("Curve");
    772   GetDlgItem(IDC_CHECK64)->SetWindowText("Inverted");
    773 #endif
    774 
    775   m_wndHScale.SetRange(0, 1000);
    776   m_wndVScale.SetRange(0, 1000);
    777   m_wndHShift.SetRange(0, 1000);
    778   m_wndVShift.SetRange(0, 1000);
    779   m_wndRotate.SetRange(0, 1000);
    780   m_wndWidth.SetRange(1, 32);
    781   m_wndHeight.SetRange(1, 32);
    782 
    783   LPVOID lpv = g_pParentWnd->GetPlugInMgr().GetSurfaceFlags();
    784   if (lpv != NULL)
    785   {
    786     int i = 0;
    787     char* p = reinterpret_cast<char*>(lpv);
    788     char* pBuff = new char[strlen(p)+1];
    789     strcpy(pBuff, p);
    790     char* pToken = strtok(pBuff, ";\0");
    791     while (pToken != NULL)
    792     {
    793       GetDlgItem(g_checkboxes[i++])->SetWindowText(pToken);
    794       pToken = strtok(NULL, ";\0");
    795     }
    796   }
    797 
    798   if (strstr(g_PrefsDlg.m_strWhatGame, "Quake3") != NULL) {
    799     for (int i=0 ; i < 64 ; i++) {
    800       ::EnableWindow(GetDlgItem(g_checkboxes[i])->GetSafeHwnd(), FALSE);
    801     }
    802 
    803   }
    804 
    805 	return TRUE;  // return TRUE unless you set the focus to a control
    806 	              // EXCEPTION: OCX Property Pages should return FALSE
    807 }
    808 
    809 void CSurfaceDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
    810 {
    811 	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
    812 	UpdateSpinners(nSBCode, nPos, pScrollBar);
    813   Sys_UpdateWindows(W_CAMERA);
    814 }
    815 
    816 void CSurfaceDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
    817 {
    818 	
    819 	CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
    820 }
    821 
    822 void CSurfaceDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
    823 {
    824 	CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
    825 	UpdateSpinners(nSBCode, nPos, pScrollBar);
    826 	Sys_UpdateWindows(W_CAMERA);
    827 }
    828 
    829 void CSurfaceDlg::OnApply() 
    830 {
    831 	GetTexMods ();
    832   Sys_UpdateWindows(W_CAMERA);
    833   if (g_bNewApplyHandling)
    834     OnOK();
    835 }
    836 
    837 void CSurfaceDlg::OnOK() 
    838 {
    839 	GetTexMods();
    840   g_surfwin = NULL;
    841 	CDialog::OnOK();
    842   Sys_UpdateWindows(W_ALL);
    843 }
    844 
    845 void CSurfaceDlg::OnClose() 
    846 {
    847   g_surfwin = NULL;
    848 	CDialog::OnClose();
    849 }
    850 
    851 void CSurfaceDlg::OnCancel() 
    852 {
    853   if (g_bGatewayhack)
    854     OnOK();
    855   else
    856     OnBtnCancel();
    857 }
    858 
    859 void CSurfaceDlg::OnDestroy() 
    860 {
    861   if (GetSafeHwnd())
    862   {
    863     CRect rct;
    864     GetWindowRect(rct);
    865 	  SaveRegistryInfo("Radiant::SurfaceWindow", &rct, sizeof(rct));
    866   }
    867 	CDialog::OnDestroy();
    868   g_surfwin = NULL;
    869   Sys_UpdateWindows(W_ALL);
    870 }
    871 
    872 void CSurfaceDlg::OnBtnCancel() 
    873 {
    874 	g_qeglobals.d_texturewin.texdef = g_old_texdef;
    875 	if (g_changed_surface)
    876 	{
    877 		//++timo if !g_qeglobals.m_bBrushPrimitMode send a NULL brushprimit_texdef
    878 		if (!g_qeglobals.m_bBrushPrimitMode)
    879 		{
    880 			Sys_Printf("Warning : non brush primitive mode call to CSurfaceDlg::GetTexMods broken\n");
    881 			Sys_Printf("          ( Select_SetTexture not called )\n");
    882 		}
    883 //		Select_SetTexture(&g_qeglobals.d_texturewin.texdef);
    884 	}
    885   g_surfwin = NULL;
    886   DestroyWindow();
    887 }
    888 
    889 void CSurfaceDlg::OnBtnColor() 
    890 {
    891 }
    892 
    893 HBRUSH CSurfaceDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
    894 {
    895 	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    896 	return hbr;
    897 }
    898 
    899 int CSurfaceDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    900 {
    901 	if (CDialog::OnCreate(lpCreateStruct) == -1)
    902 		return -1;
    903 	
    904 	return 0;
    905 }
    906 
    907 BOOL CSurfaceDlg::PreCreateWindow(CREATESTRUCT& cs) 
    908 {
    909 	// TODO: Add your specialized code here and/or call the base class
    910 	
    911 	return CDialog::PreCreateWindow(cs);
    912 }
    913 
    914 
    915 void CSurfaceDlg::OnDeltaPosSpin(NMHDR* pNMHDR, LRESULT* pResult) 
    916 {
    917 	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
    918   UpdateSpinners((pNMUpDown->iDelta > 0), pNMUpDown->hdr.idFrom);
    919 	*pResult = 0;
    920 }
    921 
    922 void CSurfaceDlg::OnBtnPatchdetails() 
    923 {
    924   Patch_NaturalizeSelected(true);
    925   Sys_UpdateWindows(W_ALL);
    926 }
    927 
    928 void CSurfaceDlg::OnBtnPatchnatural() 
    929 {
    930   Patch_NaturalizeSelected();
    931   Sys_UpdateWindows(W_ALL);
    932 }
    933 
    934 void CSurfaceDlg::OnBtnPatchreset() 
    935 {
    936   CTextureLayout dlg;
    937   if (dlg.DoModal() == IDOK)
    938   {
    939     Patch_ResetTexturing(dlg.m_fX, dlg.m_fY);
    940   }
    941   Sys_UpdateWindows(W_ALL);
    942 }
    943 
    944 void CSurfaceDlg::OnBtnPatchfit() 
    945 {
    946   Patch_FitTexturing();
    947   Sys_UpdateWindows(W_ALL);
    948 }
    949 
    950 void CSurfaceDlg::OnBtnAxial() 
    951 {
    952   Select_SetTexture (&g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, true);
    953 	g_changed_surface = true;
    954   SetTexMods();
    955   Sys_UpdateWindows(W_ALL);
    956 }
    957 
    958 void CSurfaceDlg::OnBtnBrushfit() 
    959 {
    960 	// TODO: Add your control notification handler code here
    961 	
    962 }
    963 
    964 void CSurfaceDlg::OnBtnFacefit() 
    965 {
    966   UpdateData(TRUE);
    967   if (g_ptrSelectedFaces.GetSize() == 0)
    968   {
    969     brush_t *b;
    970 		for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
    971     {
    972       for (face_t* pFace = b->brush_faces; pFace; pFace = pFace->next)
    973       {
    974         g_ptrSelectedFaces.Add(pFace);
    975         g_ptrSelectedFaceBrushes.Add(b);
    976       }
    977     }
    978   }
    979   Select_FitTexture(m_nHeight, m_nWidth);
    980   SetTexMods();
    981 	g_changed_surface = true;
    982   Sys_UpdateWindows(W_ALL);
    983 }