Delegate PCX loading to SDL_image
This adds a new dependency, but most systems likely already have SDL_image installed. Use of SDL_image can be disabled, but this is discouraged, because various in-game interfaces assume the use of the original background. The old implementation automatically corrected for filename case. The new implementation expects that the supplied filename can be passed to PYHSFS_openRead as-is. All known uses in-game have been corrected to satisfy this requirement. If the new stricter match requirement becomes a problem, a variant of PHYSFSRWOPS_openRead that adjusts filename case could be created for use here. - Update install instructions - Update ebuild - Update Arch PKGBUILD
This commit is contained in:
parent
71ca1a7553
commit
3114874713
|
@ -23,6 +23,7 @@ PhysFS 3.x is recommended.
|
|||
|
||||
Optional, but recommended:
|
||||
|
||||
* [SDL\_image 1.2](https://www.libsdl.org/projects/SDL_image/).
|
||||
* [SDL\_mixer 1.2](https://www.libsdl.org/projects/SDL_mixer/).
|
||||
* [libpng](http://www.libpng.org/).
|
||||
* C++ compiler with support for selected C++14 features. One of:
|
||||
|
@ -79,6 +80,7 @@ Install the listed prerequisites through your system package manager.
|
|||
base-devel
|
||||
scons
|
||||
sdl
|
||||
sdl\_image
|
||||
sdl\_mixer
|
||||
physfs**
|
||||
|
||||
|
@ -87,6 +89,7 @@ Install the listed prerequisites through your system package manager.
|
|||
gcc-c++
|
||||
scons
|
||||
SDL-devel
|
||||
SDL\_image-devel
|
||||
SDL\_mixer-devel
|
||||
physfs-devel**
|
||||
|
||||
|
@ -94,6 +97,7 @@ Install the listed prerequisites through your system package manager.
|
|||
* **emerge --ask --verbose --noreplace
|
||||
dev-util/scons
|
||||
media-libs/libsdl
|
||||
media-libs/sdl-image
|
||||
media-libs/sdl-mixer
|
||||
dev-games/physfs**
|
||||
|
||||
|
@ -102,6 +106,7 @@ Install the listed prerequisites through your system package manager.
|
|||
build-essential
|
||||
scons
|
||||
libsdl1.2-dev
|
||||
libsdl-image1.2-dev
|
||||
libsdl-mixer1.2-dev
|
||||
libphysfs-dev**
|
||||
|
||||
|
@ -125,6 +130,7 @@ DXX-Rebirth can be built from the Terminal (via SCons) without Xcode; to build u
|
|||
gcc5
|
||||
scons
|
||||
sdl
|
||||
sdl\_image
|
||||
sdl\_mixer
|
||||
physfs**
|
||||
|
||||
|
|
87
SConstruct
87
SConstruct
|
@ -1390,17 +1390,22 @@ static void terminate_handler()
|
|||
def _check_SDL(self,context):
|
||||
if self.user_settings.sdl2:
|
||||
check_libSDL = self.check_libSDL2
|
||||
check_SDL_image = self.check_SDL2_image
|
||||
check_SDL_mixer = self.check_SDL2_mixer
|
||||
else:
|
||||
check_libSDL = self.check_libSDL
|
||||
check_SDL_image = self.check_SDL_image
|
||||
check_SDL_mixer = self.check_SDL_mixer
|
||||
check_libSDL(context)
|
||||
check_SDL_image(context)
|
||||
check_SDL_mixer(context)
|
||||
|
||||
@_implicit_test
|
||||
def check_libSDL(self,context,_guess_flags={
|
||||
'LIBS' : ['SDL'] if sys.platform != 'darwin' else [],
|
||||
}):
|
||||
self._check_libSDL(context, '', _guess_flags)
|
||||
|
||||
@_implicit_test
|
||||
def check_libSDL2(self,context,_guess_flags={
|
||||
'LIBS' : ['SDL2'] if sys.platform != 'darwin' else [],
|
||||
|
@ -1408,6 +1413,7 @@ static void terminate_handler()
|
|||
if not self.user_settings.opengl:
|
||||
raise SCons.Errors.StopError('Rebirth does not support SDL2 without OpenGL. Set opengl=1 or sdl2=0.')
|
||||
self._check_libSDL(context, '2', _guess_flags)
|
||||
|
||||
def _check_libSDL(self,context,sdl2,guess_flags):
|
||||
user_settings = self.user_settings
|
||||
successflags = self.pkgconfig.merge(context, self.msgprefix, user_settings, 'sdl%s' % sdl2, 'SDL%s' % sdl2, guess_flags).copy()
|
||||
|
@ -1475,40 +1481,62 @@ static void terminate_handler()
|
|||
if not e2 and e[0] == 1:
|
||||
e = (None, error_text_opengl_mismatch)
|
||||
raise SCons.Errors.StopError(e[1])
|
||||
|
||||
@_implicit_test
|
||||
def check_SDL_image(self,context):
|
||||
self._check_SDL_image(context, '')
|
||||
|
||||
@_implicit_test
|
||||
def check_SDL2_image(self,context):
|
||||
self._check_SDL_image(context, '2')
|
||||
|
||||
def _check_SDL_image(self,context,sdl2):
|
||||
self._check_SDL_addon_library(context, sdl2, 'SDL%s_image', 'DXX_USE_SDLIMAGE', self.user_settings.sdlimage, '''
|
||||
IMG_Init(0);
|
||||
SDL_RWops *rw = reinterpret_cast<SDL_RWops *>(argv);
|
||||
SDL_Surface *s = IMG_LoadPCX_RW(rw);
|
||||
(void)s;
|
||||
IMG_Quit();
|
||||
''')
|
||||
|
||||
# SDL_mixer/SDL2_mixer use the same -I line as SDL/SDL2
|
||||
@_implicit_test
|
||||
def check_SDL_mixer(self,context,_guess_flags={
|
||||
'LIBS' : ['SDL_mixer'] if sys.platform != 'darwin' else [],
|
||||
}):
|
||||
self._check_SDL_mixer(context, '', _guess_flags)
|
||||
def check_SDL_mixer(self,context):
|
||||
self._check_SDL_mixer(context, '')
|
||||
|
||||
@_implicit_test
|
||||
def check_SDL2_mixer(self,context,_guess_flags={
|
||||
'LIBS' : ['SDL2_mixer'] if sys.platform != 'darwin' else [],
|
||||
}):
|
||||
self._check_SDL_mixer(context, '2', _guess_flags)
|
||||
def _check_SDL_mixer(self,context,sdl2,guess_flags):
|
||||
mixer = 'SDL%s_mixer' % sdl2
|
||||
user_settings = self.user_settings
|
||||
context.Display('%s: checking whether to use %s...%s\n' % (self.msgprefix, mixer, 'yes' if user_settings.sdlmixer else 'no'))
|
||||
# SDL_mixer support?
|
||||
use_sdlmixer = user_settings.sdlmixer
|
||||
self._define_macro(context, 'DXX_USE_SDLMIXER', int(use_sdlmixer))
|
||||
if not use_sdlmixer:
|
||||
return
|
||||
successflags = self.pkgconfig.merge(context, self.msgprefix, user_settings, mixer, mixer, guess_flags)
|
||||
if user_settings.host_platform == 'darwin':
|
||||
successflags = successflags.copy()
|
||||
successflags['FRAMEWORKS'] = [mixer]
|
||||
relative_headers = 'Library/Frameworks/%s.framework/Headers' % mixer
|
||||
successflags['CPPPATH'] = [os.path.join(os.getenv("HOME"), relative_headers), '/%s' % relative_headers]
|
||||
self._check_system_library(context,header=['SDL_mixer.h'],main='''
|
||||
def check_SDL2_mixer(self,context):
|
||||
self._check_SDL_mixer(context, '2')
|
||||
|
||||
def _check_SDL_mixer(self,context,sdl2):
|
||||
self._check_SDL_addon_library(context, sdl2, 'SDL%s_mixer', 'DXX_USE_SDLMIXER', self.user_settings.sdlmixer, '''
|
||||
int i = Mix_Init(MIX_INIT_FLAC | MIX_INIT_OGG);
|
||||
(void)i;
|
||||
Mix_Pause(0);
|
||||
Mix_ResumeMusic();
|
||||
Mix_Quit();
|
||||
''',
|
||||
lib=mixer, successflags=successflags)
|
||||
''')
|
||||
|
||||
def _check_SDL_addon_library(self,context,sdl2,library_format_name,macro_name,use_addon,main):
|
||||
library_name = library_format_name % sdl2
|
||||
self._define_macro(context, macro_name, int(use_addon))
|
||||
context.Display('%s: checking whether to use %s...%s\n' % (self.msgprefix, library_name, 'yes' if use_addon else 'no'))
|
||||
if not use_addon:
|
||||
return
|
||||
user_settings = self.user_settings
|
||||
guess_flags = {
|
||||
'LIBS' : [library_name] if sys.platform != 'darwin' else [],
|
||||
}
|
||||
successflags = self.pkgconfig.merge(context, self.msgprefix, user_settings, library_name, library_name, guess_flags)
|
||||
if user_settings.host_platform == 'darwin':
|
||||
successflags = successflags.copy()
|
||||
successflags['FRAMEWORKS'] = [library_name]
|
||||
relative_headers = 'Library/Frameworks/%s.framework/Headers' % library_name
|
||||
successflags['CPPPATH'] = [h for h in (os.path.join(os.getenv("HOME"), relative_headers), '/%s' % relative_headers) if os.path.isdir(h)]
|
||||
# SDL2 headers still use SDL_*.h for their filename, not
|
||||
# SDL2_*.h, so expanded library_format_name with an explicitly
|
||||
# blank insert, regardless of whether building for SDL1 or SDL2.
|
||||
self._check_system_library(context, header=['%s.h' % (library_format_name % '')], main=main, lib=library_name, successflags=successflags)
|
||||
|
||||
@_custom_test
|
||||
def check_compiler_missing_field_initializers(self,context,
|
||||
|
@ -3728,6 +3756,11 @@ class DXXCommon(LazyObjectConstructor):
|
|||
('opengles', self.default_opengles, 'build with OpenGL ES support'),
|
||||
('editor', False, 'include editor into build (!EXPERIMENTAL!)'),
|
||||
('sdl2', self.default_sdl2, 'use libSDL2+SDL2_mixer (!EXPERIMENTAL!)'),
|
||||
# Build with SDL_Image support for PCX file support
|
||||
# Currently undocumented because the user experience
|
||||
# without PCX support is ugly, so this should always
|
||||
# be left enabled.
|
||||
('sdlimage', True, None),
|
||||
('sdlmixer', True, 'build with SDL_Mixer support for sound and music (includes external music support)'),
|
||||
('ipv6', False, 'enable UDP/IPv6 for multiplayer'),
|
||||
('use_udp', True, 'enable UDP support'),
|
||||
|
@ -4490,6 +4523,7 @@ class DXXArchive(DXXCommon):
|
|||
'common/misc/hash.cpp',
|
||||
'common/misc/hmp.cpp',
|
||||
'common/misc/ignorecase.cpp',
|
||||
'common/misc/physfsrwops.cpp',
|
||||
'common/misc/strutil.cpp',
|
||||
'common/misc/vgrphys.cpp',
|
||||
'common/misc/vgwphys.cpp',
|
||||
|
@ -5202,7 +5236,6 @@ class D2XProgram(DXXProgram):
|
|||
'd2x-rebirth/main/escort.cpp',
|
||||
'd2x-rebirth/main/gamepal.cpp',
|
||||
'd2x-rebirth/main/movie.cpp',
|
||||
'd2x-rebirth/misc/physfsrwops.cpp',
|
||||
))):
|
||||
value = __get_dxx_objects_common(self)
|
||||
value.extend(__get_dsx_objects_common(self))
|
||||
|
|
|
@ -52,7 +52,6 @@ struct palette_array_t : public std::array<rgb_t, 256> {};
|
|||
#endif
|
||||
|
||||
void copy_bound_palette(palette_array_t &d, const palette_array_t &s);
|
||||
void copy_diminish_palette(palette_array_t &palette, const ubyte *p);
|
||||
void diminish_palette(palette_array_t &palette);
|
||||
extern void gr_palette_set_gamma( int gamma );
|
||||
extern int gr_palette_get_gamma();
|
||||
|
@ -66,6 +65,12 @@ extern ubyte gr_palette_gamma;
|
|||
extern palette_array_t gr_current_pal;
|
||||
}
|
||||
|
||||
#ifdef DXX_BUILD_DESCENT_I
|
||||
namespace dsx {
|
||||
void copy_diminish_palette(palette_array_t &palette, const uint8_t *p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,7 +9,7 @@ pkgdesc="An enhanced engine to play with Descent1 data."
|
|||
arch=('x86_64')
|
||||
url="https://www.dxx-rebirth.com/"
|
||||
license=('custom:D1x' 'LGPL' 'custom:as-is')
|
||||
depends=('sdl' 'sdl_mixer' 'mesa' 'physfs')
|
||||
depends=('sdl' 'sdl_image' 'sdl_mixer' 'mesa' 'physfs')
|
||||
makedepends=('scons' 'unzip')
|
||||
install="$pkgname.install"
|
||||
source=("https://www.dxx-rebirth.com/download/dxx/rebirth/dxx-rebirth_$pkgver-src.tar.xz"
|
||||
|
|
|
@ -9,7 +9,7 @@ pkgdesc="An enhanced engine to play with Descent2 data."
|
|||
arch=('x86_64')
|
||||
url="https://www.dxx-rebirth.com/"
|
||||
license=('custom:D2x' 'LGPL' 'custom:as-is')
|
||||
depends=('sdl' 'sdl_mixer' 'mesa' 'physfs')
|
||||
depends=('sdl' 'sdl_image' 'sdl_mixer' 'mesa' 'physfs')
|
||||
makedepends=('scons' 'unzip')
|
||||
install="$pkgname.install"
|
||||
source=("https://www.dxx-rebirth.com/download/dxx/rebirth/dxx-rebirth_$pkgver-src.tar.xz"
|
||||
|
|
|
@ -111,6 +111,7 @@ DXX_RDEPEND_ENGINE_FRAGMENT='
|
|||
|
||||
DXX_DEPEND_USE_SDL_VERSION_FRAGMENT='
|
||||
media-libs/lib${SDL_version}[joystick?,opengl?,sound,video]
|
||||
media-libs/sdl${SDL_version}-image
|
||||
music? ( media-libs/${SDL_version}-mixer )
|
||||
'
|
||||
DXX_RDEPEND_USE_SDL_VERSION_FRAGMENT='
|
||||
|
|
|
@ -76,16 +76,6 @@ void copy_bound_palette(palette_array_t &d, const palette_array_t &s)
|
|||
std::transform(s.begin(), s.end(), d.begin(), a);
|
||||
}
|
||||
|
||||
void copy_diminish_palette(palette_array_t &palette, const ubyte *p)
|
||||
{
|
||||
range_for (auto &i, palette)
|
||||
{
|
||||
i.r = *p++ >> 2;
|
||||
i.g = *p++ >> 2;
|
||||
i.b = *p++ >> 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace dcx {
|
||||
|
@ -124,6 +114,18 @@ int gr_palette_get_gamma()
|
|||
|
||||
namespace dsx {
|
||||
|
||||
#if defined(DXX_BUILD_DESCENT_I)
|
||||
void copy_diminish_palette(palette_array_t &palette, const uint8_t *p)
|
||||
{
|
||||
range_for (auto &i, palette)
|
||||
{
|
||||
i.r = *p++ >> 2;
|
||||
i.g = *p++ >> 2;
|
||||
i.b = *p++ >> 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DXX_BUILD_DESCENT_II)
|
||||
void gr_copy_palette(palette_array_t &gr_palette, const palette_array_t &pal)
|
||||
{
|
||||
|
|
|
@ -36,12 +36,41 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
|||
#include "dxxsconf.h"
|
||||
#include "dsx-ns.h"
|
||||
#include "compiler-lengthof.h"
|
||||
#include "compiler-poison.h"
|
||||
#include "compiler-range_for.h"
|
||||
#include "d_range.h"
|
||||
#include "partial_range.h"
|
||||
#include "console.h"
|
||||
|
||||
#if DXX_USE_SDLIMAGE
|
||||
#include "physfsrwops.h"
|
||||
#include <SDL_image.h>
|
||||
#endif
|
||||
|
||||
namespace dcx {
|
||||
|
||||
namespace {
|
||||
|
||||
#if DXX_USE_SDLIMAGE
|
||||
struct RAII_SDL_Surface
|
||||
{
|
||||
struct deleter
|
||||
{
|
||||
void operator()(SDL_Surface *s) const
|
||||
{
|
||||
SDL_FreeSurface(s);
|
||||
}
|
||||
};
|
||||
std::unique_ptr<SDL_Surface, deleter> surface;
|
||||
explicit RAII_SDL_Surface(SDL_Surface *const s) :
|
||||
surface(s)
|
||||
{
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if !DXX_USE_OGL && DXX_USE_SCREENSHOT_FORMAT_LEGACY
|
||||
static int pcx_encode_byte(ubyte byt, ubyte cnt, PHYSFS_File *fid);
|
||||
static int pcx_encode_line(const uint8_t *inBuff, uint_fast32_t inLen, PHYSFS_File *fp);
|
||||
|
@ -69,32 +98,68 @@ struct PCXHeader
|
|||
|
||||
#define PCXHEADER_SIZE 128
|
||||
|
||||
/*
|
||||
* reads n PCXHeader structs from a PHYSFS_File
|
||||
*/
|
||||
static int PCXHeader_read_n(PCXHeader *ph, int n, PHYSFS_File *fp)
|
||||
#if DXX_USE_SDLIMAGE
|
||||
static pcx_result pcx_read_bitmap(const char *const filename, grs_main_bitmap &bmp, palette_array_t &palette, RWops_ptr rw)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
ph->Manufacturer = PHYSFSX_readByte(fp);
|
||||
ph->Version = PHYSFSX_readByte(fp);
|
||||
ph->Encoding = PHYSFSX_readByte(fp);
|
||||
ph->BitsPerPixel = PHYSFSX_readByte(fp);
|
||||
ph->Xmin = PHYSFSX_readShort(fp);
|
||||
ph->Ymin = PHYSFSX_readShort(fp);
|
||||
ph->Xmax = PHYSFSX_readShort(fp);
|
||||
ph->Ymax = PHYSFSX_readShort(fp);
|
||||
ph->Hdpi = PHYSFSX_readShort(fp);
|
||||
ph->Vdpi = PHYSFSX_readShort(fp);
|
||||
PHYSFS_read(fp, &ph->ColorMap, 16*3, 1);
|
||||
ph->Reserved = PHYSFSX_readByte(fp);
|
||||
ph->Nplanes = PHYSFSX_readByte(fp);
|
||||
ph->BytesPerLine = PHYSFSX_readShort(fp);
|
||||
PHYSFS_read(fp, &ph->filler, 60, 1);
|
||||
RAII_SDL_Surface surface(IMG_LoadPCX_RW(rw.get()));
|
||||
if (!surface.surface)
|
||||
{
|
||||
con_printf(CON_NORMAL, "%s:%u: failed to create surface from \"%s\"", __FILE__, __LINE__, filename);
|
||||
return pcx_result::ERROR_OPENING;
|
||||
}
|
||||
return i;
|
||||
const auto &s = *surface.surface.get();
|
||||
const auto fmt = s.format;
|
||||
if (!fmt || fmt->BitsPerPixel != 8)
|
||||
return pcx_result::ERROR_WRONG_VERSION;
|
||||
const auto fpal = fmt->palette;
|
||||
if (!fpal || fpal->ncolors != palette.size())
|
||||
return pcx_result::ERROR_NO_PALETTE;
|
||||
const unsigned xsize = s.w;
|
||||
const unsigned ysize = s.h;
|
||||
if (xsize > 3840)
|
||||
return pcx_result::ERROR_MEMORY;
|
||||
if (ysize > 2400)
|
||||
return pcx_result::ERROR_MEMORY;
|
||||
DXX_CHECK_MEM_IS_DEFINED(s.pixels, xsize * ysize);
|
||||
gr_init_bitmap_alloc(bmp, bm_mode::linear, 0, 0, xsize, ysize, xsize);
|
||||
std::copy_n(reinterpret_cast<const uint8_t *>(s.pixels), xsize * ysize, &bmp.get_bitmap_data()[0]);
|
||||
{
|
||||
const auto a = [](const SDL_Color &c) {
|
||||
return rgb_t{
|
||||
static_cast<uint8_t>(c.r >> 2),
|
||||
static_cast<uint8_t>(c.g >> 2),
|
||||
static_cast<uint8_t>(c.b >> 2)
|
||||
};
|
||||
};
|
||||
std::transform(fpal->colors, fpal->colors + palette.size(), palette.begin(), a);
|
||||
}
|
||||
return pcx_result::SUCCESS;
|
||||
}
|
||||
#else
|
||||
static pcx_result pcx_read_blank(const char *const filename, grs_main_bitmap &bmp, palette_array_t &palette)
|
||||
{
|
||||
con_printf(CON_NORMAL, "%s:%u: PCX support disabled at compile time; cannot read file \"%s\"", __FILE__, __LINE__, filename);
|
||||
constexpr unsigned xsize = 640;
|
||||
constexpr unsigned ysize = 480;
|
||||
gr_init_bitmap_alloc(bmp, bm_mode::linear, 0, 0, xsize, ysize, xsize);
|
||||
auto &bitmap_data = *reinterpret_cast<uint8_t (*)[ysize][xsize]>(bmp.get_bitmap_data());
|
||||
constexpr uint8_t border = 1;
|
||||
constexpr uint8_t body = 0;
|
||||
std::fill(&bitmap_data[0][0], &bitmap_data[2][0], border);
|
||||
std::fill(&bitmap_data[2][0], &bitmap_data[ysize - 2][0], body);
|
||||
std::fill(&bitmap_data[ysize - 2][0], &bitmap_data[ysize][0], border);
|
||||
for (auto &&y : xrange(2u, ysize - 2))
|
||||
{
|
||||
bitmap_data[y][0] = border;
|
||||
bitmap_data[y][1] = border;
|
||||
bitmap_data[y][xsize - 2] = border;
|
||||
bitmap_data[y][xsize - 1] = border;
|
||||
}
|
||||
palette = {};
|
||||
palette[border] = {63, 63, 63};
|
||||
return pcx_result::SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -192,92 +257,19 @@ pcx_result bald_guy_load(const char *const filename, grs_bitmap *const bmp, pale
|
|||
|
||||
namespace dcx {
|
||||
|
||||
struct PCX_PHYSFS_file
|
||||
{
|
||||
RAIIPHYSFS_File PCXfile;
|
||||
};
|
||||
|
||||
static pcx_result pcx_read_bitmap_file(struct PCX_PHYSFS_file *const pcxphysfs, grs_main_bitmap &bmp, palette_array_t &palette);
|
||||
|
||||
pcx_result pcx_read_bitmap(const char *const filename, grs_main_bitmap &bmp, palette_array_t &palette)
|
||||
{
|
||||
PCX_PHYSFS_file pcxphysfs{PHYSFSX_openReadBuffered(filename)};
|
||||
if (!pcxphysfs.PCXfile)
|
||||
#if DXX_USE_SDLIMAGE
|
||||
auto rw = PHYSFSRWOPS_openRead(filename);
|
||||
if (!rw)
|
||||
{
|
||||
con_printf(CON_NORMAL, "%s:%u: failed to open \"%s\"", __FILE__, __LINE__, filename);
|
||||
return pcx_result::ERROR_OPENING;
|
||||
return pcx_read_bitmap_file(&pcxphysfs, bmp, palette);
|
||||
}
|
||||
|
||||
static int PCX_PHYSFS_read(struct PCX_PHYSFS_file *pcxphysfs, ubyte *data, unsigned size)
|
||||
{
|
||||
return PHYSFS_read(pcxphysfs->PCXfile, data, size, sizeof(*data));
|
||||
}
|
||||
|
||||
static pcx_result pcx_read_bitmap_file(struct PCX_PHYSFS_file *const pcxphysfs, grs_main_bitmap &bmp, palette_array_t &palette)
|
||||
{
|
||||
PCXHeader header;
|
||||
|
||||
// read 128 char PCX header
|
||||
if (PCXHeader_read_n( &header, 1, pcxphysfs->PCXfile )!=1) {
|
||||
return pcx_result::ERROR_NO_HEADER;
|
||||
}
|
||||
|
||||
// Is it a 256 color PCX file?
|
||||
if ((header.Manufacturer != 10)||(header.Encoding != 1)||(header.Nplanes != 1)||(header.BitsPerPixel != 8)||(header.Version != 5)) {
|
||||
return pcx_result::ERROR_WRONG_VERSION;
|
||||
}
|
||||
|
||||
// Find the size of the image
|
||||
const unsigned xsize = header.Xmax - header.Xmin + 1;
|
||||
if (xsize > 3840)
|
||||
return pcx_result::ERROR_MEMORY;
|
||||
const unsigned ysize = header.Ymax - header.Ymin + 1;
|
||||
if (ysize > 2400)
|
||||
return pcx_result::ERROR_MEMORY;
|
||||
|
||||
gr_init_bitmap_alloc(bmp, bm_mode::linear, 0, 0, xsize, ysize, xsize);
|
||||
|
||||
{
|
||||
range_for (const unsigned row, xrange(ysize))
|
||||
{
|
||||
auto pixdata = &bmp.get_bitmap_data()[bmp.bm_rowsize*row];
|
||||
for (unsigned col = 0; col < xsize;)
|
||||
{
|
||||
uint8_t data;
|
||||
if (PCX_PHYSFS_read(pcxphysfs, &data, 1) != 1) {
|
||||
return pcx_result::ERROR_READING;
|
||||
}
|
||||
if ((data & 0xC0) == 0xC0) {
|
||||
const unsigned count = std::min(data & 0x3Fu, xsize - col);
|
||||
if (PCX_PHYSFS_read(pcxphysfs, &data, 1) != 1) {
|
||||
return pcx_result::ERROR_READING;
|
||||
}
|
||||
memset( pixdata, data, count );
|
||||
pixdata += count;
|
||||
col += count;
|
||||
} else {
|
||||
*pixdata++ = data;
|
||||
col++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read the extended palette at the end of PCX file
|
||||
// Read in a character which should be 12 to be extended palette file
|
||||
{
|
||||
uint8_t data;
|
||||
if (PCX_PHYSFS_read(pcxphysfs, &data, 1) == 1) {
|
||||
if ( data == 12 ) {
|
||||
if (PCX_PHYSFS_read(pcxphysfs, reinterpret_cast<ubyte *>(&palette[0]), palette.size() * sizeof(palette[0])) != 1) {
|
||||
return pcx_result::ERROR_READING;
|
||||
}
|
||||
diminish_palette(palette);
|
||||
}
|
||||
} else {
|
||||
return pcx_result::ERROR_NO_PALETTE;
|
||||
}
|
||||
}
|
||||
return pcx_result::SUCCESS;
|
||||
return pcx_read_bitmap(filename, bmp, palette, std::move(rw));
|
||||
#else
|
||||
return pcx_read_blank(filename, bmp, palette);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !DXX_USE_OGL && DXX_USE_SCREENSHOT_FORMAT_LEGACY
|
||||
|
|
|
@ -17,6 +17,11 @@
|
|||
#include "text.h"
|
||||
#include "args.h"
|
||||
#include "window.h"
|
||||
#include "dxxsconf.h"
|
||||
|
||||
#if DXX_USE_SDLIMAGE
|
||||
#include <SDL_image.h>
|
||||
#endif
|
||||
|
||||
namespace dsx {
|
||||
|
||||
|
@ -36,6 +41,9 @@ static void arch_close(void)
|
|||
{
|
||||
digi_close();
|
||||
}
|
||||
#if DXX_USE_SDLIMAGE
|
||||
IMG_Quit();
|
||||
#endif
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
|
@ -50,6 +58,9 @@ arch_atexit arch_init()
|
|||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||
Error("SDL library initialisation failed: %s.",SDL_GetError());
|
||||
#if DXX_USE_SDLIMAGE
|
||||
IMG_Init(0);
|
||||
#endif
|
||||
#if SDL_MAJOR_VERSION == 2
|
||||
/* In SDL1, grabbing input grabbed both the keyboard and the mouse.
|
||||
* Many game management keys assume a keyboard grab.
|
||||
|
|
|
@ -111,6 +111,9 @@ char copyright[] = "DESCENT II COPYRIGHT (C) 1994-1996 PARALLAX SOFTWARE CORPOR
|
|||
#include "dsx-ns.h"
|
||||
#include "compiler-begin.h"
|
||||
|
||||
#if DXX_USE_SDLIMAGE
|
||||
#include <SDL_image.h>
|
||||
#endif
|
||||
#if DXX_USE_SDLMIXER
|
||||
#include <SDL_mixer.h>
|
||||
#endif
|
||||
|
@ -547,6 +550,14 @@ static int main(int argc, char *argv[])
|
|||
#endif
|
||||
con_printf(CON_VERBOSE, "D" DXX_NAME_NUMBER "X-Rebirth built with libSDL %u.%u.%u; loaded with libSDL %u.%u.%u", vc.major, vc.minor, vc.patch, vl->major, vl->minor, vl->patch);
|
||||
}
|
||||
#if DXX_USE_SDLIMAGE
|
||||
{
|
||||
SDL_version vc;
|
||||
SDL_IMAGE_VERSION(&vc);
|
||||
const auto vl = IMG_Linked_Version();
|
||||
con_printf(CON_VERBOSE, "D" DXX_NAME_NUMBER "X-Rebirth built with SDL_image %u.%u.%u; loaded with SDL_image %u.%u.%u", vc.major, vc.minor, vc.patch, vl->major, vl->minor, vl->patch);
|
||||
}
|
||||
#endif
|
||||
#if DXX_USE_SDLMIXER
|
||||
{
|
||||
SDL_version vc;
|
||||
|
|
Loading…
Reference in New Issue