Elric's changes:
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 8 Nov 2002 23:26:54 +0000 (23:26 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 8 Nov 2002 23:26:54 +0000 (23:26 +0000)
JPEG texture loading using libjpeg (entirely optional at runtime - if not present, it won't load it)
gl_extensionfunctionlist_t is now renamed dllfunction_t and part of a shared system for library opening/function retrieval (functions Sys_LoadLibrary, Sys_GetProcAddress, Sys_UnloadLibrary - for this the library handles are considered void *'s)
LordHavoc's changes:
fixed libjpeg support in non-win32 by using jpeglib.h - honors jpeglib.h's idea of boolean - Linux libjpeg is compiled with boolean as int, unlike windows where it is apparently byte - unfortunately this also means you need libjpeg-devel installed to compile it in non-win32, not sure what can be done about this (but most people seem to have that anyway...)
looks for libjpeg.so.62 instead of libjpeg.so

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2610 d7cf8633-e32d-0410-b094-e92efae38249

15 files changed:
darkplaces.dsp
gl_rsurf.c
gl_textures.c
image.c
jpeg.c [new file with mode: 0644]
jpeg.h [new file with mode: 0644]
makefile
quakedef.h
sys.h
sys_linux.c
sys_win.c
vid.h
vid_glx.c
vid_shared.c
vid_wgl.c

index de49a84..5a08d7e 100644 (file)
@@ -16,7 +16,7 @@ CFG=darkplaces - Win32 Debug
 !MESSAGE NMAKE /f "darkplaces.mak" CFG="darkplaces - Win32 Debug"\r
 !MESSAGE \r
 !MESSAGE Possible choices for configuration are:\r
-!MESSAGE \r
+!MESSAGE\r
 !MESSAGE "darkplaces - Win32 Release" (based on "Win32 (x86) Application")\r
 !MESSAGE "darkplaces - Win32 Debug" (based on "Win32 (x86) Application")\r
 !MESSAGE \r
@@ -220,6 +220,10 @@ SOURCE=.\image.c
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\jpeg.c\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\keys.c\r
 # End Source File\r
 # Begin Source File\r
@@ -524,6 +528,10 @@ SOURCE=.\input.h
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\jpeg.h\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\keys.h\r
 # End Source File\r
 # Begin Source File\r
index 8bdb5db..97589a2 100644 (file)
@@ -1494,7 +1494,7 @@ void R_DrawSurfaces(entity_render_t *ent, int type)
        texture_t *t;
        R_Mesh_Matrix(&ent->matrix);
        for (i = 0, t = ent->model->textures;i < ent->model->numtextures;i++, t++)
-               if (t->shader->shaderfunc[type] && ent->model->texturesurfacechains[i])
+               if (t->shader->shaderfunc[type] && t->currentframe && ent->model->texturesurfacechains[i])
                        t->shader->shaderfunc[type](ent, t->currentframe, ent->model->texturesurfacechains[i]);
 }
 
index 076f12d..8ad1278 100644 (file)
@@ -1,6 +1,7 @@
 
 #include "quakedef.h"
 #include "image.h"
+#include "jpeg.h"
 
 cvar_t r_max_size = {CVAR_SAVE, "r_max_size", "2048"};
 cvar_t r_max_scrapsize = {CVAR_SAVE, "r_max_scrapsize", "256"};
@@ -476,11 +477,16 @@ static void r_textures_start(void)
        texturemempool = Mem_AllocPool("Texture Info");
        texturedatamempool = Mem_AllocPool("Texture Storage (not yet uploaded)");
        textureprocessingmempool = Mem_AllocPool("Texture Processing Buffers");
+
+       JPEG_OpenLibrary ();
 }
 
 static void r_textures_shutdown(void)
 {
        rtexturepool_t *temp;
+
+       JPEG_CloseLibrary ();
+
        while(gltexturepoolchain)
        {
                temp = (rtexturepool_t *) gltexturepoolchain;
diff --git a/image.c b/image.c
index 0abe8d0..2b17283 100644 (file)
--- a/image.c
+++ b/image.c
@@ -1,6 +1,7 @@
 
 #include "quakedef.h"
 #include "image.h"
+#include "jpeg.h"
 
 int            image_width;
 int            image_height;
@@ -541,8 +542,8 @@ void Image_StripImageExtension (const char *in, char *out)
 qbyte *loadimagepixels (const char *filename, qboolean complain, int matchwidth, int matchheight)
 {
        qbyte *f, *data;
-       char basename[256], name[256], *c;
-       Image_StripImageExtension(filename, basename); // strip .tga, .pcx and .lmp extensions to allow replacement by other types
+       char basename[MAX_QPATH], name[MAX_QPATH], *c;
+       Image_StripImageExtension(filename, basename); // strip filename extensions to allow replacement by other types
        // replace *'s with #, so commandline utils don't get confused when dealing with the external files
        for (c = basename;*c;c++)
                if (*c == '*')
@@ -555,6 +556,14 @@ qbyte *loadimagepixels (const char *filename, qboolean complain, int matchwidth,
                Mem_Free(f);
                return data;
        }
+       sprintf (name, "override/%s.jpg", basename);
+       f = COM_LoadFile(name, true);
+       if (f)
+       {
+               data = JPEG_LoadImage (f, matchwidth, matchheight);
+               Mem_Free(f);
+               return data;
+       }
        sprintf (name, "textures/%s.tga", basename);
        f = COM_LoadFile(name, true);
        if (f)
@@ -563,6 +572,14 @@ qbyte *loadimagepixels (const char *filename, qboolean complain, int matchwidth,
                Mem_Free(f);
                return data;
        }
+       sprintf (name, "textures/%s.jpg", basename);
+       f = COM_LoadFile(name, true);
+       if (f)
+       {
+               data = JPEG_LoadImage (f, matchwidth, matchheight);
+               Mem_Free(f);
+               return data;
+       }
        sprintf (name, "textures/%s.pcx", basename);
        f = COM_LoadFile(name, true);
        if (f)
@@ -579,6 +596,14 @@ qbyte *loadimagepixels (const char *filename, qboolean complain, int matchwidth,
                Mem_Free(f);
                return data;
        }
+       sprintf (name, "%s.jpg", basename);
+       f = COM_LoadFile(name, true);
+       if (f)
+       {
+               data = JPEG_LoadImage (f, matchwidth, matchheight);
+               Mem_Free(f);
+               return data;
+       }
        sprintf (name, "%s.pcx", basename);
        f = COM_LoadFile(name, true);
        if (f)
@@ -596,7 +621,7 @@ qbyte *loadimagepixels (const char *filename, qboolean complain, int matchwidth,
                return data;
        }
        if (complain)
-               Con_Printf ("Couldn't load %s.tga, .pcx, .lmp\n", filename);
+               Con_Printf ("Couldn't load %s.tga, .jpg, .pcx, .lmp\n", filename);
        return NULL;
 }
 
diff --git a/jpeg.c b/jpeg.c
new file mode 100644 (file)
index 0000000..ed9896d
--- /dev/null
+++ b/jpeg.c
@@ -0,0 +1,462 @@
+/*
+       Copyright (C) 2002  Mathieu Olivier
+
+       This program is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License
+       as published by the Free Software Foundation; either version 2
+       of the License, or (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+       See the GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to:
+
+               Free Software Foundation, Inc.
+               59 Temple Place - Suite 330
+               Boston, MA  02111-1307, USA
+
+*/
+
+
+#include "quakedef.h"
+#include "jpeg.h"
+
+// LordHavoc: Elric's jpeg structs conflict with Linux ones (mainly on the definition of boolean being qbyte instead of int)
+#ifdef WIN32
+typedef qbyte boolean;
+/*
+=================================================================
+
+  Minimal set of definitions from the JPEG lib
+
+  WARNING: for a matter of simplicity, several pointer types are
+  casted to "void*", and most enumerated values are not included
+
+=================================================================
+*/
+
+#define JPEG_LIB_VERSION  62  // Version 6b
+
+typedef void *j_common_ptr;
+typedef struct jpeg_decompress_struct *j_decompress_ptr;
+typedef enum {JPEG_DUMMY1} J_COLOR_SPACE;
+typedef enum {JPEG_DUMMY2} J_DCT_METHOD;
+typedef enum {JPEG_DUMMY3} J_DITHER_MODE;
+typedef unsigned int JDIMENSION;
+
+#define JPOOL_PERMANENT 0
+
+#define JPEG_EOI       0xD9  // EOI marker code
+
+#define JMSG_STR_PARM_MAX  80
+
+#define DCTSIZE2 64
+#define NUM_QUANT_TBLS 4
+#define NUM_HUFF_TBLS 4
+#define NUM_ARITH_TBLS 16
+#define MAX_COMPS_IN_SCAN 4
+#define D_MAX_BLOCKS_IN_MCU 10
+
+struct jpeg_memory_mgr
+{
+  void* (*alloc_small) (j_common_ptr cinfo, int pool_id, size_t sizeofobject);
+  void (*alloc_large) ();
+  void (*alloc_sarray) ();
+  void (*alloc_barray) ();
+  void (*request_virt_sarray) ();
+  void (*request_virt_barray) ();
+  void (*realize_virt_arrays) ();
+  void (*access_virt_sarray) ();
+  void (*access_virt_barray) ();
+  void (*free_pool) ();
+  void (*self_destruct) ();
+
+  long max_memory_to_use;
+  long max_alloc_chunk;
+};
+
+struct jpeg_error_mgr
+{
+       void (*error_exit) (j_common_ptr cinfo);
+       void (*emit_message) (j_common_ptr cinfo, int msg_level);
+       void (*output_message) (j_common_ptr cinfo);
+       void (*format_message) (j_common_ptr cinfo, char * buffer);
+       void (*reset_error_mgr) (j_common_ptr cinfo);
+       int msg_code;
+       union {
+               int i[8];
+               char s[JMSG_STR_PARM_MAX];
+       } msg_parm;
+       int trace_level;
+       long num_warnings;
+       const char * const * jpeg_message_table;
+       int last_jpeg_message;
+       const char * const * addon_message_table;
+       int first_addon_message;
+       int last_addon_message;
+};
+
+struct jpeg_source_mgr
+{
+       const qbyte *next_input_byte;
+       size_t bytes_in_buffer;
+
+       void (*init_source) (j_decompress_ptr cinfo);
+       qbyte (*fill_input_buffer) (j_decompress_ptr cinfo);
+       void (*skip_input_data) (j_decompress_ptr cinfo, long num_bytes);
+       qbyte (*resync_to_restart) (j_decompress_ptr cinfo, int desired);
+       void (*term_source) (j_decompress_ptr cinfo);
+};
+
+struct jpeg_decompress_struct
+{
+       struct jpeg_error_mgr *err;             // USED
+       struct jpeg_memory_mgr *mem;    // USED
+
+       void *progress;
+       void *client_data;
+       qbyte is_decompressor;
+       int global_state;
+
+       struct jpeg_source_mgr *src;    // USED
+       JDIMENSION image_width;                 // USED
+       JDIMENSION image_height;                // USED
+
+       int num_components;
+       J_COLOR_SPACE jpeg_color_space;
+       J_COLOR_SPACE out_color_space;
+       unsigned int scale_num, scale_denom;
+       double output_gamma;
+       qbyte buffered_image;
+       qbyte raw_data_out;
+       J_DCT_METHOD dct_method;
+       qbyte do_fancy_upsampling;
+       qbyte do_block_smoothing;
+       qbyte quantize_colors;
+       J_DITHER_MODE dither_mode;
+       qbyte two_pass_quantize;
+       int desired_number_of_colors;
+       qbyte enable_1pass_quant;
+       qbyte enable_external_quant;
+       qbyte enable_2pass_quant;
+       JDIMENSION output_width;
+
+       JDIMENSION output_height;       // USED
+
+       int out_color_components;
+
+       int output_components;          // USED
+
+       int rec_outbuf_height;
+       int actual_number_of_colors;
+       void *colormap;
+
+       JDIMENSION output_scanline;     // USED
+
+       int input_scan_number;
+       JDIMENSION input_iMCU_row;
+       int output_scan_number;
+       JDIMENSION output_iMCU_row;
+       int (*coef_bits)[DCTSIZE2];
+       void *quant_tbl_ptrs[NUM_QUANT_TBLS];
+       void *dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+       void *ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+       int data_precision;
+       void *comp_info;
+       qbyte progressive_mode;
+       qbyte arith_code;
+       qbyte arith_dc_L[NUM_ARITH_TBLS];
+       qbyte arith_dc_U[NUM_ARITH_TBLS];
+       qbyte arith_ac_K[NUM_ARITH_TBLS];
+       unsigned int restart_interval;
+       qbyte saw_JFIF_marker;
+       qbyte JFIF_major_version;
+       qbyte JFIF_minor_version;
+       qbyte density_unit;
+       unsigned short X_density;
+       unsigned short Y_density;
+       qbyte saw_Adobe_marker;
+       qbyte Adobe_transform;
+       qbyte CCIR601_sampling;
+       void *marker_list;
+       int max_h_samp_factor;
+       int max_v_samp_factor;
+       int min_DCT_scaled_size;
+       JDIMENSION total_iMCU_rows;
+       void *sample_range_limit;
+       int comps_in_scan;
+       void *cur_comp_info[MAX_COMPS_IN_SCAN];
+       JDIMENSION MCUs_per_row;
+       JDIMENSION MCU_rows_in_scan;
+       int blocks_in_MCU;
+       int MCU_membership[D_MAX_BLOCKS_IN_MCU];
+       int Ss, Se, Ah, Al;
+       int unread_marker;
+       void *master;
+       void *main;
+       void *coef;
+       void *post;
+       void *inputctl;
+       void *marker;
+       void *entropy;
+       void *idct;
+       void *upsample;
+       void *cconvert;
+       void *cquantize;
+};
+#else
+#include <jpeglib.h>
+#endif
+
+
+/*
+=================================================================
+
+  DarkPlaces definitions
+
+=================================================================
+*/
+
+// Functions exported from libjpeg
+static void (*qjpeg_CreateDecompress) (j_decompress_ptr cinfo, int version, size_t structsize);
+static void (*qjpeg_destroy_decompress) (j_decompress_ptr cinfo);
+static boolean (*qjpeg_finish_decompress) (j_decompress_ptr cinfo);
+static boolean (*qjpeg_resync_to_restart) (j_decompress_ptr cinfo, int desired);
+static int (*qjpeg_read_header) (j_decompress_ptr cinfo, qbyte require_image);
+static JDIMENSION (*qjpeg_read_scanlines) (j_decompress_ptr cinfo, qbyte** scanlines, JDIMENSION max_lines);
+static boolean (*qjpeg_start_decompress) (j_decompress_ptr cinfo);
+static struct jpeg_error_mgr* (*qjpeg_std_error) (struct jpeg_error_mgr *err);
+
+static dllfunction_t jpegfuncs[] =
+{
+       {"jpeg_CreateDecompress",       (void **) &qjpeg_CreateDecompress},
+       {"jpeg_destroy_decompress",     (void **) &qjpeg_destroy_decompress},
+       {"jpeg_finish_decompress",      (void **) &qjpeg_finish_decompress},
+       {"jpeg_resync_to_restart",      (void **) &qjpeg_resync_to_restart},
+       {"jpeg_read_header",            (void **) &qjpeg_read_header},
+       {"jpeg_read_scanlines",         (void **) &qjpeg_read_scanlines},
+       {"jpeg_start_decompress",       (void **) &qjpeg_start_decompress},
+       {"jpeg_std_error",                      (void **) &qjpeg_std_error},
+       {NULL, NULL}
+};
+
+// Handle for JPEG DLL
+static dllhandle_t jpeg_dll = NULL;
+
+
+/*
+=================================================================
+
+  DLL load & unload
+
+=================================================================
+*/
+
+/*
+====================
+JPEG_OpenLibrary
+
+Try to load the JPEG DLL
+====================
+*/
+qboolean JPEG_OpenLibrary (void)
+{
+       const char* dllname;
+       const dllfunction_t *func;
+
+       // Already loaded?
+       if (jpeg_dll)
+               return true;
+
+#ifdef WIN32
+       dllname = "libjpeg.dll";
+#else
+       dllname = "libjpeg.so.62";
+#endif
+
+       // Initializations
+       for (func = jpegfuncs; func && func->name != NULL; func++)
+               *func->funcvariable = NULL;
+
+       // Load the DLL
+       if (! (jpeg_dll = Sys_LoadLibrary (dllname)))
+       {
+               Con_Printf("Can't find %s. JPEG support disabled\n", dllname);
+               return false;
+       }
+
+       // Get the function adresses
+       for (func = jpegfuncs; func && func->name != NULL; func++)
+               if (!(*func->funcvariable = (void *) Sys_GetProcAddress (jpeg_dll, func->name)))
+               {
+                       Con_Printf("missing function \"%s\" - broken JPEG library!\n", func->name);
+                       JPEG_CloseLibrary ();
+                       return false;
+               }
+
+       return true;
+}
+
+
+/*
+====================
+JPEG_CloseLibrary
+
+Unload the JPEG DLL
+====================
+*/
+void JPEG_CloseLibrary (void)
+{
+       if (!jpeg_dll)
+               return;
+
+       Sys_UnloadLibrary (jpeg_dll);
+       jpeg_dll = NULL;
+}
+
+
+/*
+=================================================================
+
+  Functions for handling JPEG images
+
+=================================================================
+*/
+
+static qbyte jpeg_eoi_marker [2] = {0xFF, JPEG_EOI};
+
+static void JPEG_Noop (j_decompress_ptr cinfo) {}
+
+static boolean JPEG_FillInputBuffer (j_decompress_ptr cinfo)
+{
+    // Insert a fake EOI marker
+    cinfo->src->next_input_byte = jpeg_eoi_marker;
+    cinfo->src->bytes_in_buffer = 2;
+
+       return TRUE;
+}
+
+static void JPEG_SkipInputData (j_decompress_ptr cinfo, long num_bytes)
+{
+    if (cinfo->src->bytes_in_buffer <= (unsigned long)num_bytes)
+       {
+               cinfo->src->bytes_in_buffer = 0;
+               return;
+       }
+
+    cinfo->src->next_input_byte += num_bytes;
+    cinfo->src->bytes_in_buffer -= num_bytes;
+}
+
+static void JPEG_MemSrc (j_decompress_ptr cinfo, qbyte *buffer)
+{
+       cinfo->src = (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof (struct jpeg_source_mgr));
+
+       cinfo->src->next_input_byte = buffer;
+       cinfo->src->bytes_in_buffer = com_filesize;
+
+       cinfo->src->init_source = JPEG_Noop;
+       cinfo->src->fill_input_buffer = JPEG_FillInputBuffer;
+       cinfo->src->skip_input_data = JPEG_SkipInputData;
+       cinfo->src->resync_to_restart = qjpeg_resync_to_restart; // use the default method
+       cinfo->src->term_source = JPEG_Noop;
+}
+
+
+/*
+====================
+JPEG_LoadImage
+
+Load a JPEG image into a RGBA buffer
+====================
+*/
+qbyte* JPEG_LoadImage (qbyte *f, int matchwidth, int matchheight)
+{
+       struct jpeg_decompress_struct cinfo;
+       struct jpeg_error_mgr jerr;
+       qbyte *image_rgba, *scanline;
+       unsigned int line;
+
+       // No DLL = no JPEGs
+       if (!jpeg_dll)
+               return NULL;
+
+       cinfo.err = qjpeg_std_error (&jerr);
+       qjpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, (size_t) sizeof(struct jpeg_decompress_struct));
+       JPEG_MemSrc (&cinfo, f);
+       qjpeg_read_header (&cinfo, TRUE);
+       qjpeg_start_decompress (&cinfo);
+
+       image_width = cinfo.image_width;
+       image_height = cinfo.image_height;
+
+       if ((matchwidth && image_width != matchwidth) || (matchheight && image_height != matchheight))
+       {
+               qjpeg_finish_decompress (&cinfo);
+               qjpeg_destroy_decompress (&cinfo);
+               return NULL;
+       }
+
+       image_rgba = Mem_Alloc(tempmempool, image_width * image_height * 4);
+       scanline = Mem_Alloc(tempmempool, image_width * cinfo.output_components);
+       if (!image_rgba || !scanline)
+       {
+               if (!image_rgba)
+                       Mem_Free (image_rgba);
+
+               Con_Printf("JPEG_LoadImage: not enough memory for %i by %i image\n", image_width, image_height);
+               qjpeg_finish_decompress (&cinfo);
+               qjpeg_destroy_decompress (&cinfo);
+               return NULL;
+       }
+
+       // Decompress the image, line by line
+       line = 0;
+       while (cinfo.output_scanline < cinfo.output_height)
+       {
+               qbyte *buffer_ptr;
+               int ind;
+
+               qjpeg_read_scanlines (&cinfo, &scanline, 1);
+
+               // Convert the image to RGBA
+               switch (cinfo.output_components)
+               {
+                       // RGB images
+                       case 3:
+                               buffer_ptr = &image_rgba[image_width * line * 4];
+                               for (ind = 0; ind < image_width * 3; ind += 3, buffer_ptr += 4)
+                               {
+                                       buffer_ptr[0] = scanline[ind];
+                                       buffer_ptr[1] = scanline[ind + 1];
+                                       buffer_ptr[2] = scanline[ind + 2];
+                                       buffer_ptr[3] = 255;
+                               }
+                               break;
+
+                       // Greyscale images (default to it, just in case)
+                       case 1:
+                       default:
+                               buffer_ptr = &image_rgba[image_width * line * 4];
+                               for (ind = 0; ind < image_width; ind++, buffer_ptr += 4)
+                               {
+                                       buffer_ptr[0] = scanline[ind];
+                                       buffer_ptr[1] = scanline[ind];
+                                       buffer_ptr[2] = scanline[ind];
+                                       buffer_ptr[3] = 255;
+                               }
+               }
+
+               line++;
+       }
+       Mem_Free (scanline);
+
+       qjpeg_finish_decompress (&cinfo);
+       qjpeg_destroy_decompress (&cinfo);
+
+       return image_rgba;
+}
diff --git a/jpeg.h b/jpeg.h
new file mode 100644 (file)
index 0000000..d9de27c
--- /dev/null
+++ b/jpeg.h
@@ -0,0 +1,33 @@
+/*
+       Copyright (C) 2002  Mathieu Olivier
+
+       This program is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License
+       as published by the Free Software Foundation; either version 2
+       of the License, or (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+       See the GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to:
+
+               Free Software Foundation, Inc.
+               59 Temple Place - Suite 330
+               Boston, MA  02111-1307, USA
+
+*/
+
+#ifndef JPEG_H
+#define JPEG_H
+
+
+qboolean JPEG_OpenLibrary (void);
+void JPEG_CloseLibrary (void);
+qbyte* JPEG_LoadImage (qbyte *f, int matchwidth, int matchheight);
+
+
+#endif
index 29e9b3c..c0ac45e 100644 (file)
--- a/makefile
+++ b/makefile
@@ -40,7 +40,7 @@ CLIENTOBJECTS=        cgame.o cgamevm.o chase.o cl_collision.o cl_demo.o cl_input.o \
                cl_main.o cl_parse.o cl_particles.o cl_screen.o cl_video.o \
                console.o dpvsimpledecode.o fractalnoise.o gl_backend.o \
                gl_draw.o gl_models.o gl_rmain.o gl_rsurf.o gl_textures.o \
-               keys.o menu.o meshqueue.o r_crosshairs.o r_explosion.o \
+               jpeg.o keys.o menu.o meshqueue.o r_crosshairs.o r_explosion.o \
                r_explosion.o r_lerpanim.o r_light.o r_modules.o r_sky.o \
                r_sprites.o sbar.o ui.o vid_shared.o view.o wavefile.o \
                r_shadow.c
index dc1be09..ae27cfe 100644 (file)
@@ -161,8 +161,8 @@ extern char *buildstring;
 #include "common.h"
 #include "cvar.h"
 #include "bspfile.h"
-#include "vid.h"
 #include "sys.h"
+#include "vid.h"
 #include "mathlib.h"
 
 #include "r_textures.h"
diff --git a/sys.h b/sys.h
index 0c91f4d..cc0ced4 100644 (file)
--- a/sys.h
+++ b/sys.h
@@ -22,6 +22,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #ifndef SYS_H
 #define SYS_H
 
+
+//
+// DLL management
+//
+
+// Win32 specific
+#ifdef WIN32
+# include <windows.h>
+typedef HMODULE dllhandle_t;
+
+// Other platforms
+#else
+  typedef void* dllhandle_t;
+#endif
+
+typedef struct
+{
+       const char *name;
+       void **funcvariable;
+}
+dllfunction_t;
+
+dllhandle_t Sys_LoadLibrary (const char* name);
+void Sys_UnloadLibrary (dllhandle_t handle);
+void* Sys_GetProcAddress (dllhandle_t handle, const char* name);
+
+
 //
 // file IO
 //
index abe5a45..1e675e4 100644 (file)
 #include <errno.h>
 #include <time.h>
 
+#include <dlfcn.h>
+
 #include "quakedef.h"
 
+/*
+===============================================================================
+
+DLL MANAGEMENT
+
+===============================================================================
+*/
+
+dllhandle_t Sys_LoadLibrary (const char* name)
+{
+       return dlopen (name, RTLD_LAZY);
+}
+
+void Sys_UnloadLibrary (dllhandle_t handle)
+{
+       dlclose (handle);
+}
+
+void* Sys_GetProcAddress (dllhandle_t handle, const char* name)
+{
+       return (void *)dlsym (handle, name);
+}
+
+
 // =======================================================================
 // General routines
 // =======================================================================
index acd3c16..e5655b6 100644 (file)
--- a/sys_win.c
+++ b/sys_win.c
@@ -45,6 +45,31 @@ static HANDLE        hFile;
 static HANDLE  heventParent;
 static HANDLE  heventChild;
 
+
+/*
+===============================================================================
+
+DLL MANAGEMENT
+
+===============================================================================
+*/
+
+dllhandle_t Sys_LoadLibrary (const char* name)
+{
+       return LoadLibrary (name);
+}
+
+void Sys_UnloadLibrary (dllhandle_t handle)
+{
+       FreeLibrary (handle);
+}
+
+void* Sys_GetProcAddress (dllhandle_t handle, const char* name)
+{
+       return (void *)GetProcAddress (handle, name);
+}
+
+
 /*
 ===============================================================================
 
diff --git a/vid.h b/vid.h
index e892b80..fffadd1 100644 (file)
--- a/vid.h
+++ b/vid.h
@@ -76,26 +76,10 @@ extern qboolean isRagePro;
 // LordHavoc: GLX_SGI_video_sync and WGL_EXT_swap_control
 extern int gl_videosyncavailable;
 
-typedef struct
-{
-       const char *name;
-       void **funcvariable;
-}
-gl_extensionfunctionlist_t;
-
-typedef struct
-{
-       const char *name;
-       const gl_extensionfunctionlist_t *funcs;
-       int *enablevariable;
-       const char *disableparm;
-}
-gl_extensioninfo_t;
-
 int GL_OpenLibrary(const char *name);
 void GL_CloseLibrary(void);
 void *GL_GetProcAddress(const char *name);
-int GL_CheckExtension(const char *name, const gl_extensionfunctionlist_t *funcs, const char *disableparm, int silent);
+int GL_CheckExtension(const char *name, const dllfunction_t *funcs, const char *disableparm, int silent);
 
 void VID_Shared_Init(void);
 
index 22075cb..a8a8407 100644 (file)
--- a/vid_glx.c
+++ b/vid_glx.c
@@ -53,7 +53,7 @@ const char *(GLAPIENTRY *qglXQueryExtensionsString)(Display *dpy, int screen);
 //GLX_ARB_get_proc_address
 void *(GLAPIENTRY *qglXGetProcAddressARB)(const GLubyte *procName);
 
-static gl_extensionfunctionlist_t getprocaddressfuncs[] =
+static dllfunction_t getprocaddressfuncs[] =
 {
        {"glXGetProcAddressARB", (void **) &qglXGetProcAddressARB},
        {NULL, NULL}
@@ -63,7 +63,7 @@ static gl_extensionfunctionlist_t getprocaddressfuncs[] =
 GLint (GLAPIENTRY *qglXGetVideoSyncSGI)(GLuint *count);
 GLint (GLAPIENTRY *qglXWaitVideoSyncSGI)(int divisor, int remainder, unsigned int *count);
 
-static gl_extensionfunctionlist_t videosyncfuncs[] =
+static dllfunction_t videosyncfuncs[] =
 {
        {"glXGetVideoSyncSGI", (void **) &qglXGetVideoSyncSGI},
        {"glXWaitVideoSyncSGI", (void **) &qglXWaitVideoSyncSGI},
index 6cf000a..2b1b370 100644 (file)
@@ -183,10 +183,10 @@ void (GLAPIENTRY *qglScissor)(GLint x, GLint y, GLsizei width, GLsizei height);
 
 void (GLAPIENTRY *qglPolygonOffset)(GLfloat factor, GLfloat units);
 
-int GL_CheckExtension(const char *name, const gl_extensionfunctionlist_t *funcs, const char *disableparm, int silent)
+int GL_CheckExtension(const char *name, const dllfunction_t *funcs, const char *disableparm, int silent)
 {
        int failed = false;
-       const gl_extensionfunctionlist_t *func;
+       const dllfunction_t *func;
 
        Con_Printf("checking for %s...  ", name);
 
@@ -224,7 +224,7 @@ int GL_CheckExtension(const char *name, const gl_extensionfunctionlist_t *funcs,
        }
 }
 
-static gl_extensionfunctionlist_t opengl110funcs[] =
+static dllfunction_t opengl110funcs[] =
 {
        {"glClearColor", (void **) &qglClearColor},
        {"glClear", (void **) &qglClear},
@@ -311,19 +311,19 @@ static gl_extensionfunctionlist_t opengl110funcs[] =
        {NULL, NULL}
 };
 
-static gl_extensionfunctionlist_t drawrangeelementsfuncs[] =
+static dllfunction_t drawrangeelementsfuncs[] =
 {
        {"glDrawRangeElements", (void **) &qglDrawRangeElements},
        {NULL, NULL}
 };
 
-static gl_extensionfunctionlist_t drawrangeelementsextfuncs[] =
+static dllfunction_t drawrangeelementsextfuncs[] =
 {
        {"glDrawRangeElementsEXT", (void **) &qglDrawRangeElementsEXT},
        {NULL, NULL}
 };
 
-static gl_extensionfunctionlist_t multitexturefuncs[] =
+static dllfunction_t multitexturefuncs[] =
 {
        {"glMultiTexCoord2fARB", (void **) &qglMultiTexCoord2f},
        {"glActiveTextureARB", (void **) &qglActiveTexture},
@@ -331,14 +331,14 @@ static gl_extensionfunctionlist_t multitexturefuncs[] =
        {NULL, NULL}
 };
 
-static gl_extensionfunctionlist_t compiledvertexarrayfuncs[] =
+static dllfunction_t compiledvertexarrayfuncs[] =
 {
        {"glLockArraysEXT", (void **) &qglLockArraysEXT},
        {"glUnlockArraysEXT", (void **) &qglUnlockArraysEXT},
        {NULL, NULL}
 };
 
-static gl_extensionfunctionlist_t texture3dextfuncs[] =
+static dllfunction_t texture3dextfuncs[] =
 {
        {"glTexImage3DEXT", (void **) &qglTexImage3D},
        {"glTexSubImage3DEXT", (void **) &qglTexSubImage3D},
index f2c4f17..789f64d 100644 (file)
--- a/vid_wgl.c
+++ b/vid_wgl.c
@@ -40,7 +40,7 @@ BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC);
 BOOL (WINAPI *qwglSwapIntervalEXT)(int interval);
 const char *(WINAPI *qwglGetExtensionsStringARB)(HDC hdc);
 
-static gl_extensionfunctionlist_t wglfuncs[] =
+static dllfunction_t wglfuncs[] =
 {
        {"wglChoosePixelFormat", (void **) &qwglChoosePixelFormat},
        {"wglDescribePixelFormat", (void **) &qwglDescribePixelFormat},
@@ -56,7 +56,7 @@ static gl_extensionfunctionlist_t wglfuncs[] =
        {NULL, NULL}
 };
 
-static gl_extensionfunctionlist_t wglswapintervalfuncs[] =
+static dllfunction_t wglswapintervalfuncs[] =
 {
        {"wglSwapIntervalEXT", (void **) &qwglSwapIntervalEXT},
        {NULL, NULL}