2237 lines
54 KiB
C
2237 lines
54 KiB
C
/******************************************************************************
|
|
* XRSRC.C
|
|
*
|
|
* Extended Resource-Manager. RSC-Files can now have up to
|
|
* 4294967295 bytes length.
|
|
*
|
|
******************************************************************************/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <tos.h>
|
|
#include <vdi.h>
|
|
#include <aes.h>
|
|
#include <assert.h>
|
|
#ifdef __GNUC__
|
|
#include <sys/stat.h>
|
|
#else
|
|
#include <ext.h>
|
|
#endif
|
|
#include "xrsrc.h"
|
|
|
|
/* horizontal text alignment */
|
|
#ifndef ALI_LEFT
|
|
#define ALI_LEFT 0
|
|
#define ALI_CENTER 1
|
|
#define ALI_RIGHT 2
|
|
#endif
|
|
#ifndef ALI_TOP
|
|
#define ALI_TOP 5
|
|
#endif
|
|
#ifndef R_IBPTEXT
|
|
#define R_IBPTEXT 13
|
|
#endif
|
|
|
|
#ifndef FALSE
|
|
# define FALSE 0
|
|
# define TRUE 1
|
|
#endif
|
|
|
|
#ifndef _CDECL
|
|
#ifdef __GNUC__
|
|
#define _CDECL /**/
|
|
#else
|
|
#define _CDECL cdecl
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef G_SHORTCUT
|
|
#define G_SHORTCUT 38
|
|
#endif
|
|
|
|
#ifndef G_EXTBOX
|
|
#define G_EXTBOX 40
|
|
#endif
|
|
#ifndef G_WHITE
|
|
#define G_WHITE 0
|
|
#endif
|
|
#ifndef G_BLACK
|
|
#define G_BLACK 1
|
|
#endif
|
|
#ifndef OS_SELECTED
|
|
#define OS_SELECTED SELECTED
|
|
#endif
|
|
#undef fclose
|
|
|
|
#ifndef _AESrscfile
|
|
# define _AESrscfile (((AES_GLOBAL *)_GemParBlk.global)->ap_ptree)
|
|
# define _AESrscmem (((AES_GLOBAL *)_GemParBlk.global)->ap_rscmem)
|
|
#endif
|
|
|
|
#define USE_NICELINES 0
|
|
|
|
#define ICOLSPEC_GET_DATACOL(color) ( ((color) >> 12) & 0x0f )
|
|
#define ICOLSPEC_GET_MASKCOL(color) ( ((color) >> 8) & 0x0f )
|
|
#define ICOLSPEC_GET_CHARACTER(color) ( ((color) ) & 0xff )
|
|
|
|
/****** TYPES ****************************************************************/
|
|
|
|
struct userdef {
|
|
OBJECT orig;
|
|
USERBLK user;
|
|
_WORD obj;
|
|
};
|
|
|
|
struct userdef_list {
|
|
struct userdef_list *next;
|
|
RSHDR *hdr;
|
|
OBJECT *objects;
|
|
_WORD nobjs;
|
|
_WORD nuserobjs;
|
|
struct userdef userobjs[1];
|
|
};
|
|
|
|
/****** VARIABLES ************************************************************/
|
|
|
|
static struct userdef_list *userdefs;
|
|
|
|
/*
|
|
* vdi handle used for drawing USERDEF objects
|
|
* It's safe to directly use the AES handle here,
|
|
* because we save/restore all attributes we change
|
|
*/
|
|
static _WORD aes_handle;
|
|
|
|
#define TEST_COLOR 15
|
|
#define XMAX_PLANES 32
|
|
#define XMAX_COLOR 256
|
|
|
|
typedef _WORD table4[XMAX_COLOR][4];
|
|
|
|
/*
|
|
* vdi handle used for initializing the color icon tables
|
|
*/
|
|
#define xvdi_handle aes_handle
|
|
static _WORD xscrn_planes;
|
|
|
|
/* number of bytes per pixel (0 == planeoriented) */
|
|
static _WORD xpixelbytes = -1;
|
|
/* table for plane oriented images */
|
|
static _WORD *colortbl;
|
|
/* table for pixel oriented imaged */
|
|
static _ULONG colortbl2[XMAX_COLOR];
|
|
/* wether an palette has already been set */
|
|
static _BOOL is_std_palette;
|
|
static table4 rgb_palette;
|
|
|
|
static _WORD xscr_w, xscr_h;
|
|
|
|
static _WORD const pixtbl[XMAX_COLOR] = {
|
|
0, 2, 3, 6, 4, 7, 5, 8, 9, 10, 11, 14, 12, 15, 13, 255,
|
|
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
|
32 , 33 , 34 , 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
|
48 , 49 , 50 , 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
|
64 , 65 , 66 , 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
|
80 , 81 , 82 , 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
|
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
|
|
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
|
|
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
|
|
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
|
|
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
|
|
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
|
|
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
|
|
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
|
|
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
|
|
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 1
|
|
};
|
|
|
|
/******************************************************************************/
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
/******************************************************************************/
|
|
|
|
static _BOOL xywh2pxy(_WORD x, _WORD y, _WORD w, _WORD h, _WORD *pxy, _WORD max_w, _WORD max_h)
|
|
{
|
|
if (x < 0)
|
|
{
|
|
w += x;
|
|
x = 0;
|
|
}
|
|
if (x >= max_w)
|
|
{
|
|
x = 0;
|
|
w = 0;
|
|
}
|
|
if (x + w > max_w)
|
|
{
|
|
w = max_w - x;
|
|
}
|
|
if (y < 0)
|
|
{
|
|
h += y;
|
|
y = 0;
|
|
}
|
|
if (y >= max_h)
|
|
{
|
|
y = 0;
|
|
h = 0;
|
|
}
|
|
if (y + h > max_h)
|
|
{
|
|
h = max_h - y;
|
|
}
|
|
pxy[0] = x;
|
|
pxy[1] = y;
|
|
pxy[2] = x + w - 1;
|
|
pxy[3] = y + h - 1;
|
|
return w > 0 && h > 0;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void save_fillattr(_WORD handle, _WORD attrib[5])
|
|
{
|
|
vqf_attributes(handle, attrib);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void restore_fillattr(_WORD handle, _WORD attrib[5])
|
|
{
|
|
vsf_interior(handle, attrib[0]);
|
|
vsf_color(handle, attrib[1]);
|
|
vsf_style(handle, attrib[2]);
|
|
vswr_mode(handle, attrib[3]);
|
|
vsf_perimeter(handle, attrib[4]);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void save_lineattr(_WORD handle, _WORD attrib[6])
|
|
{
|
|
vql_attributes(handle, attrib);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void restore_lineattr(_WORD handle, _WORD attrib[6])
|
|
{
|
|
vsl_type(handle, attrib[0]);
|
|
vsl_color(handle, attrib[1]);
|
|
vswr_mode(handle, attrib[2]);
|
|
vsl_width(handle, attrib[3]);
|
|
vsl_ends(handle, attrib[4], attrib[5]);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void save_textattr(_WORD handle, _WORD attrib[10])
|
|
{
|
|
_WORD dummy;
|
|
|
|
vqt_attributes(handle, attrib);
|
|
vst_effects(handle, 0);
|
|
vst_alignment(handle, ALI_LEFT, ALI_TOP, &dummy, &dummy);
|
|
vst_rotation(handle, 0);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void save_clip(_WORD handle, _WORD clip[5])
|
|
{
|
|
_WORD wo[57];
|
|
|
|
vq_extnd(handle, 1, wo);
|
|
clip[0] = wo[45];
|
|
clip[1] = wo[46];
|
|
clip[2] = wo[47];
|
|
clip[3] = wo[48];
|
|
clip[4] = wo[19];
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void restore_clip(_WORD handle, _WORD clip[5])
|
|
{
|
|
vs_clip(handle, clip[4], clip);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
/*
|
|
* set VDI clipping to coordinates in PARMBLK structure.
|
|
* Neccessary on some AES that don't set the clipping
|
|
* rectangle during objc_draw() (i.e. XaAES)
|
|
*/
|
|
static void set_user_clip(_WORD handle, PARMBLK *pb)
|
|
{
|
|
_WORD pxy[4];
|
|
|
|
pxy[0] = pb->pb_xc;
|
|
pxy[1] = pb->pb_yc;
|
|
pxy[2] = pb->pb_xc + pb->pb_wc - 1;
|
|
pxy[3] = pb->pb_yc + pb->pb_hc - 1;
|
|
vs_clip(handle, TRUE, pxy);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void restore_textattr(_WORD handle, _WORD attrib[10])
|
|
{
|
|
_WORD dummy;
|
|
|
|
vst_color(handle, attrib[1]);
|
|
vst_rotation(handle, attrib[2]);
|
|
vst_alignment(handle, attrib[3], attrib[4], &dummy, &dummy);
|
|
/* original vqt_attributes returns mode-1 */
|
|
vswr_mode(handle, attrib[5] + 1);
|
|
vst_height(handle, attrib[7], &dummy, &dummy, &dummy, &dummy);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void GetScreenSize(_WORD *width, _WORD *height)
|
|
{
|
|
*width = xscr_w;
|
|
*height = xscr_h;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void scrfdb(MFDB *fdb)
|
|
{
|
|
fdb->fd_addr = (void *) 0;
|
|
GetScreenSize(&fdb->fd_w, &fdb->fd_h);
|
|
fdb->fd_wdwidth = (fdb->fd_w + 15) >> 4;
|
|
fdb->fd_stand = FALSE;
|
|
fdb->fd_nplanes = xscrn_planes;
|
|
fdb->fd_r1 = fdb->fd_r2 = fdb->fd_r3 = 0;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
/******************************************************************************/
|
|
|
|
void GetTextSize(_WORD *width, _WORD *height)
|
|
{
|
|
_WORD dummy;
|
|
|
|
graf_handle(width, height, &dummy, &dummy);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void rsc_obfix(OBJECT *tree, _ULONG count)
|
|
{
|
|
_WORD wchar, hchar;
|
|
|
|
GetTextSize(&wchar, &hchar);
|
|
while (count)
|
|
{
|
|
tree->ob_x = wchar * (tree->ob_x & 0xff) + (tree->ob_x >> 8);
|
|
tree->ob_y = hchar * (tree->ob_y & 0xff) + (tree->ob_y >> 8);
|
|
tree->ob_width = wchar * (tree->ob_width & 0xff) + (tree->ob_width >> 8);
|
|
tree->ob_height = hchar * (tree->ob_height & 0xff) + (tree->ob_height >> 8);
|
|
tree++;
|
|
count--;
|
|
}
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static _WORD _CDECL draw_nothing(PARMBLK *pb)
|
|
{
|
|
(void) pb;
|
|
return 0;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void xrsrc_hdr2xrsc(RSXHDR *xrsc_header, RSHDR *header)
|
|
{
|
|
xrsc_header->rsh_vrsn = 3 | (header->rsh_vrsn & ~RSC_VERSION_MASK);
|
|
xrsc_header->rsh_extvrsn = XRSC_VRSN_ORCS;
|
|
xrsc_header->rsh_object = header->rsh_object;
|
|
xrsc_header->rsh_tedinfo = header->rsh_tedinfo;
|
|
xrsc_header->rsh_iconblk = header->rsh_iconblk;
|
|
xrsc_header->rsh_bitblk = header->rsh_bitblk;
|
|
xrsc_header->rsh_frstr = header->rsh_frstr;
|
|
xrsc_header->rsh_string = header->rsh_string;
|
|
xrsc_header->rsh_imdata = header->rsh_imdata;
|
|
xrsc_header->rsh_frimg = header->rsh_frimg;
|
|
xrsc_header->rsh_trindex = header->rsh_trindex;
|
|
xrsc_header->rsh_nobs = header->rsh_nobs;
|
|
xrsc_header->rsh_ntree = header->rsh_ntree;
|
|
xrsc_header->rsh_nted = header->rsh_nted;
|
|
xrsc_header->rsh_nib = header->rsh_nib;
|
|
xrsc_header->rsh_nbb = header->rsh_nbb;
|
|
xrsc_header->rsh_nstring = header->rsh_nstring;
|
|
xrsc_header->rsh_nimages = header->rsh_nimages;
|
|
xrsc_header->rsh_rssize = header->rsh_rssize;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void std_palette(table4 palette)
|
|
{
|
|
_WORD color;
|
|
|
|
for (color = 0; color < XMAX_COLOR; color++)
|
|
{
|
|
vq_color(xvdi_handle, pixtbl[color], 1, palette[color]);
|
|
palette[color][3] = pixtbl[color];
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Test how many bytes per pixel are needed in device-dependent format */
|
|
/*****************************************************************************/
|
|
|
|
static _WORD test_rez(void)
|
|
{
|
|
_WORD i, np, color, bpp = 0;
|
|
_WORD pxy[8], rgb[3];
|
|
_UWORD backup[XMAX_PLANES], test[XMAX_PLANES], test2[XMAX_PLANES];
|
|
_WORD black[3] = { 0, 0, 0 };
|
|
_WORD white[3] = { 1000, 1000, 1000 };
|
|
MFDB screen;
|
|
MFDB pixel;
|
|
MFDB stdfm;
|
|
|
|
pixel.fd_addr = NULL;
|
|
pixel.fd_w = 16;
|
|
pixel.fd_h = 1;
|
|
pixel.fd_wdwidth = 1;
|
|
pixel.fd_stand = FALSE;
|
|
pixel.fd_nplanes = xscrn_planes;
|
|
pixel.fd_r1 = 0;
|
|
pixel.fd_r2 = 0;
|
|
pixel.fd_r3 = 0;
|
|
stdfm = pixel;
|
|
stdfm.fd_stand = TRUE;
|
|
|
|
if (xscrn_planes >= 8)
|
|
{
|
|
if (xscrn_planes == 8)
|
|
{
|
|
color = 0xff;
|
|
memset(test, 0, sizeof(test));
|
|
memset(test2, 0, sizeof(test2));
|
|
for (np = 0; np < xscrn_planes; np++)
|
|
test2[np] = (color & (1 << np)) << (15 - np);
|
|
|
|
pixel.fd_addr = test;
|
|
stdfm.fd_addr = test2;
|
|
vr_trnfm(xvdi_handle, &stdfm, &pixel);
|
|
|
|
for (i = 1; i < xscrn_planes; i++)
|
|
if (test[i])
|
|
break;
|
|
|
|
if (i >= xscrn_planes && !(test[0] & 0x00ff))
|
|
bpp = 1;
|
|
} else
|
|
{
|
|
_WORD lineattrib[6];
|
|
_WORD clip[5];
|
|
|
|
save_lineattr(xvdi_handle, lineattrib);
|
|
save_clip(xvdi_handle, clip);
|
|
|
|
scrfdb(&screen);
|
|
pxy[0] = 0;
|
|
pxy[1] = 0;
|
|
pxy[2] = screen.fd_w - 1;
|
|
pxy[3] = screen.fd_h - 1;
|
|
vs_clip(xvdi_handle, FALSE, pxy);
|
|
|
|
memset(backup, 0, sizeof(backup));
|
|
|
|
vswr_mode(xvdi_handle, MD_REPLACE);
|
|
vsl_ends(xvdi_handle, 0, 0);
|
|
vsl_type(xvdi_handle, SOLID);
|
|
vsl_width(xvdi_handle, 1);
|
|
pxy[0] = 0;
|
|
pxy[1] = 0;
|
|
pxy[2] = 0;
|
|
pxy[3] = 0;
|
|
pxy[4] = 0;
|
|
pxy[5] = 0;
|
|
pxy[6] = 0;
|
|
pxy[7] = 0;
|
|
|
|
v_hide_c(xvdi_handle);
|
|
|
|
/* save pixel */
|
|
pixel.fd_addr = backup;
|
|
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &screen, &pixel);
|
|
|
|
/* save old color */
|
|
vq_color(xvdi_handle, TEST_COLOR, 1, rgb);
|
|
|
|
/* set 1 white pixel */
|
|
vsl_color(xvdi_handle, TEST_COLOR);
|
|
vs_color(xvdi_handle, TEST_COLOR, white);
|
|
v_pline(xvdi_handle, 2, pxy);
|
|
|
|
/* fetch pixel value */
|
|
memset(test, 0, sizeof(test));
|
|
pixel.fd_addr = test;
|
|
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &screen, &pixel);
|
|
|
|
for (i = ((xscrn_planes + 15) >> 4) * 2; i < xscrn_planes; i++)
|
|
if (test[i])
|
|
break;
|
|
|
|
if (i >= xscrn_planes)
|
|
{
|
|
vs_color(xvdi_handle, TEST_COLOR, black);
|
|
v_pline(xvdi_handle, 2, pxy);
|
|
|
|
memset(test, 0, sizeof(test));
|
|
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &screen, &pixel);
|
|
|
|
for (i = ((xscrn_planes + 15) >> 4) * 2; i < xscrn_planes; i++)
|
|
if (test[i])
|
|
break;
|
|
|
|
if (i >= xscrn_planes)
|
|
bpp = (xscrn_planes + 7) >> 3;
|
|
}
|
|
|
|
/* restore old color */
|
|
vs_color(xvdi_handle, TEST_COLOR, rgb);
|
|
|
|
/* restore saved pixel */
|
|
pixel.fd_addr = backup;
|
|
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &pixel, &screen);
|
|
|
|
restore_lineattr(xvdi_handle, lineattrib);
|
|
restore_clip(xvdi_handle, clip);
|
|
|
|
v_show_c(xvdi_handle, 1);
|
|
}
|
|
}
|
|
|
|
return bpp;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* determine pixel values for the selected palette */
|
|
/*****************************************************************************/
|
|
static void xfill_colortbl(void)
|
|
{
|
|
_WORD np, color, backup[XMAX_PLANES * 4];
|
|
_WORD pxy[8], rgb[3];
|
|
MFDB screen;
|
|
MFDB pixel;
|
|
MFDB stdfm;
|
|
_UWORD pixel_data[XMAX_PLANES];
|
|
_UWORD pixel_data2[XMAX_PLANES];
|
|
|
|
pixel.fd_addr = NULL;
|
|
pixel.fd_w = 16;
|
|
pixel.fd_h = 1;
|
|
pixel.fd_wdwidth = 1;
|
|
pixel.fd_stand = FALSE;
|
|
pixel.fd_nplanes = xscrn_planes;
|
|
pixel.fd_r1 = 0;
|
|
pixel.fd_r2 = 0;
|
|
pixel.fd_r3 = 0;
|
|
stdfm = pixel;
|
|
stdfm.fd_stand = TRUE;
|
|
|
|
if (xscrn_planes >= 8)
|
|
{
|
|
if (xscrn_planes > 8)
|
|
{
|
|
_WORD lineattrib[6];
|
|
_WORD clip[5];
|
|
|
|
save_lineattr(xvdi_handle, lineattrib);
|
|
save_clip(xvdi_handle, clip);
|
|
|
|
scrfdb(&screen);
|
|
|
|
pxy[0] = 0;
|
|
pxy[1] = 0;
|
|
pxy[2] = screen.fd_w - 1;
|
|
pxy[3] = screen.fd_h - 1;
|
|
vs_clip(xvdi_handle, TRUE, pxy);
|
|
v_hide_c(xvdi_handle);
|
|
|
|
if (xpixelbytes == 0 && colortbl == NULL)
|
|
{
|
|
colortbl = (_WORD *)malloc(xscrn_planes * XMAX_COLOR * sizeof(_WORD));
|
|
}
|
|
|
|
memset(backup, 0, sizeof(backup));
|
|
if (colortbl != NULL)
|
|
memset(colortbl, 0, xscrn_planes * XMAX_COLOR * sizeof(_WORD));
|
|
|
|
vswr_mode(xvdi_handle, MD_REPLACE);
|
|
vsl_ends(xvdi_handle, 0, 0);
|
|
vsl_type(xvdi_handle, SOLID);
|
|
vsl_width(xvdi_handle, 1);
|
|
|
|
/* save pixel value */
|
|
memset(pxy, 0, sizeof(pxy));
|
|
pxy[2] = 1;
|
|
pxy[6] = 1;
|
|
pixel.fd_addr = backup;
|
|
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &screen, &pixel);
|
|
pxy[6] = 0;
|
|
|
|
/* save old color */
|
|
vq_color(xvdi_handle, TEST_COLOR, 1, rgb);
|
|
|
|
for (color = 0; color < XMAX_COLOR; color++)
|
|
{
|
|
vs_color(xvdi_handle, TEST_COLOR, rgb_palette[color]);
|
|
vsl_color(xvdi_handle, TEST_COLOR);
|
|
pxy[2] = 1;
|
|
v_pline(xvdi_handle, 2, pxy);
|
|
|
|
pixel.fd_addr = pixel_data;
|
|
stdfm.fd_addr = pixel_data2;
|
|
|
|
/* vro_cpyfm, because v_get_pixel does not work for TrueColor */
|
|
pxy[2] = 0;
|
|
memset(pixel_data, 0, sizeof(pixel_data));
|
|
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &screen, &pixel);
|
|
|
|
if (xpixelbytes != 0)
|
|
{
|
|
colortbl2[color] = 0L;
|
|
memcpy(&colortbl2[color], pixel.fd_addr, xpixelbytes);
|
|
} else
|
|
{
|
|
memset(pixel_data2, 0, sizeof(pixel_data2));
|
|
vr_trnfm(xvdi_handle, &pixel, &stdfm);
|
|
for (np = 0; np < xscrn_planes; np++)
|
|
if (pixel_data2[np])
|
|
pixel_data2[np] = 0xffff;
|
|
if (colortbl != NULL)
|
|
memcpy(&colortbl[color * xscrn_planes], pixel_data2, xscrn_planes * sizeof(_WORD));
|
|
}
|
|
}
|
|
|
|
/* restore old color */
|
|
vs_color(xvdi_handle, TEST_COLOR, rgb);
|
|
|
|
/* restore old pixel */
|
|
pixel.fd_addr = backup;
|
|
pxy[2] = 1;
|
|
pxy[6] = 1;
|
|
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &pixel, &screen);
|
|
|
|
/* restore line attributes */
|
|
restore_lineattr(xvdi_handle, lineattrib);
|
|
restore_clip(xvdi_handle, clip);
|
|
|
|
v_show_c(xvdi_handle, 1);
|
|
} else
|
|
{
|
|
if (xpixelbytes != 0)
|
|
for (color = 0; color < XMAX_COLOR; color++)
|
|
*(unsigned char *)&colortbl2[color] = color;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* std_to_byte converts an image from standard format to device dependent */
|
|
/* format (for resolutions >= 16 Planes) */
|
|
/*****************************************************************************/
|
|
|
|
static void std_to_byte(_UWORD *col_data, _LONG len, _WORD old_planes, _ULONG *colortbl2, MFDB *s)
|
|
{
|
|
_LONG x, i, pos;
|
|
_UWORD np, *new_data, pixel, color, back[XMAX_PLANES];
|
|
_WORD memflag = FALSE;
|
|
unsigned char *p1, *p2;
|
|
_ULONG colback = 0;
|
|
_UWORD *plane_ptr[XMAX_PLANES];
|
|
|
|
if ((s->fd_addr = (_UWORD *)malloc(len * 2 * s->fd_nplanes)) == NULL)
|
|
{
|
|
return;
|
|
}
|
|
memcpy(s->fd_addr, col_data, len * 2 * old_planes);
|
|
new_data = (_UWORD *)s->fd_addr;
|
|
p1 = (unsigned char *)new_data;
|
|
|
|
if (old_planes < 8)
|
|
{
|
|
colback = colortbl2[(1 << old_planes) - 1];
|
|
colortbl2[(1 << old_planes) - 1] = colortbl2[XMAX_COLOR - 1];
|
|
}
|
|
|
|
for (i = 0; i < old_planes; i++)
|
|
plane_ptr[i] = &col_data[i * len];
|
|
|
|
pos = 0;
|
|
|
|
for (x = 0; x < len; x++)
|
|
{
|
|
for (np = 0; np < old_planes; np++)
|
|
back[np] = plane_ptr[np][x];
|
|
|
|
for (pixel = 0; pixel < 16; pixel++)
|
|
{
|
|
color = 0;
|
|
for (np = 0; np < old_planes; np++)
|
|
{
|
|
color |= ((back[np] & 0x8000) >> (15 - np));
|
|
back[np] <<= 1;
|
|
}
|
|
|
|
switch (xpixelbytes)
|
|
{
|
|
case 2:
|
|
new_data[pos++] = *(_UWORD *) &colortbl2[color];
|
|
break;
|
|
|
|
case 3:
|
|
p2 = (unsigned char *) &colortbl2[color];
|
|
*(p1++) = *(p2++);
|
|
*(p1++) = *(p2++);
|
|
*(p1++) = *(p2++);
|
|
break;
|
|
|
|
case 4:
|
|
((_ULONG *)new_data)[pos++] = colortbl2[color];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (old_planes < 8)
|
|
colortbl2[(1 << old_planes) - 1] = colback;
|
|
|
|
if (memflag)
|
|
free(col_data);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static _BOOL W_Cicon_Setpalette(_WORD *palette)
|
|
{
|
|
_BOOL need_recalc = FALSE;
|
|
|
|
if (palette != NULL)
|
|
{
|
|
_WORD i;
|
|
table4 palbuf;
|
|
|
|
std_palette(palbuf);
|
|
is_std_palette = TRUE;
|
|
|
|
for (i = 0; i < XMAX_COLOR; i++)
|
|
{
|
|
if (rgb_palette[i][0] != palette[0] ||
|
|
rgb_palette[i][1] != palette[1] ||
|
|
rgb_palette[i][2] != palette[2])
|
|
need_recalc = TRUE;
|
|
if (palbuf[i][0] != palette[0] ||
|
|
palbuf[i][1] != palette[1] ||
|
|
palbuf[i][2] != palette[2])
|
|
is_std_palette = FALSE;
|
|
rgb_palette[i][0] = *palette++;
|
|
rgb_palette[i][1] = *palette++;
|
|
rgb_palette[i][2] = *palette++;
|
|
rgb_palette[i][3] = *palette++;
|
|
}
|
|
} else
|
|
{
|
|
need_recalc = !is_std_palette;
|
|
std_palette(rgb_palette);
|
|
is_std_palette = TRUE;
|
|
}
|
|
if (xpixelbytes < 0)
|
|
{
|
|
xpixelbytes = test_rez();
|
|
need_recalc = TRUE;
|
|
}
|
|
if (need_recalc)
|
|
xfill_colortbl();
|
|
return TRUE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
/******************************************************************************/
|
|
|
|
static void *rs_load(const char *filename)
|
|
{
|
|
register _UWORD UObj;
|
|
register CICONBLK *cicon_p;
|
|
RSXHDR xrsc_header;
|
|
unsigned char *buf = NULL;
|
|
FILE *fp;
|
|
_ULONG filesize;
|
|
|
|
cicon_p = NULL;
|
|
{
|
|
char fname_buf[128];
|
|
|
|
strncpy(fname_buf, filename, sizeof(fname_buf));
|
|
fname_buf[sizeof(fname_buf) - 1] = '\0';
|
|
if (!shel_find(fname_buf) || (fp = fopen(fname_buf, "rb")) == NULL)
|
|
{
|
|
form_error(2); /* ENOENT */
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
{
|
|
struct stat st;
|
|
|
|
if (fstat(fileno(fp), &st) < 0)
|
|
{
|
|
fclose(fp);
|
|
return NULL;
|
|
}
|
|
filesize = st.st_size;
|
|
}
|
|
|
|
if ((buf = (unsigned char *)malloc((size_t)filesize)) == NULL)
|
|
{
|
|
fclose(fp);
|
|
form_error(8); /* ENOMEM */
|
|
return NULL;
|
|
}
|
|
if (fread(buf, 1, (size_t)filesize, fp) != filesize)
|
|
{
|
|
free(buf);
|
|
fclose(fp);
|
|
return NULL;
|
|
}
|
|
fclose(fp);
|
|
|
|
if (!IS_XRSC_HEADER(buf))
|
|
xrsrc_hdr2xrsc(&xrsc_header, (RSHDR *)buf);
|
|
else
|
|
xrsc_header = *((RSXHDR *)buf);
|
|
|
|
if (xrsc_header.rsh_vrsn & RSC_EXT_FLAG)
|
|
{
|
|
_LONG *p;
|
|
_BOOL ok = TRUE;
|
|
|
|
p = (_LONG *)(buf + (size_t)xrsc_header.rsh_rssize);
|
|
if ((_ULONG)p[RSC_EXT_FILESIZE] != filesize)
|
|
{
|
|
ok = FALSE;
|
|
} else if (p[RSC_EXT_CICONBLK] < 0 || (_ULONG)p[RSC_EXT_CICONBLK] >= filesize)
|
|
{
|
|
ok = FALSE;
|
|
} else
|
|
{
|
|
_LONG *cp = p + RSC_EXT_CICONBLK + 1;
|
|
|
|
while (ok != FALSE)
|
|
{
|
|
if ((_ULONG)((unsigned char *)cp - buf) >= filesize)
|
|
ok = FALSE;
|
|
else if (*cp == 0)
|
|
break;
|
|
else if (*cp != -1)
|
|
{
|
|
/* ok = FALSE; */
|
|
if (cp == (p + RSC_EXT_PALETTE))
|
|
{
|
|
_WORD *palette = (_WORD *)(buf + (size_t)(*cp));
|
|
W_Cicon_Setpalette(palette);
|
|
}
|
|
break;
|
|
}
|
|
cp++;
|
|
}
|
|
}
|
|
|
|
if (ok != FALSE)
|
|
{
|
|
p = (_LONG *)(buf + (size_t)p[RSC_EXT_CICONBLK]);
|
|
while (ok != FALSE)
|
|
{
|
|
if ((_ULONG)((unsigned char *)p - buf) >= filesize)
|
|
ok = FALSE;
|
|
else if (*p == -1)
|
|
break;
|
|
else if (*p != 0)
|
|
ok = FALSE;
|
|
else
|
|
p++;
|
|
}
|
|
if (ok != FALSE && *p == -1)
|
|
{
|
|
p++;
|
|
cicon_p = (CICONBLK *)p;
|
|
}
|
|
}
|
|
if (ok == FALSE)
|
|
{
|
|
free(buf);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
{
|
|
OBJECT *_rs_object;
|
|
|
|
_rs_object = (OBJECT *)(buf + (size_t)xrsc_header.rsh_object);
|
|
rsc_obfix(_rs_object, xrsc_header.rsh_nobs);
|
|
for (UObj = 0; UObj < xrsc_header.rsh_nobs; UObj++)
|
|
{
|
|
switch (_rs_object->ob_type & 0xff)
|
|
{
|
|
case G_BOX:
|
|
case G_IBOX:
|
|
case G_BOXCHAR:
|
|
case G_EXTBOX:
|
|
break;
|
|
case G_STRING:
|
|
case G_TITLE:
|
|
case G_BUTTON:
|
|
case G_TEXT:
|
|
case G_FTEXT:
|
|
case G_BOXTEXT:
|
|
case G_FBOXTEXT:
|
|
case G_IMAGE:
|
|
case G_ICON:
|
|
_rs_object->ob_spec.free_string = (char *)buf + (size_t)(_rs_object->ob_spec.index);
|
|
break;
|
|
case G_SHORTCUT:
|
|
/* not changed to G_STRING here;
|
|
might be displayed in window
|
|
where we use our own functions
|
|
*/
|
|
_rs_object->ob_spec.free_string = (char *)buf + (size_t)(_rs_object->ob_spec.index);
|
|
break;
|
|
case G_CICON:
|
|
|
|
if (cicon_p == NULL)
|
|
{
|
|
/* !!! */
|
|
} else
|
|
{
|
|
CICON *dp;
|
|
CICONBLK *cicon;
|
|
_LONG size;
|
|
unsigned char *p;
|
|
_LONG num_cicons;
|
|
_LONG idx;
|
|
|
|
cicon = cicon_p;
|
|
cicon_p++;
|
|
_rs_object->ob_spec.ciconblk = cicon;
|
|
size = ((cicon->monoblk.ib_wicon + 15) / 16) * 2l * cicon->monoblk.ib_hicon;
|
|
p = (unsigned char *)cicon_p;
|
|
cicon->monoblk.ib_pdata = (_WORD *)p;
|
|
p += (size_t)size;
|
|
cicon->monoblk.ib_pmask = (_WORD *)p;
|
|
p += (size_t)size;
|
|
idx = (_LONG)cicon->monoblk.ib_ptext;
|
|
if (idx <= 0 || (buf + (size_t)idx) == p || idx < (_LONG)xrsc_header.rsh_string || idx >= (_LONG)xrsc_header.rsh_rssize)
|
|
cicon->monoblk.ib_ptext = (char *)p;
|
|
else
|
|
cicon->monoblk.ib_ptext = (char *)buf + (size_t)idx;
|
|
p += 12; /* skip reserved space for icon text */
|
|
dp = (CICON *)p;
|
|
num_cicons = (_LONG)(cicon->mainlist);
|
|
if (p > (buf + (size_t)filesize))
|
|
{
|
|
free(buf);
|
|
return NULL;
|
|
}
|
|
if (num_cicons == 0)
|
|
{
|
|
cicon->mainlist = NULL;
|
|
} else
|
|
{
|
|
cicon->mainlist = dp;
|
|
while (num_cicons != 0)
|
|
{
|
|
p += sizeof(CICON);
|
|
dp->col_data = (_WORD *)p;
|
|
p += (size_t)(size * dp->num_planes);
|
|
dp->col_mask = (_WORD *)p;
|
|
p += (size_t)size;
|
|
if (dp->sel_data != NULL)
|
|
{
|
|
dp->sel_data = (_WORD *)p;
|
|
p += (size_t)(size * dp->num_planes);
|
|
dp->sel_mask = (_WORD *)p;
|
|
p += (size_t)size;
|
|
} else
|
|
{
|
|
dp->sel_data = NULL;
|
|
dp->sel_mask = NULL;
|
|
}
|
|
num_cicons--;
|
|
if (num_cicons == 0)
|
|
{
|
|
dp->next_res = NULL;
|
|
} else
|
|
{
|
|
dp->next_res = (CICON *)p;
|
|
}
|
|
dp = (CICON *)p;
|
|
}
|
|
}
|
|
cicon_p = (CICONBLK *)p;
|
|
}
|
|
break;
|
|
case G_USERDEF:
|
|
_rs_object->ob_spec.userblk = (USERBLK *)(buf + (size_t)_rs_object->ob_spec.index);
|
|
/*
|
|
* It's up to the application to set the appropiate function.
|
|
* To be on the safe side, let it point to some function
|
|
* that draws a box only, or simply does nothing.
|
|
*/
|
|
_rs_object->ob_spec.userblk->ub_code = draw_nothing;
|
|
break;
|
|
}
|
|
_rs_object++;
|
|
}
|
|
}
|
|
|
|
{
|
|
TEDINFO *_rs_tedinfo;
|
|
|
|
_rs_tedinfo = (TEDINFO *)(buf + (size_t)xrsc_header.rsh_tedinfo);
|
|
for (UObj = 0; UObj < xrsc_header.rsh_nted; UObj++)
|
|
{
|
|
_rs_tedinfo->te_ptext += (size_t)buf;
|
|
_rs_tedinfo->te_ptmplt += (size_t)buf;
|
|
_rs_tedinfo->te_pvalid += (size_t)buf;
|
|
_rs_tedinfo++;
|
|
}
|
|
}
|
|
|
|
{
|
|
ICONBLK *_rs_iconblk;
|
|
|
|
_rs_iconblk = (ICONBLK *)(buf + (size_t)xrsc_header.rsh_iconblk);
|
|
for (UObj = 0; UObj < xrsc_header.rsh_nib; UObj++)
|
|
{
|
|
_rs_iconblk->ib_pmask = (_WORD *)(buf + (size_t)(_rs_iconblk->ib_pmask));
|
|
_rs_iconblk->ib_pdata = (_WORD *)(buf + (size_t)(_rs_iconblk->ib_pdata));
|
|
_rs_iconblk->ib_ptext = (char *)buf + (size_t)_rs_iconblk->ib_ptext;
|
|
_rs_iconblk++;
|
|
}
|
|
}
|
|
|
|
{
|
|
BITBLK *_rs_bitblk;
|
|
|
|
_rs_bitblk = (BITBLK *)(buf + (size_t)xrsc_header.rsh_bitblk);
|
|
for (UObj = 0; UObj < xrsc_header.rsh_nbb; UObj++)
|
|
{
|
|
_rs_bitblk->bi_pdata = (_WORD *)(buf + (size_t)(_rs_bitblk->bi_pdata));
|
|
_rs_bitblk++;
|
|
}
|
|
}
|
|
|
|
{
|
|
char **_rs_frstr;
|
|
|
|
_rs_frstr = (char **)(buf + (size_t)xrsc_header.rsh_frstr);
|
|
for (UObj = 0; UObj < xrsc_header.rsh_nstring; UObj++)
|
|
{
|
|
*_rs_frstr += (size_t)buf;
|
|
_rs_frstr++;
|
|
}
|
|
}
|
|
|
|
{
|
|
BITBLK **_rs_frimg;
|
|
|
|
_rs_frimg = (BITBLK **)(buf + (size_t)xrsc_header.rsh_frimg);
|
|
for (UObj = 0; UObj < xrsc_header.rsh_nimages; UObj++)
|
|
{
|
|
*_rs_frimg = (BITBLK *)(buf + (size_t)(*_rs_frimg));
|
|
_rs_frimg++;
|
|
}
|
|
}
|
|
|
|
{
|
|
OBJECT **_rs_trindex;
|
|
|
|
_rs_trindex = (OBJECT **)(buf + (size_t)xrsc_header.rsh_trindex);
|
|
#if 0
|
|
/*
|
|
* settings these variables in the global array
|
|
* would actually allow using rsrc_gaddr(),
|
|
* but rsrc_free() might bomb since we did not use rsrc_load before
|
|
*/
|
|
_AESrscfile = _rs_trindex;
|
|
_AESrscmem = buf;
|
|
#endif
|
|
for (UObj = 0; UObj < xrsc_header.rsh_ntree; UObj++)
|
|
{
|
|
*_rs_trindex = (OBJECT *)(buf + (size_t)(*_rs_trindex));
|
|
_rs_trindex++;
|
|
}
|
|
}
|
|
|
|
{
|
|
OBJECT *_rs_object;
|
|
|
|
_rs_object = (OBJECT *)(buf + (size_t)xrsc_header.rsh_object);
|
|
hfix_objs((RSHDR *)buf, _rs_object, (_WORD)xrsc_header.rsh_nobs);
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Convert icon data to current resolution */
|
|
/* (e.g. 4 Plane Icon to 24 Plane TrueColor) */
|
|
/*****************************************************************************/
|
|
|
|
static _BOOL xfix_cicon(_UWORD *col_data, _LONG len, _WORD old_planes, _WORD new_planes, MFDB *s)
|
|
{
|
|
_LONG x, i, old_len, rest_len, new_len;
|
|
_UWORD np, *new_data, mask, pixel, bit, color, back[XMAX_PLANES];
|
|
MFDB d;
|
|
|
|
len >>= 1;
|
|
|
|
s->fd_nplanes = new_planes;
|
|
if (old_planes == new_planes)
|
|
{
|
|
d = *s;
|
|
d.fd_stand = FALSE;
|
|
s->fd_addr = col_data;
|
|
if ((d.fd_addr = malloc(len * 2 * new_planes)) == NULL)
|
|
d.fd_addr = s->fd_addr;
|
|
|
|
vr_trnfm(xvdi_handle, s, &d);
|
|
if (d.fd_addr != s->fd_addr)
|
|
{
|
|
memcpy(s->fd_addr, d.fd_addr, len * 2 * new_planes);
|
|
free(d.fd_addr);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
old_len = old_planes * len;
|
|
new_len = new_planes * len;
|
|
rest_len = new_len - old_len;
|
|
if (new_planes <= 8)
|
|
{
|
|
s->fd_addr = malloc(new_len * 2);
|
|
if (s->fd_addr != NULL)
|
|
{
|
|
new_data = &((_UWORD *)s->fd_addr)[old_len];
|
|
memset(new_data, 0, rest_len * 2);
|
|
memcpy(s->fd_addr, col_data, old_len * 2);
|
|
|
|
col_data = (_UWORD *)s->fd_addr;
|
|
|
|
for (x = 0; x < len; x++)
|
|
{
|
|
mask = 0xffff;
|
|
|
|
for (i = 0; i < old_len; i += len)
|
|
mask &= col_data[x + i];
|
|
|
|
if (mask)
|
|
for (i = 0; i < rest_len; i += len)
|
|
new_data[x + i] |= mask;
|
|
}
|
|
|
|
/* convert to device dependent format */
|
|
d = *s;
|
|
d.fd_stand = FALSE;
|
|
if ((d.fd_addr = malloc(len * 2 * new_planes)) == NULL)
|
|
d.fd_addr = s->fd_addr;
|
|
|
|
vr_trnfm(xvdi_handle, s, &d);
|
|
if (d.fd_addr != s->fd_addr)
|
|
{
|
|
memcpy(s->fd_addr, d.fd_addr, len * 2 * new_planes);
|
|
free(d.fd_addr);
|
|
}
|
|
}
|
|
} else
|
|
{
|
|
/* TrueColor */
|
|
if (xpixelbytes == 0)
|
|
{
|
|
s->fd_addr = NULL;
|
|
if (colortbl != NULL)
|
|
{
|
|
_UWORD *plane_ptr[XMAX_PLANES], *pos;
|
|
_UWORD old_col[XMAX_PLANES];
|
|
_UWORD maxcol = 0;
|
|
|
|
if (old_planes < 8)
|
|
{
|
|
maxcol = (1 << old_planes) - 1;
|
|
memcpy(old_col, &colortbl[maxcol * new_planes], new_planes * sizeof(_WORD));
|
|
memset(&colortbl[maxcol * new_planes], 0, new_planes * sizeof(_WORD));
|
|
}
|
|
|
|
if ((new_data = (_UWORD *)malloc(len * 2 * new_planes)) != NULL)
|
|
{
|
|
_WORD *colp;
|
|
|
|
memcpy(new_data, col_data, old_len * 2);
|
|
memset(new_data + old_len, 0, rest_len * 2);
|
|
|
|
for (i = 0; i < new_planes; i++)
|
|
plane_ptr[i] = &new_data[i * len];
|
|
|
|
for (x = 0; x < len; x++)
|
|
{
|
|
bit = 1;
|
|
for (np = 0; np < old_planes; np++)
|
|
back[np] = plane_ptr[np][x];
|
|
|
|
for (pixel = 0; pixel < 16; pixel++)
|
|
{
|
|
color = 0;
|
|
for (np = 0; np < old_planes; np++)
|
|
{
|
|
color += ((back[np] & 1) << np);
|
|
back[np] >>= 1;
|
|
}
|
|
|
|
colp = &colortbl[color * new_planes];
|
|
for (np = 0; np < new_planes; np++)
|
|
{
|
|
pos = plane_ptr[np] + x;
|
|
*pos = (*pos & ~bit) | (colp[np] & bit);
|
|
}
|
|
|
|
bit <<= 1;
|
|
}
|
|
}
|
|
if (old_planes < 8)
|
|
memcpy(&colortbl[maxcol * new_planes], old_col, new_planes * sizeof(_WORD));
|
|
|
|
/* convert to device dependent format */
|
|
d = *s;
|
|
s->fd_addr = new_data;
|
|
d.fd_stand = FALSE;
|
|
if ((d.fd_addr = malloc(len * 2 * new_planes)) == NULL)
|
|
d.fd_addr = s->fd_addr;
|
|
|
|
vr_trnfm(xvdi_handle, s, &d);
|
|
if (d.fd_addr != s->fd_addr)
|
|
{
|
|
memcpy(s->fd_addr, d.fd_addr, len * 2 * new_planes);
|
|
free(d.fd_addr);
|
|
}
|
|
}
|
|
}
|
|
} else
|
|
{
|
|
std_to_byte(col_data, len, old_planes, colortbl2, s);
|
|
}
|
|
}
|
|
if (s->fd_addr == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void xfix_make_selmask(_WORD w, _WORD h, void *dst, const void *src)
|
|
{
|
|
_UWORD mask = 0x5555;
|
|
_WORD x, y;
|
|
_UWORD *d = (_UWORD *)dst;
|
|
const _UWORD *s = (const _UWORD *)src;
|
|
|
|
w = (w + 15) >> 4;
|
|
for (y = h; --y >= 0;)
|
|
{
|
|
for (x = w; --x >= 0; )
|
|
*d++ = (*s++) & mask;
|
|
mask = ~mask;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
/******************************************************************************/
|
|
|
|
#if USE_NICELINES
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void rect2pxy(const GRECT *gr, _WORD *pxy, _WORD max_w, _WORD max_h)
|
|
{
|
|
xywh2pxy(gr->g_x, gr->g_y, gr->g_w, gr->g_h, pxy, max_w, max_h);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static _WORD _CDECL draw_niceline(PARMBLK *pb)
|
|
{
|
|
GRECT gr;
|
|
GRECT clip;
|
|
_WORD pxy[4];
|
|
_WORD aes_clip[5];
|
|
|
|
save_clip(aes_handle, aes_clip);
|
|
set_user_clip(aes_handle, pb);
|
|
|
|
gr.g_x = pb->pb_x;
|
|
gr.g_y = pb->pb_y + pb->pb_h / 2 - 1;
|
|
gr.g_w = pb->pb_w;
|
|
gr.g_h = 2;
|
|
clip.g_x = pb->pb_xc;
|
|
clip.g_y = pb->pb_yc;
|
|
clip.g_w = pb->pb_wc;
|
|
clip.g_h = pb->pb_hc;
|
|
if (rc_intersect(&clip, &gr))
|
|
{
|
|
_WORD attrib[5];
|
|
_WORD max_w, max_h;
|
|
|
|
save_fillattr(aes_handle, attrib);
|
|
|
|
vswr_mode(aes_handle, MD_REPLACE);
|
|
vsf_perimeter(aes_handle, FALSE);
|
|
GetScreenSize(&max_w, &max_h);
|
|
rect2pxy(&gr, pxy, max_w, max_h);
|
|
if (xscrn_planes >= 4)
|
|
{
|
|
vsf_color(aes_handle, G_LBLACK);
|
|
vsf_interior(aes_handle, FIS_SOLID);
|
|
vsf_style(aes_handle, 0);
|
|
} else
|
|
{
|
|
vsf_color(aes_handle, G_BLACK);
|
|
vsf_interior(aes_handle, FIS_PATTERN);
|
|
vsf_style(aes_handle, 4);
|
|
}
|
|
vr_recfl(aes_handle, pxy);
|
|
|
|
restore_fillattr(aes_handle, attrib);
|
|
}
|
|
restore_clip(aes_handle, aes_clip);
|
|
return OS_NORMAL;
|
|
}
|
|
#endif
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void draw_small_text(char *text, _WORD *pxy)
|
|
{
|
|
_WORD extent[8];
|
|
_WORD textw, texth;
|
|
|
|
vqt_extent(aes_handle, text, extent);
|
|
textw = extent[2] - extent[0];
|
|
texth = extent[5] - extent[3];
|
|
pxy[0] += (pxy[2] - pxy[0] + 1 - textw) / 2;
|
|
pxy[1] += (pxy[3] - pxy[1] + 1 - texth) / 2;
|
|
v_gtext(aes_handle, pxy[0], pxy[1], text);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void draw_icon_text(ICONBLK *ib, _WORD xpos, _WORD ypos, _WORD selected)
|
|
{
|
|
_WORD x, y, w, h;
|
|
_WORD pxy[4];
|
|
_WORD datacol = ICOLSPEC_GET_DATACOL(ib->ib_char);
|
|
_WORD maskcol = ICOLSPEC_GET_MASKCOL(ib->ib_char);
|
|
char c[2];
|
|
_WORD max_w, max_h;
|
|
_WORD dummy;
|
|
_WORD cw, ch;
|
|
_WORD attrib[5];
|
|
_WORD textattrib[10];
|
|
|
|
save_fillattr(aes_handle, attrib);
|
|
save_textattr(aes_handle, textattrib);
|
|
|
|
GetScreenSize(&max_w, &max_h);
|
|
x = xpos + ib->ib_xtext;
|
|
y = ypos + ib->ib_ytext;
|
|
w = ib->ib_wtext;
|
|
h = ib->ib_htext;
|
|
vsf_interior(aes_handle, FIS_SOLID);
|
|
vsf_style(aes_handle, 0);
|
|
vst_height(aes_handle, 4, &dummy, &dummy, &cw, &ch);
|
|
vswr_mode(aes_handle, MD_TRANS);
|
|
if (w > 0 && h > 0 && ib->ib_ptext && *ib->ib_ptext &&
|
|
xywh2pxy(x, y, w, h, pxy, max_w, max_h))
|
|
{
|
|
if (selected)
|
|
{
|
|
vsf_color(aes_handle, datacol);
|
|
if (datacol != G_WHITE)
|
|
vr_recfl(aes_handle, pxy);
|
|
vst_color(aes_handle, maskcol);
|
|
draw_small_text(ib->ib_ptext, pxy);
|
|
} else
|
|
{
|
|
vsf_color(aes_handle, maskcol);
|
|
if (maskcol != G_WHITE)
|
|
vr_recfl(aes_handle, pxy);
|
|
vst_color(aes_handle, datacol);
|
|
draw_small_text(ib->ib_ptext, pxy);
|
|
}
|
|
}
|
|
|
|
c[0] = ib->ib_char;
|
|
c[1] = 0;
|
|
if (c[0] != 0)
|
|
{
|
|
x = xpos + ib->ib_xicon + ib->ib_xchar;
|
|
y = ypos + ib->ib_yicon + ib->ib_ychar;
|
|
if (xywh2pxy(x, y, cw, ch, pxy, max_w, max_h))
|
|
{
|
|
vst_color(aes_handle, selected ? maskcol : datacol);
|
|
v_gtext(aes_handle, pxy[0], pxy[1], c);
|
|
}
|
|
}
|
|
|
|
restore_textattr(aes_handle, textattrib);
|
|
restore_fillattr(aes_handle, attrib);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static CICON *cicon_best_match(CICONBLK *cib, _WORD planes)
|
|
{
|
|
_WORD best_match = 0;
|
|
CICON *best = NULL;
|
|
CICON *list;
|
|
|
|
for (list = cib->mainlist; list != NULL; list = list->next_res)
|
|
{
|
|
if (list->num_planes > best_match && list->num_planes <= planes)
|
|
{
|
|
best_match = list->num_planes;
|
|
best = list;
|
|
}
|
|
}
|
|
return best;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static _WORD _CDECL draw_cicon(PARMBLK *pb)
|
|
{
|
|
MFDB src, dst;
|
|
_WORD pxy[8];
|
|
struct userdef *u = (struct userdef *)pb->pb_parm;
|
|
CICONBLK *ciconblk = u->orig.ob_spec.ciconblk;
|
|
ICONBLK *ib = &ciconblk->monoblk;
|
|
_WORD x = pb->pb_x + ib->ib_xicon;
|
|
_WORD y = pb->pb_y + ib->ib_yicon;
|
|
_WORD w = ib->ib_wicon;
|
|
_WORD h = ib->ib_hicon;
|
|
_WORD datacol = ICOLSPEC_GET_DATACOL(ib->ib_char);
|
|
_WORD maskcol = ICOLSPEC_GET_MASKCOL(ib->ib_char);
|
|
_WORD colind[2];
|
|
_WORD selected = pb->pb_currstate & OS_SELECTED;
|
|
CICON *cicon;
|
|
void *pdata, *pmask;
|
|
_WORD aes_clip[5];
|
|
|
|
save_clip(aes_handle, aes_clip);
|
|
set_user_clip(aes_handle, pb);
|
|
|
|
scrfdb(&dst);
|
|
src.fd_w = w;
|
|
src.fd_h = h;
|
|
src.fd_wdwidth = (src.fd_w + 15) >> 4;
|
|
src.fd_stand = TRUE;
|
|
src.fd_nplanes = 1;
|
|
src.fd_r1 = src.fd_r2 = src.fd_r3 = 0;
|
|
if (xywh2pxy(x, y, w, h, &pxy[4], dst.fd_w, dst.fd_h))
|
|
{
|
|
pxy[0] = pxy[4] - x;
|
|
pxy[1] = pxy[5] - y;
|
|
pxy[2] = pxy[6] - x;
|
|
pxy[3] = pxy[7] - y;
|
|
|
|
cicon = ciconblk->mainlist;
|
|
if (selected)
|
|
{
|
|
if (cicon->sel_data != NULL)
|
|
{
|
|
pmask = cicon->sel_mask;
|
|
pdata = cicon->sel_data;
|
|
selected = FALSE;
|
|
} else
|
|
{
|
|
pmask = cicon->col_mask;
|
|
pdata = cicon->col_data;
|
|
|
|
/*
|
|
* for >1 planes, draw selection by darken the image
|
|
* instead of inverting, if the icon didn't have a mask
|
|
*/
|
|
if (cicon->sel_mask != NULL && cicon->num_planes > 1)
|
|
selected = 2;
|
|
}
|
|
} else
|
|
{
|
|
pmask = cicon->col_mask;
|
|
pdata = cicon->col_data;
|
|
}
|
|
|
|
src.fd_addr = pmask;
|
|
src.fd_nplanes = 1;
|
|
src.fd_stand = TRUE;
|
|
colind[0] = selected == 1 ? datacol : maskcol;
|
|
colind[1] = G_WHITE;
|
|
vrt_cpyfm(aes_handle, MD_TRANS, pxy, &src, &dst, colind);
|
|
|
|
src.fd_nplanes = cicon->num_planes;
|
|
if (src.fd_nplanes == 1)
|
|
{
|
|
src.fd_addr = pdata;
|
|
src.fd_stand = TRUE;
|
|
colind[0] = selected ? maskcol : datacol;
|
|
colind[1] = G_WHITE;
|
|
vrt_cpyfm(aes_handle, MD_TRANS, pxy, &src, &dst, colind);
|
|
} else
|
|
{
|
|
_WORD mode;
|
|
|
|
if (dst.fd_nplanes > 8)
|
|
mode = S_AND_D;
|
|
else
|
|
mode = S_OR_D;
|
|
src.fd_addr = pdata;
|
|
src.fd_stand = FALSE;
|
|
src.fd_nplanes = xscrn_planes;
|
|
vro_cpyfm(aes_handle, mode, pxy, &src, &dst);
|
|
if (selected == 2)
|
|
{
|
|
src.fd_nplanes = 1;
|
|
src.fd_addr = cicon->sel_mask;
|
|
src.fd_stand = TRUE;
|
|
colind[0] = G_BLACK;
|
|
colind[1] = G_WHITE;
|
|
vrt_cpyfm(aes_handle, MD_TRANS, pxy, &src, &dst, colind);
|
|
}
|
|
}
|
|
}
|
|
|
|
draw_icon_text(ib, pb->pb_x, pb->pb_y, selected);
|
|
|
|
restore_clip(aes_handle, aes_clip);
|
|
|
|
return pb->pb_currstate & ~OS_SELECTED;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
static void release_list(struct userdef_list *list)
|
|
{
|
|
OBJECT *tree = list->objects;
|
|
_WORD i;
|
|
|
|
for (i = 0; i < list->nuserobjs; i++)
|
|
{
|
|
tree[list->userobjs[i].obj] = list->userobjs[i].orig;
|
|
switch (list->userobjs[i].orig.ob_type & 0xff)
|
|
{
|
|
case G_CICON:
|
|
{
|
|
CICONBLK *ciconblk = list->userobjs[i].orig.ob_spec.ciconblk;
|
|
CICON *cicon;
|
|
|
|
cicon = ciconblk->mainlist;
|
|
assert(cicon != NULL);
|
|
if (cicon->num_planes > 1 && cicon->num_planes != xscrn_planes)
|
|
{
|
|
free(cicon->col_data);
|
|
if (cicon->sel_data)
|
|
free(cicon->sel_data);
|
|
}
|
|
if (cicon->num_planes > 1 && cicon->sel_data == NULL)
|
|
free(cicon->sel_mask);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (list->hdr)
|
|
{
|
|
free(list->hdr);
|
|
list->hdr = NULL;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*** Exported functions ***/
|
|
/******************************************************************************/
|
|
|
|
/*
|
|
* This function is called by inlined sources
|
|
*/
|
|
void *hfix_objs(RSHDR *hdr, OBJECT *objects, _WORD num_objs)
|
|
{
|
|
_WORD i;
|
|
_WORD num_user;
|
|
_WORD dummy;
|
|
struct userdef_list *list;
|
|
|
|
aes_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
|
|
{
|
|
_WORD wo[57];
|
|
vq_extnd(aes_handle, 1, wo);
|
|
xscrn_planes = wo[4];
|
|
}
|
|
if (xpixelbytes < 0)
|
|
{
|
|
xpixelbytes = test_rez();
|
|
std_palette(rgb_palette);
|
|
}
|
|
xfill_colortbl();
|
|
|
|
num_user = 0;
|
|
for (i = 0; i < num_objs; i++)
|
|
{
|
|
OBJECT *ob = &objects[i];
|
|
|
|
switch (ob->ob_type & 0xff)
|
|
{
|
|
case G_ICON:
|
|
break;
|
|
|
|
case G_CICON:
|
|
{
|
|
CICONBLK *cicon = ob->ob_spec.ciconblk;
|
|
|
|
if (cicon_best_match(cicon, xscrn_planes) != NULL)
|
|
++num_user;
|
|
}
|
|
break;
|
|
|
|
case G_IMAGE:
|
|
break;
|
|
|
|
case G_FTEXT:
|
|
case G_FBOXTEXT:
|
|
break;
|
|
|
|
case G_TEXT:
|
|
case G_BOXTEXT:
|
|
break;
|
|
|
|
case G_TITLE:
|
|
case G_BUTTON:
|
|
break;
|
|
|
|
case G_STRING:
|
|
case G_SHORTCUT:
|
|
#if USE_NICELINES
|
|
if ((ob->ob_state & OS_DISABLED) &&
|
|
ob->ob_spec.free_string[0] == '-')
|
|
{
|
|
num_user++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
list = (struct userdef_list *)malloc(sizeof(*list) + (num_user - 1) * sizeof(struct userdef));
|
|
if (list == NULL)
|
|
return NULL;
|
|
list->hdr = hdr;
|
|
list->objects = objects;
|
|
list->nobjs = num_objs;
|
|
list->nuserobjs = num_user;
|
|
list->next = userdefs;
|
|
userdefs = list;
|
|
|
|
#define adduser(f) \
|
|
list->userobjs[num_user].orig = *ob; \
|
|
list->userobjs[num_user].obj = i; \
|
|
list->userobjs[num_user].user.ub_code = f; \
|
|
list->userobjs[num_user].user.ub_parm = (_LONG)&list->userobjs[num_user]; \
|
|
ob->ob_type = G_USERDEF; \
|
|
ob->ob_spec.userblk = &list->userobjs[num_user].user; \
|
|
num_user++
|
|
|
|
num_user = 0;
|
|
for (i = 0; i < num_objs; i++)
|
|
{
|
|
OBJECT *ob = &objects[i];
|
|
|
|
switch (ob->ob_type & 0xff)
|
|
{
|
|
case G_ICON:
|
|
break;
|
|
|
|
case G_CICON:
|
|
{
|
|
CICONBLK *ciconblk = ob->ob_spec.ciconblk;
|
|
CICON *cicon;
|
|
MFDB d;
|
|
_LONG len;
|
|
|
|
cicon = cicon_best_match(ciconblk, xscrn_planes);
|
|
if (cicon != NULL)
|
|
{
|
|
if (cicon->num_planes > 1)
|
|
{
|
|
d.fd_w = ciconblk->monoblk.ib_wicon;
|
|
d.fd_h = ciconblk->monoblk.ib_hicon;
|
|
d.fd_wdwidth = (d.fd_w + 15) >> 4;
|
|
d.fd_stand = TRUE;
|
|
d.fd_nplanes = xscrn_planes;
|
|
len = (_LONG) d.fd_wdwidth * 2l * d.fd_h;
|
|
|
|
xfix_cicon((_UWORD *)cicon->col_data, len, cicon->num_planes, xscrn_planes, &d);
|
|
cicon->col_data = d.fd_addr;
|
|
if (cicon->sel_data)
|
|
{
|
|
xfix_cicon((_UWORD *)cicon->sel_data, len, cicon->num_planes, xscrn_planes, &d);
|
|
cicon->sel_data = d.fd_addr;
|
|
} else
|
|
{
|
|
/* prepare darken mask */
|
|
cicon->sel_mask = malloc(len);
|
|
if (cicon->sel_mask != NULL)
|
|
xfix_make_selmask(d.fd_w, d.fd_h, cicon->sel_mask, cicon->col_mask);
|
|
}
|
|
}
|
|
ciconblk->mainlist = cicon;
|
|
cicon->next_res = NULL;
|
|
adduser(draw_cicon);
|
|
} else
|
|
{
|
|
ob->ob_spec.iconblk = &ciconblk->monoblk;
|
|
ob->ob_type = (ob->ob_type & 0xff00) | G_ICON;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case G_IMAGE:
|
|
break;
|
|
|
|
case G_FTEXT:
|
|
case G_FBOXTEXT:
|
|
break;
|
|
|
|
case G_TEXT:
|
|
case G_BOXTEXT:
|
|
break;
|
|
|
|
case G_TITLE:
|
|
case G_BUTTON:
|
|
break;
|
|
|
|
case G_STRING:
|
|
case G_SHORTCUT:
|
|
#if USE_NICELINES
|
|
if ((ob->ob_state & OS_DISABLED) &&
|
|
ob->ob_spec.free_string[0] == '-')
|
|
{
|
|
adduser(draw_niceline);
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
assert(num_user == list->nuserobjs);
|
|
#undef adduser
|
|
|
|
return list;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
RSHDR *xrsrc_load(const char *re_lpfname)
|
|
{
|
|
return rs_load(re_lpfname);
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
_WORD xrsrc_free(RSHDR *hdr)
|
|
{
|
|
struct userdef_list **list, *l;
|
|
|
|
for (list = &userdefs; (l = *list) != NULL; list = &l->next)
|
|
{
|
|
if (l->hdr == hdr)
|
|
{
|
|
*list = l->next;
|
|
release_list(l);
|
|
free(l);
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
/*
|
|
* xrsrc_gaddr: like rsrc_gaddr(), taking an extra parameter for the resource
|
|
*/
|
|
_BOOL xrsrc_gaddr(RSHDR *handle, _WORD type, _WORD idx, void *gaddr)
|
|
{
|
|
RSXHDR xrsc_header;
|
|
|
|
if (gaddr == NULL)
|
|
return FALSE;
|
|
*(void **)gaddr = NULL;
|
|
if (handle == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
if (IS_XRSC_HEADER(handle))
|
|
{
|
|
xrsc_header = *((RSXHDR *)handle);
|
|
} else
|
|
{
|
|
xrsrc_hdr2xrsc(&xrsc_header, handle);
|
|
}
|
|
switch (type)
|
|
{
|
|
case R_TREE:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_ntree)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
OBJECT **_rs_trindex = (OBJECT **)((char *)handle + (size_t)xrsc_header.rsh_trindex);
|
|
*((OBJECT **)gaddr) = _rs_trindex[idx];
|
|
}
|
|
break;
|
|
case R_OBJECT:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nobs)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
OBJECT *_rs_object = (OBJECT *)((char *)handle + (size_t)xrsc_header.rsh_object);
|
|
*((OBJECT **)gaddr) = &_rs_object[idx];
|
|
}
|
|
break;
|
|
case R_TEDINFO:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
|
|
*((TEDINFO **)gaddr) = &_rs_tedinfo[idx];
|
|
}
|
|
break;
|
|
case R_ICONBLK:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
|
|
*((ICONBLK **)gaddr) = &_rs_iconblk[idx];
|
|
}
|
|
break;
|
|
case R_BITBLK:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nbb)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
BITBLK *_rs_bitblk = (BITBLK *)((char *)handle + (size_t)xrsc_header.rsh_bitblk);
|
|
*((BITBLK **)gaddr) = &_rs_bitblk[idx];
|
|
}
|
|
break;
|
|
case R_STRING:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nstring)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
char **_rs_frstr = (char **)((char *)handle + (size_t)xrsc_header.rsh_frstr);
|
|
*((char **)gaddr) = _rs_frstr[idx];
|
|
}
|
|
break;
|
|
case R_IMAGEDATA:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nimages)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
BITBLK **_rs_frimg = (BITBLK **)((char *)handle + (size_t)xrsc_header.rsh_frimg);
|
|
*((BITBLK **)gaddr) = _rs_frimg[idx];
|
|
}
|
|
break;
|
|
case R_OBSPEC:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nobs)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
OBJECT *_rs_object = (OBJECT *)((char *)handle + (size_t)xrsc_header.rsh_object);
|
|
*((_LONG **)gaddr) = &_rs_object[idx].ob_spec.index;
|
|
}
|
|
break;
|
|
case R_TEPTEXT:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
|
|
*((char ***)gaddr) = &_rs_tedinfo[idx].te_ptext;
|
|
}
|
|
break;
|
|
case R_TEPTMPLT:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
|
|
*((char ***)gaddr) = &_rs_tedinfo[idx].te_ptmplt;
|
|
}
|
|
break;
|
|
case R_TEPVALID:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
|
|
*((char ***)gaddr) = &_rs_tedinfo[idx].te_pvalid;
|
|
}
|
|
break;
|
|
case R_IBPMASK:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
|
|
*((char ***)gaddr) = (char **)&_rs_iconblk[idx].ib_pmask;
|
|
}
|
|
break;
|
|
case R_IBPDATA:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
|
|
*((char ***)gaddr) = (char **)&_rs_iconblk[idx].ib_pdata;
|
|
}
|
|
break;
|
|
case R_IBPTEXT:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
|
|
*((char ***)gaddr) = &_rs_iconblk[idx].ib_ptext;
|
|
}
|
|
break;
|
|
case R_BIPDATA:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nbb)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
BITBLK *_rs_bitblk = (BITBLK *)((char *)handle + (size_t)xrsc_header.rsh_bitblk);
|
|
*((char ***)gaddr) = (char **)&_rs_bitblk[idx].bi_pdata;
|
|
}
|
|
break;
|
|
case R_FRSTR:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nstring)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
char **_rs_frstr = (char **)((char *)handle + (size_t)xrsc_header.rsh_frstr);
|
|
*((char ***)gaddr) = &_rs_frstr[idx];
|
|
}
|
|
break;
|
|
case R_FRIMG:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nimages)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
BITBLK **_rs_frimg = (BITBLK **)((char *)handle + (size_t)xrsc_header.rsh_frimg);
|
|
*((BITBLK ***)gaddr) = &_rs_frimg[idx];
|
|
}
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
/*
|
|
* xrsrc_gaddr: like rsrc_gaddr(), taking an extra parameter for the resource
|
|
*/
|
|
_BOOL xrsrc_saddr(RSHDR *handle, _WORD type, _WORD idx, void *saddr)
|
|
{
|
|
RSXHDR xrsc_header;
|
|
|
|
if (handle == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
if (IS_XRSC_HEADER(handle))
|
|
{
|
|
xrsc_header = *((RSXHDR *)handle);
|
|
} else
|
|
{
|
|
xrsrc_hdr2xrsc(&xrsc_header, handle);
|
|
}
|
|
switch (type)
|
|
{
|
|
case R_TREE:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_ntree)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
OBJECT **_rs_trindex = (OBJECT **)((char *)handle + (size_t)xrsc_header.rsh_trindex);
|
|
_rs_trindex[idx] = saddr;
|
|
}
|
|
break;
|
|
|
|
/*
|
|
* setting the address of an OBJECT simply does not work;
|
|
* current AES implementations (including GEM/3) trash the
|
|
* first 2 WORD of the OBJECT structure
|
|
*/
|
|
case R_OBJECT:
|
|
return FALSE;
|
|
|
|
/*
|
|
* current AES implementations (including GEM/3) set the first
|
|
* first member of the TEDINFO structure (te_ptext)
|
|
*/
|
|
case R_TEDINFO:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
|
|
_rs_tedinfo[idx].te_ptext = saddr;
|
|
}
|
|
break;
|
|
|
|
/*
|
|
* current AES implementations (including GEM/3) set the first
|
|
* first member of the ICONBLK structure (ib_pmask)
|
|
*/
|
|
case R_ICONBLK:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
|
|
_rs_iconblk[idx].ib_pmask = saddr;
|
|
}
|
|
break;
|
|
|
|
/*
|
|
* current AES implementations (including GEM/3) set the first
|
|
* first member of the BITBLK structure (ib_pdata)
|
|
*/
|
|
case R_BITBLK:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nbb)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
BITBLK *_rs_bitblk = (BITBLK *)((char *)handle + (size_t)xrsc_header.rsh_bitblk);
|
|
_rs_bitblk[idx].bi_pdata = saddr;
|
|
}
|
|
break;
|
|
|
|
/*
|
|
* setting the address of a string simply does not work;
|
|
* current AES implementations (including GEM/3) trash the
|
|
* first 4 bytes of the string
|
|
*/
|
|
case R_STRING:
|
|
return FALSE;
|
|
|
|
case R_IMAGEDATA:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nimages)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
BITBLK **_rs_frimg = (BITBLK **)((char *)handle + (size_t)xrsc_header.rsh_frimg);
|
|
_rs_frimg[idx]->bi_pdata = saddr;
|
|
}
|
|
break;
|
|
|
|
case R_OBSPEC:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nobs)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
OBJECT *_rs_object = (OBJECT *)((char *)handle + (size_t)xrsc_header.rsh_object);
|
|
_rs_object[idx].ob_spec.indirect = saddr;
|
|
}
|
|
break;
|
|
|
|
case R_TEPTEXT:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
|
|
_rs_tedinfo[idx].te_ptext = saddr;
|
|
}
|
|
break;
|
|
|
|
case R_TEPTMPLT:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
|
|
_rs_tedinfo[idx].te_ptmplt = saddr;
|
|
}
|
|
break;
|
|
case R_TEPVALID:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
|
|
_rs_tedinfo[idx].te_pvalid = saddr;
|
|
}
|
|
break;
|
|
case R_IBPMASK:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
|
|
_rs_iconblk[idx].ib_pmask = saddr;
|
|
}
|
|
break;
|
|
case R_IBPDATA:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
|
|
_rs_iconblk[idx].ib_pdata = saddr;
|
|
}
|
|
break;
|
|
case R_IBPTEXT:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
|
|
_rs_iconblk[idx].ib_ptext = saddr;
|
|
}
|
|
break;
|
|
case R_BIPDATA:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nbb)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
BITBLK *_rs_bitblk = (BITBLK *)((char *)handle + (size_t)xrsc_header.rsh_bitblk);
|
|
_rs_bitblk[idx].bi_pdata = saddr;
|
|
}
|
|
break;
|
|
case R_FRSTR:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nstring)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
char **_rs_frstr = (char **)((char *)handle + (size_t)xrsc_header.rsh_frstr);
|
|
_rs_frstr[idx] = saddr;
|
|
}
|
|
break;
|
|
case R_FRIMG:
|
|
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nimages)
|
|
{
|
|
return FALSE;
|
|
}
|
|
{
|
|
BITBLK **_rs_frimg = (BITBLK **)((char *)handle + (size_t)xrsc_header.rsh_frimg);
|
|
_rs_frimg[idx] = saddr;
|
|
}
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
_WORD xrsrc_obfix(OBJECT *re_otree, _WORD re_oobject)
|
|
{
|
|
rsc_obfix(&re_otree[re_oobject], 1);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
_BOOL init_xrsrc(void)
|
|
{
|
|
_WORD dummy;
|
|
|
|
aes_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
|
|
{
|
|
_WORD workout[57];
|
|
vq_extnd(aes_handle, 0, workout);
|
|
xscr_w = workout[0] + 1;
|
|
xscr_h = workout[1] + 1;
|
|
vq_extnd(aes_handle, 1, workout);
|
|
xscrn_planes = workout[4];
|
|
}
|
|
std_palette(rgb_palette);
|
|
is_std_palette = TRUE;
|
|
return TRUE;
|
|
}
|
|
|
|
/*** ---------------------------------------------------------------------- ***/
|
|
|
|
void term_xrsrc(void)
|
|
{
|
|
struct userdef_list *list, *next;
|
|
|
|
for (list = userdefs; list != NULL; list = next)
|
|
{
|
|
next = list->next;
|
|
release_list(list);
|
|
free(list);
|
|
}
|
|
userdefs = NULL;
|
|
free(colortbl);
|
|
colortbl = NULL;
|
|
}
|