/* * 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/TableFileFilterMng.cpp $ * $Revision: 1.1.1.1 $ * $Date: 2003-08-26 03:57:39 $ * $Author: kevinb $ * * * * $Log: not supported by cvs2svn $ * * 49 10/22/99 6:05p Jeff * fixed bugs and compiler errors resulting from mac code merge * * 48 4/21/99 4:49p Kevin * * 47 4/21/99 4:18p Jason * check texture sounds when determining pages * * 46 4/08/99 5:11p Nate * Added logging of Remaining and Removed Pages during a filtering * * 45 3/30/99 4:42p Kevin * For Matt T. -- Silly bug. * * 44 3/28/99 4:03p Matt * Added code to handle soundsource objects * * 43 3/05/99 6:54p Jason * fixed table file filter for sound bands * * 42 3/04/99 5:27p Jason * added matcen stuff to table file * * 41 2/19/99 12:01p Jason * took out sky band * * 40 2/17/99 7:06p Kevin * OEM build setup * * 39 2/11/99 5:46p Kevin * changes for jason * * 38 2/11/99 12:50p Kevin * Changes for jason -- to get fireball stuff in * * 37 2/09/99 4:58p Nate * Fixed up the TableParse file stuff * * 36 2/09/99 4:20p Nate * Added TableParse file support * * 35 2/08/99 10:23a Jason * made table file filter work again * * 34 1/22/99 3:59p Jason * added 256x256 textures to help with terrain skies * * 33 1/21/99 11:15p Jeff * pulled out some structs and defines from header files and moved them * into seperate header files so that multiplayer dlls don't require major * game headers, just those new headers. Side effect is a shorter build * time. Also cleaned up some header file #includes that weren't needed. * This affected polymodel.h, object.h, player.h, vecmat.h, room.h, * manage.h and multi.h * * 32 1/20/99 10:50a Jason * added new terrain * * 31 1/08/99 2:56p Samir * Ripped out OSIRIS1. * * 30 11/05/98 7:54p Jason * changes for new manage system * * 29 10/23/98 1:37p Nate * Fixed spelling of sound page. * * 28 10/23/98 12:39p Nate * Added a few more pages. * * 27 10/21/98 8:53a Nate * * 26 10/19/98 11:33p Nate * Yet more hard coded pages to add * * 25 10/19/98 7:21p Nate * * 24 10/19/98 7:19p Matt * Added system to support different types of damage to the player and * have these different types make different sounds. * * 23 10/16/98 6:01p Nate * added more hard-coded pages * * 22 10/16/98 11:35a Jason * added some more defaults * * 21 10/14/98 1:02p Jason * fixed FindSoundName issues * * 20 10/14/98 11:32a Jason * added gunboy * * 19 10/13/98 8:41p Jason * fixed cockpit problem * * 18 10/13/98 5:25p Nate * Added ship flags * * 17 10/13/98 4:44p Jason * added more primitives * * 16 10/13/98 2:32p Chris * BuddyBot to GuideBot * * 15 10/12/98 11:38p Jeff * wrapped all the Object_info[].description whenever freed...trying to * find an obscure bug. Added icon_name to manage page of Generic * * 14 10/09/98 10:45p Jeff * renamed FlagYellow bug * * 13 10/09/98 7:40p Jason * fixed gamefile .oofs to read in their textures * * * 12 10/09/98 1:41p Jason * Hard coded more stuff for demo * * 11 10/09/98 10:55a Nate * Fixed bug, now correctly displays which pages weren't written out to * the table file * * 10 10/09/98 3:16a Jason * more changes for demo * * 9 10/09/98 2:40a Jason * fixed table file issues with demo * * 8 10/08/98 10:48p Nate * * 7 10/08/98 2:26p Jason * added table file filter functionality * * 6 10/08/98 10:48a Nate * Fixed memory leaks by freeing level script when done with loaded level. * * 5 10/08/98 10:30a Nate * Initial version * * $NoKeywords: $ */ #include "stdafx.h" #include "resource.h" #include "TableFileFilterMng.h" #include "manage.h" #include "mono.h" #include "LoadLevel.h" #include "object.h" #include "objinfo.h" //@@#include "d3x.h" #include "texpage.h" #include "doorpage.h" #include "soundpage.h" #include "megapage.h" #include "shippage.h" #include "weaponpage.h" #include "gamefilepage.h" #include "genericpage.h" #include "sounds.h" #include "gametexture.h" #include "terrain.h" #include "fireball.h" #include "mem.h" #include "polymodel.h" #include "ddio.h" #include "DallasUtilities.h" #include "matcen.h" #include "game.h" #define TITLE_NAME "Table File Filter v1.0" // Function Prototypes void DeferMessages(void); void OpenFilterLogFiles(void); void WriteToRemainingLog(char *name, int type); void WriteToRemovedLog(char *name, int type); void CloseFilterLogFiles(void); //////////////////////////////////////////////////////////////// // PageDataNode Class Members //////////////////////////////////////////////////////////////// PageDataNode::PageDataNode() { prev = NULL; next = NULL; name[0] = '\0'; type = PAGETYPE_UNKNOWN; flags = 0; tag_count = 0; } PageDataNode::~PageDataNode() {} // Performs a comparison based upon the page name bool PageDataNode::operator<(const PageDataNode &node) { return (stricmp(name, node.name) < 0); } // Loads a Page Data Node from a given stream bool PageDataNode::Load(CFILE *infile) { cf_ReadString(name, PAGENAME_LEN, infile); type = (uint8_t)cf_ReadByte(infile); flags = cf_ReadInt(infile); tag_count = cf_ReadInt(infile); return TRUE; } // Saves a Page Data Node to a given stream bool PageDataNode::Save(CFILE *outfile) { cf_WriteString(outfile, name); cf_WriteByte(outfile, (int8_t)type); cf_WriteInt(outfile, flags); cf_WriteInt(outfile, tag_count); return TRUE; } //////////////////////////////////////////////////////////////// // PageDataList Class Members //////////////////////////////////////////////////////////////// PageDataList::PageDataList() { int j; // Init the list to be empty m_head = NULL; m_tail = NULL; m_size = 0; // Init the level filename list to be empty m_NumLevelFilenames = 0; for (j = 0; j < MAX_LEVEL_FILENAMES; j++) m_LevelFilenames[j][0] = '\0'; // Init the dialog control pointers m_Dlg = NULL; m_TableParseFile = NULL; m_PageDataListCtrl = NULL; m_LevelListBox = NULL; m_NumPagesText = NULL; m_StatusText = NULL; m_DataListFilename = ""; m_DataListLoaded = FALSE; m_DataListModified = FALSE; } PageDataList::~PageDataList() { // Detach the dialog control pointers m_Dlg = NULL; m_TableParseFile = NULL; m_PageDataListCtrl = NULL; m_LevelListBox = NULL; m_NumPagesText = NULL; m_StatusText = NULL; ClearList(); } // Wipes out the data list void PageDataList::ClearList(void) { PageDataNode *temp, *node; int j; CWaitCursor wc; node = m_head; while (node != NULL) { temp = node; node = node->next; delete temp; } m_size = 0; m_head = NULL; m_tail = NULL; // Init the level filename list to be empty m_NumLevelFilenames = 0; for (j = 0; j < MAX_LEVEL_FILENAMES; j++) m_LevelFilenames[j][0] = '\0'; m_DataListFilename = ""; m_DataListLoaded = FALSE; m_DataListModified = FALSE; // Clear out the dialog data if (m_PageDataListCtrl) m_PageDataListCtrl->DeleteAllItems(); if (m_LevelListBox) m_LevelListBox->ResetContent(); if (m_NumPagesText) m_NumPagesText->Format("0"); if (m_StatusText) m_StatusText->Format("Blank Page Data List Created"); if (m_Dlg) m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); } // Adds the node to the list in ascending alphabetical order // according to the page names of the nodes bool PageDataList::AddToList(PageDataNode *new_node) { PageDataNode *node; CWaitCursor wc; 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++; goto UpdateControls; } // 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++; goto UpdateControls; } // 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++; UpdateControls: // Add it to the data list control AddToListCtrl(0, new_node); // Update the count if (m_NumPagesText) m_NumPagesText->Format("%d", m_size); if (m_Dlg) m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); m_DataListModified = TRUE; return TRUE; } // Creates a new node and adds it to the list (if not already in it) bool PageDataList::AddToList(char *page_name, uint8_t page_type, int page_flags) { PageDataNode *new_node, *found_node; CWaitCursor wc; // If the node is already in the list, don't add it! found_node = FindNode(page_name, page_type); if (found_node != NULL) { // If the new node has been added for a level, tag it once if (page_flags & ADDED_FOR_LEVEL_FLAG) { found_node->flags |= ADDED_FOR_LEVEL_FLAG; found_node->tag_count++; } // If it's been added directly by user, set that flag if (page_flags & ADDED_FOR_USER_FLAG) found_node->flags |= ADDED_FOR_USER_FLAG; return TRUE; } // Allocate memory for the new node new_node = new PageDataNode; if (new_node == NULL) { mprintf(0, "ERROR: Could not allocate new PageDataNode!\n"); return FALSE; } // Initialize the data strcpy(new_node->name, page_name); new_node->type = page_type; new_node->flags = page_flags; new_node->tag_count = 0; // If the new node has been added for a level, tag it once if (new_node->flags & ADDED_FOR_LEVEL_FLAG) new_node->tag_count++; // Add the new node to the list AddToList(new_node); return TRUE; } // Searches for and removes matching node from the list bool PageDataList::RemoveFromList(char *page_name, uint8_t page_type) { int index; LVFINDINFO find_info; CWaitCursor wc; if (m_PageDataListCtrl == NULL) return FALSE; // Find and remove node from the data list PageDataNode *found_node; found_node = FindNode(page_name, page_type); if (found_node != NULL) { // If node has been "level tagged", decrement it if (found_node->tag_count > 0) found_node->tag_count--; // If node is still tagged by another level, leave it if (found_node->tag_count > 0) return TRUE; // Otherwise, continue and get rid of it RemoveFromList(found_node); } // Find and remove item from the list control find_info.flags = LVFI_STRING; find_info.psz = page_name; index = m_PageDataListCtrl->FindItem(&find_info, -1); if (index == -1) return FALSE; m_PageDataListCtrl->DeleteItem(index); return TRUE; } // Removes the given node from the list bool PageDataList::RemoveFromList(PageDataNode *goner_node) { CWaitCursor wc; if (goner_node == NULL) return FALSE; // Connect previous node to the next node if (goner_node->prev != NULL) goner_node->prev->next = goner_node->next; // Connect the next node to the previous node if (goner_node->next != NULL) goner_node->next->prev = goner_node->prev; // If node to be removed is the head, make the next node the head if (goner_node == m_head) m_head = goner_node->next; // If node to be removed is the tail, make the previous node the tail if (goner_node == m_tail) m_tail = goner_node->prev; delete goner_node; m_size--; // Update the count if (m_NumPagesText) m_NumPagesText->Format("%d", m_size); if (m_Dlg) m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); m_DataListModified = TRUE; return TRUE; } // Loads a Page Data List from a file bool PageDataList::LoadList(char *list_filename) { int i, list_size; CFILE *infile; PageDataNode *new_node; CWaitCursor wc; // Wipe out the current data list ClearList(); wc.Restore(); // Try to open the file for loading infile = cfopen(list_filename, "rb"); if (!infile) { mprintf(0, "Couldn't open the input list file!\n"); return FALSE; } // Display "saving" message m_StatusText->Format("Loading %s...", list_filename); m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); // Read in the number of nodes in the list list_size = cf_ReadInt(infile); // Read in each data node to the list for (i = 0; i < list_size; i++) { // Allocate memory for the new node new_node = new PageDataNode; if (new_node == NULL) { mprintf(0, "ERROR: Could not allocate new PageDataNode!\n"); return FALSE; } // Read in the node's data new_node->Load(infile); // Add the new node to the list AddToList(new_node); wc.Restore(); } // Read in the number of level filenames m_NumLevelFilenames = cf_ReadInt(infile); // Read in each level filename for (i = 0; i < m_NumLevelFilenames; i++) { cf_ReadString(m_LevelFilenames[i], _MAX_PATH, infile); // Add the filename to the list box m_LevelListBox->InsertString(-1, m_LevelFilenames[i]); DeferMessages(); wc.Restore(); } // Close the saved file cfclose(infile); // Save the current filename m_DataListFilename = list_filename; m_DataListModified = FALSE; // Display "saving" message m_StatusText->Format("Load Complete"); m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); return TRUE; } // Saves a Page Data List to a file bool PageDataList::SaveList(char *list_filename) { int i; CFILE *outfile; PageDataNode *node; CWaitCursor wc; if (list_filename == NULL) { if (!FilenameSpecified()) return FALSE; list_filename = m_DataListFilename.GetBuffer(0); } // Try to open the file for saving outfile = cfopen(list_filename, "wb"); if (!outfile) { mprintf(0, "Couldn't open the output list file!\n"); return FALSE; } // Display "saving" message m_StatusText->Format("Saving %s...", list_filename); m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); // Write out the number of nodes in the list cf_WriteInt(outfile, m_size); // Write out each data node in the list node = m_head; for (i = 0; i < m_size; i++) { node->Save(outfile); node = node->next; } // Write out the number of level filenames cf_WriteInt(outfile, m_NumLevelFilenames); // Write out each level filename for (i = 0; i < m_NumLevelFilenames; i++) cf_WriteString(outfile, m_LevelFilenames[i]); // Close the saved file cfclose(outfile); // Save the current filename m_DataListFilename = list_filename; m_DataListModified = FALSE; // Display "saving" message m_StatusText->Format("Save Complete"); m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); return TRUE; } // Scans the list for a certain page, and returns a pointer to the // matching data node (or NULL if not found) PageDataNode *PageDataList::FindNode(char *page_name, uint8_t page_type) { PageDataNode *node, *found_node; found_node = NULL; node = m_head; while (node != NULL) { if (node->type == page_type && stricmp(node->name, page_name) == 0) { found_node = node; break; } node = node->next; } return (found_node); } // Adds a level filename to the filename list (and to the dialog list box) bool PageDataList::AddLevelFilename(char *level_filename) { int i, level_found; CWaitCursor wc; if (level_filename == NULL) return FALSE; // Make sure the level hasn't already been added level_found = -1; for (i = 0; i < m_NumLevelFilenames; i++) if (stricmp(m_LevelFilenames[i], level_filename) == 0) level_found = i; if (level_found >= 0) return FALSE; // Add the filename to the list if (m_NumLevelFilenames >= MAX_LEVEL_FILENAMES) return FALSE; strcpy(m_LevelFilenames[m_NumLevelFilenames], level_filename); m_NumLevelFilenames++; // Add the filename to the list box m_LevelListBox->InsertString(-1, level_filename); // Add the pages required by this level ProcessPagesForLevel(level_filename, ADD_PAGES); wc.Restore(); m_DataListModified = TRUE; return TRUE; } // Removes the selected level from the filename list (and from the dialog list box) bool PageDataList::RemoveSelLevelFilename(void) { int i, level_found; int index; CString level_filename; CWaitCursor wc; if (m_LevelListBox == NULL) return FALSE; index = m_LevelListBox->GetCurSel(); if (index == LB_ERR) return FALSE; m_LevelListBox->GetText(index, level_filename); // Find the level position in the filename list level_found = -1; for (i = 0; i < m_NumLevelFilenames; i++) if (stricmp(m_LevelFilenames[i], level_filename.GetBuffer(0)) == 0) level_found = i; if (level_found < 0) return FALSE; // Remove the filename from the list for (i = level_found; i < m_NumLevelFilenames - 1; i++) strcpy(m_LevelFilenames[i], m_LevelFilenames[i + 1]); m_NumLevelFilenames--; // Remove the filename from the list box m_LevelListBox->DeleteString(index); // Remove the pages required by this level ProcessPagesForLevel(level_filename.GetBuffer(0), REMOVE_PAGES); wc.Restore(); m_DataListModified = TRUE; return TRUE; } char *gamefile_level_ext[] = {".d3l", ".cpp", ".dll", ".msg", ".omf", ".brf", ".str", ".msn", NULL}; // Processes all pages needed by the given level bool PageDataList::ProcessPagesForLevel(char *level_filename, int process_type) { CWaitCursor wc; if (level_filename == NULL) return FALSE; m_StatusText->Format("Loading level - %s...", level_filename); m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); // Load the given level if (!LoadLevel(level_filename)) { m_Dlg->MessageBox("Error loading level", "Level Load Error"); return FALSE; } m_StatusText->Format("Processing level - %s...", level_filename); m_NumPagesText->Format("%d", m_size); m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); // Process level, adding pages that it requires DetermineRequiredPages(process_type); // Add Level's gamefile pages char filename[_MAX_FNAME + 1]; char pagename[_MAX_PATH + 1]; _splitpath(level_filename, NULL, NULL, filename, NULL); for (int j = 0; gamefile_level_ext[j] != NULL; j++) { sprintf(pagename, "%s%s", filename, gamefile_level_ext[j]); ProcessPage(pagename, PAGETYPE_GAMEFILE, process_type); } wc.Restore(); m_StatusText->Format("Processing Complete", level_filename); m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); return TRUE; } // Either adds the given level page to the list, or removes it bool PageDataList::ProcessPage(char *page_name, uint8_t page_type, int process_type, int flags) { CWaitCursor wc; switch (process_type) { case ADD_PAGES: AddToList(page_name, page_type, ADDED_FOR_LEVEL_FLAG); break; case REMOVE_PAGES: RemoveFromList(page_name, page_type); break; default: break; } m_NumPagesText->Format("%d", m_size); m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); return TRUE; } // Get extension of a file bool GetFileExt(char *file, char *ext) { char *temp; if (strlen(file) < 4) return FALSE; temp = (file + strlen(file) - 4); strcpy(ext, temp); if (ext[0] != '.') return FALSE; return TRUE; } // Determines what pages are required by the currently loaded level, // and processes each one appropriately void PageDataList::AddTexturePage(int id, int process_type) { if (id == -1) return; CWaitCursor wc; ProcessPage(GameTextures[id].name, PAGETYPE_TEXTURE, process_type); wc.Restore(); if (GameTextures[id].flags & TF_DESTROYABLE && GameTextures[id].destroy_handle != -1) { AddTexturePage(GameTextures[id].destroy_handle, process_type); } if (GameTextures[id].sound != -1) AddSoundPage(GameTextures[id].sound, process_type); } void PageDataList::AddSoundPage(int id, int process_type) { if (id == -1) return; CWaitCursor wc; ProcessPage(Sounds[id].name, PAGETYPE_SOUND, process_type); wc.Restore(); } void PageDataList::AddDoorPage(int id, int process_type) { CWaitCursor wc; // Set sounds door *doorpointer = &Doors[id]; ProcessPage(Doors[id].name, PAGETYPE_DOOR, process_type); wc.Restore(); PageInPolymodel(doorpointer->model_handle); poly_model *pm = &Poly_models[doorpointer->model_handle]; for (int t = 0; t < pm->n_textures; t++) AddTexturePage(pm->textures[t], process_type); if (doorpointer->open_sound != -1 && doorpointer->open_sound != SOUND_NONE_INDEX) AddSoundPage(doorpointer->open_sound, process_type); if (doorpointer->close_sound != -1 && doorpointer->close_sound != SOUND_NONE_INDEX) AddSoundPage(doorpointer->close_sound, process_type); } void PageDataList::AddWeaponPage(int id, int process_type) { CWaitCursor wc; weapon *weaponpointer = &Weapons[id]; if (id == -1) return; int i; ProcessPage(Weapons[id].name, PAGETYPE_WEAPON, process_type); wc.Restore(); if (!(weaponpointer->flags & (WF_IMAGE_BITMAP | WF_IMAGE_VCLIP))) { PageInPolymodel(weaponpointer->fire_image_handle); poly_model *pm = &Poly_models[weaponpointer->fire_image_handle]; for (int t = 0; t < pm->n_textures; t++) AddTexturePage(pm->textures[t], process_type); } // Load the various textures associated with this weapon if (weaponpointer->explode_image_handle != -1) { AddTexturePage(weaponpointer->explode_image_handle, process_type); } if (weaponpointer->particle_handle != -1) { AddTexturePage(weaponpointer->particle_handle, process_type); } if (weaponpointer->smoke_handle != -1) { AddTexturePage(weaponpointer->smoke_handle, process_type); } if (weaponpointer->scorch_handle != -1) { AddTexturePage(weaponpointer->scorch_handle, process_type); } if (weaponpointer->icon_handle != -1) { AddTexturePage(weaponpointer->icon_handle, process_type); } // Try to load spawn weapons if (weaponpointer->spawn_handle != -1 && weaponpointer->spawn_count > 0 && weaponpointer->spawn_handle != id) { AddWeaponPage(weaponpointer->spawn_handle, process_type); } if (weaponpointer->alternate_spawn_handle != -1 && weaponpointer->spawn_count > 0 && weaponpointer->alternate_spawn_handle != id) { AddWeaponPage(weaponpointer->alternate_spawn_handle, process_type); } if (weaponpointer->robot_spawn_handle != -1) { AddGenericPage(weaponpointer->robot_spawn_handle, process_type); } // Try and load the various sounds for (i = 0; i < MAX_WEAPON_SOUNDS; i++) { if (weaponpointer->sounds[i] != SOUND_NONE_INDEX) { AddSoundPage(weaponpointer->sounds[i], process_type); } } } void PageDataList::AddShipPage(int id, int process_type) { int i, t; CWaitCursor wc; ProcessPage(Ships[id].name, PAGETYPE_SHIP, process_type); wc.Restore(); ship *shippointer = &Ships[id]; // Page in all textures for this object PageInPolymodel(shippointer->model_handle); poly_model *pm = &Poly_models[shippointer->model_handle]; for (t = 0; t < pm->n_textures; t++) AddTexturePage(pm->textures[t], process_type); if (shippointer->med_render_handle != -1) { PageInPolymodel(shippointer->med_render_handle); pm = &Poly_models[shippointer->med_render_handle]; for (t = 0; t < pm->n_textures; t++) AddTexturePage(pm->textures[t], process_type); } if (shippointer->lo_render_handle != -1) { PageInPolymodel(shippointer->lo_render_handle); pm = &Poly_models[shippointer->lo_render_handle]; for (t = 0; t < pm->n_textures; t++) AddTexturePage(pm->textures[t], process_type); } if (shippointer->dying_model_handle != -1) { PageInPolymodel(shippointer->dying_model_handle); pm = &Poly_models[shippointer->dying_model_handle]; for (t = 0; t < pm->n_textures; t++) AddTexturePage(pm->textures[t], process_type); } // Try and load the various weapons int j; for (i = 0; i < MAX_PLAYER_WEAPONS; i++) { for (j = 0; j < MAX_WB_GUNPOINTS; j++) { if (shippointer->static_wb[i].gp_weapon_index[j] != LASER_INDEX) { AddWeaponPage(shippointer->static_wb[i].gp_weapon_index[j], process_type); } } } // Try and load the various weapons for (i = 0; i < MAX_PLAYER_WEAPONS; i++) { for (j = 0; j < MAX_WB_FIRING_MASKS; j++) { if (shippointer->static_wb[i].fm_fire_sound_index[j] != SOUND_NONE_INDEX) AddSoundPage(shippointer->static_wb[i].fm_fire_sound_index[j], process_type); } } for (i = 0; i < MAX_PLAYER_WEAPONS; i++) { if (shippointer->firing_sound[i] != -1) AddSoundPage(shippointer->firing_sound[i], process_type); if (shippointer->firing_release_sound[i] != -1) AddSoundPage(shippointer->firing_release_sound[i], process_type); if (shippointer->spew_powerup[i] != -1) AddGenericPage(shippointer->spew_powerup[i], process_type); } } void PageDataList::AddGenericPage(int id, int process_type) { int i, t; CWaitCursor wc; if (id == -1) return; ProcessPage(Object_info[id].name, PAGETYPE_GENERIC, process_type); wc.Restore(); object_info *objinfopointer = &Object_info[id]; // Page in all textures for this object PageInPolymodel(objinfopointer->render_handle); poly_model *pm = &Poly_models[objinfopointer->render_handle]; for (t = 0; t < pm->n_textures; t++) AddTexturePage(pm->textures[t], process_type); if (objinfopointer->med_render_handle != -1) { PageInPolymodel(objinfopointer->med_render_handle); pm = &Poly_models[objinfopointer->med_render_handle]; for (t = 0; t < pm->n_textures; t++) AddTexturePage(pm->textures[t], process_type); } if (objinfopointer->lo_render_handle != -1) { PageInPolymodel(objinfopointer->lo_render_handle); pm = &Poly_models[objinfopointer->lo_render_handle]; for (t = 0; t < pm->n_textures; t++) AddTexturePage(pm->textures[t], process_type); } // Process all sounds for this object for (i = 0; i < MAX_OBJ_SOUNDS; i++) { if (objinfopointer->sounds[i] != SOUND_NONE_INDEX) { AddSoundPage(objinfopointer->sounds[i], process_type); } } for (i = 0; i < MAX_AI_SOUNDS; i++) { if (objinfopointer->ai_info->sound[i] != SOUND_NONE_INDEX) { AddSoundPage(objinfopointer->ai_info->sound[i], process_type); } } // Try and load the various wb sounds int j; for (i = 0; i < MAX_WBS_PER_OBJ; i++) { for (j = 0; j < MAX_WB_FIRING_MASKS; j++) { if (objinfopointer->static_wb[i].fm_fire_sound_index[j] != SOUND_NONE_INDEX) { AddSoundPage(objinfopointer->static_wb[i].fm_fire_sound_index[j], process_type); } } } // Try and load the various wb sounds for (i = 0; i < NUM_MOVEMENT_CLASSES; i++) { for (j = 0; j < NUM_ANIMS_PER_CLASS; j++) { if (objinfopointer->anim[i].elem[j].anim_sound_index != SOUND_NONE_INDEX) { AddSoundPage(objinfopointer->anim[i].elem[j].anim_sound_index, process_type); } } } // Load the spew types for (i = 0; i < MAX_DSPEW_TYPES; i++) { if (objinfopointer->dspew_number[i] > 0 && objinfopointer->dspew[i] != 0 && objinfopointer->dspew[i] != id) { AddGenericPage(objinfopointer->dspew[i], process_type); } } // Try and load the various weapons // Automatically include laser AddWeaponPage(LASER_INDEX, process_type); for (i = 0; i < MAX_WBS_PER_OBJ; i++) { for (j = 0; j < MAX_WB_GUNPOINTS; j++) { if (objinfopointer->static_wb[i].gp_weapon_index[j] != LASER_INDEX) { AddWeaponPage(objinfopointer->static_wb[i].gp_weapon_index[j], process_type); } } } } extern const char *Static_sound_names[]; bool PageDataList::DetermineRequiredPages(int process_type) { CWaitCursor wc; CString filename; int i; //////////////////////////////////////////////////////////// // Note to Jason: // // For every page needed by the level call these functions: // ProcessPage(page_name,page_type,process_type); // wc.Restore(); //////////////////////////////////////////////////////////// // Processes all the pages in the TableParse output file m_TableParseFile->GetWindowText(filename); ProcessPagesInTextFile(filename.GetBuffer(0), process_type); /* SHOULDN'T NEED THE FOLLOWING ANYMORE // Add all the other files char ext[12]; for(i=0;in_textures;t++) AddTexturePage (pm->textures[t],process_type); } else { mprintf(0,"Couldn't find polymodel %s!\n",Gamefiles[i].name); Int3(); } } } } // Get misc pages AddSoundPage (FindSoundName ("AmbSwitch31"),process_type); AddSoundPage (FindSoundName ("AmbLavaLoop1"),process_type); AddTexturePage (FindTextureName("Ready1"),process_type); AddTexturePage (FindTextureName("Online"),process_type); AddTexturePage (FindTextureName("hilite0"),process_type); AddTexturePage (FindTextureName("hilite1"),process_type); AddTexturePage (FindTextureName("hilite2"),process_type); AddTexturePage (FindTextureName("hilite3"),process_type); AddTexturePage (FindTextureName("hilite4"),process_type); AddTexturePage (FindTextureName("hilite5"),process_type); AddTexturePage (FindTextureName("smhilite01"),process_type); AddTexturePage (FindTextureName("smhilite11"),process_type); AddTexturePage (FindTextureName("smhilite21"),process_type); AddTexturePage (FindTextureName("smhilite31"),process_type); AddTexturePage (FindTextureName("smhilite41"),process_type); AddTexturePage (FindTextureName("smhilite51"),process_type); AddTexturePage (FindTextureName("smhilite61"),process_type); AddTexturePage (FindTextureName("smhilite71"),process_type); AddWeaponPage (FindWeaponName ("GunBoy"),process_type); AddWeaponPage (FindWeaponName ("FragBarrel"),process_type); AddWeaponPage (FindWeaponName ("NapalmBarrel"),process_type); AddWeaponPage (FindWeaponName ("TubbsHitBlast"),process_type); AddWeaponPage (FindWeaponName ("ChaffSpark"),process_type); AddWeaponPage (FindWeaponName ("NapalmBlob"),process_type); AddGenericPage (FindObjectIDName ("ShipRedFlag"),process_type); AddGenericPage (FindObjectIDName ("ShipBlueFlag"),process_type); AddGenericPage (FindObjectIDName ("ShipYellowFlag"),process_type); AddGenericPage (FindObjectIDName ("ShipGreenFlag"),process_type); AddGenericPage (FindObjectIDName ("GuideBot"),process_type); AddGenericPage (FindObjectIDName ("SmallDebris"),process_type); AddGenericPage (FindObjectIDName ("BigDebris"),process_type); AddGenericPage (FindObjectIDName ("VirusHousing"),process_type); AddGenericPage (FindObjectIDName ("Afterburner"),process_type); AddGenericPage (FindObjectIDName ("attached light bulb"),process_type); AddGenericPage (FindObjectIDName ("GuideBot"),process_type); AddGenericPage (FindObjectIDName ("ChaffChunk"),process_type); AddGenericPage (FindObjectIDName ("Jugghead"),process_type); AddGenericPage (FindObjectIDName ("Jugg main turret"),process_type); AddGenericPage (FindObjectIDName ("Juggbelly"),process_type); AddGenericPage (FindObjectIDName ("Jugg flame turret"),process_type); AddGenericPage (FindObjectIDName ("Trackerhatch"),process_type); AddGenericPage (FindObjectIDName ("Trackerturret"),process_type); AddGenericPage (FindObjectIDName ("Pesttail"),process_type); AddGenericPage (FindObjectIDName ("Aliencuplinkhousing"),process_type); AddTexturePage (FindTextureName("LightFlareStar"),process_type); AddTexturePage (FindTextureName("TelcomPowerBar"),process_type); AddTexturePage (FindTextureName("Matcen Lightning"),process_type); AddTexturePage (FindTextureName("WhiteGlowingBall"),process_type); AddTexturePage (FindTextureName("SkyDome10"),process_type); AddTexturePage (FindTextureName("SkyBand10"),process_type); AddTexturePage (FindTextureName("Multicolor"),process_type); AddSoundPage (FindSoundName ("Energy Converter"),process_type); AddSoundPage (FindSoundName ("CockpitSequenceTest1"),process_type); AddSoundPage (FindSoundName ("Player hit by weapon"),process_type); AddSoundPage (FindSoundName ("Metallic Door Hit"),process_type); AddSoundPage (FindSoundName ("Wall Fade ???"),process_type); AddSoundPage (FindSoundName ("RainDrop"),process_type); AddSoundPage (FindSoundName ("Lightning"),process_type); AddSoundPage (FindSoundName ("AmbSwitch31"),process_type); AddSoundPage (FindSoundName ("AmbLavaLoop1"),process_type); AddSoundPage (FindSoundName ("Invulnerability on"),process_type); AddSoundPage (FindSoundName ("Invulnerability off"),process_type); AddSoundPage (FindSoundName ("Cloak on"),process_type); AddSoundPage (FindSoundName ("Cloak off"),process_type); AddSoundPage (FindSoundName ("GBotConcern1"),process_type); AddSoundPage (FindSoundName ("Drop bomb"),process_type); AddSoundPage (FindSoundName ("RbtStingeattack1"),process_type); AddSoundPage (FindSoundName ("AmbDroneV"),process_type); AddSoundPage (FindSoundName ("AmbDroneR"),process_type); AddSoundPage (FindSoundName ("AmbDroneO"),process_type); AddSoundPage (FindSoundName ("AmbDroneN"),process_type); AddSoundPage (FindSoundName ("AmbDroneI"),process_type); AddSoundPage (FindSoundName ("AmbDroneK"),process_type); AddSoundPage (FindSoundName ("AmbDroneM"),process_type); AddSoundPage (FindSoundName ("AmbDroneX"),process_type); AddSoundPage (FindSoundName ("AmbDroneQ"),process_type); AddSoundPage (FindSoundName ("AmbDroneL"),process_type); AddSoundPage (FindSoundName ("AmbDroneF"),process_type); AddSoundPage (FindSoundName ("AmbDroneS"),process_type); AddSoundPage (FindSoundName ("AmbDroneD"),process_type); AddSoundPage (FindSoundName ("AmbDroneU"),process_type); AddSoundPage (FindSoundName ("AmbDroneH"),process_type); AddSoundPage (FindSoundName ("rainhigh1"),process_type); AddSoundPage (FindSoundName ("rainlow1"),process_type); AddSoundPage (FindSoundName ("AmbWindGust"),process_type); AddSoundPage (FindSoundName ("AmbVirusSwitch"),process_type); AddSoundPage (FindSoundName ("VoxCompAutoSecurity.osf"),process_type); AddSoundPage (FindSoundName ("CTFHatTrick"),process_type); AddSoundPage (FindSoundName ("CTFPickupFlag1"),process_type); AddSoundPage (FindSoundName ("CTFScore1"),process_type); AddSoundPage (FindSoundName ("CTFLostFlag1"),process_type); AddSoundPage (FindSoundName ("CTFReturnedFlag1"),process_type); AddSoundPage (FindSoundName ("Cheater!"),process_type); AddSoundPage (FindSoundName ("Hostage pickup"),process_type); AddGenericPage (FindObjectIDName ("Converter"),process_type); AddGenericPage (FindObjectIDName ("Shield"),process_type); AddGenericPage (FindObjectIDName ("Energy"),process_type); AddGenericPage (FindObjectIDName ("Afterburner"),process_type); AddGenericPage (FindObjectIDName ("Attached light bulb"),process_type); AddGenericPage (FindObjectIDName ("ChaffChunk"),process_type); AddGenericPage (FindObjectIDName ("TrackerHatch"),process_type); AddGenericPage (FindObjectIDName ("TrackerTurret"),process_type); AddGenericPage (FindObjectIDName ("PestTail"),process_type); AddGenericPage (FindObjectIDName ("Virushousing"),process_type); AddGenericPage (FindObjectIDName ("Viruscartridge"),process_type); AddWeaponPage (FindWeaponName ("TubbsHitBlast"),process_type); AddShipPage (FindShipName ("Pyro-SE"),process_type); AddGenericPage (FindObjectIDName ("FlagRed"),process_type); AddGenericPage (FindObjectIDName ("FlagBlue"),process_type); AddGenericPage (FindObjectIDName ("FlagGreen"),process_type); AddGenericPage (FindObjectIDName ("FlagYellow"),process_type); AddTexturePage (FindTextureName("RedBase"),process_type); AddTexturePage (FindTextureName("BlueBase"),process_type); AddTexturePage (FindTextureName("YellowBase"),process_type); AddTexturePage (FindTextureName("GreenBase"),process_type); AddTexturePage (FindTextureName("Multicolor"),process_type); */ // Add in matcen stuff for (i = 0; i < Num_matcens; i++) { int t; AddTexturePage(Matcen[i]->GetCreationTexture(), process_type); for (t = 0; t < MAX_MATCEN_SOUNDS; t++) AddSoundPage(Matcen[i]->GetSound(t), process_type); for (t = 0; t < Matcen[i]->GetNumProdTypes(); t++) { int index; Matcen[i]->GetProdInfo(t, &index, NULL, NULL, NULL); if (index != MATCEN_ERROR) AddGenericPage(index, process_type); } } for (i = 0; i < NUM_TERRAIN_SOUND_BANDS; i++) { if (Terrain_sound_bands[i].sound_index != -1) AddSoundPage(Terrain_sound_bands[i].sound_index, process_type); } // Get static fireballs for (i = 0; i < NUM_FIREBALLS; i++) { char name[PAGENAME_LEN]; strcpy(name, Fireballs[i].name); name[strlen(name) - 4] = 0; int id = FindTextureName(name); if (id != -1) AddTexturePage(id, process_type); else AddToList(Fireballs[i].name, PAGETYPE_GAMEFILE, process_type); } // Get static sounds for (i = 0; i < NUM_STATIC_SOUNDS; i++) { int sid = FindSoundName(Static_sound_names[i]); if (sid != -1) AddSoundPage(sid, process_type); } // First get textures for (i = 0; i <= Highest_room_index; i++) { if (!Rooms[i].used) continue; room *rp = &Rooms[i]; for (int t = 0; t < rp->num_faces; t++) { AddTexturePage(rp->faces[t].tmap, process_type); } } // Touch all terrain textures for (i = 0; i < TERRAIN_TEX_WIDTH * TERRAIN_TEX_DEPTH; i++) { AddTexturePage(Terrain_tex_seg[i].tex_index, process_type); } AddTexturePage(Terrain_sky.dome_texture, process_type); for (i = 0; i < Terrain_sky.num_satellites; i++) { AddTexturePage(Terrain_sky.satellite_texture[i], process_type); } // Touch all objects for (i = 0; i <= Highest_object_index; i++) { object *obj = &Objects[i]; if (obj->type == OBJ_NONE) { continue; } if (obj->type == OBJ_POWERUP || obj->type == OBJ_ROBOT || obj->type == OBJ_CLUTTER || obj->type == OBJ_BUILDING) { AddGenericPage(obj->id, process_type); continue; } if (obj->type == OBJ_DOOR) { AddDoorPage(obj->id, process_type); continue; } if (obj->control_type == CT_SOUNDSOURCE) { ASSERT(obj->type == OBJ_SOUNDSOURCE); if (obj->ctype.soundsource_info.sound_index != -1) AddSoundPage(obj->ctype.soundsource_info.sound_index, process_type); } } return TRUE; } // Creates the new table file by filtering out any pages that // are not in the current page data list bool PageDataList::CreateNewTableFile(char *new_table_filename, char *src_table_filename) { CFILE *infile, *outfile; uint8_t pagetype, replaced = 0; int done = 0, len; int pages_written; PageDataNode *node; CString summary_msg; bool unwritten_page_found; char ext[12]; mngs_texture_page texpage; //@@mngs_power_page powpage; mngs_door_page doorpage; //@@mngs_robot_page robotpage; mngs_generic_page genericpage; mngs_gamefile_page gamefilepage; mngs_sound_page soundpage; mngs_ship_page shippage; mngs_weapon_page weaponpage; mngs_megacell_page megacellpage; CWaitCursor wc; if (new_table_filename == NULL || src_table_filename == NULL) return FALSE; if (m_StatusText) m_StatusText->Format("Creating new table file - %s...", new_table_filename); if (m_Dlg) m_Dlg->UpdateData(FALSE); DeferMessages(); wc.Restore(); // First make sure we can open the table file and the temp table file infile = cfopen(src_table_filename, "rb"); if (!infile) { mprintf(0, "Couldn't open input table file!\n"); return FALSE; } outfile = cfopen(new_table_filename, "wb"); if (!outfile) { mprintf(0, "Couldn't open output table file!\n"); cfclose(infile); return FALSE; } // Mark all pages in data list as not having been written out for (node = m_head; node != NULL; node = node->next) node->flags &= ~PAGE_WRITTEN_FLAG; OpenFilterLogFiles(); // Read in every page from the source table file, but only write // out a page to the new table file if the same page name (and type) // are found in the current page data list pages_written = 0; while (!done) { if (cfeof(infile)) { done = 1; continue; } pagetype = cf_ReadByte(infile); len = cf_ReadInt(infile); switch (pagetype) { case PAGETYPE_TEXTURE: // Read it in, write it out. mng_ReadNewTexturePage(infile, &texpage); if ((node = FindNode(texpage.tex_struct.name, pagetype)) != NULL) { WriteToRemainingLog(texpage.tex_struct.name, pagetype); mng_WriteNewTexturePage(outfile, &texpage); node->flags |= PAGE_WRITTEN_FLAG; pages_written++; } else { WriteToRemovedLog(texpage.tex_struct.name, pagetype); } break; case PAGETYPE_POWERUP: // Read it in, write it out. //@@mng_ReadPowerPage (infile,&powpage); //@@mng_WritePowerPage (outfile,&powpage); if (m_Dlg) m_Dlg->MessageBox("A Powerup page was encountered in the source table file", "Powerup Page Encountered"); break; case PAGETYPE_DOOR: // Read it in, write it out. mng_ReadNewDoorPage(infile, &doorpage); if ((node = FindNode(doorpage.door_struct.name, pagetype)) != NULL) { WriteToRemainingLog(doorpage.door_struct.name, pagetype); mng_WriteNewDoorPage(outfile, &doorpage); node->flags |= PAGE_WRITTEN_FLAG; pages_written++; } else { WriteToRemovedLog(doorpage.door_struct.name, pagetype); } break; case PAGETYPE_ROBOT: // Read it in, write it out. //@@mng_ReadRobotPage (infile,&robotpage); //@@mng_WriteRobotPage (outfile,&robotpage); if (m_Dlg) m_Dlg->MessageBox("A Robot page was encountered in the source table file", "Robot Page Encountered"); break; case PAGETYPE_GENERIC: // Read it in, write it out. mng_ReadNewGenericPage(infile, &genericpage); if ((node = FindNode(genericpage.objinfo_struct.name, pagetype)) != NULL) { WriteToRemainingLog(genericpage.objinfo_struct.name, pagetype); mng_WriteNewGenericPage(outfile, &genericpage); node->flags |= PAGE_WRITTEN_FLAG; pages_written++; } else { WriteToRemovedLog(genericpage.objinfo_struct.name, pagetype); } if (genericpage.objinfo_struct.description != NULL) { mem_free(genericpage.objinfo_struct.description); genericpage.objinfo_struct.description = NULL; } break; case PAGETYPE_GAMEFILE: // Read it in, write it out. mng_ReadNewGamefilePage(infile, &gamefilepage); node = NULL; strcpy(ext, ""); if ((node = FindNode(gamefilepage.gamefile_struct.name, pagetype)) != NULL || ALWAYS_WRITE_GAMEFILE_PAGES) { // if(GetFileExt(gamefilepage.gamefile_struct.name,ext) && stricmp(ext,".d3l")!=0) { WriteToRemainingLog(gamefilepage.gamefile_struct.name, pagetype); mng_WriteNewGamefilePage(outfile, &gamefilepage); if (node) node->flags |= PAGE_WRITTEN_FLAG; pages_written++; //} else { // WriteToRemovedLog(gamefilepage.gamefile_struct.name,pagetype); //} } else { WriteToRemovedLog(gamefilepage.gamefile_struct.name, pagetype); } break; case PAGETYPE_SOUND: // Read it in, write it out. mng_ReadNewSoundPage(infile, &soundpage); if ((node = FindNode(soundpage.sound_struct.name, pagetype)) != NULL) { WriteToRemainingLog(soundpage.sound_struct.name, pagetype); mng_WriteNewSoundPage(outfile, &soundpage); node->flags |= PAGE_WRITTEN_FLAG; pages_written++; } else { WriteToRemovedLog(soundpage.sound_struct.name, pagetype); } break; case PAGETYPE_MEGACELL: // Read it in, write it out. mng_ReadNewMegacellPage(infile, &megacellpage); if ((node = FindNode(megacellpage.megacell_struct.name, pagetype)) != NULL) { WriteToRemainingLog(megacellpage.megacell_struct.name, pagetype); mng_WriteNewMegacellPage(outfile, &megacellpage); node->flags |= PAGE_WRITTEN_FLAG; pages_written++; } else { WriteToRemovedLog(megacellpage.megacell_struct.name, pagetype); } break; case PAGETYPE_SHIP: // Read it in, write it out. mng_ReadNewShipPage(infile, &shippage); if ((node = FindNode(shippage.ship_struct.name, pagetype)) != NULL) { WriteToRemainingLog(shippage.ship_struct.name, pagetype); mng_WriteNewShipPage(outfile, &shippage); node->flags |= PAGE_WRITTEN_FLAG; pages_written++; } else { WriteToRemovedLog(shippage.ship_struct.name, pagetype); } break; case PAGETYPE_WEAPON: // Read it in, write it out. mng_ReadNewWeaponPage(infile, &weaponpage); if ((node = FindNode(weaponpage.weapon_struct.name, pagetype)) != NULL) { WriteToRemainingLog(weaponpage.weapon_struct.name, pagetype); mng_WriteNewWeaponPage(outfile, &weaponpage); node->flags |= PAGE_WRITTEN_FLAG; pages_written++; } else { WriteToRemovedLog(weaponpage.weapon_struct.name, pagetype); } break; case PAGETYPE_UNKNOWN: WriteToRemainingLog("Unknown", pagetype); mng_WriteUnknownPage(outfile); break; default: Int3(); // unrecognized pagetype break; } } CloseFilterLogFiles(); cfclose(infile); cfclose(outfile); if (m_StatusText) m_StatusText->Format("New Table File Created (%d pages)", pages_written); if (m_Dlg) m_Dlg->UpdateData(FALSE); DeferMessages(); // Create message summary (if some pages weren't written) unwritten_page_found = FALSE; summary_msg = "The following pages were not written out (they were not found in the source table file):\n\n"; for (node = m_head; node != NULL; node = node->next) { if (node->flags & PAGE_WRITTEN_FLAG) continue; // This node was not written out! unwritten_page_found = TRUE; CString temp_str; temp_str.Format("%s, ", node->name); summary_msg += temp_str; } // Display message summary (if some pages weren't written) if (unwritten_page_found) if (m_Dlg) m_Dlg->MessageBox(summary_msg, "Not All Pages Were Written"); // Mark all pages in data list as not having been written out for (node = m_head; node != NULL; node = node->next) node->flags &= ~PAGE_WRITTEN_FLAG; return TRUE; // successful! } // Inserts data from the given node into the dialog list control bool PageDataList::AddToListCtrl(int index, PageDataNode *node) { int pos; CString type_text; CWaitCursor wc; // Make sure this is worth doing if (node == NULL) return FALSE; if (m_PageDataListCtrl == NULL) return FALSE; // Add the data to the list control if ((pos = m_PageDataListCtrl->InsertItem(0, node->name)) == -1) return FALSE; switch (node->type) { case PAGETYPE_UNKNOWN: type_text = "Unknown"; break; case PAGETYPE_TEXTURE: type_text = "Texture"; break; case PAGETYPE_WEAPON: type_text = "Weapon"; break; case PAGETYPE_ROBOT: type_text = "Robot"; break; case PAGETYPE_POWERUP: type_text = "Powerup"; break; case PAGETYPE_DOOR: type_text = "Door"; break; case PAGETYPE_SHIP: type_text = "Ship"; break; case PAGETYPE_SOUND: type_text = "Sound"; break; case PAGETYPE_MEGACELL: type_text = "Megacell"; break; case PAGETYPE_GAMEFILE: type_text = "Gamefile"; break; case PAGETYPE_GENERIC: type_text = "Generic"; break; } m_PageDataListCtrl->SetItem(pos, PAGE_TYPE_COLUMN, LVIF_TEXT, type_text.GetBuffer(0), 0, 0, 0, 0); return TRUE; } // Removes all selected items from the list control bool PageDataList::RemoveSelFromListCtrl(void) { int j, num_items; LV_ITEM item_info; char name[PAGENAME_LEN + 1]; char type[_MAX_PATH + 1]; CWaitCursor wc; if (m_PageDataListCtrl == NULL) return FALSE; // How many items in the control list? num_items = m_PageDataListCtrl->GetItemCount(); j = 0; while (j < num_items) { // Grab the info for item #j item_info.iItem = j; item_info.iSubItem = 0; item_info.mask = LVIF_TEXT | LVIF_STATE; item_info.stateMask = LVIS_SELECTED; item_info.pszText = name; item_info.cchTextMax = PSFILENAME_LEN + 1; m_PageDataListCtrl->GetItem(&item_info); // Is item at index j selected? if (item_info.state & LVIS_SELECTED) { // yes, delete it // Get Directory name for item #j item_info.iSubItem = PAGE_TYPE_COLUMN; item_info.pszText = type; item_info.cchTextMax = _MAX_PATH; m_PageDataListCtrl->GetItem(&item_info); int page_type; if (stricmp(type, "Unknown") == 0) page_type = PAGETYPE_UNKNOWN; else if (stricmp(type, "Texture") == 0) page_type = PAGETYPE_TEXTURE; else if (stricmp(type, "Weapon") == 0) page_type = PAGETYPE_WEAPON; else if (stricmp(type, "Robot") == 0) page_type = PAGETYPE_ROBOT; else if (stricmp(type, "Powerup") == 0) page_type = PAGETYPE_POWERUP; else if (stricmp(type, "Door") == 0) page_type = PAGETYPE_DOOR; else if (stricmp(type, "Ship") == 0) page_type = PAGETYPE_SHIP; else if (stricmp(type, "Sound") == 0) page_type = PAGETYPE_SOUND; else if (stricmp(type, "Megacell") == 0) page_type = PAGETYPE_MEGACELL; else if (stricmp(type, "Gamefile") == 0) page_type = PAGETYPE_GAMEFILE; else page_type = PAGETYPE_GENERIC; // Search for and remove corresponding entry from Document Library PageDataNode *found_node; found_node = FindNode(name, page_type); if (found_node != NULL) { RemoveFromList(found_node); wc.Restore(); } else { if (m_Dlg) m_Dlg->MessageBox("The list control does not match the data list.", "List Mismatch Error!"); wc.Restore(); } // Delete entry/item from control list m_PageDataListCtrl->DeleteItem(j); num_items = m_PageDataListCtrl->GetItemCount(); } else j++; } return TRUE; } // Displays the modified confirmation prompt if appropriate int PageDataList::ModifiedPrompt(void) { if (m_Dlg == NULL) return (IDNO); // If current file has been modified, check with user first... if (!m_DataListModified) return (IDYES); if (m_Dlg->MessageBox("Changes to data list will be lost. Proceed?", "Page Data List Has Been Modified", MB_YESNO) == IDYES) return (IDYES); return (IDNO); } // Sets the title bar string void PageDataList::SetTitleString(void) { if (m_Dlg == NULL) return; char title[1024]; char loaded_file[1024]; if (!m_DataListFilename.IsEmpty()) sprintf(loaded_file, " - [%s%s]", m_DataListFilename.GetBuffer(0), (m_DataListModified) ? "*" : ""); else sprintf(loaded_file, ""); sprintf(title, "%s%s", TITLE_NAME, loaded_file); m_Dlg->SetWindowText(title); } // Adds a page specified by the "Add Page" button bool PageDataList::AddPageFromUser(char *page_name, uint8_t page_type) { int id; switch (page_type) { case PAGETYPE_GENERIC: id = FindObjectIDName(page_name); if (id == -1) return FALSE; AddGenericPage(id, ADD_PAGES); break; case PAGETYPE_TEXTURE: id = FindTextureName(page_name); if (id == -1) return FALSE; AddTexturePage(id, ADD_PAGES); break; case PAGETYPE_SOUND: id = FindSoundName(page_name); if (id == -1) return FALSE; AddSoundPage(id, ADD_PAGES); break; case PAGETYPE_DOOR: id = FindDoorName(page_name); if (id == -1) return FALSE; AddDoorPage(id, ADD_PAGES); break; case PAGETYPE_SHIP: id = FindShipName(page_name); if (id == -1) return FALSE; AddShipPage(id, ADD_PAGES); break; case PAGETYPE_WEAPON: id = FindWeaponName(page_name); if (id == -1) return FALSE; AddWeaponPage(id, ADD_PAGES); break; default: return FALSE; } return TRUE; } // Returns the pagetype for a given string (PAGETYPE_UNKNOWN if not valid) uint8_t PageDataList::GetPageTypeFromString(char *text) { int type; if (text == NULL) return (PAGETYPE_UNKNOWN); type = PAGETYPE_UNKNOWN; if (strcmp(text, "PAGETYPE_SOUND") == 0) type = PAGETYPE_SOUND; else if (strcmp(text, "PAGETYPE_GENERIC") == 0) type = PAGETYPE_GENERIC; else if (strcmp(text, "PAGETYPE_WEAPON") == 0) type = PAGETYPE_WEAPON; else if (strcmp(text, "PAGETYPE_GAMEFILE") == 0) type = PAGETYPE_GAMEFILE; else if (strcmp(text, "PAGETYPE_TEXTURE") == 0) type = PAGETYPE_TEXTURE; else if (strcmp(text, "PAGETYPE_DOOR") == 0) type = PAGETYPE_DOOR; else if (strcmp(text, "PAGETYPE_SHIP") == 0) type = PAGETYPE_SHIP; return (type); } // Processes a page read in from text file bool PageDataList::ProcessPageFromFile(char *page_name, uint8_t page_type, int process_type) { char ext[12]; int id; switch (page_type) { case PAGETYPE_GENERIC: id = FindObjectIDName(page_name); if (id == -1) return FALSE; AddGenericPage(id, process_type); break; case PAGETYPE_TEXTURE: id = FindTextureName(page_name); if (id == -1) return FALSE; AddTexturePage(id, process_type); break; case PAGETYPE_SOUND: id = FindSoundName(page_name); if (id == -1) return FALSE; AddSoundPage(id, process_type); break; case PAGETYPE_DOOR: id = FindDoorName(page_name); if (id == -1) return FALSE; AddDoorPage(id, process_type); break; case PAGETYPE_SHIP: id = FindShipName(page_name); if (id == -1) return FALSE; AddShipPage(id, process_type); break; case PAGETYPE_WEAPON: id = FindWeaponName(page_name); if (id == -1) return FALSE; AddWeaponPage(id, process_type); break; case PAGETYPE_GAMEFILE: GetFileExt(page_name, ext); // if (stricmp(ext,".d3l")) //{ ProcessPage(page_name, PAGETYPE_GAMEFILE, process_type); //} if (!stricmp(ext, ".oof")) { int pid = LoadPolyModel(page_name, 0); if (pid != -1) { PageInPolymodel(pid); poly_model *pm = &Poly_models[pid]; for (int t = 0; t < pm->n_textures; t++) AddTexturePage(pm->textures[t], process_type); } else { mprintf(0, "Couldn't find polymodel %s!\n", page_name); Int3(); } } break; default: return FALSE; } return TRUE; } // Scans one of Jeff's TableParse output files and processes // all of the pages contained within bool PageDataList::ProcessPagesInTextFile(char *filename, int process_type) { CFILE *infile; char linebuf[2048]; char *line; int linenum; char *pagename; uint8_t pagetype; char *pagetype_text; CString pages_not_added; int num_pages_not_added; // Try to open the file for loading infile = cfopen(filename, "rt"); if (!infile) { CString msg; msg.Format("Unable to open \"%s\"!", filename); m_Dlg->MessageBox(msg, "TableParse Output File Error!", MB_OK | MB_ICONEXCLAMATION); return FALSE; } linenum = 0; pages_not_added = "The following pages were not processed successfully:\n\n"; num_pages_not_added = 0; // Read in and parse each line of the file while (!cfeof(infile)) { // Clear the buffer strcpy(linebuf, ""); // Read in a line from the file cf_ReadString(linebuf, sizeof(linebuf), infile); linenum++; // Remove whitespace padding at start and end of line RemoveTrailingWhitespace(linebuf); line = SkipInitialWhitespace(linebuf); // If the line is empty, grab a new one if (strlen(line) == 0) continue; // Grab the page type line = strtok(line, " \t\n"); if (line == NULL) continue; pagetype = GetPageTypeFromString(line); if (pagetype == PAGETYPE_UNKNOWN) { CString msg; msg.Format("Found invalid page type: %s, in %s, line %d", line, filename, linenum); m_Dlg->MessageBox(msg, "Invalid Page Type", MB_OK | MB_ICONEXCLAMATION); continue; } pagetype_text = line; // Grab the page name pagename = strtok(NULL, ""); if (pagename == NULL || strlen(pagename) == 0) { CString msg; msg.Format("No page name found in %s, line %d", filename, linenum); m_Dlg->MessageBox(msg, "Invalid Page Name", MB_OK | MB_ICONEXCLAMATION); continue; } // remove quotes if (pagename[0] == '"') { char *end_of_name; pagename++; end_of_name = strchr(pagename, '"'); if (end_of_name != NULL) (*end_of_name) = '\0'; } // Make sure we still have a name if (strlen(pagename) == 0) { CString msg; msg.Format("No page name found in %s, line %d", filename, linenum); m_Dlg->MessageBox(msg, "Invalid Page Name", MB_OK | MB_ICONEXCLAMATION); continue; } // Try and add the page if (!ProcessPageFromFile(pagename, pagetype, process_type)) { CString msg; msg.Format("%s(%s), ", pagename, pagetype_text); if (num_pages_not_added < 30) pages_not_added += msg; else if (num_pages_not_added == 30) pages_not_added += "and even more..."; num_pages_not_added++; } } cfclose(infile); /* if(num_pages_not_added>0) { m_Dlg->MessageBox(pages_not_added,"Not All Pages From File Were Processed",MB_OK|MB_ICONEXCLAMATION); } */ return TRUE; } // Adds all appropriate gamefiles to the list bool PageDataList::AddAllGamefilePages(void) { int i; char ext[12]; for (i = 0; i < MAX_GAMEFILES; i++) { if (Gamefiles[i].used != 0 && GetFileExt(Gamefiles[i].name, ext) && stricmp(ext, ".d3l") != 0) { AddToList(Gamefiles[i].name, PAGETYPE_GAMEFILE, ADDED_FOR_LEVEL_FLAG); } } return TRUE; } // Processes any waiting messages #define MAX_MESSAGES 10 // max messages to process during a message deferral void DeferMessages(void) { MSG msg; for (int MsgCount = MAX_MESSAGES; MsgCount && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); MsgCount--) { TranslateMessage(&msg); DispatchMessage(&msg); } } // Log file handles CFILE *remaining_log_file = NULL; CFILE *removed_log_file = NULL; // Opens the Filter Log Files void OpenFilterLogFiles(void) { char fullpath[_MAX_PATH + 1]; ddio_MakePath(fullpath, LocalD3Dir, "Remaining Pages.txt", NULL); remaining_log_file = cfopen(fullpath, "wt"); if (remaining_log_file == NULL) { mprintf(0, "Couldn't open \"Remaining Pages\" log file!\n"); return; } ddio_MakePath(fullpath, LocalD3Dir, "Removed Pages.txt", NULL); removed_log_file = cfopen(fullpath, "wt"); if (removed_log_file == NULL) { mprintf(0, "Couldn't open \"Removed Pages\" log file!\n"); return; } } // Returns the pagetype string for a given type void GetPageTypeString(int type, CString &type_text) { switch (type) { case PAGETYPE_TEXTURE: type_text = "Texture "; break; case PAGETYPE_WEAPON: type_text = "Weapon "; break; case PAGETYPE_ROBOT: type_text = "Robot "; break; case PAGETYPE_POWERUP: type_text = "Powerup "; break; case PAGETYPE_DOOR: type_text = "Door "; break; case PAGETYPE_SHIP: type_text = "Ship "; break; case PAGETYPE_SOUND: type_text = "Sound "; break; case PAGETYPE_MEGACELL: type_text = "Megacell"; break; case PAGETYPE_GAMEFILE: type_text = "Gamefile"; break; case PAGETYPE_GENERIC: type_text = "Generic "; break; default: type_text = "Unknown "; break; } } // Writes a page to the "remaining pages" log file void WriteToRemainingLog(char *name, int type) { if (remaining_log_file != NULL) { CString line, type_string; GetPageTypeString(type, type_string); line.Format("%s\t%s", type_string, name); cf_WriteString(remaining_log_file, line.GetBuffer(0)); } } // Writes a page to the "removed pages" log file void WriteToRemovedLog(char *name, int type) { if (removed_log_file != NULL) { CString line, type_string; GetPageTypeString(type, type_string); line.Format("%s\t%s", type_string, name); cf_WriteString(removed_log_file, line.GetBuffer(0)); } } // Closes the Filter Log Files void CloseFilterLogFiles(void) { if (remaining_log_file != NULL) cfclose(remaining_log_file); if (removed_log_file != NULL) cfclose(removed_log_file); }