From bdffd88cf8584630d1e24363e75a969435af2809 Mon Sep 17 00:00:00 2001 From: havoc Date: Fri, 8 Nov 2002 23:26:54 +0000 Subject: [PATCH] Elric's changes: 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 --- darkplaces.dsp | 10 +- gl_rsurf.c | 2 +- gl_textures.c | 6 + image.c | 31 +++- jpeg.c | 462 +++++++++++++++++++++++++++++++++++++++++++++++++ jpeg.h | 33 ++++ makefile | 2 +- quakedef.h | 2 +- sys.h | 27 +++ sys_linux.c | 26 +++ sys_win.c | 25 +++ vid.h | 18 +- vid_glx.c | 4 +- vid_shared.c | 16 +- vid_wgl.c | 4 +- 15 files changed, 632 insertions(+), 36 deletions(-) create mode 100644 jpeg.c create mode 100644 jpeg.h diff --git a/darkplaces.dsp b/darkplaces.dsp index de49a844..5a08d7e0 100644 --- a/darkplaces.dsp +++ b/darkplaces.dsp @@ -16,7 +16,7 @@ CFG=darkplaces - Win32 Debug !MESSAGE NMAKE /f "darkplaces.mak" CFG="darkplaces - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "darkplaces - Win32 Release" (based on "Win32 (x86) Application") !MESSAGE "darkplaces - Win32 Debug" (based on "Win32 (x86) Application") !MESSAGE @@ -220,6 +220,10 @@ SOURCE=.\image.c # End Source File # Begin Source File +SOURCE=.\jpeg.c +# End Source File +# Begin Source File + SOURCE=.\keys.c # End Source File # Begin Source File @@ -524,6 +528,10 @@ SOURCE=.\input.h # End Source File # Begin Source File +SOURCE=.\jpeg.h +# End Source File +# Begin Source File + SOURCE=.\keys.h # End Source File # Begin Source File diff --git a/gl_rsurf.c b/gl_rsurf.c index 8bdb5db5..97589a2c 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -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]); } diff --git a/gl_textures.c b/gl_textures.c index 076f12da..8ad1278f 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -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 0abe8d04..2b17283d 100644 --- 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 index 00000000..ed9896dd --- /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 +#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 index 00000000..d9de27c5 --- /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 diff --git a/makefile b/makefile index 29e9b3ca..c0ac45ed 100644 --- 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 diff --git a/quakedef.h b/quakedef.h index dc1be096..ae27cfee 100644 --- a/quakedef.h +++ b/quakedef.h @@ -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 0c91f4d0..cc0ced45 100644 --- 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 +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 // diff --git a/sys_linux.c b/sys_linux.c index abe5a454..1e675e47 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -19,8 +19,34 @@ #include #include +#include + #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 // ======================================================================= diff --git a/sys_win.c b/sys_win.c index acd3c161..e5655b65 100644 --- 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 e892b80a..fffadd1e 100644 --- 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); diff --git a/vid_glx.c b/vid_glx.c index 22075cb4..a8a8407a 100644 --- 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}, diff --git a/vid_shared.c b/vid_shared.c index 6cf000ac..2b1b370c 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -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}, diff --git a/vid_wgl.c b/vid_wgl.c index f2c4f173..789f64d3 100644 --- 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} -- 2.39.2