diff options
author | Ian C <ianc@noddybox.co.uk> | 2011-06-09 13:46:28 +0000 |
---|---|---|
committer | Ian C <ianc@noddybox.co.uk> | 2011-06-09 13:46:28 +0000 |
commit | a9022b5972dc49d86f617a27940fafe9c4d0e7e7 (patch) | |
tree | 61405aa4ade91ed1057f863ddf118ceb38e14f8e /vidoom.c |
Initial import of (very old) vidoom sources.
Diffstat (limited to 'vidoom.c')
-rw-r--r-- | vidoom.c | 892 |
1 files changed, 892 insertions, 0 deletions
diff --git a/vidoom.c b/vidoom.c new file mode 100644 index 0000000..467912c --- /dev/null +++ b/vidoom.c @@ -0,0 +1,892 @@ +/* + + viDOOM - level editor for DOOM + + Copyright (C) 2000 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------- + + Doom I/II editor + +*/ +static const char rcs_id[]="$Id$"; + +#include "config.h" +#include "globals.h" + +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +#include "wad.h" +#include "platgui.h" +#include "gui.h" +#include "gfx.h" +#include "file.h" +#include "mem.h" +#include "edit.h" +#include "texture.h" +#include "things.h" +#include "runcmd.h" +#include "names.h" +#include "util.h" + +/* ---------------------------------------- VARS +*/ +static WadMap *wad=NULL; +static char mapname[32]="NONE"; +static GFX_IMAGE doom_image; + +/* Menu for asking game type +*/ +static PLAT_MENU game_type_menu[]= + { + {"Doom", DOOM}, + {"Ultimate Doom", ULTIMATE_DOOM}, + {"Doom II", DOOM_2}, + {"TNT:Evilution", FINAL_TNT}, + {"The Plutonia Experiment", FINAL_PLUTONIA}, + {"ZDoom", ZDOOM}, + {NULL,0} + }; + + +/* ---------------------------------------- PROTOS +*/ +static void MainMenu(void); +static void GPL_clear(void); +static int CreateHexenMap(void); + + +/* ---------------------------------------- MAIN +*/ +int viDOOM(int argc,char *argv[]) +{ + char *load,*p; + int f; + + if (getenv("VIDOOM_DIR")) + Cd(getenv("VIDOOM_DIR")); + + GFX_init(); + + if (GFX_mouse_buttons()<2) + GFX_exit(EXIT_FAILURE,"viDOOM expects at least a 2-button mouse\n"); + + LoadGlobalsPart1(); + + if ((disp_width<640)||(disp_height<480)) + GFX_exit(EXIT_FAILURE,"viDOOM expects at least a display of 640x480\n"); + + GFX_open(disp_width,disp_height); + EditSetScreen(disp_width,disp_height); + GuiSetScreen(disp_width,disp_height); + GUI_setscreen(disp_width,disp_height); + + GPL_clear(); + + /* Ask for game type? + */ + if (ask_for_game_type) + { + int new; + + GFX_redraw(); + + new=GUI_menu("Select type of game to edit", + disp_width/2,disp_height/2,game_type_menu,-666); + + if (new!=-666) + game=(GameType)new; + } + + LoadGlobalsPart2(); + + if (AddIWAD(IWAD_path)!=WAD_OK) + { + GuiInfoBox("ERROR","AddIWAD(%s): %s",IWAD_path,WadErrorString()); + GFX_close(); + return(EXIT_FAILURE); + } + + /* Read in resource WADS from preloaded config + */ + if (PWAD_preload[0]) + { + load=Strdup(PWAD_preload); + + p=strtok(load,";"); + + while(p) + { + if (AddPWAD(p)!=WAD_OK) + GuiInfoBox("ERROR","AddPWAD(%s): %s",p,WadErrorString()); + + p=strtok(NULL,";"); + } + + Release(load); + } + + /* Read in WADS from command line + */ + for(f=1;f<argc;f++) + if (AddPWAD(argv[f])!=WAD_OK) + GuiInfoBox("ERROR","AddPWAD(%s): %s",argv[f],WadErrorString()); + + /* Read in editor configuration + */ + GPL_clear(); + GuiDrawInfoBox("Please wait",GUI_CENTRE,GUI_CENTRE,TRUE, + "Reading editor|config file"); + GFX_redraw(); + LoadConfig(); + + /* Read in TEXTURES and FLATS + */ + GPL_clear(); + ReadWADTextures(); + + GPL_clear(); + ReadWADFlats(); + + if (show_titlepic) + doom_image=DecodeGraphicsLump("TITLEPIC"); + else + doom_image=NULL; + + + /* Auto load levels + */ + if (!STREQ(auto_loadmap,"")) + { + char *orig; + + UCase(auto_loadmap); + orig=Strdup(auto_loadmap); + p=strtok(auto_loadmap,","); + + while((p)&&(!wad)) + { + if ((wad=LoadMap(p))) + { + strcpy(mapname,p); + EditLoad(wad); + } + + p=strtok(NULL,","); + } + + if (!wad) + GuiInfoBox("ERROR","Failed to load any of the following:|%s",orig); + + Release(orig); + } + else + { + /* Create initial empty map + */ + if (initial_empty_map) + { + switch(level_style) + { + case DOOM_LEVELS: + case ULTIMATE_DOOM_LEVELS: + strcpy(mapname,"E1M1"); + break; + + case DOOM_2_LEVELS: + strcpy(mapname,"MAP01"); + break; + + } + + wad=NewMap(CreateHexenMap()); + EditLoad(wad); + } + } + + MainMenu(); + + GFX_close(); + + return(EXIT_SUCCESS); +} + +/* Clear screen and show simple GPL warning during startup +*/ +static void GPL_clear(void) +{ + GFX_clear(BLACK); + + GuiDrawInfoBox("viDOOM " VIDOOMVER " " VIDOOMRELEASE, + GUI_CENTRE,GUI_FLUSH_TOP,TRUE, + "Copyright (c) 2000 Ian Cowburn| |" + "viDOOM comes with ABSOLUTELY NO WARRANTY.|" + "For details see LICENSE.| |" + "This is free software, and you are welcome|" + "to redistribute it under certain conditions.|" + "See LICENSE for details."); +} + + +/* Returns TRUE/FALSE as to whether to create a HEXEN map +*/ +static int CreateHexenMap(void) +{ + switch(create_hexen) + { + case GEN_NO: + return(FALSE); + break; + + case GEN_YES: + return(TRUE); + break; + + case GEN_ASK: + return(GUI_yesno("Create as a HEXEN map?")); + break; + } + + return(FALSE); +} + + +/* Format an argument for the node builder command +*/ +static char *FormatArg(char *path, char *arg) +{ + char *ret; + char *p; + + ret=Grab(PATH_MAX); + p=ret; + + while(*arg) + if (*arg=='%') + { + *p=0; + strcat(ret,path); + p+=strlen(path); + arg++; + } + else + *p++=*arg++; + + return(ret); +} + + +/* Upper case a string +*/ +static void ToUpper(char *p) +{ + while(*p) + { + *p=toupper(*p); + p++; + } +} + + +/* Check whether file should be ignored for node building +*/ +static int IsIgnored(char *path) +{ + char i[PATH_MAX]; + char w[PATH_MAX]; + + if (!build_ignore[0]) + return(FALSE); + + strcpy(w,Basename(path)); + strcpy(i,build_ignore); + + ToUpper(w); + ToUpper(i); + + return((int)strstr(w,i)); +} + + +/* ---------------------------------------- TOP LEVEL MENU +*/ +static void MainMenu(void) +{ +# define MENU_NEW 1 +# define MENU_LOAD 2 +# define MENU_EDIT 3 +# define MENU_SAVE 4 +# define MENU_OPEN 5 +# define MENU_CLOSE 6 +# define MENU_PREVIEW 7 +# define MENU_ABOUT 8 +# define MENU_QUIT 9 +# define MENU_RENAME 10 +# define MENU_LISTDIR 11 +# define MENU_DEBUG 12 +# define MENU_LICENSE 13 + + static PLAT_MENU main_menu[]= + { + {"Edit current level", MENU_EDIT}, + {"Load level from open WADs", MENU_LOAD}, + {"Save current level", MENU_SAVE}, + {"Create new empty level", MENU_NEW}, + {"Change current level name", MENU_RENAME}, + {"Open PWAD file", MENU_OPEN}, + {"Close PWAD file", MENU_CLOSE}, + {"Preview level", MENU_PREVIEW}, + {"View entries in WAD directory", MENU_LISTDIR}, + {"About viDOOM " VIDOOMVER, MENU_ABOUT}, + {"View License", MENU_LICENSE}, +#ifdef VIDOOM_DEBUG + {"DEBUG", MENU_DEBUG}, +#endif + {"Quit", MENU_QUIT}, + {NULL,0} + }; + + int quit; + int edited; + + quit=FALSE; + edited=FALSE; + +#ifdef VIDOOM_DEBUG + if (FileExists("todo")) + GUI_view_file("TODO list","todo"); +#endif + + while(!quit) + { + char *open; + + GFX_clear(BLACK); + + if (doom_image) + GFX_fill_screen(doom_image); + + if (STREQ(mapname,"NONE")) + GuiDrawInfoBox(GameName(),GUI_FLUSH_RIGHT,GUI_FLUSH_TOP,FALSE, + "Current map : %s|" + " | |" + "Open WAD files :|%s", + mapname,open=OpenWads()); + else + GuiDrawInfoBox(GameName(),GUI_FLUSH_RIGHT,GUI_FLUSH_TOP,FALSE, + "Current map : %s|" + " %s| |" + "Open WAD files :|%s", + mapname,MapName(mapname),open=OpenWads()); + + Release(open); + + GFX_redraw(); + + switch(GUI_menu("MAIN MENU",10,10,main_menu,-1)) + { + case MENU_NEW: + { + char *name; + int new=TRUE; + + if ((name=GuiPickLevel("Pick map to create"))) + { + if (wad) + if ((!map_warn)|| + (new=GUI_yesno("Map already open. Continue?"))) + { + strcpy(mapname,"NONE"); + wad=ClearMap(wad); + edited=FALSE; + } + + if (new) + { + strcpy(mapname,name); + wad=NewMap(CreateHexenMap()); + EditLoad(wad); + edited=FALSE; + } + } + + break; + } + + case MENU_LOAD: + { + char *name; + int load=TRUE; + + if ((name=GuiPickLevel("Pick map to load for editting"))) + { + if (wad) + if ((!map_warn)|| + (load=GUI_yesno("Map already open. Continue?"))) + { + strcpy(mapname,"NONE"); + wad=ClearMap(wad); + edited=FALSE; + } + + if (load) + { + GuiDrawInfoBox("Loading...",GUI_CENTRE,GUI_CENTRE,TRUE, + "Loading level %s",name); + GFX_redraw(); + + if (!(wad=LoadMap(name))) + GuiInfoBox("ERROR","LoadMap(%s): %s", + name,WadErrorString()); + else + { + strcpy(mapname,name); + EditLoad(wad); + edited=FALSE; + } + } + } + + break; + } + + case MENU_EDIT: + if (!wad) + GuiInfoBox("ERROR","No map currently being edited"); + else + { + EditLoop(); + edited=TRUE; + } + break; + + case MENU_SAVE: + { + char *wadf; + + if (!wad) + GuiInfoBox("ERROR","No map currently being edited"); + else + if ((wadf=GUI_fsel + ("Select WAD to save map as",PWAD_dir,".WAD"))) + { + int ok; + + if (WadFileType(wadf)==FILE_IS_IWAD) + { + GuiInfoBox("ERROR","Cannot overwrite %s|" + "It is an IWAD",wadf); + + ok=FALSE; + } + else + { + if ((overwrite_warning)&&(FileExists(wadf))) + ok=GUI_yesno("Overwrite file?"); + else + ok=TRUE; + } + + if (ok) + { + GuiDrawInfoBox + ("Saving...",GUI_CENTRE,GUI_CENTRE,TRUE, + "Saving level %s to %s",mapname,wadf); + GFX_redraw(); + + EditCompact(); + EditSave(wad); + + if (SaveMap(wad,mapname,wadf)!=WAD_OK) + GuiInfoBox("ERROR","SaveMap(%s)|%s", + wadf,WadErrorString()); + else + { + int do_build; + char *open; + char *p; + + edited=FALSE; + + if (use_build) + do_build=!IsIgnored(wadf); + else + do_build=FALSE; + + if (do_build) + { + char path[PATH_MAX]; + char *arg[4]; + + arg[0]=build_cmd; + + if (build_in_before_out) + { + arg[1]=FormatArg(wadf,build_in); + arg[2]=FormatArg(wadf,build_out); + } + else + { + arg[2]=FormatArg(wadf,build_in); + arg[1]=FormatArg(wadf,build_out); + } + + arg[3]=NULL; + + if (RunCommand(arg,path)) + { + if ((build_always_view)&&(path[0])) + GUI_view_file("Node Builder",path); + } + else + if (path[0]) + GUI_view_file("Node Builder FAILED", + path); + else + GuiInfoBox("ERROR", + "Node builder|%s|failed|" + "(no results available)", + build_cmd); + + if (path[0]) + remove(path); + + Release(arg[1]); + Release(arg[2]); + } + + /* Check to see if we've saved on of the + currently loaded PWADS + */ + if ((open=OpenWads())) + { + p=open; + + p=strtok(p,"|"); + + while(p) + { + if (FilenamesEqual(p,wadf)) + { + if (CloseWad(wadf)!=WAD_OK) + GuiInfoBox + ("ERROR","CloseWad(%s)|%s", + wadf,WadErrorString()); + + if (AddPWAD(wadf)!=WAD_OK) + GuiInfoBox + ("ERROR","AddPWAD(%s)|%s", + wadf,WadErrorString()); + + p=NULL; + } + else + p=strtok(NULL,"|"); + } + + Release(open); + } + } + } + + Release(wadf); + } + break; + } + + case MENU_RENAME: + { + char *name; + + if (!wad) + GuiInfoBox("ERROR","No map currently being edited"); + else + if ((name=GuiPickLevel("Pick new name for level"))) + strcpy(mapname,name); + + break; + } + + case MENU_OPEN: + { + char *wadf; + + if ((wadf=GUI_fsel("Select WAD to open",PWAD_dir,".WAD"))) + { + GuiDrawInfoBox("Loading...",GUI_CENTRE,GUI_CENTRE,TRUE, + "Loading PWAD %s",wadf); + GFX_redraw(); + + if (AddPWAD(wadf)!=WAD_OK) + GuiInfoBox("ERROR","AddPWAD(%s)|%s", + wadf,WadErrorString()); + + Release(wadf); + } + } + break; + + case MENU_CLOSE: + { + char *open; + char *wadf[512]; + char *p; + int f; + + if ((open=OpenWads())) + { + p=strtok(open,"|"); + f=0; + + while(p) + { + wadf[f++]=p; + p=strtok(NULL,"|"); + } + + wadf[f]=NULL; + + f=GUI_picklist("Select WAD file to close",wadf); + + if (f!=-1) + { + if (strcmp(wadf[f],IWAD_path)==0) + GuiInfoBox("ERROR","Cannot unload base IWAD|%s", + wadf[f]); + else + { + GuiDrawInfoBox("Closing...", + GUI_CENTRE,GUI_CENTRE,TRUE, + "Closing PWAD %s",wadf[f]); + + if (CloseWad(wadf[f])!=WAD_OK) + GuiInfoBox("ERROR","CloseWad(%s)|%s", + wadf[f],WadErrorString()); + } + } + + Release(open); + } + + break; + } + + case MENU_LISTDIR: + { + char s[256]; + WadDir *wd; + Iterator i; + char **list; + WadDir **dir; + int f; + int opt; + + list=Grab(sizeof(char *)*(GetWadDirSize()+1)); + dir=Grab(sizeof(WadDir *)*(GetWadDirSize())); + i=GetWadDir(); + + f=0; + while(i) + { + wd=IteratorData(i); + i=IteratorNext(i); + + sprintf(s,"%-9s 0x%.8lx 0x%.8lx %s", + wd->name,wd->off,wd->size,Basename(wd->wad)); + + dir[f]=wd; + list[f]=Strdup(s); + + f++; + } + + list[f]=NULL; + + if ((opt=GUI_picklist + ("WAD DIR (Name, Offset, Size, WAD file)",list))!=-1) + { + char asc[9]; + unsigned char *lump; + Long len; + FILE *fp; + char *path; + int r; + + if ((lump=GetLumpFrom(dir[opt],&len))) + { + if (len) + { + path=tmpnam(NULL); + if ((fp=fopen(path,"w"))) + { + f=0; + + while(f<len) + { + strcpy(asc," "); + + fprintf(fp,"%6.6x: ",f); + + for(r=0;r<8;r++) + { + if ((f+r)<len) + { + fprintf(fp,"%2.2x ", + (unsigned char)lump[f+r]); + + if (isprint(lump[f+r])) + asc[r]=lump[f+r]; + else + asc[r]='.'; + } + else + fprintf(fp,"** "); + } + + fprintf(fp," \"%s\"\n",asc); + + f+=8; + } + + fclose(fp); + + sprintf(s,"%s (Offset 0x%lx, " + "Size 0x%lx) from %s", + dir[opt]->name, + dir[opt]->off, + dir[opt]->size, + Basename(dir[opt]->wad)); + + GUI_view_file(s,path); + + remove(path); + } + } + else + GuiInfoBox("NOTICE", + "%s is a zero length lump",dir[opt]->name); + + Release(lump); + } + } + + f=0; + while(list[f]) + { + Release(list[f]); + f++; + } + + Release(list); + Release(dir); + + break; + } + + case MENU_PREVIEW: + { + char *name; + WadMap *preview; + + if ((name=GuiPickLevel("Pick map to preview"))) + { + if (!(preview=LoadMap(name))) + GuiInfoBox("ERROR","LoadMap(%s): %s", + name,WadErrorString()); + else + { + EditPreviewWadMap(name,preview); + preview=ClearMap(preview); + } + } + + break; + } + + case MENU_ABOUT: + GuiInfoBox ("viDOOM " VIDOOMVER " " VIDOOMRELEASE, + "Copyright (c) 2000 Ian Cowburn|" + "http://www.noddybox.demon.co.uk/vidoom/| |" + + "viDOOM comes with ABSOLUTELY NO WARRANTY.|" + "For details see LICENSE.| |" + + "This is free software, and you are welcome|" + "to redistribute it under certain conditions.|" + "See LICENSE for details.| |" + + "DOOM, Ultimate DOOM, DOOM 2 and Final DOOM|" + "(c) id Software.|" + "http://www.idsoftware.com/| |" + "Levels in DOOM, DOOM 2 and Ultimate DOOM|" + "designed by id Software.| |" + "Levels in The Plutonia Experiment designed by|" + "Milo & Dario Casali whilst in Team TNT.| |" + "Levels in TNT:Evilution designed by|" + "various members of Team TNT. Get details at|" + "http://www.teamtnt.com/| |" + "Thanks to all concerned for some of my favourite|" + "Lovecraftian Dark Evil Places.| |" + "viDOOM will only work if you have the registered|" + "version of any of the follow id Sofwtare games:|" + "DOOM, Ultimate DOOM, DOOM 2 or Final DOOM"); + break; + + case MENU_LICENSE: + GUI_view_file("viDOOM " VIDOOMVER " " VIDOOMRELEASE, + "LICENSE"); + break; + + case MENU_QUIT: + if ((map_exit_warn)&&(edited)) + quit=GUI_yesno("Map may have been changed " + "- really quit?"); + else + quit=TRUE; + break; + +#ifdef VIDOOM_DEBUG + case MENU_DEBUG: + GuiInfoBox("DEBUG", + "block_bit=%d|" + "block_mask=%d|" + "side2_bit=%d|" + "side2_mask=%d|" + "upper_bit=%d|" + "upper_mask=%d|" + "lower_bit=%d|" + "lower_mask=%d|" + "empty_texture='%s'|" + "", + block_bit,block_mask, + side2_bit,side2_mask, + upper_peg_bit,upper_peg_mask, + lower_peg_bit,lower_peg_mask, + empty_texture); + break; +#endif + + default: + break; + } + } +} + + +/* END OF FILE */ |