Applied relevant upstream patches, including one that fixes the CL-GD.
Several small fixes here and there.
This commit is contained in:
@@ -135,6 +135,7 @@ device_add(const device_t *d)
|
||||
{
|
||||
wchar_t temp[1024];
|
||||
void *priv = NULL;
|
||||
device_t *old;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < DEVICE_MAX; c++) {
|
||||
@@ -164,6 +165,7 @@ device_add(const device_t *d)
|
||||
INFO("DEVICE: device '%s' is unstable, user agreed!\n", d->name);
|
||||
}
|
||||
|
||||
old = device_current;
|
||||
device_current = (device_t *)d;
|
||||
|
||||
devices[c] = (device_t *)d;
|
||||
@@ -183,6 +185,7 @@ device_add(const device_t *d)
|
||||
}
|
||||
|
||||
device_priv[c] = priv;
|
||||
device_current = old;
|
||||
|
||||
return(priv);
|
||||
}
|
||||
@@ -204,8 +207,6 @@ device_add_ex(const device_t *d, void *priv)
|
||||
if (c >= DEVICE_MAX)
|
||||
fatal("DEVICE: too many devices\n");
|
||||
|
||||
device_current = (device_t *)d;
|
||||
|
||||
devices[c] = (device_t *)d;
|
||||
device_priv[c] = priv;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Generic interface for CD-ROM/DVD/BD implementations.
|
||||
*
|
||||
* Version: @(#)cdrom.c 1.0.24 2018/10/20
|
||||
* Version: @(#)cdrom.c 1.0.25 2018/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -271,7 +271,7 @@ cdrom_eject(uint8_t id)
|
||||
}
|
||||
|
||||
if (dev->host_drive == 200) {
|
||||
dev->prev_image_path = (wchar_t *)mem_alloc(1024);
|
||||
dev->prev_image_path = (wchar_t *)mem_alloc(1024 * sizeof(wchar_t));
|
||||
wcscpy(dev->prev_image_path, dev->image_path);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* CD-ROM image support.
|
||||
*
|
||||
* Version: @(#)cdrom_image.cpp 1.0.17 2018/10/20
|
||||
* Version: @(#)cdrom_image.cpp 1.0.19 2018/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -133,7 +133,7 @@ enum {
|
||||
|
||||
|
||||
static int cdrom_sector_size;
|
||||
static uint8_t raw_buffer[2448];
|
||||
static uint8_t raw_buffer[2856]; /* same size as sector_buffer_t */
|
||||
static uint8_t extra_buffer[296];
|
||||
|
||||
|
||||
@@ -467,9 +467,9 @@ read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, i
|
||||
bb += mode2 ? 12 : 4;
|
||||
bb += len;
|
||||
if (mode2 && ((mode2 & 0x03) == 1))
|
||||
memset(bb, 0, 280);
|
||||
memset(bb, 0, 88); /* 280 */
|
||||
else if (!mode2)
|
||||
memset(bb, 0, 288);
|
||||
memset(bb, 0, 96); /* 288 */
|
||||
}
|
||||
|
||||
|
||||
@@ -730,13 +730,8 @@ image_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int is_msf,
|
||||
if (!is_legal(dev->id, type, flags, audio, mode2))
|
||||
return 0;
|
||||
|
||||
if ((type == 3) || ((type > 4) && (type != 8))) {
|
||||
if (type == 3) {
|
||||
DEBUG("CD-ROM %i: Attempting to read a Yellowbook Mode 2 data sector from an image\n", dev->id);
|
||||
}
|
||||
if (type > 4) {
|
||||
DEBUG("CD-ROM %i: Attempting to read a XA Mode 2 Form 2 data sector from an image\n", dev->id);
|
||||
}
|
||||
if ((type > 5) && (type != 8)) {
|
||||
DEBUG("CD-ROM %i: Attempting to read an unrecognized sector type from an image\n", dev->id);
|
||||
return 0;
|
||||
} else if (type == 1) {
|
||||
if (!audio || dev->img_is_iso) {
|
||||
@@ -1107,6 +1102,7 @@ cdrom_image_open(cdrom_t *dev, const wchar_t *fn)
|
||||
if (! img->SetDevice(temp, false)) {
|
||||
image_close(dev);
|
||||
dev->ops = NULL;
|
||||
dev->host_drive = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the Iomega ZIP drive with SCSI(-like)
|
||||
* commands, for both ATAPI and SCSI usage.
|
||||
*
|
||||
* Version: @(#)zip.c 1.0.20 2018/10/20
|
||||
* Version: @(#)zip.c 1.0.21 2018/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -2760,15 +2760,15 @@ zip_identify(void *p, int ide_has_dma)
|
||||
}
|
||||
|
||||
|
||||
static zip_t *
|
||||
static void
|
||||
zip_drive_reset(int c)
|
||||
{
|
||||
scsi_device_t *sd;
|
||||
ide_t *id;
|
||||
|
||||
if (!zip[c]) {
|
||||
zip[c] = (zip_t *) malloc(sizeof(zip_t));
|
||||
memset(zip[c], 0, sizeof(zip_t));
|
||||
zip[c] = (zip_t *)mem_alloc(sizeof(zip_t));
|
||||
memset(zip[c], 0x00, sizeof(zip_t));
|
||||
}
|
||||
|
||||
zip[c]->id = c;
|
||||
@@ -2807,8 +2807,6 @@ zip_drive_reset(int c)
|
||||
ide_atapi_attach(id);
|
||||
}
|
||||
}
|
||||
|
||||
return zip[c];
|
||||
}
|
||||
|
||||
|
||||
@@ -2829,7 +2827,7 @@ zip_hard_reset(void)
|
||||
if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) && (zip_drives[c].bus_id.ide_channel > 7))
|
||||
continue;
|
||||
|
||||
zip[c] = zip_drive_reset(c);
|
||||
zip_drive_reset(c);
|
||||
|
||||
zip[c]->id = c;
|
||||
zip[c]->drv = &zip_drives[c];
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
* Logitech Mouse.exe 6.50
|
||||
* Microsoft Mouse.com 2.00
|
||||
* Microsoft Mouse.sys 3.00
|
||||
* Microsoft Mouse.com 7.04
|
||||
* Microsoft Mouse.com 8.21J
|
||||
* Microsoft Windows 1.00 DR5
|
||||
* Microsoft Windows 3.10.026
|
||||
* Microsoft Windows NT 3.1
|
||||
@@ -51,7 +53,7 @@
|
||||
* Microsoft Windows NT 3.1
|
||||
* Microsoft Windows 98 SE
|
||||
*
|
||||
* Version: @(#)mouse_bus.c 1.1.1 2018/10/11
|
||||
* Version: @(#)mouse_bus.c 1.1.2 2018/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the common AHA/BL code.
|
||||
*
|
||||
* Version: @(#)scsi_x54x.h 1.0.5 2018/10/14
|
||||
* Version: @(#)scsi_x54x.h 1.0.6 2018/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -133,50 +133,10 @@
|
||||
#define INTR_MBIF 0x01 /* MBI full */
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t hi;
|
||||
uint8_t mid;
|
||||
uint8_t lo;
|
||||
} addr24;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define ADDR_TO_U32(x) (((x).hi<<16)|((x).mid<<8)|((x).lo&0xFF))
|
||||
#define U32_TO_ADDR(a,x) do {(a).hi=(x)>>16;(a).mid=(x)>>8;(a).lo=(x)&0xFF;}while(0)
|
||||
|
||||
|
||||
/* Structure for the INQUIRE_SETUP_INFORMATION reply. */
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t uOffset :4,
|
||||
uTransferPeriod :3,
|
||||
fSynchronous :1;
|
||||
} ReplyInquireSetupInformationSynchronousValue;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t fSynchronousInitiationEnabled :1,
|
||||
fParityCheckingEnabled :1,
|
||||
uReserved1 :6;
|
||||
uint8_t uBusTransferRate;
|
||||
uint8_t uPreemptTimeOnBus;
|
||||
uint8_t uTimeOffBus;
|
||||
uint8_t cMailbox;
|
||||
addr24 MailboxAddress;
|
||||
ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8];
|
||||
uint8_t uDisconnectPermittedId0To7;
|
||||
uint8_t VendorSpecificData[28];
|
||||
} ReplyInquireSetupInformation;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t Count;
|
||||
addr24 Address;
|
||||
} MailboxInit_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
/*
|
||||
* Mailbox Definitions.
|
||||
*
|
||||
@@ -193,31 +153,6 @@ typedef struct {
|
||||
#define MBI_NOT_FOUND 0x03
|
||||
#define MBI_ERROR 0x04
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t CmdStatus;
|
||||
addr24 CCBPointer;
|
||||
} Mailbox_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint32_t CCBPointer;
|
||||
union {
|
||||
struct {
|
||||
uint8_t Reserved[3];
|
||||
uint8_t ActionCode;
|
||||
} out;
|
||||
struct {
|
||||
uint8_t HostStatus;
|
||||
uint8_t TargetStatus;
|
||||
uint8_t Reserved;
|
||||
uint8_t CompletionCode;
|
||||
} in;
|
||||
} u;
|
||||
} Mailbox32_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
/*
|
||||
*
|
||||
* CCB - SCSI Command Control Block
|
||||
@@ -265,13 +200,77 @@ typedef struct {
|
||||
#define CCB_DUPLICATE_CCB 0x19 /* Duplicate CCB */
|
||||
#define CCB_INVALID_CCB 0x1A /* Invalid CCB - bad parameter */
|
||||
|
||||
#define lba32_blk(p) ((uint32_t)(p->u.lba.lba0<<24) | (p->u.lba.lba1<<16) | \
|
||||
(p->u.lba.lba2<<8) | p->u.lba.lba3)
|
||||
/*
|
||||
*
|
||||
* Scatter/Gather Segment List Definitions
|
||||
*
|
||||
* Adapter limits
|
||||
*/
|
||||
#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t hi;
|
||||
uint8_t mid;
|
||||
uint8_t lo;
|
||||
} addr24;
|
||||
|
||||
/* Structure for the INQUIRE_SETUP_INFORMATION reply. */
|
||||
typedef struct {
|
||||
uint8_t uOffset :4,
|
||||
uTransferPeriod :3,
|
||||
fSynchronous :1;
|
||||
} ReplyInquireSetupInformationSynchronousValue;
|
||||
typedef struct {
|
||||
uint8_t fSynchronousInitiationEnabled :1,
|
||||
fParityCheckingEnabled :1,
|
||||
uReserved1 :6;
|
||||
uint8_t uBusTransferRate;
|
||||
uint8_t uPreemptTimeOnBus;
|
||||
uint8_t uTimeOffBus;
|
||||
uint8_t cMailbox;
|
||||
addr24 MailboxAddress;
|
||||
ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8];
|
||||
uint8_t uDisconnectPermittedId0To7;
|
||||
uint8_t VendorSpecificData[28];
|
||||
} ReplyInquireSetupInformation;
|
||||
|
||||
typedef struct {
|
||||
uint8_t Count;
|
||||
addr24 Address;
|
||||
} MailboxInit_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t CmdStatus;
|
||||
addr24 CCBPointer;
|
||||
} Mailbox_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t CCBPointer;
|
||||
union {
|
||||
struct {
|
||||
uint8_t Reserved[3];
|
||||
uint8_t ActionCode;
|
||||
} out;
|
||||
struct {
|
||||
uint8_t HostStatus;
|
||||
uint8_t TargetStatus;
|
||||
uint8_t Reserved;
|
||||
uint8_t CompletionCode;
|
||||
} in;
|
||||
} u;
|
||||
} Mailbox32_t;
|
||||
|
||||
|
||||
/* Byte 15 Target Status
|
||||
|
||||
See scsi.h files for these statuses.
|
||||
Bytes 16 and 17 Reserved (must be 0)
|
||||
Bytes 18 through 18+n-1, where n=size of CDB Command Descriptor Block */
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t Opcode;
|
||||
uint8_t Reserved1 :3,
|
||||
@@ -293,9 +292,7 @@ typedef struct {
|
||||
uint8_t Reserved3[6];
|
||||
uint32_t SensePointer;
|
||||
} CCB32;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t Opcode;
|
||||
uint8_t Lun :3,
|
||||
@@ -312,9 +309,7 @@ typedef struct {
|
||||
uint8_t Reserved[2];
|
||||
uint8_t Cdb[12];
|
||||
} CCB;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint8_t Opcode;
|
||||
uint8_t Pad1 :3,
|
||||
@@ -329,17 +324,13 @@ typedef struct {
|
||||
uint8_t Pad4[2];
|
||||
uint8_t Cdb[12];
|
||||
} CCBC;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef union {
|
||||
CCB32 new_fmt;
|
||||
CCB old_fmt;
|
||||
CCBC common;
|
||||
} CCBU;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
CCBU CmdBlock;
|
||||
uint8_t *RequestSenseBuffer;
|
||||
@@ -351,6 +342,38 @@ typedef struct {
|
||||
TargetStatus,
|
||||
MailboxCompletionCode;
|
||||
} Req_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t command;
|
||||
uint8_t lun:3,
|
||||
reserved:2,
|
||||
id:3;
|
||||
union {
|
||||
struct {
|
||||
uint16_t cyl;
|
||||
uint8_t head;
|
||||
uint8_t sec;
|
||||
} chs;
|
||||
struct {
|
||||
uint8_t lba0; /* MSB */
|
||||
uint8_t lba1;
|
||||
uint8_t lba2;
|
||||
uint8_t lba3; /* LSB */
|
||||
} lba;
|
||||
} u;
|
||||
uint8_t secount;
|
||||
addr24 dma_address;
|
||||
} BIOSCMD;
|
||||
|
||||
typedef struct {
|
||||
uint32_t Segment;
|
||||
uint32_t SegmentPointer;
|
||||
} SGE32;
|
||||
|
||||
typedef struct {
|
||||
addr24 Segment;
|
||||
addr24 SegmentPointer;
|
||||
} SGE;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct {
|
||||
@@ -490,56 +513,6 @@ typedef struct {
|
||||
} x54x_t;
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t command;
|
||||
uint8_t lun:3,
|
||||
reserved:2,
|
||||
id:3;
|
||||
union {
|
||||
struct {
|
||||
uint16_t cyl;
|
||||
uint8_t head;
|
||||
uint8_t sec;
|
||||
} chs;
|
||||
struct {
|
||||
uint8_t lba0; /* MSB */
|
||||
uint8_t lba1;
|
||||
uint8_t lba2;
|
||||
uint8_t lba3; /* LSB */
|
||||
} lba;
|
||||
} u;
|
||||
uint8_t secount;
|
||||
addr24 dma_address;
|
||||
} BIOSCMD;
|
||||
#pragma pack(pop)
|
||||
#define lba32_blk(p) ((uint32_t)(p->u.lba.lba0<<24) | (p->u.lba.lba1<<16) | \
|
||||
(p->u.lba.lba2<<8) | p->u.lba.lba3)
|
||||
|
||||
/*
|
||||
*
|
||||
* Scatter/Gather Segment List Definitions
|
||||
*
|
||||
* Adapter limits
|
||||
*/
|
||||
#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
uint32_t Segment;
|
||||
uint32_t SegmentPointer;
|
||||
} SGE32;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct {
|
||||
addr24 Segment;
|
||||
addr24 SegmentPointer;
|
||||
} SGE;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
extern void x54x_reset_ctrl(x54x_t *dev, uint8_t Reset);
|
||||
extern void x54x_buf_alloc(scsi_device_t *sd, int length);
|
||||
extern void x54x_buf_free(scsi_device_t *sd);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Brooktree Bt48x series true color RAMDAC emulation.
|
||||
*
|
||||
* Version: @(#)vid_bt48x_ramdac.c 1.0.8 2018/10/06
|
||||
* Version: @(#)vid_bt48x_ramdac.c 1.0.9 2018/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -209,8 +209,10 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt48x_ramdac_t *d
|
||||
indx = svga->dac_addr & 0x03ff;
|
||||
if ((dev->type >= BT485) && (svga->hwcursor.xsize == 64))
|
||||
cd = (uint8_t *) dev->cursor64_data;
|
||||
else
|
||||
else {
|
||||
indx &= 0xff;
|
||||
cd = (uint8_t *) dev->cursor32_data;
|
||||
}
|
||||
cd[indx] = val;
|
||||
svga->dac_addr++;
|
||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||
@@ -351,8 +353,10 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, bt48x_ramdac_t *dev, svga_t *sv
|
||||
indx = (svga->dac_addr - 1) & da_mask;
|
||||
if ((dev->type >= BT485) && (svga->hwcursor.xsize == 64))
|
||||
cd = (uint8_t *) dev->cursor64_data;
|
||||
else
|
||||
else {
|
||||
indx &= 0xff;
|
||||
cd = (uint8_t *) dev->cursor32_data;
|
||||
}
|
||||
|
||||
temp = cd[indx];
|
||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Emulation of select Cirrus Logic cards (CL-GD 5428,
|
||||
* CL-GD 5429, 5430, 5434 and 5436 are supported).
|
||||
*
|
||||
* Version: @(#)vid_cl54xx.c 1.0.21 2018/10/20
|
||||
* Version: @(#)vid_cl54xx.c 1.0.22 2018/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -1016,8 +1016,13 @@ gd54xx_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
gd54xx_t *gd54xx = (gd54xx_t *)p;
|
||||
svga_t *svga = &gd54xx->svga;
|
||||
|
||||
if (gd54xx->blt.sys_tx) {
|
||||
|
||||
if ((svga->seqregs[0x07] & 0x01) == 0) {
|
||||
svga_write(addr, val, svga);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gd54xx->blt.sys_tx) {
|
||||
if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) {
|
||||
gd54xx->blt.sys_buf &= ~(0xff << (gd54xx->blt.sys_cnt * 8));
|
||||
gd54xx->blt.sys_buf |= (val << (gd54xx->blt.sys_cnt * 8));
|
||||
@@ -1028,7 +1033,7 @@ gd54xx_write(uint32_t addr, uint8_t val, void *p)
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
addr &= svga->banked_mask;
|
||||
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
|
||||
@@ -1043,13 +1048,17 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *p)
|
||||
gd54xx_t *gd54xx = (gd54xx_t *)p;
|
||||
svga_t *svga = &gd54xx->svga;
|
||||
|
||||
if (gd54xx->blt.sys_tx)
|
||||
{
|
||||
gd54xx_write(addr, val & 0xff, gd54xx);
|
||||
gd54xx_write(addr+1, val >> 8, gd54xx);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((svga->seqregs[0x07] & 0x01) == 0) {
|
||||
svga_writew(addr, val, svga);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gd54xx->blt.sys_tx) {
|
||||
gd54xx_write(addr, val, gd54xx);
|
||||
gd54xx_write(addr+1, val >> 8, gd54xx);
|
||||
return;
|
||||
}
|
||||
|
||||
addr &= svga->banked_mask;
|
||||
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
|
||||
|
||||
@@ -1068,14 +1077,18 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *p)
|
||||
gd54xx_t *gd54xx = (gd54xx_t *)p;
|
||||
svga_t *svga = &gd54xx->svga;
|
||||
|
||||
if (gd54xx->blt.sys_tx)
|
||||
{
|
||||
gd54xx_write(addr, val & 0xff, gd54xx);
|
||||
gd54xx_write(addr+1, val >> 8, gd54xx);
|
||||
gd54xx_write(addr+2, val >> 16, gd54xx);
|
||||
gd54xx_write(addr+3, val >> 24, gd54xx);
|
||||
return;
|
||||
}
|
||||
if ((svga->seqregs[0x07] & 0x01) == 0) {
|
||||
svga_writel(addr, val, svga);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gd54xx->blt.sys_tx) {
|
||||
gd54xx_write(addr, val, gd54xx);
|
||||
gd54xx_write(addr+1, val >> 8, gd54xx);
|
||||
gd54xx_write(addr+2, val >> 16, gd54xx);
|
||||
gd54xx_write(addr+3, val >> 24, gd54xx);
|
||||
return;
|
||||
}
|
||||
|
||||
addr &= svga->banked_mask;
|
||||
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
|
||||
@@ -1532,8 +1545,13 @@ gd54xx_read(uint32_t addr, void *p)
|
||||
{
|
||||
gd54xx_t *gd54xx = (gd54xx_t *)p;
|
||||
svga_t *svga = &gd54xx->svga;
|
||||
|
||||
if ((svga->seqregs[0x07] & 0x01) == 0)
|
||||
return svga_read(addr, svga);
|
||||
|
||||
addr &= svga->banked_mask;
|
||||
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
|
||||
|
||||
return svga_read_linear(addr, svga);
|
||||
}
|
||||
|
||||
@@ -1544,8 +1562,12 @@ gd54xx_readw(uint32_t addr, void *p)
|
||||
gd54xx_t *gd54xx = (gd54xx_t *)p;
|
||||
svga_t *svga = &gd54xx->svga;
|
||||
|
||||
if ((svga->seqregs[0x07] & 0x01) == 0)
|
||||
return svga_readw(addr, svga);
|
||||
|
||||
addr &= svga->banked_mask;
|
||||
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
|
||||
|
||||
return svga_readw_linear(addr, svga);
|
||||
}
|
||||
|
||||
@@ -1556,8 +1578,12 @@ gd54xx_readl(uint32_t addr, void *p)
|
||||
gd54xx_t *gd54xx = (gd54xx_t *)p;
|
||||
svga_t *svga = &gd54xx->svga;
|
||||
|
||||
if ((svga->seqregs[0x07] & 0x01) == 0)
|
||||
return svga_readl(addr, svga);
|
||||
|
||||
addr &= svga->banked_mask;
|
||||
addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1];
|
||||
|
||||
return svga_readl_linear(addr, svga);
|
||||
}
|
||||
|
||||
@@ -1567,8 +1593,8 @@ gd543x_do_mmio(svga_t *svga, uint32_t addr)
|
||||
{
|
||||
if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)
|
||||
return 1;
|
||||
else
|
||||
return ((addr & ~0xff) == 0xb8000);
|
||||
|
||||
return ((addr & ~0xff) == 0xb8000);
|
||||
}
|
||||
|
||||
|
||||
@@ -1795,6 +1821,7 @@ gd543x_mmio_read(uint32_t addr, void *p)
|
||||
}
|
||||
else if (gd54xx->mmio_vram_overlap)
|
||||
return gd54xx_read(addr, gd54xx);
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
@@ -1809,6 +1836,7 @@ gd543x_mmio_readw(uint32_t addr, void *p)
|
||||
return gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8);
|
||||
else if (gd54xx->mmio_vram_overlap)
|
||||
return gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8);
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
@@ -1823,6 +1851,7 @@ gd543x_mmio_readl(uint32_t addr, void *p)
|
||||
return gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8) | (gd543x_mmio_read(addr+2, gd54xx) << 16) | (gd543x_mmio_read(addr+3, gd54xx) << 24);
|
||||
else if (gd54xx->mmio_vram_overlap)
|
||||
return gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8) | (gd54xx_read(addr+2, gd54xx) << 16) | (gd54xx_read(addr+3, gd54xx) << 24);
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* This is intended to be used by another SVGA driver,
|
||||
* and not as a card in it's own right.
|
||||
*
|
||||
* Version: @(#)vid_svga.c 1.0.13 2018/10/07
|
||||
* Version: @(#)vid_svga.c 1.0.14 2018/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -875,15 +875,39 @@ void
|
||||
svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
||||
{
|
||||
svga_t *svga = (svga_t *)p;
|
||||
|
||||
int func_select, writemask2 = svga->writemask;
|
||||
uint32_t write_mask, bit_mask, set_mask, val32 = (uint32_t) val;
|
||||
int func_select, writemask2 = svga->writemask;
|
||||
int memory_map_mode;
|
||||
|
||||
cycles -= video_timing_write_b;
|
||||
|
||||
if (!linear) {
|
||||
addr &= svga->banked_mask;
|
||||
addr += svga->write_bank;
|
||||
if (! linear) {
|
||||
memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
|
||||
addr &= 0x1ffff;
|
||||
|
||||
switch (memory_map_mode) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (addr >= 0x10000)
|
||||
return;
|
||||
addr += svga->write_bank;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
addr -= 0x10000;
|
||||
if (addr >= 0x8000)
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 3:
|
||||
addr -= 0x18000;
|
||||
if (addr >= 0x8000)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(svga->gdcreg[6] & 1))
|
||||
@@ -1008,14 +1032,38 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
||||
{
|
||||
svga_t *svga = (svga_t *)p;
|
||||
uint32_t latch_addr = 0, ret;
|
||||
int readplane = svga->readplane;
|
||||
uint8_t ret8;
|
||||
int memory_map_mode, readplane = svga->readplane;
|
||||
|
||||
cycles -= video_timing_read_b;
|
||||
|
||||
if (!linear) {
|
||||
addr &= svga->banked_mask;
|
||||
addr += svga->read_bank;
|
||||
if (! linear) {
|
||||
memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
|
||||
|
||||
addr &= 0x1ffff;
|
||||
|
||||
switch(memory_map_mode) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (addr >= 0x10000)
|
||||
return 0xff;
|
||||
addr += svga->read_bank;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
addr -= 0x10000;
|
||||
if (addr >= 0x8000)
|
||||
return 0xff;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 3:
|
||||
addr -= 0x18000;
|
||||
if (addr >= 0x8000)
|
||||
return 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
latch_addr = (addr << 2) & svga->decode_mask;
|
||||
}
|
||||
@@ -1029,6 +1077,12 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
||||
readplane = (readplane & 2) | (addr & 1);
|
||||
addr &= ~1;
|
||||
addr <<= 2;
|
||||
addr |= readplane;
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
return 0xff;
|
||||
addr &= svga->vram_mask;
|
||||
return svga->vram[addr];
|
||||
} else
|
||||
addr <<= 2;
|
||||
|
||||
@@ -1058,16 +1112,15 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
||||
|
||||
if (!(svga->gdcreg[5] & 8)) {
|
||||
/* read mode 0 */
|
||||
return svga->vram[addr | readplane];
|
||||
} else {
|
||||
/* read mode 1 */
|
||||
ret = (svga->latch ^ mask16[svga->colourcompare & 0x0f]) & mask16[svga->colournocare & 0x0f];
|
||||
ret8 = (ret & 0xff);
|
||||
ret8 |= ((ret >> 24) & 0xff);
|
||||
ret8 |= ((ret >> 16) & 0xff);
|
||||
ret8 |= ((ret >> 8) & 0xff);
|
||||
return(~ret8);
|
||||
return (svga->latch >> (readplane * 8)) & 0xff;
|
||||
}
|
||||
|
||||
/* read mode 1 */
|
||||
ret = (svga->latch ^ mask16[svga->colourcompare & 0x0f]) & mask16[svga->colournocare & 0x0f];
|
||||
ret |= ret >> 16;
|
||||
ret |= ret >> 8;
|
||||
ret = (~ret) & 0xff;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -877,7 +877,7 @@ ui_sb_menu_command(int idm, uint8_t tag)
|
||||
/* Save current drive/pathname for later re-use. */
|
||||
cdev->prev_host_drive = cdev->host_drive;
|
||||
if (! cdev->prev_image_path)
|
||||
cdev->prev_image_path = (wchar_t *)mem_alloc(1024);
|
||||
cdev->prev_image_path = (wchar_t *)mem_alloc(1024 * sizeof(wchar_t));
|
||||
wcscpy(cdev->prev_image_path, str);
|
||||
|
||||
/* Close the current drive/pathname. */
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* we will not use that, but, instead, use a new window which
|
||||
* coverrs the entire desktop.
|
||||
*
|
||||
* Version: @(#)win_sdl.c 1.0.5 2018/10/05
|
||||
* Version: @(#)win_sdl.c 1.0.6 2018/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Michael Dr<44>ing, <michael@drueing.de>
|
||||
@@ -83,7 +83,10 @@ static SDL_Window *sdl_win = NULL;
|
||||
static SDL_Renderer *sdl_render = NULL;
|
||||
static SDL_Texture *sdl_tex = NULL;
|
||||
static HWND sdl_hwnd = NULL;
|
||||
static HWND sdl_parent_hwnd = NULL;
|
||||
static int sdl_w, sdl_h;
|
||||
static int cur_w, cur_h;
|
||||
static int sdl_fs;
|
||||
|
||||
|
||||
/* Pointers to the real functions. */
|
||||
@@ -130,15 +133,131 @@ static const dllimp_t sdl_imports[] = {
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
sdl_stretch(int *w, int *h, int *x, int *y)
|
||||
{
|
||||
double dw, dh, dx, dy, temp, temp2, ratio_w, ratio_h, gsr, hsr;
|
||||
|
||||
switch (vid_fullscreen_scale) {
|
||||
case FULLSCR_SCALE_FULL:
|
||||
*w = sdl_w;
|
||||
*h = sdl_h;
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
break;
|
||||
|
||||
case FULLSCR_SCALE_43:
|
||||
dw = (double) sdl_w;
|
||||
dh = (double) sdl_h;
|
||||
temp = (dh / 3.0) * 4.0;
|
||||
dx = (dw - temp) / 2.0;
|
||||
dw = temp;
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = (int) dx;
|
||||
*y = 0;
|
||||
break;
|
||||
|
||||
case FULLSCR_SCALE_SQ:
|
||||
dw = (double) sdl_w;
|
||||
dh = (double) sdl_h;
|
||||
temp = ((double) *w);
|
||||
temp2 = ((double) *h);
|
||||
dx = (dw / 2.0) - ((dh * temp) / (temp2 * 2.0));
|
||||
dy = 0.0;
|
||||
if (dx < 0.0) {
|
||||
dx = 0.0;
|
||||
dy = (dw / 2.0) - ((dh * temp2) / (temp * 2.0));
|
||||
}
|
||||
dw -= (dx * 2.0);
|
||||
dh -= (dy * 2.0);
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = (int) dx;
|
||||
*y = (int) dy;
|
||||
break;
|
||||
|
||||
case FULLSCR_SCALE_INT:
|
||||
dw = (double) sdl_w;
|
||||
dh = (double) sdl_h;
|
||||
temp = ((double) *w);
|
||||
temp2 = ((double) *h);
|
||||
ratio_w = dw / ((double) *w);
|
||||
ratio_h = dh / ((double) *h);
|
||||
if (ratio_h < ratio_w)
|
||||
ratio_w = ratio_h;
|
||||
dx = (dw / 2.0) - ((temp * ratio_w) / 2.0);
|
||||
dy = (dh / 2.0) - ((temp2 * ratio_h) / 2.0);
|
||||
dw -= (dx * 2.0);
|
||||
dh -= (dy * 2.0);
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = (int) dx;
|
||||
*y = (int) dy;
|
||||
break;
|
||||
|
||||
case FULLSCR_SCALE_KEEPRATIO:
|
||||
dw = (double) sdl_w;
|
||||
dh = (double) sdl_h;
|
||||
hsr = dw / dh;
|
||||
gsr = ((double) *w) / ((double) *h);
|
||||
if (gsr <= hsr) {
|
||||
temp = dh * gsr;
|
||||
dx = (dw - temp) / 2.0;
|
||||
dw = temp;
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = (int) dx;
|
||||
*y = 0;
|
||||
} else {
|
||||
temp = dw / gsr;
|
||||
dy = (dh - temp) / 2.0;
|
||||
dh = temp;
|
||||
*w = (int) dw;
|
||||
*h = (int) dh;
|
||||
*x = 0;
|
||||
*y = (int) dy;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_resize(int x, int y)
|
||||
{
|
||||
int ww = 0, wh = 0, wx = 0, wy = 0;
|
||||
|
||||
DEBUG("SDL: resizing to %dx%d\n", x, y);
|
||||
|
||||
if ((x == cur_w) && (y == cur_h)) return;
|
||||
|
||||
DEBUG("sdl_resize(%i, %i)\n", x, y);
|
||||
ww = x;
|
||||
wh = y;
|
||||
sdl_stretch(&ww, &wh, &wx, &wy);
|
||||
|
||||
MoveWindow(sdl_hwnd, wx, wy, ww, wh, TRUE);
|
||||
|
||||
cur_w = x;
|
||||
cur_h = y;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_blit(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
SDL_Rect r_src;
|
||||
void *pixeldata;
|
||||
int xx, yy, ret;
|
||||
int pitch;
|
||||
int yy;
|
||||
|
||||
if ((y1 == y2) || (buffer32 == NULL)) {
|
||||
if (y1 == y2) {
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer32 == NULL) {
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
@@ -151,25 +270,34 @@ sdl_blit(int x, int y, int y1, int y2, int w, int h)
|
||||
sdl_LockTexture(sdl_tex, 0, &pixeldata, &pitch);
|
||||
|
||||
for (yy = y1; yy < y2; yy++) {
|
||||
if ((y + yy) >= 0 && (y + yy) < buffer32->h)
|
||||
#if 0
|
||||
if (video_grayscale || invert_display)
|
||||
if ((y + yy) >= 0 && (y + yy) < buffer32->h) {
|
||||
if (vid_grayscale || invert_display)
|
||||
video_transform_copy((uint32_t *) &(((uint8_t *)pixeldata)[yy * pitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w);
|
||||
else
|
||||
#endif
|
||||
else
|
||||
memcpy((uint32_t *) &(((uint8_t *)pixeldata)[yy * pitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4);
|
||||
}
|
||||
}
|
||||
|
||||
video_blit_complete();
|
||||
|
||||
sdl_UnlockTexture(sdl_tex);
|
||||
|
||||
if (sdl_fs) {
|
||||
get_screen_size_natural(&xx, &yy);
|
||||
DEBUG("sdl_blit(%i, %i, %i, %i, %i, %i) (%i, %i)\n", x, y, y1, y2, w, h, xx, yy);
|
||||
if (w == xx)
|
||||
sdl_resize(w, h);
|
||||
DEBUG("(%08X, %08X, %08X)\n", sdl_win, sdl_render, sdl_tex);
|
||||
}
|
||||
|
||||
r_src.x = 0;
|
||||
r_src.y = 0;
|
||||
r_src.w = w;
|
||||
r_src.h = h;
|
||||
|
||||
sdl_RenderCopy(sdl_render, sdl_tex, &r_src, 0);
|
||||
ret = sdl_RenderCopy(sdl_render, sdl_tex, &r_src, 0);
|
||||
if (ret)
|
||||
DEBUG("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError());
|
||||
|
||||
sdl_RenderPresent(sdl_render);
|
||||
}
|
||||
@@ -199,15 +327,18 @@ sdl_close(void)
|
||||
if (sdl_hwnd != NULL) {
|
||||
plat_set_input(hwndMain);
|
||||
|
||||
#if 1
|
||||
ShowWindow(hwndRender, TRUE);
|
||||
SetFocus(hwndMain);
|
||||
#endif
|
||||
|
||||
DestroyWindow(sdl_hwnd);
|
||||
sdl_hwnd = NULL;
|
||||
}
|
||||
|
||||
if (sdl_parent_hwnd != NULL) {
|
||||
DestroyWindow(sdl_parent_hwnd);
|
||||
sdl_parent_hwnd = NULL;
|
||||
}
|
||||
|
||||
/* Quit and unload the DLL if possible. */
|
||||
if (sdl_handle != NULL) {
|
||||
sdl_Quit();
|
||||
@@ -223,6 +354,7 @@ sdl_init(int fs)
|
||||
{
|
||||
wchar_t temp[128];
|
||||
SDL_version ver;
|
||||
int x, y;
|
||||
|
||||
INFO("SDL: init (fs=%d)\n", fs);
|
||||
|
||||
@@ -253,7 +385,7 @@ sdl_init(int fs)
|
||||
/* Create the desktop-covering window. */
|
||||
swprintf(temp, sizeof_w(temp),
|
||||
L"%s v%s Full-Screen", EMU_NAME, emu_version);
|
||||
sdl_hwnd = CreateWindow(FS_CLASS_NAME,
|
||||
sdl_parent_hwnd = CreateWindow(FS_CLASS_NAME,
|
||||
temp,
|
||||
WS_POPUP,
|
||||
0, 0, sdl_w, sdl_h,
|
||||
@@ -261,12 +393,28 @@ sdl_init(int fs)
|
||||
NULL,
|
||||
hInstance,
|
||||
NULL);
|
||||
|
||||
SetWindowPos(sdl_parent_hwnd, HWND_TOPMOST,
|
||||
0, 0, sdl_w, sdl_h, SWP_SHOWWINDOW);
|
||||
|
||||
/* Create the actual rendering window. */
|
||||
swprintf(temp, sizeof_w(temp), L"%s v%s", EMU_NAME, emu_version);
|
||||
sdl_hwnd = CreateWindow(FS_CLASS_NAME,
|
||||
temp,
|
||||
WS_POPUP,
|
||||
0, 0, sdl_w, sdl_h,
|
||||
sdl_parent_hwnd,
|
||||
NULL,
|
||||
hInstance,
|
||||
NULL);
|
||||
DEBUG("SDL: FS %dx%d window at %08lx\n", sdl_w, sdl_h, sdl_hwnd);
|
||||
|
||||
/* Redirect RawInput to this new window. */
|
||||
plat_set_input(sdl_hwnd);
|
||||
|
||||
/* Show the window, make it topmost, and give it focus. */
|
||||
get_screen_size_natural(&x, &y);
|
||||
sdl_stretch(&sdl_w, &sdl_h, &x, &y);
|
||||
SetWindowPos(sdl_hwnd, HWND_TOPMOST,
|
||||
0, 0, sdl_w, sdl_h, SWP_SHOWWINDOW);
|
||||
|
||||
@@ -276,11 +424,13 @@ sdl_init(int fs)
|
||||
/* Create the SDL window from the render window. */
|
||||
sdl_win = sdl_CreateWindowFrom((void *)hwndRender);
|
||||
}
|
||||
|
||||
if (sdl_win == NULL) {
|
||||
ERRLOG("SDL: unable to CreateWindowFrom (%s)\n", sdl_GetError());
|
||||
sdl_close();
|
||||
return(0);
|
||||
}
|
||||
sdl_fs = fs;
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
@@ -320,55 +470,18 @@ sdl_init(int fs)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_resize(int x, int y)
|
||||
{
|
||||
DEBUG("SDL: resizing to %dx%d\n", x, y);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdl_screenshot(const wchar_t *fn)
|
||||
{
|
||||
#if 0
|
||||
int i, res, x, y, width = 0, height = 0;
|
||||
unsigned char* rgba = NULL;
|
||||
png_bytep *b_rgb = NULL;
|
||||
FILE *fp = NULL;
|
||||
uint8_t *pixels = NULL;
|
||||
int res;
|
||||
|
||||
sdl_GetWindowSize(sdl_win, &width, &height);
|
||||
|
||||
/* Create file. */
|
||||
if ((fp = plat_fopen(fn, L"wb")) == NULL) {
|
||||
ERRLOG("SDL: screenshot: file %ls could not be opened for writing\n", fn);
|
||||
return;
|
||||
}
|
||||
|
||||
/* initialize stuff */
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (png_ptr == NULL) {
|
||||
ERRLOG("SDL: screenshot: create_write_struct failed\n");
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL) {
|
||||
ERRLOG("SDL: screenshot: create_info_struct failed");
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, width, height,
|
||||
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
|
||||
pixels = (uint8_t *)mem_alloc(width * height * 4);
|
||||
if (pixels == NULL) {
|
||||
ERRLOG("SDL: screenshot: unable to allocate RGBA Bitmap memory\n");
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -377,41 +490,10 @@ sdl_screenshot(const wchar_t *fn)
|
||||
if (res != 0) {
|
||||
ERRLOG("SDL: screenshot: error reading render pixels\n");
|
||||
free(pixels);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((b_rgb = (png_bytep *)mem_alloc(sizeof(png_bytep) * height)) == NULL) {
|
||||
ERRLOG("[sdl_take_screenshot] Unable to Allocate RGB Bitmap Memory");
|
||||
free(rgba);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
for (y = 0; y < height; ++y) {
|
||||
b_rgb[y] = (png_byte *)mem_alloc(png_get_rowbytes(png_ptr, info_ptr));
|
||||
for (x = 0; x < width; ++x) {
|
||||
b_rgb[y][(x) * 3 + 0] = rgba[(y * width + x) * 4 + 0];
|
||||
b_rgb[y][(x) * 3 + 1] = rgba[(y * width + x) * 4 + 1];
|
||||
b_rgb[y][(x) * 3 + 2] = rgba[(y * width + x) * 4 + 2];
|
||||
}
|
||||
}
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
png_write_image(png_ptr, b_rgb);
|
||||
|
||||
png_write_end(png_ptr, NULL);
|
||||
|
||||
/* cleanup heap allocation */
|
||||
for (i = 0; i < height; i++)
|
||||
if (b_rgb[i]) free(b_rgb[i]);
|
||||
|
||||
if (b_rgb) free(b_rgb);
|
||||
|
||||
if (rgba) free(rgba);
|
||||
|
||||
if (fp) fclose(fp);
|
||||
if (pixels) free(pixels);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user