mirror of
https://github.com/cxong/cdogs-sdl.git
synced 2025-07-22 15:10:33 +02:00
Replace SDL image with stb_image
This commit is contained in:
13
.github/workflows/cmake.yml
vendored
13
.github/workflows/cmake.yml
vendored
@@ -57,7 +57,7 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt install python3-pip libgl1-mesa-dev
|
||||
sudo apt install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev
|
||||
sudo apt install libsdl2-dev libsdl2-mixer-dev
|
||||
python3 -m pip install protobuf --break-system-packages
|
||||
pip3 install --upgrade protobuf --break-system-packages
|
||||
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
|
||||
- name: Install dependencies (Windows)
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: C:\vcpkg\vcpkg.exe install --triplet x64-windows sdl2 sdl2-image sdl2-mixer[core,mpg123] protobuf --recurse
|
||||
run: C:\vcpkg\vcpkg.exe install --triplet x64-windows sdl2 sdl2-mixer[core,mpg123] protobuf --recurse
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
@@ -114,14 +114,6 @@ jobs:
|
||||
file-name: 'sdl2.zip'
|
||||
location: './dll'
|
||||
|
||||
- name: Download SDL2_image DLLs on tags (Windows)
|
||||
if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'windows-latest'
|
||||
uses: carlosperate/download-file-action@v2
|
||||
with:
|
||||
file-url: 'https://www.libsdl.org/projects/SDL_image/release/SDL2_image-2.8.1-win32-x64.zip'
|
||||
file-name: 'sdl2_image.zip'
|
||||
location: './dll'
|
||||
|
||||
- name: Download SDL2_mixer DLLs on tags (Windows)
|
||||
if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'windows-latest'
|
||||
uses: carlosperate/download-file-action@v2
|
||||
@@ -135,7 +127,6 @@ jobs:
|
||||
run: |
|
||||
cd dll
|
||||
7z x -y sdl2.zip
|
||||
7z x -y sdl2_image.zip
|
||||
7z x -y sdl2_mixer.zip
|
||||
copy .\optional\*.dll .
|
||||
dir
|
||||
|
13
.github/workflows/cmake.yml.cmake
vendored
13
.github/workflows/cmake.yml.cmake
vendored
@@ -57,7 +57,7 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt install python3-pip libgl1-mesa-dev
|
||||
sudo apt install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev
|
||||
sudo apt install libsdl2-dev libsdl2-mixer-dev
|
||||
python3 -m pip install protobuf --break-system-packages
|
||||
pip3 install --upgrade protobuf --break-system-packages
|
||||
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
|
||||
- name: Install dependencies (Windows)
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: C:\vcpkg\vcpkg.exe install --triplet x64-windows sdl2 sdl2-image sdl2-mixer[core,mpg123] protobuf --recurse
|
||||
run: C:\vcpkg\vcpkg.exe install --triplet x64-windows sdl2 sdl2-mixer[core,mpg123] protobuf --recurse
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
@@ -114,14 +114,6 @@ jobs:
|
||||
file-name: 'sdl2.zip'
|
||||
location: './dll'
|
||||
|
||||
- name: Download SDL2_image DLLs on tags (Windows)
|
||||
if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'windows-latest'
|
||||
uses: carlosperate/download-file-action@v2
|
||||
with:
|
||||
file-url: 'https://www.libsdl.org/projects/SDL_image/release/SDL2_image-2.8.1-win32-x64.zip'
|
||||
file-name: 'sdl2_image.zip'
|
||||
location: './dll'
|
||||
|
||||
- name: Download SDL2_mixer DLLs on tags (Windows)
|
||||
if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'windows-latest'
|
||||
uses: carlosperate/download-file-action@v2
|
||||
@@ -135,7 +127,6 @@ jobs:
|
||||
run: |
|
||||
cd dll
|
||||
7z x -y sdl2.zip
|
||||
7z x -y sdl2_image.zip
|
||||
7z x -y sdl2_mixer.zip
|
||||
copy .\optional\*.dll .
|
||||
dir
|
||||
|
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
SDL_image: An example image loading library for use with SDL
|
||||
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
@@ -4,14 +4,11 @@ set -e
|
||||
OSX_LIB_PATH="/Library/Frameworks"
|
||||
|
||||
OSX_SDL2_PATH_FULL="$OSX_LIB_PATH/SDL2.framework"
|
||||
OSX_SDL2_IMAGE_PATH_FULL="$OSX_LIB_PATH/SDL2_image.framework"
|
||||
OSX_SDL2_MIXER_PATH_FULL="$OSX_LIB_PATH/SDL2_mixer.framework"
|
||||
|
||||
SDL2_VERSION=2.26.4
|
||||
SDL2_IMAGE_VERSION=2.8.1
|
||||
SDL2_MIXER_VERSION=2.6.3
|
||||
SDL2_URL=https://www.libsdl.org/release/SDL2-$SDL2_VERSION.dmg
|
||||
SDL2_IMAGE_URL=https://www.libsdl.org/projects/SDL_image/release/SDL2_image-$SDL2_IMAGE_VERSION.dmg
|
||||
SDL2_MIXER_URL=https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-$SDL2_MIXER_VERSION.dmg
|
||||
|
||||
function installDMG {
|
||||
@@ -37,10 +34,6 @@ function getSdl2 {
|
||||
installDMG $SDL2_URL
|
||||
}
|
||||
|
||||
function getSdl2_image {
|
||||
installDMG $SDL2_IMAGE_URL
|
||||
}
|
||||
|
||||
function getSdl2_mixer {
|
||||
installDMG $SDL2_MIXER_URL
|
||||
}
|
||||
@@ -49,7 +42,6 @@ if [[ "$1" == "--force" ]]
|
||||
then
|
||||
echo "Force build requested by --force."
|
||||
getSdl2
|
||||
getSdl2_image
|
||||
getSdl2_mixer
|
||||
exit
|
||||
fi
|
||||
@@ -68,19 +60,6 @@ else
|
||||
getSdl2
|
||||
fi
|
||||
|
||||
if [[ -d "$OSX_SDL2_IMAGE_PATH_FULL" ]]; then
|
||||
if [[ -n "$(ls -A $OSX_SDL2_IMAGE_PATH_FULL)" ]]
|
||||
then
|
||||
echo "SDL2_image exists. Skip building..."
|
||||
else
|
||||
echo "SDL2_image dir exists buit it is empty..."
|
||||
getSdl2_image
|
||||
fi
|
||||
else
|
||||
echo "SDL2_image dir missing..."
|
||||
getSdl2_image
|
||||
fi
|
||||
|
||||
if [[ -d "$OSX_SDL2_MIXER_PATH_FULL" ]]; then
|
||||
if [[ -n "$(ls -A $OSX_SDL2_MIXER_PATH_FULL)" ]]
|
||||
then
|
||||
|
@@ -3,7 +3,6 @@ setlocal enabledelayedexpansion
|
||||
|
||||
set EXTRACT_COMMAND=7z x -y
|
||||
set SDL2_VERSION=2.26.4
|
||||
set SDL2_IMAGE_VERSION=2.8.1
|
||||
set SDL2_MIXER_VERSION=2.6.3
|
||||
|
||||
|
||||
@@ -16,9 +15,6 @@ rem PLEASE NO SPACES IN SDL2_* VARIABLES
|
||||
set SDL2_ARCHIVE=SDL2-%SDL2_VERSION%-win32-x%BITS%.zip
|
||||
set SDL2_URL=https://www.libsdl.org/release/%SDL2_ARCHIVE%
|
||||
|
||||
set SDL2_IMAGE_ARCHIVE=SDL2_image-%SDL2_IMAGE_VERSION%-win32-x%BITS%.zip
|
||||
set SDL2_IMAGE_URL=https://www.libsdl.org/projects/SDL_image/release/%SDL2_IMAGE_ARCHIVE%
|
||||
|
||||
set SDL2_MIXER_ARCHIVE=SDL2_mixer-%SDL2_MIXER_VERSION%-win32-x%BITS%.zip
|
||||
set SDL2_MIXER_URL=https://www.libsdl.org/projects/SDL_mixer/release/%SDL2_MIXER_ARCHIVE%
|
||||
|
||||
@@ -41,11 +37,9 @@ echo cd into "!DESTDIR!"
|
||||
cd "!DESTDIR!"
|
||||
|
||||
call :downloadIfNeeded !SDL2_URL!
|
||||
call :downloadIfNeeded !SDL2_IMAGE_URL!
|
||||
call :downloadIfNeeded !SDL2_MIXER_URL!
|
||||
|
||||
%EXTRACT_COMMAND% !SDL2_ARCHIVE!
|
||||
%EXTRACT_COMMAND% !SDL2_IMAGE_ARCHIVE!
|
||||
%EXTRACT_COMMAND% !SDL2_MIXER_ARCHIVE!
|
||||
|
||||
rem Copy optional DLLs within the optional folders
|
||||
|
@@ -28,25 +28,17 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <SDL2/SDL_image.h>
|
||||
#else
|
||||
#include <SDL_image.h>
|
||||
#endif
|
||||
|
||||
#include "blit.h"
|
||||
#include "log.h"
|
||||
#include "pic.h"
|
||||
#include "sys_config.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#define FIRST_CHAR 0
|
||||
#define LAST_CHAR 255
|
||||
|
||||
Font gFont;
|
||||
|
||||
|
||||
FontOpts FontOptsNew(void)
|
||||
{
|
||||
FontOpts opts;
|
||||
@@ -61,13 +53,10 @@ void FontLoad(
|
||||
{
|
||||
char buf[CDOGS_PATH_MAX];
|
||||
GetDataFilePath(buf, imgPath);
|
||||
SDL_RWops *rwops = SDL_RWFromFile(buf, "rb");
|
||||
CASSERT(IMG_isPNG(rwops), "Error: font file is not PNG");
|
||||
SDL_Surface *image = IMG_Load_RW(rwops, 0);
|
||||
rwops->close(rwops);
|
||||
SDL_Surface *image = LoadImgToSurface(buf);
|
||||
if (!image)
|
||||
{
|
||||
LOG(LM_GFX, LL_ERROR, "Cannot load font image: %s", IMG_GetError());
|
||||
LOG(LM_GFX, LL_ERROR, "Cannot load font image");
|
||||
return;
|
||||
}
|
||||
if (image->format->BytesPerPixel != 4)
|
||||
@@ -88,10 +77,9 @@ void FontLoad(
|
||||
LOG(LM_GFX, LL_ERROR,
|
||||
"Error: font image not big enough for font data "
|
||||
"Image %dx%d Size %dx%d Stride %d Padding %d,%d,%d,%d",
|
||||
image->w, image->h,
|
||||
f->Size.x, f->Size.y, f->Stride,
|
||||
f->Padding.Left, f->Padding.Top,
|
||||
f->Padding.Right, f->Padding.Bottom);
|
||||
image->w, image->h, f->Size.x, f->Size.y, f->Stride,
|
||||
f->Padding.Left, f->Padding.Top, f->Padding.Right,
|
||||
f->Padding.Bottom);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -99,13 +87,12 @@ void FontLoad(
|
||||
SDL_LockSurface(image);
|
||||
int chars = 0;
|
||||
for (struct vec2i pos = svec2i_zero();
|
||||
pos.y + step.y <= image->h && chars < LAST_CHAR - FIRST_CHAR + 1;
|
||||
pos.y += step.y)
|
||||
pos.y + step.y <= image->h && chars < LAST_CHAR - FIRST_CHAR + 1;
|
||||
pos.y += step.y)
|
||||
{
|
||||
int x = 0;
|
||||
for (pos.x = 0;
|
||||
x < f->Stride && chars < LAST_CHAR - FIRST_CHAR + 1;
|
||||
pos.x += step.x, x++, chars++)
|
||||
for (pos.x = 0; x < f->Stride && chars < LAST_CHAR - FIRST_CHAR + 1;
|
||||
pos.x += step.x, x++, chars++)
|
||||
{
|
||||
Pic p;
|
||||
// TODO: HD fonts
|
||||
@@ -129,7 +116,7 @@ void FontLoad(
|
||||
void FontTerminate(Font *f)
|
||||
{
|
||||
CA_FOREACH(Pic, p, f->Chars)
|
||||
PicFree(p);
|
||||
PicFree(p);
|
||||
CA_FOREACH_END()
|
||||
CArrayTerminate(&f->Chars);
|
||||
}
|
||||
@@ -217,7 +204,8 @@ struct vec2i FontCh(const char c, const struct vec2i pos)
|
||||
{
|
||||
return FontChMask(c, pos, colorWhite);
|
||||
}
|
||||
struct vec2i FontChMask(const char c, const struct vec2i pos, const color_t mask)
|
||||
struct vec2i FontChMask(
|
||||
const char c, const struct vec2i pos, const color_t mask)
|
||||
{
|
||||
int idx = (int)c - FIRST_CHAR;
|
||||
if (idx < 0)
|
||||
@@ -262,14 +250,16 @@ struct vec2i FontStrMask(const char *s, struct vec2i pos, const color_t mask)
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
struct vec2i FontStrMaskWrap(const char *s, struct vec2i pos, color_t mask, const int width)
|
||||
struct vec2i FontStrMaskWrap(
|
||||
const char *s, struct vec2i pos, color_t mask, const int width)
|
||||
{
|
||||
char buf[1024];
|
||||
CASSERT(strlen(s) < 1024, "string too long to wrap");
|
||||
FontSplitLines(s, buf, width);
|
||||
return FontStrMask(buf, pos, mask);
|
||||
}
|
||||
static struct vec2i GetStrPos(const char *s, struct vec2i pos, const FontOpts opts);
|
||||
static struct vec2i GetStrPos(
|
||||
const char *s, struct vec2i pos, const FontOpts opts);
|
||||
void FontStrOpt(const char *s, struct vec2i pos, const FontOpts opts)
|
||||
{
|
||||
if (s == NULL)
|
||||
@@ -280,9 +270,10 @@ void FontStrOpt(const char *s, struct vec2i pos, const FontOpts opts)
|
||||
FontStrMask(s, pos, opts.Mask);
|
||||
}
|
||||
static int GetAlign(
|
||||
const FontAlign align,
|
||||
const int pos, const int pad, const int area, const int size);
|
||||
static struct vec2i GetStrPos(const char *s, struct vec2i pos, const FontOpts opts)
|
||||
const FontAlign align, const int pos, const int pad, const int area,
|
||||
const int size);
|
||||
static struct vec2i GetStrPos(
|
||||
const char *s, struct vec2i pos, const FontOpts opts)
|
||||
{
|
||||
const struct vec2i textSize = FontStrSize(s);
|
||||
return svec2i(
|
||||
@@ -290,8 +281,8 @@ static struct vec2i GetStrPos(const char *s, struct vec2i pos, const FontOpts op
|
||||
GetAlign(opts.VAlign, pos.y, opts.Pad.y, opts.Area.y, textSize.y));
|
||||
}
|
||||
static int GetAlign(
|
||||
const FontAlign align,
|
||||
const int pos, const int pad, const int area, const int size)
|
||||
const FontAlign align, const int pos, const int pad, const int area,
|
||||
const int size)
|
||||
{
|
||||
switch (align)
|
||||
{
|
||||
@@ -385,8 +376,8 @@ void FontSplitLines(const char *text, char *buf, const int width)
|
||||
}
|
||||
|
||||
struct vec2i Vec2iAligned(
|
||||
const struct vec2i v, const struct vec2i size,
|
||||
const FontAlign hAlign, const FontAlign vAlign, const struct vec2i area)
|
||||
const struct vec2i v, const struct vec2i size, const FontAlign hAlign,
|
||||
const FontAlign vAlign, const struct vec2i area)
|
||||
{
|
||||
struct vec2i vAligned = v;
|
||||
switch (hAlign)
|
||||
|
@@ -1,78 +1,72 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (C) 1995 Ronny Wester
|
||||
Copyright (C) 2003 Jeremy Chin
|
||||
Copyright (C) 2003-2007 Lucas Martin-King
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (C) 1995 Ronny Wester
|
||||
Copyright (C) 2003 Jeremy Chin
|
||||
Copyright (C) 2003-2007 Lucas Martin-King
|
||||
|
||||
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 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.
|
||||
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 the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2019 Cong Xu
|
||||
All rights reserved.
|
||||
Copyright (c) 2013-2019 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "grafx.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <SDL_events.h>
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <SDL2/SDL_image.h>
|
||||
#else
|
||||
#include <SDL_image.h>
|
||||
#endif
|
||||
#include <SDL_mouse.h>
|
||||
|
||||
#include "blit.h"
|
||||
#include "config.h"
|
||||
#include "defs.h"
|
||||
#include "draw/drawtools.h"
|
||||
#include "files.h"
|
||||
#include "font_utils.h"
|
||||
#include "grafx_bg.h"
|
||||
#include "log.h"
|
||||
#include "palette.h"
|
||||
#include "files.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
GraphicsDevice gGraphicsDevice;
|
||||
|
||||
void GraphicsInit(GraphicsDevice *device, Config *c)
|
||||
@@ -96,7 +90,7 @@ void GraphicsInitialize(GraphicsDevice *g)
|
||||
{
|
||||
char buf[CDOGS_PATH_MAX];
|
||||
GetDataFilePath(buf, "graphics/cdogs_icon.bmp");
|
||||
g->icon = IMG_Load(buf);
|
||||
g->icon = LoadImgToSurface(buf);
|
||||
g->IsWindowInitialized = true;
|
||||
}
|
||||
|
||||
@@ -105,19 +99,17 @@ void GraphicsInitialize(GraphicsDevice *g)
|
||||
const int w = g->cachedConfig.Res.x;
|
||||
const int h = g->cachedConfig.Res.y;
|
||||
|
||||
const bool initWindow =
|
||||
!!(g->cachedConfig.RestartFlags & RESTART_WINDOW);
|
||||
const bool initTextures =
|
||||
!!(g->cachedConfig.RestartFlags &
|
||||
(RESTART_WINDOW | RESTART_SCALE_MODE));
|
||||
const bool initWindow = !!(g->cachedConfig.RestartFlags & RESTART_WINDOW);
|
||||
const bool initTextures = !!(
|
||||
g->cachedConfig.RestartFlags & (RESTART_WINDOW | RESTART_SCALE_MODE));
|
||||
const bool initBrightness =
|
||||
!!(g->cachedConfig.RestartFlags &
|
||||
(RESTART_WINDOW | RESTART_SCALE_MODE | RESTART_BRIGHTNESS));
|
||||
(RESTART_WINDOW | RESTART_SCALE_MODE | RESTART_BRIGHTNESS));
|
||||
|
||||
if (initWindow)
|
||||
{
|
||||
LOG(LM_GFX, LL_INFO, "graphics mode(%dx%d %dx%s)",
|
||||
w, h, g->cachedConfig.ScaleFactor,
|
||||
LOG(LM_GFX, LL_INFO, "graphics mode(%dx%d %dx%s)", w, h,
|
||||
g->cachedConfig.ScaleFactor,
|
||||
g->cachedConfig.Fullscreen ? " fullscreen" : "");
|
||||
|
||||
Uint32 windowFlags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
@@ -125,9 +117,7 @@ void GraphicsInitialize(GraphicsDevice *g)
|
||||
svec2i(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED),
|
||||
svec2i(
|
||||
ConfigGetInt(&gConfig, "Graphics.WindowWidth"),
|
||||
ConfigGetInt(&gConfig, "Graphics.WindowHeight")
|
||||
)
|
||||
);
|
||||
ConfigGetInt(&gConfig, "Graphics.WindowHeight")));
|
||||
if (g->cachedConfig.Fullscreen)
|
||||
{
|
||||
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
@@ -139,9 +129,9 @@ void GraphicsInitialize(GraphicsDevice *g)
|
||||
SDL_FreeFormat(g->Format);
|
||||
|
||||
char title[32];
|
||||
sprintf(title, "C-Dogs SDL %s%s",
|
||||
g->cachedConfig.IsEditor ? "Editor " : "",
|
||||
CDOGS_SDL_VERSION);
|
||||
sprintf(
|
||||
title, "C-Dogs SDL %s%s",
|
||||
g->cachedConfig.IsEditor ? "Editor " : "", CDOGS_SDL_VERSION);
|
||||
if (!WindowContextCreate(
|
||||
&g->gameWindow, windowDim, windowFlags, title, g->icon,
|
||||
svec2i(w, h)))
|
||||
@@ -315,16 +305,15 @@ int GraphicsGetMemSize(GraphicsConfig *config)
|
||||
}
|
||||
|
||||
void GraphicsConfigSet(
|
||||
GraphicsConfig *c,
|
||||
struct vec2i windowSize, const bool fullscreen,
|
||||
GraphicsConfig *c, struct vec2i windowSize, const bool fullscreen,
|
||||
const int scaleFactor, const ScaleMode scaleMode, const int brightness,
|
||||
const bool secondWindow)
|
||||
{
|
||||
#define SET(_lhs, _rhs, _flag) \
|
||||
if ((_lhs) != (_rhs)) \
|
||||
{ \
|
||||
(_lhs) = (_rhs); \
|
||||
c->RestartFlags |= (_flag); \
|
||||
#define SET(_lhs, _rhs, _flag) \
|
||||
if ((_lhs) != (_rhs)) \
|
||||
{ \
|
||||
(_lhs) = (_rhs); \
|
||||
c->RestartFlags |= (_flag); \
|
||||
}
|
||||
SET(c->Fullscreen, fullscreen, RESTART_WINDOW);
|
||||
if (c->Fullscreen)
|
||||
@@ -371,7 +360,7 @@ void GraphicsConfigSetFromConfig(GraphicsConfig *gc, Config *c)
|
||||
|
||||
void GraphicsSetClip(SDL_Renderer *renderer, const Rect2i r)
|
||||
{
|
||||
const SDL_Rect rect = { r.Pos.x, r.Pos.y, r.Size.x, r.Size.y };
|
||||
const SDL_Rect rect = {r.Pos.x, r.Pos.y, r.Size.x, r.Size.y};
|
||||
if (SDL_RenderSetClipRect(renderer, Rect2iIsZero(r) ? NULL : &rect) != 0)
|
||||
{
|
||||
LOG(LM_MAIN, LL_ERROR, "Could not set clip rect: %s", SDL_GetError());
|
||||
@@ -389,6 +378,7 @@ void GraphicsResetClip(SDL_Renderer *renderer)
|
||||
{
|
||||
if (SDL_RenderSetClipRect(renderer, NULL) != 0)
|
||||
{
|
||||
LOG(LM_MAIN, LL_ERROR, "Could not reset clip rect: %s", SDL_GetError());
|
||||
LOG(LM_MAIN, LL_ERROR, "Could not reset clip rect: %s",
|
||||
SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
@@ -27,12 +27,6 @@
|
||||
*/
|
||||
#include "pic_manager.h"
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <SDL2/SDL_image.h>
|
||||
#else
|
||||
#include <SDL_image.h>
|
||||
#endif
|
||||
|
||||
#include <tinydir/tinydir.h>
|
||||
|
||||
#include "files.h"
|
||||
@@ -45,11 +39,6 @@ PicManager gPicManager;
|
||||
|
||||
void PicManagerInit(PicManager *pm)
|
||||
{
|
||||
if (!IMG_Init(IMG_INIT_PNG))
|
||||
{
|
||||
perror("Cannot initialise SDL_Image");
|
||||
return;
|
||||
}
|
||||
memset(pm, 0, sizeof *pm);
|
||||
pm->pics = hashmap_new();
|
||||
pm->sprites = hashmap_new();
|
||||
@@ -214,35 +203,28 @@ void PicManagerLoadDir(
|
||||
strerror(errno));
|
||||
goto bail;
|
||||
}
|
||||
if (file.is_reg)
|
||||
if (file.is_reg && Stricmp(file.extension, "png") == 0)
|
||||
{
|
||||
SDL_RWops *rwops = SDL_RWFromFile(file.path, "rb");
|
||||
const bool isPng = IMG_isPNG(rwops);
|
||||
if (isPng)
|
||||
SDL_Surface *data = LoadImgToSurface(file.path);
|
||||
if (!data)
|
||||
{
|
||||
SDL_Surface *data = IMG_Load_RW(rwops, 0);
|
||||
if (!data)
|
||||
LOG(LM_MAIN, LL_ERROR, "Cannot load image");
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[CDOGS_PATH_MAX];
|
||||
if (prefix)
|
||||
{
|
||||
LOG(LM_MAIN, LL_ERROR, "Cannot load image IMG_Load: %s",
|
||||
IMG_GetError());
|
||||
char buf1[CDOGS_PATH_MAX];
|
||||
sprintf(buf1, "%s/%s", prefix, file.name);
|
||||
PathGetWithoutExtension(buf, buf1);
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[CDOGS_PATH_MAX];
|
||||
if (prefix)
|
||||
{
|
||||
char buf1[CDOGS_PATH_MAX];
|
||||
sprintf(buf1, "%s/%s", prefix, file.name);
|
||||
PathGetWithoutExtension(buf, buf1);
|
||||
}
|
||||
else
|
||||
{
|
||||
PathGetBasenameWithoutExtension(buf, file.name);
|
||||
}
|
||||
PicManagerAdd(pics, sprites, buf, data, isHD);
|
||||
PathGetBasenameWithoutExtension(buf, file.name);
|
||||
}
|
||||
PicManagerAdd(pics, sprites, buf, data, isHD);
|
||||
}
|
||||
rwops->close(rwops);
|
||||
}
|
||||
else if (file.is_dir && file.name[0] != '.')
|
||||
{
|
||||
@@ -501,7 +483,6 @@ void PicManagerTerminate(PicManager *pm)
|
||||
StyleNamesDestroy(&pm->exitStyleNames);
|
||||
StyleNamesDestroy(&pm->doorStyleNames);
|
||||
StyleNamesDestroy(&pm->keyStyleNames);
|
||||
IMG_Quit();
|
||||
}
|
||||
static void NamedPicDestroy(any_t data)
|
||||
{
|
||||
|
37
src/cdogs/stb/LICENSE.txt
Normal file
37
src/cdogs/stb/LICENSE.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
786
src/cdogs/stb/SDL_stbimage.h
Normal file
786
src/cdogs/stb/SDL_stbimage.h
Normal file
@@ -0,0 +1,786 @@
|
||||
/*
|
||||
* A small header-only library to load an image into a RGB(A) SDL_Surface*,
|
||||
* like a stripped down version of SDL_Image, but using stb_image.h to decode
|
||||
* images and thus without any further external dependencies.
|
||||
* Supports all filetypes supported by stb_image (JPEG, PNG, TGA, BMP, PSD, ...
|
||||
* See stb_image.h for details).
|
||||
*
|
||||
* (C) 2015-2021 Daniel Gibson
|
||||
*
|
||||
* Homepage: https://github.com/DanielGibson/Snippets/
|
||||
*
|
||||
* Dependencies:
|
||||
* libSDL2 http://www.libsdl.org
|
||||
* stb_image.h https://github.com/nothings/stb
|
||||
*
|
||||
* Usage:
|
||||
* Put this file and stb_image.h somewhere in your project.
|
||||
* In *one* of your .c/.cpp files, do
|
||||
* #define SDL_STBIMAGE_IMPLEMENTATION
|
||||
* #include "SDL_stbimage.h"
|
||||
* to create the implementation of this library in that file.
|
||||
* You can just #include "SDL_stbimage.h" (without the #define) in other source
|
||||
* files to use it there. (See also below this comment for an usage example)
|
||||
* This header implicitly #includes <SDL.h> and "stb_image.h".
|
||||
*
|
||||
* NOTE: When using SDL3, either #include <SDL3/SDL.h> before this header,
|
||||
* or #define SDL_STBIMG_SDL3 before including it.
|
||||
*
|
||||
* You can #define SDL_STBIMG_DEF before including this header if you want to
|
||||
* prepend anything to the function signatures (like "static", "inline",
|
||||
* "__declspec(dllexport)", ...)
|
||||
* Example: #define SDL_STBIMG_DEF static inline
|
||||
*
|
||||
* By default, this deactivates stb_image's load from file functions via
|
||||
* #define STBI_NO_STDIO, as they use stdio.h and that adds a dependency to the
|
||||
* CRT on windows and with SDL you're better off using SDL_RWops, incl. SDL_RWFromFile()
|
||||
* (or the SDL3 equivalents: SDL_IOStream, SDL_IOFromFile())
|
||||
* If you wanna use stbi_load(), stbi_info(), stbi_load_from_file() etc anyway, do
|
||||
* #define SDL_STBIMG_ALLOW_STDIO
|
||||
* before including this header.
|
||||
* (Note that all the STBIMG_* functions of this lib will work without it)
|
||||
*
|
||||
* stb_image.h uses assert.h by default. You can #define STBI_ASSERT(x)
|
||||
* before the implementation-#include of SDL_stbimage.h to avoid that.
|
||||
* By default stb_image supports HDR images, for that it needs pow() from libm.
|
||||
* If you don't need HDR (it can't be loaded into a SDL_Surface anyway),
|
||||
* #define STBI_NO_LINEAR and #define STBI_NO_HDR before including this header.
|
||||
*
|
||||
* License:
|
||||
* This software is dual-licensed to the public domain and under the following
|
||||
* license: you are granted a perpetual, irrevocable license to copy, modify,
|
||||
* publish, and distribute this file as you see fit.
|
||||
* No warranty implied; use at your own risk.
|
||||
*
|
||||
* So you can do whatever you want with this code, including copying it
|
||||
* (or parts of it) into your own source.
|
||||
* No need to mention me or this "license" in your code or docs, even though
|
||||
* it would be appreciated, of course.
|
||||
*/
|
||||
|
||||
#if 0 // Usage Example:
|
||||
#define SDL_STBIMAGE_IMPLEMENTATION
|
||||
#include "SDL_stbimage.h"
|
||||
|
||||
void yourFunction(const char* imageFilePath)
|
||||
{
|
||||
SDL_Surface* surf = STBIMG_Load(imageFilePath);
|
||||
if(surf == NULL) {
|
||||
printf("ERROR: Couldn't load %s, reason: %s\n", imageFilePath, SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// ... do something with surf ...
|
||||
|
||||
SDL_FreeSurface(surf); // or SDL_DestroySurface(surf); for SDL3
|
||||
}
|
||||
#endif // 0 (usage example)
|
||||
|
||||
|
||||
#ifndef _SDL_STBIMAGE_H
|
||||
#define _SDL_STBIMAGE_H
|
||||
|
||||
// for SDL3, you either can #define SDL_STBIMG_SDL3 yourself
|
||||
// OR #include <SDL3/SDL.h> yourself before this header
|
||||
// (the following lines handle for the second case)
|
||||
#ifndef SDL_VERSION_ATLEAST
|
||||
#ifdef SDL_STBIMG_SDL3
|
||||
// in SDL3 this is the official way to include SDL.h
|
||||
#include <SDL3/SDL.h>
|
||||
#else // SDL2 and SDL1.2
|
||||
// if you really think you need <SDL2/SDL.h> here instead.. feel free to change it,
|
||||
// but the cool kids have path/to/include/SDL2/ in their compilers include path.
|
||||
// (meaning, that's how was supposed to be done for SDL2 and what sdl2-config supports)
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
// else if it *is* defined, SDL.h was already included before including this header.
|
||||
// now, after including the headers, it definitely is available.
|
||||
#endif // SDL_VERSION_ATLEAST not defined
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(3, 0, 0) && !defined(__cpluscplus)
|
||||
// allow using bool. In C++ it's a builtin type,
|
||||
// in SDL3 SDL_stdinc.h (through SDL.h) makes sure it's available
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifndef SDL_STBIMG_ALLOW_STDIO
|
||||
#define STBI_NO_STDIO // don't need STDIO, will use SDL_RWops to open files
|
||||
#endif
|
||||
#include "stb_image.h"
|
||||
|
||||
// this allows you to prepend stuff to function signatures, e.g. "static"
|
||||
#ifndef SDL_STBIMG_DEF
|
||||
// by default it's empty
|
||||
#define SDL_STBIMG_DEF
|
||||
#endif // DG_MISC_DEF
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// loads the image file at the given path into a RGB(A) SDL_Surface
|
||||
// Returns NULL on error, use SDL_GetError() to get more information.
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_Load(const char* file);
|
||||
|
||||
// loads the image file in the given memory buffer into a RGB(A) SDL_Surface
|
||||
// Returns NULL on error, use SDL_GetError() to get more information.
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_LoadFromMemory(const unsigned char* buffer, int length);
|
||||
|
||||
|
||||
// loads an image file into a RGB(A) SDL_Surface from a seekable SDL_IOStream/SDL_RWops (src)
|
||||
// if you set freesrc to true, SDL_CloseIO(src)/SDL_RWclose(src) will be executed after reading.
|
||||
// Returns NULL on error, use SDL_GetError() to get more information.
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_Load_IO(SDL_IOStream* src, bool freesrc);
|
||||
#else // SDL2 or SDL1.2
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_Load_RW(SDL_RWops* src, bool freesrc);
|
||||
#endif
|
||||
|
||||
// Creates an SDL_Surface* using the raw RGB(A) pixelData with given width/height
|
||||
// (this doesn't use stb_image and is just a simple SDL_CreateSurfaceFrom()-wrapper)
|
||||
// ! It must be byte-wise 24bit RGB ("888", bytesPerPixel=3) !
|
||||
// ! or byte-wise 32bit RGBA ("8888", bytesPerPixel=4) data !
|
||||
// If freeWithSurface is true, SDL_FreeSurface() will free the pixelData
|
||||
// you passed with SDL_free() - NOTE that you should only do that if pixelData
|
||||
// was allocated with SDL_malloc(), SDL_calloc() or SDL_realloc()!
|
||||
// Returns NULL on error (in that case pixelData won't be freed!),
|
||||
// use SDL_GetError() to get more information.
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_CreateSurface(unsigned char* pixelData, int width, int height,
|
||||
int bytesPerPixel, bool freeWithSurface);
|
||||
|
||||
#if SDL_MAJOR_VERSION > 1
|
||||
// loads the image file at the given path into a RGB(A) SDL_Texture
|
||||
// Returns NULL on error, use SDL_GetError() to get more information.
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_LoadTexture(SDL_Renderer* renderer, const char* file);
|
||||
|
||||
// loads the image file in the given memory buffer into a RGB(A) SDL_Texture
|
||||
// Returns NULL on error, use SDL_GetError() to get more information.
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_LoadTextureFromMemory(SDL_Renderer* renderer, const unsigned char* buffer, int length);
|
||||
|
||||
// loads an image file into a RGB(A) SDL_Texture from a seekable SDL_IOStream/SDL_RWops (src)
|
||||
// if you set freesrc to true, SDL_CloseIO(src)/SDL_RWclose(src) will be executed after reading.
|
||||
// Returns NULL on error, use SDL_GetError() to get more information.
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_LoadTexture_IO(SDL_Renderer* renderer, SDL_IOStream* src, bool freesrc);
|
||||
#else // SDL2
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_LoadTexture_RW(SDL_Renderer* renderer, SDL_RWops* src, bool freesrc);
|
||||
#endif
|
||||
|
||||
// Creates an SDL_Texture* using the raw RGB(A) pixelData with given width/height
|
||||
// (this doesn't use stb_image and is just a simple SDL_CreateSurfaceFrom()-wrapper)
|
||||
// ! It must be byte-wise 24bit RGB ("888", bytesPerPixel=3) !
|
||||
// ! or byte-wise 32bit RGBA ("8888", bytesPerPixel=4) data !
|
||||
// Returns NULL on error, use SDL_GetError() to get more information.
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_CreateTexture(SDL_Renderer* renderer, const unsigned char* pixelData,
|
||||
int width, int height, int bytesPerPixel);
|
||||
#endif // SDL_MAJOR_VERSION > 1
|
||||
|
||||
|
||||
typedef struct {
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_IOStream* src;
|
||||
#else
|
||||
SDL_RWops* src;
|
||||
#endif
|
||||
stbi_io_callbacks stb_cbs;
|
||||
int atEOF; // defaults to 0; 1: reached EOF or error on read, 2: error on seek
|
||||
} STBIMG_stbio_RWops;
|
||||
|
||||
// creates stbi_io_callbacks and userdata to use stbi_*_from_callbacks() directly,
|
||||
// especially useful to use SDL_IOStream/SDL_RWops with stb_image, without using SDL_Surface
|
||||
// src must be readable and seekable!
|
||||
// Returns false on error (SDL_GetError() will give you info), else true
|
||||
// NOTE: If you want to use src twice (e.g. for info and load), remember to rewind
|
||||
// it by seeking back to its initial position and resetting out->atEOF to 0
|
||||
// inbetween the uses!
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_STBIMG_DEF bool STBIMG_stbi_callback_from_IO(SDL_IOStream* src, STBIMG_stbio_RWops* out);
|
||||
#else
|
||||
SDL_STBIMG_DEF bool STBIMG_stbi_callback_from_RW(SDL_RWops* src, STBIMG_stbio_RWops* out);
|
||||
#endif
|
||||
|
||||
#if 0 // Use STBIMG_stbi_callback_from_RW() like this:
|
||||
SDL_RWops* src = ...; // wherever it's from
|
||||
STBIMG_stbio_RWops io;
|
||||
if(!STBIMG_stbi_callback_from_RW(src, &io)) {
|
||||
printf("ERROR creating stbio callbacks: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
Sint64 origSrcPosition = SDL_RWtell(src);
|
||||
int w, h, fmt;
|
||||
if(!stbi_info_from_callbacks(&io.stb_cbs, &io, &w, &h, &fmt)) {
|
||||
printf("stbi_info_from_callbacks() failed, reason: %s\n", stbi_failure_reason());
|
||||
exit(1);
|
||||
}
|
||||
printf("image is %d x %d pixels with %d bytes per pixel\n", w, h, fmt);
|
||||
|
||||
// rewind src before using it again in stbi_load_from_callbacks()
|
||||
if(SDL_RWseek(src, origSrcPosition, RW_SEEK_SET) < 0)
|
||||
{
|
||||
printf("ERROR: src not be seekable!\n");
|
||||
exit(1);
|
||||
}
|
||||
io.atEOF = 0; // remember to reset atEOF, too!
|
||||
|
||||
unsigned char* data;
|
||||
data = stbi_load_from_callbacks(&io.stb_cbs, &io, &w, &h, &fmt, 0);
|
||||
if(data == NULL) {
|
||||
printf("stbi_load_from_callbacks() failed, reason: %s\n", stbi_failure_reason());
|
||||
exit(1);
|
||||
}
|
||||
// ... do something with data ...
|
||||
stbi_image_free(data);
|
||||
#endif // 0 (STBIMG_stbi_callback_from_RW() example)
|
||||
|
||||
|
||||
#if SDL_MAJOR_VERSION > 1
|
||||
// loads an image file into a RGB(A) SDL_Surface from a SDL_RWops/SDL_IOStream (src)
|
||||
// - without using SDL_RWseek()/SDL_SeekIO, for streams that don't support or are slow
|
||||
// at seeking. It reads everything into a buffer and calls STBIMG_LoadFromMemory()
|
||||
// You should probably only use this if you *really* have performance problems
|
||||
// because of seeking or your src doesn't support SDL_RWseek()/SDL_SeekIO, but SDL_RWsize()/SDL_GetIOSize
|
||||
// src must at least support SDL_RWread()/SDL_ReadIO() and SDL_RWsize()/SDL_GetIOSize
|
||||
// if you set freesrc to true, SDL_RWclose(src)/SDL_CloseIO(src) will be executed after reading.
|
||||
// Returns NULL on error, use SDL_GetError() to get more information.
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_Load_IO_noSeek(SDL_IOStream* src, bool freesrc);
|
||||
#else
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_Load_RW_noSeek(SDL_RWops* src, bool freesrc);
|
||||
#endif
|
||||
|
||||
// the same for textures (you should probably not use this one, either..)
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_STBIMG_DEF SDL_Texture* STBIMG_LoadTexture_IO_noSeek(SDL_Renderer* renderer, SDL_IOStream* src, bool freesrc);
|
||||
#else
|
||||
SDL_STBIMG_DEF SDL_Texture* STBIMG_LoadTexture_RW_noSeek(SDL_Renderer* renderer, SDL_RWops* src, bool freesrc);
|
||||
#endif
|
||||
|
||||
#endif // SDL_MAJOR_VERSION > 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
// provide backwards-compatibility for the function names
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#define STBIMG_Load_RW STBIMG_Load_IO
|
||||
#define STBIMG_LoadTexture_RW STBIMG_LoadTexture_IO
|
||||
#define STBIMG_stbi_callback_from_RW STBIMG_stbi_callback_from_IO
|
||||
#define STBIMG_Load_RW_noSeek STBIMG_Load_IO_noSeek
|
||||
#define STBIMG_LoadTexture_RW_noSeek STBIMG_LoadTexture_IO_noSeek
|
||||
#endif
|
||||
|
||||
#endif // _SDL_STBIMAGE_H
|
||||
|
||||
|
||||
// ############# Below: Implementation ###############
|
||||
|
||||
|
||||
#ifdef SDL_STBIMAGE_IMPLEMENTATION
|
||||
|
||||
// make stb_image use SDL_malloc etc, so SDL_FreeSurface() can SDL_free()
|
||||
// the data allocated by stb_image
|
||||
#define STBI_MALLOC SDL_malloc
|
||||
#define STBI_REALLOC SDL_realloc
|
||||
#define STBI_FREE SDL_free
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#ifndef SDL_STBIMG_ALLOW_STDIO
|
||||
#define STBI_NO_STDIO // don't need STDIO, will use SDL_RWops to open files
|
||||
#endif
|
||||
#include "stb_image.h"
|
||||
|
||||
// Note: In the header part above I kept things simple, but here
|
||||
// I'm using macros to unify SDL1.2/SDL2 and SDL3 RWops/IOStream code
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
|
||||
#define _STBIMG_RWops SDL_IOStream
|
||||
|
||||
#define _STBIMG_RW_SEEK_CUR SDL_IO_SEEK_CUR
|
||||
#define _STBIMG_RW_SEEK_SET SDL_IO_SEEK_SET
|
||||
|
||||
#define _STBIMG_RWread(CTX, PTR, SIZE) SDL_ReadIO(CTX, PTR, SIZE)
|
||||
#define _STBIMG_RWseek(CTX, OFFSET, WHENCE) SDL_SeekIO(CTX, OFFSET, WHENCE)
|
||||
#define _STBIMG_RWtell(CTX) SDL_TellIO(CTX)
|
||||
#define _STBIMG_RWclose(CTX) SDL_CloseIO(CTX)
|
||||
#define _STBIMG_RWsize(CTX) SDL_GetIOSize(CTX)
|
||||
#define _STBIMG_RWFromFile(FILENAME, MODE) SDL_IOFromFile(FILENAME, MODE)
|
||||
|
||||
#else // SDL2 or SDL1.2
|
||||
|
||||
#define _STBIMG_RWops SDL_RWops
|
||||
|
||||
#define _STBIMG_RW_SEEK_CUR RW_SEEK_CUR
|
||||
#define _STBIMG_RW_SEEK_SET RW_SEEK_SET
|
||||
|
||||
#define _STBIMG_RWread(CTX, PTR, SIZE) SDL_RWread(CTX, PTR, 1, SIZE)
|
||||
#define _STBIMG_RWseek(CTX, OFFSET, WHENCE) SDL_RWseek(CTX, OFFSET, WHENCE)
|
||||
#define _STBIMG_RWtell(CTX) SDL_RWtell(CTX)
|
||||
#define _STBIMG_RWclose(CTX) SDL_RWclose(CTX)
|
||||
#define _STBIMG_RWsize(CTX) SDL_RWsize(CTX)
|
||||
#define _STBIMG_RWFromFile(FILENAME, MODE) SDL_RWFromFile(FILENAME, MODE)
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned char* data;
|
||||
int w;
|
||||
int h;
|
||||
int format; // 3: RGB, 4: RGBA
|
||||
} _STBIMG_image;
|
||||
|
||||
static SDL_Surface* _STBIMG_CreateSurfaceImpl(_STBIMG_image img, int freeWithSurface)
|
||||
{
|
||||
SDL_Surface* surf = NULL;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
|
||||
Uint32 format = (img.format == STBI_rgb) ? SDL_PIXELFORMAT_RGB24 : SDL_PIXELFORMAT_RGBA32;
|
||||
surf = SDL_CreateSurfaceFrom(img.w, img.h, format, img.data, img.format*img.w);
|
||||
|
||||
#elif SDL_VERSION_ATLEAST(2, 0, 5)
|
||||
|
||||
// SDL 2.0.5 introduced SDL_CreateRGBSurfaceWithFormatFrom() and SDL_PIXELFORMAT_RGBA32
|
||||
// which makes this code much simpler.
|
||||
|
||||
Uint32 format = (img.format == STBI_rgb) ? SDL_PIXELFORMAT_RGB24 : SDL_PIXELFORMAT_RGBA32;
|
||||
|
||||
surf = SDL_CreateRGBSurfaceWithFormatFrom((void*)img.data, img.w, img.h,
|
||||
img.format*8, img.format*img.w, format);
|
||||
|
||||
#else // older SDL2 version without SDL_CreateRGBSurfaceWithFormatFrom()
|
||||
|
||||
Uint32 rmask, gmask, bmask, amask;
|
||||
// ok, the following is pretty stupid.. SDL_CreateRGBSurfaceFrom() pretends to use
|
||||
// a void* for the data, but it's really treated as endian-specific Uint32*
|
||||
// and there isn't even an SDL_PIXELFORMAT_* for 32bit byte-wise RGBA
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
int shift = (img.format == STBI_rgb) ? 8 : 0;
|
||||
rmask = 0xff000000 >> shift;
|
||||
gmask = 0x00ff0000 >> shift;
|
||||
bmask = 0x0000ff00 >> shift;
|
||||
amask = 0x000000ff >> shift;
|
||||
#else // little endian, like x86
|
||||
rmask = 0x000000ff;
|
||||
gmask = 0x0000ff00;
|
||||
bmask = 0x00ff0000;
|
||||
amask = (img.format == STBI_rgb) ? 0 : 0xff000000;
|
||||
#endif
|
||||
|
||||
surf = SDL_CreateRGBSurfaceFrom((void*)img.data, img.w, img.h,
|
||||
img.format*8, img.format*img.w,
|
||||
rmask, gmask, bmask, amask);
|
||||
#endif // SDL_VERSION_ATLEAST
|
||||
|
||||
if(surf == NULL)
|
||||
{
|
||||
// hopefully SDL_CreateRGBSurfaceFrom() has set an sdl error
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(freeWithSurface)
|
||||
{
|
||||
// SDL_Surface::flags is documented to be read-only.. but if the pixeldata
|
||||
// has been allocated with SDL_malloc()/SDL_calloc()/SDL_realloc() this
|
||||
// should work (and it currently does) + @icculus said it's reasonably safe:
|
||||
// https://twitter.com/icculus/status/667036586610139137 :-)
|
||||
// clear the SDL_PREALLOC flag, so SDL_FreeSurface() free()s the data passed from img.data
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
// I hope that's still true for SDL3 :-p
|
||||
surf->flags &= ~SDL_SURFACE_PREALLOCATED;
|
||||
#else
|
||||
surf->flags &= ~SDL_PREALLOC;
|
||||
#endif
|
||||
}
|
||||
|
||||
return surf;
|
||||
}
|
||||
|
||||
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_LoadFromMemory(const unsigned char* buffer, int length)
|
||||
{
|
||||
_STBIMG_image img = {0};
|
||||
int bppToUse = 0;
|
||||
int inforet = 0;
|
||||
SDL_Surface* ret = NULL;
|
||||
|
||||
if(buffer == NULL)
|
||||
{
|
||||
SDL_SetError("STBIMG_LoadFromMemory(): passed buffer was NULL!");
|
||||
return NULL;
|
||||
}
|
||||
if(length <= 0)
|
||||
{
|
||||
SDL_SetError("STBIMG_LoadFromMemory(): passed invalid length: %d!", length);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inforet = stbi_info_from_memory(buffer, length, &img.w, &img.h, &img.format);
|
||||
if(!inforet)
|
||||
{
|
||||
SDL_SetError("STBIMG_LoadFromMemory(): Couldn't get image info: %s!\n", stbi_failure_reason());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// no alpha => use RGB, else use RGBA
|
||||
bppToUse = (img.format == STBI_grey || img.format == STBI_rgb) ? STBI_rgb : STBI_rgb_alpha;
|
||||
|
||||
img.data = stbi_load_from_memory(buffer, length, &img.w, &img.h, &img.format, bppToUse);
|
||||
if(img.data == NULL)
|
||||
{
|
||||
SDL_SetError("STBIMG_LoadFromMemory(): Couldn't load image: %s!\n", stbi_failure_reason());
|
||||
return NULL;
|
||||
}
|
||||
img.format = bppToUse;
|
||||
|
||||
ret = _STBIMG_CreateSurfaceImpl(img, 1);
|
||||
|
||||
if(ret == NULL)
|
||||
{
|
||||
// no need to log an error here, it was an SDL error which should still be available through SDL_GetError()
|
||||
SDL_free(img.data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// fill 'data' with 'size' bytes. return number of bytes actually read
|
||||
static int _STBIMG_io_read(void* user, char* data, int size)
|
||||
{
|
||||
STBIMG_stbio_RWops* io = (STBIMG_stbio_RWops*)user;
|
||||
|
||||
size_t ret = _STBIMG_RWread(io->src, data, size*sizeof(char));
|
||||
if(ret == 0)
|
||||
{
|
||||
// we're at EOF or some error happend
|
||||
io->atEOF = 1;
|
||||
}
|
||||
return (int)ret*sizeof(char);
|
||||
}
|
||||
|
||||
// skip the next 'n' bytes, or 'unget' the last -n bytes if negative
|
||||
static void _STBIMG_io_skip(void* user, int n)
|
||||
{
|
||||
STBIMG_stbio_RWops* io = (STBIMG_stbio_RWops*)user;
|
||||
|
||||
if(_STBIMG_RWseek(io->src, n, _STBIMG_RW_SEEK_CUR) == -1)
|
||||
{
|
||||
// an error happened during seeking, hopefully setting EOF will make stb_image abort
|
||||
io->atEOF = 2; // set this to 2 for "aborting because seeking failed" (stb_image only cares about != 0)
|
||||
}
|
||||
}
|
||||
|
||||
// returns nonzero if we are at end of file/data
|
||||
static int _STBIMG_io_eof(void* user)
|
||||
{
|
||||
STBIMG_stbio_RWops* io = (STBIMG_stbio_RWops*)user;
|
||||
return io->atEOF;
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_STBIMG_DEF bool STBIMG_stbi_callback_from_IO(_STBIMG_RWops* src, STBIMG_stbio_RWops* out)
|
||||
#else
|
||||
SDL_STBIMG_DEF bool STBIMG_stbi_callback_from_RW(_STBIMG_RWops* src, STBIMG_stbio_RWops* out)
|
||||
#endif
|
||||
{
|
||||
if(out == NULL)
|
||||
{
|
||||
SDL_SetError("STBIMG_stbi_callback_from_RW(): out must not be NULL!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure out is at least initialized to something deterministic
|
||||
memset(out, 0, sizeof(*out));
|
||||
|
||||
if(src == NULL)
|
||||
{
|
||||
SDL_SetError("STBIMG_stbi_callback_from_RW(): src must not be NULL!");
|
||||
return false;
|
||||
}
|
||||
|
||||
out->src = src;
|
||||
out->atEOF = 0;
|
||||
out->stb_cbs.read = _STBIMG_io_read;
|
||||
out->stb_cbs.skip = _STBIMG_io_skip;
|
||||
out->stb_cbs.eof = _STBIMG_io_eof;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_Load_IO(_STBIMG_RWops* src, bool freesrc)
|
||||
#else
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_Load_RW(_STBIMG_RWops* src, bool freesrc)
|
||||
#endif
|
||||
{
|
||||
_STBIMG_image img = {0};
|
||||
int bppToUse = 0;
|
||||
int inforet = 0;
|
||||
SDL_Surface* ret = NULL;
|
||||
Sint64 srcOffset = 0;
|
||||
|
||||
STBIMG_stbio_RWops cbData;
|
||||
|
||||
if(src == NULL)
|
||||
{
|
||||
SDL_SetError("STBIMG_Load_RW(): src was NULL!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
srcOffset = _STBIMG_RWtell(src);
|
||||
if(srcOffset < 0)
|
||||
{
|
||||
SDL_SetError("STBIMG_Load_RW(): src must be seekable, maybe use STBIMG_Load_RW_noSeek() instead!");
|
||||
// TODO: or do that automatically? but I think the user should be aware of what they're doing
|
||||
goto end;
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
if(!STBIMG_stbi_callback_from_IO(src, &cbData))
|
||||
#else
|
||||
if(!STBIMG_stbi_callback_from_RW(src, &cbData))
|
||||
#endif
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
inforet = stbi_info_from_callbacks(&cbData.stb_cbs, &cbData, &img.w, &img.h, &img.format);
|
||||
if(!inforet)
|
||||
{
|
||||
if(cbData.atEOF == 2) SDL_SetError("STBIMG_Load_RW(): src must be seekable!");
|
||||
else SDL_SetError("STBIMG_Load_RW(): Couldn't get image info: %s!\n", stbi_failure_reason());
|
||||
goto end;
|
||||
}
|
||||
|
||||
// rewind src so stbi_load_from_callbacks() will start reading from the beginning again
|
||||
if(_STBIMG_RWseek(src, srcOffset, _STBIMG_RW_SEEK_SET) < 0)
|
||||
{
|
||||
SDL_SetError("STBIMG_Load_RW(): src must be seekable!");
|
||||
goto end;
|
||||
}
|
||||
|
||||
cbData.atEOF = 0; // we've rewinded (rewound?)
|
||||
|
||||
// no alpha => use RGB, else use RGBA
|
||||
bppToUse = (img.format == STBI_grey || img.format == STBI_rgb) ? STBI_rgb : STBI_rgb_alpha;
|
||||
|
||||
img.data = stbi_load_from_callbacks(&cbData.stb_cbs, &cbData, &img.w, &img.h, &img.format, bppToUse);
|
||||
if(img.data == NULL)
|
||||
{
|
||||
SDL_SetError("STBIMG_Load_RW(): Couldn't load image: %s!\n", stbi_failure_reason());
|
||||
goto end;
|
||||
}
|
||||
img.format = bppToUse;
|
||||
|
||||
ret = _STBIMG_CreateSurfaceImpl(img, 1);
|
||||
|
||||
if(ret == NULL)
|
||||
{
|
||||
// no need to log an error here, it was an SDL error which should still be available through SDL_GetError()
|
||||
SDL_free(img.data);
|
||||
img.data = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
if(freesrc)
|
||||
{
|
||||
_STBIMG_RWclose(src);
|
||||
}
|
||||
else if(img.data == NULL)
|
||||
{
|
||||
// if data is still NULL, there was an error and we should probably
|
||||
// seek src back to where it was when this function was called
|
||||
_STBIMG_RWseek(src, srcOffset, _STBIMG_RW_SEEK_SET);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if SDL_MAJOR_VERSION > 1
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_Load_IO_noSeek(_STBIMG_RWops* src, bool freesrc)
|
||||
#else
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_Load_RW_noSeek(_STBIMG_RWops* src, bool freesrc)
|
||||
#endif
|
||||
{
|
||||
unsigned char* buf = NULL;
|
||||
Sint64 fileSize = 0, bytesRead=0;
|
||||
SDL_Surface* ret = NULL;
|
||||
|
||||
if(src == NULL)
|
||||
{
|
||||
SDL_SetError("STBIMG_Load_RW_noSeek(): src was NULL!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fileSize = _STBIMG_RWsize(src);
|
||||
if(fileSize < 0)
|
||||
{
|
||||
goto end; // SDL should have set an error already
|
||||
}
|
||||
else if(fileSize == 0)
|
||||
{
|
||||
SDL_SetError("STBIMG_Load_RW_noSeek(): SDL_RWsize(src) returned 0 => empty file/stream?!");
|
||||
goto end;
|
||||
}
|
||||
else if(fileSize > 0x7FFFFFFF)
|
||||
{
|
||||
// stb_image.h uses ints for all sizes, so we can't support more
|
||||
// (but >2GB images are insane anyway)
|
||||
SDL_SetError("STBIMG_Load_RW_noSeek(): SDL_RWsize(src) too big (> 2GB)!");
|
||||
goto end;
|
||||
}
|
||||
|
||||
buf = (unsigned char*)SDL_malloc(fileSize);
|
||||
if(buf == NULL)
|
||||
{
|
||||
SDL_SetError("STBIMG_Load_RW_noSeek(): Couldn't allocate buffer to read src into!");
|
||||
goto end;
|
||||
}
|
||||
|
||||
while(bytesRead < fileSize) {
|
||||
size_t read = _STBIMG_RWread(src, buf+bytesRead, fileSize-bytesRead);
|
||||
if(read == 0) {
|
||||
// TODO: set error? SDL_RWread/SDL_ReadIO should set one, I think?
|
||||
goto end;
|
||||
}
|
||||
bytesRead += read;
|
||||
}
|
||||
|
||||
// if that fails, STBIMG_LoadFromMemory() has set an SDL error
|
||||
// and ret is NULL, so nothing special to do for us
|
||||
ret = STBIMG_LoadFromMemory(buf, (int)fileSize);
|
||||
|
||||
end:
|
||||
if(freesrc)
|
||||
{
|
||||
_STBIMG_RWclose(src);
|
||||
}
|
||||
|
||||
SDL_free(buf);
|
||||
return ret;
|
||||
}
|
||||
#endif // SDL_MAJOR_VERSION > 1
|
||||
|
||||
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_Load(const char* file)
|
||||
{
|
||||
_STBIMG_RWops* src = _STBIMG_RWFromFile(file, "rb");
|
||||
if(src == NULL) return NULL;
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
return STBIMG_Load_IO(src, 1);
|
||||
#else
|
||||
return STBIMG_Load_RW(src, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
SDL_STBIMG_DEF SDL_Surface* STBIMG_CreateSurface(unsigned char* pixelData, int width, int height, int bytesPerPixel, bool freeWithSurface)
|
||||
{
|
||||
_STBIMG_image img;
|
||||
|
||||
if(pixelData == NULL)
|
||||
{
|
||||
SDL_SetError("STBIMG_CreateSurface(): passed pixelData was NULL!");
|
||||
return NULL;
|
||||
}
|
||||
if(bytesPerPixel != 3 && bytesPerPixel != 4)
|
||||
{
|
||||
SDL_SetError("STBIMG_CreateSurface(): passed bytesPerPixel = %d, only 3 (24bit RGB) and 4 (32bit RGBA) are allowed!", bytesPerPixel);
|
||||
return NULL;
|
||||
}
|
||||
if(width <= 0 || height <= 0)
|
||||
{
|
||||
SDL_SetError("STBIMG_CreateSurface(): width and height must be > 0!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
img.data = pixelData;
|
||||
img.w = width;
|
||||
img.h = height;
|
||||
img.format = bytesPerPixel;
|
||||
|
||||
return _STBIMG_CreateSurfaceImpl(img, freeWithSurface);
|
||||
}
|
||||
|
||||
#if SDL_MAJOR_VERSION > 1
|
||||
static SDL_Texture* _STBIMG_SurfToTex(SDL_Renderer* renderer, SDL_Surface* surf)
|
||||
{
|
||||
SDL_Texture* ret = NULL;
|
||||
if(surf != NULL)
|
||||
{
|
||||
ret = SDL_CreateTextureFromSurface(renderer, surf);
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_DestroySurface(surf); // not needed anymore, it's copied into tex
|
||||
#else
|
||||
SDL_FreeSurface(surf); // not needed anymore, it's copied into tex
|
||||
#endif
|
||||
}
|
||||
// if surf is NULL, whatever tried to create it should have called SDL_SetError(),
|
||||
// if SDL_CreateTextureFromSurface() returned NULL it should have set an error
|
||||
// so whenever this returns NULL, the user should be able to get a useful
|
||||
// error-message with SDL_GetError().
|
||||
return ret;
|
||||
}
|
||||
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_LoadTexture(SDL_Renderer* renderer, const char* file)
|
||||
{
|
||||
return _STBIMG_SurfToTex(renderer, STBIMG_Load(file));
|
||||
}
|
||||
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_LoadTextureFromMemory(SDL_Renderer *renderer, const unsigned char* buffer, int length)
|
||||
{
|
||||
return _STBIMG_SurfToTex(renderer, STBIMG_LoadFromMemory(buffer, length));
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_LoadTexture_IO(SDL_Renderer* renderer, _STBIMG_RWops* src, bool freesrc)
|
||||
{
|
||||
return _STBIMG_SurfToTex(renderer, STBIMG_Load_IO(src, freesrc));
|
||||
}
|
||||
#else
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_LoadTexture_RW(SDL_Renderer* renderer, _STBIMG_RWops* src, bool freesrc)
|
||||
{
|
||||
return _STBIMG_SurfToTex(renderer, STBIMG_Load_RW(src, freesrc));
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_CreateTexture(SDL_Renderer* renderer, const unsigned char* pixelData,
|
||||
int width, int height, int bytesPerPixel)
|
||||
{
|
||||
SDL_Surface* surf = STBIMG_CreateSurface((unsigned char*)pixelData, width, height, bytesPerPixel, false);
|
||||
return _STBIMG_SurfToTex(renderer, surf);
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_LoadTexture_IO_noSeek(SDL_Renderer* renderer, _STBIMG_RWops* src, bool freesrc)
|
||||
{
|
||||
return _STBIMG_SurfToTex(renderer, STBIMG_Load_IO_noSeek(src, freesrc));
|
||||
}
|
||||
#else
|
||||
SDL_STBIMG_DEF SDL_Texture*
|
||||
STBIMG_LoadTexture_RW_noSeek(SDL_Renderer* renderer, _STBIMG_RWops* src, bool freesrc)
|
||||
{
|
||||
return _STBIMG_SurfToTex(renderer, STBIMG_Load_RW_noSeek(src, freesrc));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDL_MAJOR_VERSION > 1
|
||||
|
||||
#endif // SDL_STBIMAGE_IMPLEMENTATION
|
7988
src/cdogs/stb/stb_image.h
Normal file
7988
src/cdogs/stb/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2017, 2019-2022, 2024 Cong Xu
|
||||
Copyright (c) 2013-2017, 2019-2022, 2024-2025 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -58,6 +58,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SDL_STBIMAGE_IMPLEMENTATION
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
#include <stb/SDL_stbimage.h>
|
||||
#pragma GCC diagnostic pop
|
||||
#include <tinydir/tinydir.h>
|
||||
|
||||
#include "events.h"
|
||||
@@ -682,3 +687,8 @@ end:
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
SDL_Surface *LoadImgToSurface(const char *path)
|
||||
{
|
||||
return STBIMG_Load(path);
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2017, 2019-2024 Cong Xu
|
||||
Copyright (c) 2013-2017, 2019-2025 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -54,6 +54,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "color.h"
|
||||
#include "sys_specifics.h"
|
||||
|
||||
@@ -140,7 +142,7 @@ extern bool gFalse;
|
||||
x = y; \
|
||||
y = _tmp; \
|
||||
} while (0)
|
||||
#define DIV_ROUND_UP(a, b) (((a) + ((b)-1)) / (b))
|
||||
#define DIV_ROUND_UP(a, b) (((a) + ((b) - 1)) / (b))
|
||||
|
||||
const char *StrGetFileExt(const char *filename);
|
||||
|
||||
@@ -212,7 +214,7 @@ bool IntsEqual(const void *v1, const void *v2);
|
||||
#define RAND_FLOAT(_low, _high) (float)RAND_DOUBLE(_low, _high)
|
||||
#define RAND_DOUBLE(_low, _high) \
|
||||
((_low) + ((double)rand() / RAND_MAX * ((_high) - (_low))))
|
||||
#define RAND_BOOL() (rand()>RAND_MAX/2)
|
||||
#define RAND_BOOL() (rand() > RAND_MAX / 2)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -221,7 +223,7 @@ typedef enum
|
||||
HEAD_PART_HAT,
|
||||
HEAD_PART_GLASSES,
|
||||
HEAD_PART_COUNT
|
||||
} HeadPart; // cranial accessories
|
||||
} HeadPart; // cranial accessories
|
||||
|
||||
const char *HeadPartStr(const HeadPart hp);
|
||||
|
||||
@@ -251,3 +253,5 @@ typedef enum
|
||||
int Pulse256(const int t);
|
||||
|
||||
char *ReadFileIntoBuf(const char *path, const char *mode);
|
||||
|
||||
SDL_Surface *LoadImgToSurface(const char *path);
|
||||
|
@@ -29,8 +29,6 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <SDL_image.h>
|
||||
|
||||
#include <cdogs/algorithms.h>
|
||||
#include <cdogs/map.h>
|
||||
#include <cdogs/map_build.h>
|
||||
@@ -347,7 +345,8 @@ EditorResult EditorBrushStartPainting(EditorBrush *b, Mission *m, int isMain)
|
||||
if (isMain)
|
||||
{
|
||||
const Tile *tile = MapGetTile(&gMap, b->Pos);
|
||||
const Tile *tileAbove = MapGetTile(&gMap, svec2i(b->Pos.x, b->Pos.y - 1));
|
||||
const Tile *tileAbove =
|
||||
MapGetTile(&gMap, svec2i(b->Pos.x, b->Pos.y - 1));
|
||||
|
||||
if (MapObjectIsTileOK(b->u.MapObject, tile, tileAbove) &&
|
||||
MissionStaticTryAddItem(&m->u.Static, b->u.MapObject, b->Pos))
|
||||
@@ -423,8 +422,8 @@ EditorResult EditorBrushStartPainting(EditorBrush *b, Mission *m, int isMain)
|
||||
if (isMain)
|
||||
{
|
||||
const Tile *tile = MapGetTile(&gMap, b->Pos);
|
||||
if (TileCanWalk(tile) && MissionStaticTryAddPickup(
|
||||
&m->u.Static, b->u.Pickup, b->Pos))
|
||||
if (TileCanWalk(tile) &&
|
||||
MissionStaticTryAddPickup(&m->u.Static, b->u.Pickup, b->Pos))
|
||||
{
|
||||
return EDITOR_RESULT_CHANGED_AND_RELOAD;
|
||||
}
|
||||
@@ -663,7 +662,7 @@ EditorResult EditorBrushStopPainting(EditorBrush *b, Mission *m)
|
||||
bool EditorBrushTryLoadGuideImage(EditorBrush *b, const char *filename)
|
||||
{
|
||||
PicFree(&b->GuideImagePic);
|
||||
SDL_Surface *s = IMG_Load(filename);
|
||||
SDL_Surface *s = LoadImgToSurface(filename);
|
||||
if (s == NULL)
|
||||
return false;
|
||||
SDL_Surface *sc = SDL_ConvertSurface(s, gGraphicsDevice.Format, 0);
|
||||
|
@@ -29,8 +29,6 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <SDL_image.h>
|
||||
|
||||
#include <cdogs/draw/draw.h>
|
||||
#include <cdogs/draw/draw_actor.h>
|
||||
#include <cdogs/events.h>
|
||||
|
@@ -29,7 +29,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <SDL_image.h>
|
||||
#include <SDL_mixer.h>
|
||||
#include <SDL_version.h>
|
||||
|
||||
@@ -45,9 +44,6 @@ void PrintTitle(void)
|
||||
printf(
|
||||
"SDL version %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION,
|
||||
SDL_PATCHLEVEL);
|
||||
printf(
|
||||
"SDL_image version %d.%d.%d\n", SDL_IMAGE_MAJOR_VERSION,
|
||||
SDL_IMAGE_MINOR_VERSION, SDL_IMAGE_PATCHLEVEL);
|
||||
printf(
|
||||
"SDL_mixer version %d.%d.%d\n", SDL_MIXER_MAJOR_VERSION,
|
||||
SDL_MIXER_MINOR_VERSION, SDL_MIXER_PATCHLEVEL);
|
||||
|
@@ -2,8 +2,6 @@
|
||||
#include <cbehave/cbehave.h>
|
||||
|
||||
#include <pic.h>
|
||||
|
||||
#include <SDL_image.h>
|
||||
#include <config.h>
|
||||
#include <grafx.h>
|
||||
|
||||
@@ -22,9 +20,7 @@ FEATURE(PicLoad, "Pic load")
|
||||
GraphicsInitialize(&gGraphicsDevice);
|
||||
ASSERT(gGraphicsDevice.IsInitialized, 1);
|
||||
AND("a single pixel PNG")
|
||||
SDL_RWops *rwops = SDL_RWFromFile("r64g128b192.png", "rb");
|
||||
ASSERT(IMG_isPNG(rwops), 1);
|
||||
SDL_Surface *image = IMG_Load_RW(rwops, 0);
|
||||
SDL_Surface *image = LoadImgToSurface("r64g128b192.png");
|
||||
SDL_LockSurface(image);
|
||||
|
||||
WHEN("I load the pic")
|
||||
@@ -40,7 +36,6 @@ FEATURE(PicLoad, "Pic load")
|
||||
SHOULD_INT_EQUAL(c.b, 192);
|
||||
SDL_UnlockSurface(image);
|
||||
SDL_FreeSurface(image);
|
||||
rwops->close(rwops);
|
||||
SCENARIO_END
|
||||
FEATURE_END
|
||||
|
||||
|
Reference in New Issue
Block a user