mame/src/osd/windows/drawgdi.c
2007-12-17 15:19:59 +00:00

216 lines
5.7 KiB
C

//============================================================
//
// drawgdi.c - Win32 GDI drawing
//
// Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team.
// Visit http://mamedev.org for licensing and usage restrictions.
//
//============================================================
// standard windows headers
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// MAME headers
#include "mamecore.h"
// MAMEOS headers
#include "window.h"
//============================================================
// TYPE DEFINITIONS
//============================================================
/* gdi_info is the information for the current screen */
typedef struct _gdi_info gdi_info;
struct _gdi_info
{
BITMAPINFO bminfo;
RGBQUAD colors[256];
UINT8 * bmdata;
size_t bmsize;
};
//============================================================
// PROTOTYPES
//============================================================
// core functions
static void drawgdi_exit(void);
static int drawgdi_window_init(win_window_info *window);
static void drawgdi_window_destroy(win_window_info *window);
static const render_primitive_list *drawgdi_window_get_primitives(win_window_info *window);
static int drawgdi_window_draw(win_window_info *window, HDC dc, int update);
// rendering
static void drawgdi_rgb888_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch);
//============================================================
// drawgdi_init
//============================================================
int drawgdi_init(win_draw_callbacks *callbacks)
{
// fill in the callbacks
callbacks->exit = drawgdi_exit;
callbacks->window_init = drawgdi_window_init;
callbacks->window_get_primitives = drawgdi_window_get_primitives;
callbacks->window_draw = drawgdi_window_draw;
callbacks->window_destroy = drawgdi_window_destroy;
return 0;
}
//============================================================
// drawgdi_exit
//============================================================
static void drawgdi_exit(void)
{
}
//============================================================
// drawgdi_window_init
//============================================================
static int drawgdi_window_init(win_window_info *window)
{
gdi_info *gdi;
int i;
// allocate memory for our structures
gdi = malloc_or_die(sizeof(*gdi));
memset(gdi, 0, sizeof(*gdi));
window->drawdata = gdi;
// fill in the bitmap info header
gdi->bminfo.bmiHeader.biSize = sizeof(gdi->bminfo.bmiHeader);
gdi->bminfo.bmiHeader.biPlanes = 1;
gdi->bminfo.bmiHeader.biCompression = BI_RGB;
gdi->bminfo.bmiHeader.biSizeImage = 0;
gdi->bminfo.bmiHeader.biXPelsPerMeter = 0;
gdi->bminfo.bmiHeader.biYPelsPerMeter = 0;
gdi->bminfo.bmiHeader.biClrUsed = 0;
gdi->bminfo.bmiHeader.biClrImportant = 0;
// initialize the palette to a gray ramp
for (i = 0; i < 256; i++)
{
gdi->bminfo.bmiColors[i].rgbRed = i;
gdi->bminfo.bmiColors[i].rgbGreen = i;
gdi->bminfo.bmiColors[i].rgbBlue = i;
gdi->bminfo.bmiColors[i].rgbReserved = i;
}
return 0;
}
//============================================================
// drawgdi_window_destroy
//============================================================
static void drawgdi_window_destroy(win_window_info *window)
{
gdi_info *gdi = window->drawdata;
// skip if nothing
if (gdi == NULL)
return;
// free the bitmap memory
if (gdi->bmdata != NULL)
free(gdi->bmdata);
free(gdi);
window->drawdata = NULL;
}
//============================================================
// drawgdi_window_get_primitives
//============================================================
static const render_primitive_list *drawgdi_window_get_primitives(win_window_info *window)
{
RECT client;
GetClientRect(window->hwnd, &client);
render_target_set_bounds(window->target, rect_width(&client), rect_height(&client), winvideo_monitor_get_aspect(window->monitor));
return render_target_get_primitives(window->target);
}
//============================================================
// drawgdi_window_draw
//============================================================
static int drawgdi_window_draw(win_window_info *window, HDC dc, int update)
{
gdi_info *gdi = window->drawdata;
int width, height, pitch;
RECT bounds;
// we don't have any special resize behaviors
if (window->resize_state == RESIZE_STATE_PENDING)
window->resize_state = RESIZE_STATE_NORMAL;
// get the target bounds
GetClientRect(window->hwnd, &bounds);
// compute width/height/pitch of target
width = rect_width(&bounds);
height = rect_height(&bounds);
pitch = (width + 3) & ~3;
// make sure our temporary bitmap is big enough
if (pitch * height * 4 > gdi->bmsize)
{
gdi->bmsize = pitch * height * 4 * 2;
gdi->bmdata = realloc(gdi->bmdata, gdi->bmsize);
}
// draw the primitives to the bitmap
osd_lock_acquire(window->primlist->lock);
drawgdi_rgb888_draw_primitives(window->primlist->head, gdi->bmdata, width, height, pitch);
osd_lock_release(window->primlist->lock);
// fill in bitmap-specific info
gdi->bminfo.bmiHeader.biWidth = pitch;
gdi->bminfo.bmiHeader.biHeight = -height;
gdi->bminfo.bmiHeader.biBitCount = 32;
// blit to the screen
StretchDIBits(dc, 0, 0, width, height,
0, 0, width, height,
gdi->bmdata, &gdi->bminfo, DIB_RGB_COLORS, SRCCOPY);
return 0;
}
//============================================================
// SOFTWARE RENDERING
//============================================================
#define FUNC_PREFIX(x) drawgdi_rgb888_##x
#define PIXEL_TYPE UINT32
#define SRCSHIFT_R 0
#define SRCSHIFT_G 0
#define SRCSHIFT_B 0
#define DSTSHIFT_R 16
#define DSTSHIFT_G 8
#define DSTSHIFT_B 0
#include "rendersw.c"