mirror of
https://github.com/cxong/cdogs-sdl.git
synced 2025-07-23 07:23:01 +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: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt install python3-pip libgl1-mesa-dev
|
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
|
python3 -m pip install protobuf --break-system-packages
|
||||||
pip3 install --upgrade protobuf --break-system-packages
|
pip3 install --upgrade protobuf --break-system-packages
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install dependencies (Windows)
|
- name: Install dependencies (Windows)
|
||||||
if: matrix.os == 'windows-latest'
|
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
|
- name: Configure CMake
|
||||||
env:
|
env:
|
||||||
@@ -114,14 +114,6 @@ jobs:
|
|||||||
file-name: 'sdl2.zip'
|
file-name: 'sdl2.zip'
|
||||||
location: './dll'
|
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)
|
- name: Download SDL2_mixer DLLs on tags (Windows)
|
||||||
if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'windows-latest'
|
if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'windows-latest'
|
||||||
uses: carlosperate/download-file-action@v2
|
uses: carlosperate/download-file-action@v2
|
||||||
@@ -135,7 +127,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cd dll
|
cd dll
|
||||||
7z x -y sdl2.zip
|
7z x -y sdl2.zip
|
||||||
7z x -y sdl2_image.zip
|
|
||||||
7z x -y sdl2_mixer.zip
|
7z x -y sdl2_mixer.zip
|
||||||
copy .\optional\*.dll .
|
copy .\optional\*.dll .
|
||||||
dir
|
dir
|
||||||
|
13
.github/workflows/cmake.yml.cmake
vendored
13
.github/workflows/cmake.yml.cmake
vendored
@@ -57,7 +57,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt install python3-pip libgl1-mesa-dev
|
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
|
python3 -m pip install protobuf --break-system-packages
|
||||||
pip3 install --upgrade protobuf --break-system-packages
|
pip3 install --upgrade protobuf --break-system-packages
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install dependencies (Windows)
|
- name: Install dependencies (Windows)
|
||||||
if: matrix.os == 'windows-latest'
|
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
|
- name: Configure CMake
|
||||||
env:
|
env:
|
||||||
@@ -114,14 +114,6 @@ jobs:
|
|||||||
file-name: 'sdl2.zip'
|
file-name: 'sdl2.zip'
|
||||||
location: './dll'
|
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)
|
- name: Download SDL2_mixer DLLs on tags (Windows)
|
||||||
if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'windows-latest'
|
if: startsWith(github.ref, 'refs/tags/') && matrix.os == 'windows-latest'
|
||||||
uses: carlosperate/download-file-action@v2
|
uses: carlosperate/download-file-action@v2
|
||||||
@@ -135,7 +127,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cd dll
|
cd dll
|
||||||
7z x -y sdl2.zip
|
7z x -y sdl2.zip
|
||||||
7z x -y sdl2_image.zip
|
|
||||||
7z x -y sdl2_mixer.zip
|
7z x -y sdl2_mixer.zip
|
||||||
copy .\optional\*.dll .
|
copy .\optional\*.dll .
|
||||||
dir
|
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_LIB_PATH="/Library/Frameworks"
|
||||||
|
|
||||||
OSX_SDL2_PATH_FULL="$OSX_LIB_PATH/SDL2.framework"
|
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"
|
OSX_SDL2_MIXER_PATH_FULL="$OSX_LIB_PATH/SDL2_mixer.framework"
|
||||||
|
|
||||||
SDL2_VERSION=2.26.4
|
SDL2_VERSION=2.26.4
|
||||||
SDL2_IMAGE_VERSION=2.8.1
|
|
||||||
SDL2_MIXER_VERSION=2.6.3
|
SDL2_MIXER_VERSION=2.6.3
|
||||||
SDL2_URL=https://www.libsdl.org/release/SDL2-$SDL2_VERSION.dmg
|
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
|
SDL2_MIXER_URL=https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-$SDL2_MIXER_VERSION.dmg
|
||||||
|
|
||||||
function installDMG {
|
function installDMG {
|
||||||
@@ -37,10 +34,6 @@ function getSdl2 {
|
|||||||
installDMG $SDL2_URL
|
installDMG $SDL2_URL
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSdl2_image {
|
|
||||||
installDMG $SDL2_IMAGE_URL
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSdl2_mixer {
|
function getSdl2_mixer {
|
||||||
installDMG $SDL2_MIXER_URL
|
installDMG $SDL2_MIXER_URL
|
||||||
}
|
}
|
||||||
@@ -49,7 +42,6 @@ if [[ "$1" == "--force" ]]
|
|||||||
then
|
then
|
||||||
echo "Force build requested by --force."
|
echo "Force build requested by --force."
|
||||||
getSdl2
|
getSdl2
|
||||||
getSdl2_image
|
|
||||||
getSdl2_mixer
|
getSdl2_mixer
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
@@ -68,19 +60,6 @@ else
|
|||||||
getSdl2
|
getSdl2
|
||||||
fi
|
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 [[ -d "$OSX_SDL2_MIXER_PATH_FULL" ]]; then
|
||||||
if [[ -n "$(ls -A $OSX_SDL2_MIXER_PATH_FULL)" ]]
|
if [[ -n "$(ls -A $OSX_SDL2_MIXER_PATH_FULL)" ]]
|
||||||
then
|
then
|
||||||
|
@@ -3,7 +3,6 @@ setlocal enabledelayedexpansion
|
|||||||
|
|
||||||
set EXTRACT_COMMAND=7z x -y
|
set EXTRACT_COMMAND=7z x -y
|
||||||
set SDL2_VERSION=2.26.4
|
set SDL2_VERSION=2.26.4
|
||||||
set SDL2_IMAGE_VERSION=2.8.1
|
|
||||||
set SDL2_MIXER_VERSION=2.6.3
|
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_ARCHIVE=SDL2-%SDL2_VERSION%-win32-x%BITS%.zip
|
||||||
set SDL2_URL=https://www.libsdl.org/release/%SDL2_ARCHIVE%
|
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_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%
|
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!"
|
cd "!DESTDIR!"
|
||||||
|
|
||||||
call :downloadIfNeeded !SDL2_URL!
|
call :downloadIfNeeded !SDL2_URL!
|
||||||
call :downloadIfNeeded !SDL2_IMAGE_URL!
|
|
||||||
call :downloadIfNeeded !SDL2_MIXER_URL!
|
call :downloadIfNeeded !SDL2_MIXER_URL!
|
||||||
|
|
||||||
%EXTRACT_COMMAND% !SDL2_ARCHIVE!
|
%EXTRACT_COMMAND% !SDL2_ARCHIVE!
|
||||||
%EXTRACT_COMMAND% !SDL2_IMAGE_ARCHIVE!
|
|
||||||
%EXTRACT_COMMAND% !SDL2_MIXER_ARCHIVE!
|
%EXTRACT_COMMAND% !SDL2_MIXER_ARCHIVE!
|
||||||
|
|
||||||
rem Copy optional DLLs within the optional folders
|
rem Copy optional DLLs within the optional folders
|
||||||
|
@@ -28,25 +28,17 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
#include <SDL2/SDL_image.h>
|
|
||||||
#else
|
|
||||||
#include <SDL_image.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "blit.h"
|
#include "blit.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
#include "sys_config.h"
|
#include "sys_config.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
#define FIRST_CHAR 0
|
#define FIRST_CHAR 0
|
||||||
#define LAST_CHAR 255
|
#define LAST_CHAR 255
|
||||||
|
|
||||||
Font gFont;
|
Font gFont;
|
||||||
|
|
||||||
|
|
||||||
FontOpts FontOptsNew(void)
|
FontOpts FontOptsNew(void)
|
||||||
{
|
{
|
||||||
FontOpts opts;
|
FontOpts opts;
|
||||||
@@ -61,13 +53,10 @@ void FontLoad(
|
|||||||
{
|
{
|
||||||
char buf[CDOGS_PATH_MAX];
|
char buf[CDOGS_PATH_MAX];
|
||||||
GetDataFilePath(buf, imgPath);
|
GetDataFilePath(buf, imgPath);
|
||||||
SDL_RWops *rwops = SDL_RWFromFile(buf, "rb");
|
SDL_Surface *image = LoadImgToSurface(buf);
|
||||||
CASSERT(IMG_isPNG(rwops), "Error: font file is not PNG");
|
|
||||||
SDL_Surface *image = IMG_Load_RW(rwops, 0);
|
|
||||||
rwops->close(rwops);
|
|
||||||
if (!image)
|
if (!image)
|
||||||
{
|
{
|
||||||
LOG(LM_GFX, LL_ERROR, "Cannot load font image: %s", IMG_GetError());
|
LOG(LM_GFX, LL_ERROR, "Cannot load font image");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (image->format->BytesPerPixel != 4)
|
if (image->format->BytesPerPixel != 4)
|
||||||
@@ -88,10 +77,9 @@ void FontLoad(
|
|||||||
LOG(LM_GFX, LL_ERROR,
|
LOG(LM_GFX, LL_ERROR,
|
||||||
"Error: font image not big enough for font data "
|
"Error: font image not big enough for font data "
|
||||||
"Image %dx%d Size %dx%d Stride %d Padding %d,%d,%d,%d",
|
"Image %dx%d Size %dx%d Stride %d Padding %d,%d,%d,%d",
|
||||||
image->w, image->h,
|
image->w, image->h, f->Size.x, f->Size.y, f->Stride,
|
||||||
f->Size.x, f->Size.y, f->Stride,
|
f->Padding.Left, f->Padding.Top, f->Padding.Right,
|
||||||
f->Padding.Left, f->Padding.Top,
|
f->Padding.Bottom);
|
||||||
f->Padding.Right, f->Padding.Bottom);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,13 +87,12 @@ void FontLoad(
|
|||||||
SDL_LockSurface(image);
|
SDL_LockSurface(image);
|
||||||
int chars = 0;
|
int chars = 0;
|
||||||
for (struct vec2i pos = svec2i_zero();
|
for (struct vec2i pos = svec2i_zero();
|
||||||
pos.y + step.y <= image->h && chars < LAST_CHAR - FIRST_CHAR + 1;
|
pos.y + step.y <= image->h && chars < LAST_CHAR - FIRST_CHAR + 1;
|
||||||
pos.y += step.y)
|
pos.y += step.y)
|
||||||
{
|
{
|
||||||
int x = 0;
|
int x = 0;
|
||||||
for (pos.x = 0;
|
for (pos.x = 0; x < f->Stride && chars < LAST_CHAR - FIRST_CHAR + 1;
|
||||||
x < f->Stride && chars < LAST_CHAR - FIRST_CHAR + 1;
|
pos.x += step.x, x++, chars++)
|
||||||
pos.x += step.x, x++, chars++)
|
|
||||||
{
|
{
|
||||||
Pic p;
|
Pic p;
|
||||||
// TODO: HD fonts
|
// TODO: HD fonts
|
||||||
@@ -129,7 +116,7 @@ void FontLoad(
|
|||||||
void FontTerminate(Font *f)
|
void FontTerminate(Font *f)
|
||||||
{
|
{
|
||||||
CA_FOREACH(Pic, p, f->Chars)
|
CA_FOREACH(Pic, p, f->Chars)
|
||||||
PicFree(p);
|
PicFree(p);
|
||||||
CA_FOREACH_END()
|
CA_FOREACH_END()
|
||||||
CArrayTerminate(&f->Chars);
|
CArrayTerminate(&f->Chars);
|
||||||
}
|
}
|
||||||
@@ -217,7 +204,8 @@ struct vec2i FontCh(const char c, const struct vec2i pos)
|
|||||||
{
|
{
|
||||||
return FontChMask(c, pos, colorWhite);
|
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;
|
int idx = (int)c - FIRST_CHAR;
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
@@ -262,14 +250,16 @@ struct vec2i FontStrMask(const char *s, struct vec2i pos, const color_t mask)
|
|||||||
}
|
}
|
||||||
return pos;
|
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];
|
char buf[1024];
|
||||||
CASSERT(strlen(s) < 1024, "string too long to wrap");
|
CASSERT(strlen(s) < 1024, "string too long to wrap");
|
||||||
FontSplitLines(s, buf, width);
|
FontSplitLines(s, buf, width);
|
||||||
return FontStrMask(buf, pos, mask);
|
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)
|
void FontStrOpt(const char *s, struct vec2i pos, const FontOpts opts)
|
||||||
{
|
{
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
@@ -280,9 +270,10 @@ void FontStrOpt(const char *s, struct vec2i pos, const FontOpts opts)
|
|||||||
FontStrMask(s, pos, opts.Mask);
|
FontStrMask(s, pos, opts.Mask);
|
||||||
}
|
}
|
||||||
static int GetAlign(
|
static int GetAlign(
|
||||||
const FontAlign align,
|
const FontAlign align, const int pos, const int pad, const int area,
|
||||||
const int pos, const int pad, const int area, const int size);
|
const int size);
|
||||||
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)
|
||||||
{
|
{
|
||||||
const struct vec2i textSize = FontStrSize(s);
|
const struct vec2i textSize = FontStrSize(s);
|
||||||
return svec2i(
|
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));
|
GetAlign(opts.VAlign, pos.y, opts.Pad.y, opts.Area.y, textSize.y));
|
||||||
}
|
}
|
||||||
static int GetAlign(
|
static int GetAlign(
|
||||||
const FontAlign align,
|
const FontAlign align, const int pos, const int pad, const int area,
|
||||||
const int pos, const int pad, const int area, const int size)
|
const int size)
|
||||||
{
|
{
|
||||||
switch (align)
|
switch (align)
|
||||||
{
|
{
|
||||||
@@ -385,8 +376,8 @@ void FontSplitLines(const char *text, char *buf, const int width)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct vec2i Vec2iAligned(
|
struct vec2i Vec2iAligned(
|
||||||
const struct vec2i v, const struct vec2i size,
|
const struct vec2i v, const struct vec2i size, const FontAlign hAlign,
|
||||||
const FontAlign hAlign, const FontAlign vAlign, const struct vec2i area)
|
const FontAlign vAlign, const struct vec2i area)
|
||||||
{
|
{
|
||||||
struct vec2i vAligned = v;
|
struct vec2i vAligned = v;
|
||||||
switch (hAlign)
|
switch (hAlign)
|
||||||
|
@@ -1,78 +1,72 @@
|
|||||||
/*
|
/*
|
||||||
C-Dogs SDL
|
C-Dogs SDL
|
||||||
A port of the legendary (and fun) action/arcade cdogs.
|
A port of the legendary (and fun) action/arcade cdogs.
|
||||||
Copyright (C) 1995 Ronny Wester
|
Copyright (C) 1995 Ronny Wester
|
||||||
Copyright (C) 2003 Jeremy Chin
|
Copyright (C) 2003 Jeremy Chin
|
||||||
Copyright (C) 2003-2007 Lucas Martin-King
|
Copyright (C) 2003-2007 Lucas Martin-King
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
This file incorporates work covered by the following copyright and
|
This file incorporates work covered by the following copyright and
|
||||||
permission notice:
|
permission notice:
|
||||||
|
|
||||||
Copyright (c) 2013-2019 Cong Xu
|
Copyright (c) 2013-2019 Cong Xu
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright notice, this
|
Redistributions of source code must retain the above copyright notice, this
|
||||||
list of conditions and the following disclaimer.
|
list of conditions and the following disclaimer.
|
||||||
Redistributions in binary form must reproduce the above copyright notice,
|
Redistributions in binary form must reproduce the above copyright notice,
|
||||||
this list of conditions and the following disclaimer in the documentation
|
this list of conditions and the following disclaimer in the documentation
|
||||||
and/or other materials provided with the distribution.
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
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
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include "grafx.h"
|
#include "grafx.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <SDL_events.h>
|
#include <SDL_events.h>
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
#include <SDL2/SDL_image.h>
|
|
||||||
#else
|
|
||||||
#include <SDL_image.h>
|
|
||||||
#endif
|
|
||||||
#include <SDL_mouse.h>
|
#include <SDL_mouse.h>
|
||||||
|
|
||||||
#include "blit.h"
|
#include "blit.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "draw/drawtools.h"
|
#include "draw/drawtools.h"
|
||||||
|
#include "files.h"
|
||||||
#include "font_utils.h"
|
#include "font_utils.h"
|
||||||
#include "grafx_bg.h"
|
#include "grafx_bg.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "palette.h"
|
#include "palette.h"
|
||||||
#include "files.h"
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
GraphicsDevice gGraphicsDevice;
|
GraphicsDevice gGraphicsDevice;
|
||||||
|
|
||||||
void GraphicsInit(GraphicsDevice *device, Config *c)
|
void GraphicsInit(GraphicsDevice *device, Config *c)
|
||||||
@@ -96,7 +90,7 @@ void GraphicsInitialize(GraphicsDevice *g)
|
|||||||
{
|
{
|
||||||
char buf[CDOGS_PATH_MAX];
|
char buf[CDOGS_PATH_MAX];
|
||||||
GetDataFilePath(buf, "graphics/cdogs_icon.bmp");
|
GetDataFilePath(buf, "graphics/cdogs_icon.bmp");
|
||||||
g->icon = IMG_Load(buf);
|
g->icon = LoadImgToSurface(buf);
|
||||||
g->IsWindowInitialized = true;
|
g->IsWindowInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,19 +99,17 @@ void GraphicsInitialize(GraphicsDevice *g)
|
|||||||
const int w = g->cachedConfig.Res.x;
|
const int w = g->cachedConfig.Res.x;
|
||||||
const int h = g->cachedConfig.Res.y;
|
const int h = g->cachedConfig.Res.y;
|
||||||
|
|
||||||
const bool initWindow =
|
const bool initWindow = !!(g->cachedConfig.RestartFlags & RESTART_WINDOW);
|
||||||
!!(g->cachedConfig.RestartFlags & RESTART_WINDOW);
|
const bool initTextures = !!(
|
||||||
const bool initTextures =
|
g->cachedConfig.RestartFlags & (RESTART_WINDOW | RESTART_SCALE_MODE));
|
||||||
!!(g->cachedConfig.RestartFlags &
|
|
||||||
(RESTART_WINDOW | RESTART_SCALE_MODE));
|
|
||||||
const bool initBrightness =
|
const bool initBrightness =
|
||||||
!!(g->cachedConfig.RestartFlags &
|
!!(g->cachedConfig.RestartFlags &
|
||||||
(RESTART_WINDOW | RESTART_SCALE_MODE | RESTART_BRIGHTNESS));
|
(RESTART_WINDOW | RESTART_SCALE_MODE | RESTART_BRIGHTNESS));
|
||||||
|
|
||||||
if (initWindow)
|
if (initWindow)
|
||||||
{
|
{
|
||||||
LOG(LM_GFX, LL_INFO, "graphics mode(%dx%d %dx%s)",
|
LOG(LM_GFX, LL_INFO, "graphics mode(%dx%d %dx%s)", w, h,
|
||||||
w, h, g->cachedConfig.ScaleFactor,
|
g->cachedConfig.ScaleFactor,
|
||||||
g->cachedConfig.Fullscreen ? " fullscreen" : "");
|
g->cachedConfig.Fullscreen ? " fullscreen" : "");
|
||||||
|
|
||||||
Uint32 windowFlags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
|
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(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED),
|
||||||
svec2i(
|
svec2i(
|
||||||
ConfigGetInt(&gConfig, "Graphics.WindowWidth"),
|
ConfigGetInt(&gConfig, "Graphics.WindowWidth"),
|
||||||
ConfigGetInt(&gConfig, "Graphics.WindowHeight")
|
ConfigGetInt(&gConfig, "Graphics.WindowHeight")));
|
||||||
)
|
|
||||||
);
|
|
||||||
if (g->cachedConfig.Fullscreen)
|
if (g->cachedConfig.Fullscreen)
|
||||||
{
|
{
|
||||||
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
@@ -139,9 +129,9 @@ void GraphicsInitialize(GraphicsDevice *g)
|
|||||||
SDL_FreeFormat(g->Format);
|
SDL_FreeFormat(g->Format);
|
||||||
|
|
||||||
char title[32];
|
char title[32];
|
||||||
sprintf(title, "C-Dogs SDL %s%s",
|
sprintf(
|
||||||
g->cachedConfig.IsEditor ? "Editor " : "",
|
title, "C-Dogs SDL %s%s",
|
||||||
CDOGS_SDL_VERSION);
|
g->cachedConfig.IsEditor ? "Editor " : "", CDOGS_SDL_VERSION);
|
||||||
if (!WindowContextCreate(
|
if (!WindowContextCreate(
|
||||||
&g->gameWindow, windowDim, windowFlags, title, g->icon,
|
&g->gameWindow, windowDim, windowFlags, title, g->icon,
|
||||||
svec2i(w, h)))
|
svec2i(w, h)))
|
||||||
@@ -315,16 +305,15 @@ int GraphicsGetMemSize(GraphicsConfig *config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsConfigSet(
|
void GraphicsConfigSet(
|
||||||
GraphicsConfig *c,
|
GraphicsConfig *c, struct vec2i windowSize, const bool fullscreen,
|
||||||
struct vec2i windowSize, const bool fullscreen,
|
|
||||||
const int scaleFactor, const ScaleMode scaleMode, const int brightness,
|
const int scaleFactor, const ScaleMode scaleMode, const int brightness,
|
||||||
const bool secondWindow)
|
const bool secondWindow)
|
||||||
{
|
{
|
||||||
#define SET(_lhs, _rhs, _flag) \
|
#define SET(_lhs, _rhs, _flag) \
|
||||||
if ((_lhs) != (_rhs)) \
|
if ((_lhs) != (_rhs)) \
|
||||||
{ \
|
{ \
|
||||||
(_lhs) = (_rhs); \
|
(_lhs) = (_rhs); \
|
||||||
c->RestartFlags |= (_flag); \
|
c->RestartFlags |= (_flag); \
|
||||||
}
|
}
|
||||||
SET(c->Fullscreen, fullscreen, RESTART_WINDOW);
|
SET(c->Fullscreen, fullscreen, RESTART_WINDOW);
|
||||||
if (c->Fullscreen)
|
if (c->Fullscreen)
|
||||||
@@ -371,7 +360,7 @@ void GraphicsConfigSetFromConfig(GraphicsConfig *gc, Config *c)
|
|||||||
|
|
||||||
void GraphicsSetClip(SDL_Renderer *renderer, const Rect2i r)
|
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)
|
if (SDL_RenderSetClipRect(renderer, Rect2iIsZero(r) ? NULL : &rect) != 0)
|
||||||
{
|
{
|
||||||
LOG(LM_MAIN, LL_ERROR, "Could not set clip rect: %s", SDL_GetError());
|
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)
|
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"
|
#include "pic_manager.h"
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
#include <SDL2/SDL_image.h>
|
|
||||||
#else
|
|
||||||
#include <SDL_image.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <tinydir/tinydir.h>
|
#include <tinydir/tinydir.h>
|
||||||
|
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
@@ -45,11 +39,6 @@ PicManager gPicManager;
|
|||||||
|
|
||||||
void PicManagerInit(PicManager *pm)
|
void PicManagerInit(PicManager *pm)
|
||||||
{
|
{
|
||||||
if (!IMG_Init(IMG_INIT_PNG))
|
|
||||||
{
|
|
||||||
perror("Cannot initialise SDL_Image");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memset(pm, 0, sizeof *pm);
|
memset(pm, 0, sizeof *pm);
|
||||||
pm->pics = hashmap_new();
|
pm->pics = hashmap_new();
|
||||||
pm->sprites = hashmap_new();
|
pm->sprites = hashmap_new();
|
||||||
@@ -214,35 +203,28 @@ void PicManagerLoadDir(
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
if (file.is_reg)
|
if (file.is_reg && Stricmp(file.extension, "png") == 0)
|
||||||
{
|
{
|
||||||
SDL_RWops *rwops = SDL_RWFromFile(file.path, "rb");
|
SDL_Surface *data = LoadImgToSurface(file.path);
|
||||||
const bool isPng = IMG_isPNG(rwops);
|
if (!data)
|
||||||
if (isPng)
|
|
||||||
{
|
{
|
||||||
SDL_Surface *data = IMG_Load_RW(rwops, 0);
|
LOG(LM_MAIN, LL_ERROR, "Cannot load image");
|
||||||
if (!data)
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char buf[CDOGS_PATH_MAX];
|
||||||
|
if (prefix)
|
||||||
{
|
{
|
||||||
LOG(LM_MAIN, LL_ERROR, "Cannot load image IMG_Load: %s",
|
char buf1[CDOGS_PATH_MAX];
|
||||||
IMG_GetError());
|
sprintf(buf1, "%s/%s", prefix, file.name);
|
||||||
|
PathGetWithoutExtension(buf, buf1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char buf[CDOGS_PATH_MAX];
|
PathGetBasenameWithoutExtension(buf, file.name);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
PicManagerAdd(pics, sprites, buf, data, isHD);
|
||||||
}
|
}
|
||||||
rwops->close(rwops);
|
|
||||||
}
|
}
|
||||||
else if (file.is_dir && file.name[0] != '.')
|
else if (file.is_dir && file.name[0] != '.')
|
||||||
{
|
{
|
||||||
@@ -501,7 +483,6 @@ void PicManagerTerminate(PicManager *pm)
|
|||||||
StyleNamesDestroy(&pm->exitStyleNames);
|
StyleNamesDestroy(&pm->exitStyleNames);
|
||||||
StyleNamesDestroy(&pm->doorStyleNames);
|
StyleNamesDestroy(&pm->doorStyleNames);
|
||||||
StyleNamesDestroy(&pm->keyStyleNames);
|
StyleNamesDestroy(&pm->keyStyleNames);
|
||||||
IMG_Quit();
|
|
||||||
}
|
}
|
||||||
static void NamedPicDestroy(any_t data)
|
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
|
This file incorporates work covered by the following copyright and
|
||||||
permission notice:
|
permission notice:
|
||||||
|
|
||||||
Copyright (c) 2013-2017, 2019-2022, 2024 Cong Xu
|
Copyright (c) 2013-2017, 2019-2022, 2024-2025 Cong Xu
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -58,6 +58,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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 <tinydir/tinydir.h>
|
||||||
|
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
@@ -682,3 +687,8 @@ end:
|
|||||||
}
|
}
|
||||||
return buf;
|
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
|
This file incorporates work covered by the following copyright and
|
||||||
permission notice:
|
permission notice:
|
||||||
|
|
||||||
Copyright (c) 2013-2017, 2019-2024 Cong Xu
|
Copyright (c) 2013-2017, 2019-2025 Cong Xu
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -54,6 +54,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "sys_specifics.h"
|
#include "sys_specifics.h"
|
||||||
|
|
||||||
@@ -140,7 +142,7 @@ extern bool gFalse;
|
|||||||
x = y; \
|
x = y; \
|
||||||
y = _tmp; \
|
y = _tmp; \
|
||||||
} while (0)
|
} 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);
|
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_FLOAT(_low, _high) (float)RAND_DOUBLE(_low, _high)
|
||||||
#define RAND_DOUBLE(_low, _high) \
|
#define RAND_DOUBLE(_low, _high) \
|
||||||
((_low) + ((double)rand() / RAND_MAX * ((_high) - (_low))))
|
((_low) + ((double)rand() / RAND_MAX * ((_high) - (_low))))
|
||||||
#define RAND_BOOL() (rand()>RAND_MAX/2)
|
#define RAND_BOOL() (rand() > RAND_MAX / 2)
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@@ -221,7 +223,7 @@ typedef enum
|
|||||||
HEAD_PART_HAT,
|
HEAD_PART_HAT,
|
||||||
HEAD_PART_GLASSES,
|
HEAD_PART_GLASSES,
|
||||||
HEAD_PART_COUNT
|
HEAD_PART_COUNT
|
||||||
} HeadPart; // cranial accessories
|
} HeadPart; // cranial accessories
|
||||||
|
|
||||||
const char *HeadPartStr(const HeadPart hp);
|
const char *HeadPartStr(const HeadPart hp);
|
||||||
|
|
||||||
@@ -251,3 +253,5 @@ typedef enum
|
|||||||
int Pulse256(const int t);
|
int Pulse256(const int t);
|
||||||
|
|
||||||
char *ReadFileIntoBuf(const char *path, const char *mode);
|
char *ReadFileIntoBuf(const char *path, const char *mode);
|
||||||
|
|
||||||
|
SDL_Surface *LoadImgToSurface(const char *path);
|
||||||
|
@@ -29,8 +29,6 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <SDL_image.h>
|
|
||||||
|
|
||||||
#include <cdogs/algorithms.h>
|
#include <cdogs/algorithms.h>
|
||||||
#include <cdogs/map.h>
|
#include <cdogs/map.h>
|
||||||
#include <cdogs/map_build.h>
|
#include <cdogs/map_build.h>
|
||||||
@@ -347,7 +345,8 @@ EditorResult EditorBrushStartPainting(EditorBrush *b, Mission *m, int isMain)
|
|||||||
if (isMain)
|
if (isMain)
|
||||||
{
|
{
|
||||||
const Tile *tile = MapGetTile(&gMap, b->Pos);
|
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) &&
|
if (MapObjectIsTileOK(b->u.MapObject, tile, tileAbove) &&
|
||||||
MissionStaticTryAddItem(&m->u.Static, b->u.MapObject, b->Pos))
|
MissionStaticTryAddItem(&m->u.Static, b->u.MapObject, b->Pos))
|
||||||
@@ -423,8 +422,8 @@ EditorResult EditorBrushStartPainting(EditorBrush *b, Mission *m, int isMain)
|
|||||||
if (isMain)
|
if (isMain)
|
||||||
{
|
{
|
||||||
const Tile *tile = MapGetTile(&gMap, b->Pos);
|
const Tile *tile = MapGetTile(&gMap, b->Pos);
|
||||||
if (TileCanWalk(tile) && MissionStaticTryAddPickup(
|
if (TileCanWalk(tile) &&
|
||||||
&m->u.Static, b->u.Pickup, b->Pos))
|
MissionStaticTryAddPickup(&m->u.Static, b->u.Pickup, b->Pos))
|
||||||
{
|
{
|
||||||
return EDITOR_RESULT_CHANGED_AND_RELOAD;
|
return EDITOR_RESULT_CHANGED_AND_RELOAD;
|
||||||
}
|
}
|
||||||
@@ -663,7 +662,7 @@ EditorResult EditorBrushStopPainting(EditorBrush *b, Mission *m)
|
|||||||
bool EditorBrushTryLoadGuideImage(EditorBrush *b, const char *filename)
|
bool EditorBrushTryLoadGuideImage(EditorBrush *b, const char *filename)
|
||||||
{
|
{
|
||||||
PicFree(&b->GuideImagePic);
|
PicFree(&b->GuideImagePic);
|
||||||
SDL_Surface *s = IMG_Load(filename);
|
SDL_Surface *s = LoadImgToSurface(filename);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
return false;
|
return false;
|
||||||
SDL_Surface *sc = SDL_ConvertSurface(s, gGraphicsDevice.Format, 0);
|
SDL_Surface *sc = SDL_ConvertSurface(s, gGraphicsDevice.Format, 0);
|
||||||
|
@@ -29,8 +29,6 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <SDL_image.h>
|
|
||||||
|
|
||||||
#include <cdogs/draw/draw.h>
|
#include <cdogs/draw/draw.h>
|
||||||
#include <cdogs/draw/draw_actor.h>
|
#include <cdogs/draw/draw_actor.h>
|
||||||
#include <cdogs/events.h>
|
#include <cdogs/events.h>
|
||||||
|
@@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <SDL_image.h>
|
|
||||||
#include <SDL_mixer.h>
|
#include <SDL_mixer.h>
|
||||||
#include <SDL_version.h>
|
#include <SDL_version.h>
|
||||||
|
|
||||||
@@ -45,9 +44,6 @@ void PrintTitle(void)
|
|||||||
printf(
|
printf(
|
||||||
"SDL version %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION,
|
"SDL version %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION,
|
||||||
SDL_PATCHLEVEL);
|
SDL_PATCHLEVEL);
|
||||||
printf(
|
|
||||||
"SDL_image version %d.%d.%d\n", SDL_IMAGE_MAJOR_VERSION,
|
|
||||||
SDL_IMAGE_MINOR_VERSION, SDL_IMAGE_PATCHLEVEL);
|
|
||||||
printf(
|
printf(
|
||||||
"SDL_mixer version %d.%d.%d\n", SDL_MIXER_MAJOR_VERSION,
|
"SDL_mixer version %d.%d.%d\n", SDL_MIXER_MAJOR_VERSION,
|
||||||
SDL_MIXER_MINOR_VERSION, SDL_MIXER_PATCHLEVEL);
|
SDL_MIXER_MINOR_VERSION, SDL_MIXER_PATCHLEVEL);
|
||||||
|
@@ -2,8 +2,6 @@
|
|||||||
#include <cbehave/cbehave.h>
|
#include <cbehave/cbehave.h>
|
||||||
|
|
||||||
#include <pic.h>
|
#include <pic.h>
|
||||||
|
|
||||||
#include <SDL_image.h>
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <grafx.h>
|
#include <grafx.h>
|
||||||
|
|
||||||
@@ -22,9 +20,7 @@ FEATURE(PicLoad, "Pic load")
|
|||||||
GraphicsInitialize(&gGraphicsDevice);
|
GraphicsInitialize(&gGraphicsDevice);
|
||||||
ASSERT(gGraphicsDevice.IsInitialized, 1);
|
ASSERT(gGraphicsDevice.IsInitialized, 1);
|
||||||
AND("a single pixel PNG")
|
AND("a single pixel PNG")
|
||||||
SDL_RWops *rwops = SDL_RWFromFile("r64g128b192.png", "rb");
|
SDL_Surface *image = LoadImgToSurface("r64g128b192.png");
|
||||||
ASSERT(IMG_isPNG(rwops), 1);
|
|
||||||
SDL_Surface *image = IMG_Load_RW(rwops, 0);
|
|
||||||
SDL_LockSurface(image);
|
SDL_LockSurface(image);
|
||||||
|
|
||||||
WHEN("I load the pic")
|
WHEN("I load the pic")
|
||||||
@@ -40,7 +36,6 @@ FEATURE(PicLoad, "Pic load")
|
|||||||
SHOULD_INT_EQUAL(c.b, 192);
|
SHOULD_INT_EQUAL(c.b, 192);
|
||||||
SDL_UnlockSurface(image);
|
SDL_UnlockSurface(image);
|
||||||
SDL_FreeSurface(image);
|
SDL_FreeSurface(image);
|
||||||
rwops->close(rwops);
|
|
||||||
SCENARIO_END
|
SCENARIO_END
|
||||||
FEATURE_END
|
FEATURE_END
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user