add support for 8-bit PNG files (#1708)

* move V_LinearToTransPatch function to v_fmt.c

* add simplified V_LinearToPatch function

* rename the appropriate W_CacheLump* to V_CachePatch* or V_CacheFlatNum
This commit is contained in:
Roman Fomin 2024-05-28 08:11:14 +07:00 committed by GitHub
parent 882017454d
commit e100d5c3f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 8289 additions and 357 deletions

View File

@ -182,6 +182,7 @@ add_subdirectory(data)
add_subdirectory(opl)
add_subdirectory(textscreen)
add_subdirectory(miniz)
add_subdirectory(spng)
add_subdirectory(src)
add_subdirectory(toolsrc)
add_subdirectory(setup)

View File

@ -210,6 +210,10 @@ Copyright:
© 2013-2014 RAD Game Tools and Valve Software.
License: [MIT](https://opensource.org/licenses/MIT)
Files: `spng/*`
Copyright: © 2018-2023 Randy.
License: [BSD-2-Clause](https://opensource.org/license/bsd-2-clause)
Files: `opl/*`
Copyright:
© 2005-2014 Simon Howard;

View File

@ -6,7 +6,6 @@ target_woof_settings(miniz)
target_compile_definitions(miniz PRIVATE MINIZ_NO_TIME)
target_include_directories(miniz
INTERFACE "."
PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../" "../src/")
target_include_directories(miniz INTERFACE ".")
target_link_libraries(miniz)

11
spng/CMakeLists.txt Normal file
View File

@ -0,0 +1,11 @@
include(WoofSettings)
add_library(spng STATIC spng.c spng.h)
target_woof_settings(spng)
target_compile_definitions(spng PRIVATE SPNG_USE_MINIZ INTERFACE SPNG_STATIC)
target_include_directories(spng INTERFACE ".")
target_link_libraries(spng miniz)

25
spng/LICENSE Normal file
View File

@ -0,0 +1,25 @@
BSD 2-Clause License
Copyright (c) 2018-2023, Randy <randy408@protonmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

6980
spng/spng.c Normal file

File diff suppressed because it is too large Load Diff

537
spng/spng.h Normal file
View File

@ -0,0 +1,537 @@
/* SPDX-License-Identifier: BSD-2-Clause */
#ifndef SPNG_H
#define SPNG_H
#ifdef __cplusplus
extern "C" {
#endif
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(SPNG_STATIC)
#if defined(SPNG__BUILD)
#define SPNG_API __declspec(dllexport)
#else
#define SPNG_API __declspec(dllimport)
#endif
#else
#define SPNG_API
#endif
#if defined(_MSC_VER)
#define SPNG_CDECL __cdecl
#else
#define SPNG_CDECL
#endif
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#define SPNG_VERSION_MAJOR 0
#define SPNG_VERSION_MINOR 7
#define SPNG_VERSION_PATCH 4
enum spng_errno
{
SPNG_IO_ERROR = -2,
SPNG_IO_EOF = -1,
SPNG_OK = 0,
SPNG_EINVAL,
SPNG_EMEM,
SPNG_EOVERFLOW,
SPNG_ESIGNATURE,
SPNG_EWIDTH,
SPNG_EHEIGHT,
SPNG_EUSER_WIDTH,
SPNG_EUSER_HEIGHT,
SPNG_EBIT_DEPTH,
SPNG_ECOLOR_TYPE,
SPNG_ECOMPRESSION_METHOD,
SPNG_EFILTER_METHOD,
SPNG_EINTERLACE_METHOD,
SPNG_EIHDR_SIZE,
SPNG_ENOIHDR,
SPNG_ECHUNK_POS,
SPNG_ECHUNK_SIZE,
SPNG_ECHUNK_CRC,
SPNG_ECHUNK_TYPE,
SPNG_ECHUNK_UNKNOWN_CRITICAL,
SPNG_EDUP_PLTE,
SPNG_EDUP_CHRM,
SPNG_EDUP_GAMA,
SPNG_EDUP_ICCP,
SPNG_EDUP_SBIT,
SPNG_EDUP_SRGB,
SPNG_EDUP_BKGD,
SPNG_EDUP_HIST,
SPNG_EDUP_TRNS,
SPNG_EDUP_PHYS,
SPNG_EDUP_TIME,
SPNG_EDUP_OFFS,
SPNG_EDUP_EXIF,
SPNG_ECHRM,
SPNG_EPLTE_IDX,
SPNG_ETRNS_COLOR_TYPE,
SPNG_ETRNS_NO_PLTE,
SPNG_EGAMA,
SPNG_EICCP_NAME,
SPNG_EICCP_COMPRESSION_METHOD,
SPNG_ESBIT,
SPNG_ESRGB,
SPNG_ETEXT,
SPNG_ETEXT_KEYWORD,
SPNG_EZTXT,
SPNG_EZTXT_COMPRESSION_METHOD,
SPNG_EITXT,
SPNG_EITXT_COMPRESSION_FLAG,
SPNG_EITXT_COMPRESSION_METHOD,
SPNG_EITXT_LANG_TAG,
SPNG_EITXT_TRANSLATED_KEY,
SPNG_EBKGD_NO_PLTE,
SPNG_EBKGD_PLTE_IDX,
SPNG_EHIST_NO_PLTE,
SPNG_EPHYS,
SPNG_ESPLT_NAME,
SPNG_ESPLT_DUP_NAME,
SPNG_ESPLT_DEPTH,
SPNG_ETIME,
SPNG_EOFFS,
SPNG_EEXIF,
SPNG_EIDAT_TOO_SHORT,
SPNG_EIDAT_STREAM,
SPNG_EZLIB,
SPNG_EFILTER,
SPNG_EBUFSIZ,
SPNG_EIO,
SPNG_EOF,
SPNG_EBUF_SET,
SPNG_EBADSTATE,
SPNG_EFMT,
SPNG_EFLAGS,
SPNG_ECHUNKAVAIL,
SPNG_ENCODE_ONLY,
SPNG_EOI,
SPNG_ENOPLTE,
SPNG_ECHUNK_LIMITS,
SPNG_EZLIB_INIT,
SPNG_ECHUNK_STDLEN,
SPNG_EINTERNAL,
SPNG_ECTXTYPE,
SPNG_ENOSRC,
SPNG_ENODST,
SPNG_EOPSTATE,
SPNG_ENOTFINAL,
};
enum spng_text_type
{
SPNG_TEXT = 1,
SPNG_ZTXT = 2,
SPNG_ITXT = 3
};
enum spng_color_type
{
SPNG_COLOR_TYPE_GRAYSCALE = 0,
SPNG_COLOR_TYPE_TRUECOLOR = 2,
SPNG_COLOR_TYPE_INDEXED = 3,
SPNG_COLOR_TYPE_GRAYSCALE_ALPHA = 4,
SPNG_COLOR_TYPE_TRUECOLOR_ALPHA = 6
};
enum spng_filter
{
SPNG_FILTER_NONE = 0,
SPNG_FILTER_SUB = 1,
SPNG_FILTER_UP = 2,
SPNG_FILTER_AVERAGE = 3,
SPNG_FILTER_PAETH = 4
};
enum spng_filter_choice
{
SPNG_DISABLE_FILTERING = 0,
SPNG_FILTER_CHOICE_NONE = 8,
SPNG_FILTER_CHOICE_SUB = 16,
SPNG_FILTER_CHOICE_UP = 32,
SPNG_FILTER_CHOICE_AVG = 64,
SPNG_FILTER_CHOICE_PAETH = 128,
SPNG_FILTER_CHOICE_ALL = (8|16|32|64|128)
};
enum spng_interlace_method
{
SPNG_INTERLACE_NONE = 0,
SPNG_INTERLACE_ADAM7 = 1
};
/* Channels are always in byte-order */
enum spng_format
{
SPNG_FMT_RGBA8 = 1,
SPNG_FMT_RGBA16 = 2,
SPNG_FMT_RGB8 = 4,
/* Partially implemented, see documentation */
SPNG_FMT_GA8 = 16,
SPNG_FMT_GA16 = 32,
SPNG_FMT_G8 = 64,
/* No conversion or scaling */
SPNG_FMT_PNG = 256,
SPNG_FMT_RAW = 512 /* big-endian (everything else is host-endian) */
};
enum spng_ctx_flags
{
SPNG_CTX_IGNORE_ADLER32 = 1, /* Ignore checksum in DEFLATE streams */
SPNG_CTX_ENCODER = 2 /* Create an encoder context */
};
enum spng_decode_flags
{
SPNG_DECODE_USE_TRNS = 1, /* Deprecated */
SPNG_DECODE_USE_GAMA = 2, /* Deprecated */
SPNG_DECODE_USE_SBIT = 8, /* Undocumented */
SPNG_DECODE_TRNS = 1, /* Apply transparency */
SPNG_DECODE_GAMMA = 2, /* Apply gamma correction */
SPNG_DECODE_PROGRESSIVE = 256 /* Initialize for progressive reads */
};
enum spng_crc_action
{
/* Default for critical chunks */
SPNG_CRC_ERROR = 0,
/* Discard chunk, invalid for critical chunks.
Since v0.6.2: default for ancillary chunks */
SPNG_CRC_DISCARD = 1,
/* Ignore and don't calculate checksum.
Since v0.6.2: also ignores checksums in DEFLATE streams */
SPNG_CRC_USE = 2
};
enum spng_encode_flags
{
SPNG_ENCODE_PROGRESSIVE = 1, /* Initialize for progressive writes */
SPNG_ENCODE_FINALIZE = 2, /* Finalize PNG after encoding image */
};
struct spng_ihdr
{
uint32_t width;
uint32_t height;
uint8_t bit_depth;
uint8_t color_type;
uint8_t compression_method;
uint8_t filter_method;
uint8_t interlace_method;
};
struct spng_plte_entry
{
uint8_t red;
uint8_t green;
uint8_t blue;
uint8_t alpha; /* Reserved for internal use */
};
struct spng_plte
{
uint32_t n_entries;
struct spng_plte_entry entries[256];
};
struct spng_trns
{
uint16_t gray;
uint16_t red;
uint16_t green;
uint16_t blue;
uint32_t n_type3_entries;
uint8_t type3_alpha[256];
};
struct spng_chrm_int
{
uint32_t white_point_x;
uint32_t white_point_y;
uint32_t red_x;
uint32_t red_y;
uint32_t green_x;
uint32_t green_y;
uint32_t blue_x;
uint32_t blue_y;
};
struct spng_chrm
{
double white_point_x;
double white_point_y;
double red_x;
double red_y;
double green_x;
double green_y;
double blue_x;
double blue_y;
};
struct spng_iccp
{
char profile_name[80];
size_t profile_len;
char *profile;
};
struct spng_sbit
{
uint8_t grayscale_bits;
uint8_t red_bits;
uint8_t green_bits;
uint8_t blue_bits;
uint8_t alpha_bits;
};
struct spng_text
{
char keyword[80];
int type;
size_t length;
char *text;
uint8_t compression_flag; /* iTXt only */
uint8_t compression_method; /* iTXt, ztXt only */
char *language_tag; /* iTXt only */
char *translated_keyword; /* iTXt only */
};
struct spng_bkgd
{
uint16_t gray; /* Only for gray/gray alpha */
uint16_t red;
uint16_t green;
uint16_t blue;
uint16_t plte_index; /* Only for indexed color */
};
struct spng_hist
{
uint16_t frequency[256];
};
struct spng_phys
{
uint32_t ppu_x, ppu_y;
uint8_t unit_specifier;
};
struct spng_splt_entry
{
uint16_t red;
uint16_t green;
uint16_t blue;
uint16_t alpha;
uint16_t frequency;
};
struct spng_splt
{
char name[80];
uint8_t sample_depth;
uint32_t n_entries;
struct spng_splt_entry *entries;
};
struct spng_time
{
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
};
struct spng_offs
{
int32_t x, y;
uint8_t unit_specifier;
};
struct spng_exif
{
size_t length;
char *data;
};
struct spng_chunk
{
size_t offset;
uint32_t length;
uint8_t type[4];
uint32_t crc;
};
enum spng_location
{
SPNG_AFTER_IHDR = 1,
SPNG_AFTER_PLTE = 2,
SPNG_AFTER_IDAT = 8,
};
struct spng_unknown_chunk
{
uint8_t type[4];
size_t length;
void *data;
enum spng_location location;
};
enum spng_option
{
SPNG_KEEP_UNKNOWN_CHUNKS = 1,
SPNG_IMG_COMPRESSION_LEVEL,
SPNG_IMG_WINDOW_BITS,
SPNG_IMG_MEM_LEVEL,
SPNG_IMG_COMPRESSION_STRATEGY,
SPNG_TEXT_COMPRESSION_LEVEL,
SPNG_TEXT_WINDOW_BITS,
SPNG_TEXT_MEM_LEVEL,
SPNG_TEXT_COMPRESSION_STRATEGY,
SPNG_FILTER_CHOICE,
SPNG_CHUNK_COUNT_LIMIT,
SPNG_ENCODE_TO_BUFFER,
};
typedef void* SPNG_CDECL spng_malloc_fn(size_t size);
typedef void* SPNG_CDECL spng_realloc_fn(void* ptr, size_t size);
typedef void* SPNG_CDECL spng_calloc_fn(size_t count, size_t size);
typedef void SPNG_CDECL spng_free_fn(void* ptr);
struct spng_alloc
{
spng_malloc_fn *malloc_fn;
spng_realloc_fn *realloc_fn;
spng_calloc_fn *calloc_fn;
spng_free_fn *free_fn;
};
struct spng_row_info
{
uint32_t scanline_idx;
uint32_t row_num; /* deinterlaced row index */
int pass;
uint8_t filter;
};
typedef struct spng_ctx spng_ctx;
typedef int spng_read_fn(spng_ctx *ctx, void *user, void *dest, size_t length);
typedef int spng_write_fn(spng_ctx *ctx, void *user, void *src, size_t length);
typedef int spng_rw_fn(spng_ctx *ctx, void *user, void *dst_src, size_t length);
SPNG_API spng_ctx *spng_ctx_new(int flags);
SPNG_API spng_ctx *spng_ctx_new2(struct spng_alloc *alloc, int flags);
SPNG_API void spng_ctx_free(spng_ctx *ctx);
SPNG_API int spng_set_png_buffer(spng_ctx *ctx, const void *buf, size_t size);
SPNG_API int spng_set_png_stream(spng_ctx *ctx, spng_rw_fn *rw_func, void *user);
SPNG_API int spng_set_png_file(spng_ctx *ctx, FILE *file);
SPNG_API void *spng_get_png_buffer(spng_ctx *ctx, size_t *len, int *error);
SPNG_API int spng_set_image_limits(spng_ctx *ctx, uint32_t width, uint32_t height);
SPNG_API int spng_get_image_limits(spng_ctx *ctx, uint32_t *width, uint32_t *height);
SPNG_API int spng_set_chunk_limits(spng_ctx *ctx, size_t chunk_size, size_t cache_size);
SPNG_API int spng_get_chunk_limits(spng_ctx *ctx, size_t *chunk_size, size_t *cache_size);
SPNG_API int spng_set_crc_action(spng_ctx *ctx, int critical, int ancillary);
SPNG_API int spng_set_option(spng_ctx *ctx, enum spng_option option, int value);
SPNG_API int spng_get_option(spng_ctx *ctx, enum spng_option option, int *value);
SPNG_API int spng_decoded_image_size(spng_ctx *ctx, int fmt, size_t *len);
/* Decode */
SPNG_API int spng_decode_image(spng_ctx *ctx, void *out, size_t len, int fmt, int flags);
/* Progressive decode */
SPNG_API int spng_decode_scanline(spng_ctx *ctx, void *out, size_t len);
SPNG_API int spng_decode_row(spng_ctx *ctx, void *out, size_t len);
SPNG_API int spng_decode_chunks(spng_ctx *ctx);
/* Encode/decode */
SPNG_API int spng_get_row_info(spng_ctx *ctx, struct spng_row_info *row_info);
/* Encode */
SPNG_API int spng_encode_image(spng_ctx *ctx, const void *img, size_t len, int fmt, int flags);
/* Progressive encode */
SPNG_API int spng_encode_scanline(spng_ctx *ctx, const void *scanline, size_t len);
SPNG_API int spng_encode_row(spng_ctx *ctx, const void *row, size_t len);
SPNG_API int spng_encode_chunks(spng_ctx *ctx);
SPNG_API int spng_get_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr);
SPNG_API int spng_get_plte(spng_ctx *ctx, struct spng_plte *plte);
SPNG_API int spng_get_trns(spng_ctx *ctx, struct spng_trns *trns);
SPNG_API int spng_get_chrm(spng_ctx *ctx, struct spng_chrm *chrm);
SPNG_API int spng_get_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int);
SPNG_API int spng_get_gama(spng_ctx *ctx, double *gamma);
SPNG_API int spng_get_gama_int(spng_ctx *ctx, uint32_t *gama_int);
SPNG_API int spng_get_iccp(spng_ctx *ctx, struct spng_iccp *iccp);
SPNG_API int spng_get_sbit(spng_ctx *ctx, struct spng_sbit *sbit);
SPNG_API int spng_get_srgb(spng_ctx *ctx, uint8_t *rendering_intent);
SPNG_API int spng_get_text(spng_ctx *ctx, struct spng_text *text, uint32_t *n_text);
SPNG_API int spng_get_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd);
SPNG_API int spng_get_hist(spng_ctx *ctx, struct spng_hist *hist);
SPNG_API int spng_get_phys(spng_ctx *ctx, struct spng_phys *phys);
SPNG_API int spng_get_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t *n_splt);
SPNG_API int spng_get_time(spng_ctx *ctx, struct spng_time *time);
SPNG_API int spng_get_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t *n_chunks);
/* Official extensions */
SPNG_API int spng_get_offs(spng_ctx *ctx, struct spng_offs *offs);
SPNG_API int spng_get_exif(spng_ctx *ctx, struct spng_exif *exif);
SPNG_API int spng_set_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr);
SPNG_API int spng_set_plte(spng_ctx *ctx, struct spng_plte *plte);
SPNG_API int spng_set_trns(spng_ctx *ctx, struct spng_trns *trns);
SPNG_API int spng_set_chrm(spng_ctx *ctx, struct spng_chrm *chrm);
SPNG_API int spng_set_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int);
SPNG_API int spng_set_gama(spng_ctx *ctx, double gamma);
SPNG_API int spng_set_gama_int(spng_ctx *ctx, uint32_t gamma);
SPNG_API int spng_set_iccp(spng_ctx *ctx, struct spng_iccp *iccp);
SPNG_API int spng_set_sbit(spng_ctx *ctx, struct spng_sbit *sbit);
SPNG_API int spng_set_srgb(spng_ctx *ctx, uint8_t rendering_intent);
SPNG_API int spng_set_text(spng_ctx *ctx, struct spng_text *text, uint32_t n_text);
SPNG_API int spng_set_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd);
SPNG_API int spng_set_hist(spng_ctx *ctx, struct spng_hist *hist);
SPNG_API int spng_set_phys(spng_ctx *ctx, struct spng_phys *phys);
SPNG_API int spng_set_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t n_splt);
SPNG_API int spng_set_time(spng_ctx *ctx, struct spng_time *time);
SPNG_API int spng_set_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t n_chunks);
/* Official extensions */
SPNG_API int spng_set_offs(spng_ctx *ctx, struct spng_offs *offs);
SPNG_API int spng_set_exif(spng_ctx *ctx, struct spng_exif *exif);
SPNG_API const char *spng_strerror(int err);
SPNG_API const char *spng_version_string(void);
#ifdef __cplusplus
}
#endif
#endif /* SPNG_H */

View File

@ -130,6 +130,7 @@ set(WOOF_SOURCES
u_mapinfo.c u_mapinfo.h
u_scanner.c u_scanner.h
v_flextran.c v_flextran.h
v_fmt.c v_fmt.h
v_trans.c v_trans.h
v_video.c v_video.h
version.c version.h
@ -182,7 +183,8 @@ target_link_libraries(woof PRIVATE
SndFile::sndfile
opl
textscreen
miniz)
miniz
spng)
# Some platforms require standard libraries to be linked against.
if(HAVE_LIBM)

View File

@ -45,8 +45,8 @@
#include "st_stuff.h"
#include "tables.h"
#include "v_flextran.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
//jff 1/7/98 default automap colors added
@ -548,7 +548,7 @@ static void AM_loadPics(void)
for (i=0;i<10;i++)
{
M_snprintf(namebuf, sizeof(namebuf), "AMMNUM%d", i);
marknums[i] = W_CacheLumpName(namebuf, PU_STATIC);
marknums[i] = V_CachePatchName(namebuf, PU_STATIC);
}
}

View File

@ -79,6 +79,7 @@
#include "st_stuff.h"
#include "statdump.h"
#include "u_mapinfo.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "wi_stuff.h"
@ -382,7 +383,7 @@ void D_Display (void)
{
int x = scaledviewx;
int y = 4;
patch_t *patch = W_CacheLumpName("M_PAUSE", PU_CACHE);
patch_t *patch = V_CachePatchName("M_PAUSE", PU_CACHE);
x += (scaledviewwidth - SHORT(patch->width)) / 2 - video.deltaw;
@ -464,6 +465,8 @@ void D_PageDrawer(void)
{
if (pagename)
{
V_DrawPatchFullScreen(V_CachePatchName(pagename, PU_CACHE));
#if 0
int l = W_CheckNumForName(pagename);
byte *t = W_CacheLumpNum(l, PU_CACHE);
size_t s = W_LumpLength(l);
@ -477,6 +480,7 @@ void D_PageDrawer(void)
{
V_DrawPatch(0, 0, W_CacheLumpName("DOGOVRLY", PU_CACHE));
}
#endif
}
else
MN_DrawCredits();

View File

@ -36,6 +36,7 @@
#include "s_sound.h"
#include "sounds.h"
#include "u_mapinfo.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "wi_stuff.h"
@ -355,7 +356,7 @@ void F_TextWrite (void)
if (gamemapinfo && W_CheckNumForName(finaleflat) != -1 &&
(W_CheckNumForName)(finaleflat, ns_flats) == -1)
{
V_DrawPatchFullScreen(W_CacheLumpName(finaleflat, PU_LEVEL));
V_DrawPatchFullScreen(V_CachePatchName(finaleflat, PU_LEVEL));
}
else if ((W_CheckNumForName)(finaleflat, ns_flats) != -1)
{
@ -661,7 +662,7 @@ void F_CastDrawer (void)
patch_t* patch;
// erase the entire screen to a background
V_DrawPatchFullScreen (W_CacheLumpName (bgcastcall, PU_CACHE)); // Ty 03/30/98 bg texture extern
V_DrawPatchFullScreen (V_CachePatchName (bgcastcall, PU_CACHE)); // Ty 03/30/98 bg texture extern
F_CastPrint (castorder[castnum].name);
@ -671,7 +672,7 @@ void F_CastDrawer (void)
lump = sprframe->lump[0];
flip = (boolean)sprframe->flip[0];
patch = W_CacheLumpNum (lump+firstspritelump, PU_CACHE);
patch = V_CachePatchNum (lump+firstspritelump, PU_CACHE);
if (flip)
V_DrawPatchFlipped (160, 170, patch);
else
@ -691,8 +692,8 @@ void F_BunnyScroll (void)
static int laststage;
int offset;
p1 = W_CacheLumpName ("PFUB2", PU_LEVEL);
p2 = W_CacheLumpName ("PFUB1", PU_LEVEL);
p1 = V_CachePatchName ("PFUB2", PU_LEVEL);
p2 = V_CachePatchName ("PFUB1", PU_LEVEL);
scrolled = 320 - (finalecount-230)/2;
if (scrolled > 320)
@ -722,7 +723,7 @@ void F_BunnyScroll (void)
{
V_DrawPatch ((SCREENWIDTH-13*8)/2,
(SCREENHEIGHT-8*8)/2,
W_CacheLumpName ("END0",PU_CACHE));
V_CachePatchName ("END0",PU_CACHE));
laststage = 0;
return;
}
@ -739,7 +740,7 @@ void F_BunnyScroll (void)
M_snprintf(name, sizeof(name), "END%i", stage);
V_DrawPatch ((SCREENWIDTH-13*8)/2,
(SCREENHEIGHT-8*8)/2,
W_CacheLumpName (name,PU_CACHE));
V_CachePatchName (name,PU_CACHE));
}
@ -760,7 +761,7 @@ void F_Drawer (void)
}
else
{
V_DrawPatchFullScreen(W_CacheLumpName(gamemapinfo->endpic, PU_CACHE));
V_DrawPatchFullScreen(V_CachePatchName(gamemapinfo->endpic, PU_CACHE));
}
return;
}
@ -779,18 +780,18 @@ void F_Drawer (void)
{
case 1:
if ( gamemode == retail || gamemode == commercial )
V_DrawPatchFullScreen (W_CacheLumpName("CREDIT",PU_CACHE));
V_DrawPatchFullScreen (V_CachePatchName("CREDIT",PU_CACHE));
else
V_DrawPatchFullScreen (W_CacheLumpName("HELP2",PU_CACHE));
V_DrawPatchFullScreen (V_CachePatchName("HELP2",PU_CACHE));
break;
case 2:
V_DrawPatchFullScreen (W_CacheLumpName("VICTORY2",PU_CACHE));
V_DrawPatchFullScreen (V_CachePatchName("VICTORY2",PU_CACHE));
break;
case 3:
F_BunnyScroll ();
break;
case 4:
V_DrawPatchFullScreen (W_CacheLumpName("ENDPIC",PU_CACHE));
V_DrawPatchFullScreen (V_CachePatchName("ENDPIC",PU_CACHE));
break;
}
}

View File

@ -54,6 +54,7 @@
#include "tables.h"
#include "u_mapinfo.h"
#include "u_scanner.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
@ -378,28 +379,28 @@ void HU_Init(void)
{
M_snprintf(buffer, sizeof(buffer), "STCFN%.3d", j);
if (W_CheckNumForName(buffer) != -1)
big_font.patches[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
big_font.patches[i] = V_CachePatchName(buffer, PU_STATIC);
if ('0' <= j && j <= '9')
{
M_snprintf(buffer, sizeof(buffer), "DIG%.1d", j - 48);
sml_font.patches[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
sml_font.patches[i] = V_CachePatchName(buffer, PU_STATIC);
}
else if ('A' <= j && j <= 'Z')
{
M_snprintf(buffer, sizeof(buffer), "DIG%c", j);
sml_font.patches[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
sml_font.patches[i] = V_CachePatchName(buffer, PU_STATIC);
}
else if (j > 122)
{
M_snprintf(buffer, sizeof(buffer), "STBR%.3d", j);
sml_font.patches[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
sml_font.patches[i] = V_CachePatchName(buffer, PU_STATIC);
}
else
{
M_snprintf(buffer, sizeof(buffer), "DIG%.2d", j);
if (W_CheckNumForName(buffer) != -1)
sml_font.patches[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
sml_font.patches[i] = V_CachePatchName(buffer, PU_STATIC);
}
// [FG] small font available, big font unavailable
@ -425,7 +426,7 @@ void HU_Init(void)
{
M_snprintf(buffer, sizeof(buffer), "STKEYS%.1d", j);
sml_font.patches[i] =
big_font.patches[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
big_font.patches[i] = V_CachePatchName(buffer, PU_STATIC);
}
// [FG] calculate font height once right here
@ -1319,7 +1320,7 @@ static void HU_StartCrosshair(void)
if (crosshair_lumps[hud_crosshair])
{
crosshair.patch = W_CacheLumpName(crosshair_lumps[hud_crosshair], PU_STATIC);
crosshair.patch = V_CachePatchName(crosshair_lumps[hud_crosshair], PU_STATIC);
crosshair.w = SHORT(crosshair.patch->width)/2;
crosshair.h = SHORT(crosshair.patch->height)/2;

View File

@ -50,6 +50,7 @@
#include "r_plane.h"
#include "r_voxel.h"
#include "st_stuff.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
@ -849,7 +850,7 @@ static void I_InitDiskFlash(void)
old_data = Z_Malloc(disk.sw * disk.sh * sizeof(*old_data), PU_STATIC, 0);
V_GetBlock(0, 0, disk.sw, disk.sh, temp);
V_DrawPatch(-video.deltaw, 0, W_CacheLumpName("STDISK", PU_CACHE));
V_DrawPatch(-video.deltaw, 0, V_CachePatchName("STDISK", PU_CACHE));
V_GetBlock(0, 0, disk.sw, disk.sh, diskflash);
V_PutBlock(0, 0, disk.sw, disk.sh, temp);

View File

@ -37,6 +37,8 @@
#define SHORT(x) ((signed short) SDL_SwapLE16(x))
#define LONG(x) ((signed int) SDL_SwapLE32(x))
#define SWAP_BE32(x) ((signed int) SDL_SwapBE32(x))
#endif
//----------------------------------------------------------------------------

View File

@ -16,7 +16,6 @@
// DESCRIPTION:
// Load and draw ZDoom FON2 fonts
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
@ -25,8 +24,10 @@
#include "m_misc.h"
#include "m_swap.h"
#include "r_defs.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
typedef struct
{
@ -157,7 +158,7 @@ boolean MN_LoadFon2(const byte *gfx_data, int size)
}
chars[i].patch = V_LinearToTransPatch(data, chars[i].width, height,
color_key);
color_key, PU_STATIC, NULL);
free(data);
}

View File

@ -56,6 +56,7 @@
#include "s_sound.h"
#include "sounds.h"
#include "u_mapinfo.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
@ -316,7 +317,7 @@ static void M_DrawMainMenu(void)
options_active = false;
V_DrawPatch(94, 2, W_CacheLumpName("M_DOOM", PU_CACHE));
V_DrawPatch(94, 2, V_CachePatchName("M_DOOM", PU_CACHE));
}
/////////////////////////////
@ -421,7 +422,7 @@ static void M_DrawReadThis1(void)
{
inhelpscreens = true;
V_DrawPatchFullScreen(W_CacheLumpName("HELP2", PU_CACHE));
V_DrawPatchFullScreen(V_CachePatchName("HELP2", PU_CACHE));
}
//
@ -436,14 +437,14 @@ static void M_DrawReadThis2(void)
// We only ever draw the second page if this is
// gameversion == exe_doom_1_9 and gamemode == registered
V_DrawPatchFullScreen(W_CacheLumpName("HELP1", PU_CACHE));
V_DrawPatchFullScreen(V_CachePatchName("HELP1", PU_CACHE));
}
static void M_DrawReadThisCommercial(void)
{
inhelpscreens = true;
V_DrawPatchFullScreen(W_CacheLumpName("HELP", PU_CACHE));
V_DrawPatchFullScreen(V_CachePatchName("HELP", PU_CACHE));
}
/////////////////////////////
@ -879,15 +880,15 @@ static void M_DrawSaveLoadBorder(int x, int y, byte *cr)
{
int i;
V_DrawPatchTranslated(x - 8, y + 7, W_CacheLumpName("M_LSLEFT", PU_CACHE), cr);
V_DrawPatchTranslated(x - 8, y + 7, V_CachePatchName("M_LSLEFT", PU_CACHE), cr);
for (i = 0; i < 24; i++)
{
V_DrawPatchTranslated(x, y + 7, W_CacheLumpName("M_LSCNTR", PU_CACHE), cr);
V_DrawPatchTranslated(x, y + 7, V_CachePatchName("M_LSCNTR", PU_CACHE), cr);
x += 8;
}
V_DrawPatchTranslated(x, y + 7, W_CacheLumpName("M_LSRGHT", PU_CACHE), cr);
V_DrawPatchTranslated(x, y + 7, V_CachePatchName("M_LSRGHT", PU_CACHE), cr);
}
//
@ -1677,7 +1678,7 @@ static void M_DrawExtHelp(void)
inhelpscreens = true; // killough 5/1/98
namebfr[4] = extended_help_index / 10 + 0x30;
namebfr[5] = extended_help_index % 10 + 0x30;
V_DrawPatchFullScreen(W_CacheLumpName(namebfr, PU_CACHE));
V_DrawPatchFullScreen(V_CachePatchName(namebfr, PU_CACHE));
}
//
@ -1699,7 +1700,7 @@ static void M_DrawHelp(void)
}
inhelpscreens = true; // killough 10/98
V_DrawPatchFullScreen(W_CacheLumpNum(helplump, PU_CACHE));
V_DrawPatchFullScreen(V_CachePatchNum(helplump, PU_CACHE));
}
//
@ -3155,7 +3156,7 @@ void M_Drawer(void)
}
else if (name[0])
{
patch_t *patch = W_CacheLumpName(name, PU_CACHE);
patch_t *patch = V_CachePatchName(name, PU_CACHE);
rect->y -= SHORT(patch->topoffset);
V_DrawPatchTranslated(x, y, patch, cr);
}
@ -3168,7 +3169,7 @@ void M_Drawer(void)
y = setup_active ? SCREENHEIGHT - 19 : currentMenu->y;
V_DrawPatch(x + SKULLXOFF, y - 5 + itemOn * LINEHEIGHT,
W_CacheLumpName(skullName[whichSkull], PU_CACHE));
V_CachePatchName(skullName[whichSkull], PU_CACHE));
if (delete_verify)
{
@ -3208,14 +3209,14 @@ static void M_DrawThermo(int x, int y, int thermWidth, int thermDot, byte *cr)
char num[4];
xx = x;
V_DrawPatchTranslated(xx, y, W_CacheLumpName("M_THERML", PU_CACHE), cr);
V_DrawPatchTranslated(xx, y, V_CachePatchName("M_THERML", PU_CACHE), cr);
xx += 8;
for (i = 0; i < thermWidth; i++)
{
V_DrawPatchTranslated(xx, y, W_CacheLumpName("M_THERMM", PU_CACHE), cr);
V_DrawPatchTranslated(xx, y, V_CachePatchName("M_THERMM", PU_CACHE), cr);
xx += 8;
}
V_DrawPatchTranslated(xx, y, W_CacheLumpName("M_THERMR", PU_CACHE), cr);
V_DrawPatchTranslated(xx, y, V_CachePatchName("M_THERMR", PU_CACHE), cr);
// [FG] write numerical values next to thermometer
M_snprintf(num, 4, "%3d", thermDot);
@ -3228,7 +3229,7 @@ static void M_DrawThermo(int x, int y, int thermWidth, int thermDot, byte *cr)
}
V_DrawPatchTranslated((x + 8) + thermDot * 8, y,
W_CacheLumpName("M_THERMO", PU_CACHE), cr);
V_CachePatchName("M_THERMO", PU_CACHE), cr);
}
//

View File

@ -49,6 +49,7 @@
#include "r_voxel.h"
#include "s_sound.h"
#include "sounds.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
@ -501,7 +502,7 @@ static void DrawItem(setup_menu_t *s, int accum_y)
// Draw the blinking version in tune with the blinking skull otherwise
const int index = (flags & (S_HILITE | S_SELECT)) ? whichSkull : 0;
patch_t *patch = W_CacheLumpName(reset_button_name[index], PU_CACHE);
patch_t *patch = V_CachePatchName(reset_button_name[index], PU_CACHE);
rect->x = x;
rect->y = y;
rect->w = SHORT(patch->width);
@ -579,16 +580,16 @@ static void DrawSetupThermo(int x, int y, int width, int size, int dot,
int i;
xx = x;
V_DrawPatchTranslated(xx, y, W_CacheLumpName("M_THERML", PU_CACHE), cr);
V_DrawPatchTranslated(xx, y, V_CachePatchName("M_THERML", PU_CACHE), cr);
xx += M_THRM_STEP;
patch_t *patch = W_CacheLumpName("M_THERMM", PU_CACHE);
patch_t *patch = V_CachePatchName("M_THERMM", PU_CACHE);
for (i = 0; i < width + 1; i++)
{
V_DrawPatchTranslated(xx, y, patch, cr);
xx += M_THRM_STEP;
}
V_DrawPatchTranslated(xx, y, W_CacheLumpName("M_THERMR", PU_CACHE), cr);
V_DrawPatchTranslated(xx, y, V_CachePatchName("M_THERMR", PU_CACHE), cr);
if (dot > size)
{
@ -598,7 +599,7 @@ static void DrawSetupThermo(int x, int y, int width, int size, int dot,
int step = width * M_THRM_STEP * FRACUNIT / size;
V_DrawPatchTranslated(x + M_THRM_STEP + dot * step / FRACUNIT, y,
W_CacheLumpName("M_THERMO", PU_CACHE), cr);
V_CachePatchName("M_THERMO", PU_CACHE), cr);
}
static void DrawSetting(setup_menu_t *s, int accum_y)
@ -892,7 +893,7 @@ static void DrawScreenItems(setup_menu_t *src)
static void DrawDefVerify()
{
V_DrawPatch(VERIFYBOXXORG, VERIFYBOXYORG,
W_CacheLumpName("M_VBOX", PU_CACHE));
V_CachePatchName("M_VBOX", PU_CACHE));
// The blinking messages is keyed off of the blinking of the
// cursor skull.
@ -907,7 +908,7 @@ static void DrawDefVerify()
void MN_DrawDelVerify(void)
{
V_DrawPatch(VERIFYBOXXORG, VERIFYBOXYORG,
W_CacheLumpName("M_VBOX", PU_CACHE));
V_CachePatchName("M_VBOX", PU_CACHE));
if (whichSkull)
{
@ -1546,7 +1547,7 @@ void MN_DrawStatusHUD(void)
if (hud_crosshair && current_page == 2)
{
patch_t *patch =
W_CacheLumpName(crosshair_lumps[hud_crosshair], PU_CACHE);
V_CachePatchName(crosshair_lumps[hud_crosshair], PU_CACHE);
int x = XH_X + 85 - SHORT(patch->width) / 2;
int y = M_Y + M_SPC / 2 - SHORT(patch->height) / 2 - 1;
@ -3756,7 +3757,7 @@ void MN_DrawTitle(int x, int y, const char *patch, const char *alttext)
if (patch_lump >= 0)
{
V_DrawPatch(x, y, W_CacheLumpNum(patch_lump, PU_CACHE));
V_DrawPatch(x, y, V_CachePatchNum(patch_lump, PU_CACHE));
}
else
{

View File

@ -44,6 +44,7 @@
#include "r_main.h"
#include "r_sky.h"
#include "r_state.h"
#include "v_fmt.h"
#include "v_video.h" // cr_dark, cr_shaded
#include "w_wad.h"
#include "z_zone.h"
@ -232,7 +233,7 @@ static void R_GenerateComposite(int texnum)
for (; --i >=0; patch++)
{
patch_t *realpatch = W_CacheLumpNum(patch->patch, PU_CACHE);
patch_t *realpatch = V_CachePatchNum(patch->patch, PU_CACHE);
int x, x1 = patch->originx, x2 = x1 + SHORT(realpatch->width);
const int *cofs = realpatch->columnofs - x1;
@ -348,7 +349,7 @@ static void R_GenerateLookup(int texnum, int *const errors)
while (--i >= 0)
{
int pat = patch->patch;
const patch_t *realpatch = W_CacheLumpNum(pat, PU_CACHE);
const patch_t *realpatch = V_CachePatchNum(pat, PU_CACHE);
int x, x1 = patch++->originx, x2 = x1 + SHORT(realpatch->width);
const int *cofs = realpatch->columnofs - x1;
@ -386,7 +387,7 @@ static void R_GenerateLookup(int texnum, int *const errors)
for (i = texture->patchcount, patch = texture->patches; --i >= 0;)
{
int pat = patch->patch;
const patch_t *realpatch = W_CacheLumpNum(pat, PU_CACHE);
const patch_t *realpatch = V_CachePatchNum(pat, PU_CACHE);
int x, x1 = patch++->originx, x2 = x1 + SHORT(realpatch->width);
const int *cofs = realpatch->columnofs - x1;
@ -833,7 +834,7 @@ void R_InitSpriteLumps(void)
if (!(i&127)) // killough
I_PutChar(VB_INFO, '.');
patch = W_CacheLumpNum(firstspritelump+i, PU_CACHE);
patch = V_CachePatchNum(firstspritelump+i, PU_CACHE);
spritewidth[i] = SHORT(patch->width)<<FRACBITS;
spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
@ -1160,7 +1161,7 @@ void R_PrecacheLevel(void)
for (i = numflats; --i >= 0; )
if (hitlist[i])
W_CacheLumpNum(firstflat + i, PU_CACHE);
V_CacheFlatNum(firstflat + i, PU_CACHE);
// Precache textures.
@ -1186,7 +1187,7 @@ void R_PrecacheLevel(void)
texture_t *texture = textures[i];
int j = texture->patchcount;
while (--j >= 0)
W_CacheLumpNum(texture->patches[j].patch, PU_CACHE);
V_CachePatchNum(texture->patches[j].patch, PU_CACHE);
}
// Precache sprites.
@ -1208,7 +1209,7 @@ void R_PrecacheLevel(void)
short *sflump = sprites[i].spriteframes[j].lump;
int k = 7;
do
W_CacheLumpNum(firstspritelump + sflump[k], PU_CACHE);
V_CachePatchNum(firstspritelump + sflump[k], PU_CACHE);
while (--k >= 0);
}
}
@ -1220,7 +1221,6 @@ void R_PrecacheLevel(void)
boolean R_IsPatchLump (const int lump)
{
int size;
int width, height;
const patch_t *patch;
boolean result;
@ -1229,22 +1229,12 @@ boolean R_IsPatchLump (const int lump)
if (lump < 0)
return false;
size = W_LumpLength(lump);
// minimum length of a valid Doom patch
if (size < 13)
return false;
patch = (const patch_t *)W_CacheLumpNum(lump, PU_CACHE);
// [FG] detect patches in PNG format early
if (!memcmp(patch, "\211PNG\r\n\032\n", 8))
return false;
patch = V_CachePatchNum(lump, PU_CACHE);
width = SHORT(patch->width);
height = SHORT(patch->height);
result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < size / 4);
result = (height > 0 && height <= 16384 && width > 0 && width <= 16384);
if (result)
{
@ -1259,7 +1249,7 @@ boolean R_IsPatchLump (const int lump)
unsigned int ofs = LONG(patch->columnofs[x]);
// Need one byte for an empty column (but there's patches that don't know that!)
if (ofs < (unsigned int)width * 4 + 8 || ofs >= (unsigned int)size)
if (ofs < (unsigned int)width * 4 + 8)
{
result = false;
break;

View File

@ -31,8 +31,8 @@
#include "r_draw.h"
#include "r_main.h"
#include "r_state.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
//
@ -862,38 +862,38 @@ void R_DrawBorder (int x, int y, int w, int h)
int i, j;
patch_t *patch;
patch = W_CacheLumpName("brdr_t", PU_CACHE);
patch = V_CachePatchName("brdr_t", PU_CACHE);
for (i = 0; i < w; i += 8)
V_DrawPatch(x + i - video.deltaw, y - 8, patch);
patch = W_CacheLumpName("brdr_b", PU_CACHE);
patch = V_CachePatchName("brdr_b", PU_CACHE);
for (i = 0; i < w; i += 8)
V_DrawPatch(x + i - video.deltaw, y + h, patch);
patch = W_CacheLumpName("brdr_l", PU_CACHE);
patch = V_CachePatchName("brdr_l", PU_CACHE);
for (j = 0; j < h; j += 8)
V_DrawPatch(x - 8 - video.deltaw, y + j, patch);
patch = W_CacheLumpName("brdr_r", PU_CACHE);
patch = V_CachePatchName("brdr_r", PU_CACHE);
for (j = 0; j < h; j += 8)
V_DrawPatch(x + w - video.deltaw, y + j, patch);
// Draw beveled edge.
V_DrawPatch(x - 8 - video.deltaw,
y - 8,
W_CacheLumpName("brdr_tl", PU_CACHE));
V_CachePatchName("brdr_tl", PU_CACHE));
V_DrawPatch(x + w - video.deltaw,
y - 8,
W_CacheLumpName("brdr_tr", PU_CACHE));
V_CachePatchName("brdr_tr", PU_CACHE));
V_DrawPatch(x - 8 - video.deltaw,
y + h,
W_CacheLumpName("brdr_bl", PU_CACHE));
V_CachePatchName("brdr_bl", PU_CACHE));
V_DrawPatch(x + w - video.deltaw,
y + h,
W_CacheLumpName("brdr_br", PU_CACHE));
V_CachePatchName("brdr_br", PU_CACHE));
}
void R_FillBackScreen (void)

View File

@ -49,8 +49,8 @@
#include "r_state.h"
#include "r_swirl.h" // [crispy] R_DistortedFlat()
#include "tables.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
#define MAXVISPLANES 128 /* must be a power of 2 */
@ -510,7 +510,7 @@ static void do_draw_plane(visplane_t *pl)
}
else
{
ds_source = W_CacheLumpNum(firstflat + flattranslation[pl->picnum],
ds_source = V_CacheFlatNum(firstflat + flattranslation[pl->picnum],
PU_STATIC);
ds_brightmap = R_BrightmapForFlatNum(flattranslation[pl->picnum]);
}

View File

@ -24,7 +24,7 @@
#include "i_system.h"
#include "m_fixed.h"
#include "tables.h"
#include "w_wad.h"
#include "v_fmt.h"
#include "z_zone.h"
boolean r_swirl;
@ -117,7 +117,7 @@ byte *R_DistortedFlat(int flatnum)
char *normalflat;
int i;
normalflat = W_CacheLumpNum(flatnum, PU_STATIC);
normalflat = V_CacheFlatNum(flatnum, PU_STATIC);
for (i = 0; i < FLATSIZE; i++)
{

View File

@ -42,6 +42,7 @@
#include "r_things.h"
#include "r_voxel.h"
#include "tables.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
@ -426,7 +427,7 @@ void R_DrawVisSprite(vissprite_t *vis, int x1, int x2)
column_t *column;
int texturecolumn;
fixed_t frac;
patch_t *patch = W_CacheLumpNum (vis->patch+firstspritelump, PU_CACHE);
patch_t *patch = V_CachePatchNum (vis->patch+firstspritelump, PU_CACHE);
dc_colormap[0] = vis->colormap[0];
dc_colormap[1] = vis->colormap[1];

View File

@ -23,6 +23,7 @@
#include "m_swap.h"
#include "r_defs.h"
#include "v_video.h"
#include "v_fmt.h"
#include "w_wad.h"
#include "z_zone.h"
@ -42,7 +43,7 @@ void STlib_init(void)
{
// [FG] allow playing with the Doom v1.2 IWAD which is missing the STTMINUS lump
if (W_CheckNumForName("STTMINUS") >= 0)
sttminus = (patch_t *) W_CacheLumpName("STTMINUS", PU_STATIC);
sttminus = V_CachePatchName("STTMINUS", PU_STATIC);
else
sttminus = NULL;
}

View File

@ -48,6 +48,7 @@
#include "st_lib.h"
#include "st_stuff.h"
#include "tables.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
@ -404,7 +405,7 @@ void ST_refreshBackground(void)
// in widescreen mode
const char *name = (gamemode == commercial) ? "GRNROCK" : "FLOOR7_2";
const byte *src = W_CacheLumpNum(firstflat + R_FlatNumForName(name), PU_CACHE);
const byte *src = V_CacheFlatNum(firstflat + R_FlatNumForName(name), PU_CACHE);
V_TileBlock64(SCREENHEIGHT - ST_HEIGHT, video.unscaledw, ST_HEIGHT, src);
@ -412,7 +413,7 @@ void ST_refreshBackground(void)
if (scaledviewwidth == video.unscaledw)
{
int x;
patch_t *patch = W_CacheLumpName("brdr_b", PU_CACHE);
patch_t *patch = V_CachePatchName("brdr_b", PU_CACHE);
for (x = 0; x < video.deltaw; x += 8)
{
@ -1086,24 +1087,24 @@ void ST_loadGraphics(void)
for (i=0;i<10;i++)
{
M_snprintf(namebuf, sizeof(namebuf), "STTNUM%d", i);
tallnum[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
tallnum[i] = V_CachePatchName(namebuf, PU_STATIC);
M_snprintf(namebuf, sizeof(namebuf), "STYSNUM%d", i);
shortnum[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
shortnum[i] = V_CachePatchName(namebuf, PU_STATIC);
}
// Load percent key.
//Note: why not load STMINUS here, too?
tallpercent = (patch_t *) W_CacheLumpName("STTPRCNT", PU_STATIC);
tallpercent = V_CachePatchName("STTPRCNT", PU_STATIC);
// key cards
for (i=0;i<NUMCARDS+3;i++) //jff 2/23/98 show both keys too
{
M_snprintf(namebuf, sizeof(namebuf), "STKEYS%d", i);
keys[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
keys[i] = V_CachePatchName(namebuf, PU_STATIC);
}
// arms background
armsbg = (patch_t *) W_CacheLumpName("STARMS", PU_STATIC);
armsbg = V_CachePatchName("STARMS", PU_STATIC);
// arms ownership widgets
for (i=0;i<6;i++)
@ -1111,7 +1112,7 @@ void ST_loadGraphics(void)
M_snprintf(namebuf, sizeof(namebuf), "STGNUM%d", i+2);
// gray #
arms[i][0] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
arms[i][0] = V_CachePatchName(namebuf, PU_STATIC);
// yellow #
arms[i][1] = shortnum[i+2];
@ -1123,19 +1124,19 @@ void ST_loadGraphics(void)
for (i=0; i<MAXPLAYERS; i++)
{
M_snprintf(namebuf, sizeof(namebuf), "STFB%d", i);
faceback[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
faceback[i] = V_CachePatchName(namebuf, PU_STATIC);
}
// status bar background bits
if (W_CheckNumForName("STBAR") >= 0)
{
sbar = (patch_t *) W_CacheLumpName("STBAR", PU_STATIC);
sbar = V_CachePatchName("STBAR", PU_STATIC);
sbarr = NULL;
}
else
{
sbar = (patch_t *) W_CacheLumpName("STMBARL", PU_STATIC);
sbarr = (patch_t *) W_CacheLumpName("STMBARR", PU_STATIC);
sbar = V_CachePatchName("STMBARL", PU_STATIC);
sbarr = V_CachePatchName("STMBARR", PU_STATIC);
}
// face states
@ -1146,21 +1147,21 @@ void ST_loadGraphics(void)
for (j=0;j<ST_NUMSTRAIGHTFACES;j++)
{
M_snprintf(namebuf, sizeof(namebuf), "STFST%d%d", i, j);
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
faces[facenum++] = V_CachePatchName(namebuf, PU_STATIC);
}
M_snprintf(namebuf, sizeof(namebuf), "STFTR%d0", i); // turn right
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
faces[facenum++] = V_CachePatchName(namebuf, PU_STATIC);
M_snprintf(namebuf, sizeof(namebuf), "STFTL%d0", i); // turn left
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
faces[facenum++] = V_CachePatchName(namebuf, PU_STATIC);
M_snprintf(namebuf, sizeof(namebuf), "STFOUCH%d", i); // ouch!
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
faces[facenum++] = V_CachePatchName(namebuf, PU_STATIC);
M_snprintf(namebuf, sizeof(namebuf), "STFEVL%d", i); // evil grin ;)
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
faces[facenum++] = V_CachePatchName(namebuf, PU_STATIC);
M_snprintf(namebuf, sizeof(namebuf), "STFKILL%d", i); // pissed off
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
faces[facenum++] = V_CachePatchName(namebuf, PU_STATIC);
}
faces[facenum++] = W_CacheLumpName("STFGOD0", PU_STATIC);
faces[facenum++] = W_CacheLumpName("STFDEAD0", PU_STATIC);
faces[facenum++] = V_CachePatchName("STFGOD0", PU_STATIC);
faces[facenum++] = V_CachePatchName("STFDEAD0", PU_STATIC);
// [FG] support face gib animations as in the 3DO/Jaguar/PSX ports
for (i = 0; i < ST_NUMXDTHFACES; i++)
@ -1168,7 +1169,7 @@ void ST_loadGraphics(void)
M_snprintf(namebuf, sizeof(namebuf), "STFXDTH%d", i);
if (W_CheckNumForName(namebuf) != -1)
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
faces[facenum++] = V_CachePatchName(namebuf, PU_STATIC);
else
break;
}
@ -1438,7 +1439,7 @@ void ST_InitRes(void)
void ST_Warnings(void)
{
int i;
patch_t *const patch = W_CacheLumpName("brdr_b", PU_CACHE);
patch_t *const patch = V_CachePatchName("brdr_b", PU_CACHE);
if (patch && SHORT(patch->height) > ST_HEIGHT)
{

546
src/v_fmt.c Normal file
View File

@ -0,0 +1,546 @@
//
// SLADE - It's a Doom Editor
// Copyright(C) 2008 - 2019 Simon Judd
// Copyright(C) 2024 Roman Fomin
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
#include "v_fmt.h"
#include <stdlib.h>
#include <string.h>
#include "doomtype.h"
#include "i_printf.h"
#include "m_swap.h"
#include "r_defs.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
#include "spng.h"
#define M_ARRAY_INIT_CAPACITY 256
#include "m_array.h"
#define NO_COLOR_KEY (-1)
typedef struct
{
byte row_off;
byte *pixels;
} vpost_t;
typedef struct
{
vpost_t *posts;
} vcolumn_t;
#define PUTBYTE(r, v) \
*r = (uint8_t)(v); \
++r
#define PUTSHORT(r, v) \
*(r + 0) = (byte)(((uint16_t)(v) >> 0) & 0xff); \
*(r + 1) = (byte)(((uint16_t)(v) >> 8) & 0xff); \
r += 2
#define PUTLONG(r, v) \
*(r + 0) = (byte)(((uint32_t)(v) >> 0) & 0xff); \
*(r + 1) = (byte)(((uint32_t)(v) >> 8) & 0xff); \
*(r + 2) = (byte)(((uint32_t)(v) >> 16) & 0xff); \
*(r + 3) = (byte)(((uint32_t)(v) >> 24) & 0xff); \
r += 4
//
// Converts a linear graphic to a patch with transparency. Mostly straight
// from SLADE.
//
patch_t *V_LinearToTransPatch(const byte *data, int width, int height,
int color_key, pu_tag tag, void **user)
{
vcolumn_t *columns = NULL;
// Go through columns
uint32_t offset = 0;
for (int c = 0; c < width; c++)
{
vcolumn_t col = {0};
vpost_t post = {0};
post.row_off = 0;
boolean ispost = false;
boolean first_254 = true; // first 254 pixels use absolute offsets
offset = c;
byte row_off = 0;
for (int r = 0; r < height; r++)
{
// if we're at offset 254, create a dummy post for tall doom gfx
// support
if (row_off == 254)
{
// Finish current post if any
if (ispost)
{
array_push(col.posts, post);
post.pixels = NULL;
ispost = false;
}
// Begin relative offsets
first_254 = false;
// Create dummy post
post.row_off = 254;
array_push(col.posts, post);
// Clear post
row_off = 0;
ispost = false;
}
// If the current pixel is not transparent, add it to the current
// post
if (data[offset] != color_key)
{
// If we're not currently building a post, begin one and set its
// offset
if (!ispost)
{
// Set offset
post.row_off = row_off;
// Reset offset if we're in relative offsets mode
if (!first_254)
{
row_off = 0;
}
// Start post
ispost = true;
}
// Add the pixel to the post
array_push(post.pixels, data[offset]);
}
else if (ispost)
{
// If the current pixel is transparent and we are currently
// building a post, add the current post to the list and clear
// it
array_push(col.posts, post);
post.pixels = NULL;
ispost = false;
}
// Go to next row
offset += width;
++row_off;
}
// If the column ended with a post, add it
if (ispost)
{
array_push(col.posts, post);
}
// Add the column data
array_push(columns, col);
// Go to next column
++offset;
}
size_t size = 0;
// Calculate needed memory size to allocate patch buffer
size += 4 * sizeof(int16_t); // 4 header shorts
size += array_size(columns) * sizeof(int32_t); // offsets table
for (int c = 0; c < array_size(columns); c++)
{
for (int p = 0; p < array_size(columns[c].posts); p++)
{
size_t post_len = 0;
post_len += 2; // two bytes for post header
post_len += 1; // dummy byte
post_len += array_size(columns[c].posts[p].pixels); // pixels
post_len += 1; // dummy byte
size += post_len;
}
size += 1; // room for 0xff cap byte
}
byte *output = Z_Malloc(size, tag, user);
byte *rover = output;
// write header fields
PUTSHORT(rover, width);
PUTSHORT(rover, height);
// This is written to afterwards
PUTSHORT(rover, 0);
PUTSHORT(rover, 0);
// set starting position of column offsets table, and skip over it
byte *col_offsets = rover;
rover += array_size(columns) * 4;
for (int c = 0; c < array_size(columns); c++)
{
// write column offset to offset table
uint32_t offs = (uint32_t)(rover - output);
PUTLONG(col_offsets, offs);
// write column posts
for (int p = 0; p < array_size(columns[c].posts); p++)
{
// Write row offset
PUTBYTE(rover, columns[c].posts[p].row_off);
// Write number of pixels
int numpixels = array_size(columns[c].posts[p].pixels);
PUTBYTE(rover, numpixels);
// Write pad byte
byte lastval = numpixels ? columns[c].posts[p].pixels[0] : 0;
PUTBYTE(rover, lastval);
// Write pixels
for (int a = 0; a < numpixels; a++)
{
lastval = columns[c].posts[p].pixels[a];
PUTBYTE(rover, lastval);
}
// Write pad byte
PUTBYTE(rover, lastval);
array_free(columns[c].posts[p].pixels);
}
// Write 255 cap byte
PUTBYTE(rover, 0xff);
array_free(columns[c].posts);
}
array_free(columns);
// Done!
return (patch_t *)output;
}
patch_t *V_LinearToPatch(byte *data, int width, int height, int tag,
void **user)
{
size_t size = 0;
size += 4 * sizeof(int16_t); // 4 header shorts
size += width * sizeof(int32_t); // offsets table
size += width * (height + sizeof(column_t) + 3); // 2 pad bytes and cap
byte *output = Z_Malloc(size, tag, user);
byte *rover = output;
// write header fields
PUTSHORT(rover, width);
PUTSHORT(rover, height);
// This is written to afterwards
PUTSHORT(rover, 0);
PUTSHORT(rover, 0);
// set starting position of column offsets table, and skip over it
byte *col_offsets = rover;
rover += width * sizeof(int32_t);
for (int x = 0; x < width; ++x)
{
// write column offset to offset table
PUTLONG(col_offsets, rover - output);
// column_t topdelta
PUTBYTE(rover, 0);
// column_t length
PUTBYTE(rover, height);
// pad byte
++rover;
byte *src = data + x;
for (int y = 0; y < height; ++y)
{
PUTBYTE(rover, *src);
src += width;
}
// pad byte
++rover;
// Write 255 cap byte
PUTBYTE(rover, 0xff);
}
return (patch_t *)output;
}
static patch_t *DummyPatch(int lump, pu_tag tag)
{
int num = (W_CheckNumForName)("TNT1A0", ns_sprites);
int len = W_LumpLength(num);
patch_t *dummy = V_CachePatchNum(num, PU_CACHE);
Z_Malloc(len, tag, &lumpcache[lump]);
memcpy(lumpcache[lump], dummy, len);
return lumpcache[lump];
}
static void *DummyFlat(int lump, pu_tag tag)
{
const int size = 64 * 64;
Z_Malloc(size, tag, &lumpcache[lump]);
memset(lumpcache[lump], v_darkest_color, size);
return lumpcache[lump];
}
// Set memory usage limits for storing standard and unknown chunks,
// this is important when reading untrusted files!
#define PNG_MEM_LIMIT (1024 * 1024 * 64)
patch_t *V_CachePatchNum(int lump, pu_tag tag)
{
if (lump >= numlumps)
{
I_Error("V_CachePatchNum: %d >= numlumps", lump);
}
if (lumpcache[lump])
{
Z_ChangeTag(lumpcache[lump], tag);
return lumpcache[lump];
}
void *buffer = W_CacheLumpNum(lump, tag);
int buffer_length = W_LumpLength(lump);
if (buffer_length < 8 || memcmp(buffer, "\211PNG\r\n\032\n", 8))
{
return buffer;
}
spng_ctx *ctx = spng_ctx_new(0);
// Ignore and don't calculate chunk CRC's
spng_set_crc_action(ctx, SPNG_CRC_USE, SPNG_CRC_USE);
spng_set_chunk_limits(ctx, PNG_MEM_LIMIT, PNG_MEM_LIMIT);
spng_set_option(ctx, SPNG_KEEP_UNKNOWN_CHUNKS, 1);
spng_set_png_buffer(ctx, buffer, buffer_length);
struct spng_ihdr ihdr = {0};
int ret = spng_get_ihdr(ctx, &ihdr);
if (ret)
{
I_Printf(VB_ERROR, "V_CachePatchNum: spng_get_ihdr %s\n",
spng_strerror(ret));
goto error;
}
if (ihdr.color_type != SPNG_COLOR_TYPE_INDEXED || ihdr.bit_depth != 8)
{
I_Printf(VB_ERROR, "V_CachePatchNum: Only 8-bit paletted PNG supported");
goto error;
}
int color_key = NO_COLOR_KEY;
struct spng_trns trns = {0};
ret = spng_get_trns(ctx, &trns);
if (ret && ret != SPNG_ECHUNKAVAIL)
{
I_Printf(VB_ERROR, "V_CachePatchNum: spng_get_trns %s",
spng_strerror(ret));
goto error;
}
for (int i = 0; i < trns.n_type3_entries; ++i)
{
if (trns.type3_alpha[i] < 255)
{
color_key = i;
break;
}
}
int leftoffset = 0, topoffset = 0;
uint32_t n_chunks = 0;
ret = spng_get_unknown_chunks(ctx, NULL, &n_chunks);
if (ret && ret != SPNG_ECHUNKAVAIL)
{
I_Printf(VB_ERROR, "V_CachePatchNum: spng_get_unknown_chunks %s",
spng_strerror(ret));
goto error;
}
if (n_chunks > 0)
{
struct spng_unknown_chunk *chunks = malloc(n_chunks * sizeof(*chunks));
spng_get_unknown_chunks(ctx, chunks, &n_chunks);
for (int i = 0; i < n_chunks; ++i)
{
if (!memcmp(chunks[i].type, "grAb", 4) && chunks[i].length == 8)
{
int *p = chunks[i].data;
leftoffset = SWAP_BE32(p[0]);
topoffset = SWAP_BE32(p[1]);
break;
}
}
free(chunks);
}
size_t image_size = 0;
ret = spng_decoded_image_size(ctx, SPNG_FMT_PNG, &image_size);
if (ret)
{
I_Printf(VB_ERROR, "V_CachePatchNum: spng_decoded_image_size %s",
spng_strerror(ret));
goto error;
}
byte *image = malloc(image_size);
ret = spng_decode_image(ctx, image, image_size, SPNG_FMT_PNG, 0);
if (ret)
{
I_Printf(VB_ERROR, "V_CachePatchNum: spng_decode_image %s",
spng_strerror(ret));
free(image);
goto error;
}
spng_ctx_free(ctx);
Z_Free(buffer);
patch_t *patch;
if (color_key == NO_COLOR_KEY)
{
patch = V_LinearToPatch(image, ihdr.width, ihdr.height, tag,
&lumpcache[lump]);
}
else
{
patch = V_LinearToTransPatch(image, ihdr.width, ihdr.height, color_key,
tag, &lumpcache[lump]);
}
patch->leftoffset = leftoffset;
patch->topoffset = topoffset;
free(image);
return lumpcache[lump];
error:
spng_ctx_free(ctx);
Z_Free(buffer);
return DummyPatch(lump, tag);
}
void *V_CacheFlatNum(int lump, pu_tag tag)
{
if (lump >= numlumps)
{
I_Error("V_CacheFlatNum: %d >= numlumps", lump);
}
if (lumpcache[lump])
{
Z_ChangeTag(lumpcache[lump], tag);
return lumpcache[lump];
}
void *buffer = W_CacheLumpNum(lump, tag);
int buffer_length = W_LumpLength(lump);
if (buffer_length < 8 || memcmp(buffer, "\211PNG\r\n\032\n", 8))
{
return buffer;
}
spng_ctx *ctx = spng_ctx_new(0);
// Ignore and don't calculate chunk CRC's
spng_set_crc_action(ctx, SPNG_CRC_USE, SPNG_CRC_USE);
spng_set_chunk_limits(ctx, PNG_MEM_LIMIT, PNG_MEM_LIMIT);
spng_set_png_buffer(ctx, buffer, buffer_length);
struct spng_ihdr ihdr = {0};
int ret = spng_get_ihdr(ctx, &ihdr);
if (ret)
{
I_Printf(VB_ERROR, "V_CacheFlatNum: spng_get_ihdr %s",
spng_strerror(ret));
goto error;
}
if (ihdr.color_type != SPNG_COLOR_TYPE_INDEXED || ihdr.bit_depth != 8)
{
I_Printf(VB_ERROR, "V_CacheFlatNum: Only 8-bit paletted PNG supported");
goto error;
}
size_t image_size = 0;
ret = spng_decoded_image_size(ctx, SPNG_FMT_PNG, &image_size);
if (ret)
{
I_Printf(VB_ERROR, "V_CacheFlatNum: spng_decoded_image_size %s",
spng_strerror(ret));
goto error;
}
void *image = malloc(image_size);
ret = spng_decode_image(ctx, image, image_size, SPNG_FMT_PNG, 0);
if (ret)
{
I_Printf(VB_ERROR, "V_CacheFlatNum: spng_decode_image %s",
spng_strerror(ret));
free(image);
goto error;
}
spng_ctx_free(ctx);
Z_Free(buffer);
Z_Malloc(image_size, tag, &lumpcache[lump]);
memcpy(lumpcache[lump], image, image_size);
free(image);
return lumpcache[lump];
error:
spng_ctx_free(ctx);
Z_Free(buffer);
return DummyFlat(lump, tag);
}

33
src/v_fmt.h Normal file
View File

@ -0,0 +1,33 @@
//
// SLADE - It's a Doom Editor
// Copyright(C) 2008 - 2019 Simon Judd
// Copyright(C) 2024 Roman Fomin
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
#include "doomtype.h"
#include "z_zone.h"
#include "w_wad.h"
struct patch_s *V_LinearToTransPatch(const byte *data, int width, int height,
int color_key, pu_tag tag, void **user);
struct patch_s *V_LinearToPatch(byte *data, int width, int height, int tag,
void **user);
struct patch_s *V_CachePatchNum(int lump, pu_tag tag);
inline static struct patch_s *V_CachePatchName(const char *name, pu_tag tag)
{
return V_CachePatchNum(W_GetNumForName(name), tag);
}
void *V_CacheFlatNum(int lump, pu_tag tag);

View File

@ -40,6 +40,7 @@
#include "r_state.h"
#include "s_sound.h"
#include "sounds.h"
#include "v_fmt.h"
#include "v_trans.h"
#include "v_video.h"
#include "w_wad.h" // needed for color translation lump lookup
@ -998,7 +999,7 @@ void V_ShadeScreen(void)
void V_DrawBackground(const char *patchname)
{
const byte *src =
W_CacheLumpNum(firstflat + R_FlatNumForName(patchname), PU_CACHE);
V_CacheFlatNum(firstflat + R_FlatNumForName(patchname), PU_CACHE);
V_TileBlock64(0, video.unscaledw, SCREENHEIGHT, src);
}
@ -1065,217 +1066,6 @@ void V_RestoreBuffer(void)
dest_screen = I_VideoBuffer;
}
typedef struct
{
byte row_off;
byte *pixels;
} vpost_t;
typedef struct
{
vpost_t *posts;
} vcolumn_t;
#define M_ARRAY_INIT_CAPACITY 16
#include "m_array.h"
#define PUTBYTE(r, v) \
*r = (uint8_t)(v); \
++r
#define PUTSHORT(r, v) \
*(r + 0) = (byte)(((uint16_t)(v) >> 0) & 0xff); \
*(r + 1) = (byte)(((uint16_t)(v) >> 8) & 0xff); \
r += 2
#define PUTLONG(r, v) \
*(r + 0) = (byte)(((uint32_t)(v) >> 0) & 0xff); \
*(r + 1) = (byte)(((uint32_t)(v) >> 8) & 0xff); \
*(r + 2) = (byte)(((uint32_t)(v) >> 16) & 0xff); \
*(r + 3) = (byte)(((uint32_t)(v) >> 24) & 0xff); \
r += 4
//
// Converts a linear graphic to a patch with transparency. Mostly straight
// from psxwadgen, which is mostly straight from SLADE.
//
patch_t *V_LinearToTransPatch(const byte *data, int width, int height,
int color_key)
{
vcolumn_t *columns = NULL;
// Go through columns
uint32_t offset = 0;
for (int c = 0; c < width; c++)
{
vcolumn_t col = {0};
vpost_t post = {0};
post.row_off = 0;
boolean ispost = false;
boolean first_254 = true; // first 254 pixels use absolute offsets
offset = c;
byte row_off = 0;
for (int r = 0; r < height; r++)
{
// if we're at offset 254, create a dummy post for tall doom gfx
// support
if (row_off == 254)
{
// Finish current post if any
if (ispost)
{
array_push(col.posts, post);
post.pixels = NULL;
ispost = false;
}
// Begin relative offsets
first_254 = false;
// Create dummy post
post.row_off = 254;
array_push(col.posts, post);
// Clear post
row_off = 0;
ispost = false;
}
// If the current pixel is not transparent, add it to the current
// post
if (data[offset] != color_key)
{
// If we're not currently building a post, begin one and set its
// offset
if (!ispost)
{
// Set offset
post.row_off = row_off;
// Reset offset if we're in relative offsets mode
if (!first_254)
{
row_off = 0;
}
// Start post
ispost = true;
}
// Add the pixel to the post
array_push(post.pixels, data[offset]);
}
else if (ispost)
{
// If the current pixel is transparent and we are currently
// building a post, add the current post to the list and clear
// it
array_push(col.posts, post);
post.pixels = NULL;
ispost = false;
}
// Go to next row
offset += width;
++row_off;
}
// If the column ended with a post, add it
if (ispost)
{
array_push(col.posts, post);
}
// Add the column data
array_push(columns, col);
// Go to next column
++offset;
}
size_t size = 0;
// Calculate needed memory size to allocate patch buffer
size += 4 * sizeof(int16_t); // 4 header shorts
size += array_size(columns) * sizeof(int32_t); // offsets table
for (int c = 0; c < array_size(columns); c++)
{
for (int p = 0; p < array_size(columns[c].posts); p++)
{
size_t post_len = 0;
post_len += 2; // two bytes for post header
post_len += 1; // dummy byte
post_len += array_size(columns[c].posts[p].pixels); // pixels
post_len += 1; // dummy byte
size += post_len;
}
size += 1; // room for 0xff cap byte
}
byte *output = malloc(size);
byte *rover = output;
// write header fields
PUTSHORT(rover, width);
PUTSHORT(rover, height);
// This is written to afterwards
PUTSHORT(rover, 0);
PUTSHORT(rover, 0);
// set starting position of column offsets table, and skip over it
byte *col_offsets = rover;
rover += array_size(columns) * 4;
for (int c = 0; c < array_size(columns); c++)
{
// write column offset to offset table
uint32_t offs = (uint32_t)(rover - output);
PUTLONG(col_offsets, offs);
// write column posts
for (int p = 0; p < array_size(columns[c].posts); p++)
{
// Write row offset
PUTBYTE(rover, columns[c].posts[p].row_off);
// Write number of pixels
int numpixels = array_size(columns[c].posts[p].pixels);
PUTBYTE(rover, numpixels);
// Write pad byte
byte lastval = numpixels ? columns[c].posts[p].pixels[0] : 0;
PUTBYTE(rover, lastval);
// Write pixels
for (int a = 0; a < numpixels; a++)
{
lastval = columns[c].posts[p].pixels[a];
PUTBYTE(rover, lastval);
}
// Write pad byte
PUTBYTE(rover, lastval);
array_free(columns[c].posts[p].pixels);
}
// Write 255 cap byte
PUTBYTE(rover, 0xff);
array_free(columns[c].posts);
}
array_free(columns);
// Done!
return (patch_t *)output;
}
//
// V_ScreenShot
//

View File

@ -180,9 +180,6 @@ void V_DrawBackground(const char *patchname);
int V_BloodColor(int blood);
struct patch_s *V_LinearToTransPatch(const byte *data, int width, int height,
int color_key);
void V_ScreenShot(void);
#endif

View File

@ -40,7 +40,7 @@
// Location of each lump on disk.
lumpinfo_t *lumpinfo = NULL;
int numlumps; // killough
static void **lumpcache; // killough
void **lumpcache; // killough
const char **wadfiles;

View File

@ -108,6 +108,7 @@ extern const lumpinfo_t predefined_lumps[];
extern lumpinfo_t *lumpinfo;
extern int numlumps;
extern void **lumpcache;
extern const char **wadfiles;

View File

@ -39,6 +39,7 @@
#include "st_lib.h"
#include "sounds.h"
#include "u_mapinfo.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "wi_stuff.h"
@ -409,7 +410,7 @@ void WI_slamBackground(void)
else
M_snprintf(name, sizeof(name), "WIMAP%d", wbs->epsd);
V_DrawPatchFullScreen(W_CacheLumpName(name, PU_CACHE));
V_DrawPatchFullScreen(V_CachePatchName(name, PU_CACHE));
}
// ====================================================================
@ -457,7 +458,7 @@ static void WI_drawLF(void)
}
else if (wbs->lastmapinfo && wbs->lastmapinfo->levelpic[0])
{
patch_t* lpic = W_CacheLumpName(wbs->lastmapinfo->levelpic, PU_CACHE);
patch_t* lpic = V_CachePatchName(wbs->lastmapinfo->levelpic, PU_CACHE);
V_DrawPatch((SCREENWIDTH - SHORT(lpic->width))/2,
y, lpic);
@ -511,7 +512,7 @@ static void WI_drawEL(void)
}
else if (wbs->nextmapinfo && wbs->nextmapinfo->levelpic[0])
{
patch_t* lpic = W_CacheLumpName(wbs->nextmapinfo->levelpic, PU_CACHE);
patch_t* lpic = V_CachePatchName(wbs->nextmapinfo->levelpic, PU_CACHE);
y += (5 * SHORT(lpic->height)) / 4;
@ -1976,7 +1977,7 @@ void WI_loadData(void)
M_snprintf(name, sizeof(name), "CWILV%2.2d", i);
if (W_CheckNumForName(name) != -1)
{
lnames[i] = W_CacheLumpName(name, PU_STATIC);
lnames[i] = V_CachePatchName(name, PU_STATIC);
}
else
{
@ -1993,7 +1994,7 @@ void WI_loadData(void)
M_snprintf(name, sizeof(name), "WILV%d%d", wbs->epsd, i);
if (W_CheckNumForName(name) != -1)
{
lnames[i] = W_CacheLumpName(name, PU_STATIC);
lnames[i] = V_CachePatchName(name, PU_STATIC);
}
else
{
@ -2002,13 +2003,13 @@ void WI_loadData(void)
}
// you are here
yah[0] = W_CacheLumpName("WIURH0", PU_STATIC);
yah[0] = V_CachePatchName("WIURH0", PU_STATIC);
// you are here (alt.)
yah[1] = W_CacheLumpName("WIURH1", PU_STATIC);
yah[1] = V_CachePatchName("WIURH1", PU_STATIC);
// splat
splat[0] = W_CacheLumpName("WISPLAT", PU_STATIC);
splat[0] = V_CachePatchName("WISPLAT", PU_STATIC);
if (wbs->epsd < 3)
{
@ -2022,7 +2023,7 @@ void WI_loadData(void)
{
// animations
M_snprintf(name, sizeof(name), "WIA%d%.2d%.2d", wbs->epsd, j, i);
a->p[i] = W_CacheLumpName(name, PU_STATIC);
a->p[i] = V_CachePatchName(name, PU_STATIC);
}
else
{
@ -2037,32 +2038,32 @@ void WI_loadData(void)
// More hacks on minus sign.
// [FG] allow playing with the Doom v1.2 IWAD which is missing the WIMINUS lump
if (W_CheckNumForName("WIMINUS") >= 0)
wiminus = W_CacheLumpName("WIMINUS", PU_STATIC);
wiminus = V_CachePatchName("WIMINUS", PU_STATIC);
for (i=0;i<10;i++)
{
// numbers 0-9
M_snprintf(name, sizeof(name), "WINUM%d", i);
num[i] = W_CacheLumpName(name, PU_STATIC);
num[i] = V_CachePatchName(name, PU_STATIC);
}
// percent sign
percent = W_CacheLumpName("WIPCNT", PU_STATIC);
percent = V_CachePatchName("WIPCNT", PU_STATIC);
// "finished"
finished = W_CacheLumpName("WIF", PU_STATIC);
finished = V_CachePatchName("WIF", PU_STATIC);
// "entering"
entering = W_CacheLumpName("WIENTER", PU_STATIC);
entering = V_CachePatchName("WIENTER", PU_STATIC);
// "kills"
kills = W_CacheLumpName("WIOSTK", PU_STATIC);
kills = V_CachePatchName("WIOSTK", PU_STATIC);
// "scrt"
secret = W_CacheLumpName("WIOSTS", PU_STATIC);
secret = V_CachePatchName("WIOSTS", PU_STATIC);
// "secret"
sp_secret = W_CacheLumpName("WISCRT2", PU_STATIC);
sp_secret = V_CachePatchName("WISCRT2", PU_STATIC);
// Yuck. // Ty 03/27/98 - got that right :)
// french is an enum=1 always true.
@ -2075,47 +2076,47 @@ void WI_loadData(void)
// items = W_CacheLumpName("WIOSTI", PU_STATIC);
// } else
items = W_CacheLumpName("WIOSTI", PU_STATIC);
items = V_CachePatchName("WIOSTI", PU_STATIC);
// "frgs"
frags = W_CacheLumpName("WIFRGS", PU_STATIC);
frags = V_CachePatchName("WIFRGS", PU_STATIC);
// ":"
colon = W_CacheLumpName("WICOLON", PU_STATIC);
colon = V_CachePatchName("WICOLON", PU_STATIC);
// "time"
witime = W_CacheLumpName("WITIME", PU_STATIC);
witime = V_CachePatchName("WITIME", PU_STATIC);
// "sucks"
sucks = W_CacheLumpName("WISUCKS", PU_STATIC);
sucks = V_CachePatchName("WISUCKS", PU_STATIC);
// "par"
par = W_CacheLumpName("WIPAR", PU_STATIC);
par = V_CachePatchName("WIPAR", PU_STATIC);
// "killers" (vertical)
killers = W_CacheLumpName("WIKILRS", PU_STATIC);
killers = V_CachePatchName("WIKILRS", PU_STATIC);
// "victims" (horiz)
victims = W_CacheLumpName("WIVCTMS", PU_STATIC);
victims = V_CachePatchName("WIVCTMS", PU_STATIC);
// "total"
total = W_CacheLumpName("WIMSTT", PU_STATIC);
total = V_CachePatchName("WIMSTT", PU_STATIC);
// your face
star = W_CacheLumpName("STFST01", PU_STATIC);
star = V_CachePatchName("STFST01", PU_STATIC);
// dead face
bstar = W_CacheLumpName("STFDEAD0", PU_STATIC);
bstar = V_CachePatchName("STFDEAD0", PU_STATIC);
for (i=0 ; i<MAXPLAYERS ; i++)
{
// "1,2,3,4"
M_snprintf(name, sizeof(name), "STPB%d", i);
p[i] = W_CacheLumpName(name, PU_STATIC);
p[i] = V_CachePatchName(name, PU_STATIC);
// "1,2,3,4"
M_snprintf(name, sizeof(name), "WIBP%d", i + 1);
bp[i] = W_CacheLumpName(name, PU_STATIC);
bp[i] = V_CachePatchName(name, PU_STATIC);
}
}