Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

Win_ent.cpp (32502B)


      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 #include "stdafx.h"
     23 #include "qe3.h"
     24 #include "entityw.h"
     25 #include "TexWnd.h"
     26 #include "WaveOpen.h"
     27 
     28 int rgIds[EntLast] = {
     29 	IDC_E_LIST,
     30 	IDC_E_COMMENT,
     31 	IDC_CHECK1,
     32 	IDC_CHECK2,
     33 	IDC_CHECK3,
     34 	IDC_CHECK4,
     35 	IDC_CHECK5,
     36 	IDC_CHECK6,
     37 	IDC_CHECK7,
     38 	IDC_CHECK8,
     39 	IDC_CHECK9,
     40 	IDC_CHECK10,
     41 	IDC_CHECK11,
     42 	IDC_CHECK12,
     43 	IDC_E_PROPS,
     44 	IDC_E_0,
     45 	IDC_E_45,
     46 	IDC_E_90,
     47 	IDC_E_135,
     48 	IDC_E_180,
     49 	IDC_E_225,
     50 	IDC_E_270,
     51 	IDC_E_315,
     52 	IDC_E_UP,
     53 	IDC_E_DOWN,
     54 	IDC_E_DELPROP,
     55 
     56 	IDC_STATIC_KEY,
     57 	IDC_E_KEY_FIELD,
     58 	IDC_STATIC_VALUE,
     59 	IDC_E_VALUE_FIELD,
     60 
     61 	IDC_E_COLOR,
     62 
     63   IDC_BTN_ASSIGNSOUND, 
     64   IDC_BTN_ASSIGNMODEL
     65 
     66 };
     67 
     68 HWND hwndEnt[EntLast];
     69 CTabCtrl g_wndTabs;
     70 
     71 int		inspector_mode;		// W_TEXTURE, W_ENTITY, or W_CONSOLE
     72 
     73 qboolean	multiple_entities;
     74 
     75 entity_t	*edit_entity;
     76 
     77 
     78 BOOL CALLBACK EntityWndProc(
     79     HWND hwndDlg,	// handle to dialog box
     80     UINT uMsg,		// message
     81     WPARAM wParam,	// first message parameter
     82     LPARAM lParam);	// second message parameter
     83 
     84 void SizeEntityDlg(int iWidth, int iHeight);
     85 void AddProp();
     86 void GetTexMods(void);
     87 
     88 
     89 LRESULT (CALLBACK* OldFieldWindowProc) (HWND, UINT, WPARAM, LPARAM);
     90 LRESULT (CALLBACK* OldEntityListWindowProc) (HWND, UINT, WPARAM, LPARAM);
     91 
     92 /*
     93 =========================
     94 FieldWndProc
     95 
     96 Just to handle tab and enter...
     97 =========================
     98 */
     99 BOOL CALLBACK FieldWndProc(
    100     HWND hwnd,
    101     UINT uMsg,
    102     WPARAM wParam,
    103     LPARAM lParam)
    104 {
    105     switch (uMsg)
    106     {
    107 	case WM_CHAR:
    108 		if (LOWORD(wParam) == VK_TAB)
    109 			return FALSE;
    110 		if (LOWORD(wParam) == VK_RETURN)
    111 			return FALSE;
    112 		if (LOWORD(wParam) == VK_ESCAPE)
    113 		{
    114 			SetFocus (g_qeglobals.d_hwndCamera);
    115 			return FALSE;
    116 		}
    117 		break;
    118 
    119 	case WM_KEYDOWN:
    120 		if (LOWORD(wParam) == VK_TAB)
    121 		{
    122 			if (hwnd == hwndEnt[EntKeyField])
    123 			{
    124 				SendMessage (hwndEnt[EntValueField], WM_SETTEXT, 0, (long)"");
    125 				SetFocus (hwndEnt[EntValueField]);
    126 			}
    127 			else
    128 				SetFocus (hwndEnt[EntKeyField]);
    129 		}
    130 		if (LOWORD(wParam) == VK_RETURN)
    131 		{
    132 			if (hwnd == hwndEnt[EntKeyField])
    133 			{
    134 				SendMessage (hwndEnt[EntValueField], WM_SETTEXT, 0, (long)"");
    135 				SetFocus (hwndEnt[EntValueField]);
    136 			}
    137 			else
    138 			{
    139 				AddProp ();
    140 				SetFocus (g_qeglobals.d_hwndCamera);
    141 			}
    142 		}
    143 		break;
    144 //	case WM_NCHITTEST:
    145 	case WM_LBUTTONDOWN:
    146 		SetFocus (hwnd);
    147 		break;
    148 	}
    149 	return CallWindowProc (OldFieldWindowProc, hwnd, uMsg, wParam, lParam);
    150 }
    151 
    152 
    153 /*
    154 =========================
    155 EntityListWndProc
    156 
    157 Just to handle enter...
    158 =========================
    159 */
    160 BOOL CALLBACK EntityListWndProc(
    161     HWND hwnd,
    162     UINT uMsg,
    163     WPARAM wParam,
    164     LPARAM lParam)
    165 {
    166     switch (uMsg)
    167     {
    168 	case WM_KEYDOWN:
    169 		if (LOWORD(wParam) == VK_RETURN)
    170 		{
    171 			SendMessage ( g_qeglobals.d_hwndEntity, 
    172 				          WM_COMMAND, 
    173 			              (LBN_DBLCLK<<16) + IDC_E_LIST, 
    174 						  0 );
    175 			return 0;
    176 		}
    177 		break;
    178 	}
    179 	return CallWindowProc (OldEntityListWindowProc, hwnd, uMsg, wParam, lParam);
    180 }
    181 
    182 
    183 /*
    184 ================
    185 GetEntityControls
    186 
    187 Finds the controls from the dialog and
    188 moves them to the window
    189 ================
    190 */
    191 void GetEntityControls(HWND ghwndEntity)
    192 {
    193 	int i;
    194 
    195 	for (i = 0; i < EntLast; i++)
    196 	{
    197 		if (i == EntList || i == EntProps || i == EntComment)
    198 			continue;
    199 		if (i == EntKeyField || i == EntValueField)
    200 			continue;
    201 		hwndEnt[i] = GetDlgItem(ghwndEntity, rgIds[i]);		
    202 		if (hwndEnt[i])
    203     {
    204 			SetParent (hwndEnt[i], g_qeglobals.d_hwndEntity );
    205 			SendMessage(hwndEnt[i], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
    206     }
    207 	}
    208 
    209 
    210 	// SetParent apears to not modify some internal state
    211 	// on listboxes, so create it from scratch...
    212 
    213 	hwndEnt[EntList] = CreateWindow ("listbox", NULL, 
    214 		LBS_STANDARD | LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT 
    215 		| WS_VSCROLL | WS_CHILD | WS_VISIBLE,
    216 		5, 5, 180, 99,
    217 		g_qeglobals.d_hwndEntity,
    218 		(HMENU)IDC_E_LIST,
    219 		g_qeglobals.d_hInstance,
    220 		NULL);
    221 	if (!hwndEnt[EntList])
    222 		Error ("CreateWindow failed");
    223 
    224 	hwndEnt[EntProps] = CreateWindow ("listbox", NULL, 
    225 		LBS_STANDARD | LBS_NOINTEGRALHEIGHT | LBS_USETABSTOPS
    226 		| WS_VSCROLL | WS_CHILD | WS_VISIBLE,
    227 		5, 100, 180, 99,
    228 		g_qeglobals.d_hwndEntity,
    229 		(HMENU)IDC_E_PROPS,
    230 		g_qeglobals.d_hInstance,
    231 		NULL);
    232 	if (!hwndEnt[EntProps])
    233 		Error ("CreateWindow failed");
    234 
    235 	hwndEnt[EntComment] = CreateWindow ("edit", NULL, 
    236 		ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER,
    237 		5, 100, 180, 99,
    238 		g_qeglobals.d_hwndEntity,
    239 		(HMENU)IDC_E_COMMENT,
    240 		g_qeglobals.d_hInstance,
    241 		NULL);
    242 	if (!hwndEnt[EntComment])
    243 		Error ("CreateWindow failed");
    244 
    245 	hwndEnt[EntKeyField] = CreateWindow ("edit", NULL, 
    246 		WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
    247 		5, 100, 180, 99,
    248 		g_qeglobals.d_hwndEntity,
    249 		(HMENU)IDC_E_KEY_FIELD,
    250 		g_qeglobals.d_hInstance,
    251 		NULL);
    252 	if (!hwndEnt[EntKeyField])
    253 		Error ("CreateWindow failed");
    254 
    255 	hwndEnt[EntValueField] = CreateWindow ("edit", NULL, 
    256 		WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
    257 		5, 100, 180, 99,
    258 		g_qeglobals.d_hwndEntity,
    259 		(HMENU)IDC_E_VALUE_FIELD,
    260 		g_qeglobals.d_hInstance,
    261 		NULL);
    262 	if (!hwndEnt[EntValueField])
    263 		Error ("CreateWindow failed");
    264 
    265   g_wndTabs.SubclassDlgItem(IDC_TAB_MODE, CWnd::FromHandle(ghwndEntity));
    266   hwndEnt[EntTab] = g_wndTabs.GetSafeHwnd();
    267   g_wndTabs.InsertItem(0, "Groups");
    268   ::SetParent(g_wndTabs.GetSafeHwnd(), g_qeglobals.d_hwndEntity);
    269 
    270   if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
    271   {
    272 	  g_qeglobals.d_hwndEdit = CreateWindow ("edit", NULL, ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER,
    273 		                                       5, 100, 180, 99, g_qeglobals.d_hwndEntity, (HMENU)IDC_E_STATUS,
    274 		                                       g_qeglobals.d_hInstance, NULL);
    275 	  if (!g_qeglobals.d_hwndEdit)
    276 		  Error ("CreateWindow failed");
    277     g_wndTabs.InsertItem(0, "Console");
    278     g_wndTabs.InsertItem(0, "Textures");
    279   }
    280   g_wndTabs.InsertItem(0, "Entities");
    281   g_wndTabs.ShowWindow(SW_SHOW);
    282 
    283 #if 0
    284 	for (i=0 ; i<12 ; i++)
    285 	{
    286 		hwndEnt[EntCheck1 + i] = CreateWindow ("button", NULL, 
    287 		BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE,
    288 		5, 100, 180, 99,
    289 		entwindow,
    290 		(HMENU)IDC_E_STATUS,
    291 		main_instance,
    292 		NULL);
    293 		if (!hwndEnt[EntCheck1 + i])
    294 			Error ("CreateWindow failed");
    295 	}
    296 #endif
    297 	SendMessage(hwndEnt[EntList], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
    298 	SendMessage(hwndEnt[EntProps], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
    299 	SendMessage(hwndEnt[EntComment], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
    300 	SendMessage(hwndEnt[EntKeyField], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
    301 	SendMessage(hwndEnt[EntValueField], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
    302 	SendMessage(hwndEnt[EntTab], WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
    303 
    304 	if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
    305 		SendMessage(g_qeglobals.d_hwndEdit, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)TRUE);
    306 }
    307 
    308 
    309 
    310 /*
    311 ===============================================================
    312 
    313 ENTITY WINDOW
    314 
    315 ===============================================================
    316 */
    317 
    318 
    319 void FillClassList (void)
    320 {
    321 	eclass_t	*pec;
    322 	int			iIndex;
    323 
    324 	SendMessage(hwndEnt[EntList], LB_RESETCONTENT, 0 , 0);
    325 
    326 	for (pec = eclass ; pec ; pec = pec->next)
    327 	{
    328 		iIndex = SendMessage(hwndEnt[EntList], LB_ADDSTRING, 0 , (LPARAM)pec->name);
    329 		SendMessage(hwndEnt[EntList], LB_SETITEMDATA, iIndex, (LPARAM)pec);
    330 	}	
    331 
    332 }
    333 
    334 
    335 /*
    336 ==============
    337 WEnt_Create
    338 ==============
    339 */
    340 void WEnt_Create (HINSTANCE hInstance)
    341 {
    342     WNDCLASS   wc;
    343 
    344     /* Register the camera class */
    345 	memset (&wc, 0, sizeof(wc));
    346 
    347     wc.style         = CS_NOCLOSE | CS_OWNDC;
    348     wc.lpfnWndProc   = (WNDPROC)EntityWndProc;
    349     wc.cbClsExtra    = 0;
    350     wc.cbWndExtra    = 0;
    351     wc.hInstance     = hInstance;
    352     wc.hIcon         = 0;
    353     wc.hCursor       = LoadCursor (NULL,IDC_ARROW);
    354     wc.hbrBackground = (HBRUSH)GetStockObject (LTGRAY_BRUSH);
    355     wc.lpszMenuName  = NULL;
    356     wc.lpszClassName = ENT_WINDOW_CLASS;
    357 
    358     RegisterClass (&wc);
    359 
    360     int nStyle = (g_pParentWnd->CurrentStyle() == QR_QE4) ? QE3_STYLE : QE3_STYLE2;
    361 	  g_qeglobals.d_hwndEntity = CreateWindow (ENT_WINDOW_CLASS ,
    362 		"Entity",
    363 		nStyle,
    364 		20,
    365 		20,
    366 		100,
    367 		480,	// size
    368 
    369 		g_qeglobals.d_hwndMain,	// parent
    370 		0,		// no menu
    371 		hInstance,
    372 		NULL);
    373 
    374 	if (!g_qeglobals.d_hwndEntity )
    375 		Error ("Couldn't create Entity window");
    376 }
    377 
    378 /*
    379 ==============
    380 CreateEntityWindow
    381 ==============
    382 */
    383 BOOL CreateEntityWindow(HINSTANCE hInstance)
    384 {
    385 	HWND hwndEntityPalette;
    386 
    387 	inspector_mode = W_ENTITY;
    388 
    389 	WEnt_Create (hInstance);
    390 
    391 	hwndEntityPalette = CreateDialog(hInstance, (char *)IDD_ENTITY, g_qeglobals.d_hwndMain, (DLGPROC)NULL);
    392 	if (!hwndEntityPalette)
    393 		Error ("CreateDialog failed");
    394 
    395 	GetEntityControls (hwndEntityPalette);
    396 	DestroyWindow (hwndEntityPalette);
    397 
    398 	OldFieldWindowProc = (WNDPROC)GetWindowLong (hwndEnt[EntKeyField], GWL_WNDPROC);
    399 	SetWindowLong (hwndEnt[EntKeyField], GWL_WNDPROC, (long)FieldWndProc);
    400 	SetWindowLong (hwndEnt[EntValueField], GWL_WNDPROC, (long)FieldWndProc);
    401 
    402 	OldEntityListWindowProc = (WNDPROC)GetWindowLong (hwndEnt[EntList], GWL_WNDPROC);
    403 	SetWindowLong (hwndEnt[EntList], GWL_WNDPROC, (long)EntityListWndProc);
    404 
    405 	FillClassList ();
    406 
    407 
    408 	LoadWindowPlacement(g_qeglobals.d_hwndEntity, "EntityWindowPlace");
    409 	ShowWindow (g_qeglobals.d_hwndEntity, SW_HIDE);
    410 	SetInspectorMode (W_CONSOLE);
    411 
    412 	return TRUE;
    413 }
    414 
    415 /*
    416 ==============
    417 SetInspectorMode
    418 ==============
    419 */
    420 void SetInspectorMode(int iType)
    421 {
    422 	RECT rc;
    423 	HMENU hMenu = GetMenu( g_qeglobals.d_hwndMain );
    424 
    425   if ((g_pParentWnd->CurrentStyle() == QR_SPLIT || g_pParentWnd->CurrentStyle() == QR_SPLITZ) && (iType == W_TEXTURE || iType == W_CONSOLE))
    426     return;
    427 
    428 
    429 	// Is the caller asking us to cycle to the next window?
    430 
    431 	if (iType == -1)
    432 	{
    433 		if (inspector_mode == W_ENTITY)
    434 			iType = W_TEXTURE;
    435 		else if (inspector_mode == W_TEXTURE)
    436 			iType = W_CONSOLE;
    437 		else if (inspector_mode == W_CONSOLE)
    438       iType = W_GROUP;
    439     else
    440 			iType = W_ENTITY;
    441 	}		
    442 
    443 	inspector_mode = iType;
    444 	switch(iType)
    445 	{
    446 		
    447 	case W_ENTITY:
    448 		SetWindowText(g_qeglobals.d_hwndEntity, "Entity");
    449 		EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_ENABLED | MF_BYCOMMAND );
    450     // entity is always first in the inspector
    451     g_wndTabs.SetCurSel(0);
    452 		break;
    453 
    454 	case W_TEXTURE:
    455     SetWindowText(g_qeglobals.d_hwndEntity, "Textures");
    456     g_pParentWnd->GetTexWnd()->FocusEdit();
    457 		EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND );
    458     if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
    459       g_wndTabs.SetCurSel(1);
    460 		break;
    461 
    462 	case W_CONSOLE:
    463 		SetWindowText(g_qeglobals.d_hwndEntity, "Console");		
    464 		EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND );
    465     if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
    466       g_wndTabs.SetCurSel(2);
    467 		break;
    468 
    469   case W_GROUP:
    470 		SetWindowText(g_qeglobals.d_hwndEntity, "Groups");		
    471 		EnableMenuItem( hMenu, ID_MISC_SELECTENTITYCOLOR, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND );
    472     if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
    473       g_wndTabs.SetCurSel(3);
    474     else
    475       g_wndTabs.SetCurSel(1);
    476 		break;
    477 
    478 
    479 	default:
    480 		break;
    481 	}
    482 
    483 	GetWindowRect (g_qeglobals.d_hwndEntity, &rc);
    484 	SizeEntityDlg( rc.right - rc.left - 8, rc.bottom - rc.top - 20);
    485 
    486 
    487 //	InvalidateRect(entwindow, NULL, true);
    488 //	ShowWindow (entwindow, SW_SHOW);
    489 //	UpdateWindow (entwindow);
    490 
    491   HWND hFlag = (g_pParentWnd->CurrentStyle() == QR_QE4) ? HWND_TOP : HWND_TOPMOST;
    492 	SetWindowPos( g_qeglobals.d_hwndEntity, hFlag, rc.left, rc.top,  rc.right - rc.left, rc.bottom - rc.top, SWP_NOSIZE | SWP_NOMOVE );
    493 	RedrawWindow (g_qeglobals.d_hwndEntity, NULL, NULL, RDW_ERASE | RDW_INVALIDATE| RDW_ERASENOW | RDW_UPDATENOW | RDW_ALLCHILDREN);
    494 }
    495 
    496 
    497 
    498 
    499 
    500 // SetKeyValuePairs
    501 //
    502 // Reset the key/value (aka property) listbox and fill it with the 
    503 // k/v pairs from the entity being edited.
    504 //
    505 
    506 void SetKeyValuePairs (bool bClearMD3)
    507 {
    508 	epair_t	*pep;
    509 	RECT	rc;
    510 	char	sz[4096];
    511 	
    512 	if (edit_entity == NULL)
    513 		return;
    514 	
    515 	// set key/value pair list
    516 	
    517 	GetWindowRect(hwndEnt[EntProps], &rc);
    518 	SendMessage(hwndEnt[EntProps], LB_SETCOLUMNWIDTH, (rc.right - rc.left)/2, 0);
    519 	SendMessage(hwndEnt[EntProps], LB_RESETCONTENT, 0, 0);
    520 	
    521 	// Walk through list and add pairs
    522 	
    523 	for (pep = edit_entity->epairs ; pep ; pep = pep->next)
    524 	{
    525 		// if the key is less than 8 chars, add a tab for alignment
    526 		if (strlen(pep->key) > 8)
    527 			sprintf (sz, "%s\t%s", pep->key, pep->value);
    528 		else
    529 			sprintf (sz, "%s\t\t%s", pep->key, pep->value);
    530 		SendMessage(hwndEnt[EntProps], LB_ADDSTRING, 0, (LPARAM)sz);
    531 	}
    532 	
    533 	if (edit_entity->eclass->nShowFlags & ECLASS_MISCMODEL)
    534 	{
    535 		// if this is a misc_model
    536 		// cache the md3 for display later
    537 		if (bClearMD3)
    538 		{
    539 			edit_entity->md3Class = NULL;
    540 		}
    541 		//char *pModel = ValueForKey(edit_entity, "model");
    542 		
    543 		/*
    544 		if (pModel != NULL)
    545 		{
    546 		GetCachedModel(pModel, vMin, vMax);
    547 		}
    548 		*/
    549 	}
    550 		
    551 	Sys_UpdateWindows(W_CAMERA | W_XY);
    552 	
    553 }
    554 
    555 // SetSpawnFlags
    556 // 
    557 // Update the checkboxes to reflect the flag state of the entity
    558 //
    559 void SetSpawnFlags(void)
    560 {
    561 	int		f;
    562 	int		i;
    563 	int		v;
    564 
    565 	f = atoi(ValueForKey (edit_entity, "spawnflags"));
    566 	for (i=0 ; i<12 ; i++)
    567 	{
    568 		v = !!(f&(1<<i));
    569 		SendMessage(hwndEnt[EntCheck1+i], BM_SETCHECK, v, 0);
    570 	}
    571 }
    572 
    573 
    574 // GetSpawnFlags
    575 // 
    576 // Update the entity flags to reflect the state of the checkboxes
    577 //
    578 void GetSpawnFlags(void)
    579 {
    580 	int		f;
    581 	int		i, v;
    582 	char	sz[32];
    583 
    584 	f = 0;
    585 	for (i=0 ; i<12 ; i++)
    586 	{
    587 		v = SendMessage(hwndEnt[EntCheck1+i], BM_GETCHECK, 0, 0);
    588 		f |= v<<i;
    589 	}
    590 
    591 	sprintf (sz, "%i", f);
    592 
    593 	if (multiple_entities)
    594 	{
    595 		brush_t	*b;
    596 
    597 		for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
    598 			SetKeyValue(b->owner, "spawnflags", sz);
    599 	}
    600 	else
    601 		SetKeyValue (edit_entity, "spawnflags", sz);
    602 	SetKeyValuePairs ();
    603 }
    604 
    605 // UpdateSel
    606 //
    607 // Update the listbox, checkboxes and k/v pairs to reflect the new selection
    608 //
    609 BOOL UpdateSel(int iIndex, eclass_t *pec)
    610 {
    611 	int		i;
    612 	brush_t	*b;
    613 
    614 	if (selected_brushes.next == &selected_brushes)
    615 	{
    616 		edit_entity = world_entity;
    617 		multiple_entities = false;
    618 	}
    619 	else
    620 	{
    621 		edit_entity = selected_brushes.next->owner;
    622 		for (b=selected_brushes.next->next ; b != &selected_brushes ; b=b->next)
    623 		{
    624 			if (b->owner != edit_entity)
    625 			{
    626 				multiple_entities = true;
    627 				break;
    628 			}
    629 		}
    630 	}
    631 
    632 	if (iIndex != LB_ERR)
    633 		SendMessage(hwndEnt[EntList], LB_SETCURSEL, iIndex, 0);
    634 
    635 	if (pec == NULL)
    636 		return TRUE;
    637 
    638 	// Set up the description
    639 
    640 	SendMessage(hwndEnt[EntComment], WM_SETTEXT, 0, 
    641 			(LPARAM)TranslateString(pec->comments));
    642 
    643 	for (i=0 ; i<8 ; i++)
    644 	{
    645 		HWND hwnd = hwndEnt[EntCheck1+i];
    646 		if (pec->flagnames[i] && pec->flagnames[i][0] != 0)
    647 		{
    648 			EnableWindow(hwnd, TRUE);
    649 			SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)pec->flagnames[i]);
    650 		} else {
    651 
    652 			// disable check box
    653 			SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)" ");
    654 			EnableWindow(hwnd, FALSE);
    655 		}
    656 	}
    657 
    658 	SetSpawnFlags();
    659 	SetKeyValuePairs();
    660 	return TRUE;
    661 }
    662 
    663 BOOL UpdateEntitySel(eclass_t *pec)
    664 {
    665 	int iIndex;
    666 
    667 	iIndex = (int)SendMessage(hwndEnt[EntList], LB_FINDSTRINGEXACT, 
    668 			(WPARAM)-1, (LPARAM)pec->name);
    669 
    670 	return UpdateSel(iIndex, pec);
    671 }
    672 
    673 // CreateEntity
    674 //
    675 // Creates a new entity based on the currently selected brush and entity type.
    676 //
    677 
    678 void CreateEntity(void)
    679 {
    680 	eclass_t *pecNew;
    681 	entity_t *petNew;
    682 	int i;
    683 	HWND hwnd;
    684 	char sz[1024];
    685 
    686 	// check to make sure we have a brush
    687 
    688 	if (selected_brushes.next == &selected_brushes)
    689 	{
    690 	    MessageBox(g_qeglobals.d_hwndMain, "You must have a selected brush to create an entity"
    691 			, "info", 0);
    692 		return;
    693 	}
    694 
    695 
    696 	// find out what type of entity we are trying to create
    697 
    698 	hwnd = hwndEnt[EntList];
    699 
    700 	i = SendMessage(hwndEnt[EntList], LB_GETCURSEL, 0, 0);
    701 
    702 	if (i < 0)
    703 	{
    704 	    MessageBox(g_qeglobals.d_hwndMain, "You must have a selected class to create an entity"
    705 			, "info", 0);
    706 		return;
    707 	}
    708 
    709 	SendMessage(hwnd, LB_GETTEXT, i, (LPARAM)sz);
    710 
    711 	if (!stricmp(sz, "worldspawn"))
    712 	{
    713 	    MessageBox(g_qeglobals.d_hwndMain, "Can't create an entity with worldspawn.", "info", 0);
    714 		return;
    715 	}
    716 
    717 	pecNew = Eclass_ForName(sz, false);
    718 
    719 	// create it
    720 
    721 	petNew = Entity_Create(pecNew);
    722 
    723 	if (petNew == NULL)
    724 	{
    725 	    MessageBox(g_qeglobals.d_hwndMain, "Failed to create entity.", "info", 0);
    726 		return;
    727 	}
    728 
    729 	if (selected_brushes.next == &selected_brushes)
    730 		edit_entity = world_entity;
    731 	else
    732 		edit_entity = selected_brushes.next->owner;
    733 
    734 	SetKeyValuePairs();
    735 	Select_Deselect ();
    736 	Select_Brush (edit_entity->brushes.onext);
    737   Sys_UpdateWindows(W_ALL);
    738 
    739 }
    740 
    741 
    742 
    743 /*
    744 ===============
    745 AddProp
    746 
    747 ===============
    748 */
    749 void AddProp()
    750 {
    751 	char	key[4096];
    752 	char	value[4096];
    753 
    754 	if (edit_entity == NULL)
    755 		return;
    756 
    757 	// Get current selection text
    758 
    759 	SendMessage(hwndEnt[EntKeyField], WM_GETTEXT, sizeof(key)-1, (LPARAM)key);	
    760 	SendMessage(hwndEnt[EntValueField], WM_GETTEXT, sizeof(value)-1, (LPARAM)value);	
    761 
    762 	if (multiple_entities)
    763 	{
    764 		brush_t	*b;
    765 
    766 		for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
    767 			SetKeyValue(b->owner, key, value);
    768 	}
    769 	else
    770 		SetKeyValue(edit_entity, key, value);
    771 
    772 	// refresh the prop listbox
    773 	SetKeyValuePairs();	
    774 
    775 	// if it's a plugin entity, perhaps we need to update some drawing parameters
    776 	// NOTE: perhaps moving this code to a seperate func would help if we need it in other places
    777 	// TODO: we need to call some update func in the IPluginEntity in case model name changes etc.
    778 	// ( for the moment only bounding brush is updated ), see UpdateModelBrush in Ritual's Q3Radiant
    779 	if (edit_entity->eclass->nShowFlags & ECLASS_PLUGINENTITY)
    780 	{
    781 		vec3_t	mins, maxs;
    782 		edit_entity->pPlugEnt->GetBounds( mins, maxs );
    783 		// replace old bounding brush by newly computed one
    784 		// NOTE: this part is similar to Entity_BuildModelBrush in Ritual's Q3Radiant, it can be
    785 		// usefull moved into a seperate func
    786 		brush_t *b,*oldbrush;
    787 		if (edit_entity->brushes.onext != &edit_entity->brushes)
    788 			oldbrush = edit_entity->brushes.onext;
    789 		b = Brush_Create (mins, maxs, &edit_entity->eclass->texdef);
    790 		Entity_LinkBrush (edit_entity, b);
    791 		Brush_Build( b, true );
    792 		Select_Deselect();
    793 		Brush_AddToList (edit_entity->brushes.onext, &selected_brushes);
    794 		if (oldbrush)
    795 			Brush_Free( oldbrush );
    796 	}
    797 
    798 }
    799 
    800 /*
    801 ===============
    802 DelProp
    803 
    804 ===============
    805 */
    806 void DelProp(void)
    807 {
    808 	char	sz[4096];
    809 
    810 	if (edit_entity == NULL)
    811 		return;
    812 
    813 	// Get current selection text
    814 
    815 	SendMessage(hwndEnt[EntKeyField], WM_GETTEXT, sizeof(sz)-1, (LPARAM)sz);	
    816 
    817 	if (multiple_entities)
    818 	{
    819 		brush_t	*b;
    820 
    821 		for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
    822 			DeleteKey(b->owner, sz);
    823 	}
    824 	else
    825 		DeleteKey(edit_entity, sz);
    826 
    827 	// refresh the prop listbox
    828 
    829 	SetKeyValuePairs();	
    830 }
    831 
    832 BOOL GetSelectAllCriteria(CString &strKey, CString &strVal) {
    833 	char	sz[4096];
    834 	HWND hwnd = hwndEnt[EntProps];
    835 	int i = SendMessage(hwnd, LB_GETCURSEL, 0, 0);	
    836   if (i >= 0 && inspector_mode == W_ENTITY) {
    837 	  SendMessage(hwndEnt[EntKeyField], WM_GETTEXT, sizeof(sz), (LPARAM)sz);	
    838     strKey = sz;
    839 	  SendMessage(hwndEnt[EntValueField], WM_GETTEXT, sizeof(sz), (LPARAM)sz);	
    840     strVal = sz;
    841     return TRUE;
    842   }
    843   return FALSE;
    844 }
    845 
    846 /*
    847 ===============
    848 EditProp
    849 
    850 ===============
    851 */
    852 void EditProp(void)
    853 {
    854 	int i;
    855 	HWND hwnd;
    856 	char	sz[4096];
    857 	char	*val;
    858 
    859 	if (edit_entity == NULL)
    860 		return;
    861 
    862 	hwnd = hwndEnt[EntProps];
    863 
    864 	// Get current selection text
    865 
    866 	i = SendMessage(hwnd, LB_GETCURSEL, 0, 0);	
    867 
    868 	if (i < 0)
    869 		return;
    870 
    871 	SendMessage(hwnd, LB_GETTEXT, i, (LPARAM)sz);	
    872 
    873 	// strip it down to the key name
    874 
    875 	for(i=0;sz[i] != '\t';i++)
    876 	;
    877 
    878 	sz[i] = '\0';
    879 
    880 	val = sz + i + 1;
    881 	if (*val == '\t')
    882 		val++;
    883 
    884 	SendMessage(hwndEnt[EntKeyField], WM_SETTEXT, 0, (LPARAM)sz);	
    885 	SendMessage(hwndEnt[EntValueField], WM_SETTEXT, 0, (LPARAM)val);	
    886 }
    887 
    888 
    889 HDWP	defer;
    890 int		col;
    891 void MOVE(HWND e, int x, int y, int w, int h, HWND hwndPlacement = HWND_TOP, int swp = SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOZORDER)
    892 {
    893 //	defer=DeferWindowPos(defer,e,HWND_TOP,col+(x),y,w,h,SWP_SHOWWINDOW);
    894 //	MoveWindow (e, col+x, y, w, h, FALSE);
    895 	SetWindowPos (e, hwndPlacement, col+x, y, w, h, swp);
    896 }
    897 
    898 
    899 /*
    900 ===============
    901 SizeEnitityDlg
    902 
    903 Positions all controls so that the active inspector
    904 is displayed correctly and the inactive ones are
    905 off the side
    906 ===============
    907 */
    908 void SizeEntityDlg(int iWidth, int iHeight)
    909 {
    910 	int y, x, xCheck, yCheck;
    911 	int i, iRow;
    912 	int	w, h;
    913 
    914 	if (iWidth < 32 || iHeight < 32)
    915 		return;
    916 
    917 	SendMessage( g_qeglobals.d_hwndEntity, WM_SETREDRAW, 0, 0);
    918   iHeight -= 24;
    919 
    920 
    921 	//==========================================
    922 
    923 
    924   //
    925 	// console
    926 	//
    927   if (inspector_mode == W_CONSOLE)
    928   {
    929     col = 0;
    930   }
    931   else
    932   {
    933     col = iWidth;
    934   }
    935 
    936   if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
    937 	  MOVE(g_qeglobals.d_hwndEdit,	DlgXBorder, DlgYBorder, iWidth - (2 * DlgXBorder), iHeight - (2 * DlgYBorder) );
    938 
    939 	//==========================================
    940 
    941 	//
    942 	// texture controls
    943 	//
    944   if (inspector_mode == W_TEXTURE)
    945   {
    946     col = 0;
    947   }
    948   else
    949   {
    950     col = iWidth;
    951   }
    952 
    953   if (g_pParentWnd->CurrentStyle() > 0 && g_pParentWnd->CurrentStyle() < 3)
    954 	  MOVE(g_qeglobals.d_hwndTexture,	DlgXBorder, DlgYBorder, iWidth - (2 * DlgXBorder), iHeight - (2 * DlgYBorder) );
    955 
    956   if (inspector_mode == W_GROUP)
    957   {
    958     col = 0;
    959   }
    960   else
    961   {
    962     col = iWidth;
    963   }
    964 
    965   MOVE(g_qeglobals.d_hwndGroup,	DlgXBorder, DlgYBorder, iWidth - (2 * DlgXBorder), iHeight - (2 * DlgYBorder) );
    966 
    967 	//==========================================
    968 
    969 	//
    970 	// entity controls
    971 	//
    972   if (inspector_mode == W_ENTITY)
    973   {
    974     col = 0;
    975   }
    976   else
    977   {
    978     col = iWidth;
    979   }
    980 
    981 
    982 
    983 	// top half includes the entity list (2/3) and the 
    984 	// comments (1/3) - 2 gaps, above and below.
    985 
    986 	y = iHeight/2;
    987 	y -= 2 * DlgYBorder;
    988 	y = y / 3;
    989 	w = iWidth - (2 * DlgXBorder);
    990 	MOVE(hwndEnt[EntList], DlgXBorder, DlgYBorder, w, 2 * y);
    991 	
    992 	MOVE(hwndEnt[EntComment], DlgXBorder, 2 * DlgYBorder + 2 * y, w, y - (2 * DlgYBorder));
    993 
    994 	// bottom half includes flags (fixed), k/v pairs,
    995 	// and buttons (fixed).
    996 
    997 	// xCheck = width of a single check box
    998 	// yCheck = distance from top of one check to the next
    999 
   1000 	xCheck = (iWidth - (2 * DlgXBorder)) / 3;
   1001 	yCheck = 18;
   1002 
   1003 	x = DlgXBorder;
   1004 
   1005 	for (iRow = 0; iRow <= 12; iRow += 4)
   1006 	{
   1007 		y = iHeight/2;
   1008 	
   1009 		for (i = 0; i < 4; i++)
   1010 		{
   1011 			MOVE(hwndEnt[EntCheck1 + i + iRow],
   1012 				x, y, xCheck, yCheck);
   1013 			y += yCheck;
   1014 		}
   1015 
   1016 		x += xCheck;
   1017 	}
   1018 
   1019 	//
   1020 	// properties scroll box
   1021 	//
   1022 	y = iHeight/2 + 4 * yCheck;
   1023 
   1024 	w = iWidth - (2 * DlgXBorder);
   1025 	h = (iHeight - (yCheck * 5 + 2 * DlgYBorder) ) - y;
   1026 
   1027 	MOVE(hwndEnt[EntProps], DlgXBorder, y, w, h);
   1028 
   1029 	y += h + DlgYBorder;
   1030 	
   1031 	//
   1032 	// key / value fields
   1033 	//
   1034 	w = iWidth-(DlgXBorder+45);
   1035 	MOVE(hwndEnt[EntKeyLabel], DlgXBorder, y, 40, yCheck);
   1036 	MOVE(hwndEnt[EntKeyField], DlgXBorder+40, y, w, yCheck);
   1037 	y += yCheck;		
   1038 
   1039 	MOVE(hwndEnt[EntValueLabel], DlgXBorder, y, 40, yCheck);
   1040 	MOVE(hwndEnt[EntValueField], DlgXBorder+40, y, w, yCheck);
   1041 	y += yCheck;		
   1042 
   1043 	//
   1044 	// angle check boxes
   1045 	//
   1046   y += 2;
   1047 	i = y;
   1048 	x = DlgXBorder;
   1049 
   1050 	xCheck = yCheck*2;
   1051 
   1052 	MOVE(hwndEnt[EntDir135], x, y, xCheck, yCheck);
   1053 	y += yCheck;		
   1054 	
   1055 	MOVE(hwndEnt[EntDir180], x, y, xCheck, yCheck);
   1056 	y += yCheck;		
   1057 	
   1058 	MOVE(hwndEnt[EntDir225], x, y, xCheck, yCheck);
   1059 
   1060 	y = i;
   1061 	x += xCheck;
   1062 
   1063 	
   1064 	MOVE(hwndEnt[EntDir90], x, y, xCheck, yCheck);
   1065 	y += yCheck;		
   1066 	y += yCheck;		
   1067 	
   1068 	MOVE(hwndEnt[EntDir270], x, y, xCheck, yCheck);
   1069 
   1070 	y = i;
   1071 	x += xCheck;
   1072 
   1073 	
   1074 	MOVE(hwndEnt[EntDir45], x, y, xCheck, yCheck);
   1075 	y += yCheck;		
   1076 	
   1077 	MOVE(hwndEnt[EntDir0], x, y, xCheck, yCheck);
   1078 	y += yCheck;		
   1079 	
   1080 	MOVE(hwndEnt[EntDir315], x, y, xCheck, yCheck);
   1081 
   1082 	y = i + yCheck/2;
   1083 	x += xCheck + xCheck/2;
   1084 
   1085 	
   1086 	MOVE(hwndEnt[EntDirUp], x, y, xCheck, yCheck);
   1087 	y += yCheck;		
   1088 	
   1089 	MOVE(hwndEnt[EntDirDown], x, y, xCheck, yCheck);
   1090 
   1091 	y = i;
   1092 	x += 1.5 * xCheck;
   1093 	
   1094 	MOVE(hwndEnt[EntDelProp], x, y, xCheck*2, yCheck);
   1095 	y += yCheck + 4;		
   1096 
   1097   MOVE(hwndEnt[EntAssignSounds], x, y, xCheck*2, yCheck);
   1098 	y += yCheck;		
   1099   MOVE(hwndEnt[EntAssignModels], x, y, xCheck*2, yCheck);
   1100 
   1101   // tab selector is always visible
   1102   col = 0;
   1103   iHeight += 24;
   1104   MOVE(hwndEnt[EntTab], 0,0,iWidth,iHeight, HWND_BOTTOM, SWP_NOACTIVATE | SWP_NOCOPYBITS);
   1105 
   1106 	SendMessage( g_qeglobals.d_hwndEntity, WM_SETREDRAW, 1, 0);
   1107 //	InvalidateRect(entwindow, NULL, TRUE);
   1108 }
   1109 
   1110 void AssignSound()
   1111 {
   1112   CString strBasePath = ValueForKey(g_qeglobals.d_project_entity, "basepath");
   1113   AddSlash(strBasePath);
   1114   CString strPath = strBasePath;
   1115   strPath += "sound\\";
   1116 
   1117   CWaveOpen dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Sound files (*.wav)|*.wav||", g_pParentWnd);
   1118   dlgFile.m_ofn.lpstrInitialDir = strPath;
   1119   if (dlgFile.DoModal() == IDOK)
   1120   {
   1121 	  SendMessage(hwndEnt[EntKeyField], WM_SETTEXT, 0, (LPARAM)"noise");	
   1122     CString str = dlgFile.GetPathName().GetBuffer(0);
   1123     str.MakeLower();
   1124     strBasePath.MakeLower();
   1125     QE_ConvertDOSToUnixName(str.GetBuffer(0), str.GetBuffer(0));
   1126     QE_ConvertDOSToUnixName(strBasePath.GetBuffer(0), strBasePath.GetBuffer(0));
   1127     int n = str.Find(strBasePath);
   1128     if (n == 0)
   1129     {
   1130       str = str.Right(str.GetLength() - strBasePath.GetLength());
   1131     }
   1132 
   1133 	  SendMessage(hwndEnt[EntValueField], WM_SETTEXT, 0, (LPARAM)str.GetBuffer(0));	
   1134     AddProp();
   1135     g_pParentWnd->GetXYWnd()->SetFocus();
   1136   }
   1137 }
   1138 
   1139 void AssignModel()
   1140 {
   1141   CString strBasePath = ValueForKey(g_qeglobals.d_project_entity, "basepath");
   1142   AddSlash(strBasePath);
   1143   CString strPath = strBasePath;
   1144   strPath += "models\\mapobjects\\";
   1145 
   1146   CFileDialog dlgFile(TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "Model files (*.md3)|*.md3||", g_pParentWnd);
   1147   dlgFile.m_ofn.lpstrInitialDir = strPath;
   1148   if (dlgFile.DoModal() == IDOK)
   1149   {
   1150 	  SendMessage(hwndEnt[EntKeyField], WM_SETTEXT, 0, (LPARAM)"model");
   1151     CString str = dlgFile.GetPathName().GetBuffer(0);
   1152     str.MakeLower();
   1153     strBasePath.MakeLower();
   1154     QE_ConvertDOSToUnixName(str.GetBuffer(0), str.GetBuffer(0));
   1155     QE_ConvertDOSToUnixName(strBasePath.GetBuffer(0), strBasePath.GetBuffer(0));
   1156     int n = str.Find(strBasePath);
   1157     if (n == 0)
   1158     {
   1159       str = str.Right(str.GetLength() - strBasePath.GetLength());
   1160     }
   1161 
   1162 	  SendMessage(hwndEnt[EntValueField], WM_SETTEXT, 0, (LPARAM)str.GetBuffer(0));	
   1163     AddProp();
   1164     edit_entity->md3Class = NULL;
   1165     edit_entity->brushes.onext->bModelFailed = false;
   1166     g_pParentWnd->GetXYWnd()->SetFocus();
   1167   }
   1168 }
   1169 
   1170 
   1171 /*
   1172 =========================
   1173 EntityWndProc
   1174 =========================
   1175 */
   1176 BOOL CALLBACK EntityWndProc(
   1177     HWND hwndDlg,	// handle to dialog box
   1178     UINT uMsg,		// message
   1179     WPARAM wParam,	// first message parameter
   1180     LPARAM lParam)	// second message parameter
   1181 {
   1182   LPNMHDR lpnmh = NULL;
   1183 	RECT	rc;
   1184 
   1185 	GetClientRect(hwndDlg, &rc);
   1186 
   1187     switch (uMsg)
   1188     {
   1189 
   1190       case WM_CHAR :
   1191       {
   1192         char c = toupper(LOWORD(wParam));
   1193         // escape: hide the window
   1194 		    if (c == 27)
   1195 			    ShowWindow(hwndDlg, SW_HIDE);
   1196         if (c == 'N')
   1197           g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_ENTITY, 0);
   1198         else
   1199         if (c == 'O')
   1200           g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_CONSOLE, 0);
   1201         else
   1202         if (c == 'T')
   1203           g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_TEXTURE, 0);
   1204         else
   1205         if (c == 'G')
   1206           g_pParentWnd->PostMessage(WM_COMMAND, ID_VIEW_GROUPS, 0);
   1207         else
   1208 			    DefWindowProc (hwndDlg, uMsg, wParam, lParam);
   1209         break;
   1210       }
   1211 
   1212       case WM_NOTIFY:
   1213         lpnmh = reinterpret_cast<LPNMHDR>(lParam);
   1214         if (lpnmh->hwndFrom == g_wndTabs.GetSafeHwnd()) {
   1215           if ( lpnmh->code == TCN_SELCHANGE)
   1216           {
   1217             int n = g_wndTabs.GetCurSel();
   1218             if (g_pParentWnd->CurrentStyle() == 2 || g_pParentWnd->CurrentStyle() == 1)
   1219             {
   1220               if (n == 0) {
   1221                 SetInspectorMode(W_ENTITY);
   1222               } else if (n == 1) {
   1223                 SetInspectorMode(W_TEXTURE);
   1224               } else if (n == 2) {
   1225                 SetInspectorMode(W_CONSOLE);
   1226               } else {
   1227                 SetInspectorMode(W_GROUP);
   1228               }
   1229             }
   1230             else
   1231             {
   1232               if (n == 0) {
   1233                 SetInspectorMode(W_ENTITY);
   1234               } else if (n == 1) {
   1235                 SetInspectorMode(W_GROUP);
   1236               }
   1237             }
   1238           }
   1239         }
   1240         break;
   1241         
   1242 	case WM_SIZE:
   1243 
   1244 			DefWindowProc (hwndDlg, uMsg, wParam, lParam);
   1245       break;
   1246 
   1247   case WM_DESTROY:
   1248       SaveWindowPlacement(g_qeglobals.d_hwndEntity, "EntityWindowPlace");
   1249       DefWindowProc(hwndDlg, uMsg, wParam, lParam);
   1250       break;
   1251 
   1252 	case WM_GETMINMAXINFO:
   1253 		{
   1254 			LPMINMAXINFO	lpmmi;
   1255 
   1256 			lpmmi = (LPMINMAXINFO) lParam;
   1257 			lpmmi->ptMinTrackSize.x = 320;
   1258 			lpmmi->ptMinTrackSize.y = 500;
   1259 		}
   1260 		return 0;
   1261 
   1262 	case WM_WINDOWPOSCHANGING:
   1263 		{
   1264 			LPWINDOWPOS	lpwp;
   1265 			lpwp = (LPWINDOWPOS) lParam;
   1266 
   1267 			DefWindowProc (hwndDlg, uMsg, wParam, lParam);
   1268 
   1269 			lpwp->flags |= SWP_NOCOPYBITS;
   1270 			SizeEntityDlg(lpwp->cx-8, lpwp->cy-32);
   1271 			return 0;
   1272 
   1273 		}
   1274 		return 0;
   1275 
   1276 
   1277 	case WM_COMMAND: 
   1278 		switch (LOWORD(wParam)) { 
   1279 
   1280     case IDC_BTN_ASSIGNSOUND:
   1281       AssignSound();
   1282       break;
   1283 
   1284     case IDC_BTN_ASSIGNMODEL:
   1285       AssignModel();
   1286       break;
   1287 
   1288 		case IDC_E_DELPROP:
   1289 			DelProp();
   1290 			SetFocus (g_qeglobals.d_hwndCamera);
   1291 			break;
   1292 
   1293 		case IDC_E_0:
   1294 			SetKeyValue (edit_entity, "angle", "360");
   1295 			SetFocus (g_qeglobals.d_hwndCamera);
   1296 			SetKeyValuePairs ();
   1297 			break;
   1298 		case IDC_E_45:
   1299 			SetKeyValue (edit_entity, "angle", "45");
   1300 			SetFocus (g_qeglobals.d_hwndCamera);
   1301 			SetKeyValuePairs ();
   1302 			break;
   1303 		case IDC_E_90:
   1304 			SetKeyValue (edit_entity, "angle", "90");
   1305 			SetFocus (g_qeglobals.d_hwndCamera);
   1306 			SetKeyValuePairs ();
   1307 			break;
   1308 		case IDC_E_135:
   1309 			SetKeyValue (edit_entity, "angle", "135");
   1310 			SetFocus (g_qeglobals.d_hwndCamera);
   1311 			SetKeyValuePairs ();
   1312 			break;
   1313 		case IDC_E_180:
   1314 			SetKeyValue (edit_entity, "angle", "180");
   1315 			SetFocus (g_qeglobals.d_hwndCamera);
   1316 			SetKeyValuePairs ();
   1317 			break;
   1318 		case IDC_E_225:
   1319 			SetKeyValue (edit_entity, "angle", "225");
   1320 			SetFocus (g_qeglobals.d_hwndCamera);
   1321 			SetKeyValuePairs ();
   1322 			break;
   1323 		case IDC_E_270:
   1324 			SetKeyValue (edit_entity, "angle", "270");
   1325 			SetFocus (g_qeglobals.d_hwndCamera);
   1326 			SetKeyValuePairs ();
   1327 			break;
   1328 		case IDC_E_315:
   1329 			SetKeyValue (edit_entity, "angle", "315");
   1330 			SetFocus (g_qeglobals.d_hwndCamera);
   1331 			SetKeyValuePairs ();
   1332 			break;
   1333 		case IDC_E_UP:
   1334 			SetKeyValue (edit_entity, "angle", "-1");
   1335 			SetFocus (g_qeglobals.d_hwndCamera);
   1336 			SetKeyValuePairs ();
   1337 			break;
   1338 		case IDC_E_DOWN:
   1339 			SetKeyValue (edit_entity, "angle", "-2");
   1340 			SetFocus (g_qeglobals.d_hwndCamera);
   1341 			SetKeyValuePairs ();
   1342 			break;
   1343 
   1344     case IDC_BTN_HIDE:
   1345       ::PostMessage(g_qeglobals.d_hwndMain, WM_COMMAND, ID_VIEW_CAMERATOGGLE, 0);
   1346       break;
   1347 
   1348 		case IDC_CHECK1:
   1349 		case IDC_CHECK2:
   1350 		case IDC_CHECK3:
   1351 		case IDC_CHECK4:
   1352 		case IDC_CHECK5:
   1353 		case IDC_CHECK6:
   1354 		case IDC_CHECK7:
   1355 		case IDC_CHECK8:
   1356 		case IDC_CHECK9:
   1357 		case IDC_CHECK10:
   1358 		case IDC_CHECK11:
   1359 		case IDC_CHECK12:
   1360 			GetSpawnFlags();
   1361 			SetFocus (g_qeglobals.d_hwndCamera);
   1362 			break;
   1363 
   1364 
   1365 		case IDC_E_PROPS: 
   1366 			switch (HIWORD(wParam))
   1367 			{ 
   1368 			case LBN_SELCHANGE:
   1369 
   1370 				EditProp();
   1371 				return TRUE; 
   1372 			}
   1373 			break;
   1374 
   1375 		case IDC_E_LIST: 
   1376 	   
   1377 			switch (HIWORD(wParam)) { 
   1378 			
   1379 			case LBN_SELCHANGE: 
   1380 			{
   1381 				int iIndex;
   1382 				eclass_t *pec;
   1383 				
   1384 				iIndex = SendMessage(hwndEnt[EntList], LB_GETCURSEL, 0, 0);	
   1385 				pec = (eclass_t *)SendMessage(hwndEnt[EntList], LB_GETITEMDATA, 
   1386 						iIndex, 0); 
   1387 			
   1388 				UpdateSel(iIndex, pec);
   1389 
   1390 				return TRUE; 
   1391 				break; 
   1392 			}
   1393 
   1394 			case LBN_DBLCLK: 
   1395 				CreateEntity ();
   1396 				SetFocus (g_qeglobals.d_hwndCamera);
   1397 				break; 
   1398 			} 
   1399             break; 
   1400 
   1401 
   1402             default: 
   1403               return DefWindowProc( hwndDlg, uMsg, wParam, lParam ); 
   1404         } 
   1405 
   1406 		return 0;
   1407 	}
   1408 
   1409     return DefWindowProc (hwndDlg, uMsg, wParam, lParam);
   1410 }
   1411