shithub: choc

Download patch

ref: 100b658b470ecaf9ff5e2c3407bfff224e91fb01
parent: ba1accec2394c6ee70c5c79a42827099ef20e638
parent: be3bba2a1cf9551778683e25f61bffc7c187f93c
author: Simon Howard <fraggle@gmail.com>
date: Thu Sep 10 16:28:59 EDT 2009

Merge from trunk.

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

--- /dev/null
+++ b/acinclude.m4
@@ -1,0 +1,31 @@
+
+dnl Macro to check if autoconf's compile tests have been broken by
+dnl SDL.  Tries to build the simplest possible program, and if it
+dnl fails, calls the given block.
+
+AC_DEFUN([AC_CHECK_SDL_BREAKAGE], [
+    AC_LINK_IFELSE(AC_LANG_PROGRAM([], []), [], [
+        $1
+    ])
+])
+
+dnl Macro to work around SDL redefining main.  The provided block
+dnl is run with main #defined to SDL_main via a compiler switch
+dnl if autoconf tests are found to be broken.
+
+AC_DEFUN([AC_SDL_MAIN_WORKAROUND], [
+    sdl_workaround_saved_CFLAGS="$CFLAGS"
+
+    AC_CHECK_SDL_BREAKAGE([
+        CFLAGS="$CFLAGS -Dmain=SDL_main"
+    ])
+
+    AC_CHECK_SDL_BREAKAGE([
+        AC_MSG_ERROR([Autoconf checks broken by SDL, and can't figure out how to fix them.])
+    ])
+
+    $1
+
+    CFLAGS="$sdl_workaround_saved_CFLAGS"
+])
+
--- a/configure.in
+++ b/configure.in
@@ -39,20 +39,42 @@
 CFLAGS="$CFLAGS $SDL_CFLAGS"
 LDFLAGS="$LDFLAGS $SDL_LIBS"
 
-AC_CHECK_LIB(SDL_mixer,Mix_LoadMUS,[
-    SDLMIXER_LIBS="$SDLMIXER_LIBS -lSDL_mixer"
-],[
-    echo "*** Could not find SDL_mixer.  Please install it."
-    exit -1
-])
+# On some platforms, SDL renames main() to SDL_main() using a #define,
+# so that its own main, stored in the SDLmain library, can be run first.
+# Unfortunately, this causes problems for autoconf, which builds
+# test programs to probe the system.  All library/header/symbol checks
+# must be run in this block, that performs a workaround for the problem.
 
-AC_CHECK_LIB(SDL_net,SDLNet_UDP_Send,[
-    SDLNET_LIBS="$SDLNET_LIBS -lSDL_net"
-],[
-    echo "*** Could not find SDL_net.  Please install it."
-    exit -1
+AC_SDL_MAIN_WORKAROUND([
+
+    # Check for SDL_mixer.
+
+    AC_CHECK_LIB(SDL_mixer,Mix_LoadMUS,[
+        SDLMIXER_LIBS="$SDLMIXER_LIBS -lSDL_mixer"
+    ],[
+        echo "*** Could not find SDL_mixer.  Please install it."
+        exit -1
+    ])
+
+    # Check for SDL_net.
+
+    AC_CHECK_LIB(SDL_net,SDLNet_UDP_Send,[
+        SDLNET_LIBS="$SDLNET_LIBS -lSDL_net"
+    ],[
+        echo "*** Could not find SDL_net.  Please install it."
+        exit -1
+    ])
+
+    # Check for libsamplerate.
+
+    AC_CHECK_LIB(samplerate, src_new)
+
+    AC_CHECK_HEADERS([linux/kd.h dev/isa/spkrio.h dev/speaker/speaker.h])
+    AC_CHECK_FUNCS(mmap sched_setaffinity)
 ])
 
+AC_CHECK_TOOL(WINDRES, windres, )
+
 # Windows CE build?
 
 WINDOWS_CE=false
@@ -65,14 +87,6 @@
     *)
         ;;
 esac
-
-AC_CHECK_HEADERS([linux/kd.h dev/isa/spkrio.h dev/speaker/speaker.h])
-AC_CHECK_FUNCS(mmap sched_setaffinity ioperm)
-
-# DWF 2008-02-10:  FIXME
-AC_CHECK_LIB(samplerate, src_new)
-
-AC_CHECK_TOOL(WINDRES, windres, )
 
 AM_CONDITIONAL(WINDOWS_CE, $WINDOWS_CE)
 AM_CONDITIONAL(HAVE_WINDRES, test "$WINDRES" != "")
--- a/src/i_main.c
+++ b/src/i_main.c
@@ -47,7 +47,7 @@
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
-typedef BOOL WINAPI (*SetAffinityFunc)(HANDLE hProcess, DWORD_PTR mask);
+typedef BOOL (WINAPI *SetAffinityFunc)(HANDLE hProcess, DWORD mask);
 
 // This is a bit more complicated than it really needs to be.  We really
 // just need to call the SetProcessAffinityMask function, but that
@@ -74,7 +74,7 @@
 
     // Find the SetProcessAffinityMask function.
 
-    SetAffinity = GetProcAddress(kernel32_dll, "SetProcessAffinityMask");
+    SetAffinity = (SetAffinityFunc)GetProcAddress(kernel32_dll, "SetProcessAffinityMask");
 
     // If the function was not found, we are on an old (Win9x) system
     // that doesn't have this function.  That's no problem, because
--- a/src/i_sdlsound.c
+++ b/src/i_sdlsound.c
@@ -275,12 +275,15 @@
 			     uint32_t *length,
 			     byte **data_ref)
 {
+    int lumplen;
+    byte *data;
+
     // Load the sound
 
     *lumpnum    = S_sfx[sound].lumpnum;
     *data_ref   = W_CacheLumpNum(*lumpnum, PU_STATIC);
-    int lumplen = W_LumpLength(*lumpnum);
-    byte *data  = *data_ref;
+    lumplen = W_LumpLength(*lumpnum);
+    data  = *data_ref;
 
     // Ensure this is a valid sound
 
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -50,6 +50,9 @@
 #include "w_wad.h"
 #include "z_zone.h"
 
+#define LOADING_DISK_W 16
+#define LOADING_DISK_H 16
+
 // Non aspect ratio-corrected modes (direct multiples of 320x200)
 
 static screen_mode_t *screen_modes[] = {
@@ -145,7 +148,6 @@
 // restored by EndRead
 
 static byte *disk_image = NULL;
-static int disk_image_w, disk_image_h;
 static byte *saved_background;
 static boolean window_focused;
 
@@ -258,6 +260,8 @@
     patch_t *disk;
     char *disk_name;
     int y;
+    int xoffset = SCREENWIDTH - LOADING_DISK_W;
+    int yoffset = SCREENHEIGHT - LOADING_DISK_H;
     char buf[20];
 
     SDL_VideoDriverName(buf, 15);
@@ -278,19 +282,20 @@
 
     disk = W_CacheLumpName(disk_name, PU_STATIC);
 
-    V_DrawPatch(0, 0, 0, disk);
-    disk_image_w = SHORT(disk->width);
-    disk_image_h = SHORT(disk->height);
+    // Draw the disk to the screen:
 
-    disk_image = Z_Malloc(disk_image_w * disk_image_h, PU_STATIC, NULL);
-    saved_background = Z_Malloc(disk_image_w * disk_image_h, PU_STATIC, NULL);
+    V_DrawPatch(SCREENWIDTH - LOADING_DISK_W,
+                SCREENHEIGHT - LOADING_DISK_H,
+                0, disk);
 
-    for (y=0; y<disk_image_h; ++y) 
+    disk_image = Z_Malloc(LOADING_DISK_W * LOADING_DISK_H, PU_STATIC, NULL);
+    saved_background = Z_Malloc(LOADING_DISK_W * LOADING_DISK_H, PU_STATIC, NULL);
+
+    for (y=0; y<LOADING_DISK_H; ++y) 
     {
-        memcpy(disk_image + disk_image_w * y,
-               screens[0] + SCREENWIDTH * y,
-               disk_image_w);
-        memset(screens[0] + SCREENWIDTH * y, 0, disk_image_w);
+        memcpy(disk_image + LOADING_DISK_W * y,
+               screens[0] + SCREENWIDTH * (y + yoffset) + xoffset,
+               LOADING_DISK_W);
     }
 
     W_ReleaseLumpName(disk_name);
@@ -731,6 +736,9 @@
 
 void I_BeginRead(void)
 {
+    byte *screenloc = screens[0]
+                    + (SCREENHEIGHT - LOADING_DISK_H) * SCREENWIDTH
+                    + (SCREENWIDTH - LOADING_DISK_W);
     int y;
 
     if (!initialised || disk_image == NULL)
@@ -738,25 +746,27 @@
 
     // save background and copy the disk image in
 
-    for (y=0; y<disk_image_h; ++y)
+    for (y=0; y<LOADING_DISK_H; ++y)
     {
-        byte *screenloc = 
-               screens[0] 
-                 + (SCREENHEIGHT - 1 - disk_image_h + y) * SCREENWIDTH
-                 + (SCREENWIDTH - 1 - disk_image_w);
-
-        memcpy(saved_background + y * disk_image_w,
+        memcpy(saved_background + y * LOADING_DISK_W,
                screenloc,
-               disk_image_w);
-        memcpy(screenloc, disk_image + y * disk_image_w, disk_image_w);
+               LOADING_DISK_W);
+        memcpy(screenloc,
+               disk_image + y * LOADING_DISK_W,
+               LOADING_DISK_W);
+
+        screenloc += SCREENWIDTH;
     }
 
-    UpdateRect(SCREENWIDTH - disk_image_w, SCREENHEIGHT - disk_image_h,
+    UpdateRect(SCREENWIDTH - LOADING_DISK_W, SCREENHEIGHT - LOADING_DISK_H,
                SCREENWIDTH, SCREENHEIGHT);
 }
 
 void I_EndRead(void)
 {
+    byte *screenloc = screens[0]
+                    + (SCREENHEIGHT - LOADING_DISK_H) * SCREENWIDTH
+                    + (SCREENWIDTH - LOADING_DISK_W);
     int y;
 
     if (!initialised || disk_image == NULL)
@@ -764,17 +774,16 @@
 
     // save background and copy the disk image in
 
-    for (y=0; y<disk_image_h; ++y)
+    for (y=0; y<LOADING_DISK_H; ++y)
     {
-        byte *screenloc = 
-               screens[0] 
-                 + (SCREENHEIGHT - 1 - disk_image_h + y) * SCREENWIDTH
-                 + (SCREENWIDTH - 1 - disk_image_w);
+        memcpy(screenloc,
+               saved_background + y * LOADING_DISK_W,
+               LOADING_DISK_W);
 
-        memcpy(screenloc, saved_background + y * disk_image_w, disk_image_w);
+        screenloc += SCREENWIDTH;
     }
 
-    UpdateRect(SCREENWIDTH - disk_image_w, SCREENHEIGHT - disk_image_h,
+    UpdateRect(SCREENWIDTH - LOADING_DISK_W, SCREENHEIGHT - LOADING_DISK_H,
                SCREENWIDTH, SCREENHEIGHT);
 }
 
--- a/src/w_file_win32.c
+++ b/src/w_file_win32.c
@@ -28,6 +28,8 @@
 
 #ifdef _WIN32
 
+#include <stdio.h>
+
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
--- a/textscreen/txt_gui.c
+++ b/textscreen/txt_gui.c
@@ -234,7 +234,6 @@
 
     if (VALID_Y(y))
     {
-        p = s;
         x1 = x;
 
         for (p = s; *p != '\0'; ++p)
--- a/textscreen/txt_scrollpane.c
+++ b/textscreen/txt_scrollpane.c
@@ -254,10 +254,53 @@
     }
 }
 
+// Another hack for tables - when scrolling in 'pages', the normal key press
+// event does not provide children with enough information to know how far
+// to move their selection to reach a new page. This function does so.
+// Note that it *only* affects scrolling in pages, not with arrows!
+// A side-effect of this, rather than 'pulling' the selection to fit within
+// the new page, is that we will jump straight over ranges of unselectable
+// items longer than a page, but that is also true of arrow-key scrolling.
+// The other unfortunate effect of doing things this way is that page keys
+// have no effect on tables _not_ in scrollpanes: not even home/end.
+
+static int PageSelectedWidget(txt_scrollpane_t *scrollpane, int key)
+{
+    int pagex = 0; // No page left/right yet, but some keyboards have them
+    int pagey = 0;
+
+    // Subtract one from the absolute page distance as this is slightly more
+    // intuitive: a page down first jumps to the bottom of the current page,
+    // then proceeds to scroll onwards.
+
+    switch (key)
+    {
+        case KEY_PGUP:
+            pagey = 1 - scrollpane->h;
+            break;
+
+        case KEY_PGDN:
+            pagey = scrollpane->h - 1;
+            break;
+
+        default: // We shouldn't even be in this function
+            return 0;
+    }
+
+    if (scrollpane->child->widget_class == &txt_table_class)
+    {
+        return TXT_PageTable(scrollpane->child, pagex, pagey);
+    }
+
+    return 0;
+}
+
 // Interpret arrow key presses as scroll commands
 
 static int InterpretScrollKey(txt_scrollpane_t *scrollpane, int key)
 {
+    int maxy;
+
     switch (key)
     {
         case KEY_UPARROW:
@@ -292,6 +335,31 @@
             }
             break;
 
+        case KEY_PGUP:
+            if (scrollpane->y > 0)
+            {
+                scrollpane->y -= scrollpane->h;
+                if (scrollpane->y < 0)
+                {
+                    scrollpane->y = 0;
+                }
+                return 1;
+            }
+            break;
+
+        case KEY_PGDN:
+            maxy = FullHeight(scrollpane) - scrollpane->h;
+            if (scrollpane->y < maxy)
+            {
+                scrollpane->y += scrollpane->h;
+                if (scrollpane->y > maxy)
+                {
+                    scrollpane->y = maxy;
+                }
+                return 1;
+            }
+            break;
+
         default:
             break;
     }
@@ -316,8 +384,14 @@
 
         if (scrollpane->child->widget_class == &txt_table_class
          && (key == KEY_UPARROW || key == KEY_DOWNARROW
-          || key == KEY_LEFTARROW || key == KEY_RIGHTARROW))
+          || key == KEY_LEFTARROW || key == KEY_RIGHTARROW
+          || key == KEY_PGUP || key == KEY_PGDN))
         {
+            if (PageSelectedWidget(scrollpane, key))
+            {
+                result = 1;
+            }
+
             ShowSelectedWidget(scrollpane);
         }
 
--- a/textscreen/txt_table.c
+++ b/textscreen/txt_table.c
@@ -770,3 +770,85 @@
     va_end(args);
 }
 
+// Moves the select by at least the given number of characters.
+// Currently quietly ignores pagex, as we don't use it.
+
+int TXT_PageTable(TXT_UNCAST_ARG(table), int pagex, int pagey)
+{
+    TXT_CAST_ARG(txt_table_t, table);
+    unsigned int *column_widths;
+    unsigned int *row_heights;
+    int rows;
+    int changed = 0;
+
+    rows = TableRows(table);
+
+    row_heights = malloc(sizeof(int) * rows);
+    column_widths = malloc(sizeof(int) * table->columns);
+
+    CalcRowColSizes(table, row_heights, column_widths);
+
+    if (pagex)
+    {
+        // @todo Jump selection to the left or right as needed
+    }
+
+    if (pagey)
+    {
+        int new_x, new_y;
+        int distance = 0;
+        int dir;
+
+        // What direction are we moving?
+
+        if (pagey > 0)
+        {
+            dir = 1;
+        }
+        else
+        {
+            dir = -1;
+        }
+
+        // Move the cursor until the desired distance is reached.
+
+        new_y = table->selected_y;
+
+        while (new_y >= 0 && new_y < rows)
+        {
+            // We are about to travel a distance equal to the height of the row
+            // we are about to leave.
+
+            distance += row_heights[new_y];
+
+            // *Now* increment the loop.
+
+            new_y += dir;
+
+            new_x = FindSelectableColumn(table, new_y, table->selected_x);
+
+            if (new_x >= 0)
+            {
+                // Found a selectable widget in this column!
+                // Select it anyway in case we don't find something better.
+
+                table->selected_x = new_x;
+                table->selected_y = new_y;
+                changed = 1;
+
+                // ...but is it far enough away?
+
+                if (distance >= abs(pagey))
+                {
+                    break;
+                }
+            }
+        }
+    }
+
+    free(row_heights);
+    free(column_widths);
+
+    return changed;
+}
+
--- a/textscreen/txt_table.h
+++ b/textscreen/txt_table.h
@@ -178,6 +178,19 @@
 
 void TXT_ClearTable(TXT_UNCAST_ARG(table));
 
+/**
+ * Hack to move the selection in a table by a 'page', triggered by the
+ * scrollpane. This acts as per the keyboard events for the arrows, but moves
+ * the selection by at least the specified number of characters.
+ *
+ * @param table    The table.
+ * @param pagex    Minimum distance to move the selection horizontally.
+ * @param pagey    Minimum distance to move the selection vertically.
+ * @return         Non-zero if the selection has been changed.
+ */
+
+int TXT_PageTable(TXT_UNCAST_ARG(table), int pagex, int pagey);
+
 #endif /* #ifndef TXT_TABLE_T */
 
 
--- a/wince/Makefile.am
+++ b/wince/Makefile.am
@@ -10,7 +10,7 @@
 
 else
 
-libc_wince_a_SOURCES =
+libc_wince_a_SOURCES = dummy.c
 
 endif
 
--- /dev/null
+++ b/wince/dummy.c
@@ -1,0 +1,8 @@
+
+// Dummy source file so that the Windows CE workaround library is
+// not empty.  Some platforms don't like empty libraries.
+
+void DummyWindowsCEFunction(void)
+{
+}
+