shithub: choc

Download patch

ref: 3cf74a97261b1a0aceb591b495b0857781918edd
parent: 299e1c5abf804e2e249c4f77b82fb7949a3f9d7b
parent: 892ad7c072a6717e8935053d7837a33974d0d824
author: Simon Howard <fraggle@gmail.com>
date: Fri Nov 20 20:16:14 EST 2009

Merge from trunk.

Subversion-branch: /branches/opl-branch
Subversion-revision: 1734

--- a/Makefile.am
+++ b/Makefile.am
@@ -46,6 +46,7 @@
 
 docdir=$(prefix)/share/doc/@PACKAGE@
 SUBDIRS=wince textscreen opl pcsound src man setup
+DIST_SUBDIRS=pkg $(SUBDIRS)
 
 if HAVE_PYTHON
 
--- a/configure.in
+++ b/configure.in
@@ -129,7 +129,8 @@
 opl/examples/Makefile
 src/Makefile
 pcsound/Makefile
-pkg/wince/Makefile
+pkg/Makefile
+pkg/wince/GNUmakefile
 src/resource.rc
 src/doom-screensaver.desktop
 setup/setup-res.rc
--- a/msvc/ChocolateDoom.vcproj
+++ b/msvc/ChocolateDoom.vcproj
@@ -9631,6 +9631,46 @@
 					/>
 				</FileConfiguration>
 			</File>
+			<File
+				RelativePath="..\textscreen\txt_scrollpane.c"
+				>
+				<FileConfiguration
+					Name="Debug Server|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release Server|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\textscreen\txt_scrollpane.h"
+				>
+				<FileConfiguration
+					Name="Debug Server|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release Server|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+			</File>
 		</Filter>
 	</Files>
 	<Globals>
--- /dev/null
+++ b/pkg/Makefile.am
@@ -1,0 +1,3 @@
+
+DIST_SUBDIRS=wince
+
--- /dev/null
+++ b/pkg/wince/GNUmakefile.am
@@ -1,0 +1,12 @@
+
+DEPS=$(shell ./wince-cabgen -d $(CONFIG_FILE))
+CONFIG_FILE=wince-cab.cfg
+OUTPUT_FILE=@PACKAGE_TARNAME@-@PACKAGE_VERSION@.cab
+
+EXTRA_DIST=wince-cabgen $(CONFIG_FILE)
+
+noinst_DATA = $(OUTPUT_FILE)
+
+$(OUTPUT_FILE) : $(CONFIG_FILE) $(DEPS)
+	./wince-cabgen $< $@
+
--- a/pkg/wince/Makefile.am
+++ /dev/null
@@ -1,10 +1,0 @@
-
-DEPS=$(shell ./wince-cabgen -d $(CONFIG_FILE))
-CONFIG_FILE=wince-cab.cfg
-OUTPUT_FILE=@PACKAGE_TARNAME@-@PACKAGE_VERSION@.cab
-
-noinst_DATA = $(OUTPUT_FILE)
-
-$(OUTPUT_FILE) : $(CONFIG_FILE) $(DEPS)
-	./wince-cabgen $< $@
-
--- a/setup/Makefile.am
+++ b/setup/Makefile.am
@@ -1,7 +1,7 @@
 
 gamesdir = $(prefix)/games
 
-AM_CFLAGS = -I../textscreen -I../src -DINSTALL_DIR="\"$(gamesdir)\""
+AM_CFLAGS = -I../textscreen -I../src @SDLMIXER_CFLAGS@
 
 games_PROGRAMS = chocolate-setup
 
@@ -34,6 +34,7 @@
 chocolate_setup_LDADD =                              \
                        ../wince/libc_wince.a         \
                        ../textscreen/libtextscreen.a \
+                       @SDLMIXER_LIBS@               \
                        @LDFLAGS@
 
 .rc.o:
--- a/setup/configfile.c
+++ b/setup/configfile.c
@@ -42,6 +42,8 @@
 #include <sys/types.h>
 #endif
 
+#include "SDL_mixer.h"
+
 #include "config.h"
 
 #include "doomfeatures.h"
@@ -530,8 +532,16 @@
 
                     intparm = ParseIntParameter(strparm);
                     defaults[i].untranslated = intparm;
-                    intparm = scantokey[intparm];
 
+                    if (intparm >= 0 && intparm < 128)
+                    {
+                        intparm = scantokey[intparm];
+                    }
+                    else
+                    {
+                        intparm = 0;
+                    }
+
                     defaults[i].original_translated = intparm;
                     * (int *) def->location = intparm;
                     break;
@@ -720,6 +730,22 @@
 {
 #ifdef _WIN32_WCE
     M_ApplyWindowsCEDefaults();
+#endif
+
+    // Before SDL_mixer version 1.2.11, MIDI music caused the game
+    // to crash when it looped.  If this is an old SDL_mixer version,
+    // disable MIDI.
+
+#ifdef __MACOSX__
+    {
+        const SDL_version *v = Mix_Linked_Version();
+
+        if (SDL_VERSIONNUM(v->major, v->minor, v->patch)
+          < SDL_VERSIONNUM(1, 2, 11))
+        {
+            snd_musicdevice = SNDDEVICE_NONE;
+        }
+    }
 #endif
 }
 
--- a/setup/execute.c
+++ b/setup/execute.c
@@ -55,7 +55,7 @@
 #ifdef _WIN32
 #define DOOM_BINARY PACKAGE_TARNAME ".exe"
 #else
-#define DOOM_BINARY INSTALL_DIR "/" PACKAGE_TARNAME
+#define DOOM_BINARY PACKAGE_TARNAME
 #endif
 
 #ifdef _WIN32
@@ -172,81 +172,69 @@
     }
 }
 
-static wchar_t *GetFullExePath(const char *program)
+static void ConcatWCString(wchar_t *buf, const char *value)
 {
+    MultiByteToWideChar(CP_OEMCP, 0,
+                        value, strlen(value) + 1,
+                        buf + wcslen(buf), strlen(value) + 1);
+}
+
+// Build the command line string, a wide character string of the form:
+//
+// "program" "arg"
+
+static wchar_t *BuildCommandLine(const char *program, const char *arg)
+{
     wchar_t *result;
-    unsigned int path_len;
     char *sep;
 
-    // Find the full path to the EXE to execute, by taking the path
-    // to this program and concatenating the EXE name:
+    result = calloc(strlen(myargv[0]) + strlen(program) + strlen(arg) + 6,
+                    sizeof(wchar_t));
 
+    wcscpy(result, L"\"");
+
     sep = strrchr(myargv[0], DIR_SEPARATOR);
 
-    if (sep == NULL)
+    if (sep != NULL)
     {
-        path_len = 0;
-        result = calloc(strlen(program) + 1, sizeof(wchar_t));
-    }
-    else
-    {
-        path_len = sep - myargv[0] + 1;
+        ConcatWCString(result, myargv[0]);
 
-        result = calloc(path_len + strlen(program) + 1,
-                        sizeof(wchar_t));
-        MultiByteToWideChar(CP_OEMCP, 0,
-                            myargv[0], path_len,
-                            result, path_len);
+        // Cut off the string after the last directory separator,
+        // before appending the actual program.
+
+        result[sep - myargv[0] + 2] = '\0';
+        
     }
 
-    MultiByteToWideChar(CP_OEMCP, 0,
-                        program, strlen(program) + 1,
-                        result + path_len, strlen(program) + 1);
+    ConcatWCString(result, program);
 
-    return result;
-}
+    wcscat(result, L"\" \"");
 
-// Convert command line argument to wchar_t string and add surrounding
-// "" quotes:
+    ConcatWCString(result, arg);
 
-static wchar_t *GetPaddedWideArg(const char *arg)
-{
-    wchar_t *result;
-    unsigned int len = strlen(arg);
+    wcscat(result, L"\"");
 
-    // Convert the command line arg to a wide char string:
-
-    result = calloc(len + 3, sizeof(wchar_t));
-    MultiByteToWideChar(CP_OEMCP, 0,
-                        arg, len + 1,
-                        result + 1, len + 1);
-
-    // Surrounding quotes:
-
-    result[0] = '"';
-    result[len + 1] = '"';
-    result[len + 2] = 0;
-
     return result;
 }
 
 static int ExecuteCommand(const char *program, const char *arg)
 {
+    STARTUPINFOW startup_info;
     PROCESS_INFORMATION proc_info;
-    wchar_t *exe_path;
-    wchar_t *warg;
+    wchar_t *command;
     int result = 0;
 
-    exe_path = GetFullExePath(program);
-    warg = GetPaddedWideArg(arg);
+    command = BuildCommandLine(program, arg);
 
     // Invoke the program:
 
     memset(&proc_info, 0, sizeof(proc_info));
+    memset(&startup_info, 0, sizeof(startup_info));
+    startup_info.cb = sizeof(startup_info);
 
-    if (!CreateProcessW(exe_path, warg,
-                        NULL, NULL, FALSE, 0, NULL, NULL, NULL,
-                        &proc_info))
+    if (!CreateProcessW(NULL, command,
+                        NULL, NULL, FALSE, 0, NULL, NULL,
+                        &startup_info, &proc_info))
     {
         result = -1;
     }
@@ -260,8 +248,7 @@
         CloseHandle(proc_info.hThread);
     }
 
-    free(exe_path);
-    free(warg);
+    free(command);
 
     return result;
 }
@@ -268,11 +255,41 @@
 
 #else
 
+// Given the specified program name, get the full path to the program,
+// assuming that it is in the same directory as this program is.
+
+static char *GetFullExePath(const char *program)
+{
+    char *result;
+    char *sep;
+    unsigned int path_len;
+
+    sep = strrchr(myargv[0], DIR_SEPARATOR);
+
+    if (sep == NULL)
+    {
+        result = strdup(program);
+    }
+    else
+    {
+        path_len = sep - myargv[0] + 1;
+
+        result = malloc(strlen(program) + path_len + 1);
+
+        strncpy(result, myargv[0], path_len);
+        result[path_len] = '\0';
+
+        strcat(result, program);
+    }
+
+    return result;
+}
+
 static int ExecuteCommand(const char *program, const char *arg)
 {
     pid_t childpid;
     int result;
-    const char *argv[] = { program, arg, NULL };
+    const char *argv[3];
 
     childpid = fork();
 
@@ -279,6 +296,10 @@
     if (childpid == 0) 
     {
         // This is the child.  Execute the command.
+
+        argv[0] = GetFullExePath(program);
+        argv[1] = arg;
+        argv[2] = NULL;
 
         execv(argv[0], (char **) argv);
 
--- a/setup/mainmenu.c
+++ b/setup/mainmenu.c
@@ -19,6 +19,7 @@
 // 02111-1307, USA.
 //
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
--- a/setup/sound.c
+++ b/setup/sound.c
@@ -27,20 +27,6 @@
 
 #include "sound.h"
 
-enum
-{
-    SNDDEVICE_NONE = 0,
-    SNDDEVICE_PCSPEAKER = 1,
-    SNDDEVICE_ADLIB = 2,
-    SNDDEVICE_SB = 3,
-    SNDDEVICE_PAS = 4,
-    SNDDEVICE_GUS = 5,
-    SNDDEVICE_WAVEBLASTER = 6,
-    SNDDEVICE_SOUNDCANVAS = 7,
-    SNDDEVICE_GENMIDI = 8,
-    SNDDEVICE_AWE32 = 9,
-};
-
 typedef enum
 {
     SFXMODE_DISABLED,
@@ -71,13 +57,11 @@
     "Native MIDI"
 };
 
-#define DEFAULT_MUSIC_DEVICE SNDDEVICE_SB
-
 int snd_sfxdevice = SNDDEVICE_SB;
 int numChannels = 8;
 int sfxVolume = 15;
 
-int snd_musicdevice = DEFAULT_MUSIC_DEVICE;
+int snd_musicdevice = SNDDEVICE_SB;
 int musicVolume = 15;
 
 int snd_samplerate = 22050;
--- a/setup/sound.h
+++ b/setup/sound.h
@@ -22,6 +22,20 @@
 #ifndef SETUP_SOUND_H
 #define SETUP_SOUND_H
 
+enum
+{
+    SNDDEVICE_NONE = 0,
+    SNDDEVICE_PCSPEAKER = 1,
+    SNDDEVICE_ADLIB = 2,
+    SNDDEVICE_SB = 3,
+    SNDDEVICE_PAS = 4,
+    SNDDEVICE_GUS = 5,
+    SNDDEVICE_WAVEBLASTER = 6,
+    SNDDEVICE_SOUNDCANVAS = 7,
+    SNDDEVICE_GENMIDI = 8,
+    SNDDEVICE_AWE32 = 9,
+};
+
 extern int snd_sfxdevice;
 extern int numChannels;
 extern int sfxVolume;
--- a/src/i_sdlmusic.c
+++ b/src/i_sdlmusic.c
@@ -81,18 +81,28 @@
 // Initialize music subsystem
 
 static boolean I_SDL_InitMusic(void)
-{ 
-    // When trying to run with music enabled on OSX, display
-    // a warning message.
+{
+    // SDL_mixer prior to v1.2.11 has a bug that causes crashes
+    // with MIDI playback.  Print a warning message if we are
+    // using an old version.
 
-#ifdef __APPLE__
-    printf("\n"
-           "                   *** WARNING ***\n"
-           "      Music playback on OSX may cause crashes and\n"
-           "      is disabled by default.\n"
-           "\n");
+#ifdef __MACOSX__
+    {
+        const SDL_version *v = Mix_Linked_Version();
+
+        if (SDL_VERSIONNUM(v->major, v->minor, v->patch)
+          < SDL_VERSIONNUM(1, 2, 11))
+        {
+            printf("\n"
+               "                   *** WARNING ***\n"
+               "      You are using an old version of SDL_mixer.\n"
+               "      Music playback on this version may cause crashes\n"
+               "      under OS X and is disabled by default.\n"
+               "\n");
+        }
+    }
 #endif
-    
+
     // If SDL_mixer is not initialized, we have to initialize it
     // and have the responsibility to shut it down later on.
 
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -334,7 +334,9 @@
 
       case SDLK_PAUSE:	return KEY_PAUSE;
 
+#if !SDL_VERSION_ATLEAST(1, 3, 0)
       case SDLK_EQUALS: return KEY_EQUALS;
+#endif
 
       case SDLK_MINUS:          return KEY_MINUS;
 
@@ -347,9 +349,11 @@
 	return KEY_RCTRL;
 	
       case SDLK_LALT:
-      case SDLK_LMETA:
       case SDLK_RALT:
+#if !SDL_VERSION_ATLEAST(1, 3, 0)
+      case SDLK_LMETA:
       case SDLK_RMETA:
+#endif
         return KEY_RALT;
 
       case SDLK_CAPSLOCK: return KEY_CAPSLOCK;
@@ -420,9 +424,15 @@
 
 static int MouseButtonState(void)
 {
-    Uint8 state = SDL_GetMouseState(NULL, NULL);
+    Uint8 state;
     int result = 0;
 
+#if SDL_VERSION_ATLEAST(1, 3, 0)
+    state = SDL_GetMouseState(0, NULL, NULL);
+#else
+    state = SDL_GetMouseState(NULL, NULL);
+#endif
+
     // Note: button "0" is left, button "1" is right,
     // button "2" is middle for Doom.  This is different
     // to how SDL sees things.
@@ -585,7 +595,11 @@
     // Clear any relative movement caused by warping
 
     SDL_PumpEvents();
+#if SDL_VERSION_ATLEAST(1, 3, 0)
+    SDL_GetRelativeMouseState(0, NULL, NULL);
+#else
     SDL_GetRelativeMouseState(NULL, NULL);
+#endif
 }
 
 //
@@ -599,7 +613,11 @@
     int x, y;
     event_t ev;
 
+#if SDL_VERSION_ATLEAST(1, 3, 0)
+    SDL_GetRelativeMouseState(0, &x, &y);
+#else
     SDL_GetRelativeMouseState(&x, &y);
+#endif
 
     if (x != 0 || y != 0) 
     {
@@ -1553,7 +1571,9 @@
     // has to be done before the call to SDL_SetVideoMode.
 
     I_SetWindowCaption();
+#if !SDL_VERSION_ATLEAST(1, 3, 0)
     I_SetWindowIcon();
+#endif
 
     // Set the video mode.
 
--- a/src/m_config.c
+++ b/src/m_config.c
@@ -36,6 +36,8 @@
 #include <windows.h>
 #endif
 
+#include "SDL_mixer.h"
+
 #include "config.h"
 #include "deh_main.h"
 #include "doomdef.h"
@@ -53,6 +55,7 @@
 #include "i_swap.h"
 #include "i_system.h"
 #include "i_video.h"
+#include "s_sound.h"
 #include "v_video.h"
 
 #include "hu_stuff.h"
@@ -1234,7 +1237,14 @@
 
                     intparm = ParseIntParameter(strparm);
                     defaults[i].untranslated = intparm;
-                    intparm = scantokey[intparm];
+                    if (intparm >= 0 && intparm < 128)
+                    {
+                        intparm = scantokey[intparm];
+                    }
+                    else
+                    {
+                        intparm = 0;
+                    }
 
                     defaults[i].original_translated = intparm;
                     * (int *) def->location = intparm;
@@ -1455,6 +1465,22 @@
 {
 #ifdef _WIN32_WCE
     M_ApplyWindowsCEDefaults();
+#endif
+
+    // Before SDL_mixer version 1.2.11, MIDI music caused the game
+    // to crash when it looped.  If this is an old SDL_mixer version,
+    // disable MIDI.
+
+#ifdef __MACOSX__
+    {
+        const SDL_version *v = Mix_Linked_Version();
+
+        if (SDL_VERSIONNUM(v->major, v->minor, v->patch)
+          < SDL_VERSIONNUM(1, 2, 11))
+        {
+            snd_musicdevice = SNDDEVICE_NONE;
+        }
+    }
 #endif
 }
 
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -198,3 +198,11 @@
     return result;
 }
 
+boolean M_StrToInt(const char *str, int *result)
+{
+    return sscanf(str, " 0x%x", result) == 1
+        || sscanf(str, " 0X%x", result) == 1
+        || sscanf(str, " 0%o", result) == 1
+        || sscanf(str, " %d", result) == 1;
+}
+
--- a/src/m_misc.h
+++ b/src/m_misc.h
@@ -39,6 +39,7 @@
 char *M_TempFile(char *s);
 boolean M_FileExists(char *file);
 long M_FileLength(FILE *handle);
+boolean M_StrToInt(const char *str, int *result);
 
 #endif
 
--- a/src/p_doors.c
+++ b/src/p_doors.c
@@ -420,8 +420,41 @@
 	    {
 		if (!thing->player)
 		    return;		// JDC: bad guys never close doors
-		
-		door->direction = -1;	// start going down immediately
+
+                // When is a door not a door?
+                // In Vanilla, door->direction is set, even though
+                // "specialdata" might not actually point at a door.
+
+                if (door->thinker.function.acp1 == (actionf_p1) T_VerticalDoor)
+                {
+                    door->direction = -1;	// start going down immediately
+                }
+                else if (door->thinker.function.acp1 == (actionf_p1) T_PlatRaise)
+                {
+                    // Erm, this is a plat, not a door.
+                    // This notably causes a problem in ep1-0500.lmp where
+                    // a plat and a door are cross-referenced; the door
+                    // doesn't open on 64-bit.
+                    // The direction field in vldoor_t corresponds to the wait
+                    // field in plat_t.  Let's set that to -1 instead.
+
+                    plat_t *plat;
+
+                    plat = (plat_t *) door;
+                    plat->wait = -1;
+                }
+                else
+                {
+                    // This isn't a door OR a plat.  Now we're in trouble.
+
+                    fprintf(stderr, "EV_VerticalDoor: Tried to close "
+                                    "something that wasn't a door.\n");
+
+                    // Try closing it anyway. At least it will work on 32-bit
+                    // machines.
+
+                    door->direction = -1;
+                }
 	    }
 	    return;
 	}
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -36,6 +36,7 @@
 
 #include "doomdef.h"
 #include "m_argv.h"
+#include "m_misc.h"
 #include "p_local.h"
 
 #include "s_sound.h"
@@ -1412,7 +1413,7 @@
         
         if (p > 0)
         {
-            baseaddr = atoi(myargv[p+1]);
+            M_StrToInt(myargv[p+1], (int *) &baseaddr);
         }
         else
         {
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -38,6 +38,7 @@
 #include "i_system.h"
 #include "z_zone.h"
 #include "m_argv.h"
+#include "m_misc.h"
 #include "m_random.h"
 #include "w_wad.h"
 
@@ -1169,11 +1170,95 @@
 		memset(&buttonlist[i],0,sizeof(button_t));
 	    }
 	}
-	
 }
 
 
+//
+// Donut overrun emulation
+//
+// Derived from the code from PrBoom+.  Thanks go to Andrey Budko (entryway)
+// as usual :-)
+//
 
+#define DONUT_FLOORHEIGHT_DEFAULT 0x00000000
+#define DONUT_FLOORPIC_DEFAULT 0x16
+
+static void DonutOverrun(fixed_t *s3_floorheight, short *s3_floorpic,
+                         line_t *line, sector_t *pillar_sector)
+{
+    static int first = 1;
+    static int tmp_s3_floorheight;
+    static int tmp_s3_floorpic;
+
+    extern int numflats;
+
+    if (first)
+    {
+        int p;
+
+        // This is the first time we have had an overrun.
+        first = 0;
+
+        // Default values
+        tmp_s3_floorheight = DONUT_FLOORHEIGHT_DEFAULT;
+        tmp_s3_floorpic = DONUT_FLOORPIC_DEFAULT;
+
+        //!
+        // @category compat
+        // @arg <x> <y>
+        //
+        // Use the specified magic values when emulating behavior caused
+        // by memory overruns from improperly constructed donuts.
+        // In Vanilla Doom this can differ depending on the operating
+        // system.  The default (if this option is not specified) is to
+        // emulate the behavior when running under Windows 98.
+
+        p = M_CheckParm("-donut");
+
+        if (p > 0 && p < myargc - 2)
+        {
+            // Dump of needed memory: (fixed_t)0000:0000 and (short)0000:0008
+            //
+            // 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    (00 00 00 00) 65 04 70 00-(16 00)
+            // DOSBox under XP:
+            // 0000:0000    (00 00 00 F1) ?? ?? ?? 00-(07 00)
+
+            M_StrToInt(myargv[p + 1], &tmp_s3_floorheight);
+            M_StrToInt(myargv[p + 2], &tmp_s3_floorpic);
+
+            if (tmp_s3_floorpic >= numflats)
+            {
+                fprintf(stderr,
+                        "DonutOverrun: The second parameter for \"-donut\" "
+                        "switch should be greater than 0 and less than number "
+                        "of flats (%d). Using default value (%d) instead. \n",
+                        numflats, DONUT_FLOORPIC_DEFAULT);
+                tmp_s3_floorpic = DONUT_FLOORPIC_DEFAULT;
+            }
+        }
+    }
+
+    /*
+    fprintf(stderr,
+            "Linedef: %d; Sector: %d; "
+            "New floor height: %d; New floor pic: %d\n",
+            line->iLineID, pillar_sector->iSectorID,
+            tmp_s3_floorheight >> 16, tmp_s3_floorpic);
+     */
+
+    *s3_floorheight = (fixed_t) tmp_s3_floorheight;
+    *s3_floorpic = (short) tmp_s3_floorpic;
+}
+
+
 //
 // Special Stuff that can not be categorized
 //
@@ -1186,26 +1271,67 @@
     int			rtn;
     int			i;
     floormove_t*	floor;
-	
+    fixed_t s3_floorheight;
+    short s3_floorpic;
+
     secnum = -1;
     rtn = 0;
     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
     {
 	s1 = &sectors[secnum];
-		
+
 	// ALREADY MOVING?  IF SO, KEEP GOING...
 	if (s1->specialdata)
 	    continue;
-			
+
 	rtn = 1;
 	s2 = getNextSector(s1->lines[0],s1);
-	for (i = 0;i < s2->linecount;i++)
+
+        // Vanilla Doom does not check if the linedef is one sided.  The
+        // game does not crash, but reads invalid memory and causes the
+        // sector floor to move "down" to some unknown height.
+        // DOSbox prints a warning about an invalid memory access.
+        //
+        // I'm not sure exactly what invalid memory is being read.  This
+        // isn't something that should be done, anyway.
+        // Just print a warning and return.
+
+        if (s2 == NULL)
+        {
+            fprintf(stderr,
+                    "EV_DoDonut: linedef had no second sidedef! "
+                    "Unexpected behavior may occur in Vanilla Doom. \n");
+	    break;
+        }
+
+	for (i = 0; i < s2->linecount; i++)
 	{
-	    if ((!s2->lines[i]->flags & ML_TWOSIDED) ||
-		(s2->lines[i]->backsector == s1))
-		continue;
 	    s3 = s2->lines[i]->backsector;
-	    
+
+	    if (s3 == s1)
+		continue;
+
+            if (s3 == NULL)
+            {
+                // e6y
+                // s3 is NULL, so
+                // s3->floorheight is an int at 0000:0000
+                // s3->floorpic is a short at 0000:0008
+                // Trying to emulate
+
+                fprintf(stderr,
+                        "EV_DoDonut: WARNING: emulating buffer overrun due to "
+                        "NULL back sector. "
+                        "Unexpected behavior may occur in Vanilla Doom.\n");
+
+                DonutOverrun(&s3_floorheight, &s3_floorpic, line, s1);
+            }
+            else
+            {
+                s3_floorheight = s3->floorheight;
+                s3_floorpic = s3->floorpic;
+            }
+
 	    //	Spawn rising slime
 	    floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
 	    P_AddThinker (&floor->thinker);
@@ -1216,9 +1342,9 @@
 	    floor->direction = 1;
 	    floor->sector = s2;
 	    floor->speed = FLOORSPEED / 2;
-	    floor->texture = s3->floorpic;
+	    floor->texture = s3_floorpic;
 	    floor->newspecial = 0;
-	    floor->floordestheight = s3->floorheight;
+	    floor->floordestheight = s3_floorheight;
 	    
 	    //	Spawn lowering donut-hole
 	    floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
@@ -1230,7 +1356,7 @@
 	    floor->direction = -1;
 	    floor->sector = s1;
 	    floor->speed = FLOORSPEED / 2;
-	    floor->floordestheight = s3->floorheight;
+	    floor->floordestheight = s3_floorheight;
 	    break;
 	}
     }
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -69,14 +69,6 @@
 #define NORM_PRIORITY 64
 #define NORM_SEP 128
 
-// Disable music on OSX by default; there are problems with SDL_mixer.
-
-#ifndef __APPLE__
-#define DEFAULT_MUSIC_DEVICE SNDDEVICE_SB
-#else
-#define DEFAULT_MUSIC_DEVICE SNDDEVICE_NONE
-#endif
-
 typedef struct
 {
     // sound information (if null, channel avail.)
@@ -128,7 +120,7 @@
 
 int numChannels = 8;
 
-int snd_musicdevice = DEFAULT_MUSIC_DEVICE;
+int snd_musicdevice = SNDDEVICE_SB;
 int snd_sfxdevice = SNDDEVICE_SB;
 
 // Sound modules
--- a/textscreen/txt_sdl.c
+++ b/textscreen/txt_sdl.c
@@ -263,19 +263,44 @@
     }
 }
 
+static int LimitToRange(int val, int min, int max)
+{
+    if (val < min)
+    {
+        return min;
+    }
+    else if (val > max)
+    {
+        return max;
+    }
+    else
+    {
+        return val;
+    }
+}
+
 void TXT_UpdateScreenArea(int x, int y, int w, int h)
 {
     int x1, y1;
+    int x_end;
+    int y_end;
 
-    for (y1=y; y1<y+h; ++y1)
+    x_end = LimitToRange(x + w, 0, TXT_SCREEN_W - 1);
+    y_end = LimitToRange(y + h, 0, TXT_SCREEN_H - 1);
+    x = LimitToRange(x, 0, TXT_SCREEN_W - 1);
+    y = LimitToRange(y, 0, TXT_SCREEN_H - 1);
+
+    for (y1=y; y1<y_end; ++y1)
     {
-        for (x1=x; x1<x+w; ++x1)
+        for (x1=x; x1<x_end; ++x1)
         {
             UpdateCharacter(x1, y1);
         }
     }
 
-    SDL_UpdateRect(screen, x * font->w, y * font->h, w * font->w, h * font->h);
+    SDL_UpdateRect(screen,
+                   x * font->w, y * font->h,
+                   (x_end - x) * font->w, (y_end - y) * font->h);
 }
 
 void TXT_UpdateScreen(void)
@@ -285,7 +310,11 @@
 
 void TXT_GetMousePosition(int *x, int *y)
 {
+#if SDL_VERSION_ATLEAST(1, 3, 0)
+    SDL_GetMouseState(0, x, y);
+#else
     SDL_GetMouseState(x, y);
+#endif
 
     *x /= font->w;
     *y /= font->h;
@@ -324,7 +353,9 @@
 
         case SDLK_PAUSE:       return KEY_PAUSE;
 
+#if !SDL_VERSION_ATLEAST(1, 3, 0)
         case SDLK_EQUALS:      return KEY_EQUALS;
+#endif
 
         case SDLK_LSHIFT:
         case SDLK_RSHIFT:
@@ -335,9 +366,11 @@
                                return KEY_RCTRL;
 
         case SDLK_LALT:
-        case SDLK_LMETA:
         case SDLK_RALT:
+#if !SDL_VERSION_ATLEAST(1, 3, 0)
+        case SDLK_LMETA:
         case SDLK_RMETA:
+#endif
                                return KEY_RALT;
 
         case SDLK_CAPSLOCK:    return KEY_CAPSLOCK;