diff options
Diffstat (limited to 'src')
34 files changed, 548 insertions, 171 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 5dc9fe11..746a015b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -191,6 +191,18 @@ EXTRA_DIST = \ icon.c \ doom-screensaver.desktop.in +appdir = $(prefix)/share/applications +app_DATA = @PROGRAM_PREFIX@doom.desktop + +@PROGRAM_PREFIX@doom.desktop : doom.desktop + cp $^ $@ + +screensaverdir = $(prefix)/share/applications/screensavers +screensaver_DATA = @PROGRAM_PREFIX@doom-screensaver.desktop + +@PROGRAM_PREFIX@doom-screensaver.desktop: doom-screensaver.desktop + cp $^ $@ + .rc.o: $(WINDRES) $^ -o $@ %.o : %.rc diff --git a/src/d_mode.h b/src/d_mode.h index 29f61c10..1c4fff64 100644 --- a/src/d_mode.h +++ b/src/d_mode.h @@ -65,6 +65,7 @@ typedef enum exe_hacx, // Hacx exe_ultimate, // Ultimate Doom (retail) exe_final, // Final Doom + exe_final2, // Final Doom (alternate exe) exe_chex, // Chex Quest executable (based on Final Doom) exe_heretic_1_3, // Heretic 1.3 diff --git a/src/deh_io.c b/src/deh_io.c index 92c81632..83609068 100644 --- a/src/deh_io.c +++ b/src/deh_io.c @@ -181,7 +181,7 @@ int DEH_GetCharLump(deh_context_t *context) int DEH_GetChar(deh_context_t *context) { - int result; + int result = 0; // Read characters, but ignore carriage returns // Essentially this is a DOS->Unix conversion diff --git a/src/doom-screensaver.desktop.in b/src/doom-screensaver.desktop.in index cee79c2d..178575a2 100644 --- a/src/doom-screensaver.desktop.in +++ b/src/doom-screensaver.desktop.in @@ -1,10 +1,10 @@ [Desktop Entry] Encoding=UTF-8 -Name=Doom -Comment=DOOM by Id Software. -TryExec=@PACKAGE_TARNAME@ -Exec=@PACKAGE_TARNAME@ +Name=@PACKAGE_NAME@ +Comment=@PACKAGE_SHORTDESC@ +TryExec=@PROGRAM_PREFIX@doom +Exec=@PROGRAM_PREFIX@doom StartupNotify=false Terminal=false Type=Application diff --git a/src/doom.desktop.in b/src/doom.desktop.in new file mode 100644 index 00000000..44b76e62 --- /dev/null +++ b/src/doom.desktop.in @@ -0,0 +1,7 @@ +[Desktop Entry] +Name=@PACKAGE_NAME@ +Exec=@PROGRAM_PREFIX@doom +Icon=@PROGRAM_PREFIX@doom +Type=Application +Comment=@PACKAGE_SHORTDESC@ +Categories=Game;ActionGame; diff --git a/src/doom/d_main.c b/src/doom/d_main.c index 991907fa..f626d408 100644 --- a/src/doom/d_main.c +++ b/src/doom/d_main.c @@ -532,6 +532,9 @@ void D_DoAdvanceDemo (void) // include a DEMO4 lump, so the game bombs out with an error // when it reaches this point in the demo sequence. + // However! There is an alternate version of Final Doom that + // includes a fixed executable. + if (gameversion == exe_ultimate || gameversion == exe_final) demosequence = (demosequence+1)%7; else @@ -914,6 +917,7 @@ static struct {"Hacx", "hacx", exe_hacx}, {"Ultimate Doom", "ultimate", exe_ultimate}, {"Final Doom", "final", exe_final}, + {"Final Doom (alt)", "final2", exe_final2}, {"Chex Quest", "chex", exe_chex}, { NULL, NULL, 0}, }; @@ -930,7 +934,7 @@ static void InitGameVersion(void) // @category compat // // Emulate a specific version of Doom. Valid values are "1.9", - // "ultimate" and "final". + // "ultimate", "final", "final2", "hacx" and "chex". // p = M_CheckParmWithArgs("-gameversion", 1); @@ -994,8 +998,10 @@ static void InitGameVersion(void) else { // Final Doom: tnt or plutonia + // Default to the "alt" version of the executable that + // fixes the demo loop behavior. - gameversion = exe_final; + gameversion = exe_final2; } } } @@ -1034,11 +1040,37 @@ void PrintGameVersion(void) static void LoadChexDeh(void) { - char *chex_deh; + char *chex_deh = NULL; + char *sep; if (gameversion == exe_chex) { - chex_deh = D_FindWADByName("chex.deh"); + // Look for chex.deh in the same directory as the IWAD file. + + sep = strrchr(iwadfile, DIR_SEPARATOR); + + if (sep != NULL) + { + chex_deh = malloc(strlen(iwadfile) + 9); + strcpy(chex_deh, iwadfile); + chex_deh[sep - iwadfile + 1] = '\0'; + strcat(chex_deh, "chex.deh"); + } + else + { + chex_deh = strdup("chex.deh"); + } + + // If the dehacked patch isn't found, try searching the WAD + // search path instead. We might find it... + + if (!M_FileExists(chex_deh)) + { + free(chex_deh); + chex_deh = D_FindWADByName("chex.deh"); + } + + // Still not found? if (chex_deh == NULL) { diff --git a/src/doom/d_net.c b/src/doom/d_net.c index dd1ec563..f3155a9b 100644 --- a/src/doom/d_net.c +++ b/src/doom/d_net.c @@ -474,7 +474,8 @@ boolean D_InitNetGame(net_connect_data_t *connect_data, // Start a multiplayer server, listening for connections. // - if (M_CheckParm("-server") > 0) + if (M_CheckParm("-server") > 0 + || M_CheckParm("-privateserver") > 0) { NET_SV_Init(); NET_SV_AddModule(&net_loop_server_module); diff --git a/src/doom/doom.desktop.in b/src/doom/doom.desktop.in new file mode 100644 index 00000000..44b76e62 --- /dev/null +++ b/src/doom/doom.desktop.in @@ -0,0 +1,7 @@ +[Desktop Entry] +Name=@PACKAGE_NAME@ +Exec=@PROGRAM_PREFIX@doom +Icon=@PROGRAM_PREFIX@doom +Type=Application +Comment=@PACKAGE_SHORTDESC@ +Categories=Game;ActionGame; diff --git a/src/doom/doomstat.c b/src/doom/doomstat.c index b591358f..2bbb45e7 100644 --- a/src/doom/doomstat.c +++ b/src/doom/doomstat.c @@ -32,7 +32,7 @@ // Game Mode - identify IWAD as shareware, retail etc. GameMode_t gamemode = indetermined; GameMission_t gamemission = doom; -GameVersion_t gameversion = exe_final; +GameVersion_t gameversion = exe_final2; char *gamedescription; // Set if homebrew PWAD stuff has been added. diff --git a/src/doom/g_game.c b/src/doom/g_game.c index 5662d3f2..598f1c5e 100644 --- a/src/doom/g_game.c +++ b/src/doom/g_game.c @@ -361,6 +361,13 @@ int G_CmdChecksum (ticcmd_t* cmd) static boolean WeaponSelectable(weapontype_t weapon) { + // Can't select the super shotgun in Doom 1. + + if (weapon == wp_supershotgun && gamemission == doom) + { + return false; + } + // Can't select a weapon if we don't own it. if (!players[consoleplayer].weaponowned[weapon]) diff --git a/src/doom/m_menu.c b/src/doom/m_menu.c index 478e7f66..4a365cfb 100644 --- a/src/doom/m_menu.c +++ b/src/doom/m_menu.c @@ -798,6 +798,7 @@ void M_DrawReadThis1(void) break; case exe_final: + case exe_final2: // Final Doom always displays "HELP". diff --git a/src/doom/p_map.c b/src/doom/p_map.c index 78102bdf..7e92e23a 100644 --- a/src/doom/p_map.c +++ b/src/doom/p_map.c @@ -885,24 +885,16 @@ PTR_AimTraverse (intercept_t* in) dist = FixedMul (attackrange, in->frac); - // Return false if there is no back sector. This should never - // be the case if the line is two-sided; however, some WADs - // (eg. ottawau.wad) use this as an "impassible glass" trick - // and rely on Vanilla Doom's (unintentional) support for this. - - if (li->backsector == NULL) - { - return false; - } - - if (li->frontsector->floorheight != li->backsector->floorheight) + if (li->backsector == NULL + || li->frontsector->floorheight != li->backsector->floorheight) { slope = FixedDiv (openbottom - shootz , dist); if (slope > bottomslope) bottomslope = slope; } - if (li->frontsector->ceilingheight != li->backsector->ceilingheight) + if (li->backsector == NULL + || li->frontsector->ceilingheight != li->backsector->ceilingheight) { slope = FixedDiv (opentop - shootz , dist); if (slope < topslope) @@ -983,26 +975,35 @@ boolean PTR_ShootTraverse (intercept_t* in) dist = FixedMul (attackrange, in->frac); - // Check if backsector is NULL. See comment in PTR_AimTraverse. + // e6y: emulation of missed back side on two-sided lines. + // backsector can be NULL when emulating missing back side. - if (li->backsector == NULL) + if (li->backsector == NULL) { - goto hitline; - } + slope = FixedDiv (openbottom - shootz , dist); + if (slope > aimslope) + goto hitline; - if (li->frontsector->floorheight != li->backsector->floorheight) - { - slope = FixedDiv (openbottom - shootz , dist); - if (slope > aimslope) - goto hitline; - } - - if (li->frontsector->ceilingheight != li->backsector->ceilingheight) - { - slope = FixedDiv (opentop - shootz , dist); - if (slope < aimslope) - goto hitline; - } + slope = FixedDiv (opentop - shootz , dist); + if (slope < aimslope) + goto hitline; + } + else + { + if (li->frontsector->floorheight != li->backsector->floorheight) + { + slope = FixedDiv (openbottom - shootz , dist); + if (slope > aimslope) + goto hitline; + } + + if (li->frontsector->ceilingheight != li->backsector->ceilingheight) + { + slope = FixedDiv (opentop - shootz , dist); + if (slope < aimslope) + goto hitline; + } + } // shot continues return true; diff --git a/src/doom/p_setup.c b/src/doom/p_setup.c index 3fc95cab..58d5f462 100644 --- a/src/doom/p_setup.c +++ b/src/doom/p_setup.c @@ -155,7 +155,24 @@ void P_LoadVertexes (int lump) W_ReleaseLumpNum(lump); } +// +// GetSectorAtNullAddress +// +sector_t* GetSectorAtNullAddress(void) +{ + static boolean null_sector_is_initialized = false; + static sector_t null_sector; + + if (!null_sector_is_initialized) + { + memset(&null_sector, 0, sizeof(null_sector)); + I_GetMemoryValue(0, &null_sector.floorheight, 4); + I_GetMemoryValue(4, &null_sector.ceilingheight, 4); + null_sector_is_initialized = true; + } + return &null_sector; +} // // P_LoadSegs @@ -204,10 +221,12 @@ void P_LoadSegs (int lump) if (sidenum < 0 || sidenum >= numsides) { - sidenum = 0; + li->backsector = GetSectorAtNullAddress(); + } + else + { + li->backsector = sides[sidenum].sector; } - - li->backsector = sides[sidenum].sector; } else { @@ -681,7 +700,7 @@ static void PadRejectArray(byte *array, unsigned int len) if (len > sizeof(rejectpad)) { fprintf(stderr, "PadRejectArray: REJECT lump too short to pad! (%i > %i)\n", - len, sizeof(rejectpad)); + len, (int) sizeof(rejectpad)); // Pad remaining space with 0 (or 0xff, if specified on command line). diff --git a/src/doom/st_stuff.c b/src/doom/st_stuff.c index 7e5e225c..8595ff50 100644 --- a/src/doom/st_stuff.c +++ b/src/doom/st_stuff.c @@ -525,8 +525,13 @@ ST_Responder (event_t* ev) plyr->message = DEH_String(STSTR_MUS); cht_GetParam(&cheat_mus, buf); - - if (gamemode == commercial) + + // Note: The original v1.9 had a bug that tried to play back + // the Doom II music regardless of gamemode. This was fixed + // in the Ultimate Doom executable so that it would work for + // the Doom 1 music as well. + + if (gamemode == commercial || gameversion < exe_ultimate) { musnum = mus_runnin + (buf[0]-'0')*10 + buf[1]-'0' - 1; diff --git a/src/i_endoom.c b/src/i_endoom.c index 021a3604..09c2d2d2 100644 --- a/src/i_endoom.c +++ b/src/i_endoom.c @@ -67,7 +67,7 @@ void I_Endoom(byte *endoom_data) { TXT_UpdateScreen(); - if (TXT_GetChar() >= 0) + if (TXT_GetChar() > 0) { break; } diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c index e7a42e83..dd35ce5e 100644 --- a/src/i_oplmusic.c +++ b/src/i_oplmusic.c @@ -1079,7 +1079,7 @@ static void ScheduleTrack(opl_track_data_t *track); // Restart a song from the beginning. -static void RestartSong(void) +static void RestartSong(void *unused) { unsigned int i; @@ -1117,10 +1117,15 @@ static void TrackTimerCallback(void *arg) --running_tracks; // When all tracks have finished, restart the song. + // Don't restart the song immediately, but wait for 5ms + // before triggering a restart. Otherwise it is possible + // to construct an empty MIDI file that causes the game + // to lock up in an infinite loop. (5ms should be short + // enough not to be noticeable by the listener). if (running_tracks <= 0 && song_looping) { - RestartSong(); + OPL_SetCallback(5, RestartSong, NULL); } return; diff --git a/src/i_scale.c b/src/i_scale.c index 2c0b718c..6d03d708 100644 --- a/src/i_scale.c +++ b/src/i_scale.c @@ -33,6 +33,7 @@ #include "doomtype.h" #include "i_video.h" +#include "m_argv.h" #include "z_zone.h" #if defined(_MSC_VER) && !defined(__cplusplus) @@ -967,6 +968,21 @@ static boolean I_Stretch5x(int x1, int y1, int x2, int y2) screenp += dest_pitch; bufp += SCREENWIDTH; } + // test hack for Porsche Monty... scan line simulation: + // See here: http://www.doomworld.com/vb/post/962612 + + if (M_CheckParm("-scanline") > 0) + { + screenp = (byte *) dest_buffer + 2 * dest_pitch; + + for (y=0; y<1198; y += 3) + { + memset(screenp, 0, 1600); + + screenp += dest_pitch * 3; + } + } + return true; } diff --git a/src/i_system.c b/src/i_system.c index 0a856ca9..1d961956 100644 --- a/src/i_system.c +++ b/src/i_system.c @@ -55,6 +55,10 @@ #include "w_wad.h" #include "z_zone.h" +#ifdef __MACOSX__ +#include <CoreFoundation/CFUserNotification.h> +#endif + #define DEFAULT_RAM 16 /* MiB */ #define MIN_RAM 4 /* MiB */ @@ -282,7 +286,6 @@ void I_BindVariables(void) } */ - // // I_Quit // @@ -366,8 +369,151 @@ void I_Error (char *error, ...) } #endif +#ifdef __MACOSX__ + { + CFStringRef message; + char msgbuf[512]; + int i; + + va_start(argptr, error); + memset(msgbuf, 0, sizeof(msgbuf)); + vsnprintf(msgbuf, sizeof(msgbuf) - 1, error, argptr); + va_end(argptr); + + // The CoreFoundation message box wraps text lines, so replace + // newline characters with spaces so that multiline messages + // are continuous. + + for (i = 0; msgbuf[i] != '\0'; ++i) + { + if (msgbuf[i] == '\n') + { + msgbuf[i] = ' '; + } + } + + message = CFStringCreateWithCString(NULL, msgbuf, + kCFStringEncodingUTF8); + + CFUserNotificationDisplayNotice(0, + kCFUserNotificationCautionAlertLevel, + NULL, + NULL, + NULL, + CFSTR(PACKAGE_STRING), + message, + NULL); + } +#endif + // abort(); exit(-1); } +// +// Read Access Violation emulation. +// +// From PrBoom+, by entryway. +// + +// C:\>debug +// -d 0:0 +// +// DOS 6.22: +// 0000:0000 (57 92 19 00) F4 06 70 00-(16 00) +// DOS 7.1: +// 0000:0000 (9E 0F C9 00) 65 04 70 00-(16 00) +// Win98: +// 0000:0000 (9E 0F C9 00) 65 04 70 00-(16 00) +// DOSBox under XP: +// 0000:0000 (00 00 00 F1) ?? ?? ?? 00-(07 00) + +#define DOS_MEM_DUMP_SIZE 10 + +static const unsigned char mem_dump_dos622[DOS_MEM_DUMP_SIZE] = { + 0x57, 0x92, 0x19, 0x00, 0xF4, 0x06, 0x70, 0x00, 0x16, 0x00}; +static const unsigned char mem_dump_win98[DOS_MEM_DUMP_SIZE] = { + 0x9E, 0x0F, 0xC9, 0x00, 0x65, 0x04, 0x70, 0x00, 0x16, 0x00}; +static const unsigned char mem_dump_dosbox[DOS_MEM_DUMP_SIZE] = { + 0x00, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00}; +static unsigned char mem_dump_custom[DOS_MEM_DUMP_SIZE]; + +static const unsigned char *dos_mem_dump = mem_dump_dos622; + +boolean I_GetMemoryValue(unsigned int offset, void *value, int size) +{ + static boolean firsttime = true; + + if (firsttime) + { + int p, i, val; + + firsttime = false; + i = 0; + + //! + // @category compat + // @arg <version> + // + // Specify DOS version to emulate for NULL pointer dereference + // emulation. Supported versions are: dos622, dos71, dosbox. + // The default is to emulate DOS 7.1 (Windows 98). + // + + p = M_CheckParmWithArgs("-setmem", 1); + + if (p > 0) + { + if (!strcasecmp(myargv[p + 1], "dos622")) + { + dos_mem_dump = mem_dump_dos622; + } + if (!strcasecmp(myargv[p + 1], "dos71")) + { + dos_mem_dump = mem_dump_win98; + } + else if (!strcasecmp(myargv[p + 1], "dosbox")) + { + dos_mem_dump = mem_dump_dosbox; + } + else + { + for (i = 0; i < DOS_MEM_DUMP_SIZE; ++i) + { + ++p; + + if (p >= myargc || myargv[p][0] == '-') + { + break; + } + + M_StrToInt(myargv[p], &val); + mem_dump_custom[i++] = (unsigned char) val; + } + + dos_mem_dump = mem_dump_custom; + } + } + } + + switch (size) + { + case 1: + *((unsigned char *) value) = dos_mem_dump[offset]; + return true; + case 2: + *((unsigned short *) value) = dos_mem_dump[offset] + | (dos_mem_dump[offset + 1] << 8); + return true; + case 4: + *((unsigned int *) value) = dos_mem_dump[offset] + | (dos_mem_dump[offset + 1] << 8) + | (dos_mem_dump[offset + 2] << 16) + | (dos_mem_dump[offset + 3] << 24); + return true; + } + + return false; +} + diff --git a/src/i_system.h b/src/i_system.h index 0697f7db..5a99b213 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -71,6 +71,8 @@ void I_Tactile (int on, int off, int total); void I_Error (char *error, ...); +boolean I_GetMemoryValue(unsigned int offset, void *value, int size); + // Schedule a function to be called when the program exits. // If run_if_error is true, the function is called if the exit // is due to an error (I_Error) diff --git a/src/i_video.c b/src/i_video.c index 9d70e88e..6a3175bb 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -656,7 +656,7 @@ static int GetTypedChar(SDL_Event *event) { // Unicode value, from key layout. - return event->key.keysym.unicode; + return tolower(event->key.keysym.unicode); } } diff --git a/src/m_misc.c b/src/m_misc.c index ed41b5f1..e14436a3 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -209,8 +209,9 @@ boolean M_StrToInt(const char *str, int *result) void M_ExtractFileBase(char *path, char *dest) { - char* src; - int length; + char *src; + char *filename; + int length; src = path + strlen(path) - 1; @@ -220,20 +221,26 @@ void M_ExtractFileBase(char *path, char *dest) src--; } - // copy up to eight characters - memset(dest, 0, 8); + filename = src; + + // Copy up to eight characters + // Note: Vanilla Doom exits with an error if a filename is specified + // with a base of more than eight characters. To remove the 8.3 + // filename limit, instead we simply truncate the name. + length = 0; + memset(dest, 0, 8); while (*src != '\0' && *src != '.') { - ++length; - - if (length > 8) + if (length >= 8) { - I_Error ("Filename base of %s >8 chars", path); + printf("Warning: Truncated '%s' lump name to '%.8s'.\n", + filename, dest); + break; } - *dest++ = toupper((int)*src++); + dest[length++] = toupper((int)*src++); } } diff --git a/src/net_server.c b/src/net_server.c index ae46be4a..157f5069 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -1563,6 +1563,7 @@ void NET_SV_RegisterWithMaster(void) { //! // When running a server, don't register with the global master server. + // Implies -server. // // @category net // diff --git a/src/setup/Makefile.am b/src/setup/Makefile.am index 25ab38e3..7fe051ee 100644 --- a/src/setup/Makefile.am +++ b/src/setup/Makefile.am @@ -27,6 +27,12 @@ libsetup_a_SOURCES = $(SOURCE_FILES) EXTRA_DIST= \ setup_icon.c +appdir = $(prefix)/share/applications +app_DATA = @PROGRAM_PREFIX@setup.desktop + +@PROGRAM_PREFIX@setup.desktop : setup.desktop + cp $^ $@ + if HAVE_PYTHON setup_icon.c : $(top_builddir)/data/setup8.ico diff --git a/src/setup/display.c b/src/setup/display.c index 9ed0ae5f..72f3c057 100644 --- a/src/setup/display.c +++ b/src/setup/display.c @@ -527,25 +527,34 @@ static void UpdateBPP(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(modes_table)) GenerateModesTable(NULL, modes_table); } -#if defined(_WIN32) && !defined(_WIN32_WCE) +static void UpdateModeSeparator(TXT_UNCAST_ARG(widget), + TXT_UNCAST_ARG(separator)) +{ + TXT_CAST_ARG(txt_separator_t, separator); + + if (fullscreen) + { + TXT_SetSeparatorLabel(separator, "Screen mode"); + } + else + { + TXT_SetSeparatorLabel(separator, "Window size"); + } +} -static int win32_video_driver = 0; +#if defined(_WIN32) && !defined(_WIN32_WCE) -static char *win32_video_drivers[] = -{ - "DirectX", - "Windows GDI", -}; +static int use_directx = 1; static void SetWin32VideoDriver(void) { if (!strcmp(video_driver, "windib")) { - win32_video_driver = 1; + use_directx = 0; } else { - win32_video_driver = 0; + use_directx = 1; } } @@ -553,13 +562,15 @@ static void UpdateVideoDriver(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(modes_table)) { TXT_CAST_ARG(txt_table_t, modes_table); - char *drivers[] = - { - "", - "windib", - }; - video_driver = drivers[win32_video_driver != 0]; + if (use_directx) + { + video_driver = ""; + } + else + { + video_driver = "windib"; + } // When the video driver is changed, we need to restart the textscreen // library. @@ -579,16 +590,72 @@ static void UpdateVideoDriver(TXT_UNCAST_ARG(widget), #endif +static void AdvancedDisplayConfig(TXT_UNCAST_ARG(widget), + TXT_UNCAST_ARG(modes_table)) +{ + TXT_CAST_ARG(txt_table_t, modes_table); + txt_window_t *window; + txt_checkbox_t *ar_checkbox; + + window = TXT_NewWindow("Advanced display options"); + + TXT_SetColumnWidths(window, 35); + + TXT_AddWidgets(window, + ar_checkbox = TXT_NewCheckBox("Fix aspect ratio", + &aspect_ratio_correct), + NULL); + + if (gamemission == heretic || gamemission == hexen) + { + TXT_AddWidget(window, + TXT_NewCheckBox("Graphical startup", &graphical_startup)); + } + + if (gamemission == doom || gamemission == heretic) + { + TXT_AddWidget(window, + TXT_NewCheckBox("Show ENDOOM screen on exit", + &show_endoom)); + } + + TXT_SignalConnect(ar_checkbox, "changed", GenerateModesTable, modes_table); + + // On Windows, there is an extra control to change between + // the Windows GDI and DirectX video drivers. + +#if defined(_WIN32) && !defined(_WIN32_WCE) + { + txt_radiobutton_t *dx_button, *gdi_button; + + TXT_AddWidgets(window, + TXT_NewSeparator("Windows video driver"), + dx_button = TXT_NewRadioButton("DirectX", + &use_directx, 1), + gdi_button = TXT_NewRadioButton("Windows GDI", + &use_directx, 0), + NULL); + + TXT_SignalConnect(dx_button, "selected", + UpdateVideoDriver, modes_table); + TXT_SignalConnect(gdi_button, "selected", + UpdateVideoDriver, modes_table); + SetWin32VideoDriver(); + } +#endif +} void ConfigDisplay(void) { txt_window_t *window; txt_table_t *modes_table; + txt_separator_t *modes_separator; txt_table_t *bpp_table; + txt_window_action_t *advanced_button; txt_checkbox_t *fs_checkbox; - txt_checkbox_t *ar_checkbox; - txt_dropdown_list_t *bpp_selector; + int i; int num_columns; + int num_rows; int window_y; // What color depths are supported? Generate supported_bpps array @@ -606,14 +673,8 @@ void ConfigDisplay(void) } // Open the window - - window = TXT_NewWindow("Display Configuration"); - TXT_AddWidgets(window, - fs_checkbox = TXT_NewCheckBox("Fullscreen", &fullscreen), - ar_checkbox = TXT_NewCheckBox("Correct aspect ratio", - &aspect_ratio_correct), - NULL); + window = TXT_NewWindow("Display Configuration"); // Some machines can have lots of video modes. This tries to // keep a limit of six lines by increasing the number of @@ -621,93 +682,101 @@ void ConfigDisplay(void) BuildFullscreenModesList(); - window_y = 5; - - if (num_screen_modes_fullscreen <= 18) + if (num_screen_modes_fullscreen <= 24) { num_columns = 3; } - else if (num_screen_modes_fullscreen <= 24) + else if (num_screen_modes_fullscreen <= 40) { num_columns = 4; } else { num_columns = 5; - window_y -= 3; } modes_table = TXT_NewTable(num_columns); - // The window is set at a fixed vertical position. This keeps - // the top of the window stationary when switching between - // fullscreen and windowed mode (which causes the window's - // height to change). + // Build window: - TXT_SetWindowPosition(window, TXT_HORIZ_CENTER, TXT_VERT_TOP, - TXT_SCREEN_W / 2, window_y); + TXT_AddWidget(window, + fs_checkbox = TXT_NewCheckBox("Full screen", &fullscreen)); - // On Windows, there is an extra control to change between - // the Windows GDI and DirectX video drivers. - -#if defined(_WIN32) && !defined(_WIN32_WCE) + if (num_supported_bpps > 1) { - txt_table_t *driver_table; - txt_dropdown_list_t *driver_list; - - driver_table = TXT_NewTable(2); - - TXT_SetColumnWidths(driver_table, 20, 0); - - TXT_AddWidgets(driver_table, - TXT_NewLabel("Video driver"), - driver_list = TXT_NewDropdownList(&win32_video_driver, - win32_video_drivers, - 2), + TXT_AddWidgets(window, + TXT_NewSeparator("Color depth"), + bpp_table = TXT_NewTable(4), NULL); - TXT_SignalConnect(driver_list, "changed", - UpdateVideoDriver, modes_table); - SetWin32VideoDriver(); + for (i = 0; i < num_supported_bpps; ++i) + { + txt_radiobutton_t *button; - TXT_AddWidget(window, driver_table); - } -#endif + button = TXT_NewRadioButton(supported_bpps[i], + &selected_bpp, i); - // Screen modes list + TXT_AddWidget(bpp_table, button); + TXT_SignalConnect(button, "selected", UpdateBPP, modes_table); + } + } TXT_AddWidgets(window, - TXT_NewSeparator("Screen mode"), - bpp_table = TXT_NewTable(2), + modes_separator = TXT_NewSeparator(""), modes_table, - TXT_NewSeparator("Misc."), NULL); - if (gamemission == heretic || gamemission == hexen) + TXT_SignalConnect(fs_checkbox, "changed", + GenerateModesTable, modes_table); + TXT_SignalConnect(fs_checkbox, "changed", + UpdateModeSeparator, modes_separator); + + // How many rows high will the configuration window be? + // Need to take into account number of fullscreen modes, and also + // number of supported pixel depths. + // The windowed modes list is four rows, so take the maximum of + // windowed and fullscreen. + + num_rows = (num_screen_modes_fullscreen + num_columns - 1) / num_columns; + + if (num_rows < 4) { - TXT_AddWidget(window, - TXT_NewCheckBox("Graphical startup", &graphical_startup)); + num_rows = 4; } - if (gamemission == doom || gamemission == heretic) + if (num_supported_bpps > 1) { - TXT_AddWidget(window, - TXT_NewCheckBox("Show ENDOOM screen", &show_endoom)); + num_rows += 2; } - TXT_AddWidgets(bpp_table, - TXT_NewLabel("Color depth: "), - bpp_selector = TXT_NewDropdownList(&selected_bpp, - supported_bpps, - num_supported_bpps), - NULL); + if (num_rows < 14) + { + window_y = 8 - ((num_rows + 1) / 2); + } + else + { + window_y = 1; + } + // The window is set at a fixed vertical position. This keeps + // the top of the window stationary when switching between + // fullscreen and windowed mode (which causes the window's + // height to change). - TXT_SignalConnect(bpp_selector, "changed", UpdateBPP, modes_table); - TXT_SignalConnect(fs_checkbox, "changed", GenerateModesTable, modes_table); - TXT_SignalConnect(ar_checkbox, "changed", GenerateModesTable, modes_table); + TXT_SetWindowPosition(window, TXT_HORIZ_CENTER, TXT_VERT_TOP, + TXT_SCREEN_W / 2, window_y); GenerateModesTable(NULL, modes_table); + UpdateModeSeparator(NULL, modes_separator); + + // Button to open "advanced" window. + // Need to pass a pointer to the modes table, as some of the options + // in there trigger a rebuild of it. + + advanced_button = TXT_NewWindowAction('a', "Advanced"); + TXT_SetWindowAction(window, TXT_HORIZ_CENTER, advanced_button); + TXT_SignalConnect(advanced_button, "pressed", + AdvancedDisplayConfig, modes_table); } void BindDisplayVariables(void) diff --git a/src/setup/joystick.c b/src/setup/joystick.c index 0fc00ea1..2a7b1f79 100644 --- a/src/setup/joystick.c +++ b/src/setup/joystick.c @@ -27,6 +27,7 @@ #include "m_controls.h" #include "textscreen.h" +#include "execute.h" #include "joystick.h" #include "mode.h" #include "txt_joybinput.h" @@ -436,6 +437,8 @@ void ConfigJoystick(void) TXT_SignalConnect(joystick_button, "pressed", CalibrateJoystick, NULL); TXT_SignalConnect(window, "closed", JoystickWindowClosed, NULL); + TXT_SetWindowAction(window, TXT_HORIZ_CENTER, TestConfigAction()); + SetJoystickButtonLabel(); } diff --git a/src/setup/setup-manifest.xml.in b/src/setup/setup-manifest.xml.in index bac9a05e..ff879263 100644 --- a/src/setup/setup-manifest.xml.in +++ b/src/setup/setup-manifest.xml.in @@ -1,16 +1,33 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> + +<!-- Magic manifest file that should make Windows Vista/7 not + attempt to gain elevated privileges for chocolate-setup. + + Based on: + + http://www.cygwin.com/ml/cygwin/2006-12/msg00580.html + --> + <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <!-- The "name" field in this tag should be the same as the executable's name --> - <assemblyIdentity version="@PACKAGE_VERSION@.0" processorArchitecture="*" - name="@PROGRAM_PREFIX@setup" type="win32"/> + <assemblyIdentity version="0.0.0.0" processorArchitecture="X86" + name="@PROGRAM_PREFIX@setup.exe" type="win32"/> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> - <!-- Hi Vista! We don't require elevated privileges. Thanks! --> - <requestedExecutionLevel level="asInvoker"/> + <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> + + <!-- Stop the Program Compatibility Assistant appearing: --> + + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!-- 7 --> + <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> <!-- Vista --> + </application> + </compatibility> </assembly> diff --git a/src/setup/setup.desktop.in b/src/setup/setup.desktop.in new file mode 100644 index 00000000..79fb38be --- /dev/null +++ b/src/setup/setup.desktop.in @@ -0,0 +1,7 @@ +[Desktop Entry] +Name=@PACKAGE_NAME@ Setup +Exec=@PROGRAM_PREFIX@setup +Icon=@PROGRAM_PREFIX@setup +Type=Application +Comment=Setup tool for @PACKAGE_NAME@ +Categories=Settings;ConsoleOnly; diff --git a/src/setup/sound.c b/src/setup/sound.c index 627549b5..9e13edd9 100644 --- a/src/setup/sound.c +++ b/src/setup/sound.c @@ -68,7 +68,7 @@ static char *musicmode_strings[] = int snd_sfxdevice = SNDDEVICE_SB; int snd_musicdevice = SNDDEVICE_GENMIDI; -int snd_samplerate = 22050; +int snd_samplerate = 44100; int opl_io_port = 0x388; static int numChannels = 8; diff --git a/src/setup/txt_joybinput.c b/src/setup/txt_joybinput.c index cde3d2c2..9ad26a45 100644 --- a/src/setup/txt_joybinput.c +++ b/src/setup/txt_joybinput.c @@ -48,7 +48,12 @@ static int EventCallback(SDL_Event *event, TXT_UNCAST_ARG(joystick_input)) if (event->type == SDL_JOYBUTTONDOWN) { *joystick_input->variable = event->jbutton.button; - TXT_EmitSignal(joystick_input, "set"); + + if (joystick_input->check_conflicts) + { + TXT_EmitSignal(joystick_input, "set"); + } + TXT_CloseWindow(joystick_input->prompt_window); return 1; } @@ -89,6 +94,10 @@ static void OpenPromptWindow(txt_joystick_input_t *joystick_input) txt_label_t *label; SDL_Joystick *joystick; + // Silently update when the shift button is held down. + + joystick_input->check_conflicts = !TXT_GetModifierState(TXT_MOD_SHIFT); + if (SDL_Init(SDL_INIT_JOYSTICK) < 0) { return; @@ -153,15 +162,7 @@ static void TXT_JoystickInputDrawer(TXT_UNCAST_ARG(joystick_input), int selected GetJoystickButtonDescription(*joystick_input->variable, buf); } - if (selected) - { - TXT_BGColor(TXT_COLOR_GREY, 0); - } - else - { - TXT_BGColor(TXT_COLOR_BLUE, 0); - } - + TXT_SetWidgetBG(joystick_input, selected); TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); TXT_DrawString(buf); diff --git a/src/setup/txt_joybinput.h b/src/setup/txt_joybinput.h index b2920b88..69ec4a1f 100644 --- a/src/setup/txt_joybinput.h +++ b/src/setup/txt_joybinput.h @@ -37,6 +37,7 @@ struct txt_joystick_input_s txt_widget_t widget; int *variable; txt_window_t *prompt_window; + int check_conflicts; }; txt_joystick_input_t *TXT_NewJoystickInput(int *variable); diff --git a/src/setup/txt_keyinput.c b/src/setup/txt_keyinput.c index 08eb9d8c..6f1ee4dd 100644 --- a/src/setup/txt_keyinput.c +++ b/src/setup/txt_keyinput.c @@ -42,7 +42,12 @@ static int KeyPressCallback(txt_window_t *window, int key, // Got the key press. Save to the variable and close the window. *key_input->variable = key; - TXT_EmitSignal(key_input, "set"); + + if (key_input->check_conflicts) + { + TXT_EmitSignal(key_input, "set"); + } + TXT_CloseWindow(window); // Re-enable key mappings now that we have the key @@ -67,6 +72,10 @@ static void OpenPromptWindow(txt_key_input_t *key_input) txt_window_t *window; txt_label_t *label; + // Silently update when the shift button is held down. + + key_input->check_conflicts = !TXT_GetModifierState(TXT_MOD_SHIFT); + window = TXT_NewWindow(NULL); TXT_SetWindowAction(window, TXT_HORIZ_LEFT, NULL); TXT_SetWindowAction(window, TXT_HORIZ_CENTER, @@ -118,15 +127,7 @@ static void TXT_KeyInputDrawer(TXT_UNCAST_ARG(key_input), int selected) TXT_GetKeyDescription(*key_input->variable, buf); } - if (selected) - { - TXT_BGColor(TXT_COLOR_GREY, 0); - } - else - { - TXT_BGColor(TXT_COLOR_BLUE, 0); - } - + TXT_SetWidgetBG(key_input, selected); TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); TXT_DrawString(buf); diff --git a/src/setup/txt_keyinput.h b/src/setup/txt_keyinput.h index 4952a970..5df0b2e3 100644 --- a/src/setup/txt_keyinput.h +++ b/src/setup/txt_keyinput.h @@ -35,6 +35,7 @@ struct txt_key_input_s { txt_widget_t widget; int *variable; + int check_conflicts; }; txt_key_input_t *TXT_NewKeyInput(int *variable); diff --git a/src/setup/txt_mouseinput.c b/src/setup/txt_mouseinput.c index 4f454c8c..c3e17299 100644 --- a/src/setup/txt_mouseinput.c +++ b/src/setup/txt_mouseinput.c @@ -42,7 +42,12 @@ static int MousePressCallback(txt_window_t *window, // Got the mouse press. Save to the variable and close the window. *mouse_input->variable = b - TXT_MOUSE_BASE; - TXT_EmitSignal(mouse_input, "set"); + + if (mouse_input->check_conflicts) + { + TXT_EmitSignal(mouse_input, "set"); + } + TXT_CloseWindow(window); return 1; @@ -53,6 +58,9 @@ static void OpenPromptWindow(txt_mouse_input_t *mouse_input) txt_window_t *window; txt_label_t *label; + // Silently update when the shift key is held down. + mouse_input->check_conflicts = !TXT_GetModifierState(TXT_MOD_SHIFT); + window = TXT_NewWindow(NULL); TXT_SetWindowAction(window, TXT_HORIZ_LEFT, NULL); TXT_SetWindowAction(window, TXT_HORIZ_CENTER, @@ -111,15 +119,7 @@ static void TXT_MouseInputDrawer(TXT_UNCAST_ARG(mouse_input), int selected) GetMouseButtonDescription(*mouse_input->variable, buf); } - if (selected) - { - TXT_BGColor(TXT_COLOR_GREY, 0); - } - else - { - TXT_BGColor(TXT_COLOR_BLUE, 0); - } - + TXT_SetWidgetBG(mouse_input, selected); TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); TXT_DrawString(buf); diff --git a/src/setup/txt_mouseinput.h b/src/setup/txt_mouseinput.h index 57c258eb..ef3ec2aa 100644 --- a/src/setup/txt_mouseinput.h +++ b/src/setup/txt_mouseinput.h @@ -35,6 +35,7 @@ struct txt_mouse_input_s { txt_widget_t widget; int *variable; + int check_conflicts; }; txt_mouse_input_t *TXT_NewMouseInput(int *variable); |