Keep only DirectX Windowed driver (no fullscreen and no GDI).

This commit is contained in:
David Capello 2010-11-04 21:43:36 -03:00
parent b59b14444e
commit 0139524c15
6 changed files with 2 additions and 1410 deletions

View File

@ -96,15 +96,12 @@ set(ALLEGRO_SRC_WIN_FILES
src/win/wddbmp.c
src/win/wddbmpl.c
src/win/wddraw.c
src/win/wddfull.c
src/win/wddlock.c
src/win/wddmode.c
src/win/wddovl.c
src/win/wddwin.c
src/win/wdxver.c
src/win/wdispsw.c
src/win/wfile.c
src/win/wgdi.c
src/win/wgfxdrv.c
src/win/wkeybd.c
src/win/wmouse.c

View File

@ -82,24 +82,9 @@ AL_VAR(SYSTEM_DRIVER, system_directx);
/*************** gfx drivers ***************/
/*******************************************/
#define GFX_DIRECTX AL_ID('D','X','A','C')
#define GFX_DIRECTX_ACCEL AL_ID('D','X','A','C')
#define GFX_DIRECTX_SAFE AL_ID('D','X','S','A')
#define GFX_DIRECTX_SOFT AL_ID('D','X','S','O')
#define GFX_DIRECTX_WIN AL_ID('D','X','W','N')
#define GFX_DIRECTX_OVL AL_ID('D','X','O','V')
#define GFX_GDI AL_ID('G','D','I','B')
AL_VAR(GFX_DRIVER, gfx_directx_accel);
AL_VAR(GFX_DRIVER, gfx_directx_safe);
AL_VAR(GFX_DRIVER, gfx_directx_soft);
AL_VAR(GFX_DRIVER, gfx_directx_win);
AL_VAR(GFX_DRIVER, gfx_directx_ovl);
AL_VAR(GFX_DRIVER, gfx_gdi);
#define GFX_DRIVER_DIRECTX \
{ GFX_DIRECTX_ACCEL, &gfx_directx_accel, TRUE }, \
{ GFX_DIRECTX_SOFT, &gfx_directx_soft, TRUE }, \
{ GFX_DIRECTX_SAFE, &gfx_directx_safe, TRUE }, \
{ GFX_DIRECTX_WIN, &gfx_directx_win, TRUE }, \
{ GFX_DIRECTX_OVL, &gfx_directx_ovl, TRUE }, \
{ GFX_GDI, &gfx_gdi, FALSE },
{ GFX_DIRECTX_WIN, &gfx_directx_win, TRUE },

View File

@ -1,267 +0,0 @@
/* ______ ___ ___
* /\ _ \ /\_ \ /\_ \
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
* /\____/
* \_/__/
*
* DirectDraw gfx fullscreen drivers.
*
* By Stefan Schimanski.
*
* See readme.txt for copyright information.
*/
#include "wddraw.h"
static struct BITMAP *init_directx_accel(int w, int h, int v_w, int v_h, int color_depth);
static struct BITMAP *init_directx_soft(int w, int h, int v_w, int v_h, int color_depth);
static struct BITMAP *init_directx_safe(int w, int h, int v_w, int v_h, int color_depth);
static void finalize_fullscreen_init(void);
static void switch_in_fullscreen(void);
static void switch_out_fullscreen(void);
GFX_DRIVER gfx_directx_accel =
{
GFX_DIRECTX_ACCEL,
empty_string,
empty_string,
"DirectDraw accel",
init_directx_accel,
gfx_directx_exit,
NULL, // AL_METHOD(int, scroll, (int x, int y));
gfx_directx_sync,
gfx_directx_set_palette,
NULL, // AL_METHOD(int, request_scroll, (int x, int y));
NULL, // AL_METHOD(int, poll_scroll, (void));
NULL, // AL_METHOD(void, enable_triple_buffer, (void));
gfx_directx_create_video_bitmap,
gfx_directx_destroy_video_bitmap,
gfx_directx_show_video_bitmap,
gfx_directx_request_video_bitmap,
gfx_directx_create_system_bitmap,
gfx_directx_destroy_system_bitmap,
NULL, // AL_METHOD(int, set_mouse_sprite, (struct BITMAP *sprite, int xfocus, int yfocus));
NULL, // AL_METHOD(int, show_mouse, (struct BITMAP *bmp, int x, int y));
NULL, // AL_METHOD(void, hide_mouse, (void));
NULL, // AL_METHOD(void, move_mouse, (int x, int y));
NULL, // AL_METHOD(void, drawing_mode, (void));
NULL, // AL_METHOD(void, save_video_state, (void*));
NULL, // AL_METHOD(void, restore_video_state, (void*));
NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a));
gfx_directx_fetch_mode_list,
NULL, /* acknowledge_resize */
0, 0, // physical (not virtual!) screen size
TRUE, // true if video memory is linear
0, // bank size, in bytes
0, // bank granularity, in bytes
0, // video memory size, in bytes
0, // physical address of video memory
FALSE // true if driver runs windowed
};
GFX_DRIVER gfx_directx_soft =
{
GFX_DIRECTX_SOFT,
empty_string,
empty_string,
"DirectDraw soft",
init_directx_soft,
gfx_directx_exit,
NULL, // AL_METHOD(int, scroll, (int x, int y));
gfx_directx_sync,
gfx_directx_set_palette,
NULL, // AL_METHOD(int, request_scroll, (int x, int y));
NULL, // AL_METHOD(int, poll_scroll, (void));
NULL, // AL_METHOD(void, enable_triple_buffer, (void));
gfx_directx_create_video_bitmap,
gfx_directx_destroy_video_bitmap,
gfx_directx_show_video_bitmap,
gfx_directx_request_video_bitmap,
gfx_directx_create_system_bitmap,
gfx_directx_destroy_system_bitmap,
NULL, // AL_METHOD(int, set_mouse_sprite, (struct BITMAP *sprite, int xfocus, int yfocus));
NULL, // AL_METHOD(int, show_mouse, (struct BITMAP *bmp, int x, int y));
NULL, // AL_METHOD(void, hide_mouse, (void));
NULL, // AL_METHOD(void, move_mouse, (int x, int y));
NULL, // AL_METHOD(void, drawing_mode, (void));
NULL, // AL_METHOD(void, save_video_state, (void*));
NULL, // AL_METHOD(void, restore_video_state, (void*));
NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a));
gfx_directx_fetch_mode_list,
NULL, /* acknowledge_resize */
0, 0, // physical (not virtual!) screen size
TRUE, // true if video memory is linear
0, // bank size, in bytes
0, // bank granularity, in bytes
0, // video memory size, in bytes
0, // physical address of video memory
FALSE // true if driver runs windowed
};
GFX_DRIVER gfx_directx_safe =
{
GFX_DIRECTX_SAFE,
empty_string,
empty_string,
"DirectDraw safe",
init_directx_safe,
gfx_directx_exit,
NULL, // AL_METHOD(int, scroll, (int x, int y));
gfx_directx_sync,
gfx_directx_set_palette,
NULL, // AL_METHOD(int, request_scroll, (int x, int y));
NULL, // AL_METHOD(int, poll_scroll, (void));
NULL, // AL_METHOD(void, enable_triple_buffer, (void));
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, // AL_METHOD(int, set_mouse_sprite, (struct BITMAP *sprite, int xfocus, int yfocus));
NULL, // AL_METHOD(int, show_mouse, (struct BITMAP *bmp, int x, int y));
NULL, // AL_METHOD(void, hide_mouse, (void));
NULL, // AL_METHOD(void, move_mouse, (int x, int y));
NULL, // AL_METHOD(void, drawing_mode, (void));
NULL, // AL_METHOD(void, save_video_state, (void*));
NULL, // AL_METHOD(void, restore_video_state, (void*));
NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a));
gfx_directx_fetch_mode_list,
NULL, /* acknowledge_resize */
0, 0, // physical (not virtual!) screen size
TRUE, // true if video memory is linear
0, // bank size, in bytes
0, // bank granularity, in bytes
0, // video memory size, in bytes
0, // physical address of video memory
FALSE // true if driver runs windowed
};
static WIN_GFX_DRIVER win_gfx_fullscreen =
{
FALSE, // true if driver has backing store
switch_in_fullscreen,
switch_out_fullscreen,
NULL, // AL_METHOD(void, enter_sysmode, (void));
NULL, // AL_METHOD(void, exit_sysmode, (void));
NULL, // AL_METHOD(void, move, (int x, int y, int w, int h));
NULL, // AL_METHOD(void, iconify, (void));
NULL // AL_METHOD(void, paint, (RECT *));
};
/* When switching away from an 8-bit fullscreen program, the palette is lost.
* This stores the palette so it can be restored when switching back in.
*/
static PALETTE wddfull_saved_palette;
/* init_directx_accel:
* Initializes the DirectDraw fullscreen hardware-accelerated driver.
*/
static struct BITMAP *init_directx_accel(int w, int h, int v_w, int v_h, int color_depth)
{
struct BITMAP *bmp;
_enter_critical();
bmp = gfx_directx_init(&gfx_directx_accel, w, h, v_w, v_h, color_depth);
if (bmp) {
gfx_directx_enable_acceleration(&gfx_directx_accel);
gfx_directx_enable_triple_buffering(&gfx_directx_accel);
finalize_fullscreen_init();
}
_exit_critical();
return bmp;
}
/* init_directx_soft:
* Initializes the DirectDraw fullscreen software-only driver.
*/
static struct BITMAP *init_directx_soft(int w, int h, int v_w, int v_h, int color_depth)
{
struct BITMAP *bmp;
_enter_critical();
bmp = gfx_directx_init(&gfx_directx_soft, w, h, v_w, v_h, color_depth);
if (bmp) {
gfx_directx_enable_triple_buffering(&gfx_directx_soft);
finalize_fullscreen_init();
}
_exit_critical();
return bmp;
}
/* init_directx_safe:
* Initializes the DirectDraw fullscreen safe driver.
*/
static struct BITMAP *init_directx_safe(int w, int h, int v_w, int v_h, int color_depth)
{
struct BITMAP *bmp;
_enter_critical();
bmp = gfx_directx_init(&gfx_directx_safe, w, h, v_w, v_h, color_depth);
if (bmp)
finalize_fullscreen_init();
_exit_critical();
return bmp;
}
/* finalize_fullscreen_init:
* Finalizes initialization of the three fullscreen drivers.
*/
static void finalize_fullscreen_init(void)
{
/* connect to the system driver */
win_gfx_driver = &win_gfx_fullscreen;
/* set the default switching policy */
set_display_switch_mode(SWITCH_AMNESIA);
}
/* switch_in_fullscreen:
* Handles screen switched in.
*/
static void switch_in_fullscreen(void)
{
restore_all_ddraw_surfaces();
if (_color_depth == 8)
set_palette(wddfull_saved_palette);
}
/* switch_out_fullscreen:
* Handles screen switched out.
*/
static void switch_out_fullscreen(void)
{
if (_color_depth == 8)
get_palette(wddfull_saved_palette);
}

View File

@ -1,453 +0,0 @@
/* ______ ___ ___
* /\ _ \ /\_ \ /\_ \
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
* /\____/
* \_/__/
*
* DirectDraw overlay gfx driver.
*
* By Stefan Schimanski.
*
* See readme.txt for copyright information.
*/
#include "wddraw.h"
#define PREFIX_I "al-wddovl INFO: "
#define PREFIX_W "al-wddovl WARNING: "
#define PREFIX_E "al-wddovl ERROR: "
static int gfx_directx_show_video_bitmap_ovl(struct BITMAP *bitmap);
static int gfx_directx_request_video_bitmap_ovl(struct BITMAP *bitmap);
static struct BITMAP *init_directx_ovl(int w, int h, int v_w, int v_h, int color_depth);
static void gfx_directx_ovl_exit(struct BITMAP *b);
GFX_DRIVER gfx_directx_ovl =
{
GFX_DIRECTX_OVL,
empty_string,
empty_string,
"DirectDraw overlay",
init_directx_ovl,
gfx_directx_ovl_exit,
NULL, // AL_METHOD(int, scroll, (int x, int y));
gfx_directx_sync,
gfx_directx_set_palette,
NULL, // AL_METHOD(int, request_scroll, (int x, int y));
NULL, // gfx_directx_poll_scroll,
NULL, // AL_METHOD(void, enable_triple_buffer, (void));
gfx_directx_create_video_bitmap,
gfx_directx_destroy_video_bitmap,
gfx_directx_show_video_bitmap_ovl,
gfx_directx_request_video_bitmap_ovl,
gfx_directx_create_system_bitmap,
gfx_directx_destroy_system_bitmap,
NULL, // AL_METHOD(int, set_mouse_sprite, (struct BITMAP *sprite, int xfocus, int yfocus));
NULL, // AL_METHOD(int, show_mouse, (struct BITMAP *bmp, int x, int y));
NULL, // AL_METHOD(void, hide_mouse, (void));
NULL, // AL_METHOD(void, move_mouse, (int x, int y));
NULL, // AL_METHOD(void, drawing_mode, (void));
NULL, // AL_METHOD(void, save_video_state, (void*));
NULL, // AL_METHOD(void, restore_video_state, (void*));
NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a));
NULL, // AL_METHOD(int, fetch_mode_list, (void));
NULL, /* acknowledge_resize */
0, 0, // int w, h; /* physical (not virtual!) screen size */
TRUE, // int linear; /* true if video memory is linear */
0, // long bank_size; /* bank size, in bytes */
0, // long bank_gran; /* bank granularity, in bytes */
0, // long vid_mem; /* video memory size, in bytes */
0, // long vid_phys_base; /* physical address of video memory */
TRUE // int windowed; /* true if driver runs windowed */
};
static void switch_in_overlay(void);
static void show_overlay(void);
static void move_overlay(int, int, int, int);
static void hide_overlay(void);
static void paint_overlay(RECT *);
static WIN_GFX_DRIVER win_gfx_driver_overlay =
{
TRUE,
switch_in_overlay,
NULL, // AL_METHOD(void, switch_out, (void));
NULL, // AL_METHOD(void, enter_sysmode, (void));
NULL, // AL_METHOD(void, exit_sysmode, (void));
move_overlay,
hide_overlay,
paint_overlay
};
static char gfx_driver_desc[256] = EMPTY_STRING;
static DDRAW_SURFACE *overlay_surface = NULL;
static BOOL overlay_visible = FALSE;
static HBRUSH overlay_brush;
/* switch_in_overlay:
* Handles window switched in.
*/
static void switch_in_overlay(void)
{
restore_all_ddraw_surfaces();
show_overlay();
}
/* update_overlay:
* Moves and resizes the overlay surface to make it fit
* into the specified area.
*/
static int update_overlay(int x, int y, int w, int h)
{
HRESULT hr;
RECT dest_rect;
dest_rect.left = x;
dest_rect.top = y;
dest_rect.right = x + w;
dest_rect.bottom = y + h;
/* show the overlay surface */
hr = IDirectDrawSurface2_UpdateOverlay(overlay_surface->id, NULL,
gfx_directx_primary_surface->id, &dest_rect,
DDOVER_SHOW | DDOVER_KEYDEST, NULL);
if (FAILED(hr)) {
_TRACE(PREFIX_E "Can't display overlay (%x)\n", hr);
IDirectDrawSurface2_UpdateOverlay(overlay_surface->id, NULL,
gfx_directx_primary_surface->id, NULL,
DDOVER_HIDE, NULL);
return -1;
}
return 0;
}
/* show_overlay:
* Makes the overlay surface visible on the primary surface.
*/
static void show_overlay(void)
{
if (overlay_surface) {
overlay_visible = TRUE;
update_overlay(wnd_x, wnd_y, wnd_width, wnd_height);
}
}
/* move_overlay:
* Moves the overlay surface.
*/
static void move_overlay(int x, int y, int w, int h)
{
RECT window_rect;
HWND allegro_wnd = win_get_window();
int xmod;
/* handle hardware limitations */
if ((ddcaps.dwCaps & DDCAPS_ALIGNBOUNDARYDEST) && (xmod = x%ddcaps.dwAlignBoundaryDest)) {
GetWindowRect(allegro_wnd, &window_rect);
SetWindowPos(allegro_wnd, 0, window_rect.left + xmod, window_rect.top,
0, 0, SWP_NOZORDER | SWP_NOSIZE);
}
else if (overlay_visible)
update_overlay(x, y, w, h);
}
/* hide_overlay:
* Makes the overlay surface invisible on the primary surface.
*/
static void hide_overlay(void)
{
if (overlay_visible) {
overlay_visible = FALSE;
IDirectDrawSurface2_UpdateOverlay(overlay_surface->id, NULL,
gfx_directx_primary_surface->id, NULL,
DDOVER_HIDE, NULL);
}
}
/* paint_overlay:
* Handles window paint events.
*/
static void paint_overlay(RECT *rect)
{
/* We may have lost the DirectDraw surfaces, for example
* after the monitor has gone to low power.
*/
if (IDirectDrawSurface2_IsLost(gfx_directx_primary_surface->id))
switch_in_overlay();
}
/* wnd_set_windowed_coop:
* Sets the DirectDraw cooperative level to normal.
*/
static int wnd_set_windowed_coop(void)
{
HRESULT hr;
HWND allegro_wnd = win_get_window();
hr = IDirectDraw2_SetCooperativeLevel(directdraw, allegro_wnd, DDSCL_NORMAL);
if (FAILED(hr)) {
_TRACE(PREFIX_E "SetCooperative level = %s (%x), hwnd = %x\n", win_err_str(hr), hr, allegro_wnd);
return -1;
}
return 0;
}
/* gfx_directx_setup_driver_desc:
* Sets up the driver description string.
*/
static void gfx_directx_setup_driver_desc(void)
{
char tmp[256];
uszprintf(gfx_driver_desc, sizeof(gfx_driver_desc),
uconvert_ascii("DirectDraw, in matching, %d bpp overlay", tmp),
_win_desktop_depth);
gfx_directx_ovl.desc = gfx_driver_desc;
}
/* gfx_directx_show_video_bitmap_ovl:
*/
static int gfx_directx_show_video_bitmap_ovl(struct BITMAP *bitmap)
{
if (gfx_directx_show_video_bitmap(bitmap) != 0) {
return -1;
}
else {
if (overlay_visible)
update_overlay(wnd_x, wnd_y, wnd_width, wnd_height);
return 0;
}
}
/* gfx_directx_request_video_bitmap_ovl:
*/
static int gfx_directx_request_video_bitmap_ovl(struct BITMAP *bitmap)
{
if (gfx_directx_request_video_bitmap(bitmap) != 0) {
return -1;
}
else {
if (overlay_visible)
update_overlay(wnd_x, wnd_y, wnd_width, wnd_height);
return 0;
}
}
/* create_overlay:
* Creates the overlay surface.
*/
static int create_overlay(int w, int h, int color_depth)
{
overlay_surface = gfx_directx_create_surface(w, h, ddpixel_format, DDRAW_SURFACE_OVERLAY);
if (!overlay_surface) {
_TRACE(PREFIX_E "Can't create overlay surface.\n");
return -1;
}
return 0;
}
/* init_directx_ovl:
* Initializes the driver.
*/
static struct BITMAP *init_directx_ovl(int w, int h, int v_w, int v_h, int color_depth)
{
HRESULT hr;
DDCOLORKEY key;
HWND allegro_wnd = win_get_window();
/* overlay would allow scrolling on some cards, but it isn't implemented yet */
if ((v_w != w && v_w != 0) || (v_h != h && v_h != 0)) {
ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported virtual resolution"));
return NULL;
}
_enter_critical();
/* init DirectX */
if (init_directx() != 0)
goto Error;
if ((ddcaps.dwCaps & DDCAPS_OVERLAY) == 0) {
ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Overlays not supported"));
goto Error;
}
if (gfx_directx_compare_color_depth(color_depth) != 0) {
ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported color depth"));
goto Error;
}
if (wnd_call_proc(wnd_set_windowed_coop) != 0)
goto Error;
if (finalize_directx_init() != 0)
goto Error;
/* Paint window background with overlay color key. */
overlay_brush = CreateSolidBrush(MASK_COLOR_32);
SetClassLong(allegro_wnd, GCL_HBRBACKGROUND, (LONG) overlay_brush);
if (adjust_window(w, h) != 0) {
_TRACE(PREFIX_E "window size not supported.\n");
ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Resolution not supported"));
goto Error;
}
/* create surfaces */
if (gfx_directx_create_primary() != 0)
goto Error;
if (create_overlay(w, h, color_depth) != 0)
goto Error;
/* Handle hardware limitations: according to the DirectX SDK, "these restrictions
* can vary depending on the pixel formats of the overlay and primary surface", so
* we handle them after creating the surfaces.
*/
ddcaps.dwSize = sizeof(ddcaps);
hr = IDirectDraw2_GetCaps(directdraw, &ddcaps, NULL);
if (FAILED(hr)) {
_TRACE(PREFIX_E "Can't get driver caps\n");
goto Error;
}
if (ddcaps.dwCaps & DDCAPS_ALIGNSIZESRC) {
if (w%ddcaps.dwAlignSizeSrc) {
_TRACE(PREFIX_E "Alignment requirement not met: source size %d\n", ddcaps.dwAlignSizeSrc);
ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Resolution not supported"));
goto Error;
}
}
else if (ddcaps.dwCaps & DDCAPS_ALIGNSIZEDEST) {
if (w%ddcaps.dwAlignSizeDest) {
_TRACE(PREFIX_E "Alignment requirement not met: dest size %d\n", ddcaps.dwAlignSizeDest);
ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Resolution not supported"));
goto Error;
}
}
/* set color format */
if (color_depth == 8) {
if (gfx_directx_create_palette(overlay_surface) != 0)
goto Error;
}
else {
if (gfx_directx_update_color_format(overlay_surface, color_depth) != 0)
goto Error;
}
/* set up Allegro gfx driver */
gfx_directx_setup_driver_desc();
if (gfx_directx_setup_driver(&gfx_directx_ovl, w, h, color_depth) != 0)
goto Error;
gfx_directx_forefront_bitmap = gfx_directx_make_bitmap_from_surface(overlay_surface, w, h, BMP_ID_VIDEO);
/* set the overlay color key */
key.dwColorSpaceLowValue = gfx_directx_forefront_bitmap->vtable->mask_color;
key.dwColorSpaceHighValue = gfx_directx_forefront_bitmap->vtable->mask_color;
hr = IDirectDrawSurface2_SetColorKey(gfx_directx_primary_surface->id, DDCKEY_DESTOVERLAY, &key);
if (FAILED(hr)) {
_TRACE(PREFIX_E "Can't set overlay dest color key\n");
goto Error;
}
/* display the overlay surface */
show_overlay();
/* use hardware accelerated primitives */
gfx_directx_enable_acceleration(&gfx_directx_ovl);
/* use triple buffering */
gfx_directx_enable_triple_buffering(&gfx_directx_ovl);
/* connect to the system driver */
win_gfx_driver = &win_gfx_driver_overlay;
/* set default switching policy */
set_display_switch_mode(SWITCH_PAUSE);
_exit_critical();
return gfx_directx_forefront_bitmap;
Error:
_exit_critical();
/* release the DirectDraw object */
gfx_directx_ovl_exit(NULL);
return NULL;
}
/* gfx_directx_ovl_exit:
* Shuts down the driver.
*/
static void gfx_directx_ovl_exit(struct BITMAP *bmp)
{
HWND allegro_wnd = win_get_window();
_enter_gfx_critical();
if (bmp) {
save_window_pos();
clear_bitmap(bmp);
}
/* disconnect from the system driver */
win_gfx_driver = NULL;
/* destroy the overlay surface */
if (overlay_surface) {
hide_overlay();
SetClassLong(allegro_wnd, GCL_HBRBACKGROUND, (LONG) NULL);
DeleteObject(overlay_brush);
gfx_directx_destroy_surface(overlay_surface);
overlay_surface = NULL;
gfx_directx_forefront_bitmap = NULL;
}
gfx_directx_exit(NULL);
_exit_gfx_critical();
}

View File

@ -1,656 +0,0 @@
/* ______ ___ ___
* /\ _ \ /\_ \ /\_ \
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
* /\____/
* \_/__/
*
* Windowed mode gfx driver using gdi.
*
* By Stefan Schimanski.
*
* Dirty rectangles mechanism and hardware mouse cursor emulation
* by Eric Botcazou.
*
* See readme.txt for copyright information.
*/
#include "allegro.h"
#include "allegro/internal/aintern.h"
#include "allegro/platform/aintwin.h"
#ifndef ALLEGRO_WINDOWS
#error something is wrong with the makefile
#endif
#define PREFIX_I "al-wgdi INFO: "
#define PREFIX_W "al-wgdi WARNING: "
#define PREFIX_E "al-wgdi ERROR: "
static void gfx_gdi_autolock(struct BITMAP* bmp);
static void gfx_gdi_unlock(struct BITMAP* bmp);
/* This is used only in asmlock.s and this file. */
char *gdi_dirty_lines = NULL; /* used in WRITE_BANK() */
uintptr_t gfx_gdi_write_bank(BITMAP *bmp, int line)
{
gdi_dirty_lines[bmp->y_ofs +line] = 1;
if (!(bmp->id & BMP_ID_LOCKED))
gfx_gdi_autolock(bmp);
return (uintptr_t) bmp->line[line];
}
void gfx_gdi_unwrite_bank(BITMAP *bmp)
{
if (!(bmp->id & BMP_ID_AUTOLOCK))
return;
gfx_gdi_unlock(bmp);
bmp->id &= ~ BMP_ID_AUTOLOCK;
}
static struct BITMAP *gfx_gdi_init(int w, int h, int v_w, int v_h, int color_depth);
static void gfx_gdi_exit(struct BITMAP *b);
static void gfx_gdi_set_palette(AL_CONST struct RGB *p, int from, int to, int vsync);
static void gfx_gdi_vsync(void);
/* hardware mouse cursor emulation */
static int gfx_gdi_set_mouse_sprite(struct BITMAP *sprite, int xfocus, int yfocus);
static int gfx_gdi_show_mouse(struct BITMAP *bmp, int x, int y);
static void gfx_gdi_hide_mouse(void);
static void gfx_gdi_move_mouse(int x, int y);
static BITMAP *gfx_gdi_acknowledge_resize(void);
static BITMAP *_create_gdi_screen(int w, int h, int color_depth);
static void _destroy_gdi_screen(void);
GFX_DRIVER gfx_gdi =
{
GFX_GDI,
empty_string,
empty_string,
"GDI",
gfx_gdi_init,
gfx_gdi_exit,
NULL, // AL_METHOD(int, scroll, (int x, int y));
gfx_gdi_vsync,
gfx_gdi_set_palette,
NULL, // AL_METHOD(int, request_scroll, (int x, int y));
NULL, // AL_METHOD(int poll_scroll, (void));
NULL, // AL_METHOD(void, enable_triple_buffer, (void));
NULL, NULL, NULL, NULL, NULL, NULL,
gfx_gdi_set_mouse_sprite,
gfx_gdi_show_mouse,
gfx_gdi_hide_mouse,
gfx_gdi_move_mouse,
NULL, // AL_METHOD(void, drawing_mode, (void));
NULL, // AL_METHOD(void, save_video_state, (void*));
NULL, // AL_METHOD(void, restore_video_state, (void*));
NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a));
NULL, // AL_METHOD(int, fetch_mode_list, (void));
gfx_gdi_acknowledge_resize,
0, 0, // int w, h;
TRUE, // int linear;
0, // long bank_size;
0, // long bank_gran;
0, // long vid_mem;
0, // long vid_phys_base;
TRUE // int windowed;
};
static void gdi_enter_sysmode(void);
static void gdi_exit_sysmode(void);
static void gdi_update_window(RECT *rect);
static WIN_GFX_DRIVER win_gfx_driver_gdi =
{
TRUE,
NULL, // AL_METHOD(void, switch_in, (void));
NULL, // AL_METHOD(void, switch_out, (void));
gdi_enter_sysmode,
gdi_exit_sysmode,
NULL, // AL_METHOD(void, move, (int x, int y, int w, int h));
NULL, // AL_METHOD(void, iconify, (void));
gdi_update_window
};
static char *screen_surf;
static BITMAP *gdi_screen;
static int lock_nesting = 0;
static int render_semaphore = FALSE;
static PALETTE palette;
static HANDLE vsync_event;
#define RENDER_DELAY (1000/70) /* 70 Hz */
/* hardware mouse cursor emulation */
static int mouse_on = FALSE;
static int mouse_was_on = FALSE;
static BITMAP *wgdi_mouse_sprite = NULL;
static BITMAP *mouse_frontbuffer = NULL;
static BITMAP *mouse_backbuffer = NULL;
static int mouse_xfocus, mouse_yfocus;
static int mouse_xpos, mouse_ypos;
/* gfx_gdi_set_mouse_sprite:
*/
static int gfx_gdi_set_mouse_sprite(struct BITMAP *sprite, int xfocus, int yfocus)
{
if (wgdi_mouse_sprite) {
destroy_bitmap(wgdi_mouse_sprite);
wgdi_mouse_sprite = NULL;
destroy_bitmap(mouse_frontbuffer);
mouse_frontbuffer = NULL;
destroy_bitmap(mouse_backbuffer);
mouse_backbuffer = NULL;
}
wgdi_mouse_sprite = create_bitmap(sprite->w, sprite->h);
blit(sprite, wgdi_mouse_sprite, 0, 0, 0, 0, sprite->w, sprite->h);
mouse_xfocus = xfocus;
mouse_yfocus = yfocus;
mouse_frontbuffer = create_bitmap(sprite->w, sprite->h);
mouse_backbuffer = create_bitmap(sprite->w, sprite->h);
return 0;
}
/* update_mouse_pointer:
* Worker function that updates the mouse pointer.
*/
static void update_mouse_pointer(int x, int y, int retrace)
{
HDC hdc;
HWND allegro_wnd = win_get_window();
/* put the screen contents located at the new position into the frontbuffer */
blit(gdi_screen, mouse_frontbuffer, x, y, 0, 0, mouse_frontbuffer->w, mouse_frontbuffer->h);
/* draw the mouse pointer onto the frontbuffer */
draw_sprite(mouse_frontbuffer, wgdi_mouse_sprite, 0, 0);
hdc = GetDC(allegro_wnd);
if (_color_depth == 8)
set_palette_to_hdc(hdc, palette);
if (retrace) {
/* restore the screen contents located at the old position */
blit_to_hdc(mouse_backbuffer, hdc, 0, 0, mouse_xpos, mouse_ypos, mouse_backbuffer->w, mouse_backbuffer->h);
}
/* blit the mouse pointer onto the screen */
blit_to_hdc(mouse_frontbuffer, hdc, 0, 0, x, y, mouse_frontbuffer->w, mouse_frontbuffer->h);
ReleaseDC(allegro_wnd, hdc);
/* save the screen contents located at the new position into the backbuffer */
blit(gdi_screen, mouse_backbuffer, x, y, 0, 0, mouse_backbuffer->w, mouse_backbuffer->h);
/* save the new position */
mouse_xpos = x;
mouse_ypos = y;
}
/* gfx_gdi_show_mouse:
*/
static int gfx_gdi_show_mouse(struct BITMAP *bmp, int x, int y)
{
/* handle only the screen */
if (bmp != gdi_screen)
return -1;
mouse_on = TRUE;
x -= mouse_xfocus;
y -= mouse_yfocus;
update_mouse_pointer(x, y, FALSE);
return 0;
}
/* gfx_gdi_hide_mouse:
*/
static void gfx_gdi_hide_mouse(void)
{
HDC hdc;
HWND allegro_wnd = win_get_window();
if (!mouse_on)
return;
hdc = GetDC(allegro_wnd);
if (_color_depth == 8)
set_palette_to_hdc(hdc, palette);
/* restore the screen contents located at the old position */
blit_to_hdc(mouse_backbuffer, hdc, 0, 0, mouse_xpos, mouse_ypos, mouse_backbuffer->w, mouse_backbuffer->h);
ReleaseDC(allegro_wnd, hdc);
mouse_on = FALSE;
}
/* gfx_gdi_move_mouse:
*/
static void gfx_gdi_move_mouse(int x, int y)
{
if (!mouse_on)
return;
x -= mouse_xfocus;
y -= mouse_yfocus;
if ((mouse_xpos == x) && (mouse_ypos == y))
return;
update_mouse_pointer(x, y, TRUE);
}
/* render_proc:
* Timer proc that updates the window.
*/
static void render_proc(void)
{
int top_line, bottom_line;
HDC hdc = NULL;
HWND allegro_wnd = win_get_window();
/* to prevent reentrant calls */
if (render_semaphore)
return;
render_semaphore = TRUE;
/* to prevent the drawing threads and the rendering proc
* from concurrently accessing the dirty lines array.
*/
_enter_gfx_critical();
if (!gdi_screen) {
_exit_gfx_critical();
render_semaphore = FALSE;
return;
}
/* pseudo dirty rectangles mechanism:
* at most only one GDI call is performed for each frame,
* a true dirty rectangles mechanism makes the demo game
* unplayable in 640x480 on my system.
*/
/* find the first dirty line */
top_line = 0;
while (!gdi_dirty_lines[top_line])
top_line++;
if (top_line < gfx_gdi.h) {
/* find the last dirty line */
bottom_line = gfx_gdi.h-1;
while (!gdi_dirty_lines[bottom_line])
bottom_line--;
hdc = GetDC(allegro_wnd);
if (_color_depth == 8)
set_palette_to_hdc(hdc, palette);
blit_to_hdc(gdi_screen, hdc, 0, top_line, 0, top_line,
gfx_gdi.w, bottom_line - top_line + 1);
/* update mouse pointer if needed */
if (mouse_on) {
if ((mouse_ypos+wgdi_mouse_sprite->h > top_line) && (mouse_ypos <= bottom_line)) {
blit(gdi_screen, mouse_backbuffer, mouse_xpos, mouse_ypos, 0, 0,
mouse_backbuffer->w, mouse_backbuffer->h);
update_mouse_pointer(mouse_xpos, mouse_ypos, TRUE);
}
}
/* clean up the dirty lines */
while (top_line <= bottom_line)
gdi_dirty_lines[top_line++] = 0;
ReleaseDC(allegro_wnd, hdc);
}
_exit_gfx_critical();
/* simulate vertical retrace */
PulseEvent(vsync_event);
render_semaphore = FALSE;
}
/* gdi_enter_sysmode:
*/
static void gdi_enter_sysmode(void)
{
/* hide the mouse pointer */
if (mouse_on) {
mouse_was_on = TRUE;
gfx_gdi_hide_mouse();
_TRACE(PREFIX_I "mouse pointer off\n");
}
}
/* gdi_exit_sysmode:
*/
static void gdi_exit_sysmode(void)
{
if (mouse_was_on) {
mouse_on = TRUE;
mouse_was_on = FALSE;
_TRACE(PREFIX_I "mouse pointer on\n");
}
}
/* gdi_update_window:
* Updates the window.
*/
static void gdi_update_window(RECT *rect)
{
HDC hdc;
HWND allegro_wnd = win_get_window();
_enter_gfx_critical();
if (!gdi_screen) {
_exit_gfx_critical();
return;
}
hdc = GetDC(allegro_wnd);
if (_color_depth == 8)
set_palette_to_hdc(hdc, palette);
blit_to_hdc(gdi_screen, hdc, rect->left, rect->top, rect->left, rect->top,
rect->right - rect->left, rect->bottom - rect->top);
ReleaseDC(allegro_wnd, hdc);
_exit_gfx_critical();
}
/* gfx_gdi_lock:
*/
static void gfx_gdi_lock(struct BITMAP *bmp)
{
/* to prevent the drawing threads and the rendering proc
* from concurrently accessing the dirty lines array
*/
_enter_gfx_critical();
/* arrange for drawing requests to pause when we are in the background */
if (!_win_app_foreground) {
/* stop timer */
remove_int(render_proc);
_exit_gfx_critical();
if (GFX_CRITICAL_RELEASED)
_win_thread_switch_out();
_enter_gfx_critical();
/* restart timer */
install_int(render_proc, RENDER_DELAY);
}
lock_nesting++;
bmp->id |= BMP_ID_LOCKED;
}
/* gfx_gdi_autolock:
*/
static void gfx_gdi_autolock(struct BITMAP *bmp)
{
gfx_gdi_lock(bmp);
bmp->id |= BMP_ID_AUTOLOCK;
}
/* gfx_gdi_unlock:
*/
static void gfx_gdi_unlock(struct BITMAP *bmp)
{
if (lock_nesting > 0) {
lock_nesting--;
if (!lock_nesting)
bmp->id &= ~BMP_ID_LOCKED;
_exit_gfx_critical();
}
}
/* gfx_gdi_init:
*/
static struct BITMAP *gfx_gdi_init(int w, int h, int v_w, int v_h, int color_depth)
{
/* virtual screen are not supported */
if ((v_w!=0 && v_w!=w) || (v_h!=0 && v_h!=h))
return NULL;
_enter_critical();
gfx_gdi.w = w;
gfx_gdi.h = h;
if (adjust_window(w, h) != 0) {
_TRACE(PREFIX_E "window size not supported.\n");
ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Resolution not supported"));
goto Error;
}
_create_gdi_screen(w, h, color_depth);
/* create render timer */
vsync_event = CreateEvent(NULL, FALSE, FALSE, NULL);
install_int(render_proc, RENDER_DELAY);
/* connect to the system driver */
win_gfx_driver = &win_gfx_driver_gdi;
/* set the default switching policy */
set_display_switch_mode(SWITCH_PAUSE);
_exit_critical();
return gdi_screen;
Error:
_exit_critical();
gfx_gdi_exit(NULL);
return NULL;
}
/* gfx_gdi_exit:
*/
static void gfx_gdi_exit(struct BITMAP *bmp)
{
_enter_critical();
_enter_gfx_critical();
if (bmp) {
save_window_pos();
clear_bitmap(bmp);
}
/* stop timer */
remove_int(render_proc);
CloseHandle(vsync_event);
/* disconnect from the system driver */
win_gfx_driver = NULL;
_destroy_gdi_screen();
/* destroy mouse bitmaps */
if (wgdi_mouse_sprite) {
destroy_bitmap(wgdi_mouse_sprite);
wgdi_mouse_sprite = NULL;
destroy_bitmap(mouse_frontbuffer);
mouse_frontbuffer = NULL;
destroy_bitmap(mouse_backbuffer);
mouse_backbuffer = NULL;
}
_exit_gfx_critical();
/* before restoring video mode, hide window */
set_display_switch_mode(SWITCH_PAUSE);
system_driver->restore_console_state();
restore_window_style();
_exit_critical();
}
/* gfx_gdi_set_palette:
*/
static void gfx_gdi_set_palette(AL_CONST struct RGB *p, int from, int to, int vsync)
{
int c;
for (c=from; c<=to; c++)
palette[c] = p[c];
/* invalidate the whole screen */
_enter_gfx_critical();
gdi_dirty_lines[0] = gdi_dirty_lines[gfx_gdi.h-1] = 1;
_exit_gfx_critical();
}
/* gfx_gdi_vsync:
*/
static void gfx_gdi_vsync(void)
{
WaitForSingleObject(vsync_event, INFINITE);
}
static BITMAP *gfx_gdi_acknowledge_resize(void)
{
HWND allegro_wnd = win_get_window();
int color_depth = bitmap_color_depth(screen);
int w, h;
RECT rc;
BITMAP *new_screen;
GetClientRect(allegro_wnd, &rc);
w = rc.right;
h = rc.bottom;
if (w % 4)
w -= (w % 4);
_enter_gfx_critical();
/* Re-create the screen */
_destroy_gdi_screen();
new_screen = _create_gdi_screen(w, h, color_depth);
_exit_gfx_critical();
return new_screen;
}
static BITMAP *_create_gdi_screen(int w, int h, int color_depth)
{
gfx_gdi.w = w;
gfx_gdi.h = h;
/* the last flag serves as an end of loop delimiter */
gdi_dirty_lines = _AL_MALLOC_ATOMIC((h+1) * sizeof(char));
ASSERT(gdi_dirty_lines);
memset(gdi_dirty_lines, 0, (h+1) * sizeof(char));
gdi_dirty_lines[h] = 1;
/* create the screen surface */
screen_surf = _AL_MALLOC_ATOMIC(w * h * BYTES_PER_PIXEL(color_depth));
gdi_screen = _make_bitmap(w, h, (unsigned long)screen_surf, &gfx_gdi, color_depth, w * BYTES_PER_PIXEL(color_depth));
gdi_screen->write_bank = gfx_gdi_write_bank;
_screen_vtable.acquire = gfx_gdi_lock;
_screen_vtable.release = gfx_gdi_unlock;
_screen_vtable.unwrite_bank = gfx_gdi_unwrite_bank;
return gdi_screen;
}
static void _destroy_gdi_screen(void)
{
/* destroy dirty lines array */
_AL_FREE(gdi_dirty_lines);
gdi_dirty_lines = NULL;
/* destroy screen surface */
_AL_FREE(screen_surf);
gdi_screen = NULL;
}

View File

@ -51,7 +51,6 @@ static void sys_directx_save_console_state(void);
static void sys_directx_restore_console_state(void);
static int sys_directx_desktop_color_depth(void);
static int sys_directx_get_desktop_resolution(int *width, int *height);
static void sys_directx_get_gfx_safe_mode(int *driver, struct GFX_MODE *mode);
static void sys_directx_yield_timeslice(void);
static int sys_directx_trace_handler(AL_CONST char *msg);
@ -86,7 +85,7 @@ SYSTEM_DRIVER system_directx =
NULL, /* AL_METHOD(void, display_switch_lock, (int lock)); */
sys_directx_desktop_color_depth,
sys_directx_get_desktop_resolution,
sys_directx_get_gfx_safe_mode,
NULL, /* get_gfx_safe_mode */
sys_directx_yield_timeslice,
sys_directx_create_mutex,
sys_directx_destroy_mutex,
@ -433,19 +432,6 @@ static int sys_directx_get_desktop_resolution(int *width, int *height)
/* sys_directx_get_gfx_safe_mode:
* Defines the safe graphics mode for this system.
*/
static void sys_directx_get_gfx_safe_mode(int *driver, struct GFX_MODE *mode)
{
*driver = GFX_GDI;
mode->width = 320;
mode->height = 200;
mode->bpp = 8;
}
/* sys_directx_yield_timeslice:
* Yields remaining timeslice portion to the system.
*/