diff options
Diffstat (limited to 'engines/sci/gfx/drivers/dc_driver.c')
-rw-r--r-- | engines/sci/gfx/drivers/dc_driver.c | 1267 |
1 files changed, 0 insertions, 1267 deletions
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 -}; |