mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 19:55:23 +00:00
498 lines
11 KiB
C++
498 lines
11 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/>.
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "resource.h"
|
|
#include "TableFileEdit.h"
|
|
|
|
#include "PsTypes.h"
|
|
//#include "descent.h"
|
|
#include "TableManage.h"
|
|
#include "manage.h"
|
|
//#include "pserror.h"
|
|
//#include "gametexture.h"
|
|
//#include "texpage.h"
|
|
//#include "doorpage.h"
|
|
//#include "soundpage.h"
|
|
//#include "megapage.h"
|
|
//#include "shippage.h"
|
|
//#include "weaponpage.h"
|
|
//#include "gamefilepage.h"
|
|
#include "mono.h"
|
|
#include "genericpage.h"
|
|
//#include "object.h"
|
|
//#include "ddio.h"
|
|
#include "cfile.h"
|
|
//#include "AppDatabase.h"
|
|
#include "mem.h"
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// GenericPageNode Class Members
|
|
////////////////////////////////////////////////////////////////
|
|
GenericPageNode::GenericPageNode()
|
|
{
|
|
prev=NULL;
|
|
next=NULL;
|
|
page_id=0;
|
|
}
|
|
|
|
GenericPageNode::~GenericPageNode()
|
|
{
|
|
// Free up the object description memory
|
|
if (genericpage.objinfo_struct.description!=NULL)
|
|
{
|
|
mem_free (genericpage.objinfo_struct.description);
|
|
genericpage.objinfo_struct.description = NULL;
|
|
}
|
|
}
|
|
|
|
bool GenericPageNode::operator < (const GenericPageNode &node)
|
|
{
|
|
return(stricmp( genericpage.objinfo_struct.name,
|
|
node.genericpage.objinfo_struct.name) <0 );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// GenericPageList Class Members
|
|
////////////////////////////////////////////////////////////////
|
|
GenericPageList::GenericPageList()
|
|
{
|
|
m_head=NULL;
|
|
m_tail=NULL;
|
|
m_size=0;
|
|
m_TableFilename="";
|
|
m_TableLoaded=FALSE;
|
|
m_TableModified=FALSE;
|
|
m_SelectedNode=NULL;
|
|
m_SelectedIndex=0;
|
|
}
|
|
|
|
GenericPageList::~GenericPageList()
|
|
{
|
|
ClearList();
|
|
}
|
|
|
|
void GenericPageList::ClearList(void)
|
|
{
|
|
GenericPageNode *temp, *node;
|
|
|
|
node=m_head;
|
|
while(node!=NULL) {
|
|
temp=node;
|
|
node=node->next;
|
|
delete temp;
|
|
}
|
|
m_size=0;
|
|
m_head=NULL;
|
|
m_tail=NULL;
|
|
m_TableFilename="";
|
|
m_TableLoaded=FALSE;
|
|
m_TableModified=FALSE;
|
|
m_SelectedNode=NULL;
|
|
m_SelectedIndex=0;
|
|
}
|
|
|
|
// Adds the node to the list in ascending alphabetical order
|
|
// according to the page names of the nodes
|
|
bool GenericPageList::AddToList(GenericPageNode *new_node)
|
|
{
|
|
GenericPageNode *node;
|
|
|
|
if(new_node==NULL) return FALSE;
|
|
|
|
// Handle empty list case
|
|
if(m_head==NULL) {
|
|
m_head=new_node;
|
|
m_tail=new_node;
|
|
new_node->next=NULL;
|
|
new_node->prev=NULL;
|
|
|
|
m_size++;
|
|
return TRUE;
|
|
}
|
|
|
|
// Handle (new node < list head) case
|
|
if((*new_node)<(*m_head)) {
|
|
new_node->next=m_head;
|
|
new_node->prev=NULL;
|
|
m_head->prev=new_node;
|
|
m_head=new_node;
|
|
|
|
m_size++;
|
|
return TRUE;
|
|
}
|
|
|
|
// Search through list until end of list or until the new node is less
|
|
// than the next node, then add the new node after the current node
|
|
node=m_head;
|
|
while(node->next!=NULL && (*(node->next))<(*new_node) )
|
|
node=node->next;
|
|
|
|
new_node->next=node->next;
|
|
new_node->prev=node;
|
|
|
|
if(node->next==NULL)
|
|
m_tail=new_node;
|
|
else
|
|
node->next->prev=new_node;
|
|
|
|
node->next=new_node;
|
|
|
|
m_size++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
bool GenericPageList::LoadTable (char *table_filename)
|
|
{
|
|
CFILE *infile;
|
|
uint8_t pagetype;
|
|
int done;
|
|
uint32_t page_id;
|
|
|
|
GenericPageNode *generic_page_node;
|
|
|
|
infile=cfopen (table_filename,"rb");
|
|
|
|
if (!infile)
|
|
{
|
|
//mprintf(0,"Couldn't open table file to reorder!\n");
|
|
//Int3();
|
|
return FALSE;
|
|
}
|
|
|
|
CWaitCursor wc;
|
|
|
|
// Wipeout the list first
|
|
ClearList();
|
|
|
|
done=0;
|
|
page_id=0;
|
|
|
|
while (!done)
|
|
{
|
|
if (cfeof (infile))
|
|
{
|
|
done=1;
|
|
continue;
|
|
}
|
|
pagetype=cf_ReadByte (infile);
|
|
|
|
// If not a generic page, just read it in and ignore it
|
|
if (pagetype!=PAGETYPE_GENERIC)
|
|
{
|
|
mng_ReadDummyPage (infile,pagetype);
|
|
page_id++;
|
|
continue;
|
|
}
|
|
|
|
generic_page_node=new GenericPageNode;
|
|
if(generic_page_node==NULL) {
|
|
return FALSE;
|
|
}
|
|
mng_ReadNewGenericPage (infile,&(generic_page_node->genericpage));
|
|
generic_page_node->page_id=page_id;
|
|
AddToList(generic_page_node);
|
|
|
|
page_id++;
|
|
}
|
|
|
|
cfclose (infile);
|
|
|
|
// Set Loaded tabel data
|
|
m_TableFilename=table_filename;
|
|
m_TableLoaded=TRUE;
|
|
|
|
m_TableModified=FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
bool GenericPageList::SaveTable (char *table_filename)
|
|
{
|
|
CFILE *infile,*outfile;
|
|
uint8_t pagetype,replaced=0;
|
|
int done=0;
|
|
uint32_t page_id;
|
|
GenericPageNode *new_generic_page;
|
|
mngs_generic_page genericpage;
|
|
|
|
CWaitCursor wc;
|
|
|
|
// If no table is loaded, get outta here
|
|
if(!m_TableLoaded) return FALSE;
|
|
|
|
// First make sure we can open the table file and the temp table file
|
|
infile=cfopen (m_TableFilename,"rb");
|
|
if (!infile)
|
|
{
|
|
mprintf(0,"Couldn't open table file to replace generic!\n");
|
|
return FALSE;
|
|
}
|
|
|
|
outfile=cfopen (TEMP_TABLE_FILENAME,"wb");
|
|
if (!outfile)
|
|
{
|
|
mprintf(0,"Couldn't open temp table file to replace generic!\n");
|
|
cfclose (infile);
|
|
return FALSE;
|
|
}
|
|
|
|
// Clear out the generic page
|
|
memset(&genericpage, 0, sizeof(mngs_generic_page));
|
|
|
|
// Read through the entire pagefile and replace the page we want replaced
|
|
// If we can't find the one we want, we simply append it to the end of the file
|
|
page_id=0;
|
|
while (!done)
|
|
{
|
|
if (cfeof (infile))
|
|
{
|
|
done=1;
|
|
continue;
|
|
}
|
|
pagetype=cf_ReadByte (infile);
|
|
|
|
// If not a generic page, just read it in and write it right back out
|
|
if (pagetype!=PAGETYPE_GENERIC)
|
|
{
|
|
mng_ReadWriteDummyPage (infile,outfile,pagetype);
|
|
page_id++;
|
|
continue;
|
|
}
|
|
|
|
mng_ReadNewGenericPage (infile,&genericpage);
|
|
|
|
// Look for the generic page with the current page position in list
|
|
new_generic_page=FindNode(page_id);
|
|
if(new_generic_page==NULL) {
|
|
// There is a page incompatibility!!!!
|
|
// so, just write out the one that was read instead
|
|
mng_WriteNewGenericPage (outfile,&genericpage);
|
|
OutrageMessageBox("File incompatibility Error!","Error!");
|
|
}
|
|
else {
|
|
// Found the page for this position in the list,
|
|
// So write out the new generic page
|
|
mng_WriteNewGenericPage (outfile,&(new_generic_page->genericpage));
|
|
}
|
|
|
|
// Free up the description memory for the temp page
|
|
if (genericpage.objinfo_struct.description!=NULL)
|
|
{
|
|
mem_free (genericpage.objinfo_struct.description);
|
|
genericpage.objinfo_struct.description = NULL;
|
|
}
|
|
|
|
page_id++;
|
|
}
|
|
|
|
cfclose (infile);
|
|
cfclose (outfile);
|
|
|
|
if(table_filename==NULL)
|
|
// if no filename specified, just save it to the currently loaded file
|
|
table_filename=m_TableFilename.GetBuffer(0);
|
|
else {
|
|
// We need to create this one just so it can get deleted alright by
|
|
// Jason's Switcheroo function
|
|
outfile=cfopen (table_filename,"wb");
|
|
if (!outfile)
|
|
return FALSE;
|
|
cfclose (outfile);
|
|
}
|
|
|
|
// Now, perform the switcheroo by deleting the real table file and renaming the
|
|
// temp table file to be the new "real" table file.
|
|
if (!SwitcherooFiles (table_filename,TEMP_TABLE_FILENAME))
|
|
return FALSE;
|
|
|
|
m_TableModified=FALSE;
|
|
m_TableFilename=table_filename;
|
|
|
|
return TRUE; // successful!
|
|
}
|
|
|
|
bool GenericPageList::FillFromList(CComboBox *list)
|
|
{
|
|
GenericPageNode *node;
|
|
|
|
list->ResetContent();
|
|
|
|
node=m_head;
|
|
while(node!=NULL) {
|
|
list->InsertString(-1,node->genericpage.objinfo_struct.name);
|
|
node=node->next;
|
|
}
|
|
|
|
// Select the start of the list
|
|
SelectNode(0);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void GenericPageList::SelectNext(void)
|
|
{
|
|
if(m_SelectedNode==NULL) return;
|
|
|
|
if(m_SelectedNode->next==NULL) {
|
|
m_SelectedNode=m_head;
|
|
m_SelectedIndex=0;
|
|
}
|
|
else {
|
|
m_SelectedNode=m_SelectedNode->next;
|
|
m_SelectedIndex++;
|
|
}
|
|
}
|
|
|
|
void GenericPageList::SelectPrev(void)
|
|
{
|
|
if(m_SelectedNode==NULL) return;
|
|
|
|
if(m_SelectedNode->prev==NULL) {
|
|
m_SelectedNode=m_tail;
|
|
m_SelectedIndex=(m_size-1);
|
|
}
|
|
else {
|
|
m_SelectedNode=m_SelectedNode->prev;
|
|
m_SelectedIndex--;
|
|
}
|
|
}
|
|
|
|
void GenericPageList::SelectNode(uint32_t list_index)
|
|
{
|
|
uint32_t j;
|
|
GenericPageNode *node;
|
|
|
|
if(list_index<0 || list_index>(m_size-1))
|
|
return;
|
|
|
|
node=m_head;
|
|
for(j=0;j<list_index;j++)
|
|
if(node!=NULL) node=node->next;
|
|
|
|
m_SelectedNode=node;
|
|
m_SelectedIndex=list_index;
|
|
}
|
|
|
|
void GenericPageList::DisplaySelected(CComboBox *list, CEdit *description)
|
|
{
|
|
char *text;
|
|
|
|
if(m_SelectedNode==NULL) return;
|
|
|
|
list->SetCurSel(m_SelectedIndex);
|
|
|
|
text=m_SelectedNode->genericpage.objinfo_struct.description;
|
|
if (text==NULL)
|
|
description->SetWindowText(NO_DESCRIPTION_STRING);
|
|
else
|
|
description->SetWindowText(text);
|
|
}
|
|
|
|
void GenericPageList::SaveSelected(CEdit *description)
|
|
{
|
|
CString new_descrip;
|
|
char *new_text;
|
|
char *old_text;
|
|
|
|
if(m_SelectedNode==NULL) return;
|
|
|
|
// Get pointer to old text
|
|
old_text=m_SelectedNode->genericpage.objinfo_struct.description;
|
|
|
|
// Get Copy of new Description text
|
|
description->GetWindowText(new_descrip);
|
|
new_text=(char *)mem_malloc(strlen(new_descrip.GetBuffer(0))+1);
|
|
ASSERT(new_text); // out of memory!
|
|
sprintf(new_text,"%s",new_descrip.GetBuffer(0));
|
|
|
|
// Check if new description is empty, if it is, make it NULL
|
|
if(strlen(new_text)==0 || stricmp(new_text,NO_DESCRIPTION_STRING)==0) {
|
|
mem_free(new_text);
|
|
new_text=NULL;
|
|
}
|
|
|
|
// If both new and old are empty, get outta here
|
|
if(old_text==NULL && new_text==NULL) {
|
|
mem_free(new_text);
|
|
return;
|
|
}
|
|
|
|
// If both have descriptions and they match, get outta here
|
|
if(old_text!=NULL && new_text!=NULL) {
|
|
if(strcmp(old_text,new_text)==0) {
|
|
mem_free(new_text);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Free up the old text memory, and assign it to the new text
|
|
if(old_text!=NULL)
|
|
mem_free(old_text);
|
|
|
|
m_SelectedNode->genericpage.objinfo_struct.description=new_text;
|
|
m_TableModified=TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
GenericPageNode *GenericPageList::FindNode(uint32_t page_id)
|
|
{
|
|
GenericPageNode *node, *found_node;
|
|
|
|
found_node=NULL;
|
|
node=m_head;
|
|
while(node!=NULL) {
|
|
if(node->page_id==page_id) {
|
|
found_node=node;
|
|
break;
|
|
}
|
|
node=node->next;
|
|
}
|
|
|
|
return(found_node);
|
|
}
|
|
|
|
int GenericPageList::ModifiedPrompt(CDialog *wnd)
|
|
{
|
|
// If current file has been modified, check with user first...
|
|
if(!m_TableModified) return(IDYES);
|
|
if(wnd->MessageBox("Changes to table file will be lost. Proceed?",
|
|
"Table File Has Been Modified",
|
|
MB_YESNO)==IDYES) return(IDYES);
|
|
return(IDNO);
|
|
}
|
|
|
|
void GenericPageList::SetTitleString(CDialog *wnd)
|
|
{
|
|
char title[1024];
|
|
char loaded_file[1024];
|
|
|
|
if(m_TableLoaded)
|
|
sprintf(loaded_file," - [%s%s]", m_TableFilename.GetBuffer(0),
|
|
(m_TableModified) ? "*":"");
|
|
else
|
|
sprintf(loaded_file,"");
|
|
|
|
sprintf(title,"%s%s", TITLE_NAME, loaded_file);
|
|
wnd->SetWindowText(title);
|
|
}
|
|
|