1
Description: Allow to replace patented S3TC algorithm with compatible txc_dxtn
2
Origin: upstream, https://bitbucket.org/richard42/mupen64plus-video-glide64mk2/commits/0ea303a31ffd757110a69b9c6213dacdedff13c2/
3
Author: Sven Eckelmann <sven@narfation.org>
6
diff --git a/projects/unix/Makefile b/projects/unix/Makefile
7
index fe15b081981349b73427fe860e824a82fc912470..59840c13d50d15ae18a6f61b0ac3f13abaf1e38d 100644
8
--- a/projects/unix/Makefile
9
+++ b/projects/unix/Makefile
10
@@ -219,7 +219,6 @@ endif
11
CFLAGS += $(LIBPNG_CFLAGS)
12
LDLIBS += $(LIBPNG_LDLIBS)
15
# search for OpenGL libraries
17
GL_LDLIBS = -framework OpenGL
18
@@ -370,12 +369,17 @@ SOURCE += \
19
$(SRCDIR)/GlideHQ/TxReSample.cpp \
20
$(SRCDIR)/GlideHQ/TxDbg.cpp \
21
$(SRCDIR)/GlideHQ/tc-1.1+/fxt1.c \
22
- $(SRCDIR)/GlideHQ/tc-1.1+/dxtn.c \
23
$(SRCDIR)/GlideHQ/tc-1.1+/wrapper.c \
24
$(SRCDIR)/GlideHQ/tc-1.1+/texstore.c
26
CPPFLAGS += -DTEXTURE_FILTER # -DDUMP_CACHE
27
LDLIBS += -lboost_filesystem$(BOOST_SUFFIX) -lboost_system$(BOOST_SUFFIX)
29
+ ifeq ($(TXCDXTN), 1)
30
+ CPPFLAGS += -DTXCDXTN_EXTERNAL
32
+ SOURCE += $(SRCDIR)/GlideHQ/tc-1.1+/dxtn.c
37
@@ -412,6 +416,7 @@ targets:
38
@echo " PIC=(1|0) == Force enable/disable of position independent code"
39
@echo " POSTFIX=name == String added to the name of the the build (default: '')"
40
@echo " HIRES=(1|0) == Enables/Disables support for hires textures and texture filters (default: 1)"
41
+ @echo " TXCDXTN=(1|0) == Enable/Disable external txc_dxtn library (default: 0)"
42
@echo " Install Options:"
43
@echo " PREFIX=path == install/uninstall prefix (default: /usr/local)"
44
@echo " SHAREDIR=path == path to install shared data files (default: PREFIX/share/mupen64plus)"
45
diff --git a/src/Glide64/m64p.h b/src/Glide64/m64p.h
46
index 3f47cf6a10c82ebaa9b0e4f2b30d2deecfb36735..dd6e89170dad08249e176fd66c176f30c767e35c 100755
47
--- a/src/Glide64/m64p.h
48
+++ b/src/Glide64/m64p.h
50
#define CONFIG_API_VERSION 0x020000
51
#define VIDEXT_API_VERSION 0x030000
56
void WriteLog(m64p_msg_level level, const char *msg, ...);
61
//The Glide API originally used an integer to pick an enumerated resolution.
62
//To accomodate arbitrary resolutions, pack it into a 32-bit struct
63
diff --git a/src/Glide64/osal_dynamiclib.h b/src/Glide64/osal_dynamiclib.h
64
index c24377b178e0cebd91b181a408dde34b2d6339f7..7be0cab272df0715eb578fc14a3b994474a59bfc 100755
65
--- a/src/Glide64/osal_dynamiclib.h
66
+++ b/src/Glide64/osal_dynamiclib.h
68
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
69
- * Mupen64plus-core - osal/dynamiclib.h *
70
+ * Mupen64plus-video-glide64mk2 - osal_dynamiclib.h *
71
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
72
* Copyright (C) 2009 Richard Goedeken *
75
#if !defined(OSAL_DYNAMICLIB_H)
76
#define OSAL_DYNAMICLIB_H
78
+#include "m64p_types.h"
84
-#include "m64p_types.h"
85
+m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath);
87
void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName);
89
+m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle);
94
diff --git a/src/Glide64/osal_dynamiclib_unix.c b/src/Glide64/osal_dynamiclib_unix.c
95
index b3b7ba52dc690d42dbc06204afe1232c465e388f..25562c47923e1ade77c199bd57144cb52b40228b 100755
96
--- a/src/Glide64/osal_dynamiclib_unix.c
97
+++ b/src/Glide64/osal_dynamiclib_unix.c
99
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
100
- * Mupen64plus-core - osal/dynamiclib_unix.c *
101
+ * Mupen64plus-video-glide64mk2 - osal_dynamiclib_unix.c *
102
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
103
* Copyright (C) 2009 Richard Goedeken *
106
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
113
#include "m64p_types.h"
115
#include "osal_dynamiclib.h"
117
+m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath)
119
+ if (pLibHandle == NULL || pccLibraryPath == NULL)
120
+ return M64ERR_INPUT_ASSERT;
122
+ *pLibHandle = dlopen(pccLibraryPath, RTLD_NOW);
124
+ if (*pLibHandle == NULL)
126
+ /* only print an error message if there is a directory separator (/) in the pathname */
127
+ /* this prevents us from throwing an error for the use case where Mupen64Plus is not installed */
128
+ if (strchr(pccLibraryPath, '/') != NULL)
129
+ WriteLog(M64MSG_ERROR, "dlopen('%s') failed: %s", pccLibraryPath, dlerror());
130
+ return M64ERR_INPUT_NOT_FOUND;
133
+ return M64ERR_SUCCESS;
136
void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName)
138
if (pccProcedureName == NULL)
139
@@ -34,4 +55,17 @@ void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedur
140
return dlsym(LibHandle, pccProcedureName);
143
+m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle)
145
+ int rval = dlclose(LibHandle);
149
+ WriteLog(M64MSG_ERROR, "dlclose() failed: %s", dlerror());
150
+ return M64ERR_INTERNAL;
153
+ return M64ERR_SUCCESS;
157
diff --git a/src/Glide64/osal_dynamiclib_win32.c b/src/Glide64/osal_dynamiclib_win32.c
158
index 685d717c9936055cdf5b20e3af6368f5bd1fb48c..a75c238c48141c9b69a9e8f77f2a14cc028ff78b 100755
159
--- a/src/Glide64/osal_dynamiclib_win32.c
160
+++ b/src/Glide64/osal_dynamiclib_win32.c
162
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
163
- * Mupen64plus-ui-console - osal_dynamiclib_win32.c *
164
+ * Mupen64plus-video-glide64mk2 - osal_dynamiclib_win32.c *
165
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
166
* Copyright (C) 2009 Richard Goedeken *
171
#include "m64p_types.h"
173
#include "osal_dynamiclib.h"
175
m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath)
176
@@ -39,7 +40,7 @@ m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibra
177
DWORD dwErr = GetLastError();
178
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr,
179
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL);
180
- fprintf(stderr, "LoadLibrary('%s') error: %s\n", pccLibraryPath, pchErrMsg);
181
+ WriteLog(M64MSG_ERROR, "LoadLibrary('%s') error: %s", pccLibraryPath, pchErrMsg);
182
LocalFree(pchErrMsg);
183
return M64ERR_INPUT_NOT_FOUND;
185
@@ -65,7 +66,7 @@ m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle)
186
DWORD dwErr = GetLastError();
187
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr,
188
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL);
189
- fprintf(stderr, "FreeLibrary() error: %s\n", pchErrMsg);
190
+ WriteLog(M64MSG_ERROR, "FreeLibrary() error: %s", pchErrMsg);
191
LocalFree(pchErrMsg);
192
return M64ERR_INTERNAL;
194
diff --git a/src/GlideHQ/TxQuantize.cpp b/src/GlideHQ/TxQuantize.cpp
195
index b21db71ac95a27e7c18a2329c312f5dbeeb3bb12..02483cb581992841c2d913adcc981a034e9a68f2 100644
196
--- a/src/GlideHQ/TxQuantize.cpp
197
+++ b/src/GlideHQ/TxQuantize.cpp
198
@@ -41,7 +41,7 @@ TxQuantize::TxQuantize()
200
/* get dxtn extensions */
201
_tx_compress_fxt1 = TxLoadLib::getInstance()->getfxtCompressTexFuncExt();
202
- _tx_compress_dxtn = TxLoadLib::getInstance()->getdxtCompressTexFuncExt();
203
+ _tx_compress_dxtn_rgba = TxLoadLib::getInstance()->getdxtCompressTexFuncExt();
207
@@ -1990,7 +1990,7 @@ TxQuantize::DXTn(uint8 *src, uint8 *dest,
211
- if (_tx_compress_dxtn &&
212
+ if (_tx_compress_dxtn_rgba &&
213
srcwidth >= 4 && srcheight >= 4) {
215
* width and height must be larger than 4
216
@@ -2038,7 +2038,7 @@ TxQuantize::DXTn(uint8 *src, uint8 *dest,
217
unsigned int srcStride = (srcwidth * blkheight) << 2;
218
unsigned int destStride = dstRowStride * blkrow;
219
for (i = 0; i < numcore - 1; i++) {
220
- thrd[i] = new std::thread(std::bind(_tx_compress_dxtn,
221
+ thrd[i] = new std::thread(std::bind(_tx_compress_dxtn_rgba,
225
@@ -2049,7 +2049,7 @@ TxQuantize::DXTn(uint8 *src, uint8 *dest,
229
- thrd[i] = new std::thread(std::bind(_tx_compress_dxtn,
230
+ thrd[i] = new std::thread(std::bind(_tx_compress_dxtn_rgba,
233
srcheight - blkheight * i,
234
@@ -2062,7 +2062,7 @@ TxQuantize::DXTn(uint8 *src, uint8 *dest,
238
- (*_tx_compress_dxtn)(4, /* comps: ARGB8888=4, RGB888=3 */
239
+ (*_tx_compress_dxtn_rgba)(4, /* comps: ARGB8888=4, RGB888=3 */
240
srcwidth, /* width */
241
srcheight, /* height */
243
@@ -2072,7 +2072,7 @@ TxQuantize::DXTn(uint8 *src, uint8 *dest,
244
* others = 16 bytes per 4x4 texel */
247
- (*_tx_compress_dxtn)(4, /* comps: ARGB8888=4, RGB888=3 */
248
+ (*_tx_compress_dxtn_rgba)(4, /* comps: ARGB8888=4, RGB888=3 */
249
srcwidth, /* width */
250
srcheight, /* height */
252
diff --git a/src/GlideHQ/TxQuantize.h b/src/GlideHQ/TxQuantize.h
253
index d3c6ae6dc6da7c266c4baad5e6a490a4c8ed2a68..e14990f4150f22c86dd43cf5c8a520829ad082a7 100644
254
--- a/src/GlideHQ/TxQuantize.h
255
+++ b/src/GlideHQ/TxQuantize.h
256
@@ -38,7 +38,7 @@ private:
259
fxtCompressTexFuncExt _tx_compress_fxt1;
260
- dxtCompressTexFuncExt _tx_compress_dxtn;
261
+ dxtCompressTexFuncExt _tx_compress_dxtn_rgba;
263
/* fast optimized... well, sort of. */
264
void ARGB1555_ARGB8888(uint32* src, uint32* dst, int width, int height);
265
diff --git a/src/GlideHQ/TxUtil.cpp b/src/GlideHQ/TxUtil.cpp
266
index 9ad7e448b01b58422bf35a40d64e3b0891f80199..411a25efb15951be9932b98937a2d63710f86e66 100644
267
--- a/src/GlideHQ/TxUtil.cpp
268
+++ b/src/GlideHQ/TxUtil.cpp
269
@@ -42,14 +42,14 @@ TxLoadLib::TxLoadLib()
270
_dxtnlib = LoadLibrary("dxtn");
273
- if (!_tx_compress_dxtn)
274
- _tx_compress_dxtn = (dxtCompressTexFuncExt)DLSYM(_dxtnlib, "tx_compress_dxtn");
275
+ if (!_tx_compress_dxtn_rgba)
276
+ _tx_compress_dxtn_rgba = (dxtCompressTexFuncExt)DLSYM(_dxtnlib, "tx_compress_dxtn_rgba");
278
if (!_tx_compress_fxt1)
279
_tx_compress_fxt1 = (fxtCompressTexFuncExt)DLSYM(_dxtnlib, "fxt1_encode");
282
- _tx_compress_dxtn = tx_compress_dxtn;
283
+ _tx_compress_dxtn_rgba = tx_compress_dxtn_rgba;
284
_tx_compress_fxt1 = fxt1_encode;
287
@@ -74,7 +74,7 @@ TxLoadLib::getfxtCompressTexFuncExt()
288
dxtCompressTexFuncExt
289
TxLoadLib::getdxtCompressTexFuncExt()
291
- return _tx_compress_dxtn;
292
+ return _tx_compress_dxtn_rgba;
296
diff --git a/src/GlideHQ/TxUtil.h b/src/GlideHQ/TxUtil.h
297
index b89f660dfb86a34b16d3ef44221af9d95b9fa4df..7f9c5f4fdd7c08f8d5a8b472b7b5594e4ec8d655 100644
298
--- a/src/GlideHQ/TxUtil.h
299
+++ b/src/GlideHQ/TxUtil.h
304
-void tx_compress_dxtn(int srccomps, int width, int height,
305
+void tx_compress_dxtn_rgba(int srccomps, int width, int height,
306
const void *source, int destformat, void *dest,
309
@@ -62,7 +62,7 @@ private:
312
fxtCompressTexFuncExt _tx_compress_fxt1;
313
- dxtCompressTexFuncExt _tx_compress_dxtn;
314
+ dxtCompressTexFuncExt _tx_compress_dxtn_rgba;
317
static TxLoadLib* getInstance() {
318
diff --git a/src/GlideHQ/tc-1.1+/texstore.c b/src/GlideHQ/tc-1.1+/texstore.c
319
index 5dead259147eaeffce28076e92fb2a981ea451ec..69a6b39bc3a951421799a0b7115f325c7ed55723 100644
320
--- a/src/GlideHQ/tc-1.1+/texstore.c
321
+++ b/src/GlideHQ/tc-1.1+/texstore.c
324
#include "internal.h"
328
_mesa_upscale_teximage2d (unsigned int inWidth, unsigned int inHeight,
329
unsigned int outWidth, unsigned int outHeight,
330
diff --git a/src/GlideHQ/tc-1.1+/wrapper.c b/src/GlideHQ/tc-1.1+/wrapper.c
331
index 0a171ee4fabcc4a26aa64b35f659b2cdb4898011..d3a78fe73d6809567b58ca680648fb5983a03c49 100644
332
--- a/src/GlideHQ/tc-1.1+/wrapper.c
333
+++ b/src/GlideHQ/tc-1.1+/wrapper.c
341
#include "internal.h"
343
+#include "../../Glide64/m64p.h"
345
+typedef void (*dxtCompressTexFuncExt)(int srccomps, int width,
346
+ int height, const byte *srcPixData,
347
+ int destformat, byte *dest,
349
+static dxtCompressTexFuncExt _tx_compress_dxtn = NULL;
351
+#ifdef TXCDXTN_EXTERNAL
353
+#include "../../Glide64/osal_dynamiclib.h"
355
+#if defined(_WIN32) || defined(WIN32)
356
+#define DXTN_LIBNAME "dxtn.dll"
357
+#elif defined(__DJGPP__)
358
+#define DXTN_LIBNAME "dxtn.dxe"
360
+#define DXTN_LIBNAME "libtxc_dxtn.so"
363
+static m64p_dynlib_handle dxtn_lib_handle;
365
+static void tx_compress_dxtn_init()
369
+ if (_tx_compress_dxtn)
372
+ rval = osal_dynlib_open(&dxtn_lib_handle, DXTN_LIBNAME);
373
+ if (rval != M64ERR_SUCCESS) {
374
+ WriteLog(M64MSG_WARNING, "Failed to open %s", DXTN_LIBNAME);
378
+ _tx_compress_dxtn = osal_dynlib_getproc(dxtn_lib_handle, "tx_compress_dxtn");
379
+ if (!_tx_compress_dxtn) {
380
+ WriteLog(M64MSG_WARNING, "Shared library '%s' invalid; no PluginGetVersion() function found.", DXTN_LIBNAME, "tx_compress_dxtn");
381
+ osal_dynlib_close(dxtn_lib_handle);
390
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
391
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
392
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
393
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
397
fetch_2d_texel_rgb_dxt1 (int texImage_RowStride,
398
const byte *texImage_Data,
399
@@ -73,7 +117,7 @@ fetch_2d_texel_rgba_dxt5 (int texImage_RowStride,
405
tx_compress_dxtn (int srccomps, int width, int height,
406
const byte *source, int destformat, byte *dest,
408
@@ -105,3 +149,38 @@ tx_compress_dxtn (int srccomps, int width, int height,
413
+static void tx_compress_dxtn_init()
415
+ _tx_compress_dxtn = tx_compress_dxtn;
422
+tx_compress_dxtn_rgba(int srccomps, int width, int height,
423
+ const byte *source, int destformat, byte *dest,
426
+ int srcRowStride = width * srccomps;
427
+ void *newSource = NULL;
429
+ tx_compress_dxtn_init();
430
+ if (!_tx_compress_dxtn) {
431
+ WriteLog(M64MSG_ERROR, "Failed to initialize S3TC compressor");
435
+ assert(srccomps == 3 || srccomps == 4);
438
+ newSource = reorder_source_3_alloc(source, width, height, srcRowStride);
440
+ newSource = reorder_source_4_alloc(source, width, height, srcRowStride);
442
+ _tx_compress_dxtn(srccomps, width, height, newSource, destformat, dest,
447
diff --git a/src/Glitch64/main.h b/src/Glitch64/main.h
448
index 5b203ed22058e9c95b816b95c30778909cc39373..361c597f746d7603e529b36734727aaf7dd6f22c 100644
449
--- a/src/Glitch64/main.h
450
+++ b/src/Glitch64/main.h
452
#include <m64p_types.h>
454
#define LOG(...) WriteLog(M64MSG_VERBOSE, __VA_ARGS__)
458
void WriteLog(m64p_msg_level level, const char *msg, ...);