diff --git a/NEWS b/NEWS index d830691eb..b89905da5 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,14 @@ NEWS for the QuakeForge project ------------------------------- +Changes from 0.6.0 + o qfprogs has been moved from tools to qfcc (windows packages). + o The software renderer can now cope with pics being off-screen. + o A potential issue with reading past the end of PCX files has been fixed. + o qfcc now accepts --no-default-paths. Mainly for building Ruamoko code in + the main source tree, but useful for those that want to avoid libr. + o A segfault involving old dirconfs has been fixed. + o OSS sound should be working now. + Changes from 0.5.99 Beta 4.1 o Many more keys supported in X11 (-glx, -x11) clients: most of the keys on a Microsoft Natural Ergonomic Keyboard 4000 v1.0 are supported (not diff --git a/libs/audio/cd_sdl.c b/libs/audio/cd_sdl.c index cd420d944..616a4e1d7 100644 --- a/libs/audio/cd_sdl.c +++ b/libs/audio/cd_sdl.c @@ -151,7 +151,7 @@ I_CDAudio_Resume (void) return; if (SDL_CDResume (cd_id)) - Sys_MaskPrintf (SYS_SND, "CDAudio_Resume: Failed tp resume track.\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio_Resume: Failed to resume track.\n"); } static void diff --git a/libs/audio/targets/snd_oss.c b/libs/audio/targets/snd_oss.c index 5e5ad5320..b1281cddd 100644 --- a/libs/audio/targets/snd_oss.c +++ b/libs/audio/targets/snd_oss.c @@ -250,7 +250,8 @@ try_open (int rw) return 0; } - sn.frames = info.fragstotal; + sn.frames = info.fragstotal * info.fragsize; + sn.frames /= sn.channels * sn.samplebits / 8; sn.submission_chunk = 1; if (mmaped_io) { // memory map the dma buffer @@ -260,7 +261,8 @@ try_open (int rw) len = (len + sz - 1) & ~(sz - 1); sn.buffer = (byte *) mmap (NULL, len, mmmode, mmflags, audio_fd, 0); if (sn.buffer == MAP_FAILED) { - Sys_Printf ("Could not mmap %s: %s\n", snd_dev, strerror (errno)); + Sys_MaskPrintf (SYS_SND, "Could not mmap %s: %s\n", snd_dev, + strerror (errno)); close (audio_fd); return 0; } @@ -326,7 +328,7 @@ SNDDMA_GetDMAPos (void) } // sn.samplepos = (count.bytes / (sn.samplebits / 8)) & (sn.samples-1); // fprintf(stderr, "%d \r", count.ptr); - sn.framepos = count.ptr / (sn.samplebits / 8); + sn.framepos = count.ptr / (sn.channels * sn.samplebits / 8); return sn.framepos; diff --git a/libs/audio/targets/snd_sdl.c b/libs/audio/targets/snd_sdl.c index 211471068..c2ee47a34 100644 --- a/libs/audio/targets/snd_sdl.c +++ b/libs/audio/targets/snd_sdl.c @@ -53,7 +53,13 @@ static __attribute__ ((used)) const char rcsid[] = static dma_t sn; static int snd_inited; -static int snd_blocked = 0; +static int snd_blocked; + +static unsigned shm_buflen; +static unsigned char *shm_buf; +static unsigned shm_rpos; + +static unsigned wpos; static cvar_t *snd_bits; static cvar_t *snd_rate; @@ -71,25 +77,16 @@ static snd_output_funcs_t plugin_info_snd_output_funcs; static void paint_audio (void *unused, Uint8 * stream, int len) { - int frameposbytes, framesbytes, frames; - - frames = len / (sn.channels * (sn.samplebits / 8)); - frameposbytes = sn.framepos * sn.channels * (sn.samplebits / 8); - framesbytes = sn.frames * sn.channels * (sn.samplebits / 8); - - sn.framepos += frames; - while (sn.framepos >= sn.frames) - sn.framepos -= sn.frames; - - if (sn.framepos + frames <= sn.frames) - memcpy (stream, sn.buffer + frameposbytes, len); - else { - memcpy (stream, sn.buffer + frameposbytes, framesbytes - - frameposbytes); - memcpy (stream + framesbytes - frameposbytes, sn.buffer, len - - (framesbytes - frameposbytes)); + while (shm_rpos + len > shm_buflen) { + memcpy (stream, shm_buf + shm_rpos, shm_buflen - shm_rpos); + stream += shm_buflen - shm_rpos; + len -= shm_buflen - shm_rpos; + shm_rpos = 0; + } + if (len) { + memcpy (stream, shm_buf + shm_rpos, len); + shm_rpos += len; } - *plugin_info_snd_output_data.soundtime += frames; } static void @@ -101,7 +98,6 @@ SNDDMA_Init_Cvars (void) "sound playback rate. 0 is system default"); snd_bits = Cvar_Get ("snd_bits", "0", CVAR_ROM, NULL, "sound sample depth. 0 is system default"); - } static volatile dma_t * @@ -109,7 +105,8 @@ SNDDMA_Init (void) { SDL_AudioSpec desired, obtained; - snd_inited = 0; + if (snd_inited) + return &sn; if (SDL_Init (SDL_INIT_AUDIO) < 0) { Sys_Printf ("Couldn't initialize SDL AUDIO: %s\n", SDL_GetError ()); @@ -179,20 +176,37 @@ SNDDMA_Init (void) sn.frames = obtained.samples * 8; // 8 chunks in the buffer sn.framepos = 0; sn.submission_chunk = 1; - sn.buffer = calloc(sn.frames * sn.channels * (sn.samplebits / 8), 1); + + shm_buflen = sn.frames * sn.channels * (sn.samplebits / 8); + + sn.buffer = calloc (shm_buflen, 1); if (!sn.buffer) Sys_Error ("Failed to allocate buffer for sound!"); - SDL_LockAudio(); - SDL_PauseAudio (0); + shm_buf = calloc (shm_buflen, 1); + if (!shm_buf) + Sys_Error ("Failed to allocate buffer for sound!"); + + shm_rpos = wpos = 0; + + if (!snd_blocked) + SDL_PauseAudio (0); snd_inited = 1; + return &sn; } static int SNDDMA_GetDMAPos (void) { + if (!snd_inited) + return 0; + + SDL_LockAudio (); + sn.framepos = shm_rpos / (sn.channels * (sn.samplebits / 8)); + SDL_UnlockAudio (); + return sn.framepos; } @@ -200,9 +214,9 @@ static void SNDDMA_Shutdown (void) { if (snd_inited) { - SDL_PauseAudio (1); - SDL_UnlockAudio (); SDL_CloseAudio (); + free (sn.buffer); + free (shm_buf); snd_inited = 0; } } @@ -215,25 +229,53 @@ SNDDMA_Shutdown (void) static void SNDDMA_Submit (void) { - if (snd_blocked) + static unsigned old_paintedtime; + unsigned len; + + if (!snd_inited || snd_blocked) return; - SDL_UnlockAudio(); - SDL_LockAudio(); + SDL_LockAudio (); + + if (*plugin_info_snd_output_data.paintedtime < old_paintedtime) + old_paintedtime = 0; + + len = (*plugin_info_snd_output_data.paintedtime - old_paintedtime) * + sn.channels * (sn.samplebits / 8); + + old_paintedtime = *plugin_info_snd_output_data.paintedtime; + + while (wpos + len > shm_buflen) { + memcpy (shm_buf + wpos, sn.buffer + wpos, shm_buflen - wpos); + len -= shm_buflen - wpos; + wpos = 0; + } + if (len) { + memcpy (shm_buf + wpos, sn.buffer + wpos, len); + wpos += len; + } + + SDL_UnlockAudio (); } static void SNDDMA_BlockSound (void) { - ++snd_blocked; + if (!snd_inited) + return; + + if (++snd_blocked == 1) + SDL_PauseAudio (1); } static void SNDDMA_UnblockSound (void) { - if (!snd_blocked) + if (!snd_inited || !snd_blocked) return; - --snd_blocked; + + if (!--snd_blocked) + SDL_PauseAudio (0); } PLUGIN_INFO(snd_output, sdl) @@ -243,7 +285,7 @@ PLUGIN_INFO(snd_output, sdl) plugin_info.plugin_version = "0.1"; plugin_info.description = "SDL digital output"; plugin_info.copyright = "Copyright (C) 1996-1997 id Software, Inc.\n" - "Copyright (C) 1999,2000,2001 contributors of the QuakeForge " + "Copyright (C) 1999,2000,2001,2012 contributors of the QuakeForge " "project\n" "Please see the file \"AUTHORS\" for a list of contributors"; plugin_info.functions = &plugin_info_funcs; diff --git a/libs/audio/targets/snd_win.c b/libs/audio/targets/snd_win.c index 1c319f8f8..299dbfdf4 100644 --- a/libs/audio/targets/snd_win.c +++ b/libs/audio/targets/snd_win.c @@ -109,7 +109,7 @@ SNDDMA_BlockSound (void) static void SNDDMA_UnblockSound (void) { - if (!snd_blocked) + if (snd_blocked) --snd_blocked; } diff --git a/libs/image/pcx.c b/libs/image/pcx.c index a29306223..55a3ec8d8 100644 --- a/libs/image/pcx.c +++ b/libs/image/pcx.c @@ -55,6 +55,7 @@ LoadPCX (QFile *f, qboolean convert, byte *pal) pcx_t *pcx; int pcx_mark; byte *palette; + byte *end; byte *pix; byte *dataByte; int runLength = 1; @@ -85,7 +86,7 @@ LoadPCX (QFile *f, qboolean convert, byte *pal) return 0; } - palette = ((byte *) pcx) + fsize - 768; + end = palette = ((byte *) pcx) + fsize - 768; dataByte = (byte *) &pcx[1]; count = (pcx->xmax + 1) * (pcx->ymax + 1); @@ -106,12 +107,12 @@ LoadPCX (QFile *f, qboolean convert, byte *pal) pix = tex->data; while (count) { - if (dataByte >= palette) + if (dataByte >= end) break; if ((*dataByte & 0xC0) == 0xC0) { runLength = *dataByte++ & 0x3F; - if (dataByte >= palette) + if (dataByte >= end) break; } else { runLength = 1; diff --git a/libs/video/renderer/gl/gl_rsurf.c b/libs/video/renderer/gl/gl_rsurf.c index 377a721b1..84b728449 100644 --- a/libs/video/renderer/gl/gl_rsurf.c +++ b/libs/video/renderer/gl/gl_rsurf.c @@ -68,7 +68,8 @@ instsurf_t **sky_chain_tail; #define CHAIN_SURF_F2B(surf,chain) \ do { \ instsurf_t *inst = (surf)->instsurf; \ - if (!inst) (surf)->tinst = inst = get_instsurf (); \ + if (__builtin_expect(!inst, 1)) \ + (surf)->tinst = inst = get_instsurf (); \ inst->surface = (surf); \ *(chain##_tail) = inst; \ (chain##_tail) = &inst->tex_chain; \ @@ -78,7 +79,8 @@ instsurf_t **sky_chain_tail; #define CHAIN_SURF_B2F(surf,chain) \ do { \ instsurf_t *inst = (surf)->instsurf; \ - if (!inst) (surf)->tinst = inst = get_instsurf (); \ + if (__builtin_expect(!inst, 1)) \ + (surf)->tinst = inst = get_instsurf (); \ inst->surface = (surf); \ inst->tex_chain = (chain); \ (chain) = inst; \ @@ -357,7 +359,7 @@ R_DrawWaterSurfaces (void) } } -static inline void +static void DrawTextureChains (int disable_blend, int do_bind) { int i; diff --git a/libs/video/renderer/sw/draw.c b/libs/video/renderer/sw/draw.c index 3f886e972..7af9c018d 100644 --- a/libs/video/renderer/sw/draw.c +++ b/libs/video/renderer/sw/draw.c @@ -73,6 +73,26 @@ typedef struct cachepic_s { cachepic_t cachepics[MAX_CACHED_PICS]; int numcachepics; +#define CLIP(x,y,w,h,mw,mh) \ + do { \ + if (y < 0) { \ + h += y; \ + y = 0; \ + } \ + if (y + h > mh) \ + h = mh - y; \ + if (h <= 0) \ + return; \ + if (x < 0) { \ + w += x; \ + x = 0; \ + } \ + if (x + w > mw) \ + w = mw - x; \ + if (w <= 0) \ + return; \ + } while (0) + VISIBLE qpic_t * Draw_PicFromWad (const char *name) @@ -362,7 +382,9 @@ Draw_Pic (int x, int y, qpic_t *pic) if (x < 0 || (unsigned int) (x + pic->width) > vid.conwidth || y < 0 || (unsigned int) (y + pic->height) > vid.conheight) { - Sys_Error ("Draw_Pic: bad coordinates"); + Sys_MaskPrintf (SYS_VID, "Draw_Pic: bad coordinates"); + Draw_SubPic (x, y, pic, 0, 0, pic->width, pic->height); + return; } source = pic->data; @@ -414,8 +436,29 @@ Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width, if ((x < 0) || (x + width > (int) vid.conwidth) || (y < 0) || (y + height > (int) vid.conheight)) { - Sys_Error ("Draw_SubPic: bad coordinates"); + Sys_MaskPrintf (SYS_VID, "Draw_SubPic: bad coordinates"); } + // first, clip to screen + if (x < 0) { + srcx += x; + width += x; + x = 0; + } + if (x + width > (int) vid.width) + width = vid.width - x; + if (width <= 0) + return; + if (y < 0) { + srcy += y; + height += y; + y = 0; + } + if (y + height > (int) vid.height) + height = vid.height - y; + if (height <= 0) + return; + // next, clip to pic + CLIP (srcx, srcy, width, height, pic->width, pic->height); source = pic->data + srcy * pic->width + srcx; @@ -531,7 +574,6 @@ R_DrawRect (vrect_t *prect, int rowbytes, byte * psrc, int transparent) } } - /* Draw_TileClear @@ -545,6 +587,8 @@ Draw_TileClear (int x, int y, int w, int h) byte *psrc; vrect_t vr; + CLIP (x, y, w, h, (int) vid.width, (int) vid.height); + r_rectdesc.rect.x = x; r_rectdesc.rect.y = y; r_rectdesc.rect.width = w; @@ -608,9 +652,10 @@ Draw_Fill (int x, int y, int w, int h, int c) if (x < 0 || x + w > (int) vid.conwidth || y < 0 || y + h > (int) vid.conheight) { - Sys_Printf ("Bad Draw_Fill(%d, %d, %d, %d, %c)\n", x, y, w, h, c); - return; + Sys_MaskPrintf (SYS_VID, "Bad Draw_Fill(%d, %d, %d, %d, %c)\n", + x, y, w, h, c); } + CLIP (x, y, w, h, (int) vid.width, (int) vid.height); dest = ((byte*)vid.buffer) + y * vid.rowbytes + x; for (v = 0; v < h; v++, dest += vid.rowbytes) diff --git a/libs/video/renderer/sw32/draw.c b/libs/video/renderer/sw32/draw.c index f6a6e23b9..b05cfca49 100644 --- a/libs/video/renderer/sw32/draw.c +++ b/libs/video/renderer/sw32/draw.c @@ -73,6 +73,26 @@ typedef struct cachepic_s { cachepic_t cachepics[MAX_CACHED_PICS]; int numcachepics; +#define CLIP(x,y,w,h,mw,mh) \ + do { \ + if (y < 0) { \ + h += y; \ + y = 0; \ + } \ + if (y + h > mh) \ + h = mh - y; \ + if (h <= 0) \ + return; \ + if (x < 0) { \ + w += x; \ + x = 0; \ + } \ + if (x + w > mw) \ + w = mw - x; \ + if (w <= 0) \ + return; \ + } while (0) + VISIBLE qpic_t * Draw_PicFromWad (const char *name) @@ -435,7 +455,9 @@ Draw_Pic (int x, int y, qpic_t *pic) if (x < 0 || (unsigned int) (x + pic->width) > vid.conwidth || y < 0 || (unsigned int) (y + pic->height) > vid.conheight) { - Sys_Error ("Draw_Pic: bad coordinates"); + Sys_MaskPrintf (SYS_VID, "Draw_Pic: bad coordinates"); + Draw_SubPic (x, y, pic, 0, 0, pic->width, pic->height); + return; } source = pic->data; @@ -527,8 +549,29 @@ Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width, if ((x < 0) || (x + width > (int) vid.conwidth) || (y < 0) || (y + height > (int) vid.conheight)) { - Sys_Error ("Draw_SubPic: bad coordinates"); + Sys_MaskPrintf (SYS_VID, "Draw_SubPic: bad coordinates"); } + // first, clip to screen + if (x < 0) { + srcx += x; + width += x; + x = 0; + } + if (x + width > (int) vid.width) + width = vid.width - x; + if (width <= 0) + return; + if (y < 0) { + srcy += y; + height += y; + y = 0; + } + if (y + height > (int) vid.height) + height = vid.height - y; + if (height <= 0) + return; + // next, clip to pic + CLIP (srcx, srcy, width, height, pic->width, pic->height); source = pic->data + srcy * pic->width + srcx; @@ -944,7 +987,6 @@ R_DrawRect (vrect_t *prect, int rowbytes, byte * psrc, int transparent) } } - /* Draw_TileClear @@ -958,6 +1000,8 @@ Draw_TileClear (int x, int y, int w, int h) byte *psrc; vrect_t vr; + CLIP (x, y, w, h, (int) vid.width, (int) vid.height); + r_rectdesc.rect.x = x; r_rectdesc.rect.y = y; r_rectdesc.rect.width = w; @@ -1020,9 +1064,10 @@ Draw_Fill (int x, int y, int w, int h, int c) if (x < 0 || x + w > (int) vid.conwidth || y < 0 || y + h > (int) vid.conheight) { - Sys_Printf ("Bad Draw_Fill(%d, %d, %d, %d, %c)\n", x, y, w, h, c); - return; + Sys_MaskPrintf (SYS_VID, "Bad Draw_Fill(%d, %d, %d, %d, %c)\n", + x, y, w, h, c); } + CLIP (x, y, w, h, (int) vid.width, (int) vid.height); switch (r_pixbytes) { case 1: diff --git a/libs/video/targets/in_sdl.c b/libs/video/targets/in_sdl.c index 08b72a470..117c5110b 100644 --- a/libs/video/targets/in_sdl.c +++ b/libs/video/targets/in_sdl.c @@ -49,7 +49,7 @@ static __attribute__ ((used)) const char rcsid[] = cvar_t *in_snd_block; static keydest_t old_key_dest = key_none; -static int have_focus; +static int have_focus = 1; static void diff --git a/tools/build_scripts/qf-win32.py b/tools/build_scripts/qf-win32.py index fa160b9e8..640942762 100755 --- a/tools/build_scripts/qf-win32.py +++ b/tools/build_scripts/qf-win32.py @@ -74,7 +74,6 @@ tools = [ dir + "bin/qfbsp.exe", dir + "bin/qflight.exe", dir + "bin/qfmodelgen.exe", - dir + "bin/qfprogs.exe", dir + "bin/qfvis.exe", dir + "bin/qfwavinfo.exe", dir + "bin/wad.exe", @@ -85,6 +84,7 @@ qfcc = [ dir, dir + "bin", dir + "bin/qfcc.exe", + dir + "bin/qfprogs.exe", dir + "bin/qfpreqcc", dir + "qfcc.1", dir + "qfcc.pc",