/*
* 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 .
--- 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
#include "stdafx.h"
#include "editor.h"
#include "TextureDialog.h"
#include "HTexture.h"
#include "gametexture.h"
#include "gr.h"
#include "descent.h"
#include "erooms.h"
#include "mono.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 = std::max(r, g);
rmax = std::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");
}
}