Step 1+2 of the SDL 3 migration. The 2300-line graphics/glSDL.{c,h}
OpenGL-on-top-of-SDL-1.2 shim is obsolete under SDL 3 (SDL_Renderer
does what glSDL did natively), and its #define overrides of SDL
surface APIs collided directly with SDL 3's SDL_oldnames.h.
- Add graphics/sdl_compat.h: a one-line umbrella that just pulls in
<SDL3/SDL.h>.
- Replace every #include "glSDL.h" with #include "sdl_compat.h" (15
files across the tree).
- Delete graphics/glSDL.c, graphics/glSDL.h.
- Drop glSDL.c from graphics/CMakeLists.txt.
- Remove GFX_DRIVER_GLSDL from the gfx_drivers_t enum and from all
switches/conditions in gfxengine.cpp.
- Drop the glSDL_VSync() call site (will be re-introduced as
SDL_SetRenderVSync once gfxengine is ported to SDL_Renderer).
- Drop the two glSDL_Invalidate() calls in window.cpp (texture
re-upload hints with no equivalent in a pure-surface compositor).
- options.cpp: remove the now-empty "OpenGL/glSDL" menu item; force
videodriver to GFX_DRIVER_SDL2D.
- prefs.cpp: collapse legacy GLSDL setting onto SDL2D on load.
After this commit the macro-collision wall is gone (renamed_-token
errors drop from many to zero). The build still fails on the next
layer of work: SDL 1.2 surface APIs that no longer exist
(SDL_FreeSurface, SDL_SetAlpha, SDL_CreateRGBSurface, SDL_DisplayFormat,
SDL_PixelFormat struct member access, SDL audio callback API, etc.).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
267 lines
6.5 KiB
C
267 lines
6.5 KiB
C
/*(LGPL)
|
|
---------------------------------------------------------------------------
|
|
a_tools.h - Various useful audio macros and inlines
|
|
---------------------------------------------------------------------------
|
|
* Copyright (C) 2001 - 2003, David Olofson
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation; either version 2.1 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#ifndef _A_TOOLS_H_
|
|
#define _A_TOOLS_H_
|
|
|
|
#include "sdl_compat.h"
|
|
#include <string.h>
|
|
#include "kobolog.h"
|
|
#include "a_types.h"
|
|
|
|
/*----------------------------------------------------------
|
|
Integer Arithmetics
|
|
----------------------------------------------------------*/
|
|
|
|
/*
|
|
* This operation can be implemented very nicely in ML
|
|
* on virtually any CPU - but this is C... *heh*
|
|
*/
|
|
#ifdef A_USE_INT64
|
|
/* Ok, but suboptimal - unless the compiler is sufficiently smart. */
|
|
#define fixmul(a, b) ((int)((Sint64)(a) * (Sint64)(b) >> 16))
|
|
#else
|
|
/* Slooooow, but portable... :-/ */
|
|
#define fixmul(a, b) ((int)((float)(a) * (float)(b) * (1.0/65536.0)))
|
|
#endif
|
|
|
|
/*
|
|
* Given an integer value 'value', and
|
|
*
|
|
* x = y * value
|
|
*
|
|
* find the 's' that best approximates that function using
|
|
* the (on practically any CPU) faster function
|
|
*
|
|
* x = y << s
|
|
*
|
|
* The approximated x will always be equal to, or smaller
|
|
* than the exact x.
|
|
*/
|
|
static inline int int2shift(int value)
|
|
{
|
|
int res;
|
|
if(value >> 16)
|
|
res = 16;
|
|
else
|
|
res = 0;
|
|
if(value >> (res + 8))
|
|
res += 8;
|
|
if(value >> (res + 4))
|
|
res += 4;
|
|
if(value >> (res + 2))
|
|
res += 2;
|
|
if(value >> (res + 1))
|
|
res += 1;
|
|
return res;
|
|
}
|
|
|
|
/*
|
|
* Given a 16:16 fixp value 'value', and
|
|
*
|
|
* x = y * value
|
|
*
|
|
* find the 's' that best approximates that function using
|
|
* the (on practically any CPU) faster function
|
|
*
|
|
* x = y >> s
|
|
*
|
|
* The approximated x will always be equal to, or smaller
|
|
* than the exact x.
|
|
*/
|
|
static inline int fixp2shift(int value)
|
|
{
|
|
int res;
|
|
if(value >> 16)
|
|
res = 16;
|
|
else
|
|
res = 0;
|
|
if(value >> (res + 8))
|
|
res += 8;
|
|
if(value >> (res + 4))
|
|
res += 4;
|
|
if(value >> (res + 2))
|
|
res += 2;
|
|
if(value >> (res + 1))
|
|
res += 1;
|
|
return 16 - res;
|
|
}
|
|
|
|
/*
|
|
* Like fixp2shift(), but here, 'value' is clamped to the
|
|
* [4, 1/64] range (8 bits of dynamic range - hence the
|
|
* suffix) for speed.
|
|
*/
|
|
static inline int fixp2shift8(int value)
|
|
{
|
|
int res;
|
|
value >>= 10;
|
|
if(value >> 4)
|
|
res = 4;
|
|
else
|
|
res = 0;
|
|
if(value >> (res + 2))
|
|
res += 2;
|
|
if(value >> (res + 1))
|
|
res += 1;
|
|
return 6 - res;
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Basic Audio Processing
|
|
------------------------------------------------------------
|
|
* WARNING:
|
|
* Most of these macros and inlines will crash if
|
|
* told to process 0 samples! In DEBUG mode, this is
|
|
* checked and will cause error messages to be printed.
|
|
*
|
|
* Naming conventions:
|
|
* m16 16 bit mono
|
|
* s16 16 bit stereo
|
|
* m32 32 bit mono
|
|
* s32 32 bit stereo
|
|
* All samples are expected to be signed integers, wherever
|
|
* sample format matters.
|
|
*/
|
|
|
|
/* Clear 'frames' samples starting at 'buf'. */
|
|
#define m16clear(buf, frames) memset((buf), 0, (frames) << 1)
|
|
#define s16clear(buf, frames) memset((buf), 0, (frames) << 2)
|
|
#define m32clear(buf, frames) memset((buf), 0, (frames) << 2)
|
|
#define s32clear(buf, frames) memset((buf), 0, (frames) << 3)
|
|
|
|
/* Copy 'frames' samples from 'in' to 'out'. */
|
|
#define m16copy(in, out, frames) memcpy((out), (in), (frames) << 1)
|
|
#define s16copy(in, out, frames) memcpy((out), (in), (frames) << 2)
|
|
#define m32copy(in, out, frames) memcpy((out), (in), (frames) << 2)
|
|
#define s32copy(in, out, frames) memcpy((out), (in), (frames) << 3)
|
|
|
|
/* Add the contents of 'from' into buffer 'to' */
|
|
#define m16add(from, to, frames) _add16(from, to, frames)
|
|
#define s16add(from, to, frames) _add16(from, to, (frames)<<1)
|
|
static inline void _add16(Sint16 *from, Sint16 *to, unsigned samples)
|
|
{
|
|
unsigned s;
|
|
for(s = samples & 3; s; --s)
|
|
*to++ += *from++;
|
|
samples >>= 2;
|
|
s = 0;
|
|
while(samples--)
|
|
{
|
|
to[s] += from[s];
|
|
to[s+1] += from[s+1];
|
|
to[s+2] += from[s+2];
|
|
to[s+3] += from[s+3];
|
|
s += 4;
|
|
}
|
|
}
|
|
|
|
#define m32add(from, to, frames) _add32(from, to, frames)
|
|
#define s32add(from, to, frames) _add32(from, to, (frames)<<1)
|
|
static inline void _add32(Sint32 *from, Sint32 *to, unsigned samples)
|
|
{
|
|
unsigned s = -((4 - samples) & 3);
|
|
#ifdef DEBUG
|
|
if(!samples)
|
|
{
|
|
log_printf(ELOG, "a_tools.h: _add32(); zero samples!\n");
|
|
return;
|
|
}
|
|
#endif
|
|
switch(samples & 3) do
|
|
{
|
|
case 0:
|
|
to[s] += from[s];
|
|
case 3:
|
|
to[s+1] += from[s+1];
|
|
case 2:
|
|
to[s+2] += from[s+2];
|
|
case 1:
|
|
to[s+3] += from[s+3];
|
|
s += 4;
|
|
} while(s < samples);
|
|
}
|
|
|
|
/*
|
|
* Returns 1 if mixing was done, 0 if the volume
|
|
* is too low for actual output to be produced.
|
|
*/
|
|
#define m32mix(from, to, vol, frames) _mix32(from, to, vol, frames)
|
|
#define s32mix(from, to, vol, frames) _mix32(from, to, vol, (frames)<<1)
|
|
static inline int _mix32(Sint32 *from, Sint32 *to, int vol, unsigned samples)
|
|
{
|
|
unsigned s = -((4 - samples) & 3);
|
|
#ifdef DEBUG
|
|
if(!samples)
|
|
{
|
|
log_printf(ELOG, "a_tools.h: _mix32(); zero samples!\n");
|
|
return 0;
|
|
}
|
|
#endif
|
|
vol >>= 8;
|
|
if(!vol)
|
|
return 0;
|
|
switch(samples & 3) do
|
|
{
|
|
case 0:
|
|
to[s] += from[s] * vol >> 8;
|
|
case 3:
|
|
to[s+1] += from[s+1] * vol >> 8;
|
|
case 2:
|
|
to[s+2] += from[s+2] * vol >> 8;
|
|
case 1:
|
|
to[s+3] += from[s+3] * vol >> 8;
|
|
s += 4;
|
|
} while(s < samples);
|
|
return 1;
|
|
}
|
|
|
|
#define m32fastmix(f, t, vol, frames) _fastmix32(f, t, vol, frames)
|
|
#define s32fastmix(f, t, vol, frames) _fastmix32(f, t, vol, (frames)<<1)
|
|
static inline void _fastmix32(Sint32 *from, Sint32 *to, int vol, unsigned samples)
|
|
{
|
|
unsigned s = -((4 - samples) & 3);
|
|
#ifdef DEBUG
|
|
if(!samples)
|
|
{
|
|
log_printf(ELOG, "a_tools.h: _fastmix32(); zero samples!\n");
|
|
return;
|
|
}
|
|
#endif
|
|
vol = fixp2shift(vol);
|
|
switch(samples & 3) do
|
|
{
|
|
case 0:
|
|
to[s] += from[s] >> vol;
|
|
case 3:
|
|
to[s+1] += from[s+1] >> vol;
|
|
case 2:
|
|
to[s+2] += from[s+2] >> vol;
|
|
case 1:
|
|
to[s+3] += from[s+3] >> vol;
|
|
s += 4;
|
|
} while(s < samples);
|
|
}
|
|
|
|
#endif /*_A_TOOLS_H_*/
|