380 lines
10 KiB
C
380 lines
10 KiB
C
/*
|
|
* Copyright (c) 1993-1995 Argonaut Technologies Limited. All rights reserved.
|
|
*
|
|
* $Id: OUTFCTY.C 1.1 1996/05/13 14:28:43 philip Exp PHILIP $
|
|
* $Locker: PHILIP $
|
|
*
|
|
* Output type methods
|
|
*/
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <windows.h>
|
|
#include <ddraw.h>
|
|
|
|
#include "drv.h"
|
|
#include "host.h"
|
|
#include "shortcut.h"
|
|
#include "brassert.h"
|
|
|
|
BR_RCS_ID("$Id: OUTFCTY.C 1.1 1996/05/13 14:28:43 philip Exp PHILIP $");
|
|
|
|
/*
|
|
* Default dispatch table for device (defined at end of file)
|
|
*/
|
|
static struct br_output_facility_dispatch outputFacilityDispatch;
|
|
|
|
// The primitive library we are going to use
|
|
extern br_primitive_library PrimitiveLibraryHardATI;
|
|
|
|
/*
|
|
* Output Type info. template
|
|
*/
|
|
#define F(f) offsetof(struct br_output_facility, f)
|
|
|
|
static struct br_tv_template_entry outputFacilityTemplateEntries[] = {
|
|
{BRT(WIDTH_I32), F(width), BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
{BRT(WIDTH_MIN_I32), F(width), BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
{BRT(WIDTH_MAX_I32), F(width), BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
{BRT(HEIGHT_I32), F(height), BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
{BRT(HEIGHT_MIN_I32), F(height), BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
{BRT(HEIGHT_MAX_I32), F(height), BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
{BRT(PIXEL_BITS_I32), F(colour_bits), BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
{BRT(PIXEL_TYPE_U8), F(colour_type), BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
{BRT(INDEXED_B), F(indexed), BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
{BRT(IDENTIFIER_CSTR),F(identifier), BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
{BRT(WINDOW_FULLSCREEN_B), F(fullscreen), BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
|
|
{BRT(PRIMITIVE_LIBRARY_O),F(prim_lib),BRTV_QUERY | BRTV_ALL, BRTV_CONV_COPY, },
|
|
|
|
{BRT_PIXELMAP_MAX_I32,0, 0, BRTV_QUERY | BRTV_ALL, BRTV_CONV_DIRECT, 1},
|
|
{BRT_CLUT_MAX_I32, 0, 0, BRTV_QUERY | BRTV_ALL, BRTV_CONV_DIRECT, 0},
|
|
{BRT(WINDOW_HANDLE_H), NULL, BRTV_QUERY | BRTV_ALL, BRTV_CONV_DIRECT, },
|
|
};
|
|
#undef F
|
|
|
|
static struct br_tv_template outputFacilityTemplate = {
|
|
BR_ASIZE(outputFacilityTemplateEntries),
|
|
outputFacilityTemplateEntries
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Display mode enumeration callback
|
|
*/
|
|
HRESULT WINAPI EnumCallbackATI(LPDDSURFACEDESC ddsd, LPVOID context)
|
|
{
|
|
void *res;
|
|
char tmp[64];
|
|
br_int_32 bits, type;
|
|
br_boolean indexed;
|
|
br_device *dev;
|
|
br_output_facility *self;
|
|
DDPIXELFORMAT *format;
|
|
|
|
dev = (br_device *)context;
|
|
|
|
/*
|
|
* Extract information from surface description
|
|
*/
|
|
format = &ddsd->ddpfPixelFormat;
|
|
if(format->dwFlags & DDPF_PALETTEINDEXED8)
|
|
return(DDENUMRET_OK);
|
|
else if((format->dwFlags & DDPF_RGB) && (format->dwRBitMask == 0x00007c00) &&
|
|
(format->dwGBitMask == 0x000003e0) && (format->dwBBitMask == 0x0000001f))
|
|
{
|
|
bits = dev->bits16 = 15;
|
|
type = BR_PMT_RGB_555;
|
|
indexed = BR_FALSE;
|
|
}
|
|
else if((format->dwFlags & DDPF_RGB) && (format->dwRBitMask == 0x0000f800) &&
|
|
(format->dwGBitMask == 0x000007e0) && (format->dwBBitMask == 0x0000001f))
|
|
{
|
|
bits = dev->bits16 = 16;
|
|
type = BR_PMT_RGB_565;
|
|
indexed = BR_FALSE;
|
|
|
|
}
|
|
#if 0
|
|
else if((format->dwFlags & DDPF_RGB) && (format->dwRBitMask == 0x00ff0000) &&
|
|
(format->dwGBitMask == 0x0000ff00) && (format->dwBBitMask == 0x000000ff) &&
|
|
(format->dwRGBBitCount == 32))
|
|
{
|
|
bits = 32;
|
|
type = BR_PMT_RGBX_888;
|
|
indexed = BR_FALSE;
|
|
}
|
|
#endif
|
|
else
|
|
return DDENUMRET_OK;
|
|
|
|
/*
|
|
* Allocate an object
|
|
*/
|
|
res = DeviceATIResource(dev);
|
|
self = BrResAllocate(res, sizeof(*self), BR_MEMORY_OBJECT);
|
|
|
|
/*
|
|
* Fill members
|
|
*/
|
|
self->num_instances = 0;
|
|
self->dispatch = &outputFacilityDispatch;
|
|
|
|
self->width = ddsd->dwWidth;
|
|
self->height = ddsd->dwHeight;
|
|
|
|
self->colour_type = type;
|
|
self->colour_bits = bits;
|
|
|
|
self->indexed = indexed;
|
|
self->fullscreen = BR_TRUE;
|
|
|
|
/* Set primitive library for hardware rendering */
|
|
self->prim_lib = (br_object*)&PrimitiveLibraryHardATI;
|
|
|
|
/*
|
|
* Attach a descriptive identifier
|
|
*/
|
|
BrSprintfN(tmp, sizeof(tmp) - 1, "F:%dx%dx%d", self->width, self->height, self->colour_bits);
|
|
self->identifier = BrResStrDup(self, tmp);
|
|
|
|
/*
|
|
* Add to list
|
|
*/
|
|
self->object_list = BrObjectListAllocate(self);
|
|
ObjectContainerAddFront(dev, (br_object *)self);
|
|
|
|
/*
|
|
* Increment counter
|
|
*/
|
|
dev->output_facility_count++;
|
|
|
|
return DDENUMRET_OK;
|
|
}
|
|
|
|
/*
|
|
* Build a list of available output facilities
|
|
*
|
|
* For the RAGE, include the windowed options only if the screen mode is
|
|
* not 8-bit.
|
|
*/
|
|
br_error OutputFacilityATIInitialise(br_device *dev)
|
|
{
|
|
void *res;
|
|
char tmp[64];
|
|
br_uint_32 bpp, width, height;
|
|
br_boolean windowed_allowed = BR_TRUE;
|
|
br_output_facility *self;
|
|
HDC dc;
|
|
|
|
/* Clear the static output facility template */
|
|
CLEAR_TEMPLATE(outputFacility);
|
|
|
|
/*
|
|
* Determine current Windows mode
|
|
*/
|
|
dc = CreateDC("DISPLAY", NULL, NULL, NULL);
|
|
bpp = GetDeviceCaps(dc, BITSPIXEL);
|
|
width = GetDeviceCaps(dc, HORZRES);
|
|
height = GetDeviceCaps(dc, VERTRES);
|
|
DeleteDC(dc);
|
|
|
|
/* ATI card can't support 8bpp windowed */
|
|
if (bpp == 8)
|
|
windowed_allowed = BR_FALSE;
|
|
|
|
|
|
if (windowed_allowed) {
|
|
/*
|
|
* Allocate an object for the current (windowed) display mode
|
|
*/
|
|
res = DeviceATIResource(dev);
|
|
self = BrResAllocate(res, sizeof(*self), BR_MEMORY_OBJECT);
|
|
|
|
/*
|
|
* Add to list as first entry and increment instance counter
|
|
*/
|
|
self->object_list = BrObjectListAllocate(self);
|
|
ObjectContainerAddFront(dev, (br_object *)self);
|
|
dev->output_facility_count++;
|
|
}
|
|
|
|
/*
|
|
* Enumerate and record available fullscreen modes: do this now, to pick
|
|
* up whether 16-bit modes are 16 or 15 bits
|
|
*/
|
|
IDirectDraw_EnumDisplayModes(gpDD, 0, NULL, dev, EnumCallbackATI);
|
|
|
|
if (windowed_allowed) {
|
|
/*
|
|
* If Windows claims that current mode is 16-bit, use the
|
|
* actual bit depth returned during the fullscreen enumeration
|
|
*/
|
|
if(bpp == 16)
|
|
bpp = dev->bits16;
|
|
|
|
/*
|
|
* Fill members of the windowed mode
|
|
*/
|
|
self->num_instances = 0;
|
|
self->dispatch = &outputFacilityDispatch;
|
|
|
|
self->width = width;
|
|
self->height = height;
|
|
|
|
self->colour_bits = bpp;
|
|
self->fullscreen = BR_FALSE;
|
|
|
|
switch(bpp) {
|
|
case 8:
|
|
self->colour_type = BR_PMT_INDEX_8;
|
|
self->indexed = BR_TRUE;
|
|
break;
|
|
|
|
case 15:
|
|
self->colour_type = BR_PMT_RGB_555;
|
|
self->indexed = BR_FALSE;
|
|
break;
|
|
|
|
case 16:
|
|
self->colour_type = BR_PMT_RGB_565;
|
|
self->indexed = BR_FALSE;
|
|
break;
|
|
|
|
case 24:
|
|
self->colour_type = BR_PMT_RGB_888;
|
|
self->indexed = BR_FALSE;
|
|
break;
|
|
}
|
|
|
|
/* Set primitive library for hardware rendering */
|
|
self->prim_lib = (br_object*)&PrimitiveLibraryHardATI;
|
|
|
|
/*
|
|
* Attach a descriptive identifier
|
|
*/
|
|
BrSprintfN(tmp, sizeof(tmp) - 1, "W:%dx%dx%d", self->width, self->height, self->colour_bits);
|
|
self->identifier = BrResStrDup(self, tmp);
|
|
}
|
|
|
|
return BRE_OK;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Common object methods
|
|
*/
|
|
static void BR_CMETHOD_DECL(br_output_facility_ati, free)(br_output_facility *self)
|
|
{
|
|
ObjectContainerRemove(ObjectDevice(self), (br_object *)self);
|
|
|
|
/* Remove attached objects */
|
|
ObjectContainerFree((br_object_container *)self, BR_NULL_TOKEN, NULL, NULL);
|
|
BrResFreeNoCallback(self);
|
|
}
|
|
|
|
static br_token BR_CMETHOD_DECL(br_output_facility_ati, type)(br_output_facility *self)
|
|
{
|
|
return BRT_OUTPUT_FACILITY;
|
|
}
|
|
|
|
static br_boolean BR_CMETHOD_DECL(br_output_facility_ati, isType)(br_output_facility *self, br_token t)
|
|
{
|
|
return (t == BRT_OUTPUT_FACILITY) || (t == BRT_OBJECT_CONTAINER) || (t == BRT_OBJECT);
|
|
}
|
|
|
|
static br_int_32 BR_CMETHOD_DECL(br_output_facility_ati, space)(br_output_facility *self)
|
|
{
|
|
return sizeof(br_output_facility);
|
|
}
|
|
|
|
static struct br_tv_template * BR_CMETHOD_DECL(br_output_facility_ati,queryTemplate)(br_output_facility *self)
|
|
{
|
|
outputFacilityTemplate.res = DeviceATIResource(ObjectATIDevice(self));
|
|
return &outputFacilityTemplate;
|
|
}
|
|
|
|
static br_error BR_CMETHOD_DECL(br_output_facility_ati, validSource)(br_output_facility *self, br_boolean *bp, br_object *h)
|
|
{
|
|
return BRE_OK;
|
|
}
|
|
|
|
/*
|
|
* br_output_facility_ati::pixelmapNew
|
|
*
|
|
* Instantiate an output pixelmap from the output type
|
|
*/
|
|
static br_error BR_CMETHOD_DECL(br_output_facility_ati, pixelmapNew)(br_output_facility *self,
|
|
br_device_pixelmap **ppmap, br_token_value *tv)
|
|
{
|
|
br_device_pixelmap *pm;
|
|
|
|
/*
|
|
* Create a device pixelmap structure representing display memory
|
|
*/
|
|
pm = DevicePixelmapATIAllocate(ObjectDevice(self), self, tv);
|
|
if(pm == NULL)
|
|
return BRE_FAIL;
|
|
|
|
*ppmap = pm;
|
|
|
|
return BRE_OK;
|
|
}
|
|
|
|
/*
|
|
* Cannot create new CLUTs, stuck with the single hardware one
|
|
*/
|
|
static br_error BR_CMETHOD_DECL(br_output_facility_ati, clutNew)(br_output_facility *self,
|
|
br_device_clut **pclut, br_token_value *tv)
|
|
{
|
|
return BRE_FAIL;
|
|
}
|
|
|
|
static void * BR_CMETHOD_DECL(br_output_facility_ati, listQuery)
|
|
(br_output_facility *self)
|
|
{
|
|
return self->object_list;
|
|
}
|
|
|
|
/*
|
|
* Default dispatch table for device
|
|
*/
|
|
static struct br_output_facility_dispatch outputFacilityDispatch = {
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
BR_CMETHOD_REF(br_output_facility_ati, free),
|
|
BR_CMETHOD_REF(br_object_ati, identifier),
|
|
BR_CMETHOD_REF(br_output_facility_ati, type),
|
|
BR_CMETHOD_REF(br_output_facility_ati, isType),
|
|
BR_CMETHOD_REF(br_object_ati, device),
|
|
BR_CMETHOD_REF(br_output_facility_ati, space),
|
|
|
|
BR_CMETHOD_REF(br_output_facility_ati, queryTemplate),
|
|
BR_CMETHOD_REF(br_object, query),
|
|
BR_CMETHOD_REF(br_object, queryBuffer),
|
|
BR_CMETHOD_REF(br_object, queryMany),
|
|
BR_CMETHOD_REF(br_object, queryManySize),
|
|
BR_CMETHOD_REF(br_object, queryAll),
|
|
BR_CMETHOD_REF(br_object, queryAllSize),
|
|
|
|
BR_CMETHOD_REF(br_output_facility_ati, listQuery),
|
|
BR_CMETHOD_REF(br_object_container, tokensMatchBegin),
|
|
BR_CMETHOD_REF(br_object_container, tokensMatch),
|
|
BR_CMETHOD_REF(br_object_container, tokensMatchEnd),
|
|
BR_CMETHOD_REF(br_object_container, addFront),
|
|
BR_CMETHOD_REF(br_object_container, removeFront),
|
|
BR_CMETHOD_REF(br_object_container, remove),
|
|
BR_CMETHOD_REF(br_object_container, find),
|
|
BR_CMETHOD_REF(br_object_container, findMany),
|
|
BR_CMETHOD_REF(br_object_container, count),
|
|
|
|
BR_CMETHOD_REF(br_output_facility_ati, validSource),
|
|
BR_CMETHOD_REF(br_output_facility_ati, pixelmapNew),
|
|
BR_CMETHOD_REF(br_output_facility_ati, clutNew),
|
|
};
|
|
|
|
|