mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 11:28:56 +00:00
Merge pull request #325 from Arcnor/png-screenshot
Save screenshots as PNG
This commit is contained in:
commit
f793797088
@ -150,7 +150,7 @@ include_directories(
|
||||
${PLATFORM_INCLUDES}
|
||||
)
|
||||
|
||||
# file(GLOB_RECURSE INCS "*.h")
|
||||
add_subdirectory(third_party)
|
||||
|
||||
add_subdirectory(2dlib)
|
||||
add_subdirectory(AudioEncode)
|
||||
|
@ -694,6 +694,8 @@
|
||||
#include "osiris_share.h"
|
||||
#include "demofile.h"
|
||||
|
||||
#include <NewBitmap.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Variables
|
||||
|
||||
@ -1276,7 +1278,6 @@ void EndFrame() {
|
||||
|
||||
// Does a screenshot and tells the bitmap lib to save out the picture as a tga
|
||||
void DoScreenshot() {
|
||||
int bm_handle;
|
||||
int count;
|
||||
char str[255], filename[255];
|
||||
CFILE *infile;
|
||||
@ -1290,21 +1291,20 @@ void DoScreenshot() {
|
||||
height = rs.screen_height;
|
||||
}
|
||||
|
||||
bm_handle = bm_AllocBitmap(width, height, 0);
|
||||
if (bm_handle < 0) {
|
||||
StopTime();
|
||||
|
||||
// Tell our renderer lib to take a screen shot
|
||||
auto screenshot = rend_Screenshot();
|
||||
|
||||
if (!screenshot || screenshot->getData() == nullptr) {
|
||||
AddHUDMessage(TXT_ERRSCRNSHT);
|
||||
return;
|
||||
}
|
||||
|
||||
StopTime();
|
||||
|
||||
// Tell our renderer lib to take a screen shot
|
||||
rend_Screenshot(bm_handle);
|
||||
|
||||
// Find a valid filename
|
||||
count = 1;
|
||||
while (!done) {
|
||||
snprintf(str, sizeof(str), "Screenshot%.3d.tga", count);
|
||||
snprintf(str, sizeof(str), "Screenshot%.3d.png", count);
|
||||
ddio_MakePath(filename, Base_directory, str, NULL);
|
||||
infile = (CFILE *)cfopen(filename, "rb");
|
||||
if (infile == NULL) {
|
||||
@ -1318,16 +1318,12 @@ void DoScreenshot() {
|
||||
break;
|
||||
}
|
||||
|
||||
strcpy(GameBitmaps[bm_handle].name, str);
|
||||
|
||||
// Now save it
|
||||
bm_SaveBitmapTGA(filename, bm_handle);
|
||||
screenshot->saveAsPNG(filename);
|
||||
|
||||
if (Demo_flags != DF_PLAYBACK) {
|
||||
AddHUDMessage(TXT_SCRNSHT, filename);
|
||||
}
|
||||
|
||||
// Free memory
|
||||
bm_FreeBitmap(bm_handle);
|
||||
|
||||
StartTime();
|
||||
}
|
||||
|
@ -394,11 +394,6 @@ int FindTextureBitmapName(const char *name) {
|
||||
if ((!stricmp(GameBitmaps[vc->frames[t]].name, name)))
|
||||
retval = i;
|
||||
|
||||
/*if (not_res)
|
||||
{
|
||||
FreeVClipResidency (GameTextures[i].bm_handle);
|
||||
}*/
|
||||
|
||||
if (retval != -1)
|
||||
return retval;
|
||||
} else {
|
||||
|
@ -236,20 +236,6 @@ void FreeVClip(int num) {
|
||||
ASSERT(Num_vclips >= 0);
|
||||
}
|
||||
|
||||
// Frees up the bitmaps used by a vclip
|
||||
void FreeVClipResidency(int num) {
|
||||
ASSERT(GameVClips[num].used > 0);
|
||||
|
||||
mprintf((0, "Freeing vclip residency!\n"));
|
||||
|
||||
if (!(GameVClips[num].flags & VCF_NOT_RESIDENT)) {
|
||||
for (int i = 0; i < GameVClips[num].num_frames; i++)
|
||||
bm_FreeBitmap(GameVClips[num].frames[i]);
|
||||
}
|
||||
|
||||
GameVClips[num].flags |= VCF_NOT_RESIDENT;
|
||||
}
|
||||
|
||||
// Saves a given video clip to a file
|
||||
// Returns 1 if everything ok, 0 otherwise
|
||||
// "num" is index into GameVClip array
|
||||
@ -643,55 +629,3 @@ int FindVClipName(const char *name) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Returns frame "frame" of vclip "vclip". Will mod the frame so that there
|
||||
// is no overflow
|
||||
int GetVClipBitmap(int v, int frame) {
|
||||
ASSERT(GameVClips[v].used > 0);
|
||||
ASSERT(v >= 0 && v < MAX_VCLIPS);
|
||||
ASSERT(frame >= 0);
|
||||
|
||||
vclip *vc = &GameVClips[v];
|
||||
|
||||
int bm = vc->frames[frame % vc->num_frames];
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
||||
// Loads an animation from an IFF ANIM file
|
||||
int AllocLoadIFFAnimClip(const char *filename, int texture) {
|
||||
/* char name[PAGENAME_LEN];
|
||||
int i;
|
||||
|
||||
ASSERT (filename!=NULL);
|
||||
|
||||
ChangeVClipName (filename,name);
|
||||
|
||||
if ((i=FindVClipName(name))!=-1)
|
||||
{
|
||||
GameVClips[i].used++;
|
||||
return i;
|
||||
}
|
||||
|
||||
mprintf ((0,"Loading IFF vclip %s\n",name));
|
||||
|
||||
int vcnum=AllocVClip ();
|
||||
|
||||
ASSERT (vcnum>=0);
|
||||
|
||||
vclip *vc=&GameVClips[vcnum];
|
||||
|
||||
vc->num_frames=bm_AllocLoadIFFAnim (filename,vc->frames,0);
|
||||
if (vc->num_frames==-1)
|
||||
{
|
||||
mprintf ((0,"Couldn't load vclip named %d!\n",name));
|
||||
FreeVClip (vcnum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy (vc->name,name);
|
||||
|
||||
return vcnum;*/
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -77,17 +77,7 @@ void ChangeVClipName(const char *src, char *dest);
|
||||
// or index of vclip with name
|
||||
int FindVClipName(const char *name);
|
||||
|
||||
// Returns frame "frame" of vclip "vclip". Will mod the frame so that there
|
||||
// is no overflow
|
||||
int GetVClipBitmap(int vclip, int frame);
|
||||
|
||||
// Loads an animation from an IFF ANIM file
|
||||
int AllocLoadIFFAnimClip(const char *filename, int texture);
|
||||
|
||||
// Pages in a vclip if it needs to be
|
||||
void PageInVClip(int vcnum);
|
||||
|
||||
// Frees up the bitmaps used by a vclip
|
||||
void FreeVClipResidency(int vcnum);
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,8 @@
|
||||
set(HEADERS iff.h)
|
||||
set(CPPS
|
||||
NewBitmap.cpp
|
||||
NewBitmap.h
|
||||
|
||||
bitmain.cpp
|
||||
bumpmap.cpp
|
||||
iff.cpp
|
||||
@ -11,4 +14,6 @@ add_library(bitmap STATIC ${HEADERS} ${CPPS})
|
||||
target_link_libraries(bitmap PRIVATE
|
||||
cfile
|
||||
ddebug
|
||||
stb
|
||||
)
|
||||
target_include_directories(bitmap PUBLIC .)
|
||||
|
57
bitmap/NewBitmap.cpp
Normal file
57
bitmap/NewBitmap.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Descent Developers
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "NewBitmap.h"
|
||||
#include "pserror.h"
|
||||
|
||||
#include <stb_image_write.h>
|
||||
|
||||
NewBitmap::NewBitmap(uint32_t w, uint32_t h, PixelDataFormat format, bool flippedY)
|
||||
: _w(w), _h(h), _format(format), _flippedY(flippedY), _data(allocateData(w, h, format)) {
|
||||
ASSERT(_data.get());
|
||||
}
|
||||
|
||||
std::unique_ptr<uint8_t[]> NewBitmap::allocateData(uint32_t w, uint32_t h, PixelDataFormat format) {
|
||||
switch (format) {
|
||||
case PixelDataFormat::RGBA32: return std::make_unique<uint8_t[]>(w * h * 4);
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t NewBitmap::getNumComponents() const {
|
||||
switch (_format) {
|
||||
case PixelDataFormat::RGBA32: return 4;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t NewBitmap::getStride() const {
|
||||
switch (_format) {
|
||||
case PixelDataFormat::RGBA32: return _w * 4;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool NewBitmap::saveAsPNG(const char *filePath) {
|
||||
// TODO: Support more formats? stb_write supports at least RGB and RGBA
|
||||
ASSERT(_format == PixelDataFormat::RGBA32);
|
||||
|
||||
stbi_flip_vertically_on_write(_flippedY);
|
||||
return stbi_write_png(filePath, _w, _h, getNumComponents(), _data.get(), getStride()) == 0;
|
||||
}
|
60
bitmap/NewBitmap.h
Normal file
60
bitmap/NewBitmap.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Descent Developers
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DESCENT3_NEWBITMAP_H
|
||||
#define DESCENT3_NEWBITMAP_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
enum class PixelDataFormat {
|
||||
Unknown,
|
||||
RGBA32
|
||||
};
|
||||
|
||||
class NewBitmap {
|
||||
private:
|
||||
uint32_t _w, _h;
|
||||
PixelDataFormat _format;
|
||||
bool _flippedY;
|
||||
std::unique_ptr<uint8_t[]> _data;
|
||||
|
||||
static std::unique_ptr<uint8_t[]> allocateData(uint32_t w, uint32_t h, PixelDataFormat format);
|
||||
|
||||
[[nodiscard]] uint32_t getStride() const;
|
||||
|
||||
public:
|
||||
/// Creates a new bitmap of size "w * h" and the specified format. Will allocate enough memory to store it.
|
||||
NewBitmap(uint32_t w, uint32_t h, PixelDataFormat format, bool flippedY = false);
|
||||
|
||||
void getSize(uint32_t &w, uint32_t &h) const {
|
||||
w = _w;
|
||||
h = _h;
|
||||
}
|
||||
|
||||
/// @returns raw pointer to image data
|
||||
[[nodiscard]] uint8_t *getData() const { return _data.get(); }
|
||||
|
||||
/// @returns number of components for the bitmap format (i.e. 4 for "RGBA")
|
||||
[[nodiscard]] uint32_t getNumComponents() const;
|
||||
|
||||
/// @returns true on success, false otherwise
|
||||
bool saveAsPNG(const char* filePath);
|
||||
};
|
||||
|
||||
#endif // DESCENT3_NEWBITMAP_H
|
@ -586,18 +586,6 @@ int bm_FindBitmapName(const char *name) {
|
||||
return fnode->data - GameBitmaps;
|
||||
} else
|
||||
return -1;
|
||||
/*
|
||||
for (i=0;i<MAX_BITMAPS && num_counted<Num_of_bitmaps;i++)
|
||||
{
|
||||
if (GameBitmaps[i].used)
|
||||
{
|
||||
num_counted++;
|
||||
if(!stricmp (GameBitmaps[i].name,name))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
// Given a handle, frees the bitmap memory and flags this bitmap as unused
|
||||
void bm_FreeBitmap(int handle) {
|
||||
@ -876,97 +864,6 @@ int bm_AllocLoadFileBitmap(const char *fname, int mipped, int format) {
|
||||
// Allocs and loads a bitmap but doesn't actually load texel data!
|
||||
// Returns the handle of the loaded bitmap
|
||||
// Returns -1 if something is wrong
|
||||
/*
|
||||
int bm_AllocLoadFileNoMemBitmap (char *fname,int mipped)
|
||||
{
|
||||
CFILE *infile;
|
||||
if (!Bitmaps_initted)
|
||||
{
|
||||
Int3();
|
||||
mprintf ((0,"Bitmaps not initted!!!\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *filename,name[BITMAP_NAME_LEN];
|
||||
int n,src_bm;
|
||||
|
||||
filename = fname;
|
||||
|
||||
// due to a bug in some people's tablefile editors, we got to make sure there is
|
||||
// no path if there shouldn't be
|
||||
if(!cfexist(filename))
|
||||
{
|
||||
// generate a possible new filename
|
||||
char *end_ptr,*start_ptr;
|
||||
start_ptr = fname;
|
||||
end_ptr = start_ptr + strlen(start_ptr) - 1;
|
||||
while( (end_ptr >= start_ptr) && (*end_ptr!='\\') ) end_ptr--;
|
||||
if(end_ptr < start_ptr)
|
||||
{
|
||||
mprintf((0,"Unable to find bitmap %s\n",fname));
|
||||
return -1;
|
||||
}
|
||||
ASSERT(*end_ptr=='\\');
|
||||
end_ptr++;
|
||||
filename = end_ptr;
|
||||
mprintf((0,"Couldn't find %s, so gonna try %s\n",fname,filename));
|
||||
}
|
||||
|
||||
|
||||
// Check to see if this bitmap is already in memory, if so, just return that
|
||||
// bitmaps handle
|
||||
if ((n=bm_TestName(filename))!=-1)
|
||||
{
|
||||
GameBitmaps[n].used++;
|
||||
mprintf ((0,"Found duplicate bitmap %s.\n",GameBitmaps[n].name));
|
||||
return n;
|
||||
}
|
||||
|
||||
bm_ChangeEndName (filename,name);
|
||||
if (strlen(name)>33)
|
||||
{
|
||||
mprintf ((0,"ERROR!! This bitmaps name is too long, try shortening it and retry!\n"));
|
||||
return -1;
|
||||
}
|
||||
// Try to open the file. If we can't load it from the network if possible
|
||||
infile=(CFILE *)cfopen (filename,"rb");
|
||||
if( !infile)
|
||||
{
|
||||
mprintf ((0,"bm_AllocLoadFileBitmap: Can't open file named %s.\n",filename));
|
||||
|
||||
#ifdef _DEBUG
|
||||
return BAD_BITMAP_HANDLE; // return the bad texture
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
// Check to see if this is IFF. If so, call the IFF reader. If not,
|
||||
// rewind the file and read as a TGA
|
||||
|
||||
int filetype=bm_GetFileType (infile,filename);
|
||||
|
||||
switch (filetype)
|
||||
{
|
||||
case BM_FILETYPE_TGA:
|
||||
// reads a tga or an outrage graphics file (ogf)
|
||||
src_bm=bm_tga_load_short_file(infile,name);
|
||||
break;
|
||||
default:
|
||||
Int3(); // Can't read this type
|
||||
break;
|
||||
}
|
||||
cfclose (infile);
|
||||
if (src_bm<0)
|
||||
{
|
||||
mprintf ((0,"Couldn't load %s.",filename));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return src_bm; // We made it!
|
||||
}*/
|
||||
// Allocs and loads a bitmap but doesn't actually load texel data!
|
||||
// Returns the handle of the loaded bitmap
|
||||
// Returns -1 if something is wrong
|
||||
int bm_AllocLoadFileNoMemBitmap(const char *fname, int mipped, int format) {
|
||||
if (!Bitmaps_initted) {
|
||||
Int3();
|
||||
@ -1448,71 +1345,6 @@ void bm_ScaleBitmapToBitmap(int dest, int src) {
|
||||
}
|
||||
GameBitmaps[dest].flags |= BF_CHANGED;
|
||||
}
|
||||
// Returns whether or not this bitmap is in use
|
||||
int bm_used(int n) {
|
||||
ASSERT(n >= 0 && n < MAX_BITMAPS);
|
||||
return GameBitmaps[n].used;
|
||||
}
|
||||
// Loads a series of bitmaps from an IFF file
|
||||
int bm_AllocLoadIFFAnim(const char *filename, int *dest_index, int mipped) {
|
||||
char name[BITMAP_NAME_LEN];
|
||||
char str[BITMAP_NAME_LEN + 16];
|
||||
int num_bitmaps, i, src_bm, n;
|
||||
int bm_index[200];
|
||||
bm_ChangeEndName(filename, name);
|
||||
|
||||
num_bitmaps = bm_iff_read_animbrush(filename, bm_index);
|
||||
if (num_bitmaps < 0) {
|
||||
mprintf((0, "Couldn't load %s.", filename));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Allocate space for our bitmap. If its mipped it must mean its a texture,
|
||||
// so make it TEXTURE_WIDTH x TEXTURE_SIZE
|
||||
for (i = 0; i < num_bitmaps; i++) {
|
||||
src_bm = bm_index[i];
|
||||
ASSERT(GameBitmaps[src_bm].used);
|
||||
if (mipped) {
|
||||
if ((bm_mipped(src_bm)) == 0) // If we want a mipped but we don't have one
|
||||
{
|
||||
int w = bm_w(src_bm, 0);
|
||||
int h = bm_h(src_bm, 0);
|
||||
|
||||
n = bm_AllocBitmap(w, h, mipped * (((w * h * 2) / 3)));
|
||||
|
||||
ASSERT(n >= 0);
|
||||
bm_ScaleBitmapToBitmap(n, src_bm);
|
||||
bm_FreeBitmap(src_bm);
|
||||
|
||||
bm_GenerateMipMaps(n);
|
||||
} else
|
||||
n = src_bm;
|
||||
} else // If we don't want a mipped
|
||||
{
|
||||
if ((bm_mipped(src_bm)) == 0)
|
||||
n = src_bm;
|
||||
else // And this is already mipped
|
||||
{
|
||||
int w = bm_w(src_bm, 0);
|
||||
int h = bm_h(src_bm, 0);
|
||||
ushort *src_data, *dest_data;
|
||||
|
||||
n = bm_AllocBitmap(w, h, mipped * (((w * h * 2) / 3)));
|
||||
ASSERT(n >= 0);
|
||||
src_data = (ushort *)bm_data(src_bm, 0);
|
||||
dest_data = (ushort *)bm_data(n, 0);
|
||||
memcpy(dest_data, src_data, w * h * 2);
|
||||
|
||||
bm_FreeBitmap(src_bm);
|
||||
}
|
||||
}
|
||||
snprintf(str, sizeof(str), "%s%d", name, i);
|
||||
strcpy(GameBitmaps[n].name, str);
|
||||
dest_index[i] = n;
|
||||
bm_FreeBitmap(src_bm);
|
||||
}
|
||||
return num_bitmaps; // We made it!
|
||||
}
|
||||
// given a handle and a miplevel, returns the bytes per bitmap row
|
||||
int bm_rowsize(int handle, int miplevel) {
|
||||
int w;
|
||||
@ -1571,51 +1403,6 @@ int bm_SetBitmapIfTransparent(int handle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Saves the passed bitmap handle as a 32 bit uncompressed tga
|
||||
int bm_SaveBitmapTGA(const char *filename, int handle) {
|
||||
int height, width;
|
||||
int i, t;
|
||||
CFILE *fp;
|
||||
fp = (CFILE *)cfopen(filename, "wb");
|
||||
if (fp == NULL) {
|
||||
mprintf((0, "SaveTGA:couldn't open %s!\n", filename));
|
||||
return 0;
|
||||
}
|
||||
ASSERT(GameBitmaps[handle].format == BITMAP_FORMAT_1555); // Can only save 1555
|
||||
width = bm_w(handle, 0);
|
||||
height = bm_h(handle, 0);
|
||||
cf_WriteByte(fp, 0); // image_id_len
|
||||
cf_WriteByte(fp, 0); // color map type
|
||||
cf_WriteByte(fp, 2); // image type: 2= uncompressed tga
|
||||
|
||||
for (i = 0; i < 9; i++) // ingore next 9 bytes
|
||||
cf_WriteByte(fp, 0);
|
||||
|
||||
cf_WriteShort(fp, width);
|
||||
cf_WriteShort(fp, height);
|
||||
cf_WriteByte(fp, 32);
|
||||
cf_WriteByte(fp, 32 + 8);
|
||||
|
||||
// for (i=0;i<image_id_len;i++)
|
||||
// cf_ReadByte (infile);
|
||||
// upside_down=(descriptor & 0x20)>>5;
|
||||
// upside_down=1-upside_down;
|
||||
ushort *src_data = (ushort *)bm_data(handle, 0);
|
||||
for (i = 0; i < height; i++) {
|
||||
for (t = 0; t < width; t++) {
|
||||
ushort pix;
|
||||
ddgr_color color;
|
||||
pix = src_data[i * width + t];
|
||||
color = GR_16_TO_COLOR(pix);
|
||||
color |= 0xFF000000;
|
||||
|
||||
cf_WriteInt(fp, color);
|
||||
}
|
||||
}
|
||||
// Finis!
|
||||
cfclose(fp);
|
||||
return 1;
|
||||
}
|
||||
// clears bitmap
|
||||
void bm_ClearBitmap(int handle) {
|
||||
int dx, dy;
|
||||
|
19
lib/bitmap.h
19
lib/bitmap.h
@ -18,13 +18,17 @@
|
||||
|
||||
#ifndef PSBITMAP_H
|
||||
#define PSBITMAP_H
|
||||
|
||||
#include "pstypes.h"
|
||||
#include "cfile.h"
|
||||
|
||||
#ifdef __LINUX__
|
||||
#include "linux/linux_fix.h" //needed for stricmp's throughout bitmap lib
|
||||
#endif
|
||||
|
||||
#define MAX_BITMAPS 5000
|
||||
#define NUM_MIP_LEVELS 5
|
||||
|
||||
// It really doesn't matter what these are, as long as its above 10
|
||||
#define OUTRAGE_4444_COMPRESSED_MIPPED 121
|
||||
#define OUTRAGE_1555_COMPRESSED_MIPPED 122
|
||||
@ -35,6 +39,7 @@
|
||||
#define OUTRAGE_COMPRESSED_OGF 127
|
||||
#define BITMAP_NAME_LEN 35
|
||||
#define BAD_BITMAP_HANDLE 0
|
||||
|
||||
// Bitmap flags
|
||||
#define BF_TRANSPARENT 1
|
||||
#define BF_CHANGED 2 // this bitmap has changed since last frame (useful for hardware cacheing)
|
||||
@ -44,10 +49,12 @@
|
||||
#define BF_WANTS_4444 32 // Read data as 4444 when this bitmap is paged in
|
||||
#define BF_BRAND_NEW 64 // This bitmap was just allocated and hasn't been to the video card
|
||||
#define BF_COMPRESSABLE 128 // This bitmap is compressable for 3dhardware that supports it
|
||||
|
||||
// Bitmap priorities
|
||||
#define BITMAP_FORMAT_STANDARD 0
|
||||
#define BITMAP_FORMAT_1555 0
|
||||
#define BITMAP_FORMAT_4444 1
|
||||
|
||||
typedef struct {
|
||||
ushort *data16; // 16bit data
|
||||
ushort width, height; // Width and height in pixels
|
||||
@ -60,6 +67,7 @@ typedef struct {
|
||||
ubyte format; // See bitmap format types above
|
||||
char name[BITMAP_NAME_LEN]; // Whats the name of this bitmap? (ie SteelWall)
|
||||
} bms_bitmap;
|
||||
|
||||
typedef struct chunked_bitmap {
|
||||
int pw, ph; // pixel width and height
|
||||
int w, h; // width and height in square bitmaps.
|
||||
@ -67,7 +75,7 @@ typedef struct chunked_bitmap {
|
||||
} chunked_bitmap;
|
||||
extern bms_bitmap GameBitmaps[MAX_BITMAPS];
|
||||
extern ulong Bitmap_memory_used;
|
||||
extern ubyte Memory_map[];
|
||||
|
||||
// Sets all the bitmaps to unused
|
||||
void bm_InitBitmaps();
|
||||
// Frees up all memory used by bitmaps
|
||||
@ -119,18 +127,10 @@ int bm_bpp(int handle);
|
||||
void bm_GenerateMipMaps(int handle);
|
||||
// Given two bitmaps, scales the data from src to the size of dest
|
||||
void bm_ScaleBitmapToBitmap(int dest, int src);
|
||||
// Returns whether or not this bitmap is in use
|
||||
int bm_used(int n);
|
||||
// Loads a series of bitmaps from an IFF file
|
||||
int bm_AllocLoadIFFAnim(const char *filename, int *dest_index, int mipped);
|
||||
// given a handle and a miplevel, returns the bytes per bitmap row
|
||||
int bm_rowsize(int handle, int miplevel);
|
||||
// Goes through the bitmap and sees if there is any transparency...if so, flag it!
|
||||
int bm_SetBitmapIfTransparent(int handle);
|
||||
// Saves the passed bitmap handle as a 24 bit uncompressed tga
|
||||
int bm_SaveBitmapTGA(const char *filename, int handle);
|
||||
// Sets the bitmap priority. This comes in handy for our 3d hardware
|
||||
void bm_set_priority(int handle, int priority);
|
||||
// Allocs and loads a bitmap but doesn't actually load texel data!
|
||||
// Returns the handle of the loaded bitmap
|
||||
// Returns -1 if something is wrong
|
||||
@ -152,4 +152,5 @@ void bm_FreeBitmapData(int handle);
|
||||
int bm_format(int handle);
|
||||
// Returns the number of mipmap levels
|
||||
int bm_miplevels(int handle);
|
||||
|
||||
#endif
|
||||
|
@ -294,6 +294,7 @@
|
||||
#ifndef RENDERER_H
|
||||
#define RENDERER_H
|
||||
|
||||
#include <memory>
|
||||
#include "pstypes.h"
|
||||
#include "grdefs.h"
|
||||
|
||||
@ -350,6 +351,8 @@ extern bool UseMipmap; // DAJ
|
||||
extern bool ATIRagePro; // DAJ
|
||||
extern bool Formac; // DAJ
|
||||
|
||||
class NewBitmap;
|
||||
|
||||
// various state setting functions
|
||||
//------------------------------------
|
||||
|
||||
@ -578,6 +581,9 @@ float rend_GetAlphaFactor(void);
|
||||
// Sets the wrap parameter
|
||||
void rend_SetWrapType(wrap_type val);
|
||||
|
||||
/// Takes a screenshot of the current frame and returns a NewBitmap
|
||||
std::unique_ptr<NewBitmap> rend_Screenshot();
|
||||
|
||||
// Takes a screenshot of the current frame and puts it into the handle passed
|
||||
void rend_Screenshot(int bm_handle);
|
||||
|
||||
|
@ -24,3 +24,4 @@ endif()
|
||||
#Direct3D.cpp
|
||||
|
||||
add_library(renderer STATIC ${HEADERS} ${CPPS})
|
||||
target_link_libraries(renderer PRIVATE bitmap)
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include "HardwareInternal.h"
|
||||
#include "../Descent3/args.h"
|
||||
|
||||
#include <NewBitmap.h>
|
||||
|
||||
#define DECLARE_OPENGL
|
||||
#include "dyna_gl.h"
|
||||
|
||||
@ -2142,28 +2144,38 @@ void rend_DrawSpecialLine(g3Point *p0, g3Point *p1) {
|
||||
}
|
||||
|
||||
// Takes a screenshot of the current frame and puts it into the handle passed
|
||||
void rend_Screenshot(int bm_handle) {
|
||||
std::unique_ptr<NewBitmap> rend_Screenshot() {
|
||||
ushort *dest_data;
|
||||
uint *temp_data;
|
||||
int i, t;
|
||||
|
||||
int total = gpu_state.screen_width * gpu_state.screen_height;
|
||||
auto result = std::make_unique<NewBitmap>(gpu_state.screen_width, gpu_state.screen_height, PixelDataFormat::RGBA32, true);
|
||||
|
||||
if (!result || result->getData() == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dglReadPixels(0, 0, gpu_state.screen_width, gpu_state.screen_height, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
(GLvoid *)result->getData());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Takes a screenshot of the current frame and puts it into the handle passed
|
||||
void rend_Screenshot(int bm_handle) {
|
||||
auto screenshot = rend_Screenshot();
|
||||
auto *temp_data = reinterpret_cast<uint*>(screenshot->getData());
|
||||
|
||||
uint32_t w, h;
|
||||
screenshot->getSize(w, h);
|
||||
|
||||
ASSERT((bm_w(bm_handle, 0)) == gpu_state.screen_width);
|
||||
ASSERT((bm_h(bm_handle, 0)) == gpu_state.screen_height);
|
||||
|
||||
int w = bm_w(bm_handle, 0);
|
||||
int h = bm_h(bm_handle, 0);
|
||||
ushort* dest_data = bm_data(bm_handle, 0);
|
||||
|
||||
temp_data = (uint *)mem_malloc(total * 4);
|
||||
ASSERT(temp_data); // Ran out of memory?
|
||||
|
||||
dest_data = bm_data(bm_handle, 0);
|
||||
|
||||
dglReadPixels(0, 0, gpu_state.screen_width, gpu_state.screen_height, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
(GLvoid *)temp_data);
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
for (t = 0; t < w; t++) {
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int t = 0; t < w; t++) {
|
||||
uint spix = temp_data[i * w + t];
|
||||
|
||||
int r = spix & 0xff;
|
||||
|
1
third_party/CMakeLists.txt
vendored
Normal file
1
third_party/CMakeLists.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
add_subdirectory(stb)
|
5
third_party/stb/CMakeLists.txt
vendored
Normal file
5
third_party/stb/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
add_library(stb STATIC
|
||||
stb.cpp
|
||||
stb_image_write.h
|
||||
)
|
||||
target_include_directories(stb PUBLIC .)
|
20
third_party/stb/stb.cpp
vendored
Normal file
20
third_party/stb/stb.cpp
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Descent Developers
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "stb_image_write.h"
|
1724
third_party/stb/stb_image_write.h
vendored
Normal file
1724
third_party/stb/stb_image_write.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user