cin: move image load to separate file

This commit is contained in:
Denis Pauk 2024-06-20 00:41:34 +03:00
parent d4eefa247c
commit 9f84e40ab7
7 changed files with 217 additions and 126 deletions

View file

@ -1003,6 +1003,7 @@ CLIENT_OBJS_ := \
src/client/sound/sdl.o \
src/client/sound/sound.o \
src/client/sound/wave.o \
src/client/vid/image.o \
src/client/vid/vid.o \
src/common/argproc.o \
src/common/clientserver.o \

View file

@ -37,20 +37,6 @@
#define PL_MPEG_IMPLEMENTATION
#include "cinema/pl_mpeg.h"
// don't need HDR stuff
#define STBI_NO_LINEAR
#define STBI_NO_HDR
// make sure STB_image uses standard malloc(), as we'll use standard free() to deallocate
#define STBI_MALLOC(sz) malloc(sz)
#define STBI_REALLOC(p,sz) realloc(p,sz)
#define STBI_FREE(p) free(p)
// Switch of the thread local stuff. Breaks mingw under Windows.
#define STBI_NO_THREAD_LOCALS
// include implementation part of stb_image into this file
#define STB_IMAGE_IMPLEMENTATION
#include "refresh/files/stb_image.h"
extern cvar_t *vid_renderer;
cvar_t *cin_force43;
@ -111,102 +97,33 @@ typedef struct
cinematics_t cin;
static void
SCR_LoadPCX(char *filename, byte **pic, byte **palette, int *width, int *height)
SCR_LoadPCX(char *filename, byte **pic, byte **palette, int *width, int *height,
int *bytesPerPixel)
{
byte *raw;
pcx_t *pcx;
int x, y;
int len, full_size;
int dataByte, runLength;
byte *out, *pix;
byte *data, *palette_in;
*pic = NULL;
*palette = NULL;
/* load the file */
len = FS_LoadFile(filename, (void **)&raw);
VID_ImageDecode(filename, &data, &palette_in, width, height, bytesPerPixel);
if (!raw || len < sizeof(pcx_t))
if (data)
{
return;
*pic = Z_Malloc((*width) * (*height) * (*bytesPerPixel));
memcpy(*pic, data, (*height) * (*width) * (*bytesPerPixel));
free(data);
}
/* parse the PCX file */
pcx = (pcx_t *)raw;
raw = &pcx->data;
if ((pcx->manufacturer != 0x0a) ||
(pcx->version != 5) ||
(pcx->encoding != 1) ||
(pcx->bits_per_pixel != 8) ||
(pcx->xmax >= 640) ||
(pcx->ymax >= 480))
else
{
Com_Printf("Bad pcx file %s\n", filename);
return;
}
full_size = (pcx->ymax + 1) * (pcx->xmax + 1);
out = Z_Malloc(full_size);
*pic = out;
pix = out;
if (palette)
if (palette_in)
{
*palette = Z_Malloc(768);
memcpy(*palette, (byte *)pcx + len - 768, 768);
memcpy(*palette, palette_in, 768);
free(palette_in);
}
if (width)
{
*width = pcx->xmax + 1;
}
if (height)
{
*height = pcx->ymax + 1;
}
for (y = 0; y <= pcx->ymax; y++, pix += pcx->xmax + 1)
{
for (x = 0; x <= pcx->xmax; )
{
dataByte = *raw++;
if ((dataByte & 0xC0) == 0xC0)
{
runLength = dataByte & 0x3F;
dataByte = *raw++;
}
else
{
runLength = 1;
}
while (runLength-- > 0)
{
if ((*pic + full_size) <= (pix + x))
{
x += runLength;
runLength = 0;
}
else
{
pix[x++] = dataByte;
}
}
}
}
if (raw - (byte *)pcx > len)
{
Com_Printf("PCX file %s was malformed", filename);
Z_Free(*pic);
*pic = NULL;
}
FS_FreeFile(pcx);
}
void
@ -863,29 +780,25 @@ SCR_DrawCinematic(void)
static byte *
SCR_LoadHiColor(const char* namewe, const char *ext, int *width, int *height)
{
byte *pic, *data = NULL, *palette = NULL;
char filename[256];
int bytesPerPixel;
byte *pic, *data = NULL;
void *rawdata;
size_t len;
Q_strlcpy(filename, namewe, sizeof(filename));
Q_strlcat(filename, ".", sizeof(filename));
Q_strlcat(filename, ext, sizeof(filename));
len = FS_LoadFile(filename, &rawdata);
if (!rawdata || len <=0)
VID_ImageDecode(filename, &data, &palette,
width, height, &bytesPerPixel);
if (data == NULL)
{
return NULL;
}
data = stbi_load_from_memory(rawdata, len, width, height,
&bytesPerPixel, STBI_rgb_alpha);
if (data == NULL)
if (palette)
{
FS_FreeFile(rawdata);
return NULL;
/* strange, here should be no palleted image */
free(palette);
}
pic = Z_Malloc(cin.height * cin.width * 4);
@ -946,8 +859,11 @@ SCR_PlayCinematic(char *arg)
if (!cin.pic)
{
SCR_LoadPCX(name, &cin.pic, &palette, &cin.width, &cin.height);
cin.color_bits = 8;
int bytesPerPixel;
SCR_LoadPCX(name, &cin.pic, &palette, &cin.width, &cin.height,
&bytesPerPixel);
cin.color_bits = 8 * bytesPerPixel;
}
cl.cinematicframe = -1;

View file

@ -508,6 +508,8 @@ void V_AddEntity (entity_t *ent);
void V_AddParticle (vec3_t org, unsigned int color, float alpha);
void V_AddLight (vec3_t org, float intensity, float r, float g, float b);
void V_AddLightStyle (int style, float r, float g, float b);
void VID_ImageDecode(const char *filename, byte **pic, byte **palette,
int *width, int *height, int *bytesPerPixel);
void CL_RegisterTEntSounds (void);
void CL_RegisterTEntModels (void);

View file

@ -89,7 +89,8 @@ LoadSTB(const char *origname, const char* type, byte **pic, int *width, int *hei
data = stbi_load_from_memory(rawdata, rawsize, &w, &h, &bytesPerPixel, STBI_rgb_alpha);
if (data == NULL)
{
R_Printf(PRINT_ALL, "%s couldn't load data from %s: %s!\n", __func__, filename, stbi_failure_reason());
R_Printf(PRINT_ALL, "%s couldn't load data from %s: %s!\n",
__func__, filename, stbi_failure_reason());
ri.FS_FreeFile(rawdata);
return false;
}

View file

@ -220,27 +220,27 @@ R_DrawSpriteModel(entity_t *currententity, const model_t *currentmodel)
1, 1
};
VectorMA( currententity->origin, -frame->origin_y, up, point[0] );
VectorMA( point[0], -frame->origin_x, right, point[0] );
VectorMA(currententity->origin, -frame->origin_y, up, point[0]);
VectorMA(point[0], -frame->origin_x, right, point[0]);
VectorMA( currententity->origin, frame->height - frame->origin_y, up, point[1] );
VectorMA( point[1], -frame->origin_x, right, point[1] );
VectorMA(currententity->origin, frame->height - frame->origin_y, up, point[1]);
VectorMA(point[1], -frame->origin_x, right, point[1]);
VectorMA( currententity->origin, frame->height - frame->origin_y, up, point[2] );
VectorMA( point[2], frame->width - frame->origin_x, right, point[2] );
VectorMA(currententity->origin, frame->height - frame->origin_y, up, point[2]);
VectorMA(point[2], frame->width - frame->origin_x, right, point[2]);
VectorMA( currententity->origin, -frame->origin_y, up, point[3] );
VectorMA( point[3], frame->width - frame->origin_x, right, point[3] );
VectorMA(currententity->origin, -frame->origin_y, up, point[3]);
VectorMA(point[3], frame->width - frame->origin_x, right, point[3]);
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer( 3, GL_FLOAT, 0, point );
glTexCoordPointer( 2, GL_FLOAT, 0, tex );
glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
glVertexPointer(3, GL_FLOAT, 0, point);
glTexCoordPointer(2, GL_FLOAT, 0, tex);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_ALPHA_TEST);
R_TexEnv(GL_REPLACE);

170
src/client/vid/image.c Normal file
View file

@ -0,0 +1,170 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Shared image decode logic
*
* =======================================================================
*/
#include "../../client/header/client.h"
#define PCX_IDENT ((0x08 << 24) + (0x01 << 16) + (0x05 << 8) + 0x0a)
// don't need HDR stuff
#define STBI_NO_LINEAR
#define STBI_NO_HDR
// make sure STB_image uses standard malloc(), as we'll use standard free() to deallocate
#define STBI_MALLOC(sz) malloc(sz)
#define STBI_REALLOC(p,sz) realloc(p,sz)
#define STBI_FREE(p) free(p)
// Switch of the thread local stuff. Breaks mingw under Windows.
#define STBI_NO_THREAD_LOCALS
// include implementation part of stb_image into this file
#define STB_IMAGE_IMPLEMENTATION
#include "../refresh/files/stb_image.h"
static void
PCX_Decode(const byte *raw, int len, byte **pic, byte **palette,
int *width, int *height, int *bytesPerPixel)
{
pcx_t *pcx;
int x, y, full_size;
int dataByte, runLength;
byte *out, *pix;
*pic = NULL;
*bytesPerPixel = 1;
if (len < sizeof(pcx_t))
{
return;
}
/* parse the PCX file */
pcx = (pcx_t *)raw;
raw = &pcx->data;
if ((pcx->manufacturer != 0x0a) ||
(pcx->version != 5) ||
(pcx->encoding != 1) ||
(pcx->bits_per_pixel != 8))
{
return;
}
full_size = (pcx->ymax + 1) * (pcx->xmax + 1);
out = malloc(full_size);
*pic = out;
pix = out;
if (palette)
{
*palette = malloc(768);
memcpy(*palette, (byte *)pcx + len - 768, 768);
}
if (width)
{
*width = pcx->xmax + 1;
}
if (height)
{
*height = pcx->ymax + 1;
}
for (y = 0; y <= pcx->ymax; y++, pix += pcx->xmax + 1)
{
for (x = 0; x <= pcx->xmax; )
{
dataByte = *raw++;
if ((dataByte & 0xC0) == 0xC0)
{
runLength = dataByte & 0x3F;
dataByte = *raw++;
}
else
{
runLength = 1;
}
while (runLength-- > 0)
{
if ((*pic + full_size) <= (pix + x))
{
x += runLength;
runLength = 0;
}
else
{
pix[x++] = dataByte;
}
}
}
}
if (raw - (byte *)pcx > len)
{
free(*pic);
*pic = NULL;
}
}
void
VID_ImageDecode(const char *filename, byte **pic, byte **palette,
int *width, int *height, int *bytesPerPixel)
{
int len, ident;
byte *raw;
/* load the file */
len = FS_LoadFile(filename, (void **)&raw);
if (!raw || len <= 0)
{
return;
}
if (len <= sizeof(int))
{
FS_FreeFile(raw);
return;
}
ident = LittleLong(*((int*)raw));
if (ident == PCX_IDENT)
{
PCX_Decode(raw, len, pic, palette, width, height, bytesPerPixel);
}
else
{
/* other formats does not have palette directly */
*palette = NULL;
*pic = stbi_load_from_memory(raw, len, width, height,
bytesPerPixel, STBI_rgb_alpha);
}
FS_FreeFile(raw);
}

View file

@ -69,7 +69,8 @@ compress_for_stbiw(unsigned char *data, int data_len, int *out_len, int quality)
* RGB or RGBA. The pixels must be given row-wise, stating at the top
* left.
*/
void VID_WriteScreenshot(int width, int height, int comp, const void* data)
static void
VID_WriteScreenshot(int width, int height, int comp, const void* data)
{
char picname[80];
char checkname[MAX_OSPATH];