mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 08:15:59 -10:00
398 lines
8.9 KiB
C++
398 lines
8.9 KiB
C++
// ShipTexturesDlg.cpp : implementation file
|
|
// Goober5000
|
|
|
|
#include "stdafx.h"
|
|
#include "fred.h"
|
|
#include "ShipTexturesDlg.h"
|
|
#include "model/model.h"
|
|
#include "bmpman/bmpman.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CShipTexturesDlg dialog
|
|
|
|
|
|
CShipTexturesDlg::CShipTexturesDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CShipTexturesDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CShipTexturesDlg)
|
|
m_new_texture = _T("");
|
|
m_old_texture_list = 0;
|
|
//}}AFX_DATA_INIT
|
|
|
|
self_ship = -1;
|
|
active_texture_index = -1;
|
|
modified = 0;
|
|
texture_count = 0;
|
|
}
|
|
|
|
|
|
void CShipTexturesDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
|
|
//{{AFX_DATA_MAP(CShipTexturesDlg)
|
|
DDX_Text(pDX, IDC_NEW_TEXTURE, m_new_texture);
|
|
DDX_CBIndex(pDX, IDC_OLD_TEXTURE_LIST, m_old_texture_list);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CShipTexturesDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CShipTexturesDlg)
|
|
ON_WM_CLOSE()
|
|
ON_CBN_SELCHANGE(IDC_OLD_TEXTURE_LIST, OnSelchangeOldTextureList)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CShipTexturesDlg message handlers
|
|
|
|
void CShipTexturesDlg::OnOK()
|
|
{
|
|
int i, z, not_found, temp_bmp, temp_frames, temp_fps;
|
|
CString missing_files, message;
|
|
char buf[10];
|
|
|
|
// update, in case of a last-minute edit
|
|
OnSelchangeOldTextureList();
|
|
|
|
// quick skip if nothing modified
|
|
if (query_modified())
|
|
{
|
|
// sort according to new
|
|
sort_textures(SORT_NEW);
|
|
|
|
// check for filenames not found
|
|
not_found = 0;
|
|
missing_files = _T("");
|
|
for (i=0; i<texture_count; i++)
|
|
{
|
|
// make sure we have a texture
|
|
if (strlen(new_texture_name[i]))
|
|
{
|
|
// allow invisible textures without doing a file check
|
|
if (!stricmp(new_texture_name[i], "invisible"))
|
|
continue;
|
|
|
|
// try loading the texture (bmpman should take care of eventually unloading it)
|
|
temp_bmp = bm_load( new_texture_name[i] );
|
|
|
|
// if PCX not found, look for ANI
|
|
if (temp_bmp < 0)
|
|
{
|
|
temp_bmp = bm_load_animation(new_texture_name[i], &temp_frames, &temp_fps, nullptr, nullptr, nullptr, true);
|
|
}
|
|
|
|
// check if loaded
|
|
if (temp_bmp < 0)
|
|
{
|
|
not_found++;
|
|
missing_files += " ";
|
|
missing_files += new_texture_name[i];
|
|
missing_files += '\n';
|
|
}
|
|
}
|
|
}
|
|
|
|
// alert user if any textures were not found
|
|
if (not_found)
|
|
{
|
|
sprintf(buf, "%d", not_found);
|
|
message = "FRED was unable to find ";
|
|
message += buf;
|
|
message += ((not_found > 1) ? " files:\n" : " file:\n");
|
|
message += missing_files;
|
|
message += "\nContinue anyway?";
|
|
|
|
z = MessageBox(message, ((not_found > 1) ? "Some textures were not found." : "A texture was not found."), MB_OKCANCEL | MB_ICONEXCLAMATION | MB_DEFBUTTON2);
|
|
if (z == IDCANCEL)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
// re-sort according to old
|
|
sort_textures();
|
|
|
|
// overwrite all the old entries that refer to this ship
|
|
SCP_vector<texture_replace>::iterator ii, end;
|
|
end = Fred_texture_replacements.end();
|
|
for (ii = Fred_texture_replacements.begin(); ii != end; ++ii)
|
|
{
|
|
if (!stricmp(ii->ship_name, Ships[self_ship].ship_name))
|
|
{
|
|
do {
|
|
end--;
|
|
} while (end != ii && !stricmp(end->ship_name, Ships[self_ship].ship_name));
|
|
if (end == ii)
|
|
break;
|
|
texture_set(&(*ii), &(*end));
|
|
}
|
|
}
|
|
|
|
if (end != Fred_texture_replacements.end())
|
|
Fred_texture_replacements.erase(end, Fred_texture_replacements.end());
|
|
|
|
// now put the new entries on the end of the list
|
|
for (i=0; i<texture_count; i++)
|
|
{
|
|
// make sure there is an entry
|
|
if (strlen(new_texture_name[i]))
|
|
{
|
|
texture_replace tr;
|
|
|
|
strcpy_s(tr.old_texture, old_texture_name[i]);
|
|
strcpy_s(tr.new_texture, new_texture_name[i]);
|
|
strcpy_s(tr.ship_name, Ships[self_ship].ship_name);
|
|
tr.new_texture_id = -1;
|
|
tr.from_table = false;
|
|
|
|
// assign to global FRED array
|
|
Fred_texture_replacements.push_back(tr);
|
|
}
|
|
}
|
|
} // skipped here if nothing modified
|
|
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
BOOL CShipTexturesDlg::OnInitDialog()
|
|
{
|
|
int i, j, k, z, duplicate;
|
|
char *p = NULL;
|
|
char texture_file[MAX_FILENAME_LEN];
|
|
CComboBox *box;
|
|
|
|
// get our model
|
|
polymodel *pm = model_get(Ship_info[Ships[self_ship].ship_info_index].model_num);
|
|
|
|
// empty old and new fields
|
|
texture_count = 0;
|
|
for (i=0; i<MAX_REPLACEMENT_TEXTURES; i++)
|
|
{
|
|
*old_texture_name[i] = 0;
|
|
*new_texture_name[i] = 0;
|
|
}
|
|
|
|
// set up pointer to combo box
|
|
box = (CComboBox *) GetDlgItem(IDC_OLD_TEXTURE_LIST);
|
|
box->ResetContent();
|
|
|
|
// look for textures to populate the combo box
|
|
for (i=0; i<pm->n_textures; i++)
|
|
{
|
|
for(j = 0; j < TM_NUM_TYPES; j++)
|
|
{
|
|
// get texture file name
|
|
bm_get_filename(pm->maps[i].textures[j].GetOriginalTexture(), texture_file);
|
|
|
|
// skip blank textures
|
|
if (!strlen(texture_file))
|
|
continue;
|
|
|
|
// get rid of file extension
|
|
p = strchr( texture_file, '.' );
|
|
if ( p )
|
|
{
|
|
//mprintf(( "ignoring extension on file '%s'\n", texture_file ));
|
|
*p = 0;
|
|
}
|
|
|
|
// check for duplicate textures in list
|
|
duplicate = -1;
|
|
for (k=0; k<texture_count; k++)
|
|
{
|
|
if (!stricmp(old_texture_name[k], texture_file))
|
|
{
|
|
duplicate = k;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (duplicate >= 0)
|
|
continue;
|
|
|
|
// make old texture lowercase
|
|
strlwr(texture_file);
|
|
|
|
// add it to the field
|
|
strcpy_s(old_texture_name[texture_count], texture_file);
|
|
|
|
// increment
|
|
texture_count++;
|
|
}
|
|
}
|
|
|
|
// now sort the filenames
|
|
sort_textures();
|
|
|
|
// and add them to the box
|
|
for (i=0; i<texture_count; i++) {
|
|
z = box->AddString(old_texture_name[i]);
|
|
}
|
|
|
|
// now look for new textures
|
|
for (SCP_vector<texture_replace>::iterator ii = Fred_texture_replacements.begin(); ii != Fred_texture_replacements.end(); ++ii)
|
|
{
|
|
if (!stricmp(Ships[self_ship].ship_name, ii->ship_name) && !(ii->from_table))
|
|
{
|
|
// look for corresponding old texture
|
|
for (i=0; i<texture_count; i++)
|
|
{
|
|
// if match
|
|
if (!stricmp(old_texture_name[i], ii->old_texture))
|
|
{
|
|
// assign new texture
|
|
strcpy_s(new_texture_name[i], ii->new_texture);
|
|
|
|
// we found one, so no more to check
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// end of new texture check
|
|
|
|
// set indexes and flags
|
|
m_old_texture_list = 0;
|
|
active_texture_index = 0;
|
|
modified = 0;
|
|
|
|
// display new texture, if we have one
|
|
m_new_texture = CString(new_texture_name[0]);
|
|
|
|
CDialog::OnInitDialog();
|
|
UpdateData(FALSE);
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
BOOL CShipTexturesDlg::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
|
|
{
|
|
return CDialog::Create(IDD, pParentWnd);
|
|
}
|
|
|
|
void CShipTexturesDlg::OnClose()
|
|
{
|
|
int z;
|
|
|
|
if (query_modified()) {
|
|
z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
|
|
if (z == IDCANCEL)
|
|
return;
|
|
|
|
if (z == IDYES) {
|
|
OnOK();
|
|
return;
|
|
}
|
|
}
|
|
|
|
CDialog::OnClose();
|
|
}
|
|
|
|
int CShipTexturesDlg::query_modified()
|
|
{
|
|
return modified;
|
|
}
|
|
|
|
void CShipTexturesDlg::OnSelchangeOldTextureList()
|
|
{
|
|
UpdateData(TRUE);
|
|
|
|
char *p;
|
|
|
|
// see if we edited anything
|
|
if (stricmp(new_texture_name[active_texture_index], m_new_texture))
|
|
{
|
|
// assign it
|
|
strcpy_s(new_texture_name[active_texture_index], m_new_texture);
|
|
|
|
// make it lowercase
|
|
strlwr(new_texture_name[active_texture_index]);
|
|
|
|
// get rid of file extension
|
|
p = strchr( new_texture_name[active_texture_index], '.' );
|
|
if ( p )
|
|
{
|
|
mprintf(( "ignoring extension on file '%s'\n", new_texture_name[active_texture_index] ));
|
|
*p = 0;
|
|
}
|
|
|
|
// set modified flag
|
|
modified = 1;
|
|
}
|
|
|
|
// bring active texture index up to date
|
|
active_texture_index = m_old_texture_list;
|
|
|
|
// display appropriate texture
|
|
m_new_texture = CString(new_texture_name[active_texture_index]);
|
|
|
|
UpdateData(FALSE);
|
|
}
|
|
|
|
// bubble sort
|
|
void CShipTexturesDlg::sort_textures(int test)
|
|
{
|
|
int i, j, str_check = 0;
|
|
|
|
for (i = 0; i < texture_count; i++)
|
|
{
|
|
for (j = 0; j < i; j++)
|
|
{
|
|
switch(test)
|
|
{
|
|
case SORT_OLD:
|
|
str_check = stricmp(old_texture_name[i], old_texture_name[j]);
|
|
break;
|
|
case SORT_NEW:
|
|
str_check = stricmp(new_texture_name[i], new_texture_name[j]);
|
|
break;
|
|
default:
|
|
Int3();
|
|
}
|
|
|
|
if (str_check < 0)
|
|
{
|
|
// swap old
|
|
swap_strings(old_texture_name[i], old_texture_name[j]);
|
|
|
|
// swap new
|
|
swap_strings(new_texture_name[i], new_texture_name[j]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CShipTexturesDlg::swap_strings(char *str1, char *str2)
|
|
{
|
|
/*
|
|
char *temp;
|
|
temp = str1;
|
|
str1 = str2;
|
|
str2 = temp;
|
|
*/
|
|
|
|
char temp[256];
|
|
strcpy_s(temp, str1);
|
|
strcpy(str1, str2);
|
|
strcpy(str2, temp);
|
|
}
|
|
|
|
texture_replace *CShipTexturesDlg::texture_set(texture_replace *dest, const texture_replace *src)
|
|
{
|
|
dest->new_texture_id = src->new_texture_id;
|
|
strcpy_s(dest->ship_name, src->ship_name);
|
|
strcpy_s(dest->old_texture, src->old_texture);
|
|
strcpy_s(dest->new_texture, src->new_texture);
|
|
dest->from_table = src->from_table;
|
|
|
|
return dest;
|
|
}
|