diff options
author | Eugene Sandulenko | 2009-02-15 11:03:21 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2009-02-15 11:03:21 +0000 |
commit | e9f742806362a84ffdb176a7414318dd2ab4df89 (patch) | |
tree | f6e3b49f135a81370a95a5a1314414b30c45feba /engines/sci/gfx | |
parent | 7ec7c4399e4ebc57d16347050873326db8b1f4e2 (diff) | |
download | scummvm-rg350-e9f742806362a84ffdb176a7414318dd2ab4df89.tar.gz scummvm-rg350-e9f742806362a84ffdb176a7414318dd2ab4df89.tar.bz2 scummvm-rg350-e9f742806362a84ffdb176a7414318dd2ab4df89.zip |
- Move sci/scummvm/ contents to sci/
- Rename scumm_engine.cpp to sci.cpp
- Remove unneeded gfx drivers
- Rename scummvm_driver.c to gfx_driver.cpp
svn-id: r38225
Diffstat (limited to 'engines/sci/gfx')
-rw-r--r-- | engines/sci/gfx/drivers/EXPORTS_ggi | 1 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/EXPORTS_sdl | 1 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/EXPORTS_xlib | 2 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/dc_driver.c | 1267 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/dd_driver.cpp | 1021 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/dd_driver.h | 2 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/dd_driver_line.cpp | 163 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/directfb_driver.c | 1033 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/dx_driver.cpp | 1179 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/dx_driver.h | 151 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/gfx_drivers.c | 192 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/ggi_driver.c | 1035 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/null_driver.c | 211 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/sdl_driver.c | 1235 | ||||
-rw-r--r-- | engines/sci/gfx/drivers/xlib_driver.c | 1460 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_driver.cpp (renamed from engines/sci/gfx/drivers/scummvm_driver.cpp) | 0 |
16 files changed, 0 insertions, 8953 deletions
diff --git a/engines/sci/gfx/drivers/EXPORTS_ggi b/engines/sci/gfx/drivers/EXPORTS_ggi deleted file mode 100644 index 0f9ed580f6..0000000000 --- a/engines/sci/gfx/drivers/EXPORTS_ggi +++ /dev/null @@ -1 +0,0 @@ -gfx_driver_ggi diff --git a/engines/sci/gfx/drivers/EXPORTS_sdl b/engines/sci/gfx/drivers/EXPORTS_sdl deleted file mode 100644 index 55e1950033..0000000000 --- a/engines/sci/gfx/drivers/EXPORTS_sdl +++ /dev/null @@ -1 +0,0 @@ -gfx_driver_sdl diff --git a/engines/sci/gfx/drivers/EXPORTS_xlib b/engines/sci/gfx/drivers/EXPORTS_xlib deleted file mode 100644 index 5d705799b0..0000000000 --- a/engines/sci/gfx/drivers/EXPORTS_xlib +++ /dev/null @@ -1,2 +0,0 @@ -gfx_driver_xlib - diff --git a/engines/sci/gfx/drivers/dc_driver.c b/engines/sci/gfx/drivers/dc_driver.c deleted file mode 100644 index 5f2b4419ae..0000000000 --- a/engines/sci/gfx/drivers/dc_driver.c +++ /dev/null @@ -1,1267 +0,0 @@ -/*************************************************************************** - dc_driver.c Copyright (C) 2002-2005 Walter van Niftrik - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Walter van Niftrik <w.f.b.w.v.niftrik@stud.tue.nl> - -***************************************************************************/ - -#include <kos/thread.h> -#include <kos/sem.h> -#include <dc/maple.h> -#include <dc/maple/mouse.h> -#include <dc/maple/keyboard.h> -#include <dc/maple/controller.h> -#include <dc/pvr.h> - -#include <sci_memory.h> -#include <gfx_driver.h> -#include <gfx_tools.h> - -#include "keyboard.h" - -/* Event queue struct */ - -struct dc_event_t { - sci_event_t event; - struct dc_event_t *next; -}; - -#define SCI_DC_RENDER_PVR (1 << 0) /* 0 = VRAM rendering, 1 = PVR */ -#define SCI_DC_REFRESH_50HZ (1 << 1) /* 0 = 60Hz refresh rate, 1 = 50Hz */ - -static int flags = 0; - -struct _dc_state { - /* 0 = static buffer, 1 = back buffer, 2 = front buffer */ - /* Visual maps */ - byte *visual[3]; - /* Priority maps */ - byte *priority[2]; - /* Line pitch of visual buffers */ - int line_pitch[3]; - - /* PVR only */ - /* Polygon header */ - pvr_poly_hdr_t pvr_hdr; - /* Polygon header for virtual keyboard */ - pvr_poly_hdr_t pvr_hdr_vkbd; - /* Texture for virtual keyboard */ - uint16 *vkbd_txr; - - /* Pointers to first and last event in the event queue */ - struct dc_event_t *first_event; - struct dc_event_t *last_event; - - /* Semaphores for mouse pointer location and event queue updates */ - semaphore_t *sem_event, *sem_pointer; - - /* The dx and dy of the mouse pointer since last get_event() */ - int pointer_dx, pointer_dy; - - /* The current bucky state of the keys */ - int buckystate; - - /* Thread ID of the input thread */ - kthread_t *thread; - - /* Flag to stop the input thread. (!0 = run, 0 = stop) */ - int run_thread; - - /* Controller key repeat timer */ - int timer; - - /* Controller state */ - unsigned int cont_state; - - /* Virtual keyboard on/off flag */ - int vkbd; -}; - -#define S ((struct _dc_state *)(drv->state)) - -#define XFACT drv->mode->xfact -#define YFACT drv->mode->yfact -#define BYTESPP drv->mode->bytespp - -#define DC_MOUSE_LEFT (1<<0) -#define DC_MOUSE_RIGHT (1<<1) - -#define DC_KEY_CAPSLOCK (1<<0) -#define DC_KEY_NUMLOCK (1<<1) -#define DC_KEY_SCRLOCK (1<<2) -#define DC_KEY_INSERT (1<<3) - -static void -pvr_init_gfx(struct _gfx_driver *drv, int xfact, int yfact, int bytespp) -/* Initialises the graphics driver for PVR rendering mode -** Parameters: (_gfx_driver *) drv: The driver to use -** (int) xfact, yfact: X and Y scaling factors. (xfact, yfact) -** has to be either (1, 1) or (2, 2). -** (int) bytespp: The display depth in bytes per pixel. Must be 2. -** Returns : void -*/ -{ - pvr_poly_cxt_t cxt; - - /* Initialize PVR to defaults and set background color to black */ - - if (flags & SCI_DC_REFRESH_50HZ) - vid_set_mode(DM_640x480_PAL_IL, PM_RGB565); - else - vid_set_mode(DM_640x480, PM_RGB565); - - pvr_init_defaults(); - pvr_set_bg_color(0,0,0); - - /* Allocate and initialize texture RAM */ - S->visual[2] = pvr_mem_malloc(512*256*bytespp*xfact*yfact); - S->line_pitch[2] = 512*bytespp*xfact; - memset(S->visual[2], 0, 512*256*bytespp*xfact*yfact); - - /* Create textured polygon context */ - pvr_poly_cxt_txr(&cxt, PVR_LIST_OP_POLY, PVR_TXRFMT_RGB565 | - PVR_TXRFMT_NONTWIDDLED, 512*xfact, 256*yfact, S->visual[2], 0); - - /* Create polygon header from context */ - pvr_poly_compile(&(S->pvr_hdr), &cxt); - - /* Allocate and initialize texture RAM for virtual keyboard */ - S->vkbd_txr = pvr_mem_malloc(512*64*bytespp*xfact*yfact); - memset(S->vkbd_txr, 0, 512*64*bytespp*xfact*yfact); - - /* Create textured polygon context for virtual keyboard */ - pvr_poly_cxt_txr(&cxt, PVR_LIST_TR_POLY, PVR_TXRFMT_RGB565 | - PVR_TXRFMT_NONTWIDDLED, 512*xfact, 64*yfact, S->vkbd_txr, 0); - - /* Create polygon header from context for virtual keyboard */ - pvr_poly_compile(&(S->pvr_hdr_vkbd), &cxt); - - vkbd_init((uint16 *) S->vkbd_txr, 512); - vkbd_draw(); -} - -static void -pvr_do_frame(struct _gfx_driver *drv) -/* Renders a frame for PVR rendering mode -** Parameters: (_gfx_driver *) drv: The driver to use -** Returns : void -*/ -{ - pvr_vertex_t vert; - - /* Wait until we can send another frame to the PVR */ - pvr_wait_ready(); - - /* Start a new scene */ - pvr_scene_begin(); - - /* Start an opaque polygon list */ - pvr_list_begin(PVR_LIST_OP_POLY); - - /* Submit polygon header */ - pvr_prim(&(S->pvr_hdr), sizeof(S->pvr_hdr)); - - /* Create and submit vertices */ - vert.flags = PVR_CMD_VERTEX; - vert.x = 0.0f; - vert.y = 480.0f; - vert.z = 1.0f; - vert.u = 0.0f; - vert.v = 0.78125f; - vert.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f); - vert.oargb = 0; - pvr_prim(&vert, sizeof(vert)); - - vert.y = 0.0f; - vert.v = 0.0f; - pvr_prim(&vert, sizeof(vert)); - - vert.x = 640.0f; - vert.y = 480.0f; - vert.u = 0.625f; - vert.v = 0.78125f; - pvr_prim(&vert, sizeof(vert)); - - vert.flags = PVR_CMD_VERTEX_EOL; - vert.y = 0.0f; - vert.v = 0.0f; - pvr_prim(&vert, sizeof(vert)); - - /* End list */ - pvr_list_finish(); - - /* Display virtual keyboard */ - if (S->vkbd) { - /* Start an translucent polygon list */ - pvr_list_begin(PVR_LIST_TR_POLY); - - /* Submit polygon header */ - pvr_prim(&(S->pvr_hdr_vkbd), sizeof(S->pvr_hdr_vkbd)); - - /* Create and submit vertices */ - vert.flags = PVR_CMD_VERTEX; - vert.x = 0.0f; - vert.y = 480.0f; - vert.z = 1.0f; - vert.u = 0.0f; - vert.v = 0.625f; - vert.argb = PVR_PACK_COLOR(0.8f, 1.0f, 1.0f, 1.0f); - vert.oargb = 0; - pvr_prim(&vert, sizeof(vert)); - - vert.y = 400.0f; - vert.v = 0.0f; - pvr_prim(&vert, sizeof(vert)); - - vert.x = 640.0f; - vert.y = 480.0f; - vert.u = 0.625f; - vert.v = 0.625f; - pvr_prim(&vert, sizeof(vert)); - - vert.flags = PVR_CMD_VERTEX_EOL; - vert.y = 400.0f; - vert.v = 0.0f; - pvr_prim(&vert, sizeof(vert)); - - /* End list */ - pvr_list_finish(); - } - - /* End scene */ - pvr_scene_finish(); -} - -static void -vram_init_gfx(struct _gfx_driver *drv, int xfact, int yfact, int bytespp) -/* Initialises the graphics driver for VRAM rendering mode -** Parameters: (_gfx_driver *) drv: The driver to use -** (int) xfact, yfact: X and Y scaling factors. (xfact, yfact) -** has to be either (1, 1) or (2, 2). -** (int) bytespp: The display depth in bytes per pixel. Must be -** either 2 or 4. -** Returns : void -*/ -{ - int vidres = 0, vidcol = 0; - - /* Center screen vertically */ - S->visual[2] = (byte *) vram_s+320*xfact*20*yfact*bytespp; - - S->line_pitch[2] = 320*xfact*bytespp; - - memset(S->visual[2], 0, 320*xfact*240*yfact*bytespp); - - switch(bytespp) { - case 2: - vidcol = PM_RGB565; - break; - case 4: - vidcol = PM_RGB888; - } - - if (flags & SCI_DC_REFRESH_50HZ) switch (xfact) { - case 1: - vidres = DM_320x240_PAL; - break; - case 2: - vidres = DM_640x480_PAL_IL; - } - else switch (xfact) { - case 1: - vidres = DM_320x240; - break; - case 2: - vidres = DM_640x480; - } - - vid_set_mode(vidres, vidcol); - - vkbd_init((uint16 *) (S->visual[2] + 320 * xfact * 200 * yfact * bytespp), 320); -} - -static void -vram_hide_keyboard(struct _gfx_driver *drv) -/* Hides the virtual keyboard in VRAM rendering mode -** Parameters: (_gfx_driver *) drv: The driver to use -** Returns : void -*/ -{ - vid_set_start(0); - memset4(S->visual[2] + 320 * XFACT * 200 * YFACT * BYTESPP, 0, 320 * XFACT * 40 * YFACT * BYTESPP); -} - -static void -vram_show_keyboard(struct _gfx_driver *drv) -/* Displays the virtual keyboard in VRAM rendering mode -** Parameters: (_gfx_driver *) drv: The driver to use -** Returns : void -*/ -{ - vid_set_start(320 * XFACT * 20 * YFACT * BYTESPP); - vkbd_draw(); -} - -static int -dc_add_event(struct _gfx_driver *drv, sci_event_t *event) -/* Adds an event to the end of an event queue -** Parameters: (_gfx_driver *) drv: The driver to use -** (sci_event_t *) event: The event to add -** Returns : (int) 1 on success, 0 on error -*/ -{ - struct dc_event_t *dc_event; - if (!(dc_event = sci_malloc(sizeof(dc_event)))) { - printf("Error: Could not reserve memory for event\n"); - return 0; - } - - dc_event->event = *event; - dc_event->next = NULL; - - /* Semaphore prevents get_event() from removing the last event in - ** the event queue while a next event is being attached to it. - */ - - sem_wait(S->sem_event); - if (!(S->last_event)) { - /* Event queue is empty */ - S->first_event = dc_event; - S->last_event = dc_event; - sem_signal(S->sem_event); - return 1; - } - - S->last_event->next = dc_event; - S->last_event = dc_event; - sem_signal(S->sem_event); - return 1; -} - -static int -dc_map_key(int *keystate, uint8 key) -/* Converts a kos keycode to a freesci keycode. This function also adjusts -** the caps lock, num lock, scroll lock and insert states in keystate. -** Parameters: (int *) keystate: Pointer to the keystate variable -** (uint8) key: The kos keycode to convert -** Returns : (int) Converted freesci keycode on success, 0 on error -*/ -{ - if ((key >= KBD_KEY_A) && (key <= KBD_KEY_Z)) - return 'a' + (key - KBD_KEY_A); - - if ((key >= KBD_KEY_1) && (key <= KBD_KEY_9)) - return '1' + (key - KBD_KEY_1); - - switch (key) { - case KBD_KEY_0: return '0'; - case KBD_KEY_BACKSPACE: return SCI_K_BACKSPACE; - case KBD_KEY_TAB: return 9; - case KBD_KEY_ESCAPE: return SCI_K_ESC; - case KBD_KEY_ENTER: - case KBD_KEY_PAD_ENTER: return SCI_K_ENTER; - case KBD_KEY_DEL: - case KBD_KEY_PAD_PERIOD: return SCI_K_DELETE; - case KBD_KEY_INSERT: - case KBD_KEY_PAD_0: *keystate ^= DC_KEY_INSERT; - return SCI_K_INSERT; - case KBD_KEY_END: - case KBD_KEY_PAD_1: return SCI_K_END; - case KBD_KEY_DOWN: - case KBD_KEY_PAD_2: return SCI_K_DOWN; - case KBD_KEY_PGDOWN: - case KBD_KEY_PAD_3: return SCI_K_PGDOWN; - case KBD_KEY_LEFT: - case KBD_KEY_PAD_4: return SCI_K_LEFT; - case KBD_KEY_PAD_5: return SCI_K_CENTER; - case KBD_KEY_RIGHT: - case KBD_KEY_PAD_6: return SCI_K_RIGHT; - case KBD_KEY_HOME: - case KBD_KEY_PAD_7: return SCI_K_HOME; - case KBD_KEY_UP: - case KBD_KEY_PAD_8: return SCI_K_UP; - case KBD_KEY_PGUP: - case KBD_KEY_PAD_9: return SCI_K_PGUP; - case KBD_KEY_F1: return SCI_K_F1; - case KBD_KEY_F2: return SCI_K_F2; - case KBD_KEY_F3: return SCI_K_F3; - case KBD_KEY_F4: return SCI_K_F4; - case KBD_KEY_F5: return SCI_K_F5; - case KBD_KEY_F6: return SCI_K_F6; - case KBD_KEY_F7: return SCI_K_F7; - case KBD_KEY_F8: return SCI_K_F8; - case KBD_KEY_F9: return SCI_K_F9; - case KBD_KEY_F10: return SCI_K_F10; - case KBD_KEY_PAD_PLUS: return '+'; - case KBD_KEY_SLASH: - case KBD_KEY_PAD_DIVIDE: return '/'; - case KBD_KEY_MINUS: - case KBD_KEY_PAD_MINUS: return '-'; - case KBD_KEY_PAD_MULTIPLY: return '*'; - case KBD_KEY_COMMA: return ','; - case KBD_KEY_PERIOD: return '.'; - case KBD_KEY_BACKSLASH: return '\\'; - case KBD_KEY_SEMICOLON: return ';'; - case KBD_KEY_QUOTE: return '\''; - case KBD_KEY_LBRACKET: return '['; - case KBD_KEY_RBRACKET: return ']'; - case KBD_KEY_TILDE: return '`'; - case KBD_KEY_PLUS: return '='; - case KBD_KEY_SPACE: return ' '; - case KBD_KEY_CAPSLOCK: *keystate ^= DC_KEY_CAPSLOCK; - return 0; - case KBD_KEY_SCRLOCK: *keystate ^= DC_KEY_SCRLOCK; - return 0; - case KBD_KEY_PAD_NUMLOCK: *keystate ^= DC_KEY_NUMLOCK; - return 0; - } - - printf("Warning: Unmapped key: %02x\n", key); - - return 0; -} - -static void -dc_input_thread(struct _gfx_driver *drv) -/* Thread that checks the dreamcast keyboard and mouse states. It adds -** keypresses and mouseclicks to the end of the event queue. It also updates -** drv->state.buckystate and drv->state.pointer_dx/dy. -** Parameters: (_gfx_driver *) drv: The driver to use -** Returns : void -*/ -{ - /* State of mouse buttons */ - unsigned int mstate = 0; - /* Last key pressed */ - unsigned int lastkey = KBD_KEY_NONE; - /* State of caps lock, scroll lock, num lock and insert keys */ - int keystate = DC_KEY_INSERT; - - while (S->run_thread) { - maple_device_t *kaddr = NULL, *maddr, *caddr; - mouse_state_t *mouse; - kbd_state_t *kbd = 0; - cont_state_t *cont; - uint8 key; - int skeys; - int bucky = 0, vkbd_bucky = 0; - sci_event_t event; - - if (!(flags & SCI_DC_RENDER_PVR)) - /* Sleep for 10ms */ - thd_sleep(10); - else - pvr_do_frame(drv); - - /* Keyboard handling */ - /* Experimental workaround for the Mad Catz adapter problem */ - if (!kaddr) - kaddr = maple_enum_type(0, MAPLE_FUNC_KEYBOARD); - if (kaddr && (kbd = maple_dev_status(kaddr))) { - key = kbd->cond.keys[0]; - skeys = kbd->shift_keys; - - bucky = ((skeys & (KBD_MOD_LCTRL | KBD_MOD_RCTRL))? - SCI_EVM_CTRL : 0) | - ((skeys & (KBD_MOD_LALT | KBD_MOD_RALT))? - SCI_EVM_ALT : 0) | - ((skeys & KBD_MOD_LSHIFT)? - SCI_EVM_LSHIFT : 0) | - ((skeys & KBD_MOD_RSHIFT)? - SCI_EVM_RSHIFT : 0) | - ((keystate & DC_KEY_NUMLOCK)? - SCI_EVM_NUMLOCK : 0) | - ((keystate & DC_KEY_SCRLOCK)? - SCI_EVM_SCRLOCK : 0) | - ((keystate & DC_KEY_INSERT)? - SCI_EVM_INSERT : 0); - - /* If a shift key is pressed when caps lock is on, set - ** both shift key states to 0. If no shift keys are - ** pressed when caps lock is on, set both shift key - ** states to 1 - */ - - if (keystate & DC_KEY_CAPSLOCK) { - if ((bucky & SCI_EVM_LSHIFT) || - (bucky & SCI_EVM_RSHIFT)) - bucky &= - ~(SCI_EVM_LSHIFT | SCI_EVM_RSHIFT); - else bucky |= SCI_EVM_LSHIFT | SCI_EVM_RSHIFT; - } - - if ((key != lastkey) && (key != KBD_KEY_NONE)) { - event.type = SCI_EVT_KEYBOARD; - event.data = dc_map_key(&keystate, key); - event.buckybits = bucky | vkbd_bucky; - if (event.data) dc_add_event(drv, &event); - } - lastkey = key; - } - else kaddr = NULL; - - /* Mouse handling */ - if ((maddr = maple_enum_type(0, MAPLE_FUNC_MOUSE)) && - (mouse = maple_dev_status(maddr))) { - - /* Enable mouse support */ - drv->capabilities |= GFX_CAPABILITY_MOUSE_SUPPORT; - - /* Semaphore prevents get_event() from accessing - ** S->pointer_dx/dy while they are being updated - */ - sem_wait(S->sem_pointer); - S->pointer_dx += mouse->dx; - S->pointer_dy += mouse->dy; - sem_signal(S->sem_pointer); - - if ((mouse->buttons & MOUSE_LEFTBUTTON) && - !(mstate & DC_MOUSE_LEFT)) { - event.type = SCI_EVT_MOUSE_PRESS; - event.data = 1; - event.buckybits = bucky | vkbd_bucky; - dc_add_event(drv, &event); - mstate |= DC_MOUSE_LEFT; - } - if ((mouse->buttons & MOUSE_RIGHTBUTTON) && - !(mstate & DC_MOUSE_RIGHT)) { - event.type = SCI_EVT_MOUSE_PRESS; - event.data = 2; - event.buckybits = bucky | vkbd_bucky; - dc_add_event(drv, &event); - mstate |= DC_MOUSE_RIGHT; - } - if (!(mouse->buttons & MOUSE_LEFTBUTTON) && - (mstate & DC_MOUSE_LEFT)) { - event.type = SCI_EVT_MOUSE_RELEASE; - event.data = 1; - event.buckybits = bucky | vkbd_bucky; - dc_add_event(drv, &event); - mstate &= ~DC_MOUSE_LEFT; - } - if (!(mouse->buttons & MOUSE_RIGHTBUTTON) && - (mstate & DC_MOUSE_RIGHT)) { - event.type = SCI_EVT_MOUSE_RELEASE; - event.data = 2; - event.buckybits = bucky | vkbd_bucky; - dc_add_event(drv, &event); - mstate &= ~DC_MOUSE_RIGHT; - } - } - else if ((caddr = maple_enum_type(0, MAPLE_FUNC_CONTROLLER)) && - (cont = maple_dev_status(caddr))) { - /* Enable mouse support */ - drv->capabilities |= GFX_CAPABILITY_MOUSE_SUPPORT; - - /* Semaphore prevents get_event() from accessing - ** S->pointer_dx/dy while they are being updated - */ - sem_wait(S->sem_pointer); - S->pointer_dx += cont->joyx/20; - S->pointer_dy += cont->joyy/20; - sem_signal(S->sem_pointer); - - if ((cont->ltrig > 5) && - !(mstate & DC_MOUSE_LEFT)) { - event.type = SCI_EVT_MOUSE_PRESS; - event.data = 1; - event.buckybits = bucky | vkbd_bucky; - dc_add_event(drv, &event); - mstate |= DC_MOUSE_LEFT; - } - if ((cont->rtrig > 5) && - !(mstate & DC_MOUSE_RIGHT)) { - event.type = SCI_EVT_MOUSE_PRESS; - event.data = 2; - event.buckybits = bucky | vkbd_bucky; - dc_add_event(drv, &event); - mstate |= DC_MOUSE_RIGHT; - } - if ((cont->ltrig <= 5) && - (mstate & DC_MOUSE_LEFT)) { - event.type = SCI_EVT_MOUSE_RELEASE; - event.data = 1; - event.buckybits = bucky | vkbd_bucky; - dc_add_event(drv, &event); - mstate &= ~DC_MOUSE_LEFT; - } - if ((cont->rtrig <= 5) && - (mstate & DC_MOUSE_RIGHT)) { - event.type = SCI_EVT_MOUSE_RELEASE; - event.data = 2; - event.buckybits = bucky | vkbd_bucky; - dc_add_event(drv, &event); - mstate &= ~DC_MOUSE_RIGHT; - } - if (S->timer > 0) - S->timer--; - if ((cont->buttons != S->cont_state) || !S->timer) { - S->cont_state = cont->buttons; - S->timer = 25; - if (cont->buttons & CONT_START) { - S->vkbd = S->vkbd ^ 1; - if (!(flags & SCI_DC_RENDER_PVR)) { - if(S->vkbd) - vram_show_keyboard(drv); - else - vram_hide_keyboard(drv); - } - } - if (S->vkbd) { - if (cont->buttons & CONT_DPAD_RIGHT) - vkbd_handle_input(KBD_RIGHT); - if (cont->buttons & CONT_DPAD_LEFT) - vkbd_handle_input(KBD_LEFT); - if (cont->buttons & CONT_DPAD_UP) - vkbd_handle_input(KBD_UP); - if (cont->buttons & CONT_DPAD_DOWN) - vkbd_handle_input(KBD_DOWN); - if (cont->buttons & CONT_A) { - int vkbd_key; - if (vkbd_get_key(&vkbd_key, &vkbd_bucky)) { - event.type = SCI_EVT_KEYBOARD; - event.data = vkbd_key; - event.buckybits = bucky | vkbd_bucky; - dc_add_event(drv, &event); - } - } - } - else { - event.data = 0; - if (cont->buttons & CONT_DPAD_RIGHT) - event.data = SCI_K_RIGHT; - else if (cont->buttons & CONT_DPAD_LEFT) - event.data = SCI_K_LEFT; - else if (cont->buttons & CONT_DPAD_UP) - event.data = SCI_K_UP; - else if (cont->buttons & CONT_DPAD_DOWN) - event.data = SCI_K_DOWN; - event.type = SCI_EVT_KEYBOARD; - event.buckybits = bucky | vkbd_bucky; - if (event.data) dc_add_event(drv, &event); - } - event.data = 0; - if (cont->buttons & CONT_B) - event.data = SCI_K_ENTER; - else if (cont->buttons & CONT_X) - event.data = ' '; - else if (cont->buttons & CONT_Y) - event.data = SCI_K_ESC; - event.type = SCI_EVT_KEYBOARD; - event.buckybits = bucky | vkbd_bucky; - if (event.data) - dc_add_event(drv, &event); - } - } - else drv->capabilities &= ~GFX_CAPABILITY_MOUSE_SUPPORT; - - S->buckystate = bucky | vkbd_bucky; - } -} - -static uint32 -dc_get_color(struct _gfx_driver *drv, gfx_color_t col) -/* Converts a color as described in col to it's representation in memory -** Parameters: (_gfx_driver *) drv: The driver to use -** (gfx_color_t) color: The color to convert -** Returns : (uint32) the color's representation in memory -*/ -{ - uint32 retval; - uint32 temp; - - retval = 0; - - temp = col.visual.r; - temp |= temp << 8; - temp |= temp << 16; - retval |= (temp >> drv->mode->red_shift) & (drv->mode->red_mask); - temp = col.visual.g; - temp |= temp << 8; - temp |= temp << 16; - retval |= (temp >> drv->mode->green_shift) & (drv->mode->green_mask); - temp = col.visual.b; - temp |= temp << 8; - temp |= temp << 16; - retval |= (temp >> drv->mode->blue_shift) & (drv->mode->blue_mask); - - return retval; -} - -static void -dc_draw_line_buffer(byte *buf, int line, int bytespp, int x1, - int y1, int x2, int y2, uint32 color) -/* Draws a line in a buffer -** This function was taken from sdl_driver.c with small modifications -** Parameters: (byte *) buf: The buffer to draw in -** (int) line: line pitch of buf in bytes -** (int) bytespp: number of bytes per pixel of buf -** (int) x1, y1, x2, y2: The line to draw: (x1,y1)-(x2,y2). -** (uint32) color: The color to draw with -** Returns : (void) -*/ -{ - int pixx, pixy; - int x,y; - int dx,dy; - int sx,sy; - int swaptmp; - uint8 *pixel; - - dx = x2 - x1; - dy = y2 - y1; - sx = (dx >= 0) ? 1 : -1; - sy = (dy >= 0) ? 1 : -1; - - dx = sx * dx + 1; - dy = sy * dy + 1; - pixx = bytespp; - pixy = line; - pixel = ((uint8*) buf) + pixx * x1 + pixy * y1; - pixx *= sx; - pixy *= sy; - if (dx < dy) { - swaptmp = dx; dx = dy; dy = swaptmp; - swaptmp = pixx; pixx = pixy; pixy = swaptmp; - } - - x=0; - y=0; - switch(bytespp) { - case 1: - for(; x < dx; x++, pixel += pixx) { - *pixel = color; - y += dy; - if (y >= dx) { - y -= dx; - pixel += pixy; - } - } - break; - case 2: - for (; x < dx; x++, pixel += pixx) { - *(uint16*)pixel = color; - y += dy; - if (y >= dx) { - y -= dx; - pixel += pixy; - } - } - break; - case 4: - for(; x < dx; x++, pixel += pixx) { - *(uint32*)pixel = color; - y += dy; - if (y >= dx) { - y -= dx; - pixel += pixy; - } - } - break; - } - -} - -static void -dc_draw_filled_rect_buffer(byte *buf, int line, int bytespp, rect_t rect, - uint32 color) -/* Draws a filled rectangle in a buffer -** Parameters: (byte *) buf: The buffer to draw in -** (int) line: line pitch of buf in bytes -** (int) bytespp: number of bytes per pixel of buf -** (rect_t) rect: The rectangle to fill -** (uint32) color: The fill color -** Returns : (void) -*/ -{ - buf += rect.y*line + rect.x*bytespp; - int i; - - switch (bytespp) { - case 1: for (i = 0; i<rect.yl; i++) { - memset(buf, color, rect.xl); - buf += line; - } - break; - case 2: for (i = 0; i<rect.yl; i++) { - memset2(buf, color, rect.xl*2); - buf += line; - } - break; - case 4: for (i = 0; i<rect.yl; i++) { - memset4(buf, color, rect.xl*4); - buf += line; - } - } -} - - -static void -dc_copy_rect_buffer(byte *src, byte *dest, int srcline, int destline, - int bytespp, rect_t sr, point_t dp) -/* Copies a rectangle from one buffer to another -** Parameters: (byte *) src: The source buffer -** (byte *) dest: The destination buffer -** (int) srcline: line pitch of src in bytes -** (int) destline: line pitch of dest in bytes -** (int) bytespp: number of bytes per pixel of src and dest -** (rect_t) sr: Rectangle of src to copy -** (point_t) dp: Left top corner in dest where copy should go -** Returns : (void) -*/ -{ - src += sr.y*srcline + sr.x*bytespp; - dest += dp.y*destline + dp.x*bytespp; - int i; - - switch (bytespp) { - case 1: for (i = 0; i<sr.yl; i++) { - memcpy(dest, src, sr.xl); - src += srcline; - dest += destline; - } - break; - case 2: for (i = 0; i<sr.yl; i++) { - memcpy2(dest, src, sr.xl*2); - src += srcline; - dest += destline; - } - break; - case 4: for (i = 0; i<sr.yl; i++) { - memcpy4(dest, src, sr.xl*4); - src += srcline; - dest += destline; - } - } -} - -static int -dc_set_parameter(struct _gfx_driver *drv, char *attribute, char *value) -{ - if (!strcasecmp(attribute, "render_mode")) { - if (!strcasecmp(value, "vram")) { - flags &= ~SCI_DC_RENDER_PVR; - return GFX_OK; - } - else if (!strcasecmp(value, "pvr")) { - flags |= SCI_DC_RENDER_PVR; - return GFX_OK; - } - else { - sciprintf("Fatal error: Invalid value `%s' specified for attribute `render_mode'\n", value); - return GFX_FATAL; - } - } - if (!strcasecmp(attribute, "refresh_rate")) { - if (!strcasecmp(value, "60Hz")) { - flags &= ~SCI_DC_REFRESH_50HZ; - return GFX_OK; - } - else if (!strcasecmp(value, "50Hz")) { - flags |= SCI_DC_REFRESH_50HZ; - return GFX_OK; - } - else { - sciprintf("Fatal error: Invalid value `%s' specified for attribute `refresh_rate'\n", value); - return GFX_FATAL; - } - } - - sciprintf("Fatal error: Attribute '%s' does not exist\n", attribute); - return GFX_FATAL; -} - - -static int -dc_init_specific(struct _gfx_driver *drv, int xfact, int yfact, int bytespp) -{ - int i; - int rmask = 0, gmask = 0, bmask = 0, rshift = 0, gshift = 0; - int bshift = 0; - - sciprintf("Initialising video mode\n"); - - pvr_shutdown(); - - if (!drv->state /* = S */) - drv->state = sci_malloc(sizeof(struct _dc_state)); - if (!S) - return GFX_FATAL; - - if ((flags & SCI_DC_RENDER_PVR) && ((xfact != 1 && xfact != 2) - || bytespp != 2 || xfact != yfact)) { - sciprintf("Error: PVR rendering mode does not support " - "buffers with scale factors (%d,%d) and bpp=%d\n", - xfact, yfact, bytespp); - return GFX_ERROR; - } - else if ((xfact != 1 && xfact != 2) || (bytespp != 2 && bytespp != 4) - || xfact != yfact) { - sciprintf("Error: VRAM rendering mode does not support " - "buffers with scale factors (%d,%d) and bpp=%d\n", - xfact, yfact, bytespp); - return GFX_ERROR; - } - - for (i = 0; i < 2; i++) { - if (!(S->priority[i] = sci_malloc(320*xfact*200*yfact)) || - !(S->visual[i] = sci_malloc(320*xfact*200*yfact* bytespp))) { - sciprintf("Error: Could not reserve memory for buffer\n"); - return GFX_ERROR; - } - } - - for (i = 0; i < 2; i++) { - S->line_pitch[i] = 320*xfact*bytespp; - memset(S->visual[i], 0, 320*xfact*200*yfact*bytespp); - memset(S->priority[i], 0, 320*xfact*200*yfact); - } - - S->pointer_dx = 0; - S->pointer_dy = 0; - S->buckystate = 0; - S->timer = 0; - S->vkbd = 0; - - switch(bytespp) { - case 2: rmask = 0xF800; - gmask = 0x7E0; - bmask = 0x1F; - rshift = 16; - gshift = 21; - bshift = 27; - break; - case 4: rmask = 0xFF0000; - gmask = 0xFF00; - bmask = 0xFF; - rshift = 8; - gshift = 16; - bshift = 24; - } - - if (!(flags & SCI_DC_RENDER_PVR)) - vram_init_gfx(drv, xfact, yfact, bytespp); - else - pvr_init_gfx(drv, xfact, yfact, bytespp); - - drv->mode = gfx_new_mode(xfact, yfact, bytespp, rmask, gmask, bmask, 0, - rshift, gshift, bshift, 0, 0, 0); - - printf("Video mode initialisation completed succesfully\n"); - - S->run_thread = 1; - - S->thread = thd_create((void *) dc_input_thread, drv); - - S->first_event = NULL; - S->last_event = NULL; - - if (!(S->sem_event = sem_create(1)) || - !(S->sem_pointer = sem_create(1))) { - printf("Error: Could not reserve memory for semaphore\n"); - return GFX_ERROR; - }; - - return GFX_OK; -} - -static int -dc_init(struct _gfx_driver *drv) -{ - if (dc_init_specific(drv, 1, 1, 2) != GFX_OK) - return GFX_FATAL; - - return GFX_OK; -} - -static void -dc_exit(struct _gfx_driver *drv) -{ - if (S) { - sciprintf("Freeing graphics buffers\n"); - sci_free(S->visual[0]); - sci_free(S->visual[1]); - sci_free(S->priority[0]); - sci_free(S->priority[1]); - if (flags & SCI_DC_RENDER_PVR) { - pvr_mem_free(S->visual[2]); - pvr_mem_free(S->vkbd_txr); - } - - sciprintf("Waiting for input thread to exit... "); - S->run_thread = 0; - thd_wait(S->thread); - sciprintf("ok\n"); - - sciprintf("Freeing semaphores\n"); - sem_destroy(S->sem_event); - sem_destroy(S->sem_pointer); - sci_free(S); - drv->state /* = S */ = NULL; - } -} - - /*** Drawing operations ***/ - -static int -dc_draw_line(struct _gfx_driver *drv, point_t start, point_t end, - gfx_color_t color, gfx_line_mode_t line_mode, - gfx_line_style_t line_style) -{ - uint32 scolor; - int xfact = (line_mode == GFX_LINE_MODE_FINE)? 1: XFACT; - int yfact = (line_mode == GFX_LINE_MODE_FINE)? 1: YFACT; - int xsize = XFACT*320; - int ysize = YFACT*200; - - int xc, yc; - int x1, y1, x2, y2; - - scolor = dc_get_color(drv, color); - - for (xc = 0; xc < xfact; xc++) - for (yc = 0; yc < yfact; yc++) { - x1 = start.x + xc; - y1 = start.y + yc; - x2 = end.x + xc; - y2 = end.y + yc; - - if (x1 < 0) - x1 = 0; - if (x2 < 0) - x2 = 0; - if (y1 < 0) - y1 = 0; - if (y2 < 0) - y2 = 0; - - if (x1 > xsize) - x1 = xsize; - if (x2 >= xsize) - x2 = xsize - 1; - if (y1 > ysize) - y1 = ysize; - if (y2 >= ysize) - y2 = ysize - 1; - - if (color.mask & GFX_MASK_VISUAL) - dc_draw_line_buffer(S->visual[1], - XFACT*320*BYTESPP, BYTESPP, x1, y1, x2, y2, - dc_get_color(drv, color)); - - if (color.mask & GFX_MASK_PRIORITY) - dc_draw_line_buffer(S->priority[1], XFACT*320, - 1, x1, y1, x2, y2, color.priority); - } - - return GFX_OK; -} - -static int -dc_draw_filled_rect(struct _gfx_driver *drv, rect_t rect, - gfx_color_t color1, gfx_color_t color2, gfx_rectangle_fill_t shade_mode) -{ - if (color1.mask & GFX_MASK_VISUAL) - dc_draw_filled_rect_buffer(S->visual[1], S->line_pitch[1], - BYTESPP, rect, dc_get_color(drv, color1)); - - if (color1.mask & GFX_MASK_PRIORITY) - dc_draw_filled_rect_buffer(S->priority[1], XFACT*320, 1, rect, - color1.priority); - - return GFX_OK; -} - - /*** Pixmap operations ***/ - -static int -dc_register_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm) -{ - return GFX_ERROR; -} - -static int -dc_unregister_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm) -{ - return GFX_ERROR; -} - -static int -dc_draw_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm, int priority, - rect_t src, rect_t dest, gfx_buffer_t buffer) -{ - int bufnr = (buffer == GFX_BUFFER_STATIC)? 0:1; - - return gfx_crossblit_pixmap(drv->mode, pxm, priority, src, dest, - S->visual[bufnr], S->line_pitch[bufnr], S->priority[bufnr], XFACT*320, - 1, 0); -} - -static int -dc_grab_pixmap(struct _gfx_driver *drv, rect_t src, gfx_pixmap_t *pxm, - gfx_map_mask_t map) -{ - switch (map) { - case GFX_MASK_VISUAL: - dc_copy_rect_buffer(S->visual[1], pxm->data, - S->line_pitch[1], src.xl*BYTESPP, BYTESPP, src, - gfx_point(0, 0)); - pxm->xl = src.xl; - pxm->yl = src.yl; - return GFX_OK; - case GFX_MASK_PRIORITY: - dc_copy_rect_buffer(S->priority[1], pxm->index_data, - XFACT*320, src.xl, 1, src, gfx_point(0, 0)); - pxm->index_xl = src.xl; - pxm->index_yl = src.yl; - return GFX_OK; - default: - sciprintf("Error: attempt to grab pixmap from invalid map"); - return GFX_ERROR; - } -} - - - /*** Buffer operations ***/ - -static int -dc_update(struct _gfx_driver *drv, rect_t src, point_t dest, gfx_buffer_t buffer) -{ - int tbufnr = (buffer == GFX_BUFFER_BACK)? 1:2; - - dc_copy_rect_buffer(S->visual[tbufnr-1], S->visual[tbufnr], - S->line_pitch[tbufnr-1], S->line_pitch[tbufnr], BYTESPP, src, dest); - - if ((tbufnr == 1) && (src.x == dest.x) && (src.y == dest.y)) - dc_copy_rect_buffer(S->priority[0], S->priority[1], XFACT*320, - XFACT*320, 1, src, dest); - - return GFX_OK; -} - -static int -dc_set_static_buffer(struct _gfx_driver *drv, gfx_pixmap_t *pic, gfx_pixmap_t *priority) -{ - memcpy4(S->visual[0], pic->data, XFACT*320 * YFACT*200 * BYTESPP); - memcpy4(S->priority[0], priority->index_data, XFACT*320 * YFACT*200); - return GFX_OK; -} - - /*** Palette operations ***/ - -static int -dc_set_palette(struct _gfx_driver *drv, int index, byte red, byte green, byte blue) -{ - return GFX_ERROR; -} - - - /*** Mouse pointer operations ***/ - -static int -dc_set_pointer (struct _gfx_driver *drv, gfx_pixmap_t *pointer) -{ - return GFX_ERROR; -} - - /*** Event management ***/ - -static sci_event_t -dc_get_event(struct _gfx_driver *drv) -{ - sci_event_t event; - struct dc_event_t *first; - sem_wait(S->sem_pointer); - drv->pointer_x += S->pointer_dx; - drv->pointer_y += S->pointer_dy; - S->pointer_dx = 0; - S->pointer_dy = 0; - sem_signal(S->sem_pointer); - - if (drv->pointer_x < 0) - drv->pointer_x = 0; - if (drv->pointer_x >= 320*XFACT) - drv->pointer_x = 320*XFACT-1; - if (drv->pointer_y < 0) - drv->pointer_y = 0; - if (drv->pointer_y >= 200*YFACT) - drv->pointer_y = 200*YFACT-1; - - sem_wait(S->sem_event); - first = S->first_event; - - if (first) { - event = first->event; - S->first_event = first->next; - free(first); - if (S->first_event == NULL) S->last_event = NULL; - sem_signal(S->sem_event); - return event; - } - - sem_signal(S->sem_event); - event.type = SCI_EVT_NONE; - event.buckybits = S->buckystate; - return event; -} - - -static int -dc_usec_sleep(struct _gfx_driver *drv, long usecs) -{ - /* TODO: wake up on mouse move */ - int ms = usecs/1000; - if (ms) - thd_sleep(ms); - return GFX_OK; -} - -gfx_driver_t -gfx_driver_dc = { - "dc", - "0.2b", - SCI_GFX_DRIVER_MAGIC, - SCI_GFX_DRIVER_VERSION, - NULL, - 0, - 0, - GFX_CAPABILITY_FINE_LINES, - 0, - dc_set_parameter, - dc_init_specific, - dc_init, - dc_exit, - dc_draw_line, - dc_draw_filled_rect, - dc_register_pixmap, - dc_unregister_pixmap, - dc_draw_pixmap, - dc_grab_pixmap, - dc_update, - dc_set_static_buffer, - dc_set_pointer, - dc_set_palette, - dc_get_event, - dc_usec_sleep, - NULL -}; diff --git a/engines/sci/gfx/drivers/dd_driver.cpp b/engines/sci/gfx/drivers/dd_driver.cpp deleted file mode 100644 index f2920b4089..0000000000 --- a/engines/sci/gfx/drivers/dd_driver.cpp +++ /dev/null @@ -1,1021 +0,0 @@ -#ifndef __cplusplus -#error NOTE: This file MUST be compiled as C++. In Visual C++, use the /Tp command line option. -#endif - -// for WINNT 4.0 (only DirectDraw 3) -#ifdef HAVE_DDRAW - -#define DIRECTDRAW_VERSION 0x0300 - -#define INITGUID - -#include <windows.h> -#include <ddraw.h> -#include <stdarg.h> - -extern "C" { -#include <gfx_system.h> -#include <gfx_driver.h> -#include <gfx_tools.h> -#include <assert.h> -#include <uinput.h> -#include <ctype.h> -#include <console.h> // for sciprintf -#include <sci_memory.h> -}; - -#include "dd_driver.h" - -#define DD_DRIVER_VERSION "0.1" - -#define GFX_DD_DEBUG - - -#ifdef GFX_DD_DEBUG -#define POSMSG sciprintf("%s L%d:", __FILE__, __LINE__) -#define DEBUG_PTR (!(drv->debug_flags & GFX_DEBUG_POINTER))? 0 : POSMSG && sciprintf -#define DEBUG_UPDATES (!(drv->debug_flags & GFX_DEBUG_UPDATES))? 0 : POSMSG && sciprintf -#define DEBUG_PIXMAPS (!(drv->debug_flags & GFX_DEBUG_PIXMAPS))? 0 : POSMSG && sciprintf -#define DEBUG_BASIC (!(drv->debug_flags & GFX_DEBUG_BASIC))? 0 : POSMSG , sciprintf -#else /* !GFX_DD_DEBUG */ -#define DEBUG_PTR (1)? 0 : -#define DEBUG_UPDATES (1)? 0 : -#define DEBUG_PIXMAPS (1)? 0 : -#define DEBUG_BASIC (1)? 0 : -#endif /* !GFX_DD_DEBUG */ - -BOOL g_bFullScreen = FALSE; - -#define DD_BUFFER_BACK 0 -#define DD_BUFFER_STATIC 1 - -static long FAR PASCAL WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); -static int process_messages(void); - -struct gfx_dd_struct_t -{ - LPDIRECTDRAW pDD; - HWND hMainWnd; - LPDIRECTDRAWSURFACE pPrimary; - LPDIRECTDRAWSURFACE pBack; - LPDIRECTDRAWSURFACE pStatic; - LPDIRECTDRAWCLIPPER pClipper; // used in windowed (not fullscreen) mode - int win_xpos,win_ypos; // current position of the window (windowed mode only) - BOOL bShowMouse; - gfx_pixmap_t *priority_maps[2]; - // event queue - int queue_size,queue_first,queue_last; - sci_event_t * event_queue; -}; - -static void init_event_queue(gfx_dd_struct_t *ctx); -static void free_event_queue(gfx_dd_struct_t *ctx); - -static __inline DWORD MakeRGB(gfx_mode_t *mode,unsigned int r,unsigned int g,unsigned int b) -{ - return ((r << mode->red_shift) & mode->red_mask) | - ((g << mode->green_shift) & mode->green_mask) | - ((b << mode->blue_shift) & mode->blue_mask); -}; - -static int -dd_set_param(gfx_driver_t *drv, char *attribute, char *value) -{ - DEBUG_BASIC("dd_set_param('%s' to '%s')\n", attribute, value); - return GFX_OK; -} - -static int -ShiftCount(DWORD mask) -{ - int cnt; - - if(mask==0) - return 0; // error !!! - - cnt=0; - - while((mask & 1)==0) - { - mask >>=1; - cnt++; - } - return cnt; -} - -static int -dd_init_specific(gfx_driver_t *drv, int xres, int yres, int bpp) -{ - DDSURFACEDESC dd_desc,ddsd; - HRESULT hr; - WNDCLASS wc; - RECT rc; - POINT pnt; - gfx_dd_struct_t *ctx; - int dd_bpp,r_sh,g_sh,b_sh,dd_bpp2,tbytes; -// const ggi_pixelformat *pixelformat; - int frames = 3; - - // force .... - xres=1; yres=1; bpp=1; - - if(g_bFullScreen) - { - // force the best mode - xres=1; yres=1; bpp=1; - } - switch(bpp) // bpp of 8,16,24,32 - { - case 1: - dd_bpp=8; break; - case 2: - dd_bpp=16; break; - case 3: - dd_bpp=24; break; - case 4: - dd_bpp=32; break; - default: - sciprintf("GFXDD: Error: Invalid bytes per pixel value: %d\n", bpp); - return GFX_ERROR; - } - - drv->state = NULL; - - ctx = (struct gfx_dd_struct_t *) sci_malloc(sizeof(gfx_dd_struct_t)); - if(ctx == NULL) - return GFX_FATAL; - - memset(ctx,0,sizeof(gfx_dd_struct_t)); - - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = sizeof(void *); - wc.hInstance = NULL; - wc.hIcon = LoadIcon (NULL, IDI_APPLICATION); - wc.hCursor = NULL; /*LoadCursor (NULL, IDC_ARROW)*/; - wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = "freesci.WndClass"; - RegisterClass (&wc); - - SetRect (&rc, 0, 0, xres*320-1, yres*200-1); - if(!g_bFullScreen) - { - AdjustWindowRectEx (&rc, WS_OVERLAPPEDWINDOW, FALSE, 0); - } - - init_event_queue(ctx); - - ctx->hMainWnd = CreateWindowEx (0,"freesci.WndClass","FreeSCI", - g_bFullScreen ? WS_POPUP : (WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU), - 0,0,rc.right-rc.left,rc.bottom-rc.top,NULL,NULL,NULL,NULL); - - SetWindowLong(ctx->hMainWnd,0,(long) drv); - - hr = DirectDrawCreate(NULL,&(ctx->pDD),NULL); - if ( FAILED(hr)) - { - DestroyWindow(ctx->hMainWnd); - free(ctx); - return GFX_FATAL; - } - - - if(g_bFullScreen) - { - // fulscreen mode, change to the desired mode - hr = ctx->pDD->SetCooperativeLevel ( ctx->hMainWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); - hr = ctx->pDD->SetDisplayMode ( xres*320, yres*200, dd_bpp); - } - else - { - // windowed mode, accept whatever mode is current - hr = ctx->pDD->SetCooperativeLevel (ctx->hMainWnd, DDSCL_NORMAL); - } - - drv->state = ctx; - - ShowWindow(ctx->hMainWnd,SW_NORMAL); - UpdateWindow(ctx->hMainWnd); - - pnt.x = 0; pnt.y = 0; - ClientToScreen (ctx->hMainWnd, &pnt); - ctx->win_xpos = pnt.x; - ctx->win_ypos = pnt.y; - - // create surface - primary - memset(&dd_desc,0,sizeof(dd_desc)); - dd_desc.dwSize = sizeof(dd_desc); - dd_desc.dwFlags = DDSD_CAPS; - dd_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - hr = ctx->pDD->CreateSurface(&dd_desc,&ctx->pPrimary,NULL); - if(FAILED(hr)) - { - if(g_bFullScreen) - { - hr = ctx->pDD->RestoreDisplayMode (); - hr = ctx->pDD->SetCooperativeLevel (ctx->hMainWnd, DDSCL_NORMAL); - } - ctx->pDD->Release(); - free(ctx); - return GFX_FATAL; - } - - // get the current mode; in windowed mode it can be different than the one we want - memset(&dd_desc,0,sizeof(dd_desc)); - dd_desc.dwSize = sizeof(dd_desc); - hr = ctx->pDD->GetDisplayMode(&dd_desc); - - r_sh = ShiftCount(dd_desc.ddpfPixelFormat.dwRBitMask); - g_sh = ShiftCount(dd_desc.ddpfPixelFormat.dwGBitMask); - b_sh = ShiftCount(dd_desc.ddpfPixelFormat.dwBBitMask); - dd_bpp2=0; - if(dd_desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED1) - dd_bpp2=2; - if(dd_desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED2) - dd_bpp2=4; - if(dd_desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) - dd_bpp2=16; - if(dd_desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) - dd_bpp2=256; - - drv->mode = gfx_new_mode(xres,yres,dd_desc.ddpfPixelFormat.dwRGBBitCount/8, - dd_desc.ddpfPixelFormat.dwRBitMask,dd_desc.ddpfPixelFormat.dwGBitMask,dd_desc.ddpfPixelFormat.dwBBitMask,0, - r_sh,g_sh,b_sh,0, dd_bpp2, 0); - - tbytes = 320*xres*200*yres* (dd_desc.ddpfPixelFormat.dwRGBBitCount/8); - - // create a secondary surfaces - memset (&ddsd, 0, sizeof (DDSURFACEDESC)); - ddsd.dwSize = sizeof (DDSURFACEDESC); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; - ddsd.dwWidth = 320 * drv->mode->xfact; - ddsd.dwHeight = 200 * drv->mode->yfact; - hr = ctx->pDD->CreateSurface(&ddsd,&ctx->pBack,NULL); - if(FAILED(hr)) - { - return GFX_FATAL; - } - memset (&ddsd, 0, sizeof (DDSURFACEDESC)); - ddsd.dwSize = sizeof (DDSURFACEDESC); - hr = ctx->pBack->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); - if(!FAILED(hr)) - { - memset(ddsd.lpSurface,0,tbytes); - hr = ctx->pBack->Unlock(NULL); - } - - memset (&ddsd, 0, sizeof (DDSURFACEDESC)); - ddsd.dwSize = sizeof (DDSURFACEDESC); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; - ddsd.dwWidth = 320 * drv->mode->xfact; - ddsd.dwHeight = 200 * drv->mode->yfact; - hr = ctx->pDD->CreateSurface(&ddsd,&ctx->pStatic,NULL); - if(FAILED(hr)) - { - return GFX_FATAL; - } - memset (&ddsd, 0, sizeof (DDSURFACEDESC)); - ddsd.dwSize = sizeof (DDSURFACEDESC); - hr = ctx->pStatic->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); - if(!FAILED(hr)) - { - memset(ddsd.lpSurface,0,tbytes); - hr = ctx->pStatic->Unlock(NULL); - } - - // if not in full-screen mode, set the clipper - if (!g_bFullScreen) - { - hr = ctx->pDD->CreateClipper (0, &ctx->pClipper, NULL); - hr = ctx->pClipper->SetHWnd (0, ctx->hMainWnd); - hr = ctx->pPrimary->SetClipper (ctx->pClipper); - } - - ctx->priority_maps[DD_BUFFER_BACK] = - gfx_pixmap_alloc_index_data(gfx_new_pixmap(320 * xres, 200 * yres, GFX_RESID_NONE, 0, 0)); - ctx->priority_maps[DD_BUFFER_STATIC] = - gfx_pixmap_alloc_index_data(gfx_new_pixmap(320 * xres, 200 * yres, GFX_RESID_NONE, 0, 0)); - - ctx->priority_maps[DD_BUFFER_BACK]->flags |= GFX_PIXMAP_FLAG_SCALED_INDEX; - ctx->priority_maps[DD_BUFFER_STATIC]->flags |= GFX_PIXMAP_FLAG_SCALED_INDEX; - -/* - if (_open_meta_visuals(drv)) { - free(meta); - gfx_free_pixmap(drv, meta->priority_maps[GGI_BUFFER_BACK]); - gfx_free_pixmap(drv, meta->priority_maps[GGI_BUFFER_STATIC]); - ggiClose(meta->vis); - ggiExit(); - return GFX_ERROR; - } - - if (frames < 2) { - meta->alt_back_buffer = sci_malloc(bpp * 320 * 200 * xres * yres); - meta->back_vis = ggiOpen("memory:pointer", meta->alt_back_buffer, NULL); - if (ggiSetSimpleMode(meta->back_vis, xres * 320, yres * 200, 1, GT_8BIT)) { - sciprintf("GFXGGI: Warning: Setting mode for memory visual failed\n"); - } - } else meta->alt_back_buffer = NULL; - - if (frames < 3) { - meta->static_buffer = sci_malloc(bpp * 320 * 200 * xres * yres); - meta->static_vis = ggiOpen("memory:pointer", meta->static_buffer, NULL); - if (ggiSetSimpleMode(meta->static_vis, xres * 320, yres * 200, 1, GT_8BIT)) { - sciprintf("GFXGGI: Warning: Setting mode for memory visual #2 failed\n"); - } - } else meta->static_buffer = NULL; - - init_input_ggi(); -*/ - return GFX_OK; -} - -int -dd_init(gfx_driver_t *drv) -{ - return dd_init_specific(drv,1,1,1); -} - -void -dd_exit(gfx_driver_t *drv) -{ - HRESULT hr; - gfx_dd_struct_t *ctx; - - if(drv->state == NULL) - return; - - ctx = (gfx_dd_struct_t *) drv->state; - - if(g_bFullScreen) - { - hr = ctx->pDD->RestoreDisplayMode (); - hr = ctx->pDD->SetCooperativeLevel (ctx->hMainWnd, DDSCL_NORMAL); - } - - free_event_queue(ctx); - - gfx_free_pixmap(drv, ctx->priority_maps[0]); - gfx_free_pixmap(drv, ctx->priority_maps[1]); - - if(ctx->hMainWnd) - { - DestroyWindow(ctx->hMainWnd); - ctx->hMainWnd = NULL; - } - - if(ctx->pBack) - { - ctx->pBack->Release(); - ctx->pBack=NULL; - } - if(ctx->pStatic) - { - ctx->pStatic->Release(); - ctx->pStatic=NULL; - } - if(ctx->pPrimary) - { - ctx->pPrimary->Release(); - ctx->pPrimary=NULL; - } - if(ctx->pClipper) - { - ctx->pClipper->Release(); - ctx->pClipper=NULL; - } - if(ctx->pDD) - { - ctx->pDD->Release(); - ctx->pDD = NULL; - } - - drv->state = NULL; - - free(ctx); -} - -int -dd_draw_line(gfx_driver_t *drv, - point_t start, point_t end, - gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style) -{ - rect_t line = gfx_rect(start.x, start.y, - end.x - start.x, end.y - start.y); - HRESULT hr; - DDSURFACEDESC ddsc; - gfx_dd_struct_t *ctx; - - if(drv->state == NULL) - return GFX_ERROR; - - ctx = (gfx_dd_struct_t *) drv->state; - - memset(&ddsc,0,sizeof(ddsc)); - ddsc.dwSize = sizeof(ddsc); - hr = ctx->pBack->Lock(NULL,&ddsc,DDLOCK_WAIT,NULL); - if(FAILED(hr)) - { - return GFX_ERROR; - } - - _dd_draw_line(drv->mode, start, end, (byte *) ddsc.lpSurface, ddsc.lPitch,color); - -// gfx_crossblit_pixmap(drv->mode, pxm, priority, src, dest, (byte *) ddsc.lpSurface, -// ddsc.lPitch,pri_map, drv->mode->xfact * 320, 1); - - hr = ctx->pBack->Unlock(NULL); - return GFX_OK; -} - -int -dd_draw_filled_rect(gfx_driver_t *drv, rect_t box, gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode) -{ - HRESULT hr; - RECT rcDest; - DDBLTFX ddblt; - gfx_dd_struct_t *ctx; - byte *pri; - int i; - - if(drv->state == NULL) - return GFX_ERROR; - - ctx = (gfx_dd_struct_t *) drv->state; - - rcDest.left = box.x; - rcDest.top = box.y; - rcDest.right = box.x+box.xl; - rcDest.bottom = box.y+box.yl; - - if (color1.mask & GFX_MASK_VISUAL) - { - memset(&ddblt,0,sizeof(ddblt)); - ddblt.dwSize = sizeof(ddblt); - if(drv->mode->palette!=NULL) - ddblt.dwFillColor = color1.visual.global_index; - else - ddblt.dwFillColor = MakeRGB(drv->mode,color1.visual.r,color1.visual.g,color1.visual.b); - hr = ctx->pBack->Blt(&rcDest,NULL,NULL,DDBLT_COLORFILL,&ddblt); - } - - if (color1.mask & GFX_MASK_PRIORITY) - { - pri = ctx->priority_maps[DD_BUFFER_BACK]->index_data + box.x + box.y*(drv->mode->xfact * 320); - for(i=0; i<box.yl; i++) - { - memset(pri,color1.priority,box.xl); - pri += drv->mode->xfact * 320; - } - } - - return GFX_OK; -} - -int -dd_draw_pixmap(gfx_driver_t *drv, gfx_pixmap_t *pxm, int priority, - rect_t src, rect_t dest, gfx_buffer_t buffer) -{ - HRESULT hr; - gfx_dd_struct_t *ctx; - LPDIRECTDRAWSURFACE dst; - DDSURFACEDESC ddsc; - byte *pri_map = NULL; - - if(drv->state == NULL) - return GFX_ERROR; - - ctx = (gfx_dd_struct_t *) drv->state; - - if (src.xl != dest.xl || src.yl != dest.yl) - { - GFXERROR("Attempt to draw scaled view- not supported by this driver!\n"); - return GFX_FATAL; /* Scaling not supported! */ - } - - switch(buffer) - { - case GFX_BUFFER_FRONT: - GFXERROR("Attempt to draw pixmap to front buffer\n"); - return GFX_ERROR; - case GFX_BUFFER_BACK: - dst = ctx->pBack; - pri_map = ctx->priority_maps[DD_BUFFER_BACK]->index_data; - break; - case GFX_BUFFER_STATIC: - dst = ctx->pStatic; - pri_map = ctx->priority_maps[DD_BUFFER_STATIC]->index_data; - break; - default: - GFXERROR("Unexpected buffer ID %d\n", buffer); - return GFX_ERROR; - } - - memset(&ddsc,0,sizeof(ddsc)); - ddsc.dwSize = sizeof(ddsc); - hr = dst->Lock(NULL,&ddsc,DDLOCK_WAIT,NULL); - if(FAILED(hr)) - { - return GFX_ERROR; - } - - gfx_crossblit_pixmap(drv->mode, pxm, priority, src, dest, (byte *) ddsc.lpSurface, - ddsc.lPitch,pri_map, drv->mode->xfact * 320, 1, 0); - - hr = dst->Unlock(NULL); - - return GFX_OK; -} - -int -dd_grab_pixmap(gfx_driver_t *drv, rect_t src, gfx_pixmap_t *pxm, gfx_map_mask_t map) -{ - HRESULT hr; - gfx_dd_struct_t *ctx; - DDSURFACEDESC ddsc; - int i,x,y,xlb,bpp; - BYTE *s,*d; - - if(drv->state == NULL) - return GFX_ERROR; - - ctx = (gfx_dd_struct_t *) drv->state; - - if (src.x < 0 || src.y < 0) - { - GFXERROR("Attempt to grab pixmap from invalid coordinates (%d,%d)\n", src.x, src.y); - return GFX_ERROR; - } - - if (!pxm->data) - { - GFXERROR("Attempt to grab pixmap to unallocated memory\n"); - return GFX_ERROR; - } - - pxm->xl = src.xl; - pxm->yl = src.yl; - - memset(&ddsc,0,sizeof(ddsc)); - ddsc.dwSize = sizeof(ddsc); - hr = ctx->pBack->Lock(NULL,&ddsc,DDLOCK_WAIT,NULL); - if(FAILED(hr)) - return GFX_ERROR; - - bpp = ddsc.ddpfPixelFormat.dwRGBBitCount / 8; - x = src.x*drv->mode->xfact; - y = src.y*drv->mode->yfact; -/* - if(!g_bFullScreen) - { - x += ctx->win_xpos; - y += ctx->win_ypos; - } -*/ - s = (BYTE *) ddsc.lpSurface + x*bpp + y*ddsc.lPitch; - d = pxm->data; - xlb = src.xl * bpp; - - for(i=0; i<src.yl; i++) - { - memcpy(d,s,xlb); - d += xlb; - s += ddsc.lPitch; - } - - hr = ctx->pBack->Unlock(NULL); - - return GFX_OK; -} - -static int -dd_update(gfx_driver_t *drv, rect_t src, point_t dest, gfx_buffer_t buffer) -{ - gfx_dd_struct_t *ctx; - RECT rcDst,rcSrc; - HRESULT hr; - LPDIRECTDRAWSURFACE p_dst,p_src; - - if(drv->state == NULL) - return GFX_ERROR; - - ctx = (gfx_dd_struct_t *) drv->state; - - rcSrc.left = src.x; - rcSrc.right = src.x + src.xl; - rcSrc.top = src.y; - rcSrc.bottom = src.y + src.yl; - - rcDst.left = dest.x; - rcDst.right = dest.x + src.xl; - rcDst.top = dest.y; - rcDst.bottom = dest.y + src.yl; - - switch(buffer) - { - case GFX_BUFFER_FRONT: - rcDst.left += ctx->win_xpos; - rcDst.right += ctx->win_xpos; - rcDst.top += ctx->win_ypos; - rcDst.bottom += ctx->win_ypos; - p_dst = ctx->pPrimary; - p_src = ctx->pBack; - break; - case GFX_BUFFER_BACK: - p_dst = ctx->pBack; - p_src = ctx->pStatic; - break; - default: - return GFX_ERROR; - } - - hr = p_dst->Blt(&rcDst,p_src,&rcSrc,DDBLT_WAIT,NULL); - if(FAILED(hr)) - return GFX_ERROR; - - return GFX_OK; -} - -static int -dd_set_static_buffer(gfx_driver_t *drv, gfx_pixmap_t *pic, gfx_pixmap_t *priority) -{ - gfx_dd_struct_t *ctx; - DDSURFACEDESC ddsc; - HRESULT hr; - int i,xs; - byte *s,*d; -// ggi_visual_t vis = get_writeable_static_visual(drv); - - if(drv->state == NULL) - return GFX_ERROR; - - ctx = (gfx_dd_struct_t *) drv->state; - - /* First, check if the priority map is sane */ - if (priority->index_xl != ctx->priority_maps[DD_BUFFER_STATIC]->index_xl - || priority->index_yl != ctx->priority_maps[DD_BUFFER_STATIC]->index_yl) - { - GFXERROR("Invalid priority map: (%dx%d) vs expected (%dx%d)\n", - priority->index_xl, priority->index_yl, - ctx->priority_maps[DD_BUFFER_STATIC]->index_xl, - ctx->priority_maps[DD_BUFFER_STATIC]->index_yl); - return GFX_ERROR; - } - -// ggiPutBox(vis, 0, 0, pic->xl, pic->yl, pic->data); - memset(&ddsc,0,sizeof(ddsc)); - ddsc.dwSize = sizeof(ddsc); - hr = ctx->pStatic->Lock(NULL,&ddsc,DDLOCK_WAIT,NULL); - if(FAILED(hr)) - { - return GFX_ERROR; - } - - s = pic->data; - d = (byte *) ddsc.lpSurface; - xs = drv->mode->bytespp * pic->xl; - - for(i=0; i<pic->yl; i++) - { - memcpy(d,s,xs); - s+= xs; - d+= ddsc.lPitch; - } - - hr = ctx->pStatic->Unlock(NULL); - - memcpy(ctx->priority_maps[DD_BUFFER_STATIC]->index_data, priority->index_data, - priority->index_xl * priority->index_yl); - - return GFX_OK; -} - -static int -dd_set_palette(gfx_driver_t *drv, int index, byte red, byte green, byte blue) -{ - //!! implement me !! - return GFX_ERROR; -} - -// ------------------------------------- non-drawing functions ------------------------------------ -sci_event_t get_queue_event(gfx_dd_struct_t *ctx); - -static int process_messages(void) -{ - MSG msg; - - while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) - { - if (!GetMessage (&msg, NULL, 0, 0)) - return 0; - TranslateMessage (&msg); - DispatchMessage(&msg); - } - return 1; -} - -static sci_event_t -dd_get_event(gfx_driver_t *drv) -{ - gfx_dd_struct_t *ctx; - - process_messages(); - - assert(drv->state!=NULL); - - ctx = (gfx_dd_struct_t *) drv->state; - - return get_queue_event(ctx); -} - -static void -MsgWait (long WaitTime) -{ - DWORD dwRet=0; - long dwWait; - DWORD StartTime=timeGetTime(); - - dwWait = WaitTime; - - if (!process_messages()) - return; - - if (dwWait <= 0) - return; - do - { - dwWait=WaitTime-(timeGetTime()-StartTime); - if (dwWait <= 0) - break; - - dwRet=MsgWaitForMultipleObjects (0, NULL, FALSE, dwWait, QS_ALLINPUT); - - if(dwRet == WAIT_TIMEOUT) - return; - - if (!process_messages()) - return; - - } while(1); -} - -int -dd_usleep(gfx_driver_t* drv, long usec) -{ - if (usec < 1000) - Sleep(usec / 1000); - else - MsgWait (usec / 1000); - - return GFX_OK; -} -/* --------------------------------------------------------------- */ - -static void init_event_queue(gfx_dd_struct_t *ctx) -{ - ctx->queue_first = 0; - ctx->queue_last = 0; - ctx->queue_size = 256; - ctx->event_queue = (sci_event_t *) sci_malloc (ctx->queue_size * sizeof (sci_event_t)); -} - -static void free_event_queue(gfx_dd_struct_t *ctx) -{ - if (ctx->event_queue) sci_free(ctx->event_queue); - ctx->queue_size = 0; - ctx->queue_first =0; - ctx->queue_last =0; -} - -static void add_queue_event(gfx_dd_struct_t *ctx,int type, int data, int buckybits) -{ - if ((ctx->queue_last+1) % ctx->queue_size == ctx->queue_first) - { - /* Reallocate queue */ - int i, event_count; - sci_event_t *new_queue; - - new_queue = (sci_event_t *) sci_malloc (ctx->queue_size * 2 * sizeof (sci_event_t)); - event_count = (ctx->queue_last - ctx->queue_first) % ctx->queue_size; - for (i=0; i<event_count; i++) - new_queue [i] = ctx->event_queue [(ctx->queue_first+i) % ctx->queue_size]; - free (ctx->event_queue); - ctx->event_queue = new_queue; - ctx->queue_size *= 2; - ctx->queue_first = 0; - ctx->queue_last = event_count; - } - - ctx->event_queue [ctx->queue_last].data = data; - ctx->event_queue [ctx->queue_last].type = type; - ctx->event_queue [ctx->queue_last++].buckybits = buckybits; - if (ctx->queue_last == ctx->queue_size) - ctx->queue_last=0; -} - -static void add_mouse_event (gfx_dd_struct_t *ctx,int type, int data, WPARAM wParam) -{ - int buckybits = 0; - - if (wParam & MK_SHIFT) - buckybits |= SCI_EVM_LSHIFT | SCI_EVM_RSHIFT; - if (wParam & MK_CONTROL) - buckybits |= SCI_EVM_CTRL; - - add_queue_event (ctx,type, data, buckybits); -} - -static void add_key_event (gfx_dd_struct_t *ctx,int data) -{ - int buckybits = 0; - - /* FIXME: If anyone cares, on Windows NT we can distinguish left and right shift */ - if (GetAsyncKeyState (VK_SHIFT)) - buckybits |= SCI_EVM_LSHIFT | SCI_EVM_RSHIFT; - if (GetAsyncKeyState (VK_CONTROL)) - buckybits |= SCI_EVM_CTRL; - if (GetAsyncKeyState (VK_MENU)) - buckybits |= SCI_EVM_ALT; - if (GetKeyState (VK_CAPITAL) & 1) - buckybits |= SCI_EVM_CAPSLOCK; - - add_queue_event (ctx,SCI_EVT_KEYBOARD, data, buckybits); -} - -sci_event_t get_queue_event(gfx_dd_struct_t *ctx) -{ - if (ctx->queue_first == ctx->queue_size) - ctx->queue_first = 0; - - if (ctx->queue_first == ctx->queue_last) - { - sci_event_t noevent; - noevent.data = 0; - noevent.type = SCI_EVT_NONE; - noevent.buckybits = 0; - return noevent; - } - else - return ctx->event_queue [ctx->queue_first++]; -} - -#define MAP_KEY(x,y) case x: add_key_event (ctx, y); break - -static long FAR PASCAL WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - HRESULT hr; - gfx_dd_struct_t *ctx; - gfx_driver_t* drv; - - drv = (gfx_driver_t *) GetWindowLong(hWnd,0); - if(drv == NULL) - return DefWindowProc(hWnd,message,wParam,lParam); - ctx = (gfx_dd_struct_t *) drv->state; - if(ctx == NULL) - return DefWindowProc(hWnd,message,wParam,lParam); - - switch(message) - { - case WM_SIZE: - case WM_MOVE: - { - POINT pnt; - pnt.x = 0; pnt.y = 0; - ClientToScreen (hWnd, &pnt); - ctx->win_xpos = pnt.x; - ctx->win_ypos = pnt.y; - } - break; - case WM_PAINT: - { - RECT rcSrc,rcDst; - if (ctx->pPrimary!=NULL && ctx->pBack!=NULL && GetUpdateRect (hWnd, &rcSrc, FALSE)) - { - if(rcSrc.right>320) - rcSrc.right=320; - if(rcSrc.bottom>200) - rcSrc.bottom=200; - rcDst.left = rcSrc.left + ctx->win_xpos; - rcDst.right = rcSrc.right + ctx->win_xpos; - rcDst.top = rcSrc.top + ctx->win_ypos; - rcDst.bottom = rcSrc.bottom + ctx->win_ypos; - hr = ctx->pPrimary->Blt(&rcDst,ctx->pBack,&rcSrc,DDBLT_WAIT,NULL); - ValidateRect(hWnd,&rcSrc); - } - } - break; - case WM_SETCURSOR: - if(IsIconic(hWnd) || ctx->bShowMouse) - { - SetCursor(LoadCursor (NULL, IDC_ARROW)); - } - else - { - SetCursor(NULL); - } - return TRUE; - case WM_NCMOUSEMOVE: - ctx->bShowMouse = TRUE; - break; - case WM_MOUSEMOVE: - ctx->bShowMouse = FALSE; - if( ((lParam & 0xFFFF) >= 320*drv->mode->xfact) || ((lParam >> 16) >= 200*drv->mode->yfact)) - break; - drv->pointer_x = lParam & 0xFFFF; - drv->pointer_y = lParam >> 16; - break; - - case WM_LBUTTONDOWN: add_mouse_event (ctx, SCI_EVT_MOUSE_PRESS, 1, wParam); break; - case WM_RBUTTONDOWN: add_mouse_event (ctx, SCI_EVT_MOUSE_PRESS, 2, wParam); break; - case WM_MBUTTONDOWN: add_mouse_event (ctx, SCI_EVT_MOUSE_PRESS, 3, wParam); break; - case WM_LBUTTONUP: add_mouse_event (ctx, SCI_EVT_MOUSE_RELEASE, 1, wParam); break; - case WM_RBUTTONUP: add_mouse_event (ctx, SCI_EVT_MOUSE_RELEASE, 2, wParam); break; - case WM_MBUTTONUP: add_mouse_event (ctx, SCI_EVT_MOUSE_RELEASE, 3, wParam); break; - - case WM_KEYDOWN: - switch (wParam) - { - MAP_KEY (VK_ESCAPE, SCI_K_ESC); - MAP_KEY (VK_END, SCI_K_END); - MAP_KEY (VK_DOWN, SCI_K_DOWN); - MAP_KEY (VK_NEXT, SCI_K_PGDOWN); - MAP_KEY (VK_LEFT, SCI_K_LEFT); - MAP_KEY (VK_RIGHT, SCI_K_RIGHT); - MAP_KEY (VK_HOME, SCI_K_HOME); - MAP_KEY (VK_UP, SCI_K_UP); - MAP_KEY (VK_PRIOR, SCI_K_PGUP); - MAP_KEY (VK_INSERT, SCI_K_INSERT); - MAP_KEY (VK_DELETE, SCI_K_DELETE); - MAP_KEY (VK_BACK, SCI_K_BACKSPACE); - MAP_KEY (VK_TAB, '\t'); - MAP_KEY (VK_RETURN, '\r'); - - default: - if (wParam >= VK_F1 && wParam <= VK_F10) - add_key_event (ctx, wParam - VK_F1 + SCI_K_F1); - else if (wParam >= 'A' && wParam <= 'Z') - add_key_event (ctx, wParam - 'A' + 97); - else if (wParam >= VK_NUMPAD0 && wParam <= VK_NUMPAD9) - { - if (GetKeyState (VK_NUMLOCK) & 1) - add_key_event (ctx, wParam - VK_NUMPAD0 + '0'); - else - switch (wParam) - { - MAP_KEY (VK_NUMPAD0, SCI_K_INSERT); - MAP_KEY (VK_NUMPAD1, SCI_K_END); - MAP_KEY (VK_NUMPAD2, SCI_K_DOWN); - MAP_KEY (VK_NUMPAD3, SCI_K_PGDOWN); - MAP_KEY (VK_NUMPAD4, SCI_K_LEFT); - MAP_KEY (VK_NUMPAD6, SCI_K_RIGHT); - MAP_KEY (VK_NUMPAD7, SCI_K_HOME); - MAP_KEY (VK_NUMPAD8, SCI_K_UP); - MAP_KEY (VK_NUMPAD9, SCI_K_PGUP); - } - } - else if (wParam == 0xC0) /* tilde key - used for invoking console */ - add_key_event (ctx, '`'); - else - add_key_event (ctx, wParam); - break; - } - } - return DefWindowProc(hWnd,message,wParam,lParam); -} - -/* --------------------------------------------------------------- */ -extern "C" -gfx_driver_t gfx_driver_dd = { - "ddraw", - DD_DRIVER_VERSION, - SCI_GFX_DRIVER_MAGIC, - SCI_GFX_DRIVER_VERSION, - NULL, - 0,0, - 0, - GFX_DEBUG_POINTER | GFX_DEBUG_UPDATES | GFX_DEBUG_PIXMAPS | GFX_DEBUG_BASIC, - dd_set_param, - dd_init_specific, - dd_init, - dd_exit, - dd_draw_line, - dd_draw_filled_rect, - NULL, - NULL, - dd_draw_pixmap, - dd_grab_pixmap, - dd_update, - dd_set_static_buffer, - NULL, - dd_set_palette, - dd_get_event, - dd_usleep -}; - -#endif // HAVE_DDRAW diff --git a/engines/sci/gfx/drivers/dd_driver.h b/engines/sci/gfx/drivers/dd_driver.h deleted file mode 100644 index 209fe51569..0000000000 --- a/engines/sci/gfx/drivers/dd_driver.h +++ /dev/null @@ -1,2 +0,0 @@ - -void _dd_draw_line(gfx_mode_t * mode, rect_t line, byte * dest, int linewidth,gfx_color_t color); diff --git a/engines/sci/gfx/drivers/dd_driver_line.cpp b/engines/sci/gfx/drivers/dd_driver_line.cpp deleted file mode 100644 index e83b368a5e..0000000000 --- a/engines/sci/gfx/drivers/dd_driver_line.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef __cplusplus -#error NOTE: This file MUST be compiled as C++. In Visual C++, use the /Tp command line option. -#endif - -extern "C" { -#include <gfx_system.h> -#include <gfx_tools.h> -}; - -#define LINEMACRO_1(startx, starty, deltalinear, deltanonlinear, linearvar, nonlinearvar, \ - linearend, nonlinearstart, linearmod, nonlinearmod) \ - x = (startx); y = (starty); \ - incrNE = ((deltalinear) > 0)? (deltalinear) : -(deltalinear); \ - incrNE <<= 1; \ - deltanonlinear <<= 1; \ - incrE = ((deltanonlinear) > 0) ? -(deltanonlinear) : (deltanonlinear); \ - d = nonlinearstart-1; \ - while (linearvar != (linearend)) { \ - buffer[linewidth * y + x] = color; \ - linearvar += linearmod; \ - if ((d+=incrE) < 0) { \ - d += incrNE; \ - nonlinearvar += nonlinearmod; \ - }; \ - }; \ - buffer[linewidth * y + x] = color; - -#define LINEMACRO_N(startx, starty, deltalinear, deltanonlinear, linearvar, nonlinearvar, \ - linearend, nonlinearstart, linearmod, nonlinearmod) \ - x = (startx); y = (starty); \ - incrNE = ((deltalinear) > 0)? (deltalinear) : -(deltalinear); \ - incrNE <<= 1; \ - deltanonlinear <<= 1; \ - incrE = ((deltanonlinear) > 0) ? -(deltanonlinear) : (deltanonlinear); \ - d = nonlinearstart-1; \ - while (linearvar != (linearend)) { \ - memcpy(&buffer[linewidth * y + bpp*x],&color,bpp); \ - linearvar += linearmod; \ - if ((d+=incrE) < 0) { \ - d += incrNE; \ - nonlinearvar += nonlinearmod; \ - }; \ - }; \ - memcpy(&buffer[linewidth * y + x],&color,bpp); - -void _dd_draw_line_buffer_1(byte *buffer, int linewidth, rect_t line, int color) -{ - /*void dither_line(picture_t buffers, int curx, int cury, short x1, short y1, - int col1, int col2, int priority, int special, char drawenable)*/ - - int dx, dy, incrE, incrNE, d, finalx, finaly; - int x = line.x; - int y = line.y; - dx = line.xl; - dy = line.yl; - finalx = x + dx; - finaly = y + dy; - - dx = abs(dx); - dy = abs(dy); - - if (dx > dy) { - if (finalx < x) { - if (finaly < y) { /* llu == left-left-up */ - LINEMACRO_1(x, y, dx, dy, x, y, finalx, dx, -1, -1); - } else { /* lld */ - LINEMACRO_1(x, y, dx, dy, x, y, finalx, dx, -1, 1); - } - } else { /* x1 >= x */ - if (finaly < y) { /* rru */ - LINEMACRO_1(x, y, dx, dy, x, y, finalx, dx, 1, -1); - } else { /* rrd */ - LINEMACRO_1(x, y, dx, dy, x, y, finalx, dx, 1, 1); - } - } - } else { /* dx <= dy */ - if (finaly < y) { - if (finalx < x) { /* luu */ - LINEMACRO_1(x, y, dy, dx, y, x, finaly, dy, -1, -1); - } else { /* ruu */ - LINEMACRO_1(x, y, dy, dx, y, x, finaly, dy, -1, 1); - } - } else { /* y1 >= y */ - if (finalx < x) { /* ldd */ - LINEMACRO_1(x, y, dy, dx, y, x, finaly, dy, 1, -1); - } else { /* rdd */ - LINEMACRO_1(x, y, dy, dx, y, x, finaly, dy, 1, 1); - } - } - } -} - -void _dd_draw_line_buffer_n(int bpp,byte *buffer, int linewidth, rect_t line, byte * color) -{ - /*void dither_line(picture_t buffers, int curx, int cury, short x1, short y1, - int col1, int col2, int priority, int special, char drawenable)*/ - - int dx, dy, incrE, incrNE, d, finalx, finaly; - int x = line.x; - int y = line.y; - dx = line.xl; - dy = line.yl; - finalx = x + dx; - finaly = y + dy; - - dx = abs(dx); - dy = abs(dy); - - if (dx > dy) { - if (finalx < x) { - if (finaly < y) { /* llu == left-left-up */ - LINEMACRO_N(x, y, dx, dy, x, y, finalx, dx, -1, -1); - } else { /* lld */ - LINEMACRO_N(x, y, dx, dy, x, y, finalx, dx, -1, 1); - } - } else { /* x1 >= x */ - if (finaly < y) { /* rru */ - LINEMACRO_N(x, y, dx, dy, x, y, finalx, dx, 1, -1); - } else { /* rrd */ - LINEMACRO_N(x, y, dx, dy, x, y, finalx, dx, 1, 1); - } - } - } else { /* dx <= dy */ - if (finaly < y) { - if (finalx < x) { /* luu */ - LINEMACRO_N(x, y, dy, dx, y, x, finaly, dy, -1, -1); - } else { /* ruu */ - LINEMACRO_N(x, y, dy, dx, y, x, finaly, dy, -1, 1); - } - } else { /* y1 >= y */ - if (finalx < x) { /* ldd */ - LINEMACRO_N(x, y, dy, dx, y, x, finaly, dy, 1, -1); - } else { /* rdd */ - LINEMACRO_N(x, y, dy, dx, y, x, finaly, dy, 1, 1); - } - } - } -} - -void _dd_draw_line(gfx_mode_t * mode, rect_t line, byte * dest, int linewidth,gfx_color_t color) -{ - byte ca[4]; - unsigned short co1; - - switch(mode->bytespp) - { - case 1: - _dd_draw_line_buffer_1(dest,linewidth,line,color.visual.global_index); - break; - case 2: - co1 = (color.visual.r << mode->red_shift) & mode->red_mask; - co1 |= (color.visual.g << mode->green_shift) & mode->green_mask; - co1 |= (color.visual.b << mode->blue_shift) & mode->blue_mask; - _dd_draw_line_buffer_n(2,dest,linewidth,line, (byte *) &co1); - break; - case 3: - ca[mode->red_shift/8]=color.visual.r; - ca[mode->green_shift/8]=color.visual.g; - ca[mode->blue_shift/8]=color.visual.b; - _dd_draw_line_buffer_n(3,dest,linewidth,line, ca); - break; - } -} diff --git a/engines/sci/gfx/drivers/directfb_driver.c b/engines/sci/gfx/drivers/directfb_driver.c deleted file mode 100644 index 634b2b11df..0000000000 --- a/engines/sci/gfx/drivers/directfb_driver.c +++ /dev/null @@ -1,1033 +0,0 @@ -/*************************************************************************** - directfb_driver.c Copyright (C) 2002 Christoph Reichenbach - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Christoph Reichenbach (CR) <jameson@linuxgames.com> - -***************************************************************************/ -/* FreeSCI 0.3.1+ graphics driver module for libdirectfb */ - - -#include <stdarg.h> -#include <gfx_system.h> -#include <gfx_driver.h> -#include <gfx_tools.h> -#include <assert.h> -#include <uinput.h> - -#ifdef HAVE_DIRECTFB - -#include <stdio.h> -#include <stdlib.h> -#include <directfb/directfb.h> -#include <unistd.h> - -#define SCIDFB_DRIVER_VERSION "0.4" - -typedef struct _event_queue_struct { - sci_event_t evt; - struct _event_queue_struct *next; -} event_queue_t; - -/* -** For this driver to work to the fullest of its capabilities, the user running it -** must have rw permissions on the following: -** /dev/tty0 (including VT_ACTIVATE perms) -** /dev/tty7 -** /dev/fb0 -** /dev/psaux (if using a PS/2 mouse) -** -** VT_ACTIVATE permissions are, AFAIK, only available to root ATM :-( -*/ - -#define SCIDFB_CAP_ALPHA (1 << 0) /* Do we have an Alpha channel? */ - -#define SCIDFB_MAY_ALPHA (scidfb_internal_caps & SCIDFB_CAP_ALPHA) - -/* Global data */ - -static IDirectFB *scidfb_framebuffer; /* The global framebuffer */ -static IDirectFBDisplayLayer *scidfb_layer; /* The layer we use for drawing */ -static IDirectFBSurface *scidfb_visual; /* Static visual buffer */ -static IDirectFBSurface *scidfb_static_visual; /* Static visual buffer */ -static gfx_pixmap_t *scidfb_static_priority = NULL; -static gfx_pixmap_t *scidfb_back_priority = NULL; -static int scidfb_internal_caps = 0; /* Certain internal capabilities available to us */ - -/* Input structures */ -static IDirectFBEventBuffer *scidfb_input_buffer = NULL; -static event_queue_t *scidfb_event_queue = NULL; -static unsigned int scidfb_buckybits = SCI_EVM_INSERT; - - -/*#define LIST_ALL_DFB_MODES */ /* Uncomment for minimal debugging */ - -#define SCIDFB_CHECKED(f) \ - { \ - DFBResult _r = (f); \ - if (_r != DFB_OK) { \ - scidfb_handle_error(_r, __FILE__, __LINE__); \ - return GFX_ERROR; \ - } \ - } - -#define SCIGFX_CHECKED(f) \ - { \ - DFBResult _r = (f); \ - if (_r != GFX_OK) { \ - return _r; \ - } \ - } - - -static void -scidfb_handle_error(DFBResult errc, char *file, int line) -{ - const char *err = DirectFBErrorString(errc); - - GFXERROR("DFB-GFX, %s L%d: %s\n", file, line, err); -} - - -typedef struct { - int x, y, bpp; -} scidfb_mode_t; - - -static DFBEnumerationResult -scidfb_mode_callback(unsigned int width, unsigned int height, unsigned int bpp, void *conf) -{ - scidfb_mode_t *aim = (scidfb_mode_t *) conf; - scidfb_mode_t *best = aim + 1; - - if ((width >= aim->x && height >= aim->y && bpp >= aim->bpp) - /* Sufficient in all respects... */ - && ((best->bpp == 0) /* First mode that matched */ - || (width < best->x && height <= best->y) /* Improvement on x */ - || (width <= best->x && height < best->y) /* Improvement on y */ - || (width <= best->x && height <= best->y && bpp < best->bpp) - /* Improvement on bpp */ - )) { - best->x = width; - best->y = height; - best->bpp = bpp; - } - -#ifdef LIST_ALL_DFB_MODES - GFXERROR("DFB-GFX: Supports %dx%d at %d bpp\n", width, height, bpp); - return DFENUM_OK; -#endif - - if (aim->x == best->x - && aim->y == best->y - && aim->bpp == best->bpp) - return DFENUM_CANCEL; /* We have what we were looking for */ - - return DFENUM_OK; /* Continue searching */ -} - - -static DFBEnumerationResult -scidfb_layer_callback(unsigned int layer_id, DFBDisplayLayerCapabilities caps, void *resultp) -{ - unsigned int *results = (unsigned int *) resultp; - - if (!(caps & DLCAPS_SURFACE)) - return DFENUM_OK; /* We need a surface */ - - if (!results[1]) - results[0] = layer_id; - - results[1] = 1; - - if (caps & DLCAPS_ALPHACHANNEL) { - /* Optimal! */ - scidfb_internal_caps |= SCIDFB_MAY_ALPHA; - return DFENUM_CANCEL; /* We're done */ - } - - /* Found something, but it might get better */ - return DFENUM_OK; -} - -#define LOOKING_FOR_POINTING_DEVICE 1 -#define LOOKING_FOR_KEYBOARD 2 -#define FOUND_IT 255 - -static DFBEnumerationResult -scidfb_input_callback(unsigned int device_id, DFBInputDeviceDescription descr, void *p) -{ - int *state = (int *) p; - int *result = state + 1; - - /* Check for mouse */ - if (*state == LOOKING_FOR_POINTING_DEVICE - && (descr.type & DIDTF_MOUSE)) { - *result = device_id; - *state = FOUND_IT; - return DFENUM_CANCEL; - } - - /* Check for keyboard */ - if (*state == LOOKING_FOR_KEYBOARD - && (descr.type & DIDTF_KEYBOARD)) { - *result = device_id; - *state = FOUND_IT; - return DFENUM_CANCEL; - } - - return DFENUM_OK; -} - -static int -scidfb_find_layer() -{ - unsigned int results[2]; - - results[1] = 0; - SCIDFB_CHECKED(scidfb_framebuffer->EnumDisplayLayers(scidfb_framebuffer, - scidfb_layer_callback, &results)); - - if (!results[1]) - return GFX_FATAL; /* No decent layer! */ - else { - SCIDFB_CHECKED(scidfb_framebuffer->GetDisplayLayer(scidfb_framebuffer, - results[0], - &scidfb_layer)); - - return GFX_OK; - } -} - -static int -_scidfb_init_input(int *found_keyboard, int *found_mouse) -{ - int inputs[2]; - - inputs[0] = LOOKING_FOR_POINTING_DEVICE; - SCIDFB_CHECKED(scidfb_framebuffer->EnumInputDevices(scidfb_framebuffer, - scidfb_input_callback, &inputs)); - - if ((*found_mouse = (inputs[0] == FOUND_IT))) { - IDirectFBInputDevice *mouse; - SCIDFB_CHECKED(scidfb_framebuffer->GetInputDevice(scidfb_framebuffer, - inputs[1], &mouse)); - - SCIDFB_CHECKED(mouse->CreateEventBuffer(mouse, &scidfb_input_buffer)); - } - - inputs[0] = LOOKING_FOR_KEYBOARD; - SCIDFB_CHECKED(scidfb_framebuffer->EnumInputDevices(scidfb_framebuffer, - scidfb_input_callback, &inputs)); - if ((*found_keyboard = (inputs[0] == FOUND_IT))) { - IDirectFBInputDevice *keyboard; - SCIDFB_CHECKED(scidfb_framebuffer->GetInputDevice(scidfb_framebuffer, - inputs[1], &keyboard)); - - if (scidfb_input_buffer) - SCIDFB_CHECKED(keyboard->AttachEventBuffer(keyboard, scidfb_input_buffer)) - else - SCIDFB_CHECKED(keyboard->CreateEventBuffer(keyboard, - &scidfb_input_buffer)); - } - - - SCIDFB_CHECKED(scidfb_framebuffer->CreateEventBuffer(scidfb_framebuffer, - DICAPS_KEYS - | DICAPS_AXES - | DICAPS_BUTTONS, - &scidfb_input_buffer)); -} - -static int -_scidfb_init_gfx_mode(int width, int height, int bpp) -{ - scidfb_mode_t modes[2]; - modes[0].x = width; - modes[0].y = height; - modes[0].bpp = bpp; - - modes[1].bpp = 0; /* nothing found yet */ - - SCIDFB_CHECKED(DirectFBCreate(&scidfb_framebuffer)); - SCIDFB_CHECKED(scidfb_framebuffer->EnumVideoModes(scidfb_framebuffer, - scidfb_mode_callback, &modes)); - - if (modes[1].bpp) { - DFBDisplayLayerConfig conf; - - if (scidfb_find_layer()) { - GFXERROR("DFB-GFX: No useable display layer found"); - return GFX_FATAL; - } - - SCIDFB_CHECKED(scidfb_framebuffer->SetVideoMode(scidfb_framebuffer, - modes[1].x, modes[1].y, modes[1].bpp)); - - SCIDFB_CHECKED(scidfb_layer->SetCooperativeLevel(scidfb_layer, DLSCL_EXCLUSIVE)); - SCIDFB_CHECKED(scidfb_layer->GetSurface(scidfb_layer, &scidfb_visual)); - - return GFX_OK; - } else - GFXERROR("DFB-GFX: No matching visual could be found!\n"); - - return GFX_FATAL; -} - - -static int -scidfb_build_virtual_surface(IDirectFBSurface **result, int width, int height, - IDirectFBSurface *prototype) -{ - /* This function creates a _virtual_ surface, i.e. a memory buffer, - ** without flipping support */ - DFBSurfaceDescription srf_desc; - IDirectFBSurface *surface; - - SCIDFB_CHECKED(prototype->GetCapabilities(prototype, &(srf_desc.caps))); - srf_desc.caps &= ~DSCAPS_FLIPPING; - srf_desc.width = width; - srf_desc.height = height; - SCIDFB_CHECKED(prototype->GetPixelFormat(prototype, &(srf_desc.pixelformat))); - srf_desc.flags = (DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT); - SCIDFB_CHECKED(scidfb_framebuffer->CreateSurface(scidfb_framebuffer, &srf_desc, &surface)); - SCIDFB_CHECKED(surface->Clear(surface, 0, 0, 0, 255)); - - *result = surface; - - return GFX_OK; -} - -static int -scidfb_deactivate_pointer() -{ - SCIDFB_CHECKED(scidfb_layer->EnableCursor(scidfb_layer, 0)); - return 0; -} - - - /*----------------------------------------------------------------*/ -/*----------- Event queue implementation --------------*/ - /*----------------------------------------------------------------*/ - -#define MILLION 1000000 - -static int -scidfb_xlate_key(DFBInputDeviceKeyIdentifier key, int keysym) -{ - if ((keysym >= 'A') && (keysym <= 'Z')) - return keysym; - if ((keysym >= 'a') && (keysym <= 'z')) - return keysym; - if ((keysym >= '0') && (keysym <= '9')) - return keysym; - - switch (key) { - - case DIKI_0: return '0'; - case DIKI_1: return '1'; - case DIKI_2: return '2'; - case DIKI_3: return '3'; - case DIKI_4: return '4'; - case DIKI_5: return '5'; - case DIKI_6: return '6'; - case DIKI_7: return '7'; - case DIKI_8: return '8'; - case DIKI_9: return '9'; - - case DIKI_F1: return SCI_K_F1; - case DIKI_F2: return SCI_K_F2; - case DIKI_F3: return SCI_K_F3; - case DIKI_F4: return SCI_K_F4; - case DIKI_F5: return SCI_K_F5; - case DIKI_F6: return SCI_K_F6; - case DIKI_F7: return SCI_K_F7; - case DIKI_F8: return SCI_K_F8; - case DIKI_F9: return SCI_K_F9; - case DIKI_F10: return SCI_K_F10; - - case DIKI_KP_0: - case DIKI_INSERT: scidfb_buckybits ^= SCI_EVM_INSERT; - return SCI_K_INSERT; - - case DIKI_ESCAPE: return SCI_K_ESC; - case DIKI_LEFT: return SCI_K_LEFT; - case DIKI_RIGHT: return SCI_K_RIGHT; - case DIKI_UP: return SCI_K_UP; - case DIKI_DOWN: return SCI_K_DOWN; - case DIKI_TAB: return SCI_K_TAB; - case DIKI_ENTER: return SCI_K_ENTER; - case DIKI_SPACE: return ' '; - case DIKI_BACKSPACE: return SCI_K_BACKSPACE; - case DIKI_DELETE: return SCI_K_DELETE; - case DIKI_HOME: return SCI_K_HOME; - case DIKI_END: return SCI_K_END; - case DIKI_PAGE_UP: return SCI_K_PGDOWN; - case DIKI_PAGE_DOWN: return SCI_K_PGUP; - - case DIKI_QUOTE_LEFT: return '`'; - case DIKI_MINUS_SIGN: return '-'; - case DIKI_EQUALS_SIGN: return '='; - case DIKI_BRACKET_LEFT: return '['; - case DIKI_BRACKET_RIGHT: return ']'; - case DIKI_BACKSLASH: return '\\'; - case DIKI_SEMICOLON: return ';'; - case DIKI_QUOTE_RIGHT: return '\''; - case DIKI_COMMA: return ','; - case DIKI_SLASH: return '/'; - case DIKI_PERIOD: return '.'; - - case DIKI_KP_DIV: return '/'; - case DIKI_KP_MULT: return '*'; - case DIKI_KP_MINUS: return '-'; - case DIKI_KP_PLUS: return '+'; - case DIKI_KP_ENTER: return SCI_K_ENTER; - case DIKI_KP_SPACE: return ' '; - case DIKI_KP_TAB: return SCI_K_TAB; - case DIKI_KP_F1: return SCI_K_F1; - case DIKI_KP_F2: return SCI_K_F2; - case DIKI_KP_F3: return SCI_K_F3; - case DIKI_KP_F4: return SCI_K_F4; - case DIKI_KP_EQUAL: return '='; - - case DIKI_KP_DECIMAL: return SCI_K_DELETE; - case DIKI_KP_1: return SCI_K_END; - case DIKI_KP_2: return SCI_K_DOWN; - case DIKI_KP_3: return SCI_K_PGDOWN; - case DIKI_KP_4: return SCI_K_LEFT; - case DIKI_KP_5: return SCI_K_CENTER; - case DIKI_KP_6: return SCI_K_RIGHT; - case DIKI_KP_7: return SCI_K_HOME; - case DIKI_KP_8: return SCI_K_UP; - case DIKI_KP_9: return SCI_K_PGUP; - - default: - - } - return 0; /* Could not map key */ -} - - -scidfb_handle_bucky(int add, DFBInputDeviceKeyIdentifier key) -{ - int modifier = 0; - - switch(key) { - case DIKI_SHIFT_L: modifier = SCI_EVM_LSHIFT; - break; - case DIKI_SHIFT_R: modifier = SCI_EVM_RSHIFT; - break; - case DIKI_CONTROL_L: - case DIKI_CONTROL_R: modifier = SCI_EVM_CTRL; - break; - case DIKI_ALT_L: - case DIKI_ALT_R: - case DIKI_META_L: - case DIKI_META_R: modifier = SCI_EVM_ALT; - break; - case DIKI_CAPS_LOCK: modifier = SCI_EVM_CAPSLOCK; - break; - case DIKI_NUM_LOCK: modifier = SCI_EVM_NUMLOCK; - break; - case DIKI_SCROLL_LOCK: modifier = SCI_EVM_SCRLOCK; - break; - } - - if (add) - scidfb_buckybits |= modifier; - else - scidfb_buckybits &= ~modifier; -} - -static sci_event_t -scidfb_xlate_event(gfx_driver_t *drv, DFBEvent dfb_pre_evt) -{ - sci_event_t retval; - - retval.type = SCI_EVT_NONE; - retval.buckybits = scidfb_buckybits; - - if (dfb_pre_evt.clazz == DFEC_INPUT) { /* What kind of idiot named these field members? */ - DFBInputEvent dfbevt = dfb_pre_evt.input; - switch (dfbevt.type) { - - case DIET_KEYPRESS: - retval.type = SCI_EVT_KEYBOARD; - scidfb_handle_bucky(1, dfbevt.key_id); - retval.data = scidfb_xlate_key(dfbevt.key_id, dfbevt.key_symbol); - if (retval.data == 0) - retval.type = SCI_EVT_NONE; - break; - - case DIET_KEYRELEASE: - scidfb_handle_bucky(0, dfbevt.key_id); - break; - - case DIET_BUTTONPRESS: - retval.type = SCI_EVT_MOUSE_PRESS; - retval.data = dfbevt.button - DIBI_FIRST; - break; - - case DIET_AXISMOTION:{ - int *victim = NULL; - - if (dfbevt.axis == DIAI_X) - victim = &(drv->pointer_x); - else if (dfbevt.axis == DIAI_Y) - victim = &(drv->pointer_y); - else break; - - if (dfbevt.flags & DIEF_AXISABS) - *victim = dfbevt.axisabs; - else if (dfbevt.flags & DIEF_AXISREL) - *victim += dfbevt.axisrel; - } - break; - - case DIET_BUTTONRELEASE: - retval.type = SCI_EVT_MOUSE_RELEASE; - retval.data = dfbevt.button - DIBI_FIRST; - break; - } - } - - return retval; -} - -static void -scidfb_queue_event(sci_event_t evt) -{ - event_queue_t *node = malloc(sizeof(event_queue_t)); - event_queue_t **seekerp = &scidfb_event_queue; - - node->evt = evt; - node->next = NULL; - - while (*seekerp) - seekerp = &((*seekerp)->next); - - *seekerp = node; -} - - -static int -scidfb_queue_next_event(gfx_driver_t *drv, long micros_to_wait) -{ - DFBEvent dfb_event; - long secs = micros_to_wait / MILLION; - long usecs = (micros_to_wait - (secs * MILLION)) / 1000; - int has_event; - DFBResult timeout; - - timeout = scidfb_input_buffer->WaitForEventWithTimeout(scidfb_input_buffer, - secs, usecs); - if (timeout != DFB_TIMEOUT) - SCIDFB_CHECKED(timeout); - - has_event = scidfb_input_buffer->HasEvent(scidfb_input_buffer); - if (has_event == DFB_OK) { - sci_event_t evt; - /* We have a new event */ - SCIDFB_CHECKED(scidfb_input_buffer->GetEvent(scidfb_input_buffer, &dfb_event)); - evt = scidfb_xlate_event(drv, dfb_event); - - if (evt.type != SCI_EVT_NONE) - scidfb_queue_event(evt); - - return 0; - } else - if (has_event != DFB_BUFFEREMPTY) - return has_event; /* An error occured */ -} - - -static int -_scidfb_read_event(sci_event_t *evtp) -{ - if (scidfb_event_queue) { - event_queue_t *q = scidfb_event_queue; - *evtp = q->evt; - scidfb_event_queue = q->next; - free(q); - - return 1; - } else { - evtp->type = SCI_EVT_NONE; - return 0; - } -} - - - - - /*----------------------------------------------------------------*/ -/*----------- Implementations required by gfx_driver_t --------------*/ - /*----------------------------------------------------------------*/ - - -static int -scidfb_set_parameter(gfx_driver_t *drv, char *name, char *value) -{ - fprintf(stderr, "FIXME: These must be caught and moved in between DirectFBInit() and ..Create()\n"); - exit(1); - SCIDFB_CHECKED(DirectFBSetOption(name, value)); - return GFX_OK; -} - -static int -_scidfb_decode_pixel_format(DFBSurfacePixelFormat pixel_format, - int *rm, int *gm, int *bm, int *am, - int *rs, int *gs, int *bs, int *as, int *bytespp) -{ - /* Initially, the masks are set to the number of bits they occupy, and shifts - ** are left shifts */ - int _rs, _gs, _bs, _as; - - _as = 0; - *am = 0; - *as = 0; - - switch (pixel_format) { - - case DSPF_RGB15: - *bytespp = 2; - *rm = 5; _rs = 10; - *gm = 5; _gs = 5; - *bm = 5; _bs = 0; - break; - - case DSPF_RGB16: - *bytespp = 2; - *rm = 5; _rs = 11; - *gm = 6; _gs = 5; - *bm = 5; _bs = 0; - break; - - case DSPF_RGB24: - *bytespp = 3; - *rm = 8; _rs = 16; - *gm = 8; _gs = 8; - *bm = 8; _bs = 0; - break; - - case DSPF_RGB32: - *bytespp = 4; - *rm = 8; _rs = 16; - *gm = 8; _gs = 8; - *bm = 8; _bs = 0; - break; - - case DSPF_ARGB: - *bytespp = 4; - *am = 8; _as = 24; - *rm = 8; _rs = 16; - *gm = 8; _gs = 8; - *bm = 8; _bs = 0; - break; - - case DSPF_RGB332: - *bytespp = 1; - *rm = 3; _rs = 5; - *gm = 3; _gs = 2; - *bm = 2; _bs = 0; - break; - - default: - GFXERROR("DFB-GFX: Unknown/unsupported pixel format %08x\n", pixel_format); - return GFX_FATAL; - } - - /* Calculate correct shifts */ - *rs = 32 - *rm - _rs; - *gs = 32 - *gm - _gs; - *bs = 32 - *bm - _bs; - *as = 32 - *am - _as; - - /* Calculate correct masks */ - *rm = ((1 << (*rm)) - 1) << _rs; - *gm = ((1 << (*gm)) - 1) << _gs; - *bm = ((1 << (*bm)) - 1) << _bs; - *am = ((1 << (*am)) - 1) << _as; - - return GFX_OK; -} - -static int -scidfb_init_specific(gfx_driver_t *drv, int xres, int yres, int bytespp) -{ - DFBSurfacePixelFormat pixel_format; - char **p; - char *foo = ""; - int n = 1; - - int width, height; - int red_mask, green_mask, blue_mask, alpha_mask; - int red_shift, green_shift, blue_shift, alpha_shift; - int bytespp_real; - int mouse, keyboard; - - p = &foo; - DirectFBInit(&n, &p); - - SCIDFB_CHECKED(DirectFBSetOption("no-sighandler", "1")); - - SCIGFX_CHECKED(_scidfb_init_gfx_mode(xres, yres, (1 << bytespp) - 1)); - SCIGFX_CHECKED(_scidfb_init_input(&keyboard, &mouse)); - - if (!keyboard) { - GFXERROR("DFB-GFX: No keyboard found-- aborting...\n"); - return GFX_FATAL; - } - if (!mouse) { - GFXWARN("DFB-GFX: No pointing device found, disabling mouse support...\n"); - drv->capabilities &= ~GFX_CAPABILITY_MOUSE_SUPPORT; - } - - SCIDFB_CHECKED(scidfb_visual->GetSize(scidfb_visual, &width, &height)); - - scidfb_deactivate_pointer(); - SCIDFB_CHECKED(scidfb_visual->Clear(scidfb_visual, 0, 0, 0, 255)); - SCIDFB_CHECKED(scidfb_visual->Flip(scidfb_visual, NULL, DSFLIP_BLIT)); - - - /* If neccessary, create a sub-surface */ - if (width > xres * 320 || height > yres * 200) { - IDirectFBSurface *subsurface; - DFBRectangle region; - region.w = xres * 320; - region.h = yres * 200; - region.x = (width - region.w) >> 1; - region.y = (height - region.h) >> 1; - - SCIDFB_CHECKED(scidfb_visual->GetSubSurface(scidfb_visual, ®ion, &subsurface)); - - scidfb_visual = subsurface; - } - - scidfb_visual->SetDrawingFlags(scidfb_visual, DSDRAW_BLEND); /* Unchecked: It's just a - ** feature */ - SCIDFB_CHECKED(scidfb_visual->GetPixelFormat(scidfb_visual, &pixel_format)); - - SCIGFX_CHECKED(_scidfb_decode_pixel_format(pixel_format, - &red_mask, &green_mask, &blue_mask, &alpha_mask, - &red_shift, &green_shift, &blue_shift, &alpha_shift, - &bytespp_real)); - - fprintf(stderr, "Mode %08x -> (%x>>%d, %x>>%d, %x>>%d, %x>>%d) at %d bytespp\n", - pixel_format, - red_mask, red_shift, - green_mask, green_shift, - blue_mask, blue_shift, - alpha_mask, alpha_shift, - bytespp_real); - - drv->mode = gfx_new_mode(xres, yres, - bytespp_real, - red_mask, green_mask, blue_mask, alpha_mask, - red_shift, green_shift, blue_shift, alpha_shift, - 0 /* not palette mode*/, - 0); - - SCIGFX_CHECKED(scidfb_build_virtual_surface(&scidfb_static_visual, - drv->mode->xfact * 320, - drv->mode->yfact * 200, - scidfb_visual)); - - scidfb_back_priority = - gfx_pixmap_alloc_index_data(gfx_new_pixmap(drv->mode->xfact * 320, - drv->mode->yfact * 200, - GFX_RESID_NONE, 0, 0)); - - return GFX_OK; -} - -static int -_scidfb_set_color(gfx_color_t *c) -{ - SCIDFB_CHECKED(scidfb_visual->SetColor(scidfb_visual, - c->visual.r, c->visual.g, c->visual.b, - (c->mask & GFX_MASK_VISUAL)? (255 - c->alpha) : 0)); - return GFX_OK; -} - -static int -scidfb_init(gfx_driver_t *drv) -{ - return scidfb_init_specific(drv, 2, 2, 1); -} - - -static void -scidfb_exit(gfx_driver_t *drv) -{ - gfx_free_pixmap(drv, scidfb_back_priority); -} - -static int -scidfb_draw_line(gfx_driver_t *drv, point_t start, point_t end, gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style) -{ - int xc, yc; - - SCIGFX_CHECKED(_scidfb_set_color(&color)); - - if (line_mode == GFX_LINE_MODE_FINE) { - SCIDFB_CHECKED(scidfb_visual->DrawLine(scidfb_visual, - start.x, start.y, - end.x, end.y)); - } else /* "Correct" lines */ - for (xc = 0; xc < drv->mode->xfact; xc++) - for (yc = 0; yc < drv->mode->yfact; yc++) - SCIDFB_CHECKED(scidfb_visual->DrawLine(scidfb_visual, - start.x + xc, - start.y + yc, - end.x + xc, - end.y + yc)); - - return GFX_OK; -} - -static int -scidfb_draw_filled_rect(gfx_driver_t *drv, rect_t rect, - gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode) -{ - SCIGFX_CHECKED(_scidfb_set_color(&color1)); - SCIDFB_CHECKED(scidfb_visual->FillRectangle(scidfb_visual, - rect.x, rect.y, - rect.xl, rect.yl)); - - return GFX_OK; -} - -static int -scidfb_register_pixmap(gfx_driver_t *drv, gfx_pixmap_t *pxm) -{ - return GFX_OK; -} - - -static int -scidfb_unregister_pixmap(gfx_driver_t *drv, gfx_pixmap_t *pxm) -{ - return GFX_OK; -} - - -static int -scidfb_draw_pixmap(gfx_driver_t *drv, gfx_pixmap_t *pxm, int priority, - rect_t src, rect_t dest, gfx_buffer_t buffer) -{ - void *_dest_data; - byte *dest_data; - int line_width; - IDirectFBSurface *visual = (buffer == GFX_BUFFER_STATIC)? - scidfb_static_visual : scidfb_visual; - gfx_pixmap_t *priority_map = (buffer == GFX_BUFFER_STATIC)? - scidfb_static_priority : scidfb_back_priority; - - SCIDFB_CHECKED(visual->Lock(visual, DSLF_WRITE | DSLF_READ, - &_dest_data, &line_width)); - dest_data = (byte *) _dest_data; - - gfx_crossblit_pixmap(drv->mode, pxm, priority, src, dest, dest_data, - line_width, - priority_map->index_data, priority_map->index_xl, - 1, 0); - - SCIDFB_CHECKED(visual->Unlock(visual)); -} - -static int -scidfb_grab_pixmap(gfx_driver_t *drv, rect_t src, gfx_pixmap_t *pxm, - gfx_map_mask_t map) -{ - void *_src_data; - byte *src_data; - byte *dest = pxm->data; - int line_width; - int write_width = drv->mode->bytespp * (src.xl); - - pxm->xl = src.xl; - pxm->yl = src.yl; - - if (map != GFX_MASK_VISUAL) { - fprintf(stderr, "Not trying to read from visual mask-- not supported!"); - return GFX_FATAL; - } - - SCIDFB_CHECKED(scidfb_visual->Lock(scidfb_visual, DSLF_READ | DSLF_WRITE, - /* Must use DSLF_WRITE to choose the back buffer, - ** otherwise the front buffer would be chosen */ - &_src_data, &line_width)); - src_data = (byte *) _src_data; - - src_data += (drv->mode->bytespp * src.x) - + (line_width * src.y); /* left upper corner of the source */ - - if (src.y < 0){ - fprintf(stderr, "src.y=%d\n", src.y); - exit(1); - } - - while (src.yl--) { - memcpy(dest, src_data, write_width); - src_data += line_width; - dest += write_width; - } - - - SCIDFB_CHECKED(scidfb_visual->Unlock(scidfb_visual)); -} - -static int -scidfb_update(gfx_driver_t *drv, rect_t src, point_t dest, gfx_buffer_t buffer) -{ - if (src.x != dest.x - || src.y != dest.y) { - GFXERROR("DFB-GFX: Attempt to update from (%d,%d,%d,%d) to (%d,%d)\n", - GFX_PRINT_RECT(src), dest.x, dest.y); - } - - if (buffer == GFX_BUFFER_FRONT) { - DFBRegion region; - region.x1 = src.x; - region.y1 = src.y; - region.x2 = src.x + src.xl; - region.y2 = src.y + src.yl; - - SCIDFB_CHECKED(scidfb_visual->Flip(scidfb_visual, ®ion, DSFLIP_BLIT)); - } else { /* Back buffer update */ - DFBRectangle dest_rect; - dest_rect.x = src.x; - dest_rect.y = src.y; - dest_rect.w = src.xl; - dest_rect.h = src.yl; - - SCIDFB_CHECKED(scidfb_visual->Blit(scidfb_visual, - scidfb_static_visual, - &dest_rect, - dest.x, dest.y)); - - /* Now update the priority map: */ - if (scidfb_static_priority) /* only if the buffers have been initialized */ - gfx_copy_pixmap_box_i(scidfb_back_priority, scidfb_static_priority, src); - } - - return GFX_OK; -} - -static int -scidfb_set_static_buffer(gfx_driver_t *drv, gfx_pixmap_t *pic, gfx_pixmap_t *priority) -{ - void *_dest; - byte *dest; - byte *src = pic->data; - int line_width; - int draw_width = pic->xl * drv->mode->bytespp; - int i; - - scidfb_static_priority = priority; - SCIDFB_CHECKED(scidfb_static_visual->Lock(scidfb_static_visual, DSLF_WRITE, - &_dest, &line_width)); - dest = (byte *) _dest; - - for (i = 0; i < pic->yl; i++) { - memcpy(dest, src, draw_width); - dest += line_width; - src += draw_width; - } - - SCIDFB_CHECKED(scidfb_static_visual->Unlock(scidfb_static_visual)); - - return GFX_OK; -} - -static void -_normalize_pointer(gfx_driver_t *drv) -{ - int maxw = drv->mode->xfact * 320; - int maxh = drv->mode->yfact * 200; - - if (drv->pointer_x < 0) - drv->pointer_x = 0; - if (drv->pointer_x >= maxw) - drv->pointer_x = maxw - 1; - if (drv->pointer_y < 0) - drv->pointer_y = 0; - if (drv->pointer_y >= maxh) - drv->pointer_y = maxh - 1; -} - - -static sci_event_t -scidfb_get_event(gfx_driver_t *drv) -{ - sci_event_t retval; - - scidfb_queue_next_event(drv, 0); - _scidfb_read_event(&retval); - - _normalize_pointer(drv); - - - return retval; -} - -static int -scidfb_usec_sleep(gfx_driver_t *drv, long usecs) -{ - scidfb_queue_next_event(drv, usecs); - _normalize_pointer(drv); - return GFX_OK; -} - -gfx_driver_t gfx_driver_dfb = { - "dfb", - SCIDFB_DRIVER_VERSION, - SCI_GFX_DRIVER_MAGIC, - SCI_GFX_DRIVER_VERSION, - NULL, - 0, 0, - GFX_CAPABILITY_MOUSE_SUPPORT - | GFX_CAPABILITY_FINE_LINES, - 0, - scidfb_set_parameter, - scidfb_init_specific, - scidfb_init, - scidfb_exit, - scidfb_draw_line, - scidfb_draw_filled_rect, - scidfb_register_pixmap, - scidfb_unregister_pixmap, - scidfb_draw_pixmap, - scidfb_grab_pixmap, - scidfb_update, - scidfb_set_static_buffer, - NULL, - NULL, - scidfb_get_event, - scidfb_usec_sleep, - NULL -}; - -#endif diff --git a/engines/sci/gfx/drivers/dx_driver.cpp b/engines/sci/gfx/drivers/dx_driver.cpp deleted file mode 100644 index 899d1fa70c..0000000000 --- a/engines/sci/gfx/drivers/dx_driver.cpp +++ /dev/null @@ -1,1179 +0,0 @@ -/*************************************************************************** - dx_driver.cpp Copyright (C) 2008 Alexander R Angas, - Some portions Copyright (C) 1999 Dmitry Jemerov - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Alexander R Angas (Alex) <arangas AT internode dot on dot net> - - History: - 20051106 (AAngas) - Rewrite - 20060201 (AAngas) - Fixed wrong format for texture priority maps - 20060205 (AAngas) - Changed pointer to use D3DXSprite - 20060208 (AAngas) - Fixed pointer alpha blending bug - 20060307 (AAngas) - Fixed crash on exit - 20080118 (AAngas) - Fixed pointer scaling and window size - - Notes: - DirectX handles all scaling. All drawing functions assume an unscaled - resolution. - -TODO: - P1 - Corrupt cursor at different resolutions - P1 - Lost devices - P1 - Problems moving and activating window - P1 - Occasional pause when starting FreeSCI and poor sound resulting (?) - P1 - Mouse pointer corruption at bottom and why need to scale vertical by 4? - P2 - Full screen - P3 - Draw lines as Direct3D vertices - P3 - Fine line mode - P3 - Allow user to specify hardware or software vertex processing - P3 - Fancies - -***************************************************************************/ - -#ifdef HAVE_DIRECTX - -#ifndef __cplusplus -#error NOTE: This file MUST be compiled as C++. In Visual C++, use the /Tp command line option. -#endif - -#include "dx_driver.h" - -#define TO_STRING2(x) #x -#define TO_STRING(x) TO_STRING2(x) -#if (DIRECT3D_VERSION < 0x0800) -# error The DirectX 8 SDK (or higher) is required for this driver. -#elif (DIRECT3D_VERSION > 0x0800) -# pragma message (" ") -# pragma message ("*** This driver has been developed against version 8 of the DirectX SDK and may not work against your version " TO_STRING(DIRECT3D_VERSION)) -# pragma message (" ") -#endif - - -// Stores driver flags -static int flags = 0; - - -// Windows message processing -LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) -{ - return DefWindowProc( hWnd, msg, wParam, lParam ); -} - - -///// RENDERING - -// Render the scene to screen -static gfx_return_value_t -RenderD3D(struct _gfx_driver *drv) -{ - HRESULT hr; - - // Check we haven't lost the device (i.e. window focus) - if (CheckDevice(drv)) - { - // Begin scene - DODX( (dx_state->pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0, 0)), RenderD3D ); - DODX( (dx_state->pDevice->BeginScene()), RenderD3D ); - - // Set texture - DODX( (dx_state->pDevice->SetTexture( 0, dx_state->pTexVisuals[PRIMARY_VIS] )), RenderD3D ); // Scene image - - // Set texture states for scene - DODX( (dx_state->pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE )), RenderD3D ); - DODX( (dx_state->pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE )), RenderD3D ); - DODX( (dx_state->pDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE )), RenderD3D ); - - // Set vertices and how to draw - DODX( (dx_state->pDevice->SetStreamSource(0, dx_state->pVertBuff, sizeof(CUSTOMVERTEX))), RenderD3D ); - DODX( (dx_state->pDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX )), RenderD3D ); - DODX( (dx_state->pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2)), RenderD3D ); - - // Draw the pointer sprite - if (dx_state->pTexPointer) - { - D3DXVECTOR2 pointerPos((float)drv->pointer_x, (float)drv->pointer_y); - DODX( (dx_state->pSPointer->Begin()), RenderD3D ); - DODX( (dx_state->pSPointer->Draw(dx_state->pTexPointer, NULL, NULL, NULL, 0.0, &pointerPos, 0xFFFFFFFF)), RenderD3D ); - DODX( (dx_state->pSPointer->End()), RenderD3D ); - } - - // Present scene - DODX( (dx_state->pDevice->EndScene()), RenderD3D ); - DODX( (dx_state->pDevice->Present(NULL, NULL, NULL, NULL)), RenderD3D ); - } - - return GFX_OK; -} - - -// Check device hasn't been lost -static int -CheckDevice(struct _gfx_driver *drv) -{ - HRESULT hr; - switch ( dx_state->pDevice->TestCooperativeLevel() ) - { - case D3DERR_DEVICELOST: return false; // Lost window focus - - case D3DERR_DEVICENOTRESET: // We're back! - { - // Reset with our presentation parameters and reinitialise the scene - DODX( (dx_state->pDevice->Reset(&dx_state->presParams)), CheckDevice ); - if (hr != D3D_OK) - return false; - - InitScene(drv); - return true; - } - - default: return true; - } -} - - -///// INITIALIZATION - -// Create window to draw to -static gfx_return_value_t -InitWindow(struct _gfx_driver *drv, UINT width, UINT height) -{ - DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; - DWORD dwStyle = WS_OVERLAPPEDWINDOW; - RECT clientSize = { 0, 0, width, height }; - sciprintf("Window %d x %d\n", width, height); - - // Register the window class - ZeroMemory( &(dx_state->wc), sizeof(WNDCLASSEX) ); - dx_state->wc.cbSize = sizeof(WNDCLASSEX); - dx_state->wc.style = CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE; - dx_state->wc.lpfnWndProc = MsgProc; - dx_state->wc.hInstance = GetModuleHandle(NULL); - dx_state->wc.lpszClassName = DX_CLASS_NAME; - if ( RegisterClassEx( &dx_state->wc ) == 0 ) - { - sciprintf("InitWindow(): RegisterClassEx failed (%u)\n", GetLastError()); - return GFX_FATAL; - } - - // Get correct size of window to pass to CreateWindow (considering window decorations) - if ( AdjustWindowRectEx( &clientSize, dwStyle, false, dwExStyle ) == 0 ) - { - sciprintf("InitWindow(): Window size calculation failed (%u)\n", GetLastError()); - return GFX_FATAL; - } - - // Create the application's window - dx_state->hWnd = CreateWindowEx( - dwExStyle, - DX_CLASS_NAME, DX_APP_NAME, - dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, - CW_USEDEFAULT, CW_USEDEFAULT, - clientSize.right - clientSize.left, clientSize.bottom - clientSize.top, - NULL/*GetDesktopWindow()*/, NULL, dx_state->wc.hInstance, NULL ); - - if ( dx_state->hWnd == NULL ) - { - sciprintf("InitWindow(): CreateWindow failed (%u)\n", GetLastError()); - return GFX_FATAL; - } - - // Show the window - ShowWindow( dx_state->hWnd, SW_SHOWDEFAULT ); - UpdateWindow( dx_state->hWnd ); - - return GFX_OK; -} - - -// Initialize Direct3D -static gfx_return_value_t -InitD3D(struct _gfx_driver *drv) -{ - HRESULT hr; - - sciprintf("Initializing Direct3D\n"); - - // Set our colour format - dx_state->d3dFormat = D3DFMT_A8R8G8B8; - dx_state->vertexProcessing = D3DCREATE_MIXED_VERTEXPROCESSING; - - // Create Direct3D object - dx_state->pD3d = Direct3DCreate8( D3D_SDK_VERSION ); - if ( FAILED( dx_state->pD3d ) ) { - sciprintf("InitD3D(): Direct3DCreate8 failed\n"); - return GFX_FATAL; - } - - // Look for adapters - for ( UINT adapterLoop = 0; adapterLoop < dx_state->pD3d->GetAdapterCount(); adapterLoop++ ) - { - D3DADAPTER_IDENTIFIER8 adapterId; - DODX( (dx_state->pD3d->GetAdapterIdentifier(adapterLoop, D3DENUM_NO_WHQL_LEVEL, &adapterId)), InitD3D ); - if ( FAILED( hr ) ) - break; - if (adapterId.Driver[0] == '\0') - break; - sciprintf(" Adapter %u: %s\n", adapterLoop++, adapterId.Description); - } - if (dx_state->adapterId == -1) - dx_state->adapterId = D3DADAPTER_DEFAULT; - - // Get device caps - DODX( (dx_state->pD3d->GetDeviceCaps(dx_state->adapterId, D3DDEVTYPE_HAL, &(dx_state->deviceCaps))), InitD3D ); - if ( FAILED( hr ) ) { - sciprintf("Sorry, this adapter does not have a 3D accelerated video driver installed.\n"); - return GFX_FATAL; - } - - // Define presentation parameters - ZeroMemory( &dx_state->presParams, sizeof(D3DPRESENT_PARAMETERS) ); - dx_state->presParams.Windowed = TRUE; // We want windowed by default - dx_state->presParams.SwapEffect = D3DSWAPEFFECT_DISCARD; // Throw away last frame - dx_state->presParams.hDeviceWindow = dx_state->hWnd; // Window handle - dx_state->presParams.BackBufferWidth = 320; // Back buffer dimensions - dx_state->presParams.BackBufferHeight = 200; // - dx_state->presParams.BackBufferFormat = dx_state->d3dFormat; // Colour format - - // Check if user requested full screen - if (flags & DX_FLAGS_FULLSCREEN) - { - if (dx_state->deviceCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) { - dx_state->presParams.Windowed = FALSE; - sciprintf("Full screen mode"); - } else { - sciprintf("Sorry, DirectX will not render in full screen with your video card\n"); - } - } - - // Get current display mode - DODX( (dx_state->pD3d->GetAdapterDisplayMode( dx_state->adapterId, &dx_state->displayMode )), InitD3D ); - sciprintf("Chosen adapter %u\n", dx_state->adapterId); - - // Turn off Windows mouse pointer - ShowCursor(FALSE); - - return GFX_OK; -} - - -// Initialize scene -static gfx_return_value_t -InitScene(struct _gfx_driver *drv) -{ - HRESULT hr; - - sciprintf("Creating scene\n"); - - // Describe how scene will be rendered - DODX((dx_state->pDevice->SetRenderState( D3DRS_AMBIENT, RGB(255,255,255) )), InitScene); // Maximum ambient light - DODX((dx_state->pDevice->SetRenderState( D3DRS_LIGHTING, FALSE )), InitScene); // Disable lighting features - DODX((dx_state->pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE )), InitScene); // Don't cull back side of polygons - DODX((dx_state->pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE )), InitScene); // No depth buffering - - return GFX_OK; -} - - -// For user to set a driver-specific parameter -static int -dx_set_param(struct _gfx_driver *drv, char *attribute, char *value) -{ -/* // Full screen - if (!strncmp(attribute, "fullscreen", 11)) { - if (string_truep(value)) - flags |= DX_FLAGS_FULLSCREEN; - else - flags &= ~DX_FLAGS_FULLSCREEN; - - return GFX_OK; - } -*/ - // Adapter ID - if (!strncmp(attribute, "adapterid", 11)) { - int aid = D3DADAPTER_DEFAULT; - dx_state->adapterId = atoi(value); - - return GFX_OK; - } - - sciprintf("Unrecognised attempt to set DirectX parameter \"%s\" to \"%s\"\n", attribute, value); - return GFX_ERROR; -} - - -// Initialize a specific graphics mode -static int -dx_init_specific(struct _gfx_driver *drv, - int xfact, int yfact, /* horizontal and vertical scaling */ - int bytespp) /* must be value 4 */ -{ - HRESULT hr; - int red_shift = 8, green_shift = 16, blue_shift = 24, alpha_shift = 32; - int alpha_mask = 0x00000000, red_mask = 0x00ff0000, green_mask = 0x0000ff00, blue_mask = 0x000000ff; - gfx_return_value_t d3dret; - - // Error checking - if (xfact < 1 || yfact < 1 || bytespp < 1 || bytespp > 4) { - sciprintf("Attempt to open window with invalid scale factors (%d,%d) and bpp=%d!\n", - xfact, yfact, bytespp); - return GFX_ERROR; - } - - // Prepare memory for gfx_dx_struct_t - drv->state = (struct gfx_dx_struct_t *) sci_malloc(sizeof(gfx_dx_struct_t)); - ZeroMemory(drv->state, sizeof(gfx_dx_struct_t)); - dx_state->adapterId = -1; // we will set this later - - // Set window size factor - dx_state->xfact = xfact; - dx_state->yfact = yfact; - dx_state->bpp = bytespp; - sciprintf("Window scaling %d x %d @ %d bpp\n", dx_state->xfact, dx_state->yfact, dx_state->bpp << 3); - - // Set up Direct3D - d3dret = InitD3D(drv); - if (d3dret != GFX_OK) - return d3dret; - - // Create window - InitWindow(drv, dx_state->xfact * 320, dx_state->yfact * 200); - - // Create D3D device - DODX( (dx_state->pD3d->CreateDevice(dx_state->adapterId, D3DDEVTYPE_HAL, dx_state->hWnd, - dx_state->vertexProcessing, &dx_state->presParams, &dx_state->pDevice)), dx_init_specific ); - - // Create the scene - d3dret = InitScene(drv); - if (d3dret != GFX_OK) - return d3dret; - - // Define and populate vertex buffers - DODX((dx_state->pDevice->CreateVertexBuffer( 4 * sizeof(CUSTOMVERTEX), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, - D3DPOOL_MANAGED, &dx_state->pVertBuff )), dx_init_specific); - - dx_state->pvData[0].p = D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f); - dx_state->pvData[1].p = D3DXVECTOR4(320.0f, 0.0f, 0.0f, 1.0f); - dx_state->pvData[2].p = D3DXVECTOR4( 0.0f, 200.0f, 0.0f, 1.0f); - dx_state->pvData[3].p = D3DXVECTOR4(320.0f, 200.0f, 0.0f, 1.0f); - dx_state->pvData[0].colour = dx_state->pvData[1].colour = dx_state->pvData[2].colour = dx_state->pvData[3].colour = 0xffffffff; - dx_state->pvData[0].t = D3DXVECTOR2(0.0f, 0.0f); - dx_state->pvData[1].t = D3DXVECTOR2(1.0f, 0.0f); - dx_state->pvData[2].t = D3DXVECTOR2(0.0f, 1.0f); - dx_state->pvData[3].t = D3DXVECTOR2(1.0f, 1.0f); - - VOID *ptr; - DODX((dx_state->pVertBuff->Lock(0, 0, (BYTE**)&ptr, 0)), dx_init_specific); - memcpy(ptr, dx_state->pvData, sizeof(dx_state->pvData)); - DODX((dx_state->pVertBuff->Unlock()), dx_init_specific); - - // Create textures - int i; - for (i = 0; i < NUM_VISUAL_BUFFERS; i++) - { - DODX((dx_state->pDevice->CreateTexture(320, 200, - 1, 0, - dx_state->d3dFormat, - D3DPOOL_MANAGED, - &dx_state->pTexVisuals[i])), dx_init_specific); - } - for (i = 0; i < NUM_PRIORITY_BUFFERS; i++) - { - DODX((dx_state->pDevice->CreateTexture(320, 200, - 1, 0, - dx_state->d3dFormat, - D3DPOOL_MANAGED, - &dx_state->pTexPrioritys[i])), dx_init_specific); - } - - // Create sprite for pointer - DODX( (D3DXCreateSprite(dx_state->pDevice, &dx_state->pSPointer)), dx_init_specific ); - - // Allocate priority maps - for (int i = 0; i < NUM_PRIORITY_BUFFERS; i++) - { - dx_state->priority_maps[i] = gfx_pixmap_alloc_index_data(gfx_new_pixmap(320, 200, GFX_RESID_NONE, -i, -777)); - if (!dx_state->priority_maps[i]) { - GFXERROR("Out of memory: Could not allocate priority maps! (%dx%d)\n", 320, 200); - return GFX_FATAL; - } - dx_state->priority_maps[i]->flags |= GFX_PIXMAP_FLAG_SCALED_INDEX; - } - - // Set up the event queue - dx_state->queue_first = 0; - dx_state->queue_last = 0; - dx_state->queue_size = 256; - dx_state->event_queue = (sci_event_t *) sci_malloc (dx_state->queue_size * sizeof (sci_event_t)); - - // Set up graphics mode for primary vis - drv->mode = gfx_new_mode(1, 1, dx_state->bpp, - red_mask, green_mask, blue_mask, alpha_mask, - red_shift, green_shift, blue_shift, alpha_shift, - (dx_state->bpp == 1) ? 256 : 0, 0); - - // Set up graphics mode for pointer - dx_state->pointerMode = gfx_new_mode(1, 4, dx_state->bpp, - 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, - 24, 16, 8, 0, - 0, GFX_MODE_FLAG_REVERSE_ALPHA); - - return GFX_OK; -} - - -// Initialize 'most natural' graphics mode -static int -dx_init(struct _gfx_driver *drv) -{ - return dx_init_specific(drv, 2, 2, 4); -} - - -// Uninitialize the current graphics mode -static void -dx_exit(struct _gfx_driver *drv) -{ - int i; - - if(drv->state == NULL) - return; - - for (i = 0; i < NUM_PRIORITY_BUFFERS; i++) - SAFE_RELEASE( dx_state->pTexPrioritys[i] ); - for (i = 0; i < NUM_VISUAL_BUFFERS; i++) - SAFE_RELEASE( dx_state->pTexVisuals[i] ); - SAFE_RELEASE( dx_state->pTexPointer ); - SAFE_RELEASE( dx_state->pSPointer ); - SAFE_RELEASE( dx_state->pVertBuff ); - SAFE_RELEASE( dx_state->pDevice ); - SAFE_RELEASE( dx_state->pD3d ); - - if ( dx_state->pointerMode ) - gfx_free_mode(dx_state->pointerMode); - if ( drv->mode ) - gfx_free_mode(drv->mode); - - if ( dx_state->event_queue ) - sci_free(dx_state->event_queue); - dx_state->queue_size = 0; - - for (i = 0; i < NUM_PRIORITY_BUFFERS; i++) - gfx_free_pixmap(drv, dx_state->priority_maps[i]); - - UnregisterClass( DX_CLASS_NAME, dx_state->wc.hInstance ); - DestroyWindow(dx_state->hWnd); - - sci_free(dx_state); -} - - -///// DRAWING - -// Draws a single filled and possibly shaded rectangle to the back buffer -static int -dx_draw_filled_rect(struct _gfx_driver *drv, rect_t box, - gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode) -{ - if (color1.mask & GFX_MASK_VISUAL) - { - HRESULT hr; - D3DLOCKED_RECT lockedRect; - - // Calculate colour value for line pixel - UINT lineColor = (color1.alpha << 24) | (color1.visual.r << 16) | (color1.visual.g << 8) | color1.visual.b; - RECT r = { box.x, box.y, box.x + box.xl, box.y + box.yl }; - RECT lr = r; - - // Fix bounds - if (lr.left == lr.right) - lr.right++; - if (lr.top == lr.bottom) - lr.bottom++; - if ((UINT)r.right > 320) - lr.right = r.right = 320; - if ((UINT)r.bottom > 200) - lr.bottom = r.bottom = 200; - - sciprintf("dx_draw_filled_rect(): %08X %i,%i -> %i,%i\n", lineColor, r.left, r.top, r.right, r.bottom); - - DODX( (dx_state->pTexVisuals[BACK_VIS]->LockRect(0, &lockedRect, &lr, 0)), dx_draw_filled_rect ); - UINT *rectPtr = (UINT*)lockedRect.pBits; - - // Going along x axis - for (int y_pixel = r.top; y_pixel < r.bottom; y_pixel++) - { - UINT *startLine = rectPtr; - for (int x_pixel = r.left; x_pixel < r.right; x_pixel++) - { - *rectPtr = lineColor; - rectPtr++; - } - rectPtr = startLine; - rectPtr += 320; - } - - DODX( (dx_state->pTexVisuals[BACK_VIS]->UnlockRect(0)), dx_draw_filled_rect ); - } - - if (color1.mask & GFX_MASK_PRIORITY) - { - byte *pri; - pri = dx_state->priority_maps[BACK_PRI]->index_data + box.x + box.y*(320); - for(int i=0; i<box.yl; i++) - { - memset(pri,color1.priority,box.xl); - pri += 320; - } - } - - return GFX_OK; -} - - -// Draws a single line to the back buffer -static int -dx_draw_line(struct _gfx_driver *drv, - point_t start, point_t end, - gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style) -{ - if (color.mask & GFX_MASK_VISUAL) { - - rect_t line_rect = { start.x, start.y, end.x - start.x + 1, end.y - start.y + 1 }; - - sciprintf("dx_draw_line(): %i,%i -> %i,%i\n", line_rect.x, line_rect.y, line_rect.xl + line_rect.x, line_rect.yl + line_rect.y); - - // Make sure priorities are not updated in dx_draw_filled_rect() - gfx_color_t col = color; - col.mask = GFX_MASK_VISUAL; - - dx_draw_filled_rect(drv, line_rect, col, col, GFX_SHADE_FLAT); - } - - if (color.mask & GFX_MASK_PRIORITY) { - gfx_draw_line_pixmap_i(dx_state->priority_maps[BACK_PRI], start, end, color.priority); - } - - return GFX_OK; -} - - -///// PIXMAPS - -// Register the pixmap as a texture -static int -dx_register_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm) -{ - HRESULT hr; - - int i, xs; - byte *s, *d; - D3DLOCKED_RECT lockedRect; - LPDIRECT3DTEXTURE8 newTex; - DODX( (dx_state->pDevice->CreateTexture(pxm->xl, pxm->yl, 1, 0, dx_state->d3dFormat, D3DPOOL_MANAGED, &newTex )), dx_register_pixmap ); - - // Do gfx crossblit - DODX( (newTex->LockRect(0, &lockedRect, NULL, 0)), dx_register_pixmap ); - s = pxm->data; - d = (byte *) lockedRect.pBits; - xs = drv->mode->bytespp * pxm->xl; - - for(i = 0; i < pxm->yl; i++) - { - memcpy(d, s, xs); - s += xs; - d += lockedRect.Pitch; - } - DODX( (newTex->UnlockRect(0)), dx_register_pixmap ); - - pxm->internal.info = newTex; - pxm->internal.handle = SCI_DX_HANDLE_NORMAL; - - return GFX_OK; -} - - -// Unregister the pixmap -static int -dx_unregister_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm) -{ - SAFE_RELEASE((LPDIRECT3DTEXTURE8) (pxm->internal.info)); - pxm->internal.info = NULL; - - return GFX_OK; -} - - -// Draws part of a pixmap to the static or back buffer -static int -dx_draw_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm, int priority, - rect_t src, rect_t dest, gfx_buffer_t buffer) -{ - HRESULT hr; - int bufnr = (buffer == GFX_BUFFER_STATIC) ? 2 : 1; - int pribufnr = bufnr - 1; - LPDIRECT3DTEXTURE8 srct, dstt; - LPDIRECT3DSURFACE8 sbuf, dbuf; - D3DLOCKED_RECT lockedRect; - byte *pri_map = NULL; - - if (pxm->internal.handle == SCI_DX_HANDLE_GRABBED) { - // copy from pxm->internal.info to visual[bufnr] - RECT srcRect = RECT_T_TO_RECT(src); - POINT dstPoint = { dest.x, dest.y }; - - srct = (LPDIRECT3DTEXTURE8) (pxm->internal.info); - dstt = dx_state->pTexVisuals[bufnr]; - - DODX( (srct->GetSurfaceLevel(0, &sbuf)), dx_draw_pixmap ); - DODX( (dstt->GetSurfaceLevel(0, &dbuf)), dx_draw_pixmap ); - DODX( (dx_state->pDevice->CopyRects(sbuf, &srcRect, 1, dbuf, &dstPoint)), dx_draw_pixmap ); - - SAFE_RELEASE(sbuf); - SAFE_RELEASE(dbuf); - - return GFX_OK; - } - - - // Create texture to temporarily hold visuals[bufnr] - LPDIRECT3DTEXTURE8 temp; - DODX( (dx_state->pDevice->CreateTexture(pxm->xl, pxm->yl, 1, 0, dx_state->d3dFormat, D3DPOOL_MANAGED, &temp)), dx_draw_pixmap ); - RECT srcRect = RECT_T_TO_RECT(dest); - RECT destRect = { 0, 0, dest.xl, dest.yl }; - POINT dstPoint = { destRect.left, destRect.top }; - - // Copy from visuals[bufnr] to temp - srct = dx_state->pTexVisuals[bufnr]; - dstt = temp; - DODX( (srct->GetSurfaceLevel(0, &sbuf)), dx_draw_pixmap ); - DODX( (dstt->GetSurfaceLevel(0, &dbuf)), dx_draw_pixmap ); - DODX( (dx_state->pDevice->CopyRects(sbuf, &srcRect, 1, dbuf, &dstPoint)), dx_draw_pixmap ); - - // Copy from given pixmap to temp - DODX( (dbuf->LockRect(&lockedRect, &destRect, 0)), dx_draw_pixmap ); - gfx_crossblit_pixmap(drv->mode, pxm, priority, src, dest, - (byte *) lockedRect.pBits, lockedRect.Pitch, - dx_state->priority_maps[pribufnr]->index_data, - dx_state->priority_maps[pribufnr]->index_xl, 1, - GFX_CROSSBLIT_FLAG_DATA_IS_HOMED); - DODX( (dbuf->UnlockRect()), dx_draw_pixmap ); - - SAFE_RELEASE(sbuf); - SAFE_RELEASE(dbuf); - - - // Copy from temp to visuals[bufnr] - RECT src2Rect = { 0, 0, dest.xl, dest.yl }; - POINT dst2Point = { dest.x, dest.y }; - - srct = temp; - dstt = dx_state->pTexVisuals[bufnr]; - DODX( (srct->GetSurfaceLevel(0, &sbuf)), dx_draw_pixmap ); - DODX( (dstt->GetSurfaceLevel(0, &dbuf)), dx_draw_pixmap ); - DODX( (dx_state->pDevice->CopyRects(sbuf, &src2Rect, 1, dbuf, &dst2Point)), dx_draw_pixmap ); - - SAFE_RELEASE(sbuf); - SAFE_RELEASE(dbuf); - SAFE_RELEASE(temp); - - return GFX_OK; -} - - -// Grabs an image from the visual or priority back buffer -static int -dx_grab_pixmap(struct _gfx_driver *drv, rect_t src, gfx_pixmap_t *pxm, - gfx_map_mask_t map) -{ - HRESULT hr; - - if (src.x < 0 || src.y < 0) { - GFXERROR("Attempt to grab pixmap from invalid coordinates (%d,%d)\n", src.x, src.y); - return GFX_ERROR; - } - - if (!pxm->data) { - GFXERROR("Attempt to grab pixmap to unallocated memory\n"); - return GFX_ERROR; - } - - // Choose map to grab from - switch (map) { - - case GFX_MASK_VISUAL: { - LPDIRECT3DTEXTURE8 temp; - LPDIRECT3DSURFACE8 tempSrf, backSrf; - CONST RECT srcRect = RECT_T_TO_RECT(src); - CONST POINT dstPoint = { 0, 0 }; - - pxm->xl = src.xl; - pxm->yl = src.yl; - - DODX( (dx_state->pDevice->CreateTexture(pxm->xl, pxm->yl, 1, 0, dx_state->d3dFormat, D3DPOOL_MANAGED, &temp)), dx_grab_pixmap ); - - DODX( (dx_state->pTexVisuals[BACK_VIS]->GetSurfaceLevel(0, &backSrf)), dx_grab_pixmap ); - DODX( (temp->GetSurfaceLevel(0, &tempSrf)), dx_grab_pixmap ); - DODX( (dx_state->pDevice->CopyRects(backSrf, &srcRect, 1, tempSrf, &dstPoint)), dx_grab_pixmap ); - - pxm->internal.info = temp; - pxm->internal.handle = SCI_DX_HANDLE_GRABBED; - pxm->flags |= GFX_PIXMAP_FLAG_INSTALLED | GFX_PIXMAP_FLAG_EXTERNAL_PALETTE | GFX_PIXMAP_FLAG_PALETTE_SET; - - SAFE_RELEASE(backSrf); - SAFE_RELEASE(tempSrf); - - break; - } - - case GFX_MASK_PRIORITY: - sciprintf("FIXME: priority map grab not implemented yet!\n"); - break; - - default: - sciprintf("Attempt to grab pixmap from invalid map 0x%02x\n", map); - return GFX_ERROR; - } - - return GFX_OK; -} - - -///// BUFFERING - -// Updates the front buffer or the back buffers -static int -dx_update(struct _gfx_driver *drv, rect_t src, point_t dest, gfx_buffer_t buffer) -{ - HRESULT hr; - LPDIRECT3DTEXTURE8 srct, dstt; - LPDIRECT3DSURFACE8 sbuf, dbuf; - CONST RECT srcRect = RECT_T_TO_RECT(src); - CONST POINT dstPoint = { dest.x, dest.y }; - - switch (buffer) { - - case GFX_BUFFER_FRONT: - srct = dx_state->pTexVisuals[BACK_VIS]; - dstt = dx_state->pTexVisuals[PRIMARY_VIS]; - - DODX( (srct->GetSurfaceLevel(0, &sbuf)), dx_update ); - DODX( (dstt->GetSurfaceLevel(0, &dbuf)), dx_update ); - - DODX( (dx_state->pDevice->CopyRects(sbuf, &srcRect, 1, dbuf, &dstPoint)), dx_update ); - - SAFE_RELEASE(sbuf); - SAFE_RELEASE(dbuf); - - RenderD3D(drv); - break; - - case GFX_BUFFER_BACK: - if (src.x == dest.x && src.y == dest.y) - gfx_copy_pixmap_box_i(dx_state->priority_maps[BACK_PRI], dx_state->priority_maps[STATIC_PRI], src); - - srct = dx_state->pTexVisuals[STATIC_VIS]; - dstt = dx_state->pTexVisuals[BACK_VIS]; - - DODX( (srct->GetSurfaceLevel(0, &sbuf)), dx_update ); - DODX( (dstt->GetSurfaceLevel(0, &dbuf)), dx_update ); - - DODX( (dx_state->pDevice->CopyRects(sbuf, &srcRect, 1, dbuf, &dstPoint)), dx_update ); - - SAFE_RELEASE(sbuf); - SAFE_RELEASE(dbuf); - - break; - - default: - GFXERROR("Invalid buffer %d in update!\n", buffer); - return GFX_ERROR; - } - - return GFX_OK; -} - - -// Sets the contents of the static visual and priority buffers -static int -dx_set_static_buffer(struct _gfx_driver *drv, gfx_pixmap_t *pic, - gfx_pixmap_t *priority) -{ - if (!pic->internal.info) { - GFXERROR("Attempt to set static buffer with unregistered pixmap!\n"); - return GFX_ERROR; - } - - HRESULT hr; - LPDIRECT3DTEXTURE8 pii = (LPDIRECT3DTEXTURE8) (pic->internal.info); - LPDIRECT3DSURFACE8 pbf; - LPDIRECT3DTEXTURE8 vis = dx_state->pTexVisuals[STATIC_VIS]; - LPDIRECT3DSURFACE8 vbf; - - // Copy from pic to visual[static] - DODX( (pii->GetSurfaceLevel(0, &pbf)), dx_set_static_buffer ); - DODX( (vis->GetSurfaceLevel(0, &vbf)), dx_set_static_buffer ); - DODX( (dx_state->pDevice->CopyRects(pbf, NULL, 0, vbf, NULL)), dx_set_static_buffer ); - - SAFE_RELEASE(pbf); - SAFE_RELEASE(vbf); - - // Copy priority map - gfx_copy_pixmap_box_i(dx_state->priority_maps[STATIC_PRI], priority, gfx_rect(0, 0, 320, 200)); - - return GFX_OK; -} - - -///// MOUSE - -// Sets a new mouse pointer -static int -dx_set_pointer(struct _gfx_driver *drv, gfx_pixmap_t *pointer) -{ - HRESULT hr; - - if (pointer->data == NULL) - return GFX_OK; - pointer->yl /= 2; // Scale the pointer to compensate for mode scale - - LPDIRECT3DTEXTURE8 pntTex; - LPDIRECT3DSURFACE8 pntSrf; - - // Get pointer dimensions and init - POINTS pDims = {pointer->xl, pointer->yl}; - dx_state->pointerDims = pDims; - RECT r = {0, 0, pointer->xl, pointer->yl}; - - // Recreate pointer data according to the graphics mode we need - gfx_pixmap_free_data(pointer); - gfx_xlate_pixmap(pointer, dx_state->pointerMode, GFX_XLATE_FILTER_NONE); - - // Create texture and fill with pointer data - DODX( (dx_state->pDevice->CreateTexture(pointer->xl, pointer->yl, 1, 0, dx_state->d3dFormat, D3DPOOL_MANAGED, &pntTex )), dx_set_pointer ); - DODX( (pntTex->GetSurfaceLevel(0, &pntSrf)), dx_set_pointer ); - - DODX( (D3DXLoadSurfaceFromMemory(pntSrf, NULL, &r, pointer->data, dx_state->d3dFormat, 256, NULL, &r, D3DX_FILTER_NONE, 0)), dx_set_pointer); - - SAFE_RELEASE(pntSrf); - - // Assign as current pointer texture - if (dx_state->pTexPointer) - SAFE_RELEASE(dx_state->pTexPointer); - dx_state->pTexPointer = pntTex; - - return GFX_OK; -} - - -// Display mouse pointer -static int -show_pointer(struct _gfx_driver *drv, LPARAM pos) -{ - POINTS mousePos; // mouse coordinates - - // Sort out coordinates - mousePos = MAKEPOINTS(pos); - - // Update pos - drv->pointer_x = mousePos.x; - drv->pointer_y = mousePos.y; - - RenderD3D(drv); - - return GFX_OK; -} - - -///// EVENTS - -// Get event from the queue -static sci_event_t -get_queue_event(gfx_dx_struct_t *ctx) -{ - if (ctx->queue_first == ctx->queue_size) - ctx->queue_first = 0; - - if (ctx->queue_first == ctx->queue_last) - { - sci_event_t noevent; - noevent.data = 0; - noevent.type = SCI_EVT_NONE; - noevent.buckybits = 0; - return noevent; - } - else - return ctx->event_queue [ctx->queue_first++]; -} - - -// Add event to the queue -static void add_queue_event(gfx_dx_struct_t *ctx, int type, int data, short buckybits) -{ - if ((ctx->queue_last+1) % ctx->queue_size == ctx->queue_first) - { - /* Reallocate queue */ - int i, event_count; - sci_event_t *new_queue; - - new_queue = (sci_event_t *) sci_malloc (ctx->queue_size * 2 * sizeof (sci_event_t)); - event_count = (ctx->queue_last - ctx->queue_first) % ctx->queue_size; - for (i=0; i<event_count; i++) - new_queue [i] = ctx->event_queue [(ctx->queue_first+i) % ctx->queue_size]; - free (ctx->event_queue); - ctx->event_queue = new_queue; - ctx->queue_size *= 2; - ctx->queue_first = 0; - ctx->queue_last = event_count; - } - - ctx->event_queue [ctx->queue_last].data = data; - ctx->event_queue [ctx->queue_last].type = type; - ctx->event_queue [ctx->queue_last++].buckybits = buckybits; - if (ctx->queue_last == ctx->queue_size) - ctx->queue_last=0; -} - - -// Add keystroke event to queue -static void add_key_event (gfx_dx_struct_t *ctx, int data) -{ - short buckybits = 0; - - if (GetAsyncKeyState (VK_RSHIFT)) - buckybits |= SCI_EVM_RSHIFT; - if (GetAsyncKeyState (VK_LSHIFT)) - buckybits |= SCI_EVM_LSHIFT; - if (GetAsyncKeyState (VK_CONTROL)) - buckybits |= SCI_EVM_CTRL; - if (GetAsyncKeyState (VK_MENU)) - buckybits |= SCI_EVM_ALT; - if (GetKeyState (VK_SCROLL) & 1) - buckybits |= SCI_EVM_SCRLOCK; - if (GetKeyState (VK_NUMLOCK) & 1) - buckybits |= SCI_EVM_NUMLOCK; - if (GetKeyState (VK_CAPITAL) & 1) - buckybits |= SCI_EVM_CAPSLOCK; - - add_queue_event (ctx, SCI_EVT_KEYBOARD, data, buckybits); -} - - -// Add mouse event to queue -static void add_mouse_event(gfx_dx_struct_t *ctx, int type, int data, WPARAM wParam) -{ - short buckybits = 0; - if (wParam & MK_SHIFT) - buckybits |= SCI_EVM_LSHIFT | SCI_EVM_RSHIFT; - if (wParam & MK_CONTROL) - buckybits |= SCI_EVM_CTRL; - - add_queue_event (ctx, type, data, buckybits); -} - - -// Returns the next event in the event queue for this driver -static sci_event_t -dx_get_event(struct _gfx_driver *drv) -{ - assert(drv->state != NULL); - return get_queue_event(dx_state); -} - - -// Sleeps the specified amount of microseconds, or until the mouse moves -static int -dx_usleep(struct _gfx_driver *drv, long usecs) -{ - if (usecs < 1000) - { - sleep(0); - } - else - { - sleep(usecs/1000); - } - ProcessMessages(drv); - - return GFX_OK; -} - - -// Process any Windows messages -static int -ProcessMessages(struct _gfx_driver *drv) -{ - MSG msg; - - while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { - switch( msg.message ) - { - case WM_PAINT: - ValidateRect( dx_state->hWnd, NULL ); - RenderD3D(drv); - break; - - case WM_KEYDOWN: - switch (msg.wParam) - { - MAP_KEY (VK_ESCAPE, SCI_K_ESC); - MAP_KEY (VK_BACK, SCI_K_BACKSPACE); - MAP_KEY (VK_RETURN, SCI_K_ENTER); - MAP_KEY (VK_TAB, SCI_K_TAB); - MAP_KEY (VK_END, SCI_K_END); - MAP_KEY (VK_DOWN, SCI_K_DOWN); - MAP_KEY (VK_NEXT, SCI_K_PGDOWN); - MAP_KEY (VK_LEFT, SCI_K_LEFT); - MAP_KEY (VK_RIGHT, SCI_K_RIGHT); - MAP_KEY (VK_HOME, SCI_K_HOME); - MAP_KEY (VK_UP, SCI_K_UP); - MAP_KEY (VK_PRIOR, SCI_K_PGUP); - MAP_KEY (VK_INSERT, SCI_K_INSERT); - MAP_KEY (VK_DELETE, SCI_K_DELETE); - MAP_KEY (VK_DECIMAL, SCI_K_DELETE); - /* TODO: Glutton no longer had SCI_K etc... declared - MAP_KEY (VK_ADD, SCI_K_PLUS); - MAP_KEY (VK_OEM_PLUS, SCI_K_EQUALS); - MAP_KEY (VK_SUBTRACT, SCI_K_MINUS); - MAP_KEY (VK_OEM_MINUS, SCI_K_MINUS); - MAP_KEY (VK_MULTIPLY, SCI_K_MULTIPLY); - MAP_KEY (VK_DIVIDE, SCI_K_DIVIDE); - */ - MAP_KEY (VK_OEM_COMMA, ','); - MAP_KEY (VK_OEM_PERIOD, '.'); - MAP_KEY (VK_OEM_1, ';'); // US keyboards only - MAP_KEY (VK_OEM_2, '/'); - MAP_KEY (VK_OEM_3, '`'); - MAP_KEY (VK_OEM_4, '['); - MAP_KEY (VK_OEM_5, '\\'); - MAP_KEY (VK_OEM_6, ']'); - MAP_KEY (VK_OEM_7, '\''); - MAP_KEY (VK_F1, SCI_K_F1); - MAP_KEY (VK_F2, SCI_K_F2); - MAP_KEY (VK_F3, SCI_K_F3); - MAP_KEY (VK_F4, SCI_K_F4); - MAP_KEY (VK_F5, SCI_K_F5); - MAP_KEY (VK_F6, SCI_K_F6); - MAP_KEY (VK_F7, SCI_K_F7); - MAP_KEY (VK_F8, SCI_K_F8); - MAP_KEY (VK_F9, SCI_K_F9); - MAP_KEY (VK_F10, SCI_K_F10); - - case VK_RSHIFT: - case VK_LSHIFT: - case VK_CONTROL: - case VK_MENU: - case VK_SCROLL: - case VK_NUMLOCK: - case VK_CAPITAL: - break; // ignore - - default: - if (msg.wParam >= 'A' && msg.wParam <= 'Z') - add_key_event (dx_state, msg.wParam - 'A' + 97); - else if (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9) - { - if (GetKeyState (VK_NUMLOCK) & 1) - add_key_event (dx_state, msg.wParam - VK_NUMPAD0 + '0'); - else - switch (msg.wParam) - { - MAP_KEY (VK_NUMPAD0, SCI_K_INSERT); - MAP_KEY (VK_NUMPAD1, SCI_K_END); - MAP_KEY (VK_NUMPAD2, SCI_K_DOWN); - MAP_KEY (VK_NUMPAD3, SCI_K_PGDOWN); - MAP_KEY (VK_NUMPAD4, SCI_K_LEFT); - MAP_KEY (VK_NUMPAD6, SCI_K_RIGHT); - MAP_KEY (VK_NUMPAD7, SCI_K_HOME); - MAP_KEY (VK_NUMPAD8, SCI_K_UP); - MAP_KEY (VK_NUMPAD9, SCI_K_PGUP); - } - } - else if (msg.wParam == 0xC0) // tilde key - used for invoking console - add_key_event (dx_state, '`'); - else - add_key_event (dx_state, msg.wParam); - break; - } - break; - - case WM_MOUSEMOVE: - // Turn off mouse cursor - ShowCursor(FALSE); - show_pointer(drv, msg.lParam); - break; - - case WM_MOUSELEAVE: - // Turn on mouse cursor - ShowCursor(TRUE); - break; - - case WM_LBUTTONDOWN: add_mouse_event (dx_state, SCI_EVT_MOUSE_PRESS, 1, msg.wParam); break; - case WM_RBUTTONDOWN: add_mouse_event (dx_state, SCI_EVT_MOUSE_PRESS, 2, msg.wParam); break; - case WM_MBUTTONDOWN: add_mouse_event (dx_state, SCI_EVT_MOUSE_PRESS, 3, msg.wParam); break; - case WM_LBUTTONUP: add_mouse_event (dx_state, SCI_EVT_MOUSE_RELEASE, 1, msg.wParam); break; - case WM_RBUTTONUP: add_mouse_event (dx_state, SCI_EVT_MOUSE_RELEASE, 2, msg.wParam); break; - case WM_MBUTTONUP: add_mouse_event (dx_state, SCI_EVT_MOUSE_RELEASE, 3, msg.wParam); break; - - case WM_DESTROY: - PostQuitMessage( 0 ); - drv->exit(drv); - exit(-1); - break; - - } - } - - return 0; -} - - -extern "C" -gfx_driver_t gfx_driver_dx = { - "directx", - "0.4.2", - SCI_GFX_DRIVER_MAGIC, - SCI_GFX_DRIVER_VERSION, - NULL, /* mode */ - 0, 0, /* mouse pointer position */ - GFX_CAPABILITY_MOUSE_SUPPORT | GFX_CAPABILITY_MOUSE_POINTER | GFX_CAPABILITY_COLOR_MOUSE_POINTER | GFX_CAPABILITY_PIXMAP_REGISTRY | GFX_CAPABILITY_WINDOWED, - 0, - dx_set_param, - dx_init_specific, - dx_init, - dx_exit, - dx_draw_line, - dx_draw_filled_rect, - dx_register_pixmap, - dx_unregister_pixmap, - dx_draw_pixmap, - dx_grab_pixmap, - dx_update, - dx_set_static_buffer, - dx_set_pointer, - NULL, - dx_get_event, - dx_usleep, - NULL -}; - -#endif diff --git a/engines/sci/gfx/drivers/dx_driver.h b/engines/sci/gfx/drivers/dx_driver.h deleted file mode 100644 index 3eb280cefb..0000000000 --- a/engines/sci/gfx/drivers/dx_driver.h +++ /dev/null @@ -1,151 +0,0 @@ -/*************************************************************************** - graphics_directx.h Copyright (C) 2008 Alexander R Angas, - Some portions Copyright (C) 1999 Dmitry Jemerov - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Alexander R Angas (Alex) <arangas AT internode dot on dot net> - -***************************************************************************/ - -#include <windows.h> -#include <d3d8.h> -#include <d3dx8math.h> -#include <dxerr8.h> - -extern "C" { -#include <gfx_system.h> -#include <gfx_driver.h> -#include <gfx_tools.h> -#include <assert.h> -#include <uinput.h> -#include <ctype.h> -#include <console.h> // for sciprintf -#include <sci_win32.h> -#include <sci_memory.h> -}; - -// Error trapping, every DirectX call should use this -#define DODX(cmd, proc) \ - hr = cmd; \ - if (hr != S_OK) { \ - sciprintf("%s, %i, %i, %s from %s\n", __FILE__, __LINE__, hr, #cmd, #proc); \ - DXTrace(__FILE__, __LINE__, hr, #cmd" from "#proc, 1); \ - } - - -// Easily release only allocated objects -#define SAFE_RELEASE(p) \ - if (p) \ - (p)->Release(); - - -// Make it simple to access drv->state -#define dx_state ((struct gfx_dx_struct_t *)(drv->state)) - - -// Simply map a key using add_key_event() -#define MAP_KEY(x,y) case x: add_key_event ((struct gfx_dx_struct_t *)(drv->state), y); break - - -#define DX_CLASS_NAME "FreeSCI DirectX Graphics" -#define DX_APP_NAME "FreeSCI" - -// Vertex format -#define D3DFVF_CUSTOMVERTEX ( D3DFVF_DIFFUSE | D3DFVF_XYZRHW | D3DFVF_TEX1 ) - -// Vertex structure -struct CUSTOMVERTEX -{ - D3DXVECTOR4 p; // Vertex coordinates - DWORD colour; // Colour - D3DXVECTOR2 t; // Texture coordinates -}; - -#define SCI_DX_HANDLE_NORMAL 0 -#define SCI_DX_HANDLE_GRABBED 1 - -// Number of buffers for each type of texture -#define NUM_VISUAL_BUFFERS 3 -#define NUM_PRIORITY_BUFFERS 2 - -// What each buffer references -#define PRIMARY_VIS 0 -#define BACK_VIS 1 -#define STATIC_VIS 2 - -#define BACK_PRI 0 -#define STATIC_PRI 1 - -// Struct that holds everything -struct gfx_dx_struct_t -{ - D3DFORMAT d3dFormat; // Colour format - UINT adapterId; // Adapter ID to use - DWORD vertexProcessing; // Hardware or software vertex processing - - LPDIRECT3D8 pD3d; // D3D object - D3DCAPS8 deviceCaps; // Capabilities of device - D3DDISPLAYMODE displayMode; // Width and height of screen - D3DPRESENT_PARAMETERS presParams; // Presentation parameters - LPDIRECT3DDEVICE8 pDevice; // Rendering device - - LPDIRECT3DVERTEXBUFFER8 pVertBuff; // Buffer to hold pixmap vertices - CUSTOMVERTEX pvData[4]; // Buffer of pixmap vertex structs - - LPDIRECT3DTEXTURE8 pTexVisuals[NUM_VISUAL_BUFFERS]; // Array of visual textures - LPDIRECT3DTEXTURE8 pTexPrioritys[NUM_PRIORITY_BUFFERS]; // Array of priority textures - gfx_pixmap_t *priority_maps[NUM_PRIORITY_BUFFERS]; // Array of SCI priority maps - - gfx_mode_t *pointerMode; // SCI graphics mode for pointer - LPDIRECT3DTEXTURE8 pTexPointer; // Mouse pointer texture - LPD3DXSPRITE pSPointer; // Mouse pointer sprite - POINTS pointerDims; // Pointer dimensions - - WNDCLASSEX wc; // Window class - HWND hWnd; // Window - UINT xfact, yfact; // Scaling factors - UINT bpp; // Bits per pixel - - // Event queue - int queue_size, queue_first, queue_last; - sci_event_t *event_queue; -}; - -// Flags that may be set in the driver -#define DX_FLAGS_FULLSCREEN 1 - -// Initialization functions -static int -ProcessMessages(struct _gfx_driver *drv); - -static gfx_return_value_t -RenderD3D(struct _gfx_driver *drv); - -static int -CheckDevice(struct _gfx_driver *drv); - -static gfx_return_value_t -InitWindow(struct _gfx_driver *drv, UINT width, UINT height); - -static gfx_return_value_t -InitD3D(struct _gfx_driver *drv); - -static gfx_return_value_t -InitScene(struct _gfx_driver *drv); diff --git a/engines/sci/gfx/drivers/gfx_drivers.c b/engines/sci/gfx/drivers/gfx_drivers.c deleted file mode 100644 index b47d6467c9..0000000000 --- a/engines/sci/gfx/drivers/gfx_drivers.c +++ /dev/null @@ -1,192 +0,0 @@ -/*************************************************************************** - gfx_drivers.c Copyright (C) 2001 Christoph Reichenbach - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Christoph Reichenbach (CR) <jameson@linuxgames.com> - -***************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include <gfx_driver.h> -#include <modules.h> - - -static char *oldname = NULL; -static void *oldhandle; - - - -#ifndef HAVE_DLOPEN -# ifdef HAVE_LIBGGI -extern gfx_driver_t gfx_driver_ggi; -# endif - - -# ifndef X_DISPLAY_MISSING -extern gfx_driver_t gfx_driver_xlib; -# endif - -# ifdef HAVE_DIRECTX -extern gfx_driver_t gfx_driver_dx; -# endif - -# ifdef HAVE_DDRAW -extern gfx_driver_t gfx_driver_dd; -# endif - -# ifdef HAVE_SDL -extern gfx_driver_t gfx_driver_sdl; -# endif - -# ifdef HAVE_DIRECTFB -extern gfx_driver_t gfx_driver_dfb; -# endif - -# ifdef _DREAMCAST -extern gfx_driver_t gfx_driver_dc; -# endif -#endif - -extern gfx_driver_t gfx_driver_null; - -static gfx_driver_t *gfx_drivers[] = { -#ifndef HAVE_DLOPEN -# ifndef X_DISPLAY_MISSING - &gfx_driver_xlib, -# endif -# ifdef HAVE_SDL - &gfx_driver_sdl, -# endif -# ifdef HAVE_DIRECTX - &gfx_driver_dx, -# endif -# ifdef HAVE_DDRAW - &gfx_driver_dd, -# endif -# ifdef HAVE_DIRECTFB - &gfx_driver_dfb, -# endif -# ifdef HAVE_LIBGGI - &gfx_driver_ggi, -# endif -# ifdef _DREAMCAST - &gfx_driver_dc, -# endif -#endif - &gfx_driver_null, - NULL -}; - -#define DRIVER_TYPE "gfx" -#define DRIVER_PREFIX "gfx_driver_" -#define DRIVER_FILE_SUFFIX "_driver" - -#ifdef HAVE_DLOPEN -struct _gfx_driver * -gfx_find_driver(char *path, char *name) -{ - int retval = 0; - - if (oldhandle) - sci_close_module(oldhandle, DRIVER_TYPE, oldname); - - if (!name) { /* Find default driver */ -#ifdef _WIN32 - name = "sdl"; -#else /* !_WIN32 */ -# ifndef X_DISPLAY_MISSING - if (getenv("DISPLAY")) - name = "xlib"; - else -# endif - name = "ggi"; -#endif /* !_WIN32 */ - } - - oldname = name; - return (struct _gfx_driver *) - sci_find_module(path, name, DRIVER_TYPE, - DRIVER_PREFIX, - DRIVER_FILE_SUFFIX, - SCI_GFX_DRIVER_MAGIC, - SCI_GFX_DRIVER_VERSION, - &oldhandle); -} -#else /* No dlopen */ -struct _gfx_driver * -gfx_find_driver(char *path, char *name) -{ - int retval = 0; - - if (!name) { /* Find default driver */ -#ifndef X_DISPLAY_MISSING - if (getenv("DISPLAY")) - return &gfx_driver_xlib; -#endif -#if defined (MACOSX) && defined(HAVE_SDL) - return &gfx_driver_sdl; -#endif - return gfx_drivers[0]; - } - - while (gfx_drivers[retval] && strcasecmp(name, gfx_drivers[retval]->name)) - retval++; - - return gfx_drivers[retval]; -} -#endif - - -const char * -gfx_get_driver_name(int nr) -{ - return (gfx_drivers[nr])? gfx_drivers[nr]->name : NULL; -} - - -int -string_truep(char *value) -{ - return !(strcasecmp(value, "ok") && - strcasecmp(value, "enable") && - strcasecmp(value, "1") && - strcasecmp(value, "true") && - strcasecmp(value, "yes") && - strcasecmp(value, "on")); -} - - -int -string_falsep(char *value) -{ - return !(strcasecmp(value, "disable") && - strcasecmp(value, "0") && - strcasecmp(value, "false") && - strcasecmp(value, "no") && - strcasecmp(value, "off")); -} - - - - diff --git a/engines/sci/gfx/drivers/ggi_driver.c b/engines/sci/gfx/drivers/ggi_driver.c deleted file mode 100644 index c6cf4b0f00..0000000000 --- a/engines/sci/gfx/drivers/ggi_driver.c +++ /dev/null @@ -1,1035 +0,0 @@ -/*************************************************************************** - ggi_driver.c Copyright (C) 2000 Christoph Reichenbach - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Christoph Reichenbach (CR) <jameson@linuxgames.com> - -***************************************************************************/ -/* FreeSCI 0.3.1+ graphics driver module for libggi */ - - -#include <stdarg.h> -#include <gfx_system.h> -#include <gfx_driver.h> -#include <gfx_tools.h> -#include <assert.h> -#include <uinput.h> - -#ifdef HAVE_LIBGGI - -#include <ggi/ggi.h> -#include <ctype.h> - - -#define GGI_DRIVER_VERSION "0.4" - -#define GFX_GGI_DEBUG - -#ifdef GFX_GGI_DEBUG - -#define POSMSG sciprintf("%s L%d:", __FILE__, __LINE__) -#define DEBUG_POINTER (!(drv->debug_flags & GFX_DEBUG_POINTER))? 0 : POSMSG && gfxprintf -#define DEBUG_UPDATES (!(drv->debug_flags & GFX_DEBUG_UPDATES))? 0 : POSMSG && gfxprintf -#define DEBUG_PIXMAPS (!(drv->debug_flags & GFX_DEBUG_PIXMAPS))? 0 : POSMSG && sciprintf -#define DEBUG_BASIC (!(drv->debug_flags & GFX_DEBUG_BASIC))? 0 : POSMSG && sciprintf -#else /* !GFX_GGI_DEBUG */ -#define DEBUG_POINTER (1)? 0 : -#define DEBUG_UPDATES (1)? 0 : -#define DEBUG_PIXMAPS (1)? 0 : -#define DEBUG_BASIC (1)? 0 : -#endif /* !GFX_GGI_DEBUG */ - -static gfx_mode_t * -_aberr(char *file, int line, char *message); - -static void -init_input_ggi(); - -#define MODE ((drv->mode)? drv->mode : _aberr(__FILE__, __LINE__, "drv->mode is NULL")) -#define STATE ((gfx_ggi_struct_t *)drv->state) -#define VISUAL ((gfx_ggi_struct_t *)drv->state)->vis -#define FRAMES ((gfx_ggi_struct_t *)drv->state)->frames - -static gfx_mode_t * -_aberr(char *file, int line, char *message) -{ - fprintf(stderr,"GFXGGI: Fatal: %s L%d: %s\n", file, line, message); - exit(1); /* Die */ - return NULL; -} - -#define GGI_BUFFER_BACK 0 -#define GGI_BUFFER_STATIC 1 - -#define SCI_GGI_SWAP_CTRL_CAPS (1 << 0) - -typedef struct { - ggi_visual_t vis; - int frames; - - byte *alt_back_buffer; /* if frames < 2: Virtual back buffer */ - ggi_visual_t back_vis; /* Memory visual for the back buffer */ - - byte *static_buffer; /* if frames < 3: Virtual static buffer */ - ggi_visual_t static_vis; /* Memory visual for the static buffer */ - - gfx_pixmap_t *priority_maps[2]; - ggi_visual_t priority_visuals[2]; /* Visuals for the maps */ - - int x_blank, y_blank; - int x_blank2, y_blank2; - -} gfx_ggi_struct_t; - -static int flags; - -static int -ggi_set_param(gfx_driver_t *drv, char *attribute, char *value) -{ - gfx_ggi_struct_t *meta = (gfx_ggi_struct_t *) drv->state; - - if (!strcmp(attribute, "swap_ctrl_caps") || - !strcmp(attribute, "swap_caps_ctrl")) { - if (string_truep(value)) - flags |= SCI_GGI_SWAP_CTRL_CAPS; - else - flags &= ~SCI_GGI_SWAP_CTRL_CAPS; - - return GFX_OK; - } - - DEBUG_BASIC("ggi_set_param('%s' to '%s')\n", attribute, value); - return GFX_ERROR; -} - - -static int -_open_meta_visuals(gfx_driver_t *drv) -{ - int i; - - for (i = 0; i < 2; i++) { - if (!(STATE->priority_visuals[i] = ggiOpen("memory:pointer", STATE->priority_maps[i]->data))) { - sciprintf("GFXGGI: Could not open priority map #%d\n", i); - return 1; - } - if (ggiSetSimpleMode(STATE->priority_visuals[i], 320 * MODE->xfact, 200 * MODE->yfact, 1, GT_8BIT)) { - sciprintf("GFXGGI: Could not set mode for priority visual %d\n", i); - return 1; - } - } - - return 0; -} - -static int -ggi_init_specific(gfx_driver_t *drv, int xres, int yres, int bpp) -{ - gfx_ggi_struct_t *meta; - ggi_graphtype graphtype; - const ggi_pixelformat *pixelformat; - int frames = 3; - - switch (bpp) { - case 1: graphtype = GT_8BIT; break; - case 2: graphtype = GT_16BIT; break; - case 3: graphtype = GT_24BIT; break; - case 4: graphtype = GT_32BIT; break; - default: sciprintf("GFXGGI: Error: Invalid bytes per pixel value: %d\n", bpp); - return GFX_ERROR; - } - - drv->state = NULL; - - if (ggiInit() < 0) - return GFX_FATAL; - - meta = (gfx_ggi_struct_t *) sci_calloc(sizeof(gfx_ggi_struct_t), 1); - - if (!(meta->vis = ggiOpen(NULL))) { - DEBUG_BASIC("ggiOpen() failed!\n"); - free(meta); - ggiExit(); - return GFX_FATAL; - } - - while ((frames > 0) && (ggiSetSimpleMode(meta->vis, xres * 320, yres * 200, frames, graphtype))) - --frames; - - if (!frames) { - DEBUG_BASIC("Initializing %dx%d at %d bpp failed\n", xres*320, yres*200, bpp << 3); - free(meta); - ggiExit(); - return GFX_ERROR; - } - - DEBUG_BASIC("Initialized with %d frames\n", frames); - - meta->frames = frames; - - pixelformat = ggiGetPixelFormat(meta->vis); - drv->mode = gfx_new_mode(xres, yres, pixelformat->size >> 3, - pixelformat->red_mask, pixelformat->green_mask, pixelformat->blue_mask, - 0, /* alpha mask */ - pixelformat->red_shift, pixelformat->green_shift, pixelformat->blue_shift, - 0, /* alpha shift */ - (bpp == 1)? 256 : 0, 0); - drv->state = meta; - - meta->priority_maps[GGI_BUFFER_BACK] = - gfx_pixmap_alloc_index_data(gfx_new_pixmap(320 * xres, 200 * yres, GFX_RESID_NONE, 0, 0)); - meta->priority_maps[GGI_BUFFER_STATIC] = - gfx_pixmap_alloc_index_data(gfx_new_pixmap(320 * xres, 200 * yres, GFX_RESID_NONE, 0, 0)); - - meta->priority_maps[GGI_BUFFER_BACK]->flags |= GFX_PIXMAP_FLAG_SCALED_INDEX; - meta->priority_maps[GGI_BUFFER_STATIC]->flags |= GFX_PIXMAP_FLAG_SCALED_INDEX; - - if (_open_meta_visuals(drv)) { - free(meta); - gfx_free_pixmap(drv, meta->priority_maps[GGI_BUFFER_BACK]); - gfx_free_pixmap(drv, meta->priority_maps[GGI_BUFFER_STATIC]); - ggiClose(meta->vis); - ggiExit(); - return GFX_ERROR; - } - - if (frames < 2) { - meta->alt_back_buffer = (byte *) sci_malloc(bpp * 320 * 200 * xres * yres); - meta->back_vis = ggiOpen("memory:pointer", meta->alt_back_buffer, NULL); - if (ggiSetSimpleMode(meta->back_vis, xres * 320, yres * 200, 1, GT_8BIT)) { - sciprintf("GFXGGI: Warning: Setting mode for memory visual failed\n"); - } - } else meta->alt_back_buffer = NULL; - - if (frames < 3) { - meta->static_buffer = (byte *) sci_malloc(bpp * 320 * 200 * xres * yres); - meta->static_vis = ggiOpen("memory:pointer", meta->static_buffer, NULL); - if (ggiSetSimpleMode(meta->static_vis, xres * 320, yres * 200, 1, GT_8BIT)) { - sciprintf("GFXGGI: Warning: Setting mode for memory visual #2 failed\n"); - } - } else meta->static_buffer = NULL; - - init_input_ggi(); - flags = 0; - - return GFX_OK; -} - - -static int -ggi_init(gfx_driver_t *drv) -{ - gfx_ggi_struct_t *meta; - ggi_mode mode; - int x_blank, y_blank; - const ggi_pixelformat *pixelformat; - mode.frames = 3; - mode.visible.x = mode.visible.y = mode.virt.x = mode.virt.y - = mode.size.x = mode.size.y = mode.dpp.x = mode.dpp.y = GGI_AUTO; - - mode.graphtype = GT_AUTO; - - drv->state = NULL; - - if (ggiInit() < 0) - return GFX_FATAL; - - meta = (gfx_ggi_struct_t *) sci_calloc(sizeof(gfx_ggi_struct_t), 1); - - if (!(meta->vis = ggiOpen(NULL))) { - DEBUG_BASIC("ggiOpen() failed!\n"); - free(meta); - ggiExit(); - return GFX_FATAL; - } - - while (mode.frames && ggiCheckMode(meta->vis, &mode)) - --(mode.frames); - - if (!mode.frames) { - sciprintf("GFXGGI: Could not find any graphics mode!\n"); - free(meta); - ggiExit(); - return GFX_FATAL; - } - - x_blank = mode.visible.x % 320; - y_blank = mode.visible.y % 200; - mode.visible.x -= x_blank; - mode.visible.y -= y_blank; - - if (mode.visible.x == 0) - mode.visible.x = 320; - - if (mode.visible.y == 0) - mode.visible.y = 200; - - if (GT_DEPTH(mode.graphtype) < 8) - mode.graphtype = GT_8BIT; /* We don't support less than 8 bpp */ - - DEBUG_BASIC("Attempting to create mode with %dx%d, graphtype=%08x, %d frames\n", - mode.visible.x, mode.visible.y, mode.graphtype, mode.frames); - - mode.virt.x = mode.visible.x; - mode.virt.y = mode.visible.y; - mode.size.x = GGI_AUTO; - mode.size.y = GGI_AUTO; - - if (ggiSetMode(meta->vis, &mode)) { - sciprintf("GFXGGI: Could not set proposed graphics mode!\n"); - - mode.virt.x = mode.visible.x += x_blank; - mode.virt.y = mode.visible.y += y_blank; - mode.size.x = GGI_AUTO; - mode.size.y = GGI_AUTO; - - DEBUG_BASIC("Attempting to create augmented mode with %dx%d, graphtype=%08x, %d frames\n", - mode.visible.x, mode.visible.y, mode.graphtype, mode.frames); - - if (ggiSetMode(meta->vis, &mode)) { - sciprintf("GFXGGI: Could not set proposed graphics mode!\n"); - free(meta); - ggiExit(); - return GFX_FATAL; - } - - ggiSetOrigin(meta->vis, (x_blank >> 1), (y_blank >> 1)); - - mode.virt.x = mode.size.x = mode.visible.x -= x_blank; - mode.virt.y = mode.size.y = mode.visible.y -= y_blank; - } else - x_blank = y_blank = 0; - - meta->frames = mode.frames; - - pixelformat = ggiGetPixelFormat(meta->vis); - - drv->mode = gfx_new_mode(mode.visible.x / 320, mode.visible.y / 200, pixelformat->size >> 3, - pixelformat->red_mask, pixelformat->green_mask, pixelformat->blue_mask, - 0, /* alpha mask */ - pixelformat->red_shift, pixelformat->green_shift, pixelformat->blue_shift, - 0, /* alpha shift */ - (GT_SCHEME(mode.graphtype) == GT_PALETTE)? (1 << GT_DEPTH(mode.graphtype)) : 0, 0); - - drv->state = meta; - - meta->priority_maps[GGI_BUFFER_BACK] = - gfx_pixmap_alloc_index_data(gfx_new_pixmap(mode.visible.x, mode.visible.y, GFX_RESID_NONE, 0, 0)); - meta->priority_maps[GGI_BUFFER_STATIC] = - gfx_pixmap_alloc_index_data(gfx_new_pixmap(mode.visible.x, mode.visible.y, GFX_RESID_NONE, 0, 0)); - - meta->priority_maps[GGI_BUFFER_BACK]->flags |= GFX_PIXMAP_FLAG_SCALED_INDEX; - meta->priority_maps[GGI_BUFFER_STATIC]->flags |= GFX_PIXMAP_FLAG_SCALED_INDEX; - - if (_open_meta_visuals(drv)) { - free(meta); - gfx_free_pixmap(drv, meta->priority_maps[GGI_BUFFER_BACK]); - gfx_free_pixmap(drv, meta->priority_maps[GGI_BUFFER_STATIC]); - ggiClose(meta->vis); - ggiExit(); - return GFX_FATAL; - } - - if (meta->frames < 2) { - meta->alt_back_buffer = (byte *) sci_malloc((pixelformat->size >> 3) * mode.visible.x * mode.visible.y); - meta->back_vis = ggiOpen("memory:pointer", meta->alt_back_buffer, NULL); - if (ggiSetSimpleMode(meta->back_vis, mode.visible.x, mode.visible.y, 1, GT_8BIT)) { - sciprintf("GFXGGI: Warning: Setting mode for memory visual failed\n"); - } - } else meta->alt_back_buffer = NULL; - - if (meta->frames < 3) { - meta->static_buffer = (byte *) sci_malloc((pixelformat->size >> 3) * mode.visible.x * mode.visible.y); - meta->static_vis = ggiOpen("memory:pointer", meta->static_buffer, NULL); - if (ggiSetSimpleMode(meta->static_vis, mode.visible.x, mode.visible.y, 1, GT_8BIT)) { - sciprintf("GFXGGI: Warning: Setting mode for memory visual #2 failed\n"); - } - } else meta->static_buffer = NULL; - - init_input_ggi(); - flags = 0; - - STATE->x_blank = x_blank; - STATE->y_blank = y_blank; - STATE->x_blank2 = x_blank >> 1; - STATE->y_blank2 = y_blank >> 1; - - return GFX_OK; -} - - -static void -ggi_exit(gfx_driver_t *drv) -{ - if (drv->state) { - gfx_free_pixmap(drv, STATE->priority_maps[0]); - gfx_free_pixmap(drv, STATE->priority_maps[1]); - - if (STATE->frames < 2) - ggiClose(STATE->back_vis); - - if (STATE->frames < 3) - ggiClose(STATE->static_vis); - - ggiClose(STATE->priority_visuals[0]); - ggiClose(STATE->priority_visuals[1]); - - ggiClose(VISUAL); - } - - gfx_free_mode(drv->mode); - - ggiExit(); - - if (FRAMES < 2) - free(STATE->alt_back_buffer); - - free(drv->state); -} - - -static inline ggi_visual_t -get_writeable_back_visual(gfx_driver_t *drv) -{ - if (STATE->frames > 1) { - ggiSetWriteFrame(VISUAL, 1); - return VISUAL; - } else - return STATE->back_vis; -} - -static inline ggi_visual_t -get_writeable_static_visual(gfx_driver_t *drv) -{ - if (STATE->frames > 2) { - ggiSetWriteFrame(VISUAL, 2); - return VISUAL; - } else - return STATE->static_vis; -} - -static inline ggi_pixel -ggi_map_color(gfx_driver_t *drv, ggi_visual_t vis, gfx_color_t color) -{ - if (MODE->palette) - return (ggi_pixel) color.visual.global_index; - else { - ggi_color gcolor; - gcolor.r = ((int) color.visual.r << 8) | color.visual.r; - gcolor.g = ((int) color.visual.g << 8) | color.visual.g; - gcolor.b = ((int) color.visual.b << 8) | color.visual.b; - gcolor.a = ((int) color.alpha << 8) | color.alpha; - - return ggiMapColor(vis, &gcolor); - } -} - -static int -ggi_draw_filled_rect(gfx_driver_t *drv, rect_t box, gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode); - -static int -ggi_draw_line(gfx_driver_t *drv, point_t start, point_t end, gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style) -{ - ggi_pixel pixel; - - int xw = MODE->xfact, yw = MODE->yfact; - int rx, ry, endx, endy; - int xc, yc; - - if (line_mode == GFX_LINE_MODE_FINE) - xw = yw = 1; - else { - xw = MODE->xfact, yw = MODE->yfact; - } - - rx = start.x; - ry = start.y; - endx = end.x; - endy = end.y; - - if ((rx == endx) && (ry == endy)) - return ggi_draw_filled_rect(drv, gfx_rect(rx, ry, xw, yw), color, color, GFX_SHADE_FLAT); - - if (color.mask & GFX_MASK_PRIORITY) { - ggi_visual_t privis = STATE->priority_visuals[GFX_BUFFER_BACK]; - - ggiSetGCForeground(privis, color.priority); - - for (xc = 0; xc < xw; xc++) - ggiDrawLine(privis, rx + xc, ry, endx + xc, endy); - if (yw > 0) - for (xc = 0; xc < xw; xc++) - ggiDrawLine(privis, rx + xc, ry + yw - 1, endx + xc, endy + yw - 1); - - if (yw > 1) { - for (yc = 1; yc < yw-1; yc++) - ggiDrawLine(privis, rx, ry + yc, endx, endy + yc); - - if (xw > 0) - for (yc = 1; yc < yw-1; yc++) - ggiDrawLine(privis, rx + xw - 1, ry + yc, endx + xw - 1, endy + yc); - } - } - - if (color.mask & GFX_MASK_VISUAL) { - ggi_visual_t vis; - - pixel = ggi_map_color(drv, VISUAL, color); - - vis = get_writeable_back_visual(drv); - - ggiSetGCForeground(vis, pixel); - - for (xc = 0; xc < xw; xc++) - ggiDrawLine(vis, rx + xc, ry, endx + xc, endy); - if (yw > 0) - for (xc = 0; xc < xw; xc++) - ggiDrawLine(vis, rx + xc, ry + yw - 1, endx + xc, endy + yw - 1); - - if (yw > 1) { - for (yc = 1; yc < yw-1; yc++) - ggiDrawLine(vis, rx, ry + yc, endx, endy + yc); - - if (xw > 0) - for (yc = 1; yc < yw-1; yc++) - ggiDrawLine(vis, rx + xw - 1, ry + yc, endx + xw - 1, endy + yc); - } - } - - return GFX_OK; -} - -static int -ggi_draw_filled_rect(gfx_driver_t *drv, rect_t box, gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode) -{ - if (color1.mask & GFX_MASK_VISUAL) { - ggi_pixel pixel = ggi_map_color(drv, VISUAL, color1); - ggi_visual_t vis = get_writeable_back_visual(drv); - - ggiSetGCForeground(vis, pixel); - ggiDrawBox(vis, box.x, box.y, box.xl, box.yl); - } - - if (color1.mask & GFX_MASK_PRIORITY) { - ggi_visual_t vis; - - ggiSetGCForeground(vis = STATE->priority_visuals[GFX_BUFFER_BACK], color1.priority); - ggiDrawBox(vis, box.x, box.y, box.xl, box.yl); - } - - return GFX_OK; -} - -/**************/ -/* Pixmap ops */ -/**************/ - -int -ggi_draw_pixmap(gfx_driver_t *drv, gfx_pixmap_t *pxm, int priority, - rect_t src, rect_t dest, gfx_buffer_t buffer) -{ - ggi_visual_t vis = VISUAL; - const ggi_directbuffer *dbuf; - byte *pri_map = NULL; - - if (dest.xl != src.xl || dest.yl != src.yl) { - GFXERROR("Attempt to scale pixmap (%dx%d)->(%dx%d): Not supported\n", - src.xl, src.yl, dest.xl, dest.yl); - return GFX_ERROR; - } - - switch (buffer) { - - case GFX_BUFFER_FRONT: - GFXERROR("Attempt to draw pixmap to front buffer\n"); - return GFX_ERROR; - - case GFX_BUFFER_BACK: - if (STATE->frames > 1) - ggiSetWriteFrame(VISUAL, 1); - else vis = STATE->back_vis; - pri_map = STATE->priority_maps[GGI_BUFFER_BACK]->index_data; - break; - - - case GFX_BUFFER_STATIC: - if (STATE->frames > 2) - ggiSetWriteFrame(VISUAL, 2); - else vis = STATE->static_vis; - pri_map = STATE->priority_maps[GGI_BUFFER_STATIC]->index_data; - break; - - - default: - GFXERROR("Unexpected buffer ID %d\n", buffer); - return GFX_ERROR; - - } - - assert(pri_map); - assert(vis); - - dbuf = ggiDBGetBuffer(vis, (vis == VISUAL)? buffer : 0); - if (!dbuf) { - GFXERROR("Could not acquire direct buffer!\n"); - return GFX_FATAL; - } - - if (dbuf->resource) { - if (ggiResourceAcquire(dbuf->resource, GGI_ACTYPE_WRITE)) { - GFXERROR("Failed to allocate resource for direct buffer!\n"); - return GFX_FATAL; - } - } - - if (dbuf->layout != blPixelLinearBuffer) { - char *type; - - switch (dbuf->layout) { - case blPixelPlanarBuffer: type = "planar"; - break; - - case blExtended: type = "extended"; - break; - - default: type = "invalid"; - - } - - GFXERROR("Error: Pixel buffer is %s! Non-linear buffers are not supported.\n", type); - - if (dbuf->resource) - ggiResourceRelease(dbuf->resource); - return GFX_FATAL; - } - - gfx_crossblit_pixmap(MODE, pxm, priority, src, dest, (byte *) dbuf->write, - dbuf->buffer.plb.stride, - pri_map, MODE->xfact * 320, 1, 0); - - /* ggiPutBox(vis, dest.x * MODE->xfact, dest.y * MODE->yfact, pxm->xl, pxm->yl, pxm->data); */ - - if (dbuf->resource) - ggiResourceRelease(dbuf->resource); - - return GFX_OK; -} - -int -ggi_grab_pixmap(gfx_driver_t *drv, rect_t src, gfx_pixmap_t *pxm, - gfx_map_mask_t map) -{ - ggi_visual_t vis = VISUAL; - int error; - - pxm->xl = src.xl; - pxm->yl = src.yl; - - if (STATE->frames > 1) - ggiSetReadFrame(VISUAL, 1); - else vis = STATE->back_vis; - - if (src.x < 0 || src.y < 0) { - GFXERROR("Attempt to grab pixmap from invalid coordinates (%d,%d)\n", src.x, src.y); - return GFX_ERROR; - } - - if (!pxm->data) { - GFXERROR("Attempt to grab pixmap to unallocated memory\n"); - return GFX_ERROR; - } - - if ((error = ggiGetBox(vis, src.x, src.y, src.xl, src.yl, pxm->data))) { - GFXERROR("ggiGetBox(%d, %d, %d, %d) returned error code %d\n", src.x, src.y, src.xl, src.yl, error); - return GFX_ERROR; - } - - return GFX_OK; -} - -/************/ -/* Misc ops */ -/************/ - - -static int -ggi_update(gfx_driver_t *drv, rect_t src, point_t dest, gfx_buffer_t buffer) -{ - int sx = src.x, sy = src.y; - int dx = dest.x, dy = dest.y; - int xl = src.xl, yl = src.yl; - - switch (buffer) { - case GFX_BUFFER_FRONT: - ggiSetWriteFrame(VISUAL, 0); - - if (STATE->frames < 2) - ggiCrossBlit(STATE->back_vis, sx, sy, xl, yl, VISUAL, dx + STATE->x_blank2, dy + STATE->y_blank2); - else { - ggiSetReadFrame(VISUAL, 1); - ggiCopyBox(VISUAL, sx, sy, xl, yl, dx + STATE->x_blank2, dy + STATE->y_blank2); - } - - break; - - case GFX_BUFFER_BACK: - if (src.x == dest.x && src.y == dest.y) - gfx_copy_pixmap_box_i(STATE->priority_maps[GGI_BUFFER_BACK], STATE->priority_maps[GGI_BUFFER_STATIC], src); - - if (STATE->frames > 1) - ggiSetWriteFrame(VISUAL, 1); - - if (STATE->frames > 2) { - ggiSetReadFrame(VISUAL, 2); - ggiCopyBox(VISUAL, sx, sy, xl, yl, dx, dy); - return GFX_OK; - } - - ggiCrossBlit(STATE->static_vis, sx, sy, xl, yl, STATE->back_vis, dx, dy); - - break; - - default: - GFXERROR("Invalid buffer %d in update!\n", buffer); - return GFX_ERROR; - } - return GFX_OK; -} - - -static int -ggi_set_palette(gfx_driver_t *drv, int index, byte red, byte green, byte blue) -{ - ggi_color color; - color.r = (red << 8) | red; - color.g = (green << 8) | green; - color.b = (blue << 8) | blue; - - /* DEBUG_POINTER(stderr,"Setting index %d to %04x %04x %04x\n", index, color.r, color.g, color.b); */ - - if (ggiSetPalette(VISUAL, index, 1, &color) < 0) - return GFX_ERROR; - else - return GFX_OK; -} - - -static int -ggi_set_static_buffer(gfx_driver_t *drv, gfx_pixmap_t *pic, gfx_pixmap_t *priority) -{ - ggi_visual_t vis = get_writeable_static_visual(drv); - - /* First, check if the priority map is sane */ - if (priority->index_xl != STATE->priority_maps[GGI_BUFFER_STATIC]->index_xl - || priority->index_yl != STATE->priority_maps[GGI_BUFFER_STATIC]->index_yl) { - GFXERROR("Invalid priority map: (%dx%d) vs expected (%dx%d)\n", - priority->index_xl, priority->index_yl, - STATE->priority_maps[GGI_BUFFER_STATIC]->index_xl, - STATE->priority_maps[GGI_BUFFER_STATIC]->index_yl); - return GFX_ERROR; - } - - ggiPutBox(vis, 0, 0, pic->xl, pic->yl, pic->data); - - memcpy(STATE->priority_maps[GGI_BUFFER_STATIC]->index_data, priority->index_data, - priority->index_xl * priority->index_yl); - - return GFX_OK; -} - - -/********************/ -/* Input management */ -/********************/ - - -struct timeval _sci_ggi_redraw_loopt, _sci_ggi_loopt; -/* timer variables */ - -int _sci_ggi_double_visual; - -static int buckybits; - -#define SCI_TIMEVAL_ADD(timev, addusec) \ - { timev.tv_usec += addusec; \ - while (timev.tv_usec >= 1000000L) { \ - timev.tv_usec -= 1000000L; \ - timev.tv_sec++; \ - }} - -#define SCI_TIMEVAL_LATER(later, earlier) \ - ((later.tv_sec == earlier.tv_sec)? (later.tv_usec >= earlier.tv_usec) \ - : (later.tv_sec >= earlier.tv_sec)) - - -static sci_event_t -ggi_get_event(gfx_driver_t *drv) -{ - struct timeval temptime = {0,0}; - gfx_ggi_struct_t *meta = (gfx_ggi_struct_t *) drv->state; - int modifiers; - - while (1) { - - if (ggiEventPoll(VISUAL, emAll, &temptime)) { - ggi_event event; - sci_event_t retval; - - ggiEventRead(VISUAL, &event, emAll); - - if (flags & SCI_GGI_SWAP_CTRL_CAPS - && ((event.any.type == evKeyPress) - || (event.any.type == evKeyRepeat) - || (event.any.type == evKeyRelease))) { - - switch (event.key.label) { - case GIIK_CtrlL: event.key.label = GIIK_CapsLock; break; - case GIIK_CapsLock: event.key.label = GIIK_CtrlL; break; - } - } - - switch (event.any.type) { - case evKeyPress: - case evKeyRepeat: - retval.type = SCI_EVT_KEYBOARD; - retval.data=-1; - retval.buckybits = 0; - switch(event.key.label) - { - case GIIK_P4: - case GIIK_Left: retval.data=SCI_K_LEFT; retval.buckybits = SCI_EVM_NUMLOCK; break; - case GIIK_P6: - case GIIK_Right: retval.data=SCI_K_RIGHT; retval.buckybits = SCI_EVM_NUMLOCK;break; - case GIIK_P8: - case GIIK_Up: retval.data=SCI_K_UP; retval.buckybits = SCI_EVM_NUMLOCK;break; - case GIIK_P2: - case GIIK_Down: retval.data=SCI_K_DOWN; retval.buckybits = SCI_EVM_NUMLOCK;break; - case GIIK_P7: - case GIIK_Home: retval.data=SCI_K_HOME; retval.buckybits = SCI_EVM_NUMLOCK;break; - case GIIK_P1: - case GIIK_End: retval.data=SCI_K_END; retval.buckybits = SCI_EVM_NUMLOCK;break; - case GIIK_P9: - case GIIK_PageUp: retval.data=SCI_K_PGUP; retval.buckybits = SCI_EVM_NUMLOCK;break; - case GIIK_P3: - case GIIK_PageDown: retval.data=SCI_K_PGDOWN; retval.buckybits = SCI_EVM_NUMLOCK;break; - case GIIK_P5: retval.data=SCI_K_CENTER; retval.buckybits = SCI_EVM_NUMLOCK;break; - - case GIIUC_Minus: - case GIIK_PMinus: retval.data = '-'; break; - case GIIUC_Plus: - case GIIK_PPlus: retval.data = '+'; break; - - case GIIUC_Grave: retval.data = '`'; break; -#if 0 - case GIIK_ShiftL: buckybits |= SCI_EVM_LSHIFT; break; - case GIIK_ShiftR: buckybits |= SCI_EVM_RSHIFT; break; - case GIIK_CtrlR: - case GIIK_CtrlL: buckybits |= SCI_EVM_CTRL; break; - case GIIK_AltL: - case GIIK_AltR: - case GIIK_MetaL: - case GIIK_MetaR: buckybits |= SCI_EVM_ALT; break; - case GIIK_CapsLock: buckybits ^= SCI_EVM_CAPSLOCK; break; - case GIIK_NumLock: buckybits ^= SCI_EVM_NUMLOCK; break; - case GIIK_ScrollLock: buckybits ^= SCI_EVM_SCRLOCK; break; -#endif - case GIIK_Insert: buckybits ^= SCI_EVM_INSERT; break; - case GIIK_PEnter: - case GIIK_Enter: retval.data='\r'; break; - case GIIUC_Tab: retval.data='\t'; break; - case GIIUC_Space: retval.data=' '; break; - case GIIUC_BackSpace: retval.data=SCI_K_BACKSPACE; break; - case GIIK_F1: retval.data = SCI_K_F1; break; - case GIIK_F2: retval.data = SCI_K_F2; break; - case GIIK_F3: retval.data = SCI_K_F3; break; - case GIIK_F4: retval.data = SCI_K_F4; break; - case GIIK_F5: retval.data = SCI_K_F5; break; - case GIIK_F6: retval.data = SCI_K_F6; break; - case GIIK_F7: retval.data = SCI_K_F7; break; - case GIIK_F8: retval.data = SCI_K_F8; break; - case GIIK_F9: retval.data = SCI_K_F9; break; - case GIIK_F10: retval.data = SCI_K_F10; break; - case GIIUC_Escape: retval.data = SCI_K_ESC; break; - - /*FIXME: Add all special keys in a sane way*/ - default: - { - if(event.key.label>='a' && event.key.label<='z') - retval.data=event.key.label-'a'+97; - if(event.key.label>='A' && event.key.label<='Z') - retval.data=event.key.label-'A'+97; - if(event.key.label>='0' && event.key.label<='9') - retval.data=event.key.label-'0'+48; - } - } - - modifiers = event.key.modifiers; - - buckybits = (buckybits & SCI_EVM_INSERT) | - (((modifiers & GII_MOD_CAPS)? SCI_EVM_LSHIFT | SCI_EVM_RSHIFT : 0) - | ((modifiers & GII_MOD_CTRL)? SCI_EVM_CTRL : 0) - | ((modifiers & (GII_MOD_ALT | GII_MOD_META))? SCI_EVM_ALT : 0) - | ((modifiers & GII_MOD_NUM)? SCI_EVM_NUMLOCK : 0) - | ((modifiers & GII_MOD_SCROLL)? SCI_EVM_SCRLOCK : 0)) - ^ ((modifiers & GII_MOD_SHIFT)? SCI_EVM_LSHIFT | SCI_EVM_RSHIFT : 0); - - if(retval.data==-1) continue; - retval.buckybits |= buckybits; - - return retval; - - case evKeyRelease: -#if 0 - switch(event.key.label) - { - case GIIK_ShiftL: buckybits &= ~SCI_EVM_LSHIFT; break; - case GIIK_ShiftR: buckybits &= ~SCI_EVM_RSHIFT; break; - case GIIK_CtrlR: - case GIIK_CtrlL: buckybits &= ~SCI_EVM_CTRL; break; - case GIIK_AltL: - case GIIK_AltR: - case GIIK_MetaL: - case GIIK_MetaR: buckybits &= ~SCI_EVM_ALT; break; - } -#endif - continue; - - case evPtrButtonPress: - retval.type = SCI_EVT_MOUSE_PRESS; - retval.data = event.pbutton.button; - retval.buckybits=buckybits; - - if (event.pbutton.button == GII_PBUTTON_LEFT) - retval.buckybits |= SCI_EVM_CTRL; - - if (event.pbutton.button == GII_PBUTTON_RIGHT) - retval.buckybits |= SCI_EVM_LSHIFT | SCI_EVM_RSHIFT; - return retval; - - case evPtrButtonRelease: - retval.type = SCI_EVT_MOUSE_RELEASE; - retval.data = event.pbutton.button; - retval.buckybits=buckybits; - - if (event.pbutton.button == GII_PBUTTON_LEFT) - retval.buckybits |= SCI_EVM_CTRL; - - if (event.pbutton.button == GII_PBUTTON_RIGHT) - retval.buckybits |= SCI_EVM_LSHIFT | SCI_EVM_RSHIFT; - - return retval; - - case evPtrAbsolute: - drv->pointer_x = event.pmove.x - STATE->x_blank2; - drv->pointer_y = event.pmove.y - STATE->y_blank2; - continue; - - case evPtrRelative: - drv->pointer_x += event.pmove.x; - drv->pointer_y += event.pmove.y; - /* FIXME: This may make the pointer too fast on high res! */ - continue; - } - } else { - sci_event_t retval; - - retval.type = SCI_EVT_NONE; /* Nothing happened */ - return retval; - } - - } -} - -static void -init_input_ggi() -{ - _sci_ggi_loopt = _sci_ggi_redraw_loopt; - buckybits = SCI_EVM_INSERT; /* Start up in "insert" mode */ - /* reset timers, leave them at current time to send redraw events ASAP */ - -} - - -int -ggi_usleep(gfx_driver_t* drv, long usec) -{ - struct timeval tv = {0, usec}; - - while(tv.tv_usec>0) - { - if(ggiEventPoll(VISUAL, emPtrMove, &tv)) - { - ggi_event e; - ggiEventRead(VISUAL, &e, emPtrMove); - switch(e.any.type) - { - case evPtrRelative: - { - drv->pointer_x+=e.pmove.x; - drv->pointer_y+=e.pmove.y; - } return GFX_OK; - case evPtrAbsolute: - { - drv->pointer_x=e.pmove.x - STATE->x_blank2; - drv->pointer_y=e.pmove.y - STATE->y_blank2; - } return GFX_OK; - } - } - } - return GFX_OK; -} - - - - -gfx_driver_t gfx_driver_ggi = { - "ggi", - GGI_DRIVER_VERSION, - SCI_GFX_DRIVER_MAGIC, - SCI_GFX_DRIVER_VERSION, - NULL, - 0,0, - GFX_CAPABILITY_FINE_LINES, GFX_DEBUG_POINTER - | GFX_DEBUG_UPDATES | GFX_DEBUG_PIXMAPS | GFX_DEBUG_BASIC, - ggi_set_param, - ggi_init_specific, - ggi_init, - ggi_exit, - ggi_draw_line, - ggi_draw_filled_rect, - NULL, - NULL, - ggi_draw_pixmap, - ggi_grab_pixmap, - ggi_update, - ggi_set_static_buffer, - NULL, - ggi_set_palette, - ggi_get_event, - ggi_usleep -}; - - -#endif /* HAVE_LIBGGI */ diff --git a/engines/sci/gfx/drivers/null_driver.c b/engines/sci/gfx/drivers/null_driver.c deleted file mode 100644 index e6821f56ef..0000000000 --- a/engines/sci/gfx/drivers/null_driver.c +++ /dev/null @@ -1,211 +0,0 @@ -/*************************************************************************** - null_driver.c Copyright (C) 2000 Christoph Reichenbach - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Christoph Reichenbach (CR) <jameson@linuxgames.com> - -***************************************************************************/ - -#include <gfx_driver.h> -#include <gfx_tools.h> - -static int debug_sleep = 0; -static int debug_draw = 0; - -static int -null_set_parameter(struct _gfx_driver *drv, char *attribute, char *value) -{ - printf("[GFX-NULL] Setting '%s' <- '%s'\n", attribute, value); - - return GFX_OK; -} - - - -static int -null_init_specific(struct _gfx_driver *drv, int xfact, int yfact, int bytespp) -{ - printf("[GFX-NULL] Initializing specific: %dx%d, %d bytespp\n", - xfact, yfact, bytespp); - - drv->mode = gfx_new_mode(xfact, yfact, bytespp, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0); - - return GFX_OK; -} - - -static int -null_init(struct _gfx_driver *drv) -{ - printf("[GFX-NULL] Initializing default\n"); - return null_init_specific(drv, 1, 1, 1); -} - -static void -null_exit(struct _gfx_driver *drv) -{ - printf("[GFX-NULL] Exitting\n"); -} - - - /*** Drawing operations ***/ - -static int -null_draw_line(struct _gfx_driver *drv, point_t start, point_t end, - gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style) -{ - if (debug_draw) - printf("[GFX-NULL] Line (%d,%d) -- (%d,%d)\n", - GFX_PRINT_POINT(start), - GFX_PRINT_POINT(end)); - return GFX_OK; -} - -static int -null_draw_filled_rect(struct _gfx_driver *drv, rect_t rect, - gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode) -{ - if (debug_draw) - printf("[GFX-NULL] Box (%d,%d)d(%d,%d)\n", - GFX_PRINT_RECT(rect)); - return GFX_OK; -} - - - /*** Pixmap operations ***/ - -static int -null_register_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm) -{ - return GFX_OK; -} - -static int -null_unregister_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm) -{ - return GFX_OK; -} - -static int -null_draw_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm, int priority, - rect_t src, rect_t dest, gfx_buffer_t buffer) -{ - return GFX_OK; -} - -static int -null_grab_pixmap(struct _gfx_driver *drv, rect_t src, gfx_pixmap_t *pxm, - gfx_map_mask_t map) -{ - return GFX_OK; - pxm->xl = src.xl; - pxm->yl = src.yl; -} - - - /*** Buffer operations ***/ - -static int -null_update(struct _gfx_driver *drv, rect_t src, point_t dest, gfx_buffer_t buffer) -{ - return GFX_OK; -} - -static int -null_set_static_buffer(struct _gfx_driver *drv, gfx_pixmap_t *pic, gfx_pixmap_t *priority) -{ - return GFX_OK; -} - - - /*** Mouse pointer operations ***/ - - -static int -null_set_pointer(struct _gfx_driver *drv, gfx_pixmap_t *pointer) -{ - return GFX_OK; -} - - - /*** Palette operations ***/ - -static int -null_set_palette(struct _gfx_driver *drv, int index, byte red, byte green, byte blue) -{ - return GFX_OK; -} - - - /*** Event management ***/ - -static sci_event_t -null_get_event(struct _gfx_driver *drv) -{ - sci_event_t input; - - input.type = SCI_EVT_NONE; - - return input; -} - - -static int -null_usec_sleep(struct _gfx_driver *drv, long usecs) -{ - if (debug_sleep) - sciprintf("[GFX-NULL] Sleeping %ld usecs...\n", usecs); - return GFX_OK; -} - -gfx_driver_t -gfx_driver_null = { - "null", - "0.1", - SCI_GFX_DRIVER_MAGIC, - SCI_GFX_DRIVER_VERSION, - NULL, - 0, 0, - GFX_CAPABILITY_WINDOWED, - GFX_DEBUG_POINTER | GFX_DEBUG_UPDATES | GFX_DEBUG_PIXMAPS | GFX_DEBUG_BASIC, - null_set_parameter, - null_init_specific, - null_init, - null_exit, - null_draw_line, - null_draw_filled_rect, - null_register_pixmap, - null_unregister_pixmap, - null_draw_pixmap, - null_grab_pixmap, - null_update, - null_set_static_buffer, - null_set_pointer, - null_set_palette, - null_get_event, - null_usec_sleep, - NULL -}; diff --git a/engines/sci/gfx/drivers/sdl_driver.c b/engines/sci/gfx/drivers/sdl_driver.c deleted file mode 100644 index e52cea9db5..0000000000 --- a/engines/sci/gfx/drivers/sdl_driver.c +++ /dev/null @@ -1,1235 +0,0 @@ -/*************************************************************************** - sdl_driver.c Copyright (C) 2001 Solomon Peachy - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - Solomon Peachy <pizza@shaftnet.org> - -***************************************************************************/ - -/* set optimisations for Win32: */ -/* g on: enable global optimizations */ -/* t on: use fast code */ -/* y on: suppress creation of frame pointers on stack */ -/* s off: disable minimize size code */ -#ifdef _WIN32 -# include <memory.h> -# ifndef SATISFY_PURIFY -# pragma optimize( "s", off ) -# pragma optimize( "gty", on ) -# pragma intrinsic( memcpy, memset ) -# endif -#endif - -#include <sci_memory.h> - -#include <gfx_driver.h> -#ifdef HAVE_SDL -#include <gfx_tools.h> - -#if !defined(_MSC_VER) -# include <sys/time.h> -#endif - -#include <SDL_config.h> -#undef HAVE_ICONV -#undef HAVE_ICONV_H -#undef HAVE_ALLOCA_H - -#include <SDL.h> - -#ifndef SDL_DISABLE -# define SDL_DISABLE 0 -#endif -#ifndef SDL_ALPHA_OPAQUE -# define SDL_ALPHA_OPAQUE 255 -#endif - -#define SCI_SDL_HANDLE_NORMAL 0 -#define SCI_SDL_HANDLE_GRABBED 1 - -#define SCI_SDL_SWAP_CTRL_CAPS (1 << 0) -#define SCI_SDL_FULLSCREEN (1 << 2) - -static int -sdl_usec_sleep(struct _gfx_driver *drv, long usecs); - -static int flags = 0; - -struct _sdl_state { - int used_bytespp; - gfx_pixmap_t *priority[2]; - SDL_Color colors[256]; - SDL_Surface *visual[3]; - SDL_Surface *primary; - int buckystate; - byte *pointer_data[2]; - int alpha_mask; - int SDL_alpha_shift; - int SDL_alpha_loss; -}; - -#define S ((struct _sdl_state *)(drv->state)) - -#define XFACT drv->mode->xfact -#define YFACT drv->mode->yfact - -#define DEBUGB if (drv->debug_flags & GFX_DEBUG_BASIC && ((debugline = __LINE__))) sdlprintf -#define DEBUGU if (drv->debug_flags & GFX_DEBUG_UPDATES && ((debugline = __LINE__))) sdlprintf -#define DEBUGPXM if (drv->debug_flags & GFX_DEBUG_PIXMAPS && ((debugline = __LINE__))) sdlprintf -#define DEBUGPTR if (drv->debug_flags & GFX_DEBUG_POINTER && ((debugline = __LINE__))) sdlprintf -#define SDLERROR if ((debugline = __LINE__)) sdlprintf -#define SDLPRINTF if ((debugline = __LINE__)) sdlprintf - -#define ALPHASURFACE (S->used_bytespp == 4) - -static int debugline = 0; - -static void -sdlprintf(const char *fmt, ...) -{ - va_list argp; - fprintf(stderr,"GFX-SDL %d:", debugline); - va_start(argp, fmt); - vfprintf(stderr, fmt, argp); - va_end(argp); -} - -static int -sdl_init_libsdl(struct _gfx_driver *drv) -{ - if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE)) { - DEBUGB("Failed to init SDL\n"); - return -1; - } - - SDL_EnableUNICODE(SDL_ENABLE); - - return 0; -} - -static int -sdl_alloc_primary(struct _gfx_driver *drv, int xfact, int yfact, int bytespp) -{ - int i = SDL_HWSURFACE | SDL_HWPALETTE; - - if (flags & SCI_SDL_FULLSCREEN) { - i |= SDL_FULLSCREEN; - } - - S->primary = SDL_SetVideoMode(xfact * 320, yfact * 200, bytespp << 3, i); - - if (!S->primary) { - SDLERROR("Could not set up a primary SDL surface!\n"); - return -1; - } - - if (S->primary->format->BytesPerPixel != bytespp) { - SDLERROR("Could not set up a primary SDL surface of depth %d bpp!\n",bytespp); - S->primary = NULL; - return -1; - } - - /* Set windowed flag */ - if (S->primary->flags & SDL_FULLSCREEN) - drv->capabilities &= ~GFX_CAPABILITY_WINDOWED; - else - drv->capabilities |= GFX_CAPABILITY_WINDOWED; - - return 0; -} - -static int -sdl_blit_surface(gfx_driver_t *drv, - SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect) -{ - if (S->used_bytespp == 1) { - SDL_SetColors(src, S->colors, 0, 256); - SDL_SetColors(dst, S->colors, 0, 256); - } - return SDL_BlitSurface(src, srcrect, dst, dstrect); -} - -static int -sdl_set_parameter(struct _gfx_driver *drv, char *attribute, char *value) -{ - if (!strncmp(attribute, "swap_ctrl_caps", 14) || - !strncmp(attribute, "swap_caps_ctrl", 14)) { - if (string_truep(value)) - flags |= SCI_SDL_SWAP_CTRL_CAPS; - else - flags &= ~SCI_SDL_SWAP_CTRL_CAPS; - return GFX_OK; - } - - if (!strncmp(attribute, "fullscreen", 10)) { - if (string_truep(value)) - flags |= SCI_SDL_FULLSCREEN; - else - flags &= ~SCI_SDL_FULLSCREEN; - - return GFX_OK; - } - - - SDLERROR("Attempt to set sdl parameter \"%s\" to \"%s\"\n", attribute, value); - return GFX_ERROR; -} - -static int -sdl_init_specific(struct _gfx_driver *drv, int xfact, int yfact, int bytespp) -{ - int red_shift, green_shift, blue_shift, alpha_shift; - int xsize = xfact * 320; - int ysize = yfact * 200; - - int i; - -#ifdef _MSC_VER /* Win32 doesn't support mouse pointers greater than 64x64 */ - if (xfact > 2 || yfact > 2) - drv->capabilities &= ~GFX_CAPABILITY_MOUSE_POINTER; -#endif -#if defined(__BEOS__) || defined(__amigaos4__) /* BeOS has been reported not to work well with the mouse pointer at all */ - drv->capabilities &= ~GFX_CAPABILITY_MOUSE_POINTER; -#endif - - if (sdl_init_libsdl(drv)) - return GFX_FATAL; - - if (!drv->state /* = S */) - drv->state = sci_malloc(sizeof(struct _sdl_state)); - if (!drv->state) - return GFX_FATAL; - - if (xfact < 1 || yfact < 1 || bytespp < 1 || bytespp > 4) { - SDLERROR("Internal error: Attempt to open window w/ scale factors (%d,%d) and bpp=%d!\n", - xfact, yfact, bytespp); - } - - if (sdl_alloc_primary(drv, xfact, yfact, bytespp)) - return GFX_FATAL; - - S->used_bytespp = bytespp; - - printf("Using primary SDL surface of %d,%d @%d bpp\n", - xsize, ysize, bytespp << 3); - - /* if (S->primary->format->BytesPerPixel == 4) { - S->alpha_mask = 0xff000000; - S->SDL_alpha_shift = 24; - S->SDL_alpha_loss = 0; - alpha_shift = 0; - } else { */ - S->alpha_mask = S->primary->format->Amask; - S->SDL_alpha_shift = S->primary->format->Ashift; - S->SDL_alpha_loss = S->primary->format->Aloss; - alpha_shift = bytespp << 3; - /* }*/ - - /* clear palette */ - for (i = 0; i < 256; i++) { - S->colors[i].r = (i & 1)? 0 : 0; - S->colors[i].g = (i & 2)? 0 : 0; - S->colors[i].b = (i & 4)? 0 : 0; - } - if (bytespp == 1) - SDL_SetColors(S->primary, S->colors, 0, 256); - - /* create an input event mask */ - SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE); - SDL_EventState(SDL_VIDEORESIZE, SDL_IGNORE); - SDL_EventState(SDL_KEYUP, SDL_IGNORE); - - SDL_WM_SetCaption("FreeSCI", "freesci"); - - SDL_ShowCursor(SDL_DISABLE); - S->pointer_data[0] = NULL; - S->pointer_data[1] = NULL; - - S->buckystate = 0; - - if (bytespp == 1) { - red_shift = green_shift = blue_shift = alpha_shift = 0; - } else { - red_shift = 24 - S->primary->format->Rshift + S->primary->format->Rloss; - green_shift = 24 - S->primary->format->Gshift + S->primary->format->Gloss; - blue_shift = 24 - S->primary->format->Bshift + S->primary->format->Bloss; - } - - printf("%08x %08x %08x %08x %d/%d=%d %d/%d=%d %d/%d=%d %d/%d=%d\n", - S->primary->format->Rmask, - S->primary->format->Gmask, - S->primary->format->Bmask, - S->alpha_mask, - /* S->primary->format->Amask,*/ - S->primary->format->Rshift, - S->primary->format->Rloss, - red_shift, - S->primary->format->Gshift, - S->primary->format->Gloss, - green_shift, - S->primary->format->Bshift, - S->primary->format->Bloss, - blue_shift, - S->SDL_alpha_shift, - S->SDL_alpha_loss, - /* - S->primary->format->Ashift, - S->primary->format->Aloss, */ - alpha_shift); - - for (i = 0; i < 2; i++) { - S->priority[i] = gfx_pixmap_alloc_index_data(gfx_new_pixmap(xsize, ysize, GFX_RESID_NONE, -i, -777)); - if (!S->priority[i]) { - SDLERROR("Out of memory: Could not allocate priority maps! (%dx%d)\n", - xsize, ysize); - return GFX_FATAL; - } - } - - /* create the visual buffers */ - for (i = 0; i < 3; i++) { - S->visual[i] = SDL_CreateRGBSurface(SDL_SRCALPHA, - /* SDL_HWSURFACE | SDL_SWSURFACE, */ - xsize, ysize, - bytespp << 3, - S->primary->format->Rmask, - S->primary->format->Gmask, - S->primary->format->Bmask, - S->alpha_mask); - if (S->visual[i] == NULL) { - SDLERROR("Could not set up visual buffers!\n"); - return GFX_FATAL; - } - - if (ALPHASURFACE) - SDL_SetAlpha(S->visual[i],SDL_SRCALPHA,SDL_ALPHA_OPAQUE); - - if (SDL_FillRect(S->primary, NULL, SDL_MapRGB(S->primary->format, 0,0,0))) - SDLERROR("Couldn't fill backbuffer!\n"); - } - - SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - - drv->mode = gfx_new_mode(xfact, yfact, bytespp, - S->primary->format->Rmask, - S->primary->format->Gmask, - S->primary->format->Bmask, - S->alpha_mask, - red_shift, green_shift, blue_shift, alpha_shift, - (bytespp == 1)? 256 : 0, 0); /*GFX_MODE_FLAG_REVERSE_ALPHA);*/ - - return GFX_OK; -} - -static int -sdl_init(struct _gfx_driver *drv) -{ - int depth = 0; - int i; - - if (sdl_init_libsdl(drv)) - return GFX_FATAL; - - i = SDL_HWSURFACE | SDL_HWPALETTE; - if (flags & SCI_SDL_FULLSCREEN) { - i |= SDL_FULLSCREEN; - } - - depth = SDL_VideoModeOK(640,400, 32, i); - if (depth && (! sdl_init_specific(drv, 2, 2, depth >> 3 ))) - return GFX_OK; - - DEBUGB("Failed to find visual!\n"); - return GFX_FATAL; -} - -static void -sdl_exit(struct _gfx_driver *drv) -{ - int i; - if (S) { - for (i = 0; i < 2; i++) { - gfx_free_pixmap(drv, S->priority[i]); - S->priority[i] = NULL; - } - - for (i = 0; i < 3; i++) { - SDL_FreeSurface(S->visual[i]); - S->visual[i] = NULL; - } - - SDL_FreeCursor(SDL_GetCursor()); - - for (i = 0; i < 2; i++) - if (S->pointer_data[i]) { - free(S->pointer_data[i]); - S->pointer_data[i] = NULL; - } - - } - - SDL_QuitSubSystem(SDL_INIT_VIDEO); - - if (!SDL_WasInit(SDL_INIT_EVERYTHING)) { - SDLPRINTF("No active SDL subsystems found.. shutting down SDL\n"); - SDL_Quit(); - } -} - -static void -toggle_fullscreen(struct _gfx_driver *drv) -{ - rect_t src; - point_t dest; - - flags ^= SCI_SDL_FULLSCREEN; - if (sdl_alloc_primary(drv, XFACT, YFACT, drv->mode->bytespp)) { - SDLERROR("failed to switch to full-screen mode\n"); - /* Failed to set mode, revert to previous */ - flags ^= SCI_SDL_FULLSCREEN; - - if (sdl_alloc_primary(drv, XFACT, YFACT, drv->mode->bytespp)) { - /* This shouldn't happen... */ - SDLERROR("failed to revert to previous display mode\n"); - exit(-1); - } - } - - src.x = 0; - src.y = 0; - src.xl = XFACT * 320; - src.yl = YFACT * 200; - dest.x = 0; - dest.y = 0; - - drv->update(drv, src, dest, GFX_BUFFER_FRONT); -} - -/*** Drawing operations ***/ - -static Uint32 -sdl_map_color(gfx_driver_t *drv, gfx_color_t color) -{ - int opacity = 255 - color.alpha; - - if (drv->mode->palette && opacity < 255) { - if (opacity < 127) - opacity = 0; - else - opacity = 255; - - } - - if (drv->mode->palette) - return color.visual.global_index; - - return SDL_MapRGBA(S->visual[0]->format, - color.visual.r, - color.visual.g, - color.visual.b, - opacity); -} - -/* This code shamelessly lifted from the SDL_gfxPrimitives package */ -static void lineColor2(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color) -{ - int pixx, pixy; - int x,y; - int dx,dy; - int sx,sy; - int swaptmp; - Uint8 *pixel; - - dx = x2 - x1; - dy = y2 - y1; - sx = (dx >= 0) ? 1 : -1; - sy = (dy >= 0) ? 1 : -1; - - dx = sx * dx + 1; - dy = sy * dy + 1; - pixx = dst->format->BytesPerPixel; - pixy = dst->pitch; - pixel = ((Uint8*)dst->pixels) + pixx * (int)x1 + pixy * (int)y1; - pixx *= sx; - pixy *= sy; - if (dx < dy) { - swaptmp = dx; dx = dy; dy = swaptmp; - swaptmp = pixx; pixx = pixy; pixy = swaptmp; - } - -/* Draw */ - x=0; - y=0; - switch(dst->format->BytesPerPixel) { - case 1: - for(; x < dx; x++, pixel += pixx) { - *pixel = color; - y += dy; - if (y >= dx) { - y -= dx; pixel += pixy; - } - } - break; - case 2: - for (; x < dx; x++, pixel += pixx) { - *(Uint16*)pixel = color; - y += dy; - if (y >= dx) { - y -= dx; - pixel += pixy; - } - } - break; - case 3: - for(; x < dx; x++, pixel += pixx) { - if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { - pixel[0] = (color >> 16) & 0xff; - pixel[1] = (color >> 8) & 0xff; - pixel[2] = color & 0xff; - } else { - pixel[0] = color & 0xff; - pixel[1] = (color >> 8) & 0xff; - pixel[2] = (color >> 16) & 0xff; - } - y += dy; - if (y >= dx) { - y -= dx; - pixel += pixy; - } - } - break; - case 4: - for(; x < dx; x++, pixel += pixx) { - *(Uint32*)pixel = color; - y += dy; - if (y >= dx) { - y -= dx; - pixel += pixy; - } - } - break; - default: - fprintf(stderr, "invalid depth\n"); - } - -} - -static int -sdl_draw_line(struct _gfx_driver *drv, point_t start, point_t end, gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style) -{ - Uint32 scolor; - int xfact = (line_mode == GFX_LINE_MODE_FINE)? 1: XFACT; - int yfact = (line_mode == GFX_LINE_MODE_FINE)? 1: YFACT; - int xsize = S->visual[1]->w; - int ysize = S->visual[1]->h; - - if (color.mask & GFX_MASK_VISUAL) { - int xc, yc; - point_t nstart, nend; - - scolor = sdl_map_color(drv, color); - - for (xc = 0; xc < xfact; xc++) - for (yc = 0; yc < yfact; yc++) { - nstart.x = start.x + xc; - nstart.y = start.y + yc; - nend.x = end.x + xc; - nend.y = end.y + yc; - - if (nstart.x < 0) - nstart.x = 0; - if (nend.x < 0) - nstart.x = 0; - if (nstart.y < 0) - nstart.y = 0; - if (nend.y < 0) - nend.y = 0; - if (nstart.x > xsize) - nstart.x = xsize; - if (nend.x >= xsize) - nend.x = xsize -1; - if (nstart.y > ysize) - nstart.y = ysize; - if (nend.y >= ysize) - nend.y = ysize -1; - -#if 0 - fprintf(stderr, "draw %d %d to %d %d %08x %d %d\n", nstart.x, - nstart.y, nend.x, nend.yl, scolor, xsize, ysize); -#endif - - SDL_LockSurface(S->visual[1]); - lineColor2(S->visual[1], (Sint16)nstart.x, (Sint16)nstart.y, - (Sint16)nend.x, (Sint16)nend.y, scolor); - SDL_UnlockSurface(S->visual[1]); - - if (color.mask & GFX_MASK_PRIORITY) { - gfx_draw_line_pixmap_i(S->priority[0], nstart, nend, - color.priority); - } - } - } - - return GFX_OK; -} - -static int -sdl_draw_filled_rect(struct _gfx_driver *drv, rect_t rect, - gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode) -{ - Uint32 color; - SDL_Rect srect; - - if (color1.mask & GFX_MASK_VISUAL) { - color = sdl_map_color(drv, color1); - - srect.x = rect.x; - srect.y = rect.y; - srect.w = rect.xl; - srect.h = rect.yl; - - if (SDL_FillRect(S->visual[1], &srect, color)) - SDLERROR("Can't fill rect"); - } - - if (color1.mask & GFX_MASK_PRIORITY) - gfx_draw_box_pixmap_i(S->priority[0], rect, color1.priority); - - return GFX_OK; -} - -/*** Pixmap operations ***/ - -static int -sdl_register_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm) -{ - SDL_Surface *reg_surface; - - if (pxm->internal.info) { - SDLERROR("Attempt to register pixmap twice!\n"); - return GFX_ERROR; - } - - reg_surface = - SDL_CreateRGBSurfaceFrom(pxm->data, pxm->xl, pxm->yl, - S->used_bytespp << 3, - S->used_bytespp * pxm->xl, - S->primary->format->Rmask, - S->primary->format->Gmask, - S->primary->format->Bmask, - S->alpha_mask); - - if (ALPHASURFACE) - SDL_SetAlpha(reg_surface, SDL_SRCALPHA,SDL_ALPHA_OPAQUE); - - pxm->internal.handle = SCI_SDL_HANDLE_NORMAL; - - DEBUGPXM("Registered surface %d/%d/%d at %p (%dx%d)\n", pxm->ID, pxm->loop, pxm->cel, - pxm->internal.info, pxm->xl, pxm->yl); - - pxm->internal.info = reg_surface; - - return GFX_OK; -} - -static int -sdl_unregister_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm) -{ - DEBUGPXM("Freeing surface %d/%d/%d at %p\n", pxm->ID, pxm->loop, pxm->cel, - pxm->internal.info); - - if (!pxm->internal.info) { - SDLERROR("Attempt to unregister pixmap twice!\n"); - return GFX_ERROR; - } - - SDL_FreeSurface((SDL_Surface *) pxm->internal.info); - pxm->internal.info = NULL; - if (pxm->internal.handle != SCI_SDL_HANDLE_GRABBED) - free(pxm->data); - pxm->data = NULL; - return GFX_OK; -} - -static int -sdl_draw_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm, int priority, - rect_t src, rect_t dest, gfx_buffer_t buffer) -{ - int bufnr = (buffer == GFX_BUFFER_STATIC)? 2:1; - int pribufnr = bufnr -1; - - SDL_Surface *temp; - SDL_Rect srect; - SDL_Rect drect; - - if (dest.xl != src.xl || dest.yl != src.yl) { - SDLERROR("Attempt to scale pixmap (%dx%d)->(%dx%d): Not supported\n", - src.xl, src.yl, dest.xl, dest.yl); - return GFX_ERROR; - } - - srect.x = src.x; - srect.y = src.y; - srect.w = src.xl; - srect.h = src.yl; - drect.x = dest.x; - drect.y = dest.y; - drect.w = dest.xl; - drect.h = dest.yl; - - DEBUGU("Drawing %d (%d,%d)(%dx%d) onto (%d,%d)\n", pxm, srect.x, srect.y, - srect.w, srect.h, drect.x, drect.y); - - if (pxm->internal.handle == SCI_SDL_HANDLE_GRABBED) { - if (sdl_blit_surface(drv, (SDL_Surface *)pxm->internal.info, &srect , - S->visual[bufnr], &drect )) { - SDLERROR("blt failed"); - return GFX_ERROR; - } - return GFX_OK; - } - - temp = SDL_CreateRGBSurface(SDL_SWSURFACE, drect.w, drect.h, - S->used_bytespp << 3, - S->primary->format->Rmask, - S->primary->format->Gmask, - S->primary->format->Bmask, - S->alpha_mask); - - if (ALPHASURFACE) - SDL_SetAlpha(temp, SDL_SRCALPHA,SDL_ALPHA_OPAQUE); - - if (!temp) { - SDLERROR("Failed to allocate SDL surface"); - return GFX_ERROR; - } - - srect.x = dest.x; - srect.y = dest.y; - drect.x = 0; - drect.y = 0; - - if(sdl_blit_surface(drv, S->visual[bufnr], &srect, temp, &drect)) - SDLERROR("blt failed"); - - SDL_LockSurface(temp); - gfx_crossblit_pixmap(drv->mode, pxm, priority, src, dest, - (byte *) temp->pixels, temp->pitch, - S->priority[pribufnr]->index_data, - S->priority[pribufnr]->index_xl, 1, - GFX_CROSSBLIT_FLAG_DATA_IS_HOMED); - SDL_UnlockSurface(temp); - - srect.x = 0; - srect.y = 0; - drect.x = dest.x; - drect.y = dest.y; - - if(sdl_blit_surface(drv, temp, &srect, S->visual[bufnr], &drect)) - SDLERROR("blt failed"); - - SDL_FreeSurface(temp); - return GFX_OK; -} - -static int -sdl_grab_pixmap(struct _gfx_driver *drv, rect_t src, gfx_pixmap_t *pxm, - gfx_map_mask_t map) -{ - - - if (src.x < 0 || src.y < 0) { - SDLERROR("Attempt to grab pixmap from invalid coordinates (%d,%d)\n", src.x, src.y); - return GFX_ERROR; - } - - if (!pxm->data) { - SDLERROR("Attempt to grab pixmap to unallocated memory\n"); - return GFX_ERROR; - } - switch (map) { - - case GFX_MASK_VISUAL: { - SDL_Rect srect, drect; - SDL_Surface *temp; - - pxm->xl = src.xl; - pxm->yl = src.yl; - temp = SDL_CreateRGBSurface(SDL_SWSURFACE, src.xl, src.yl, - S->used_bytespp << 3, - S->primary->format->Rmask, - S->primary->format->Gmask, - S->primary->format->Bmask, - S->alpha_mask); - - if (!temp) { - SDLERROR("Failed to allocate SDL surface"); - return GFX_ERROR; - } - - if (SDL_MUSTLOCK(temp)) - sciprintf("Warning: SDL surface for pixmap grabbing requires locking\n"); - - if (ALPHASURFACE) - SDL_SetAlpha(temp, SDL_SRCALPHA,SDL_ALPHA_OPAQUE); - - srect.x = src.x; - srect.y = src.y; - srect.w = src.xl; - srect.h = src.yl; - drect.x = 0; - drect.y = 0; - drect.w = src.xl; - drect.h = src.yl; - - if (sdl_blit_surface(drv, S->visual[1], &srect, temp, &drect)) - SDLERROR("grab_pixmap: grab blit failed!\n"); - - pxm->internal.info = temp; - pxm->internal.handle = SCI_SDL_HANDLE_GRABBED; - pxm->flags |= GFX_PIXMAP_FLAG_INSTALLED | GFX_PIXMAP_FLAG_EXTERNAL_PALETTE | GFX_PIXMAP_FLAG_PALETTE_SET; - free(pxm->data); - pxm->data = (byte *) temp->pixels; - - DEBUGPXM("Grabbed surface %p (%dx%d)(%dx%d)\n", - pxm->internal.info, srect.x, srect.y, pxm->xl, pxm->yl); - - break; - } - - case GFX_MASK_PRIORITY: - SDLERROR("FIXME: priority map grab not implemented yet!\n"); - break; - - default: - SDLERROR("Attempt to grab pixmap from invalid map 0x%02x\n", map); - return GFX_ERROR; - } - - return GFX_OK; -} - - - /*** Buffer operations ***/ - -static int -sdl_update(struct _gfx_driver *drv, rect_t src, point_t dest, gfx_buffer_t buffer) -{ - int data_source = (buffer == GFX_BUFFER_BACK)? 2 : 1; - int data_dest = data_source - 1; - SDL_Rect srect, drect; - - if (src.x != dest.x || src.y != dest.y) { - DEBUGU("Updating %d (%d,%d)(%dx%d) to (%d,%d) on %d\n", buffer, src.x, src.y, - src.xl, src.yl, dest.x, dest.y, data_dest); - } else { - DEBUGU("Updating %d (%d,%d)(%dx%d) to %d\n", buffer, src.x, src.y, src.xl, src.yl, data_dest); - } - - srect.x = src.x; - srect.y = src.y; - srect.w = src.xl; - srect.h = src.yl; - drect.x = dest.x; - drect.y = dest.y; - drect.w = src.xl; - drect.h = src.yl; - - switch (buffer) { - case GFX_BUFFER_BACK: - if (sdl_blit_surface(drv, S->visual[data_source], &srect, - S->visual[data_dest], &drect)) - SDLERROR("surface update failed!\n"); - - if ((src.x == dest.x) && (src.y == dest.y)) - gfx_copy_pixmap_box_i(S->priority[0], S->priority[1], src); - break; - case GFX_BUFFER_FRONT: - if (sdl_blit_surface(drv, S->visual[data_source], &srect, S->primary, &drect)) - SDLERROR("primary surface update failed!\n"); - SDL_UpdateRect(S->primary, drect.x, drect.y, drect.w, drect.h); - break; - default: - GFXERROR("Invalid buffer %d in update!\n", buffer); - return GFX_ERROR; - } - - return GFX_OK; -} - -static int -sdl_set_static_buffer(struct _gfx_driver *drv, gfx_pixmap_t *pic, gfx_pixmap_t *priority) -{ - - if (!pic->internal.info) { - SDLERROR("Attempt to set static buffer with unregisterd pixmap!\n"); - return GFX_ERROR; - } - sdl_blit_surface(drv, (SDL_Surface *)pic->internal.info, NULL, - S->visual[2], NULL); - - gfx_copy_pixmap_box_i(S->priority[1], priority, gfx_rect(0, 0, 320*XFACT, 200*YFACT)); - - return GFX_OK; -} - - /*** Palette operations ***/ - -static int -sdl_set_palette(struct _gfx_driver *drv, int index, byte red, byte green, byte blue) -{ - if (index < 0 || index > 255) - { - SDLERROR("Attempt to set invalid palette entry %d\n", index); - return GFX_ERROR; - } - - S->colors[index].r = red; - S->colors[index].g = green; - S->colors[index].b = blue; - - SDL_SetColors(S->primary, S->colors + index, index, 1); - return GFX_OK; -} - - - /*** Mouse pointer operations ***/ - -byte * -sdl_create_cursor_rawdata(gfx_driver_t *drv, gfx_pixmap_t *pointer, int mode) -{ - int linewidth = (pointer->xl + 7) >> 3; - int lines = pointer->yl; - int xc, yc; - byte *data = (byte*)sci_calloc(linewidth, lines); - byte *linebase = data, *pos; - byte *src = pointer->index_data; - - for (yc = 0; yc < pointer->index_yl; yc++) { - int scalectr; - int bitc = 7; - pos = linebase; - - for (xc = 0; xc < pointer->index_xl; xc++) { - int draw = mode ? (*src == 0) : (*src < 255); - for (scalectr = 0; scalectr < XFACT; scalectr++) { - if (draw) - *pos |= (1 << bitc); - bitc--; - if (bitc < 0) { - bitc = 7; - pos++; - } - } - src++; - } - for (scalectr = 1; scalectr < YFACT; scalectr++) - memcpy(linebase + linewidth * scalectr, linebase, linewidth); - linebase += linewidth * YFACT; - } - return data; -} - - -static SDL_Cursor -*sdl_create_cursor_data(gfx_driver_t *drv, gfx_pixmap_t *pointer) -{ - byte *visual_data, *mask_data; - - S->pointer_data[0] = visual_data = sdl_create_cursor_rawdata(drv, pointer, 1); - S->pointer_data[1] = mask_data = sdl_create_cursor_rawdata(drv, pointer, 0); - - return SDL_CreateCursor(visual_data, mask_data, - pointer->xl, pointer->yl, - pointer->xoffset, pointer->yoffset); - -} - -static int sdl_set_pointer (struct _gfx_driver *drv, gfx_pixmap_t *pointer) -{ - int i; - - if (pointer == NULL) - SDL_ShowCursor(SDL_DISABLE); - else { - SDL_Cursor *cursor; - for (i = 0; i < 2; i++) - if (S->pointer_data[i]) { - free(S->pointer_data[i]); - S->pointer_data[i] = NULL; - } - - cursor = SDL_GetCursor(); - SDL_SetCursor(sdl_create_cursor_data(drv, pointer)); - SDL_FreeCursor(cursor); - SDL_ShowCursor(SDL_ENABLE); - } - - return 0; -} - -/*** Event management ***/ - -int -sdl_map_key(gfx_driver_t *drv, SDL_keysym keysym) -{ - SDLKey skey = keysym.sym; - int rkey = keysym.unicode & 0x7f; - - if ((skey >= SDLK_a) && (skey <= SDLK_z)) - return ('a' + (skey - SDLK_a)); - - if ((skey >= SDLK_0) && (skey <= SDLK_9)) - return ('0' + (skey - SDLK_0)); - - if (flags & SCI_SDL_SWAP_CTRL_CAPS) { - switch (skey) { - case SDLK_LCTRL: skey = SDLK_CAPSLOCK; break; - case SDLK_CAPSLOCK: skey = SDLK_LCTRL; break; - default: break; - } - } - - switch (skey) { - /* XXXX catch KMOD_NUM for KP0-9 */ - case SDLK_BACKSPACE: return SCI_K_BACKSPACE; - case SDLK_TAB: return 9; - case SDLK_ESCAPE: return SCI_K_ESC; - case SDLK_RETURN: - case SDLK_KP_ENTER: - if (SDL_GetModState() & KMOD_ALT) { - toggle_fullscreen(drv); - return 0; - } - return SCI_K_ENTER; - case SDLK_KP_PERIOD: return SCI_K_DELETE; - case SDLK_KP0: - case SDLK_INSERT: return SCI_K_INSERT; - case SDLK_KP1: - case SDLK_END: return SCI_K_END; - case SDLK_KP2: - case SDLK_DOWN: return SCI_K_DOWN; - case SDLK_KP3: - case SDLK_PAGEDOWN: return SCI_K_PGDOWN; - case SDLK_KP4: - case SDLK_LEFT: return SCI_K_LEFT; - case SDLK_KP5: return SCI_K_CENTER; - case SDLK_KP6: - case SDLK_RIGHT: return SCI_K_RIGHT; - case SDLK_KP7: - case SDLK_HOME: return SCI_K_HOME; - case SDLK_KP8: - case SDLK_UP: return SCI_K_UP; - case SDLK_KP9: - case SDLK_PAGEUP: return SCI_K_PGUP; - - case SDLK_F1: return SCI_K_F1; - case SDLK_F2: return SCI_K_F2; - case SDLK_F3: return SCI_K_F3; - case SDLK_F4: return SCI_K_F4; - case SDLK_F5: return SCI_K_F5; - case SDLK_F6: return SCI_K_F6; - case SDLK_F7: return SCI_K_F7; - case SDLK_F8: return SCI_K_F8; - case SDLK_F9: return SCI_K_F9; - case SDLK_F10: return SCI_K_F10; - - case SDLK_LCTRL: - case SDLK_RCTRL: - case SDLK_LALT: - case SDLK_RALT: - case SDLK_LMETA: - case SDLK_RMETA: - case SDLK_CAPSLOCK: - case SDLK_SCROLLOCK: - case SDLK_NUMLOCK: - case SDLK_LSHIFT: - case SDLK_RSHIFT: return 0; - - case SDLK_PLUS: - case SDLK_KP_PLUS: return '+'; - case SDLK_SLASH: - case SDLK_KP_DIVIDE: return '/'; - case SDLK_MINUS: - case SDLK_KP_MINUS: return '-'; - case SDLK_ASTERISK: - case SDLK_KP_MULTIPLY: return '*'; - case SDLK_EQUALS: - case SDLK_KP_EQUALS: return '='; - - case SDLK_COMMA: - case SDLK_PERIOD: - case SDLK_BACKSLASH: - case SDLK_SEMICOLON: - case SDLK_QUOTE: - case SDLK_LEFTBRACKET: - case SDLK_RIGHTBRACKET: - case SDLK_LESS: - case SDLK_DOLLAR: - case SDLK_GREATER: return rkey; - case SDLK_SPACE: return ' '; - -#ifdef MACOSX - case SDLK_WORLD_0: -#endif - case SDLK_BACKQUOTE: - if (keysym.mod & KMOD_CTRL) - return '`'; - else - return rkey; - - default: - break; - } - - sciprintf("Unknown SDL keysym: %04x (%d) \n", skey, rkey); - return 0; -} - - -void -sdl_fetch_event(gfx_driver_t *drv, sci_event_t *sci_event) -{ - SDL_Event event; - - while (SDL_PollEvent(&event)) { - - switch (event.type) { - case SDL_KEYDOWN: { - int modifiers = event.key.keysym.mod; - sci_event->type = SCI_EVT_KEYBOARD; - - S->buckystate = (((modifiers & KMOD_CAPS)? SCI_EVM_LSHIFT | SCI_EVM_RSHIFT : 0) - | ((modifiers & KMOD_CTRL)? SCI_EVM_CTRL : 0) - | ((modifiers & KMOD_ALT)? SCI_EVM_ALT : 0) - | ((modifiers & KMOD_NUM) ? SCI_EVM_NUMLOCK : 0) - | ((modifiers & KMOD_RSHIFT)? SCI_EVM_RSHIFT : 0) - | ((modifiers & KMOD_LSHIFT)? SCI_EVM_LSHIFT : 0)); - - sci_event->buckybits = S->buckystate; - sci_event->data = sdl_map_key(drv, event.key.keysym); - if (sci_event->data) - return; - break; - } - case SDL_MOUSEBUTTONDOWN: - sci_event->type = SCI_EVT_MOUSE_PRESS; - sci_event->buckybits = S->buckystate; - sci_event->data = event.button.button - 1; - drv->pointer_x = event.button.x; - drv->pointer_y = event.button.y; - return; - case SDL_MOUSEBUTTONUP: - sci_event->type = SCI_EVT_MOUSE_RELEASE; - sci_event->buckybits = S->buckystate; - sci_event->data = event.button.button - 1; - drv->pointer_x = event.button.x; - drv->pointer_y = event.button.y; - return; - case SDL_MOUSEMOTION: - drv->pointer_x = event.motion.x; - drv->pointer_y = event.motion.y; - break; - case SDL_QUIT: - sci_event->type = SCI_EVT_QUIT; - return; - break; - case SDL_VIDEOEXPOSE: - break; - default: - SDLERROR("Received unhandled SDL event %04x\n", event.type); - } - } - - sci_event->type = SCI_EVT_NONE; /* No event. */ -} - -static sci_event_t -sdl_get_event(struct _gfx_driver *drv) -{ - sci_event_t input; - - sdl_fetch_event(drv, &input); - return input; -} - -static int -sdl_usec_sleep(struct _gfx_driver *drv, long usecs) -{ - int msecs; - SDL_Event event; - - /* Wait at most 10ms to keep mouse cursor responsive. */ - msecs = usecs / 1000; - if (msecs > 10) - msecs = 10; - - SDL_PumpEvents(); - while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, - SDL_EVENTMASK(SDL_MOUSEMOTION)) == 1) { - drv->pointer_x = event.motion.x; - drv->pointer_y = event.motion.y; - } - - SDL_Delay(msecs); - - return GFX_OK; -} - -gfx_driver_t -gfx_driver_sdl = { - "sdl", - "0.3a", - SCI_GFX_DRIVER_MAGIC, - SCI_GFX_DRIVER_VERSION, - NULL, - 0, 0, - GFX_CAPABILITY_MOUSE_SUPPORT | GFX_CAPABILITY_MOUSE_POINTER - | GFX_CAPABILITY_PIXMAP_REGISTRY | GFX_CAPABILITY_FINE_LINES, - 0, /*GFX_DEBUG_POINTER | GFX_DEBUG_UPDATES | GFX_DEBUG_PIXMAPS | GFX_DEBUG_BASIC, */ - sdl_set_parameter, - sdl_init_specific, - sdl_init, - sdl_exit, - sdl_draw_line, - sdl_draw_filled_rect, - sdl_register_pixmap, - sdl_unregister_pixmap, - sdl_draw_pixmap, - sdl_grab_pixmap, - sdl_update, - sdl_set_static_buffer, - sdl_set_pointer, - sdl_set_palette, - sdl_get_event, - sdl_usec_sleep, - NULL -}; - -#endif /* HAVE_SDL */ - - -/* reset to original optimisations for Win32: */ -/* (does not reset intrinsics) */ -#ifdef _WIN32 -//#pragma optimize( "", on ) -#endif diff --git a/engines/sci/gfx/drivers/xlib_driver.c b/engines/sci/gfx/drivers/xlib_driver.c deleted file mode 100644 index baa65d406b..0000000000 --- a/engines/sci/gfx/drivers/xlib_driver.c +++ /dev/null @@ -1,1460 +0,0 @@ -/*************************************************************************** - xlib_driver.h Copyright (C) 2000 Christoph Reichenbach - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Christoph Reichenbach (CR) <creichen@gmail.com> - -***************************************************************************/ - -#include <sci_memory.h> -#include <gfx_driver.h> -#ifndef X_DISPLAY_MISSING -#include <gfx_tools.h> - -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/Xos.h> -#include <X11/Xatom.h> -#include <X11/keysym.h> - -#ifdef HAVE_MITSHM -#include <sys/ipc.h> -#include <sys/shm.h> -#include <X11/extensions/XShm.h> -#if defined(HAVE_X11_EXTENSIONS_XRENDER_H) -# define HAVE_RENDER -# include <X11/extensions/Xrender.h> -# if defined(HAVE_X11_XFT_XFT_H) -# include <X11/Xft/Xft.h> -# endif -#endif -#include <errno.h> -#endif - -#ifdef HAVE_XM_MWMUTIL_H -#include <Xm/MwmUtil.h> -#endif - -#define SCI_XLIB_PIXMAP_HANDLE_NORMAL 0 -#define SCI_XLIB_PIXMAP_HANDLE_GRABBED 1 - -#define SCI_XLIB_SWAP_CTRL_CAPS (1 << 0) -#define SCI_XLIB_INSERT_MODE (1 << 1) -#define SCI_XLIB_NLS (1 << 2) /* Non-US keyboard support, sacrificing shortcut keys */ - -#define X_COLOR_EXT(c) ((c << 8) | c) - -/* In C++ mode, we re-name ``class'' to ``class_''. However, this screws up -** our interface to xlib, so we're not doing it in here. -*/ -#ifdef class -# undef class -#endif - -static int flags; - -struct _xlib_state { - Display *display; - Window window; - GC gc; - XGCValues gc_values; - Colormap colormap; - Pixmap visual[3]; - gfx_pixmap_t *priority[2]; -#ifdef HAVE_MITSHM - XShmSegmentInfo *shm[4]; -#endif - int use_render; - int buckystate; - XErrorHandler old_error_handler; - Cursor mouse_cursor; - byte *pointer_data[2]; - int used_bytespp; /* bytes actually used to display stuff, rather than bytes occupied in data space */ - XVisualInfo visinfo; -#ifdef HAVE_RENDER - Picture picture; -#endif -}; - -#define VISUAL S->visinfo.visual - -#define S ((struct _xlib_state *)(drv->state)) - -#define XASS(foo) { int val = foo; if (!val) xlderror(drv, __LINE__); } -#define XFACT drv->mode->xfact -#define YFACT drv->mode->yfact - -#define DEBUGB if (drv->debug_flags & GFX_DEBUG_BASIC && ((debugline = __LINE__))) xldprintf -#define DEBUGU if (drv->debug_flags & GFX_DEBUG_UPDATES && ((debugline = __LINE__))) xldprintf -#define DEBUGPXM if (drv->debug_flags & GFX_DEBUG_PIXMAPS && ((debugline = __LINE__))) xldprintf -#define DEBUGPTR if (drv->debug_flags & GFX_DEBUG_POINTER && ((debugline = __LINE__))) xldprintf -#define ERROR if ((debugline = __LINE__)) xldprintf - -#ifdef HAVE_MITSHM - -XShmSegmentInfo shminfo; -int have_shmem = 0; -int x11_error = 0; - -static int check_for_xshm(Display *display) -{ - int major, minor, ignore; - Bool pixmaps; - if (XQueryExtension(display, "MIT-SHM", &ignore, &ignore, &ignore)) { - if (XShmQueryVersion( display, &major, &minor, &pixmaps) == True) { - return (pixmaps == True) ? 2 : 1 ; - } else { - return 0; - } - } - return 0; -} -#endif - -#ifdef HAVE_RENDER -static int x_have_render(Display *display) -{ - int ignore, retval; - - printf("Checking for X11 RENDER extension:"); - - retval = XQueryExtension(display, "RENDER", &ignore, &ignore, &ignore); - - if (retval) - printf(" found.\n"); - else - printf(" not found.\n"); - - return retval; -} -#endif - -static int debugline = 0; - -static void -xldprintf(const char *fmt, ...) -{ - va_list argp; - fprintf(stderr,"GFX-XLIB %d:", debugline); - va_start(argp, fmt); - vfprintf(stderr, fmt, argp); - va_end(argp); -} - -static void -xlderror(gfx_driver_t *drv, int line) -{ - xldprintf("Xlib Error in line %d\n", line); -} - -static unsigned long -xlib_map_color(gfx_driver_t *drv, gfx_color_t color) -{ - gfx_mode_t *mode = drv->mode; - unsigned long temp; - unsigned long retval = 0; - - if (drv->mode->palette) - return color.visual.global_index; - - temp = color.visual.r; - temp |= temp << 8; - temp |= temp << 16; - retval |= (temp >> mode->red_shift) & (mode->red_mask); - temp = color.visual.g; - temp |= temp << 8; - temp |= temp << 16; - retval |= (temp >> mode->green_shift) & (mode->green_mask); - temp = color.visual.b; - temp |= temp << 8; - temp |= temp << 16; - retval |= (temp >> mode->blue_shift) & (mode->blue_mask); - - return retval; -} - - -static int -xlib_error_handler(Display *display, XErrorEvent *error) -{ - char errormsg[256]; -#ifdef HAVE_MITSHM - x11_error = 1; -#endif - XGetErrorText(display, error->error_code, errormsg, 255); - ERROR(" X11: %s\n", errormsg); - return 0; -} - -#define UPDATE_NLS_CAPABILITY \ - if (flags & SCI_XLIB_NLS) \ - drv->capabilities |= GFX_CAPABILITY_KEYTRANSLATE; \ - else \ - drv->capabilities &= ~GFX_CAPABILITY_KEYTRANSLATE - - - -static int -xlib_set_parameter(struct _gfx_driver *drv, char *attribute, char *value) -{ - if (!strncmp(attribute, "swap_ctrl_caps",17) || - !strncmp(attribute, "swap_caps_ctrl",17)) { - if (string_truep(value)) - flags |= SCI_XLIB_SWAP_CTRL_CAPS; - else - flags &= ~SCI_XLIB_SWAP_CTRL_CAPS; - - - return GFX_OK; - } - - if (!strncmp(attribute, "localised_keyboard", 18) - || !strncmp(attribute, "localized_keyboard", 18)) { - if (string_truep(value)) - flags |= SCI_XLIB_NLS; - else - flags &= ~SCI_XLIB_NLS; - - UPDATE_NLS_CAPABILITY; - - return GFX_OK; - - } - - if (!strncmp(attribute, "disable_shmem", 14)) { -#ifdef HAVE_MITSHM - if (string_truep(value)) - have_shmem = -1; -#endif - return GFX_OK; - } - - ERROR("Attempt to set xlib parameter \"%s\" to \"%s\"\n", attribute, value); - return GFX_ERROR; -} - -Cursor -x_empty_cursor(Display *display, Drawable drawable) /* Generates an empty X cursor */ -{ - byte cursor_data[] = {0}; - XColor black = {0,0,0}; - Pixmap cursor_map; - - Cursor retval; - - cursor_map = XCreateBitmapFromData(display, drawable, (char *) cursor_data, 1, 1); - - retval = XCreatePixmapCursor(display, cursor_map, cursor_map, &black, &black, 0, 0); - - XFreePixmap(display, cursor_map); - - return retval; -} - -static int -xlib_draw_filled_rect(struct _gfx_driver *drv, rect_t rect, - gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode); -static int -xlib_draw_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm, int priority, - rect_t src, rect_t dest, gfx_buffer_t buffer); - - -static int -xlib_init_specific(struct _gfx_driver *drv, int xfact, int yfact, int bytespp) -{ - XVisualInfo xvisinfo; - XSetWindowAttributes win_attr; - int default_screen; - int vistype = (bytespp == 1)? 3 /* PseudoColor */ : 4 /* TrueColor */; - int red_shift, green_shift, blue_shift, alpha_shift; - int bytespp_physical; - int depth_mod; /* Number of bits to subtract from the depth while checking */ - unsigned int alpha_mask; - int xsize, ysize; - XSizeHints *size_hints; - XClassHint *class_hint; - XImage *foo_image = NULL; - int reverse_endian = 0; -#ifdef HAVE_XM_MWMUTIL_H - PropMotifWmHints motif_hints; - Atom prop, proptype; -#endif - - int i; - - - UPDATE_NLS_CAPABILITY; - - if (!drv->state /* = S */) - drv->state = sci_malloc(sizeof(struct _xlib_state)); - - flags |= SCI_XLIB_INSERT_MODE; - - S->display = XOpenDisplay(NULL); - - if (!S->display) { - ERROR("Could not open X connection!\n"); - return GFX_FATAL; - } - - default_screen = DefaultScreen(S->display); - - if (xfact == -1 && yfact == -1) { /* Detect (used INTERNALLY!) */ - xfact = 2; - if (DisplayWidth(S->display, default_screen) < 640 - || DisplayHeight(S->display, default_screen) < 400) - xfact = 1; - - yfact = xfact; - } - - xsize = xfact * 320; - ysize = yfact * 200; - if (xfact < 1 || yfact < 1 || bytespp < 1 || bytespp > 4) { - ERROR("Internal error: Attempt to open window w/ scale factors (%d,%d) and bpp=%d!\n", - xfact, yfact, bytespp); - BREAKPOINT(); - } - -#ifdef HAVE_MITSHM - if (!have_shmem) { - have_shmem = check_for_xshm(S->display); - if (have_shmem) { - printf("Using the MIT-SHM extension (%d/%d)\n", have_shmem, - XShmPixmapFormat(S->display)); - } - memset(&shminfo, 0, sizeof(XShmSegmentInfo)); - } - for (i = 0; i < 4; i++) - S->shm[i] = NULL; -#endif - - depth_mod = 0; - - /* Try all bit size twiddling */ - for (depth_mod = 0; depth_mod < 8; depth_mod++) - /* Try all viable depths */ - for (; bytespp > 0; bytespp--) - /* Try all interesting visuals */ - for (vistype = 4; vistype >= 3; vistype--) - if (XMatchVisualInfo(S->display, default_screen, - (bytespp << 3) - depth_mod, vistype, &xvisinfo)) - goto found_visual; - found_visual: - - S->visinfo = xvisinfo; - - if (vistype < 3 || ((vistype == 3) && (bytespp != 1))) { - if (bytespp == 1) { - ERROR("Could not get an 8 bit Pseudocolor visual!\n"); - } else { - ERROR("Could not get a %d bit TrueColor visual!\n", bytespp << 3); - } - return GFX_FATAL; - } - - S->colormap = win_attr.colormap = - XCreateColormap(S->display, RootWindow(S->display, default_screen), - VISUAL, (bytespp == 1)? AllocAll : AllocNone); - - win_attr.event_mask = PointerMotionMask | StructureNotifyMask | ButtonPressMask - | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | ExposureMask; - win_attr.background_pixel = win_attr.border_pixel = 0; - - S->window = XCreateWindow(S->display, RootWindow(S->display, default_screen), - 0, 0, xsize, ysize, 0, xvisinfo.depth, InputOutput, - VISUAL, (CWBackPixel | CWBorderPixel | CWColormap | CWEventMask), - &win_attr); - - if (!S->window) { - ERROR("Could not create window of size %dx%d!\n", 320*xfact, 200*yfact); - return GFX_FATAL; - } - - XSync(S->display, False); -#ifdef HAVE_XM_MWMUTIL_H - motif_hints.flags = MWM_HINTS_DECORATIONS|MWM_HINTS_FUNCTIONS; - motif_hints.decorations = MWM_DECOR_BORDER|MWM_DECOR_TITLE|MWM_DECOR_MENU|MWM_DECOR_MINIMIZE; - motif_hints.functions=0 -#ifdef MWM_FUNC_MOVE - | MWM_FUNC_MOVE -#endif -#ifdef MWM_FUNC_MINIMIZE - | MWM_FUNC_MINIMIZE -#endif -#ifdef MWM_FUNC_CLOSE - | MWM_FUNC_CLOSE -#endif -#ifdef MWM_FUNC_QUIT_APP - | MWM_FUNC_QUIT_APP -#endif - ; - - prop = XInternAtom(S->display, "_MOTIF_WM_HINTS", True ); - if (prop) { - proptype = prop; - XChangeProperty(S->display, S->window, prop, proptype, 32, PropModeReplace, (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS); - } -#endif - - XStoreName(S->display, S->window, "FreeSCI"); - XDefineCursor(S->display, S->window, (S->mouse_cursor = x_empty_cursor(S->display, S->window))); - - XMapWindow(S->display, S->window); - S->buckystate = 0; - - if (bytespp == 1) - red_shift = green_shift = blue_shift = 0; - else { - red_shift = 32 - ffs((~xvisinfo.red_mask >> 1) & (xvisinfo.red_mask)); - green_shift = 32 - ffs((~xvisinfo.green_mask >> 1) & (xvisinfo.green_mask)); - blue_shift = 32 - ffs((~xvisinfo.blue_mask >> 1) & (xvisinfo.blue_mask)); - } - - class_hint = XAllocClassHint(); - class_hint->res_name = "FreeSCI"; - class_hint->res_class = "FreeSCI"; - XSetIconName(S->display, S->window, "FreeSCI"); - XSetClassHint(S->display, S->window, class_hint); - XFree(class_hint); - size_hints = XAllocSizeHints(); - size_hints->base_width = size_hints->min_width = size_hints->max_width = xsize; - size_hints->base_height = size_hints->min_height = size_hints->max_height = ysize; - size_hints->flags |= PMinSize | PMaxSize | PBaseSize; - XSetWMNormalHints(S->display, S->window, size_hints); - XFree(size_hints); - - S->gc_values.foreground = BlackPixel(S->display, DefaultScreen(S->display)); - S->gc = XCreateGC(S->display, S->window, GCForeground, &(S->gc_values)); - - for (i = 0; i < 2; i++) { - S->priority[i] = gfx_pixmap_alloc_index_data(gfx_new_pixmap(xsize, ysize, GFX_RESID_NONE, -i, -777)); - if (!S->priority[i]) { - ERROR("Out of memory: Could not allocate priority maps! (%dx%d)\n", - xsize, ysize); - return GFX_FATAL; - } - } - - foo_image = XCreateImage(S->display, VISUAL, - bytespp << 3, ZPixmap, 0, (char*)sci_malloc(23), 2, 2, 8, 0); - - bytespp_physical = foo_image->bits_per_pixel >> 3; -#ifdef WORDS_BIGENDIAN - reverse_endian = foo_image->byte_order == LSBFirst; -#else - reverse_endian = foo_image->byte_order == MSBFirst; -#endif - XDestroyImage(foo_image); - -#ifdef HAVE_MITSHM - /* set up and test the XSHM extension to make sure it's sane */ - if (have_shmem) { - XErrorHandler old_handler; - - x11_error = 0; - old_handler = XSetErrorHandler(xlib_error_handler); - - foo_image = XShmCreateImage(S->display, VISUAL, - bytespp_physical << 3, ZPixmap, 0, &shminfo, 2, 2); - if (foo_image) - shminfo.shmid = shmget(IPC_PRIVATE, - foo_image->bytes_per_line * - foo_image->height, - IPC_CREAT | 0777); - if (-1 == shminfo.shmid) { - have_shmem = 0; - ERROR("System does not support SysV IPC, disabling XSHM\n"); - perror("reason"); - foo_image = NULL; - } else { - - shminfo.shmaddr = (char *) shmat(shminfo.shmid, 0, 0); - if ((void *) -1 == shminfo.shmaddr) { - ERROR("Could not attach shared memory segment\n"); - perror("reason"); - if (foo_image) - XDestroyImage(foo_image); - return GFX_FATAL; - } - - foo_image->data = shminfo.shmaddr; - shminfo.readOnly = False; - - XShmAttach(S->display, &shminfo); - XSync(S->display, False); - shmctl(shminfo.shmid, IPC_RMID, 0); - - if (x11_error) { - have_shmem = 0; - ERROR("System does not support Shared XImages, disabling\n"); - shmdt(shminfo.shmaddr); - XDestroyImage(foo_image); - foo_image = NULL; - x11_error = 0; - } - XSetErrorHandler(old_handler); - } - } - -#endif - - - alpha_mask = xvisinfo.red_mask | xvisinfo.green_mask | xvisinfo.blue_mask; - if (!reverse_endian && bytespp_physical == 4 && (!(alpha_mask & 0xff000000) || !(alpha_mask & 0xff))) { - if (alpha_mask & 0xff) { - alpha_mask = 0xff000000; - alpha_shift = 0; - } else { /* Lowest byte */ - alpha_mask = 0x000000ff; - alpha_shift = 24; - } - } else { - alpha_mask = 0; - alpha_shift = 0; - } - /* create the visual buffers */ - for (i = 0; i < 3; i++) { -#ifdef HAVE_MITSHM - XErrorHandler old_handler; - - if (have_shmem && have_shmem != 2) { - ERROR("Shared memory pixmaps not supported. Reverting\n"); - perror("reason"); - have_shmem = 0; - } - - if (have_shmem) { - old_handler = XSetErrorHandler(xlib_error_handler); - - if ((S->shm[i] = (XShmSegmentInfo*)sci_malloc(sizeof(XShmSegmentInfo))) == 0) { - ERROR("AIEEEE! Malloc failed!\n"); - return GFX_FATAL; - } - memset(S->shm[i], 0, sizeof(XShmSegmentInfo)); - - S->shm[i]->shmid = shmget(IPC_PRIVATE, xsize * ysize * - bytespp_physical, - IPC_CREAT | IPC_EXCL | 0666); - S->shm[i]->readOnly = False; - - if (S->shm[i]->shmid == -1) { - have_shmem = 0; - ERROR("System does not support SysV IPC, disabling XSHM\n"); - perror("reason"); - } - } - if (have_shmem) { - S->shm[i]->shmaddr = (char *) shmat(S->shm[i]->shmid, 0, 0); - if (S->shm[i]->shmaddr == (void *) -1) { - ERROR("Could not attach shared memory segment\n"); - perror("reason"); - have_shmem = 0; - } - } - if (have_shmem) { - if (!XShmAttach(S->display, S->shm[i]) || x11_error) { - ERROR("ARGH! Can't attach shared memory segment\n"); - have_shmem = 0; - } - XSync(S->display, False); - shmctl(S->shm[i]->shmid, IPC_RMID, 0); - } - - if (have_shmem && !x11_error) { - S->visual[i] = XShmCreatePixmap(S->display, S->window, - S->shm[i]->shmaddr, - S->shm[i], xsize, ysize, - bytespp << 3); - XSync(S->display, False); - - if (x11_error || !S->visual[i]) { - ERROR("Shared Memory Pixmaps not supported on this system. Disabling!\n"); - have_shmem = 0; - XFreePixmap(S->display, S->visual[i]); - XShmDetach(S->display ,S->shm[i]); - XSync(S->display, False); - S->visual[i] = 0; - x11_error = 0; - shmdt(S->shm[i]->shmaddr); - sci_free(S->shm[i]); - - } - - } - XSetErrorHandler(old_handler); - - if (!have_shmem) -#endif - S->visual[i] = XCreatePixmap(S->display, S->window, xsize, ysize, bytespp << 3); - - XFillRectangle(S->display, S->visual[i], S->gc, 0, 0, xsize, ysize); - } - - /** X RENDER handling **/ -#ifdef HAVE_RENDER - S->use_render = x_have_render(S->display); - - if (S->use_render) { - XRenderPictFormat * format - = XRenderFindVisualFormat (S->display, - VISUAL); - S->picture = XRenderCreatePicture (S->display, - (Drawable) S->visual[1], - format, - 0, 0); - } else /* No Xrender */ - drv->draw_filled_rect = xlib_draw_filled_rect; -#else - S->use_render = 0; -#endif - /** End of X RENDER handling **/ - - - drv->mode = gfx_new_mode(xfact, yfact, bytespp_physical, - xvisinfo.red_mask, xvisinfo.green_mask, - xvisinfo.blue_mask, alpha_mask, - red_shift, green_shift, blue_shift, alpha_shift, - (bytespp == 1)? xvisinfo.colormap_size : 0, - (reverse_endian)? GFX_MODE_FLAG_REVERSE_ENDIAN : 0); - -#ifdef HAVE_MITSHM - if (have_shmem) { - XShmDetach(S->display, &shminfo); - XDestroyImage(foo_image); - shmdt(shminfo.shmaddr); - } -#endif - - S->used_bytespp = bytespp; - S->old_error_handler = (XErrorHandler) XSetErrorHandler(xlib_error_handler); - S->pointer_data[0] = NULL; - S->pointer_data[1] = NULL; - - - return GFX_OK; -} - - -static void -xlib_xdpy_info() -{ - int i; - XVisualInfo foo; - XVisualInfo *visuals; - int visuals_nr; - Display *display = XOpenDisplay(NULL); - const char *vis_classes[6] = {"StaticGray", "GrayScale", "StaticColor", - "PseudoColor", "TrueColor", "DirectColor"}; - - printf("Visuals provided by X11 server:\n"); - visuals = XGetVisualInfo(display, VisualNoMask, &foo, &visuals_nr); - - if (!visuals_nr) { - printf(" None!\n"); - } - - for (i = 0; i < visuals_nr; i++) { - XVisualInfo *visual = visuals + i; - - /* This works around an incompatibility between C++ and xlib: access visual->class */ - int visual_class = *((int *) (((byte *)(&(visual->depth))) + sizeof(unsigned int))); - - printf("%d:\t%d bpp %s(%d)\n" - "\tR:%08lx G:%08lx B:%08lx\n" - "\tbits_per_rgb=%d\n" - "\tcolormap_size=%d\n\n", - i, - visual->depth, - (visual_class < 0 || visual_class >5)? - "INVALID" : - vis_classes[visual_class], - visual_class, - visual->red_mask, visual->green_mask, visual->blue_mask, - visual->bits_per_rgb, visual->colormap_size); - - } - - if (visuals) - XFree(visuals); -} - -static int -xlib_init(struct _gfx_driver *drv) -{ - int i; - - /* Try 32-bit mode last due to compiz issue with bit depth 32. */ - for (i = 3; i > 0; i--) - if (!xlib_init_specific(drv, -1, -1, i)) - return GFX_OK; - - if (!xlib_init_specific(drv, -1, -1, 4)) - return GFX_OK; - - fprintf(stderr, "Could not find supported mode!\n"); - xlib_xdpy_info(); - - return GFX_FATAL; -} - -static void -xlib_exit(struct _gfx_driver *drv) -{ - int i; - if (S) { - for (i = 0; i < 2; i++) { - gfx_free_pixmap(drv, S->priority[i]); - S->priority[i] = NULL; - } - - for (i = 0; i < 3; i++) { -#ifdef HAVE_MITSHM - if (have_shmem && S->shm[i]) { - XFreePixmap(S->display, S->visual[i]); - XShmDetach(S->display, S->shm[i]); - - if (S->shm[i]->shmid >=0) - shmctl(S->shm[i]->shmid, IPC_RMID, 0); - if (S->shm[i]->shmaddr) - shmdt(S->shm[i]->shmaddr); - - sci_free(S->shm[i]); - S->shm[i] = NULL; - } else -#endif - XFreePixmap(S->display, S->visual[i]); - } - -#ifdef HAVE_RENDER - XRenderFreePicture(S->display, S->picture); -#endif - XFreeGC(S->display, S->gc); - XDestroyWindow(S->display, S->window); - XCloseDisplay(S->display); - XSetErrorHandler((XErrorHandler) (S->old_error_handler)); - sci_free(S); - drv->state /* = S */ = NULL; - gfx_free_mode(drv->mode); - } -} - - - /*** Drawing operations ***/ - -static int -xlib_draw_line(struct _gfx_driver *drv, point_t start, point_t end, gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style) -{ - int linewidth = (line_mode == GFX_LINE_MODE_FINE)? 1: - (drv->mode->xfact + drv->mode->yfact) >> 1; - - if (color.mask & GFX_MASK_VISUAL) { - int xmod = drv->mode->xfact >> 1; - int ymod = drv->mode->yfact >> 1; - - if (line_mode == GFX_LINE_MODE_FINE) - xmod = ymod = 0; - - S->gc_values.foreground = xlib_map_color(drv, color); - S->gc_values.line_width = linewidth; - S->gc_values.line_style = (line_style == GFX_LINE_STYLE_NORMAL)? - LineSolid : LineOnOffDash; - S->gc_values.cap_style = CapProjecting; - - XChangeGC(S->display, S->gc, GCLineWidth | GCLineStyle | GCForeground | GCCapStyle, &(S->gc_values)); - - XASS(XDrawLine(S->display, S->visual[1], S->gc, - start.x + xmod, start.y + ymod, - end.x + xmod, end.y + ymod)); - } - - if (color.mask & GFX_MASK_PRIORITY) { - int xc, yc; - point_t nstart, nend; - - linewidth--; - for (xc = 0; xc <= linewidth; xc++) - for (yc = -linewidth; yc <= linewidth; yc++) { - nstart.x = start.x + xc; - nstart.y = start.y + yc; - - nend.x = end.x + xc; - nend.y = end.y + yc; - - gfx_draw_line_pixmap_i(S->priority[0], - nstart, nend, color.priority); - } - } - - return GFX_OK; -} - -static int -xlib_draw_filled_rect(struct _gfx_driver *drv, rect_t rect, - gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode) -{ - if (color1.mask & GFX_MASK_VISUAL) { - S->gc_values.foreground = xlib_map_color(drv, color1); - XChangeGC(S->display, S->gc, GCForeground, &(S->gc_values)); - XASS(XFillRectangle(S->display, S->visual[1], S->gc, rect.x, rect.y, - rect.xl, rect.yl)); - } - - if (color1.mask & GFX_MASK_PRIORITY) - gfx_draw_box_pixmap_i(S->priority[0], rect, color1.priority); - - return GFX_OK; -} - -#ifdef HAVE_RENDER -static int -xlib_draw_filled_rect_RENDER(struct _gfx_driver *drv, rect_t rect, - gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode) -{ - if (S->used_bytespp == 1) /* No room for alpha! */ - return xlib_draw_filled_rect(drv, rect, color1, color2, shade_mode); - - if (color1.mask & GFX_MASK_VISUAL) { - XRenderColor fg; - - fg.red = X_COLOR_EXT(color1.visual.r); - fg.green = X_COLOR_EXT(color1.visual.g); - fg.blue = X_COLOR_EXT(color1.visual.b); - fg.alpha = 0xffff - X_COLOR_EXT(color1.alpha); - - - XRenderFillRectangle(S->display, - PictOpOver, - S->picture, - &fg, - rect.x, rect.y, - rect.xl, rect.yl); - } - - if (color1.mask & GFX_MASK_PRIORITY) - gfx_draw_box_pixmap_i(S->priority[0], rect, color1.priority); - - return GFX_OK; -} -#endif - - /*** Pixmap operations ***/ - -static int -xlib_register_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm) -{ - if (pxm->internal.info) { - ERROR("Attempt to register pixmap twice!\n"); - return GFX_ERROR; - } - pxm->internal.info = XCreateImage(S->display, VISUAL, - S->used_bytespp << 3, ZPixmap, 0, (char *) pxm->data, pxm->xl, - pxm->yl, 8, 0); - - DEBUGPXM("Registered pixmap %d/%d/%d at %p (%dx%d)\n", pxm->ID, pxm->loop, pxm->cel, - pxm->internal.info, pxm->xl, pxm->yl); - return GFX_OK; -} - -static int -xlib_unregister_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm) -{ - DEBUGPXM("Freeing pixmap %d/%d/%d at %p\n", pxm->ID, pxm->loop, pxm->cel, - pxm->internal.info); - - if (!pxm->internal.info) { - ERROR("Attempt to unregister pixmap twice!\n"); - return GFX_ERROR; - } - - XDestroyImage((XImage *) pxm->internal.info); - pxm->internal.info = NULL; - pxm->data = NULL; /* Freed by XDestroyImage */ - return GFX_OK; -} - -static int -xlib_draw_pixmap(struct _gfx_driver *drv, gfx_pixmap_t *pxm, int priority, - rect_t src, rect_t dest, gfx_buffer_t buffer) -{ - int bufnr = (buffer == GFX_BUFFER_STATIC)? 2:1; - int pribufnr = bufnr -1; - XImage *tempimg; - - if (dest.xl != src.xl || dest.yl != src.yl) { - ERROR("Attempt to scale pixmap (%dx%d)->(%dx%d): Not supported\n", - src.xl, src.yl, dest.xl, dest.yl); - return GFX_ERROR; - } - - if (pxm->internal.handle == SCI_XLIB_PIXMAP_HANDLE_GRABBED) { - XPutImage(S->display, S->visual[bufnr], S->gc, (XImage *) pxm->internal.info, - src.x, src.y, dest.x, dest.y, dest.xl, dest.yl); - return GFX_OK; - } - - tempimg = XGetImage(S->display, S->visual[bufnr], dest.x, dest.y, - dest.xl, dest.yl, 0xffffffff, ZPixmap); - - if (!tempimg) { - ERROR("Failed to grab X image!\n"); - return GFX_ERROR; - } - - gfx_crossblit_pixmap(drv->mode, pxm, priority, src, dest, - (byte *) tempimg->data, tempimg->bytes_per_line, - S->priority[pribufnr]->index_data, - S->priority[pribufnr]->index_xl, 1, - GFX_CROSSBLIT_FLAG_DATA_IS_HOMED); - - XPutImage(S->display, S->visual[bufnr], S->gc, tempimg, - 0, 0, dest.x, dest.y, dest.xl, dest.yl); - - XDestroyImage(tempimg); - return GFX_OK; -} - - -static int -xlib_grab_pixmap(struct _gfx_driver *drv, rect_t src, gfx_pixmap_t *pxm, - gfx_map_mask_t map) -{ - - if (src.x < 0 || src.y < 0) { - ERROR("Attempt to grab pixmap from invalid coordinates (%d,%d)\n", src.x, src.y); - return GFX_ERROR; - } - - if (!pxm->data) { - ERROR("Attempt to grab pixmap to unallocated memory\n"); - return GFX_ERROR; - } - - switch (map) { - - case GFX_MASK_VISUAL: - pxm->xl = src.xl; - pxm->yl = src.yl; - - pxm->internal.info = XGetImage(S->display, S->visual[1], src.x, src.y, - src.xl, src.yl, 0xffffffff, ZPixmap); - pxm->internal.handle = SCI_XLIB_PIXMAP_HANDLE_GRABBED; - pxm->flags |= GFX_PIXMAP_FLAG_INSTALLED | GFX_PIXMAP_FLAG_EXTERNAL_PALETTE | GFX_PIXMAP_FLAG_PALETTE_SET; - sci_free(pxm->data); - pxm->data = (byte *) ((XImage *)(pxm->internal.info))->data; - break; - - case GFX_MASK_PRIORITY: - ERROR("FIXME: priority map grab not implemented yet!\n"); - break; - - default: - ERROR("Attempt to grab pixmap from invalid map 0x%02x\n", map); - return GFX_ERROR; - } - - return GFX_OK; -} - - - /*** Buffer operations ***/ - -static int -xlib_update(struct _gfx_driver *drv, rect_t src, point_t dest, gfx_buffer_t buffer) -{ - int data_source = (buffer == GFX_BUFFER_BACK)? 2 : 1; - int data_dest = data_source - 1; - - - if (src.x != dest.x || src.y != dest.y) { - DEBUGU("Updating %d (%d,%d)(%dx%d) to (%d,%d)\n", buffer, src.x, src.y, - src.xl, src.yl, dest.x, dest.y); - } else { - DEBUGU("Updating %d (%d,%d)(%dx%d)\n", buffer, src.x, src.y, src.xl, src.yl); - } - - XCopyArea(S->display, S->visual[data_source], S->visual[data_dest], S->gc, - src.x, src.y, src.xl, src.yl, dest.x, dest.y); - - if (buffer == GFX_BUFFER_BACK && (src.x == dest.x) && (src.y == dest.y)) - gfx_copy_pixmap_box_i(S->priority[0], S->priority[1], src); - else { - gfx_color_t col; - col.mask = GFX_MASK_VISUAL; - col.visual.r = 0xff; - col.visual.g = 0; - col.visual.b = 0; - - XCopyArea(S->display, S->visual[0], S->window, S->gc, - dest.x, dest.y, src.xl, src.yl, dest.x, dest.y); - } - - return GFX_OK; -} - -static int -xlib_set_static_buffer(struct _gfx_driver *drv, gfx_pixmap_t *pic, gfx_pixmap_t *priority) -{ - - if (!pic->internal.info) { - ERROR("Attempt to set static buffer with unregisterd pixmap!\n"); - return GFX_ERROR; - } - XPutImage(S->display, S->visual[2], S->gc, (XImage *) pic->internal.info, - 0, 0, 0, 0, 320 * XFACT, 200 * YFACT); - gfx_copy_pixmap_box_i(S->priority[1], priority, gfx_rect(0, 0, 320*XFACT, 200*YFACT)); - - return GFX_OK; -} - - - /*** Mouse pointer operations ***/ - -byte * -xlib_create_cursor_data(gfx_driver_t *drv, gfx_pixmap_t *pointer, int mode) -{ - int linewidth = (pointer->xl + 7) >> 3; - int lines = pointer->yl; - int xc, yc; - int xfact = drv->mode->xfact; - byte *data = (byte*)sci_calloc(linewidth, lines); - byte *linebase = data, *pos; - byte *src = pointer->index_data; - - - for (yc = 0; yc < pointer->index_yl; yc++) { - int scalectr; - int bitc = 0; - pos = linebase; - - - for (xc = 0; xc < pointer->index_xl; xc++) { - int draw = mode? - (*src == 0) : (*src < 255); - - for (scalectr = 0; scalectr < xfact; scalectr++) { - if (draw) - *pos |= (1 << bitc); - - bitc++; - if (bitc == 8) { - bitc = 0; - pos++; - } - } - - src++; - } - for (scalectr = 1; scalectr < drv->mode->yfact; scalectr++) - memcpy(linebase + linewidth * scalectr, linebase, linewidth); - - linebase += linewidth * drv->mode->yfact; - } - - return data; -} - -static int -xlib_set_pointer(struct _gfx_driver *drv, gfx_pixmap_t *pointer) -{ - int i; - XFreeCursor(S->display, S->mouse_cursor); - - for (i = 0; i < 2; i++) - if (S->pointer_data[i]) { - sci_free(S->pointer_data[i]); - S->pointer_data[i] = NULL; - } - - if (pointer == NULL) - S->mouse_cursor = x_empty_cursor(S->display, S->window); - else { - XColor cols[2]; - Pixmap visual, mask; - byte *mask_data, *visual_data; - int real_xl = ((pointer->xl + 7) >> 3) << 3; - int i; - - for (i = 0; i < 2; i++) { - cols[i].red = pointer->colors[i].r; - cols[i].red |= (cols[i].red << 8); - cols[i].green = pointer->colors[i].g; - cols[i].green |= (cols[i].green << 8); - cols[i].blue = pointer->colors[i].b; - cols[i].blue |= (cols[i].blue << 8); - } - - S->pointer_data[0] = visual_data = xlib_create_cursor_data(drv, pointer, 1); - S->pointer_data[1] = mask_data = xlib_create_cursor_data(drv, pointer, 0); - S->pointer_data[0] = NULL; - S->pointer_data[1] = NULL; - visual = XCreateBitmapFromData(S->display, S->window, (char *) visual_data, real_xl, pointer->yl); - mask = XCreateBitmapFromData(S->display, S->window, (char *) mask_data, real_xl, pointer->yl); - - - S->mouse_cursor = - XCreatePixmapCursor(S->display, visual, mask, - &(cols[0]), &(cols[1]), - pointer->xoffset, pointer->yoffset); - - XFreePixmap(S->display, visual); - XFreePixmap(S->display, mask); - sci_free(mask_data); - sci_free(visual_data); - } - - XDefineCursor(S->display, S->window, S->mouse_cursor); - - return 0; -} - - - /*** Palette operations ***/ - -static int -xlib_set_palette(struct _gfx_driver *drv, int index, byte red, byte green, byte blue) -{ - char stringbuf[8]; - sprintf(stringbuf, "#%02x%02x%02x", red, green, blue); /* Argh. */ - - XStoreNamedColor(S->display, S->colormap, stringbuf, index, DoRed | DoGreen | DoBlue); - /* Isn't there some way to do this without strings? */ - - return GFX_OK; -} - - - /*** Event management ***/ -/* -int -x_unmap_key(gfx_driver_t *drv, int keycode) -{ - KeySym xkey = XKeycodeToKeysym(S->display, keycode, 0); - - return 0; -} -*/ -int -x_map_key(gfx_driver_t *drv, XEvent *key_event, char *character) -{ - KeySym xkey = XKeycodeToKeysym(S->display, key_event->xkey.keycode, 0); - - *character = 0; - - if (flags & SCI_XLIB_SWAP_CTRL_CAPS) { - switch (xkey) { - case XK_Control_L: xkey = XK_Caps_Lock; break; - case XK_Caps_Lock: xkey = XK_Control_L; break; - } - } - - switch(xkey) { - - case XK_BackSpace: return SCI_K_BACKSPACE; - case XK_Tab: return 9; - case XK_Escape: return SCI_K_ESC; - case XK_Return: - case XK_KP_Enter: return SCI_K_ENTER; - - case XK_KP_Decimal: - case XK_KP_Delete: return SCI_K_DELETE; - case XK_KP_0: - case XK_KP_Insert: return SCI_K_INSERT; - case XK_End: - case XK_KP_End: - case XK_KP_1: return SCI_K_END; - case XK_Down: - case XK_KP_Down: - case XK_KP_2: return SCI_K_DOWN; - case XK_Page_Down: - case XK_KP_Page_Down: - case XK_KP_3: return SCI_K_PGDOWN; - case XK_Left: - case XK_KP_Left: - case XK_KP_4: return SCI_K_LEFT; - case XK_KP_Begin: - case XK_KP_5: return SCI_K_CENTER; - case XK_Right: - case XK_KP_Right: - case XK_KP_6: return SCI_K_RIGHT; - case XK_Home: - case XK_KP_Home: - case XK_KP_7: return SCI_K_HOME; - case XK_Up: - case XK_KP_Up: - case XK_KP_8: return SCI_K_UP; - case XK_Page_Up: - case XK_KP_Page_Up: - case XK_KP_9: return SCI_K_PGUP; - - case XK_F1: return SCI_K_F1; - case XK_F2: return SCI_K_F2; - case XK_F3: return SCI_K_F3; - case XK_F4: return SCI_K_F4; - case XK_F5: return SCI_K_F5; - case XK_F6: return SCI_K_F6; - case XK_F7: return SCI_K_F7; - case XK_F8: return SCI_K_F8; - case XK_F9: return SCI_K_F9; - case XK_F10: return SCI_K_F10; - - - case XK_Control_L: - case XK_Control_R:/* S->buckystate |= SCI_EVM_CTRL; return 0; */ - case XK_Alt_L: - case XK_Alt_R:/* S->buckystate |= SCI_EVM_ALT; return 0; */ - case XK_Caps_Lock: - case XK_Shift_Lock:/* S->buckystate ^= SCI_EVM_CAPSLOCK; return 0; */ - case XK_Scroll_Lock:/* S->buckystate ^= SCI_EVM_SCRLOCK; return 0; */ - case XK_Num_Lock:/* S->buckystate ^= SCI_EVM_NUMLOCK; return 0; */ - case XK_Shift_L:/* S->buckystate |= SCI_EVM_LSHIFT; return 0; */ - case XK_Shift_R:/* S->buckystate |= SCI_EVM_RSHIFT; return 0; */ - return 0; - default: - break; - } - - - if (flags & SCI_XLIB_NLS) { - /* Localised key lookup */ - XLookupString(&(key_event->xkey), character, 1, &xkey, NULL); - } - - if ((xkey >= ' ') && (xkey <= '~')) - return xkey; /* All printable ASCII characters */ - - switch (xkey) { - case XK_KP_Add: return '+'; - case XK_KP_Divide: return '/'; - case XK_KP_Subtract: return '-'; - case XK_KP_Multiply: return '*'; - } - - if (*character) - return xkey; /* Should suffice for all practical purposes */ - - sciprintf("Unknown X keysym: %04x\n", xkey); - return 0; -} - - -void -x_get_event(gfx_driver_t *drv, int eventmask, long wait_usec, sci_event_t *sci_event) -{ - int x_button_xlate[] = {0, 1, 3, 2, 4, 5}; - XEvent event; - Window window = S->window; - Display *display = S->display; - struct timeval ctime, timeout_time, sleep_time; - long usecs_to_sleep; - - eventmask |= ExposureMask; /* Always check for this */ - - gettimeofday(&timeout_time, NULL); - timeout_time.tv_usec += wait_usec; - - /* Calculate wait time */ - timeout_time.tv_sec += (timeout_time.tv_usec / 1000000); - timeout_time.tv_usec %= 1000000; - - do { - int hasnext_event = 1; - - while (hasnext_event) { - if (sci_event) { /* Capable of handling any event? */ - hasnext_event = XPending(display); - if (hasnext_event) - XNextEvent(display, &event); - } else - hasnext_event = XCheckWindowEvent(display, window, eventmask, &event); - - - if (hasnext_event) - switch (event.type) { - - case ReparentNotify: - case ConfigureNotify: - case MapNotify: - case UnmapNotify: - break; - - case KeyPress: { - int modifiers = event.xkey.state; - char ch = 0; - sci_event->type = SCI_EVT_KEYBOARD; - - S->buckystate = ((flags & SCI_XLIB_INSERT_MODE)? SCI_EVM_INSERT : 0) - | (((modifiers & LockMask)? SCI_EVM_LSHIFT | SCI_EVM_RSHIFT : 0) - | ((modifiers & ControlMask)? SCI_EVM_CTRL : 0) - | ((modifiers & (Mod1Mask | Mod4Mask))? SCI_EVM_ALT : 0) - | ((modifiers & Mod2Mask)? SCI_EVM_NUMLOCK : 0) - | ((modifiers & Mod5Mask)? SCI_EVM_SCRLOCK : 0)) - ^ ((modifiers & ShiftMask)? SCI_EVM_LSHIFT | SCI_EVM_RSHIFT : 0); - - sci_event->buckybits = S->buckystate; - sci_event->data = - x_map_key(drv, &event, &ch); - - if (ch) - sci_event->character = ch; - else - sci_event->character = sci_event->data; - - if (sci_event->data == SCI_K_INSERT) - flags ^= SCI_XLIB_INSERT_MODE; - - if (sci_event->data) - return; - - break; - } - - case KeyRelease: - /*x_unmap_key(drv, event.xkey.keycode);*/ - break; - - case ButtonPress: { - sci_event->type = SCI_EVT_MOUSE_PRESS; - sci_event->buckybits = S->buckystate; - sci_event->data = x_button_xlate[event.xbutton.button]; - return; - } - - case ButtonRelease: { - sci_event->type = SCI_EVT_MOUSE_RELEASE; - sci_event->buckybits = S->buckystate; - sci_event->data = x_button_xlate[event.xbutton.button]; - return; - } - - case MotionNotify: { - - drv->pointer_x = event.xmotion.x; - drv->pointer_y = event.xmotion.y; - if (!sci_event) - /* Wake up from sleep */ - return; - } - break; - - case GraphicsExpose: - case Expose: { - XCopyArea(S->display, S->visual[0], S->window, S->gc, - event.xexpose.x, event.xexpose.y, event.xexpose.width, event.xexpose.height, - event.xexpose.x, event.xexpose.y); - } - break; - - case NoExpose: - break; - - default: - ERROR("Received unhandled X event %04x\n", event.type); - } - } - - gettimeofday(&ctime, NULL); - - usecs_to_sleep = (timeout_time.tv_sec > ctime.tv_sec)? 1000000 : 0; - usecs_to_sleep += timeout_time.tv_usec - ctime.tv_usec; - if (ctime.tv_sec > timeout_time.tv_sec) usecs_to_sleep = -1; - - - if (usecs_to_sleep > 0) { - - if (usecs_to_sleep > 10000) - usecs_to_sleep = 10000; /* Sleep for a maximum of 10 ms */ - - sleep_time.tv_usec = usecs_to_sleep; - sleep_time.tv_sec = 0; - - select(0, NULL, NULL, NULL, &sleep_time); /* Sleep. */ - } - - } while (usecs_to_sleep >= 0); - - if (sci_event) - sci_event->type = SCI_EVT_NONE; /* No event. */ -} - - -static sci_event_t -xlib_get_event(struct _gfx_driver *drv) -{ - sci_event_t input; - - x_get_event(drv, PointerMotionMask | StructureNotifyMask | ButtonPressMask - | ButtonReleaseMask | KeyPressMask | KeyReleaseMask, - 0, &input); - - return input; -} - - -static int -xlib_usec_sleep(struct _gfx_driver *drv, long usecs) -{ - x_get_event(drv, PointerMotionMask | StructureNotifyMask, usecs, NULL); - return GFX_OK; -} - -gfx_driver_t -gfx_driver_xlib = { - "xlib", - "0.6a", - SCI_GFX_DRIVER_MAGIC, - SCI_GFX_DRIVER_VERSION, - NULL, - 0, 0, - GFX_CAPABILITY_STIPPLED_LINES | GFX_CAPABILITY_MOUSE_SUPPORT - | GFX_CAPABILITY_MOUSE_POINTER | GFX_CAPABILITY_PIXMAP_REGISTRY - | GFX_CAPABILITY_FINE_LINES | GFX_CAPABILITY_WINDOWED - | GFX_CAPABILITY_KEYTRANSLATE, - 0/*GFX_DEBUG_POINTER | GFX_DEBUG_UPDATES | GFX_DEBUG_PIXMAPS | GFX_DEBUG_BASIC*/, - xlib_set_parameter, - xlib_init_specific, - xlib_init, - xlib_exit, - xlib_draw_line, -#ifdef HAVE_RENDER - xlib_draw_filled_rect_RENDER, -#else - xlib_draw_filled_rect, -#endif - xlib_register_pixmap, - xlib_unregister_pixmap, - xlib_draw_pixmap, - xlib_grab_pixmap, - xlib_update, - xlib_set_static_buffer, - xlib_set_pointer, - xlib_set_palette, - xlib_get_event, - xlib_usec_sleep, - NULL -}; - -#endif /* X_DISPLAY_MISSING */ diff --git a/engines/sci/gfx/drivers/scummvm_driver.cpp b/engines/sci/gfx/gfx_driver.cpp index a528673f6b..a528673f6b 100644 --- a/engines/sci/gfx/drivers/scummvm_driver.cpp +++ b/engines/sci/gfx/gfx_driver.cpp |