mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 19:55:23 +00:00
1004 lines
22 KiB
C++
1004 lines
22 KiB
C++
/*
|
|
* Descent 3
|
|
* Copyright (C) 2024 Parallax Software
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
--- HISTORICAL COMMENTS FOLLOW ---
|
|
|
|
* $Logfile: /DescentIII/Main/editor/TextureDialog.cpp $
|
|
* $Revision: 1.1.1.1 $
|
|
* $Date: 2003-08-26 03:57:39 $
|
|
* $Author: kevinb $
|
|
*
|
|
* Texture Dialog keypad
|
|
*
|
|
* $Log: not supported by cvs2svn $
|
|
*
|
|
* 26 5/06/99 12:43p Matt
|
|
* Fixed a bug when did a texture grab on the terrain with no cells
|
|
* selected.
|
|
*
|
|
* 25 4/19/99 6:45p Jason
|
|
* fixed satellite grabbing bug
|
|
*
|
|
* 24 4/08/99 5:47p Jason
|
|
* added face finding function
|
|
*
|
|
* 23 2/23/99 3:07p Jason
|
|
* added grabbing of terrain textures
|
|
*
|
|
* 22 12/04/98 1:14p Jason
|
|
* added "Currently Used" texture flag
|
|
*
|
|
* 21 8/20/98 4:09p Jason
|
|
* added facemap feature
|
|
*
|
|
* 20 8/05/98 8:44p Jason
|
|
* added uniform scaling of textures
|
|
*
|
|
* 19 8/03/98 2:38p Matt
|
|
* Changed the replace texture function to replace all instances of a
|
|
* texture in the current room *or* in the whole mine, at the user's
|
|
* discretion.
|
|
*
|
|
* 18 6/23/98 2:43p Matt
|
|
* Changed calls to OutrageMessageBox() & Debug_MessageBox() to deal with
|
|
* int return value (instead of bool).
|
|
*
|
|
* 17 6/15/98 4:00p Jason
|
|
* replaced monochromatic polymodel lighting with rgb lighting
|
|
*
|
|
* 16 6/10/98 1:57p Samir
|
|
* fixed some listbox problems.
|
|
*
|
|
* 15 6/10/98 12:21p Matt
|
|
* Revamped system that controls what textures are displayed on the
|
|
* texture tab. Should work correctly now, and will now save the settings
|
|
* to the registry. Also, textures now default to no type set, not all
|
|
* types set.
|
|
*
|
|
* 14 5/20/98 1:08p Jason
|
|
* more stuff for adding bumpmaps
|
|
*
|
|
* 13 3/03/98 5:39p Jason
|
|
* added swatch to texture tab
|
|
*
|
|
* 12 11/14/97 12:41p Jason
|
|
* Added ReplaceTexture function
|
|
*
|
|
* 11 9/18/97 12:32p Samir
|
|
* If currently selected texture is not in the list, default to 0 texture.
|
|
*
|
|
* 10 9/17/97 1:01p Matt
|
|
* Ripped out segment code
|
|
*
|
|
* 9 9/17/97 12:06p Jason
|
|
* ripped out segment engine
|
|
*
|
|
* 8 9/16/97 6:08p Jason
|
|
* made texture names appear
|
|
*
|
|
* 7 9/15/97 1:18p Jason
|
|
* got selectable tmap2s working
|
|
*
|
|
* 6 9/12/97 3:47p Matt
|
|
* Fixed grab texture for room engine
|
|
*
|
|
* 5 8/29/97 1:52p Samir
|
|
* Added bitmap buttons for Texture Keypad.
|
|
*
|
|
* 4 8/25/97 7:39p Samir
|
|
* Using new GrListBox from old editorPictListBox
|
|
*
|
|
* 3 8/13/97 9:53a Matt
|
|
* Show selected texture with magenta box around it.
|
|
* Use new texture rotate & scale functions
|
|
*
|
|
* 15 6/03/97 4:55p Mark
|
|
*
|
|
* 15 6/3/97 4:14p Jeff
|
|
* Added Context Sensitive Help
|
|
*
|
|
* 14 5/28/97 6:15p Samir
|
|
* Fixups for missing textures in scrollbox.
|
|
*
|
|
* 13 5/27/97 5:29p Samir
|
|
* Took out mprintf.
|
|
*
|
|
* 12 5/27/97 3:11p Samir
|
|
* Allow 'masking' of textures to be displayed in listbox.
|
|
*
|
|
* 11 4/11/97 4:53p Samir
|
|
* Grab texture button works for tmap 1s
|
|
*
|
|
* 10 3/13/97 1:42p Matt
|
|
* Don't show texture 0 (the error texture) in the texture list
|
|
*
|
|
* 9 2/26/97 4:00p Samir
|
|
* Added most keypad functions.
|
|
*
|
|
* 8 2/21/97 6:25p Samir
|
|
* Set properly the max items for the listbox.
|
|
*
|
|
* 7 2/21/97 5:09p Samir
|
|
* Uses new PictListBox class for texture listbox here.
|
|
*
|
|
* 6 2/20/97 6:05p Samir
|
|
* Allow for clean activation and deactivation of surfaces in editor when
|
|
* going into fullscreen mode.
|
|
*
|
|
* 5 2/19/97 7:29p Samir
|
|
* Got scrolling texture view to work.
|
|
*
|
|
* 4 1/27/97 11:38a Samir
|
|
* Added horizontal scrolling of keypad modeless dialog.
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "editor.h"
|
|
#include "TextureDialog.h"
|
|
|
|
#include "HTexture.h"
|
|
#include "texture.h"
|
|
#include "gametexture.h"
|
|
#include "gr.h"
|
|
#include "descent.h"
|
|
#include "erooms.h"
|
|
#include "room.h"
|
|
#include "terrain.h"
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTextureDialog dialog
|
|
|
|
// Initialization and Destruction of the Dialog.
|
|
|
|
CTextureDialog::CTextureDialog(CWnd* pParent /*=NULL*/)
|
|
: CKeypadDialog(CTextureDialog::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CTextureDialog)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
|
|
void CTextureDialog::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CTextureDialog)
|
|
// NOTE: the ClassWizard will add DDX and DDV calls here
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
void CTextureDialog::RunKeypadFunction(int code)
|
|
{
|
|
switch (code)
|
|
{
|
|
case VK_NUMPAD0: OnTexpadRotate90(); break;
|
|
case VK_NUMPAD1: OnTexpadRotLeft(); break;
|
|
case VK_NUMPAD2: OnTexpadSlideDown(); break;
|
|
case VK_NUMPAD3: OnTexpadRotRight(); break;
|
|
case VK_NUMPAD4: OnTexpadSlideLeft(); break;
|
|
case VK_NUMPAD5: OnTexpadSetDefault(); break;
|
|
case VK_NUMPAD6: OnTexpadSlideRight(); break;
|
|
case VK_NUMPAD7: OnTexpadStretchLess(); break;
|
|
case VK_NUMPAD8: OnTexpadSlideUp(); break;
|
|
case VK_NUMPAD9: OnTexpadStretchMore(); break;
|
|
case VK_DELETE: OnTexpadNextEdge(); break;
|
|
}
|
|
}
|
|
|
|
|
|
// selects a texture in the texture dialog
|
|
void CTextureDialog::SelectTexture(int texnum)
|
|
{
|
|
m_TexLB.SelectItem(texnum);
|
|
}
|
|
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CTextureDialog, CDialog)
|
|
//{{AFX_MSG_MAP(CTextureDialog)
|
|
ON_WM_KEYDOWN()
|
|
ON_WM_SIZE()
|
|
ON_WM_VSCROLL()
|
|
ON_WM_HSCROLL()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_PAINT()
|
|
ON_BN_CLICKED(IDC_TEXPAD_FLIPX, OnTexpadFlipX)
|
|
ON_BN_CLICKED(IDC_TEXPAD_FLIPY, OnTexpadFlipY)
|
|
ON_BN_CLICKED(IDC_TEXPAD_SLIDELEFT, OnTexpadSlideLeft)
|
|
ON_BN_CLICKED(IDC_TEXPAD_SLIDERIGHT, OnTexpadSlideRight)
|
|
ON_BN_CLICKED(IDC_TEXPAD_ROTLEFT, OnTexpadRotLeft)
|
|
ON_BN_CLICKED(IDC_TEXPAD_ROTRIGHT, OnTexpadRotRight)
|
|
ON_BN_CLICKED(IDC_TEXPAD_ROTATE90, OnTexpadRotate90)
|
|
ON_BN_CLICKED(IDC_TEXPAD_STRETCHLESS, OnTexpadStretchLess)
|
|
ON_BN_CLICKED(IDC_TEXPAD_STRETCHMORE, OnTexpadStretchMore)
|
|
ON_BN_CLICKED(IDC_TEXPAD_SLIDEUP, OnTexpadSlideUp)
|
|
ON_BN_CLICKED(IDC_TEXPAD_SLIDEDOWN, OnTexpadSlideDown)
|
|
ON_BN_CLICKED(IDC_TEXPAD_SETDEFAULT, OnTexpadSetDefault)
|
|
ON_BN_CLICKED(IDC_TEXPAD_NEXTEDGE, OnTexpadNextEdge)
|
|
ON_BN_CLICKED(IDC_TEXPAD_GRAB, OnTexpadGrab)
|
|
ON_BN_CLICKED(IDC_SHOW_MINE_TEXTURES2, OnShowMineTextures2)
|
|
ON_BN_CLICKED(IDC_SHOW_OBJ_TEXTURES, OnShowObjTextures)
|
|
ON_BN_CLICKED(IDC_SHOW_LIGHT_TEXTURES, OnShowLightTextures)
|
|
ON_BN_CLICKED(IDC_SHOW_TERRAIN_TEXTURES, OnShowTerrainTextures)
|
|
ON_WM_HELPINFO()
|
|
ON_BN_CLICKED(IDC_RESET_ALL_TEXTURES, OnResetAllTextures)
|
|
ON_WM_DESTROY()
|
|
ON_BN_CLICKED(IDC_SHOW_TMAP2_TEXTURES, OnShowTmap2Textures)
|
|
ON_BN_CLICKED(IDC_REPLACE_TEXTURE, OnReplaceTexture)
|
|
ON_EN_KILLFOCUS(IDC_TEXSCALE_EDIT, OnKillfocusTexscaleEdit)
|
|
ON_BN_CLICKED(IDC_TEXPAD_EXPAND_U, OnTexpadExpandU)
|
|
ON_BN_CLICKED(IDC_TEXPAD_EXPAND_V, OnTexpadExpandV)
|
|
ON_BN_CLICKED(IDC_TEXPAD_CONTRACT_U, OnTexpadContractU)
|
|
ON_BN_CLICKED(IDC_TEXPAD_CONTRACT_V, OnTexpadContractV)
|
|
ON_BN_CLICKED(IDC_FACE_MAP, OnFaceMap)
|
|
ON_BN_CLICKED(IDC_CURRENT_USED, OnCurrentUsed)
|
|
ON_BN_CLICKED(IDC_FIND_TEXTURE, OnFindTexture)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTextureDialog message handlers
|
|
|
|
static CDialog *ParentDialog=NULL;
|
|
static CTextureDialog *ParentTextureDialog=NULL;
|
|
uint8_t CurrentlyUsedTextures[MAX_TEXTURES];
|
|
bool Show_used=0;
|
|
|
|
BOOL CTextureDialog::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
RECT rect;
|
|
CWnd *wnd;
|
|
CEdit *ebox;
|
|
char str[20];
|
|
|
|
memset (CurrentlyUsedTextures,0,MAX_TEXTURES);
|
|
|
|
ParentDialog=this;
|
|
ParentTextureDialog=this;
|
|
wnd = GetDlgItem(IDC_TEXTURE_LISTBOX);
|
|
wnd->GetClientRect(&rect);
|
|
|
|
if (!GameTextures[D3EditState.texdlg_texture].used) D3EditState.texdlg_texture = 0;
|
|
|
|
m_TexLB.Create(wnd, IDC_TEXTURE_LISTBOX, rect, 36);
|
|
m_TexLB.SelectItem(D3EditState.texdlg_texture);
|
|
|
|
if (D3EditState.texture_display_flags & TF_TERRAIN)
|
|
((CButton *)GetDlgItem(IDC_SHOW_TERRAIN_TEXTURES))->SetCheck(1);
|
|
if (D3EditState.texture_display_flags & TF_MINE)
|
|
((CButton *)GetDlgItem(IDC_SHOW_MINE_TEXTURES2))->SetCheck(1);
|
|
if (D3EditState.texture_display_flags & TF_OBJECT)
|
|
((CButton *)GetDlgItem(IDC_SHOW_OBJ_TEXTURES))->SetCheck(1);
|
|
if (D3EditState.texture_display_flags & TF_TMAP2)
|
|
((CButton *)GetDlgItem(IDC_SHOW_TMAP2_TEXTURES))->SetCheck(1);
|
|
if (D3EditState.texture_display_flags & TF_LIGHT)
|
|
((CButton *)GetDlgItem(IDC_SHOW_LIGHT_TEXTURES))->SetCheck(1);
|
|
|
|
// Do bitmap buttons
|
|
m_bmUp.LoadBitmap(IDB_NORTH);
|
|
m_bmDown.LoadBitmap(IDB_SOUTH);
|
|
m_bmLeft.LoadBitmap(IDB_WEST);
|
|
m_bmRight.LoadBitmap(IDB_EAST);
|
|
m_bmRotLeft.LoadBitmap(IDB_ROTATELEFT);
|
|
m_bmRotRight.LoadBitmap(IDB_ROTATERIGHT);
|
|
m_bmStretchLess.LoadBitmap(IDB_INARROW);
|
|
m_bmStretchMore.LoadBitmap(IDB_OUTARROW);
|
|
|
|
// Set bitmap buttons
|
|
CButton *btn;
|
|
btn = (CButton*)GetDlgItem(IDC_TEXPAD_SLIDEUP);
|
|
btn->SetBitmap((HBITMAP)m_bmUp);
|
|
btn = (CButton*)GetDlgItem(IDC_TEXPAD_SLIDEDOWN);
|
|
btn->SetBitmap((HBITMAP)m_bmDown);
|
|
btn = (CButton*)GetDlgItem(IDC_TEXPAD_SLIDELEFT);
|
|
btn->SetBitmap((HBITMAP)m_bmLeft);
|
|
btn = (CButton*)GetDlgItem(IDC_TEXPAD_SLIDERIGHT);
|
|
btn->SetBitmap((HBITMAP)m_bmRight);
|
|
btn = (CButton*)GetDlgItem(IDC_TEXPAD_ROTLEFT);
|
|
btn->SetBitmap((HBITMAP)m_bmRotLeft);
|
|
btn = (CButton*)GetDlgItem(IDC_TEXPAD_ROTRIGHT);
|
|
btn->SetBitmap((HBITMAP)m_bmRotRight);
|
|
btn = (CButton*)GetDlgItem(IDC_TEXPAD_STRETCHLESS);
|
|
btn->SetBitmap((HBITMAP)m_bmStretchLess);
|
|
btn = (CButton*)GetDlgItem(IDC_TEXPAD_STRETCHMORE);
|
|
btn->SetBitmap((HBITMAP)m_bmStretchMore);
|
|
|
|
ebox=(CEdit *) GetDlgItem (IDC_TEXSCALE_EDIT);
|
|
sprintf (str,"%f",D3EditState.texscale);
|
|
ebox->SetWindowText (str);
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnDestroy()
|
|
{
|
|
CDialog::OnDestroy();
|
|
|
|
// kill all bitmaps
|
|
m_bmUp.DeleteObject();
|
|
m_bmDown.DeleteObject();
|
|
m_bmLeft.DeleteObject();
|
|
m_bmRight.DeleteObject();
|
|
m_bmRotLeft.DeleteObject();
|
|
m_bmRotRight.DeleteObject();
|
|
m_bmStretchLess.DeleteObject();
|
|
m_bmStretchMore.DeleteObject();
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
|
|
CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CKeypadDialog::OnSize(nType, cx, cy);
|
|
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
CKeypadDialog::OnVScroll(nSBCode, nPos, pScrollBar);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
|
|
CKeypadDialog::OnHScroll(nSBCode, nPos, pScrollBar);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
CDialog::OnLButtonDown(nFlags, point);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnPaint()
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
if (!m_Active) return;
|
|
}
|
|
|
|
|
|
// Keypad Functions!!
|
|
|
|
void CTextureDialog::OnTexpadFlipX()
|
|
{
|
|
HTextureFlipX();
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadFlipY()
|
|
{
|
|
HTextureFlipY();
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadSlideLeft()
|
|
{
|
|
HTextureSlide(Curroomp, Curface, (float) -1.0*D3EditState.texscale, 0.0f);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadSlideRight()
|
|
{
|
|
HTextureSlide(Curroomp, Curface, (float) 1.0*D3EditState.texscale, 0.0f);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadSlideUp()
|
|
{
|
|
HTextureSlide(Curroomp, Curface, 0.0f, (float) 1.0*D3EditState.texscale);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadSlideDown()
|
|
{
|
|
HTextureSlide(Curroomp, Curface, 0.0f, (float) -1.0*D3EditState.texscale);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadRotLeft()
|
|
{
|
|
HTextureRotate(Curroomp, Curface, (-512*D3EditState.texscale));
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadRotRight()
|
|
{
|
|
HTextureRotate(Curroomp, Curface, (512*D3EditState.texscale));
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadRotate90()
|
|
{
|
|
HTextureRotate(Curroomp, Curface, 0x4000);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadStretchLess()
|
|
{
|
|
HTextureStretchLess(Curroomp, Curface, Curedge);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadStretchMore()
|
|
{
|
|
HTextureStretchMore(Curroomp, Curface, Curedge);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadSetDefault()
|
|
{
|
|
HTextureSetDefault(Curroomp);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadNextEdge()
|
|
{
|
|
HTextureNextEdge();
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnTexpadGrab()
|
|
{
|
|
int texnum=-1;
|
|
|
|
if (Editor_view_mode==VM_TERRAIN)
|
|
{
|
|
for (int i=0;i<TERRAIN_WIDTH*TERRAIN_DEPTH;i++)
|
|
{
|
|
if (TerrainSelected[i])
|
|
{
|
|
if (texnum != -1) {
|
|
OutrageMessageBox("Cannot grab texture: More than one terrain cell selected.");
|
|
return;
|
|
}
|
|
texnum=Terrain_tex_seg[Terrain_seg[i].texseg_index].tex_index;
|
|
}
|
|
}
|
|
if (texnum == -1) {
|
|
OutrageMessageBox("Cannot grab texture: No terrain cell selected.");
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!Curroomp || Curroomp->used==0 || Curface>=Curroomp->num_faces)
|
|
return;
|
|
|
|
texnum = Curroomp->faces[Curface].tmap;
|
|
}
|
|
|
|
CTextureDialog::SelectTexture(texnum);
|
|
EditorStatus("Texture %d, \"%s\", selected.",texnum,GameTextures[texnum].name);
|
|
}
|
|
|
|
|
|
void CTextureDialog::OnShowMineTextures2()
|
|
{
|
|
D3EditState.texture_display_flags ^= TF_MINE;
|
|
Invalidate();
|
|
}
|
|
|
|
void CTextureDialog::OnShowObjTextures()
|
|
{
|
|
D3EditState.texture_display_flags ^= TF_OBJECT;
|
|
Invalidate();
|
|
}
|
|
|
|
void CTextureDialog::OnShowLightTextures()
|
|
{
|
|
D3EditState.texture_display_flags ^= TF_LIGHT;
|
|
Invalidate();
|
|
}
|
|
|
|
void CTextureDialog::OnShowTerrainTextures()
|
|
{
|
|
D3EditState.texture_display_flags ^= TF_TERRAIN;
|
|
Invalidate();
|
|
}
|
|
|
|
BOOL CTextureDialog::OnHelpInfo(HELPINFO* pHelpInfo)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
WinHelp(HID_TEXTURETAB,HELP_CONTEXT);
|
|
return TRUE;
|
|
//return CDialog::OnHelpInfo(pHelpInfo);
|
|
}
|
|
|
|
extern void AssignDefaultUVsToRoom(room *rp);
|
|
void CTextureDialog::OnResetAllTextures()
|
|
{
|
|
int answer=OutrageMessageBox (MBOX_YESNO,"Are you sure you wish to reset all textures for this room? This change cannot be undone!");
|
|
if (answer!=IDYES)
|
|
return;
|
|
|
|
AssignDefaultUVsToRoom (Curroomp);
|
|
|
|
World_changed=1;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CGrTextureListBox implementation
|
|
|
|
// enumerates items maximum in the list box. this is here to insure that any changes in
|
|
// the user-managed list.
|
|
int CGrTextureListBox::ListEnumerate()
|
|
{
|
|
int count = 0,i;
|
|
|
|
for (i=0;i<MAX_TEXTURES;i++)
|
|
{
|
|
bool countit=true;;
|
|
if (!GameTextures[i].used)
|
|
countit=false;
|
|
if (!(GameTextures[i].flags & D3EditState.texture_display_flags))
|
|
countit=false;
|
|
if (Show_used && !CurrentlyUsedTextures[i])
|
|
countit=false;
|
|
|
|
if (countit)
|
|
count++;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
// Specify the first item to be drawn in the box by DrawItem. returns the item #
|
|
// return -1 if there is no first item (list is empty, maybe)
|
|
int CGrTextureListBox::ListFirstItem(int firsttex)
|
|
{
|
|
// skip the error texture
|
|
if (firsttex < 0) firsttex = 0;
|
|
if (firsttex == 0) firsttex++;
|
|
|
|
// find first texture that is used if the texture passed became invalid.
|
|
if (!GameTextures[firsttex].used || !(GameTextures[firsttex].flags & D3EditState.texture_display_flags) || (Show_used && !CurrentlyUsedTextures[firsttex])) {
|
|
int new_first = ListNextItem(firsttex);
|
|
if (new_first == firsttex)
|
|
return -1;
|
|
else
|
|
return new_first;
|
|
}
|
|
else
|
|
return firsttex;
|
|
}
|
|
|
|
|
|
// Specify the next/prev item to be drawn in the box by DrawItem.
|
|
// Returns the item # following or preceding the passed the item #
|
|
int CGrTextureListBox::ListNextItem(int curtex)
|
|
{
|
|
int next_texture = -1;
|
|
|
|
if (curtex >= 0)
|
|
next_texture = GetNextTexture(curtex);
|
|
if (next_texture <= curtex)
|
|
return curtex;
|
|
|
|
while ((Show_used && !CurrentlyUsedTextures[next_texture]) || !(GameTextures[next_texture].flags & D3EditState.texture_display_flags) )
|
|
{
|
|
next_texture = GetNextTexture(next_texture);
|
|
// mprintf((0, "next_tex = %d\n", next_texture));
|
|
if (next_texture == curtex) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return next_texture;
|
|
}
|
|
|
|
|
|
int CGrTextureListBox::ListPrevItem(int curtex)
|
|
{
|
|
int prev_texture = -1;
|
|
|
|
if (curtex >=0)
|
|
prev_texture = GetPreviousTexture(curtex);
|
|
if (prev_texture >= curtex)
|
|
return curtex;
|
|
|
|
while ((Show_used && !CurrentlyUsedTextures[prev_texture]) || !(GameTextures[prev_texture].flags & D3EditState.texture_display_flags) )
|
|
{
|
|
prev_texture = GetPreviousTexture(prev_texture);
|
|
// mprintf((0, "prev_tex = %d\n", prev_texture));
|
|
if (prev_texture == curtex) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return prev_texture;
|
|
}
|
|
|
|
|
|
// draw the item
|
|
void CGrTextureListBox::DrawItem(int x, int y, grHardwareSurface *itemsurf, int item)
|
|
{
|
|
int bm_handle;
|
|
|
|
bm_handle = GetTextureBitmap (item,0);
|
|
|
|
itemsurf->load(bm_handle);
|
|
Desktop_surf->blt(x, y, itemsurf);
|
|
}
|
|
|
|
|
|
// if item was selected from the list box, this function is invoked.
|
|
void CGrTextureListBox::OnItemSelected(int tex)
|
|
{
|
|
D3EditState.texdlg_texture = tex;
|
|
|
|
if (ParentDialog!=NULL)
|
|
{
|
|
PrintToDlgItem (ParentDialog,IDC_CURRENT_TEXTURE_NAME,"Texture: %s",GameTextures[tex].name);
|
|
ParentTextureDialog->DrawSwatch (IDC_TEXTURE_SWATCH,GameTextures[tex].r,GameTextures[tex].g,GameTextures[tex].b);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CTextureDialog::OnShowTmap2Textures()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
D3EditState.texture_display_flags ^= TF_TMAP2;
|
|
Invalidate();
|
|
|
|
}
|
|
|
|
//Returns the number of changes
|
|
int ReplaceTextureInRoom(room *rp,int old_tmap,int new_tmap)
|
|
{
|
|
int n_changes = 0;
|
|
|
|
for (int i=0;i<rp->num_faces;i++) {
|
|
|
|
if (rp->faces[i].tmap == old_tmap) {
|
|
|
|
rp->faces[i].tmap = new_tmap;
|
|
n_changes++;
|
|
}
|
|
}
|
|
|
|
return n_changes;
|
|
}
|
|
|
|
void CTextureDialog::OnReplaceTexture()
|
|
{
|
|
ASSERT (Curroomp!=NULL);
|
|
int n_changes;
|
|
|
|
int answer = OutrageMessageBox(MBOX_YESNOCANCEL,"Do you wish to change this texture for the whole mine?\n\n(Answer NO to change only the current room.)");
|
|
|
|
if (answer == IDCANCEL)
|
|
return;
|
|
|
|
int selected_texture=Curroomp->faces[Curface].tmap;
|
|
|
|
if (answer == IDYES) {
|
|
|
|
n_changes = 0;
|
|
|
|
for (int r=0;r<=Highest_room_index;r++)
|
|
if (Rooms[r].used)
|
|
n_changes += ReplaceTextureInRoom(&Rooms[r],selected_texture,D3EditState.texdlg_texture);
|
|
}
|
|
else {
|
|
|
|
n_changes = ReplaceTextureInRoom(Curroomp,selected_texture,D3EditState.texdlg_texture);
|
|
}
|
|
|
|
EditorStatus("Texture %d replaced with texture %d on %d faces.",selected_texture,D3EditState.texdlg_texture,n_changes);
|
|
|
|
World_changed=1;
|
|
|
|
}
|
|
|
|
void CTextureDialog::DrawSwatch(int handle,float r,float g,float b)
|
|
{
|
|
CWnd *texwnd;
|
|
RECT rect;
|
|
int w,h;
|
|
float rmax=max(r,g);
|
|
rmax=max(rmax,b);
|
|
|
|
if (rmax>=.001)
|
|
{
|
|
r/=rmax;
|
|
g/=rmax;
|
|
b/=rmax;
|
|
}
|
|
|
|
texwnd = GetDlgItem(handle);
|
|
texwnd->GetWindowRect(&rect);
|
|
ScreenToClient(&rect);
|
|
|
|
Desktop_surf->attach_to_window((unsigned)m_hWnd);
|
|
|
|
w=rect.right-rect.left;
|
|
h=rect.bottom-rect.top;
|
|
|
|
ddgr_color color=GR_RGB(r*255,g*255,b*255);
|
|
|
|
Desktop_surf->clear(rect.left,rect.top,w,h,color);
|
|
|
|
Desktop_surf->attach_to_window(NULL);
|
|
|
|
}
|
|
|
|
void CTextureDialog::OnKillfocusTexscaleEdit()
|
|
{
|
|
CEdit *ebox;
|
|
char str[20];
|
|
float val;
|
|
|
|
ebox=(CEdit *) GetDlgItem (IDC_TEXSCALE_EDIT);
|
|
ebox->GetWindowText (str,20);
|
|
|
|
val = atof (str);
|
|
if (val<0)
|
|
val=0;
|
|
if (val>64)
|
|
val=64;
|
|
|
|
D3EditState.texscale=val;
|
|
|
|
ebox=(CEdit *) GetDlgItem (IDC_TEXSCALE_EDIT);
|
|
sprintf (str,"%f",D3EditState.texscale);
|
|
ebox->SetWindowText (str);
|
|
|
|
}
|
|
|
|
void CTextureDialog::OnTexpadExpandU()
|
|
{
|
|
if (Curroomp==NULL)
|
|
return;
|
|
|
|
face *fp=&Curroomp->faces[Curface];
|
|
|
|
int i;
|
|
float mid=0;
|
|
|
|
for (i=0;i<fp->num_verts;i++)
|
|
mid+=fp->face_uvls[i].u;
|
|
|
|
mid/=fp->num_verts;
|
|
|
|
for (i=0;i<fp->num_verts;i++)
|
|
{
|
|
float diff=fp->face_uvls[i].u-mid;
|
|
|
|
diff*=1.0/D3EditState.texscale;
|
|
|
|
fp->face_uvls[i].u=mid+diff;
|
|
}
|
|
|
|
World_changed=1;
|
|
}
|
|
|
|
void CTextureDialog::OnTexpadExpandV()
|
|
{
|
|
if (Curroomp==NULL)
|
|
return;
|
|
|
|
face *fp=&Curroomp->faces[Curface];
|
|
|
|
int i;
|
|
float mid=0;
|
|
|
|
for (i=0;i<fp->num_verts;i++)
|
|
mid+=fp->face_uvls[i].v;
|
|
|
|
mid/=fp->num_verts;
|
|
|
|
for (i=0;i<fp->num_verts;i++)
|
|
{
|
|
float diff=fp->face_uvls[i].v-mid;
|
|
|
|
diff*=1.0/D3EditState.texscale;
|
|
|
|
fp->face_uvls[i].v=mid+diff;
|
|
}
|
|
|
|
World_changed=1;
|
|
|
|
}
|
|
|
|
void CTextureDialog::OnTexpadContractU()
|
|
{
|
|
if (Curroomp==NULL)
|
|
return;
|
|
|
|
face *fp=&Curroomp->faces[Curface];
|
|
|
|
int i;
|
|
float mid=0;
|
|
|
|
for (i=0;i<fp->num_verts;i++)
|
|
mid+=fp->face_uvls[i].u;
|
|
|
|
mid/=fp->num_verts;
|
|
|
|
for (i=0;i<fp->num_verts;i++)
|
|
{
|
|
float diff=fp->face_uvls[i].u-mid;
|
|
|
|
diff*=D3EditState.texscale;
|
|
|
|
fp->face_uvls[i].u=mid+diff;
|
|
}
|
|
|
|
World_changed=1;
|
|
|
|
}
|
|
|
|
void CTextureDialog::OnTexpadContractV()
|
|
{
|
|
if (Curroomp==NULL)
|
|
return;
|
|
|
|
face *fp=&Curroomp->faces[Curface];
|
|
|
|
int i;
|
|
float mid=0;
|
|
|
|
for (i=0;i<fp->num_verts;i++)
|
|
mid+=fp->face_uvls[i].v;
|
|
|
|
mid/=fp->num_verts;
|
|
|
|
for (i=0;i<fp->num_verts;i++)
|
|
{
|
|
float diff=fp->face_uvls[i].v-mid;
|
|
|
|
diff*=D3EditState.texscale;
|
|
|
|
fp->face_uvls[i].v=mid+diff;
|
|
}
|
|
|
|
World_changed=1;
|
|
|
|
}
|
|
|
|
void CTextureDialog::OnFaceMap()
|
|
{
|
|
if (Curroomp==NULL)
|
|
return;
|
|
|
|
face *fp=&Curroomp->faces[Curface];
|
|
|
|
if (fp->num_verts!=4)
|
|
{
|
|
OutrageMessageBox ("Face must have four vertices to use face mapping.");
|
|
return;
|
|
}
|
|
|
|
// Simply square off this face
|
|
|
|
fp->face_uvls[0].u=0.0;
|
|
fp->face_uvls[0].v=0.0;
|
|
|
|
fp->face_uvls[1].u=1.0;
|
|
fp->face_uvls[1].v=0.0;
|
|
|
|
fp->face_uvls[2].u=1.0;
|
|
fp->face_uvls[2].v=1.0;
|
|
|
|
fp->face_uvls[3].u=0.0;
|
|
fp->face_uvls[3].v=1.0;
|
|
|
|
World_changed=1;
|
|
}
|
|
|
|
void CTextureDialog::OnCurrentUsed()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
int c=IsDlgButtonChecked(IDC_CURRENT_USED);
|
|
|
|
// If we just turned this on, build a list of textures used
|
|
if (c)
|
|
{
|
|
Show_used=1;
|
|
memset (CurrentlyUsedTextures,0,MAX_TEXTURES);
|
|
for (int i=0;i<=Highest_room_index;i++)
|
|
{
|
|
room *rp=&Rooms[i];
|
|
if (!rp->used)
|
|
continue;
|
|
for (int t=0;t<rp->num_faces;t++)
|
|
{
|
|
CurrentlyUsedTextures[rp->faces[t].tmap]=1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
Show_used=0;
|
|
|
|
Invalidate();
|
|
|
|
}
|
|
|
|
void CTextureDialog::OnFindTexture()
|
|
{
|
|
int i,t;
|
|
|
|
mprintf ((0,"Searching...please wait...\n"));
|
|
int found=0,found_room,found_face;
|
|
|
|
for (i=0;i<=Highest_room_index && !found;i++)
|
|
{
|
|
room *rp=&Rooms[i];
|
|
if (rp->used==0)
|
|
continue;
|
|
|
|
for (t=0;t<rp->num_faces && !found;t++)
|
|
{
|
|
if (rp->faces[t].tmap==D3EditState.texdlg_texture)
|
|
{
|
|
if (rp!=Curroomp || t!=Curface)
|
|
{
|
|
found_room=i;
|
|
found_face=t;
|
|
found=1;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
mprintf ((0,"Done searching!\n"));
|
|
|
|
if (found==0)
|
|
{
|
|
mprintf ((0,"Couldn't find another face with that texture!\n"));
|
|
}
|
|
else
|
|
{
|
|
Curroomp=&Rooms[found_room];
|
|
Curface=found_face;
|
|
mprintf ((0,"Found that texture in room %d face %d.\n",found_room,found_face));
|
|
mprintf ((0,"Press C to center on that face\n"));
|
|
}
|
|
|
|
}
|