diff options
-rw-r--r-- | acinclude.m4 | 31 | ||||
-rw-r--r-- | configure.in | 52 | ||||
-rw-r--r-- | src/i_main.c | 4 | ||||
-rw-r--r-- | src/i_sdlsound.c | 7 | ||||
-rw-r--r-- | src/i_video.c | 65 | ||||
-rw-r--r-- | src/w_file_win32.c | 2 | ||||
-rw-r--r-- | textscreen/txt_gui.c | 1 | ||||
-rw-r--r-- | textscreen/txt_scrollpane.c | 76 | ||||
-rw-r--r-- | textscreen/txt_table.c | 82 | ||||
-rw-r--r-- | textscreen/txt_table.h | 13 | ||||
-rw-r--r-- | wince/Makefile.am | 2 | ||||
-rw-r--r-- | wince/dummy.c | 8 |
12 files changed, 289 insertions, 54 deletions
diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 00000000..ac54f4b9 --- /dev/null +++ b/acinclude.m4 @@ -0,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" +]) + diff --git a/configure.in b/configure.in index 7c31ced4..6f450d85 100644 --- a/configure.in +++ b/configure.in @@ -39,20 +39,42 @@ AM_PATH_SDL(1.1.3) 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_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(SDL_net,SDLNet_UDP_Send,[ - SDLNET_LIBS="$SDLNET_LIBS -lSDL_net" -],[ - echo "*** Could not find SDL_net. Please install it." - exit -1 + 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 @@ -66,14 +88,6 @@ case "$host" in ;; 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" != "") AM_CONDITIONAL(HAVE_PYTHON, $HAVE_PYTHON) diff --git a/src/i_main.c b/src/i_main.c index 03f8a5ac..cdfb531a 100644 --- a/src/i_main.c +++ b/src/i_main.c @@ -47,7 +47,7 @@ static void LockCPUAffinity(void) #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 @@ static void LockCPUAffinity(void) // 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 diff --git a/src/i_sdlsound.c b/src/i_sdlsound.c index bb8229e4..ea5c92a5 100644 --- a/src/i_sdlsound.c +++ b/src/i_sdlsound.c @@ -275,12 +275,15 @@ static boolean LoadSoundLump(int sound, 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 diff --git a/src/i_video.c b/src/i_video.c index 3412051b..582a7fa7 100644 --- 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 @@ boolean screenvisible; // 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 @@ static void LoadDiskImage(void) 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 @@ static void LoadDiskImage(void) 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: + + V_DrawPatch(SCREENWIDTH - LOADING_DISK_W, + SCREENHEIGHT - LOADING_DISK_H, + 0, disk); - 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); + 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<disk_image_h; ++y) + 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 @@ static void UpdateRect(int x1, int y1, int x2, int y2) 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 @@ void I_BeginRead(void) // 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 @@ void I_EndRead(void) // 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); } diff --git a/src/w_file_win32.c b/src/w_file_win32.c index ec17cf6c..9e5d963f 100644 --- 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> diff --git a/textscreen/txt_gui.c b/textscreen/txt_gui.c index e7f0472e..276176ec 100644 --- a/textscreen/txt_gui.c +++ b/textscreen/txt_gui.c @@ -234,7 +234,6 @@ void TXT_DrawString(char *s) if (VALID_Y(y)) { - p = s; x1 = x; for (p = s; *p != '\0'; ++p) diff --git a/textscreen/txt_scrollpane.c b/textscreen/txt_scrollpane.c index ef6e4fb3..d81cce4b 100644 --- a/textscreen/txt_scrollpane.c +++ b/textscreen/txt_scrollpane.c @@ -254,10 +254,53 @@ static void ShowSelectedWidget(txt_scrollpane_t *scrollpane) } } +// 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 @@ static int InterpretScrollKey(txt_scrollpane_t *scrollpane, int key) } 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 @@ static int TXT_ScrollPaneKeyPress(TXT_UNCAST_ARG(scrollpane), int key) 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); } diff --git a/textscreen/txt_table.c b/textscreen/txt_table.c index 0d4d1e35..1b432681 100644 --- a/textscreen/txt_table.c +++ b/textscreen/txt_table.c @@ -770,3 +770,85 @@ void TXT_SetColumnWidths(TXT_UNCAST_ARG(table), ...) 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; +} + diff --git a/textscreen/txt_table.h b/textscreen/txt_table.h index 0e7fbe94..0166abee 100644 --- a/textscreen/txt_table.h +++ b/textscreen/txt_table.h @@ -178,6 +178,19 @@ void TXT_SetColumnWidths(TXT_UNCAST_ARG(table), ...); 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 */ diff --git a/wince/Makefile.am b/wince/Makefile.am index 7d694377..476b9a67 100644 --- a/wince/Makefile.am +++ b/wince/Makefile.am @@ -10,7 +10,7 @@ libc_wince_a_SOURCES = \ else -libc_wince_a_SOURCES = +libc_wince_a_SOURCES = dummy.c endif diff --git a/wince/dummy.c b/wince/dummy.c new file mode 100644 index 00000000..68af0caa --- /dev/null +++ b/wince/dummy.c @@ -0,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) +{ +} + |