Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2214-pre1
  • 2214-pre2
  • 2214-pre3
  • 2214-pre4
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-parameter-crash
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • just-in-case
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.15
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
142 results

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
  • Jisk/srb-2-beef-jerky
117 results
Select Git revision
  • 21-installer-nodd
  • 64-gl-log
  • DJGPP
  • S_SKIN-missing-flag
  • angle-for-spawn-object
  • appveyor
  • better-refusal
  • blend-locking
  • boost-tickrate
  • cleanup-opengl
  • colorstesting
  • colorstesting-224
  • comparepolygons-fix
  • continue_tweaks
  • crawlacommander-sprites
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delete-lua
  • delete-slopes
  • depth-buffer-24
  • disable-titlemap-in-netgames
  • dropshadows-spawning
  • dynres
  • exchndl-xp-fix
  • fix-allowjoin
  • fix-ded-servers
  • fix-fire-shield
  • fix-keepbody-ping
  • fix-major-issue
  • fix-mouse-controls-setup
  • fix-mouse-grabbing
  • fix-node-player-mixups
  • fix-nohw-perfstats-next
  • fix-nonslope-slopes
  • fix-perfstats-3
  • fix-playernode-crash
  • fix-portals
  • fix-splitscreen
  • flipfuncpointers
  • flipfuncpointers-master
  • float-stepup
  • fof-lightlist-fixes
  • fuck-macros-1
  • g_findmap-lua
  • gamepad_experiments
  • gl-deletetexture-fix
  • gles2-desktop-stuff
  • grr-lj
  • gtr-fixes
  • hide-useless-1p-menu-options
  • hmods-dev
  • hwcleanupstuff
  • hwportals
  • hwportalswip
  • ignore-glsegs
  • increase-input-buffer
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • keep-body
  • keycodes-only
  • larger-chat
  • ld413-mp-fix
  • libpng-version-support
  • lol-states
  • lower-unpegged-fix
  • lua-hook-cleanup
  • lua-io
  • lua-local
  • lua-opt-dev
  • lua-opt-dev-alt-cache
  • lua-opt-dev-baseline
  • lua-opt-dev-optoption2
  • lua-optimized-constants
  • lua-timestamp
  • makefile-tinkering
  • map-components-signedness-fixes
  • master
  • master-use-sse3
  • more-cleanup
  • more-lua-map-names
  • more-stats
  • musicdef-lua
  • netcode-tests
  • next
  • ogl-batching
  • ogl-better-gpu-error
  • ogl-big-room-fix
  • ogl-blend-var-fix
  • ogl-compileshaders-bug
  • ogl-driver-error
  • ogl-fof-wall-slope-fix
  • ogl-fof-wall-slope-fix-test
  • ogl-fof-wall-slope-fix2
  • ogl-fog-block-fix
  • ogl-linkdraw
  • ogl-midtexture-zfighting-fix
  • ogl-midtexture-zfix-test
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.2
  • td-release-v1.0.0
130 results
Show changes
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -53,7 +53,7 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
if (dir == 0)
{
for (;;)
for (; count > 0; count--)
{
rastertab[y1].maxx = xs;
rastertab[y1].tx2 = xe;
......@@ -62,13 +62,11 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
xs += dx0;
xe += dx1;
y1++;
if (count-- < 1) break;
}
}
else
{
for (;;)
for (; count > 0; count--)
{
rastertab[y1].maxx = xs;
rastertab[y1].tx2 = tc;
......@@ -77,8 +75,6 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
xs += dx0;
xe += dx1;
y1++;
if (count-- < 1) break;
}
}
}
......@@ -95,7 +91,7 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
if (dir == 0)
{
for (;;)
for (; count > 0; count--)
{
rastertab[y2].minx = xs;
rastertab[y2].tx1 = xe;
......@@ -104,13 +100,11 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
xs += dx0;
xe += dx1;
y2++;
if (count-- < 1) break;
}
}
else
{
for (;;)
for (; count > 0; count--)
{
rastertab[y2].minx = xs;
rastertab[y2].tx1 = tc;
......@@ -119,8 +113,6 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
xs += dx0;
xe += dx1;
y2++;
if (count-- < 1) break;
}
}
}
......@@ -381,7 +373,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
if (pSplat->slope)
{
R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle);
R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, (INT64)pSplat->xscale, (INT64)pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle);
}
else if (!ds_solidcolor)
{
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -147,9 +147,9 @@ static void R_DrawFlippedColumnInCache(column_t *column, UINT8 *cache, texpatch_
if (count > 0)
{
for (; dest < cache + position + count; --source, is_opaque++)
for (; dest < cache + position + count; --source, dest++, is_opaque++)
{
*dest++ = *source;
*dest = *source;
*is_opaque = true;
}
}
......@@ -295,7 +295,6 @@ UINT8 *R_GenerateTexture(size_t texnum)
UINT16 lumpnum = patch->lump;
UINT8 *pdata;
softwarepatch_t *realpatch;
boolean holey = false;
#ifndef NO_PNG_LUMPS
UINT8 header[PNG_HEADER_SIZE];
......@@ -310,9 +309,11 @@ UINT8 *R_GenerateTexture(size_t texnum)
pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
realpatch = (softwarepatch_t *)pdata;
texture->transparency = false;
// Check the patch for holes.
if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height))
holey = true;
texture->transparency = true;
else
{
UINT8 *colofs = (UINT8 *)realpatch->columnofs;
......@@ -332,12 +333,12 @@ UINT8 *R_GenerateTexture(size_t texnum)
col = (doompost_t *)((UINT8 *)col + col->length + 4);
}
if (y < texture->height)
holey = true; // this texture is HOLEy! D:
texture->transparency = true; // this texture is HOLEy! D:
}
}
// If the patch uses transparency, we have to save it this way.
if (holey)
if (texture->transparency)
{
texture->flip = patch->flip;
......@@ -378,6 +379,15 @@ UINT8 *R_GenerateTexture(size_t texnum)
temp_columns = Z_Calloc(sizeof(column_t) * texture->width, PU_STATIC, NULL);
temp_block = Z_Calloc(total_pixels, PU_STATIC, NULL);
#ifdef TEXTURE_255_IS_TRANSPARENT
texture->transparency = false;
// Transparency hack
memset(temp_block, TRANSPARENTPIXEL, total_pixels);
#else
texture->transparency = true;
#endif
for (x = 0; x < texture->width; x++)
{
column_t *column = &temp_columns[x];
......@@ -420,6 +430,10 @@ UINT8 *R_GenerateTexture(size_t texnum)
realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH);
}
// Well, it's not valid...
if (realpatch == NULL)
continue;
x1 = patch->originx;
width = realpatch->width;
height = realpatch->height;
......@@ -474,13 +488,27 @@ UINT8 *R_GenerateTexture(size_t texnum)
// Now write the columns
column_posts = Z_Calloc(sizeof(unsigned) * texture->width, PU_STATIC, NULL);
#ifdef TEXTURE_255_IS_TRANSPARENT
total_posts = texture->width;
temp_posts = Z_Realloc(temp_posts, sizeof(post_t) * total_posts, PU_CACHE, NULL);
#endif
for (x = 0; x < texture->width; x++)
{
post_t *post = NULL;
boolean was_opaque = false;
column_t *column = &temp_columns[x];
#ifdef TEXTURE_255_IS_TRANSPARENT
post = &temp_posts[x];
post->topdelta = 0;
post->length = texture->height;
post->data_offset = 0;
column_posts[x] = x;
column->num_posts = 1;
#else
boolean was_opaque = false;
column_posts[x] = (unsigned)-1;
for (INT32 y = 0; y < texture->height; y++)
......@@ -510,6 +538,7 @@ UINT8 *R_GenerateTexture(size_t texnum)
post->length++;
}
#endif
}
blocksize = (sizeof(column_t) * texture->width) + (sizeof(post_t) * total_posts) + (sizeof(UINT8) * total_pixels);
......@@ -821,8 +850,8 @@ Rloadflats (INT32 i, INT32 w)
UINT8 *flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
if (Picture_PNGDimensions((UINT8 *)flatlump, &texw, &texh, NULL, NULL, lumplength))
{
width = (INT16)width;
height = (INT16)height;
width = (INT16)texw;
height = (INT16)texh;
}
else
{
......@@ -900,7 +929,7 @@ Rloadtextures (INT32 i, INT32 w)
// printf("\"%s\" (wad: %u, lump: %u) is a single patch, dimensions %d x %d\n",W_CheckNameForNumPwad(wadnum,lumpnum),wadnum,lumpnum,width,height);
R_AddSinglePatchTexture(i, wadnum, lumpnum, width, height, TEXTURETYPE_SINGLEPATCH);
R_AddSinglePatchTexture(i, wadnum, lumpnum, width, height, TEXTURETYPE_TEXTURE);
i++;
}
......@@ -1068,6 +1097,98 @@ void R_LoadTexturesPwad(UINT16 wadnum)
R_FinishLoadingTextures(newtextures);
}
static lumpnum_t W_GetTexPatchLumpNum(const char *name)
{
// Flats as a texture patch crashes horribly, and flats
// can share the same name as textures.
// But even if they worked, we want to prioritize:
// Patches -> Textures -> anything else
enum
{
USE_PATCHES,
USE_TEXTURES,
USE__MAX,
};
lumpnum_t lump = LUMPERROR;
INT32 lump_type_it;
for (lump_type_it = 0; lump_type_it < USE__MAX; lump_type_it++)
{
INT32 i;
for (i = numwadfiles - 1; i >= 0; i--) // Scan wad files backwards so patched lumps take precedent
{
lumpnum_t start = LUMPERROR;
lumpnum_t end = LUMPERROR;
switch (wadfiles[i]->type)
{
case RET_WAD:
if (lump_type_it == USE_PATCHES)
{
if ((start = W_CheckNumForMarkerStartPwad("P_START", (UINT16)i, 0)) == INT16_MAX)
continue;
else if ((end = W_CheckNumForNamePwad("P_END", (UINT16)i, start)) == INT16_MAX)
continue;
}
else if (lump_type_it == USE_TEXTURES)
{
if ((start = W_CheckNumForMarkerStartPwad("TX_START", (UINT16)i, 0)) == INT16_MAX)
continue;
else if ((end = W_CheckNumForNamePwad("TX_END", (UINT16)i, start)) == INT16_MAX)
continue;
}
break;
case RET_PK3:
case RET_FOLDER:
if (lump_type_it == USE_PATCHES)
{
if ((start = W_CheckNumForFolderStartPK3("Patches/", i, 0)) == INT16_MAX)
continue;
if ((end = W_CheckNumForFolderEndPK3("Patches/", i, start)) == INT16_MAX)
continue;
}
else if (lump_type_it == USE_TEXTURES)
{
if ((start = W_CheckNumForFolderStartPK3("Textures/", i, 0)) == INT16_MAX)
continue;
if ((end = W_CheckNumForFolderEndPK3("Textures/", i, start)) == INT16_MAX)
continue;
}
break;
default:
continue;
}
// Now find lump with specified name in that range.
lump = W_CheckNumForNamePwad(name, (UINT16)i, start);
if (lump < end)
{
lump += (i<<16); // found it, in our constraints
break;
}
lump = LUMPERROR;
}
if (lump != LUMPERROR)
{
break;
}
}
if (lump == LUMPERROR)
{
// Use whatever else you can find.
return W_CheckNumForPatchName(name);
}
return lump;
}
static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
{
char *texturesToken;
......@@ -1240,13 +1361,13 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
if (actuallyLoadPatch == true)
{
// Check lump exists
patchLumpNum = W_GetNumForName(patchName);
patchLumpNum = W_GetTexPatchLumpNum(patchName);
// If so, allocate memory for texpatch_t and fill 'er up
resultPatch = (texpatch_t *)Z_Malloc(sizeof(texpatch_t),PU_STATIC,NULL);
resultPatch->originx = patchXPos;
resultPatch->originy = patchYPos;
resultPatch->lump = patchLumpNum & 65535;
resultPatch->wad = patchLumpNum>>16;
resultPatch->lump = LUMPNUM(patchLumpNum);
resultPatch->wad = WADFILENUM(patchLumpNum);
resultPatch->flip = flip;
resultPatch->alpha = alpha;
resultPatch->style = style;
......@@ -1377,7 +1498,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture)
resultTexture->hash = quickncasehash(newTextureName, 8);
resultTexture->width = newTextureWidth;
resultTexture->height = newTextureHeight;
resultTexture->type = TEXTURETYPE_COMPOSITE;
resultTexture->type = TEXTURETYPE_TEXTURE;
}
Z_Free(texturesToken);
texturesToken = M_GetToken(NULL);
......@@ -1563,7 +1684,7 @@ static void AddTextureToCache(const char *name, UINT32 hash, INT32 id, UINT8 typ
//
// Check whether texture is available. Filter out NoTexture indicator.
//
INT32 R_CheckTextureNumForName(const char *name)
INT32 R_CheckTextureNumForName(const char *name, UINT8 type)
{
INT32 i;
UINT32 hash;
......@@ -1575,14 +1696,14 @@ INT32 R_CheckTextureNumForName(const char *name)
hash = quickncasehash(name, 8);
for (i = 0; i < tidcachelen; i++)
if (tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8))
if (tidcache[i].type == type && tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8))
return tidcache[i].id;
// Need to parse the list backwards, so textures loaded more recently are used in lieu of ones loaded earlier
for (i = numtextures - 1; i >= 0; i--)
if (textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8))
if (textures[i]->type == type && textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8))
{
AddTextureToCache(name, hash, i, textures[i]->type);
AddTextureToCache(name, hash, i, type);
return i;
}
......@@ -1621,47 +1742,29 @@ const char *R_TextureNameForNum(INT32 num)
//
// R_TextureNumForName
//
// Calls R_CheckTextureNumForName, aborts with error message.
// Calls R_CheckTextureNumForName. Returns REDWALL if not found.
//
INT32 R_TextureNumForName(const char *name)
{
const INT32 i = R_CheckTextureNumForName(name);
INT32 i = R_CheckTextureNumForName(name, TEXTURETYPE_TEXTURE);
// Didn't find it, so look for a flat
if (i == -1)
{
i = R_CheckTextureNumForName(name, TEXTURETYPE_FLAT);
}
// Still didn't find it, so return REDWALL
if (i == -1)
{
static INT32 redwall = -2;
CONS_Debug(DBG_SETUP, "WARNING: R_TextureNumForName: %.8s not found\n", name);
if (redwall == -2)
redwall = R_CheckTextureNumForName("REDWALL");
redwall = R_CheckTextureNumForName("REDWALL", TEXTURETYPE_TEXTURE);
if (redwall != -1)
return redwall;
return 1;
}
return i;
}
// Like R_CheckTextureNumForName, but only looks in the flat namespace specifically.
INT32 R_CheckFlatNumForName(const char *name)
{
INT32 i;
UINT32 hash;
// "NoTexture" marker.
if (name[0] == '-')
return 0;
hash = quickncasehash(name, 8);
for (i = 0; i < tidcachelen; i++)
if (tidcache[i].type == TEXTURETYPE_FLAT && tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8))
return tidcache[i].id;
for (i = numtextures - 1; i >= 0; i--)
if (textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8) && textures[i]->type == TEXTURETYPE_FLAT)
{
AddTextureToCache(name, hash, i, TEXTURETYPE_FLAT);
return i;
}
return -1;
}
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -40,8 +40,7 @@ typedef struct
enum
{
TEXTURETYPE_UNKNOWN,
TEXTURETYPE_SINGLEPATCH,
TEXTURETYPE_COMPOSITE,
TEXTURETYPE_TEXTURE,
TEXTURETYPE_FLAT
};
......@@ -54,6 +53,7 @@ typedef struct
char name[8];
UINT32 hash;
UINT8 type; // TEXTURETYPE_*
boolean transparency;
INT16 width, height;
UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both
void *flat; // The texture, as a flat.
......@@ -99,8 +99,7 @@ void R_SetFlatVars(size_t length);
// Returns the texture number for the texture name.
INT32 R_TextureNumForName(const char *name);
INT32 R_CheckTextureNumForName(const char *name);
INT32 R_CheckFlatNumForName(const char *name);
INT32 R_CheckTextureNumForName(const char *name, UINT8 type);
// Returns the texture name for the texture number (in case you ever needed it)
const char *R_CheckTextureNameForNum(INT32 num);
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -279,6 +279,14 @@ static boolean GetFramesAndRotationsFromShortLumpName(
*ret_rotation2 = R_Char2Rotation(name[7]);
if (*ret_frame2 >= 64 || *ret_rotation2 == 255)
return false;
// TRNSLATE is a valid but extremely unlikely sprite name:
// * The sprite name is "TRNS"
// * The frame is L, rotation A; mirrored to frame T, rotation E
// In the very unfortunate event that TRNSLATE is found between sprite lumps,
// this name check prevents it from being added as a sprite, when it actually isn't.
if (memcmp(name, "TRNSLATE", 8) == 0)
return false;
}
else
{
......@@ -367,7 +375,7 @@ static void MirrorMissingRotations(void)
{
spriteframe_t *frame = &sprtemp[framenum];
if (frame->rotate == SRF_NONE || !(frame->rotate & SRF_3DMASK))
if (frame->rotate == SRF_NONE || !(frame->rotate & (SRF_3DMASK | SRF_2D)))
continue;
UINT8 numrotations = frame->rotate == SRF_3D ? 8 : 16;
......@@ -379,7 +387,7 @@ static void MirrorMissingRotations(void)
UINT8 baserotation = GetOppositeRotation(rotation, frame->rotate);
UINT32 lumpnum = frame->lumppat[baserotation - 1];
R_InstallSpriteLump(WADFILENUM(lumpnum), LUMPNUM(lumpnum), frame->lumpid[baserotation], framenum, rotation, 1);
R_InstallSpriteLump(WADFILENUM(lumpnum), LUMPNUM(lumpnum), frame->lumpid[baserotation - 1], framenum, rotation, 1);
}
}
}
......@@ -839,8 +847,10 @@ void R_DrawMaskedColumn(column_t *column, unsigned lengthcol)
{
post_t *post = &column->posts[i];
dc_postlength = post->length;
INT32 topscreen = sprtopscreen + spryscale*post->topdelta;
INT32 bottomscreen = topscreen + spryscale*post->length;
INT32 bottomscreen = topscreen + spryscale*dc_postlength;
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
dc_yh = (bottomscreen-1)>>FRACBITS;
......@@ -909,10 +919,12 @@ void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol)
if (!post->length)
continue;
topdelta = lengthcol-post->length-post->topdelta;
dc_postlength = post->length;
topdelta = lengthcol-dc_postlength-post->topdelta;
topscreen = sprtopscreen + spryscale*topdelta;
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*post->length
: sprbotscreen + spryscale*post->length;
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*dc_postlength
: sprbotscreen + spryscale*dc_postlength;
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
dc_yh = (bottomscreen-1)>>FRACBITS;
......@@ -956,7 +968,9 @@ UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 trans
if (color != SKINCOLOR_NONE)
{
// New colormap stuff for skins Tails 06-07-2002
if (mobj->colorized)
if ((mobj->state-states == S_METALSONIC_DASH || mobj->state-states == S_METALSONIC_BOUNCE) && (((leveltime/2) & 1))) // Metal boss doing attack
skinnum = TC_DASHMODE;
else if (mobj->colorized)
skinnum = TC_RAINBOW;
else if (mobj->player && mobj->player->dashmode >= DASHMODE_THRESHOLD
&& (mobj->player->charflags & SF_DASHMODE)
......@@ -992,6 +1006,12 @@ UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 trans
return NULL;
}
// Based off of R_GetLinedefTransTable
transnum_t R_GetThingTransTable(fixed_t alpha, transnum_t transmap)
{
return (20*(FRACUNIT - ((alpha * (10 - transmap))/10) - 1) + FRACUNIT) >> (FRACBITS+1);
}
//
// R_DrawVisSprite
// mfloorclip and mceilingclip should also be set.
......@@ -1497,6 +1517,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
floordiff = abs((isflipped ? interp.height : 0) + interp.z - groundz);
trans = floordiff / (100*FRACUNIT) + 3;
trans = R_GetThingTransTable(thing->alpha, trans);
if (trans >= 9) return;
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
......@@ -1770,6 +1791,10 @@ static void R_ProjectSprite(mobj_t *thing)
}
this_scale = interp.scale;
if (this_scale < 1)
return;
radius = interp.radius; // For drop shadows
height = interp.height; // Ditto
......@@ -2184,6 +2209,11 @@ static void R_ProjectSprite(mobj_t *thing)
else
trans = 0;
if ((oldthing->flags2 & MF2_LINKDRAW) && oldthing->tracer)
trans = R_GetThingTransTable(oldthing->tracer->alpha, trans);
else
trans = R_GetThingTransTable(oldthing->alpha, trans);
// Check if this sprite needs to be rendered like a shadow
shadowdraw = (!!(thing->renderflags & RF_SHADOWDRAW) && !(papersprite || splat));
shadoweffects = (thing->renderflags & RF_SHADOWEFFECTS);
......@@ -3644,6 +3674,7 @@ boolean R_ThingVisible (mobj_t *thing)
(thing->sprite == SPR_NULL) || // Don't draw null-sprites
(thing->flags2 & MF2_DONTDRAW) || // Don't draw MF2_LINKDRAW objects
(thing->drawonlyforplayer && thing->drawonlyforplayer != viewplayer) || // Don't draw other players' personal objects
(!R_BlendLevelVisible(thing->blendmode, R_GetThingTransTable(thing->alpha, 0))) ||
(!P_MobjWasRemoved(r_viewmobj) && (
(r_viewmobj == thing) || // Don't draw first-person players or awayviewmobj objects
(r_viewmobj->player && r_viewmobj->player->followmobj == thing) || // Don't draw first-person players' followmobj
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -93,6 +93,7 @@ boolean R_ThingIsFullDark (mobj_t *thing);
boolean R_ThingIsFlashing (mobj_t *thing);
UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 translation);
transnum_t R_GetThingTransTable(fixed_t alpha, transnum_t transmap);
void R_ThingOffsetOverlay (mobj_t *thing, fixed_t *outx, fixed_t *outy);
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2006 by Randy Heit.
// Copyright (C) 2023 by Sonic Team Junior.
// Copyright (C) 2023-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2006 by Randy Heit.
// Copyright (C) 2023 by Sonic Team Junior.
// Copyright (C) 2023-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -1801,6 +1801,27 @@ UINT32 S_GetMusicLength(void)
return I_GetSongLength();
}
//
// S_MusicInfo
//
// Returns metadata about supplied music
// If name is NULL, returns the currently playing music (if any)
//
musicdef_t *S_MusicInfo(const char *name)
{
if (!name)
name = music_name;
musicdef_t *def;
for (def = musicdefstart; def; def = def->next)
{
if (strcasecmp(def->name, name) == 0)
return def;
}
return NULL;
}
boolean S_SetMusicLoopPoint(UINT32 looppoint)
{
return I_SetSongLoopPoint(looppoint);
......@@ -2256,9 +2277,9 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32
return;
strncpy(newmusic, mmusic, sizeof(newmusic)-1);
newmusic[6] = 0;
if (LUA_HookMusicChange(music_name, &hook_param))
return;
newmusic[6] = 0;
// No Music (empty string)
if (newmusic[0] == 0)
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -220,6 +220,9 @@ boolean S_PrepareSoundTest(void);
// Get Length of Music
UINT32 S_GetMusicLength(void);
// Get MUSICDEF of Music
musicdef_t *S_MusicInfo(const char *name);
// Set LoopPoint of Music
boolean S_SetMusicLoopPoint(UINT32 looppoint);
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -112,6 +112,10 @@ void SCR_SetDrawFuncs(void)
colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8;
colfuncs[COLDRAWFUNC_SHADOWED] = R_DrawColumnShadowed_8;
colfuncs[COLDRAWFUNC_TRANSTRANS] = R_DrawTranslatedTranslucentColumn_8;
colfuncs[COLDRAWFUNC_CLAMPED] = R_DrawColumnClamped_8;
colfuncs[COLDRAWFUNC_CLAMPEDTRANS] = R_DrawTranslucentColumnClamped_8;
colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8;
colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8;
colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8;
spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8;
......@@ -120,6 +124,7 @@ void SCR_SetDrawFuncs(void)
spanfuncs[SPANDRAWFUNC_SPLAT] = R_DrawSplat_8;
spanfuncs[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_8;
spanfuncs[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_8;
spanfuncs[SPANDRAWFUNC_TILTEDTRANSSPLAT] = R_DrawTiltedTranslucentSplat_8;
spanfuncs[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_8;
spanfuncs[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_8;
spanfuncs[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_8;
......@@ -142,6 +147,7 @@ void SCR_SetDrawFuncs(void)
spanfuncs_npo2[SPANDRAWFUNC_SPLAT] = R_DrawSplat_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANSSPLAT] = R_DrawTiltedTranslucentSplat_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_NPO2_8;
......@@ -489,11 +495,9 @@ void SCR_ClosedCaptions(void)
basey -= 42;
else if (splitscreen)
basey -= 8;
else if ((modeattacking == ATTACKING_NIGHTS)
|| (!(maptol & TOL_NIGHTS)
&& LUA_HudEnabled(hud_powerups)
else if (LUA_HudEnabled(hud_powerups)
&& ((cv_powerupdisplay.value == 2) // "Always"
|| (cv_powerupdisplay.value == 1 && !camera.chase)))) // "First-person only"
|| (cv_powerupdisplay.value == 1 && !camera.chase))) // "First-person only"
basey -= 16;
}
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -30,10 +30,6 @@
#define NUMSCREENS 5
#endif
// Size of statusbar.
#define ST_HEIGHT 32
#define ST_WIDTH 320
// used now as a maximum video mode size for extra vesa modes.
// we try to re-allocate a minimum of buffers for stability of the memory,
......@@ -97,6 +93,10 @@ enum
COLDRAWFUNC_SHADE,
COLDRAWFUNC_SHADOWED,
COLDRAWFUNC_TRANSTRANS,
COLDRAWFUNC_CLAMPED,
COLDRAWFUNC_CLAMPEDTRANS,
COLDRAWFUNC_TWOSMULTIPATCH,
COLDRAWFUNC_TWOSMULTIPATCHTRANS,
COLDRAWFUNC_FOG,
COLDRAWFUNC_MAX
......@@ -115,6 +115,7 @@ enum
SPANDRAWFUNC_SPLAT,
SPANDRAWFUNC_TRANSSPLAT,
SPANDRAWFUNC_TILTEDSPLAT,
SPANDRAWFUNC_TILTEDTRANSSPLAT,
SPANDRAWFUNC_SPRITE,
SPANDRAWFUNC_TRANSSPRITE,
......
......@@ -14,9 +14,14 @@ target_sources(SRB2SDL2 PRIVATE
# Compatibility flag with later versions of GCC
# We should really fix our code to not need this
if (NOT SRB2_CONFIG_FORCE_NO_MS_BITFIELDS)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
check_cxx_compiler_flag("-mno-ms-bitfields" HAS_NO_MS_BITFIELDS)
if(HAS_NO_MS_BITFIELDS)
target_compile_options(SRB2SDL2 PRIVATE -mno-ms-bitfields)
endif()
endif()
endif()
# Yes we know we use insecure CRT functions...
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
......@@ -33,8 +38,6 @@ target_compile_options(SRB2SDL2 PRIVATE
-Wall
-Wno-trigraphs
-W # Was controlled by RELAXWARNINGS
-pedantic
-Wpedantic
-Wfloat-equal
-Wundef
-Wpointer-arith
......
......@@ -165,7 +165,7 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<LanguageStandard>stdcpp17</LanguageStandard>
<PreprocessorDefinitions>HAVE_CURL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>HAVE_CURL;HAVE_THREADS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\libs\curl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<CustomBuild>
......@@ -447,6 +447,7 @@
<ClCompile Include="..\blua\lauxlib.c" />
<ClCompile Include="..\blua\lbaselib.c" />
<ClCompile Include="..\blua\lcode.c" />
<ClCompile Include="..\blua\ldblib.c" />
<ClCompile Include="..\blua\ldebug.c" />
<ClCompile Include="..\blua\ldo.c" />
<ClCompile Include="..\blua\ldump.c" />
......@@ -512,6 +513,7 @@
<ClCompile Include="..\lua_hudlib_drawlist.c" />
<ClCompile Include="..\lua_infolib.c" />
<ClCompile Include="..\lua_inputlib.c" />
<ClCompile Include="..\lua_interceptlib.c" />
<ClCompile Include="..\lua_maplib.c" />
<ClCompile Include="..\lua_mathlib.c" />
<ClCompile Include="..\lua_mobjlib.c" />
......@@ -628,6 +630,7 @@
<ClCompile Include="i_main.c" />
<ClCompile Include="i_net.c" />
<ClCompile Include="i_system.c" />
<ClCompile Include="i_threads.c" />
<ClCompile Include="i_ttf.c" />
<ClCompile Include="i_video.c" />
<ClCompile Include="mixer_sound.c" />
......
......@@ -604,6 +604,9 @@
<ClCompile Include="..\blua\ldebug.c">
<Filter>BLUA</Filter>
</ClCompile>
<ClCompile Include="..\blua\ldblib.c">
<Filter>BLUA</Filter>
</ClCompile>
<ClCompile Include="..\blua\ldo.c">
<Filter>BLUA</Filter>
</ClCompile>
......@@ -754,9 +757,6 @@
<ClCompile Include="..\hardware\hw_shaders.c">
<Filter>Hw_Hardware</Filter>
</ClCompile>
<ClCompile Include="..\hardware\u_list.c">
<Filter>Hw_Hardware</Filter>
</ClCompile>
<ClCompile Include="..\filesrch.c">
<Filter>I_Interface</Filter>
</ClCompile>
......@@ -780,6 +780,9 @@
</ClCompile>
<ClCompile Include="..\lua_inputlib.c">
<Filter>LUA</Filter>
</ClCompile>
<ClCompile Include="..\lua_interceptlib.c">
<Filter>LUA</Filter>
</ClCompile>
<ClCompile Include="..\lua_maplib.c">
<Filter>LUA</Filter>
......@@ -1119,6 +1122,9 @@
<ClCompile Include="..\r_bbox.c">
<Filter>R_Rend</Filter>
</ClCompile>
<ClCompile Include="i_threads.c">
<Filter>SDLApp</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Image Include="Srb2SDL.ico">
......
......@@ -112,6 +112,7 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(SetPaletteLookup);
GETFUNC(CreateLightTable);
GETFUNC(UpdateLightTable);
GETFUNC(ClearLightTables);
GETFUNC(SetScreenPalette);
......
......@@ -5,7 +5,7 @@
//
// Copyright (C) 1993-1996 by id Software, Inc.
// Portions Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 2014-2023 by Sonic Team Junior.
// Copyright (C) 2014-2025 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
......@@ -78,10 +78,11 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#include "SDL_cpuinfo.h"
#define HAVE_SDLCPUINFO
#if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (__HAIKU__))
#if defined (__linux__)
#include <sys/vfs.h>
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#if defined (__linux__) || defined (__HAIKU__)
#include <sys/statvfs.h>
#else
#include <sys/statvfs.h>
#include <sys/param.h>
#include <sys/mount.h>
/*For meminfo*/
......@@ -94,7 +95,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif
#endif
#if defined (__linux__) || (defined (UNIXCOMMON) && !defined (__HAIKU__))
#if defined (__linux__) || defined (UNIXCOMMON)
#ifndef NOTERMIOS
#include <termios.h>
#include <sys/ioctl.h> // ioctl
......@@ -109,8 +110,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__))
#include <errno.h>
#include <sys/wait.h>
#ifndef __HAIKU__ // haiku's crash dialog is just objectively better
#define NEWSIGNALHANDLER
#endif
#endif
#ifndef NOMUMBLE
#ifdef __linux__ // need -lrt
......@@ -271,75 +274,86 @@ SDL_bool framebuffer = SDL_FALSE;
UINT8 keyboard_started = false;
#ifdef UNIXBACKTRACE
#define STDERR_WRITE(string) if (fd != -1) I_OutputMsg("%s", string)
#define CRASHLOG_WRITE(string) if (fd != -1) junk = write(fd, string, strlen(string))
#define CRASHLOG_STDERR_WRITE(string) \
if (fd != -1)\
junk = write(fd, string, strlen(string));\
I_OutputMsg("%s", string)
static void bt_write_file(int fd, const char *string) {
ssize_t written = 0;
ssize_t sourcelen = strlen(string);
while (fd != -1 && (written != -1 && errno != EINTR) && written < sourcelen)
written = write(fd, string, sourcelen);
}
static void bt_write_stderr(const char *string) {
bt_write_file(STDERR_FILENO, string);
}
static void bt_write_all(int fd, const char *string) {
bt_write_file(fd, string);
bt_write_file(STDERR_FILENO, string);
}
static void write_backtrace(INT32 signal)
{
int fd = -1;
#ifndef NOEXECINFO
size_t size;
#endif
time_t rawtime;
struct tm timeinfo;
ssize_t junk;
enum { BT_SIZE = 1024, STR_SIZE = 32 };
#ifndef NOEXECINFO
void *array[BT_SIZE];
void *funcptrs[BT_SIZE];
size_t bt_size;
#endif
char timestr[STR_SIZE];
const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n";
const char *error2 = "(Or find crash-log.txt in your SRB2 directory.)\n"; // Shown only to stderr.
const char *filename = va("%s" PATHSEP "%s", srb2home, "crash-log.txt");
fd = open(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR);
fd = open(filename, O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR);
if (fd == -1)
I_OutputMsg("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n");
if (fd == -1) // File handle error
bt_write_stderr("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n");
// Get the current time as a string.
time(&rawtime);
localtime_r(&rawtime, &timeinfo);
strftime(timestr, STR_SIZE, "%a, %d %b %Y %T %z", &timeinfo);
CRASHLOG_WRITE("------------------------\n"); // Nice looking seperator
bt_write_file(fd, "------------------------\n"); // Nice looking seperator
bt_write_all(fd, "\n"); // Newline to look nice for both outputs.
bt_write_all(fd, "An error occurred within SRB2! Send this stack trace to someone who can help!\n");
CRASHLOG_STDERR_WRITE("\n"); // Newline to look nice for both outputs.
CRASHLOG_STDERR_WRITE(error); // "Oops, SRB2 crashed" message
STDERR_WRITE(error2); // Tell the user where the crash log is.
if (fd != -1) // If the crash log exists,
bt_write_stderr("(Or find crash-log.txt in your SRB2 directory.)\n"); // tell the user where the crash log is.
// Tell the log when we crashed.
CRASHLOG_WRITE("Time of crash: ");
CRASHLOG_WRITE(timestr);
CRASHLOG_WRITE("\n");
bt_write_file(fd, "Time of crash: ");
bt_write_file(fd, timestr);
bt_write_file(fd, "\n");
// Give the crash log the cause and a nice 'Backtrace:' thing
// The signal is given to the user when the parent process sees we crashed.
CRASHLOG_WRITE("Cause: ");
CRASHLOG_WRITE(strsignal(signal));
CRASHLOG_WRITE("\n"); // Newline for the signal name
bt_write_file(fd, "Cause: ");
bt_write_file(fd, strsignal(signal));
bt_write_file(fd, "\n"); // Newline for the signal name
#ifndef NOEXECINFO
CRASHLOG_STDERR_WRITE("\nBacktrace:\n");
#ifdef NOEXECINFO
bt_write_all(fd, "\nNo Backtrace support\n");
#else
bt_write_all(fd, "\nBacktrace:\n");
// Flood the output and log with the backtrace
size = backtrace(array, BT_SIZE);
backtrace_symbols_fd(array, size, fd);
backtrace_symbols_fd(array, size, STDERR_FILENO);
bt_size = backtrace(funcptrs, BT_SIZE);
backtrace_symbols_fd(funcptrs, bt_size, fd);
backtrace_symbols_fd(funcptrs, bt_size, STDERR_FILENO);
#endif
CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :)
(void)junk;
bt_write_file(fd, "\n"); // Write another newline to the log so it looks nice :)
if (fd != -1) {
fsync(fd); // reaaaaally make sure we got that data written.
close(fd);
}
#undef STDERR_WRITE
#undef CRASHLOG_WRITE
#undef CRASHLOG_STDERR_WRITE
}
#endif // UNIXBACKTRACE
static void I_ReportSignal(int num, int coredumped)
......@@ -466,10 +480,9 @@ typedef struct
feild_t tty_con;
// when printing general stuff to stdout stderr (Sys_Printf)
// we need to disable the tty console stuff
// this increments so we can recursively disable
static INT32 ttycon_hide = 0;
// lock to prevent clearing partial lines, since not everything
// printed ends on a newline.
static boolean ttycon_ateol = true;
// some key codes that the terminal may be using
// TTimo NOTE: I'm not sure how relevant this is
static INT32 tty_erase;
......@@ -497,63 +510,31 @@ static inline void tty_FlushIn(void)
// TTimo NOTE: it seems on some terminals just sending '\b' is not enough
// so for now, in any case we send "\b \b" .. yeah well ..
// (there may be a way to find out if '\b' alone would work though)
// Hanicef NOTE: using \b this way is unreliable because of terminal state,
// it's better to use \r to reset the cursor to the beginning of the
// line and clear from there.
static void tty_Back(void)
{
char key;
ssize_t d;
key = '\b';
d = write(STDOUT_FILENO, &key, 1);
key = ' ';
d = write(STDOUT_FILENO, &key, 1);
key = '\b';
d = write(STDOUT_FILENO, &key, 1);
(void)d;
}
static void tty_Clear(void)
{
size_t i;
write(STDOUT_FILENO, "\r", 1);
if (tty_con.cursor>0)
{
for (i=0; i<tty_con.cursor; i++)
{
tty_Back();
}
write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor);
}
}
// clear the display of the line currently edited
// bring cursor back to beginning of line
static inline void tty_Hide(void)
{
//I_Assert(consolevent);
if (ttycon_hide)
{
ttycon_hide++;
return;
}
tty_Clear();
ttycon_hide++;
write(STDOUT_FILENO, " \b", 2);
}
// show the current line
// FIXME TTimo need to position the cursor if needed??
static inline void tty_Show(void)
static void tty_Clear(void)
{
size_t i;
ssize_t d;
//I_Assert(consolevent);
I_Assert(ttycon_hide>0);
ttycon_hide--;
if (ttycon_hide == 0 && tty_con.cursor)
write(STDOUT_FILENO, "\r", 1);
if (tty_con.cursor>0)
{
for (i=0; i<tty_con.cursor; i++)
{
d = write(STDOUT_FILENO, tty_con.buffer+i, 1);
write(STDOUT_FILENO, " ", 1);
}
write(STDOUT_FILENO, "\r", 1);
}
(void)d;
}
// never exit without calling this, or your terminal will be left in a pretty bad state
......@@ -661,6 +642,11 @@ void I_GetConsoleEvents(void)
tty_con.cursor = 0;
ev.key = KEY_ENTER;
}
else if (key == 0x4) // ^D, aka EOF
{
// shut down, most unix programs behave this way
I_Quit();
}
else continue;
}
else if (tty_con.cursor < sizeof (tty_con.buffer))
......@@ -868,9 +854,16 @@ static void I_RegisterChildSignals(void)
void I_OutputMsg(const char *fmt, ...)
{
size_t len;
char txt[8192];
char *txt;
va_list argptr;
va_start(argptr,fmt);
len = vsnprintf(NULL, 0, fmt, argptr);
va_end(argptr);
if (len == 0)
return;
txt = malloc(len+1);
va_start(argptr,fmt);
vsprintf(txt, fmt, argptr);
va_end(argptr);
......@@ -904,7 +897,10 @@ void I_OutputMsg(const char *fmt, ...)
DWORD bytesWritten;
if (co == INVALID_HANDLE_VALUE)
{
free(txt);
return;
}
if (GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &bytesWritten))
{
......@@ -920,11 +916,16 @@ void I_OutputMsg(const char *fmt, ...)
if (oldLength > 0)
{
LPVOID blank = malloc(oldLength);
if (!blank) return;
if (!blank)
{
free(txt);
return;
}
memset(blank, ' ', oldLength); // Blank out.
oldLines = malloc(oldLength*sizeof(TCHAR));
if (!oldLines)
{
free(txt);
free(blank);
return;
}
......@@ -959,18 +960,20 @@ void I_OutputMsg(const char *fmt, ...)
}
#else
#ifdef HAVE_TERMIOS
if (consolevent)
if (consolevent && ttycon_ateol)
{
tty_Hide();
tty_Clear();
ttycon_ateol = false;
}
#endif
if (!framebuffer)
fprintf(stderr, "%s", txt);
#ifdef HAVE_TERMIOS
if (consolevent)
if (consolevent && txt[len-1] == '\n')
{
tty_Show();
write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor);
ttycon_ateol = true;
}
#endif
......@@ -979,6 +982,7 @@ void I_OutputMsg(const char *fmt, ...)
fflush(stderr);
#endif
free(txt);
}
//
......@@ -2296,8 +2300,13 @@ void I_Sleep(UINT32 ms)
void I_SleepDuration(precise_t duration)
{
#if defined(__linux__) || defined(__FreeBSD__)
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__)
UINT64 precision = I_GetPrecisePrecision();
precise_t dest = I_GetPreciseTime() + duration;
precise_t slack = (precision / 5000); // 0.2 ms slack
if (duration > slack)
{
duration -= slack;
struct timespec ts = {
.tv_sec = duration / precision,
.tv_nsec = duration * 1000000000 / precision % 1000000000,
......@@ -2305,6 +2314,10 @@ void I_SleepDuration(precise_t duration)
int status;
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
while (status == EINTR);
}
// busy-wait the rest
while (((INT64)dest - (INT64)I_GetPreciseTime()) > 0);
#elif defined (MIN_SLEEP_DURATION_MS)
UINT64 precision = I_GetPrecisePrecision();
INT32 sleepvalue = cv_sleep.value;
......@@ -2743,18 +2756,13 @@ void I_ShutdownSystem(void)
void I_GetDiskFreeSpace(INT64 *freespace)
{
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#if defined (SOLARIS) || defined (__HAIKU__)
*freespace = INT32_MAX;
return;
#else // Both Linux and BSD have this, apparently.
struct statfs stfs;
if (statfs(srb2home, &stfs) == -1)
struct statvfs stfs;
if (statvfs(srb2home, &stfs) == -1)
{
*freespace = INT32_MAX;
return;
}
*freespace = stfs.f_bavail * stfs.f_bsize;
#endif
#elif defined (_WIN32)
static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL;
static boolean testwin95 = false;
......@@ -2976,7 +2984,7 @@ static void pathonly(char *s)
*/
static const char *searchWad(const char *searchDir)
{
static char tempsw[256] = "";
static char tempsw[MAX_WADPATH] = "";
filestatus_t fstemp;
strcpy(tempsw, WADKEYWORD1);
......@@ -2992,8 +3000,8 @@ static const char *searchWad(const char *searchDir)
#define CHECKWADPATH(ret) \
do { \
I_OutputMsg(",%s", returnWadPath); \
if (isWadPathOk(returnWadPath)) \
I_OutputMsg(",%s", ret); \
if (isWadPathOk(ret)) \
return ret; \
} while (0)
......@@ -3022,7 +3030,9 @@ static const char *locateWad(void)
#ifndef NOCWD
// examine current dir
strcpy(returnWadPath, ".");
CHECKWADPATH(NULL);
I_OutputMsg(",%s", returnWadPath);
if (isWadPathOk(returnWadPath))
return NULL;
#endif
#ifdef __APPLE__
......@@ -3039,9 +3049,16 @@ static const char *locateWad(void)
#ifndef NOHOME
// find in $HOME
I_OutputMsg(",HOME");
I_OutputMsg(",HOME/" DEFAULTDIR);
if ((envstr = I_GetEnv("HOME")) != NULL)
SEARCHWAD(envstr);
{
char *tmp = malloc(strlen(envstr) + 1 + sizeof(DEFAULTDIR));
strcpy(tmp, envstr);
strcat(tmp, "/");
strcat(tmp, DEFAULTDIR);
CHECKWADPATH(tmp);
free(tmp);
}
#endif
// search paths
......@@ -3067,8 +3084,10 @@ const char *I_LocateWad(void)
{
// change to the directory where we found srb2.pk3
#if defined (_WIN32)
waddir = _fullpath(NULL, waddir, MAX_PATH);
SetCurrentDirectoryA(waddir);
#else
waddir = realpath(waddir, NULL);
if (chdir(waddir) == -1)
I_OutputMsg("Couldn't change working directory\n");
#endif
......@@ -3275,4 +3294,18 @@ const char *I_GetSysName(void)
return SDL_GetPlatform();
}
void I_SetTextInputMode(boolean active)
{
if (active)
SDL_StartTextInput();
else
SDL_StopTextInput();
}
boolean I_GetTextInputMode(void)
{
return SDL_IsTextInputActive();
}
#endif
......@@ -87,7 +87,7 @@
#endif
// maximum number of windowed modes (see windowedModes[][])
#define MAXWINMODES (18)
#define MAXWINMODES (21)
/** \brief
*/
......@@ -157,7 +157,9 @@ static INT32 windowedModes[MAXWINMODES][2] =
{1920,1080}, // 1.66
{1680,1050}, // 1.60,5.25
{1600,1200}, // 1.33
{1600,1000}, // 1.60,5.00
{1600, 900}, // 1.66
{1536, 864}, // 1.66,4.80
{1366, 768}, // 1.66
{1440, 900}, // 1.60,4.50
{1280,1024}, // 1.33?
......@@ -166,6 +168,7 @@ static INT32 windowedModes[MAXWINMODES][2] =
{1280, 720}, // 1.66
{1152, 864}, // 1.33,3.60
{1024, 768}, // 1.33,3.20
{ 960, 600}, // 1.60,3.00
{ 800, 600}, // 1.33,2.50
{ 640, 480}, // 1.33,2.00
{ 640, 400}, // 1.60,2.00
......@@ -382,6 +385,8 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
static boolean ShouldIgnoreMouse(void)
{
if (cv_alwaysgrabmouse.value)
return false;
if (menuactive)
return !M_MouseNeeded();
if (paused || con_destlines || chat_on)
......@@ -1704,7 +1709,7 @@ static void Impl_VideoSetupBuffer(void)
vid.direct = NULL;
if (vid.buffer)
free(vid.buffer);
vid.buffer = calloc(vid.rowbytes*vid.height, NUMSCREENS);
vid.buffer = calloc(NUMSCREENS, vid.rowbytes*vid.height);
if (!vid.buffer)
{
I_Error("%s", M_GetText("Not enough memory for video buffer\n"));
......@@ -1852,6 +1857,9 @@ void I_StartupGraphics(void)
if (mousegrabok && !disable_mouse)
SDLdoGrabMouse();
// disable text input right off the bat, since we don't need it at the start.
I_SetTextInputMode(textinputmodeenabledbylua);
graphics_started = true;
}
......@@ -1899,6 +1907,7 @@ void VID_StartupOpenGL(void)
HWD.pfnSetPaletteLookup = hwSym("SetPaletteLookup",NULL);
HWD.pfnCreateLightTable = hwSym("CreateLightTable",NULL);
HWD.pfnUpdateLightTable = hwSym("UpdateLightTable",NULL);
HWD.pfnClearLightTables = hwSym("ClearLightTables",NULL);
HWD.pfnSetScreenPalette = hwSym("SetScreenPalette",NULL);
......@@ -1943,8 +1952,6 @@ void I_ShutdownGraphics(void)
I_OutputMsg("shut down\n");
#ifdef HWRENDER
if (GLUhandle)
hwClose(GLUhandle);
if (sdlglcontext)
{
SDL_GL_DeleteContext(sdlglcontext);
......
......@@ -135,7 +135,7 @@ static void Midiplayer_Onchange(void)
if (Mix_GetMidiPlayer() != cv_midiplayer.value)
{
if (Mix_SetMidiPlayer(cv_midiplayer.value)) // <> 0 means error
CONS_Alert(CONS_ERROR, "Midi player error: %s", Mix_GetError());
CONS_Alert(CONS_ERROR, "Midi player error: %s\n", Mix_GetError());
else
restart = true;
}
......@@ -143,7 +143,7 @@ static void Midiplayer_Onchange(void)
if (!Mix_GetSoundFonts() || stricmp(Mix_GetSoundFonts(), cv_midisoundfontpath.string))
{
if (!Mix_SetSoundFonts(cv_midisoundfontpath.string)) // == 0 means error
CONS_Alert(CONS_ERROR, "Sound font error: %s", Mix_GetError());
CONS_Alert(CONS_ERROR, "Sound font error: %s\n", Mix_GetError());
else
restart = true;
}
......@@ -190,7 +190,7 @@ static void MidiSoundfontPath_Onchange(void)
if (proceed)
{
if (!Mix_SetSoundFonts(cv_midisoundfontpath.string))
CONS_Alert(CONS_ERROR, "Sound font error: %s", Mix_GetError());
CONS_Alert(CONS_ERROR, "Sound font error: %s\n", Mix_GetError());
else
S_StartEx(true);
}
......@@ -199,7 +199,18 @@ static void MidiSoundfontPath_Onchange(void)
// make sure that s_sound.c does not already verify these
// which happens when: defined(HAVE_MIXERX) && !defined(HAVE_MIXER)
static CV_PossibleValue_t midiplayer_cons_t[] = {{MIDI_OPNMIDI, "OPNMIDI"}, {MIDI_Fluidsynth, "Fluidsynth"}, {MIDI_Timidity, "Timidity"}, {MIDI_Native, "Native"}, {0, NULL}};
static CV_PossibleValue_t midiplayer_cons_t[] = {
{MIDI_ADLMIDI, "ADLMIDI"},
{MIDI_OPNMIDI, "OPNMIDI"},
{MIDI_Timidity, "Timidity"},
{MIDI_Fluidsynth, "Fluidsynth"},
#if SDL_MIXER_VERSION_ATLEAST(2,6,0)
{MIDI_EDMIDI, "EDMIDI"},
#endif
{MIDI_Native, "Native"},
{MIDI_ANY, "Any"},
{0, NULL}
};
consvar_t cv_midiplayer = CVAR_INIT ("midiplayer", "OPNMIDI" /*MIDI_OPNMIDI*/, CV_CALL|CV_NOINIT|CV_SAVE, midiplayer_cons_t, Midiplayer_Onchange);
consvar_t cv_midisoundfontpath = CVAR_INIT ("midisoundfont", "sf2/8bitsf.SF2", CV_CALL|CV_NOINIT|CV_SAVE, NULL, MidiSoundfontPath_Onchange);
consvar_t cv_miditimiditypath = CVAR_INIT ("midisoundbank", "./timidity", CV_SAVE, NULL, NULL);
......
......@@ -70,18 +70,10 @@ PFNglGetString pglGetString;
/** \brief SDL video display surface
*/
INT32 oglflags = 0;
void *GLUhandle = NULL;
SDL_GLContext sdlglcontext = 0;
void *GetGLFunc(const char *proc)
{
if (strncmp(proc, "glu", 3) == 0)
{
if (GLUhandle)
return hwSym(proc, GLUhandle);
else
return NULL;
}
return SDL_GL_GetProcAddress(proc);
}
......@@ -89,7 +81,6 @@ boolean LoadGL(void)
{
#ifndef STATIC_OPENGL
const char *OGLLibname = NULL;
const char *GLULibname = NULL;
if (M_CheckParm("-OGLlib") && M_IsNextParm())
OGLLibname = M_GetNextParm();
......@@ -102,43 +93,6 @@ boolean LoadGL(void)
CONS_Printf("If you know what is the OpenGL library's name, use -OGLlib\n");
return 0;
}
#if 0
GLULibname = "/proc/self/exe";
#elif defined (_WIN32)
GLULibname = "GLU32.DLL";
#elif defined (__MACH__)
GLULibname = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib";
#elif defined (macintos)
GLULibname = "OpenGLLibrary";
#elif defined (__unix__)
GLULibname = "libGLU.so.1";
#elif defined (__HAIKU__)
GLULibname = "libGLU.so";
#else
GLULibname = NULL;
#endif
if (M_CheckParm("-GLUlib") && M_IsNextParm())
GLULibname = M_GetNextParm();
if (GLULibname)
{
GLUhandle = hwOpen(GLULibname);
if (GLUhandle)
return SetupGLfunc();
else
{
CONS_Alert(CONS_ERROR, "Could not load GLU Library: %s\n", GLULibname);
if (!M_CheckParm ("-GLUlib"))
CONS_Alert(CONS_ERROR, "If you know what is the GLU library's name, use -GLUlib\n");
}
}
else
{
CONS_Alert(CONS_ERROR, "Could not load GLU Library\n");
CONS_Alert(CONS_ERROR, "If you know what is the GLU library's name, use -GLUlib\n");
}
#endif
return SetupGLfunc();
}
......@@ -155,6 +109,7 @@ boolean OglSdlSurface(INT32 w, INT32 h)
{
INT32 cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value;
static boolean first_init = false;
static int majorGL = 0, minorGL = 0;
oglflags = 0;
......@@ -189,6 +144,12 @@ boolean OglSdlSurface(INT32 w, INT32 h)
else
maximumAnisotropy = 1;
if (sscanf((const char*)gl_version, "%d.%d", &majorGL, &minorGL)
&& (!(majorGL == 1 && minorGL <= 3)))
supportMipMap = true;
else
supportMipMap = false;
SetupGLFunc4();
glanisotropicmode_cons_t[1].value = maximumAnisotropy;
......
......@@ -19,8 +19,6 @@
#include "../v_video.h"
extern void *GLUhandle;
boolean OglSdlSurface(INT32 w, INT32 h);
void OglSdlFinishUpdate(boolean vidwait);
......