diff options
Diffstat (limited to 'sword2/driver/_mouse.cpp')
-rw-r--r-- | sword2/driver/_mouse.cpp | 618 |
1 files changed, 618 insertions, 0 deletions
diff --git a/sword2/driver/_mouse.cpp b/sword2/driver/_mouse.cpp new file mode 100644 index 0000000000..da2627a3f1 --- /dev/null +++ b/sword2/driver/_mouse.cpp @@ -0,0 +1,618 @@ +/* Copyright (C) 1994-2003 Revolution Software Ltd + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + */ + +//============================================================================= +// +// Filename : mouse.c +// Created : 17th September 1996 +// By : P.R.Porter +// +// Summary : This module holds the interface to the mouse.. +// +// Version Date By Description +// ------- --------- --- ----------------------------------------------- +// 1.0 18-Sep-96 PRP Initial mouse functions. Simple logging of +// previous 16 mouse events implemented. Mouse +// drawing is currently hard coded, but animations +// will be definable at a later date. +// +// 1.1 03-Oct-96 PRP Changed the mouse position so that mouse y of +// zero is the top left corner of the screen, and +// not the top left corner of the top menubar. +// Also, removed the x and y position from the +// mouse log. And changed the MouseEvent function +// so that it returns a pointer to _mouseEvent +// +// 1.2 04-Oct-96 PRP Put direct path in for ddraw.h +// +// 1.3 31-Oct-96 PRP Added code to draw the proper type of mouse +// sprite, which comprises of the internal +// function DrawMouse and globally available +// AnimateMouse and SetMouseAnim. +// +// 1.4 15-Nov-96 PRP Definition of menubar size is now obtained +// from menu.h +// +// 1.5 18-Nov-96 PRP Changed the direct draw interface to +// IDirectDraw2. +// +// 1.6 25-Nov-96 PRP Added functionality to set the luggage +// sprite. +// +// 1.7 06-Jan-97 PRP Changed the width and height of sprites +// to be signed. +// +// 1.8 14-Jan-97 JEL Reset mouse frame when new animation starts. +// +// 1.9 27-Jan-97 PRP Changed the mouse drawing routines to utilize +// directDraw surfaces and transparency blitting. +// +// 1.10 10-Feb-97 PRP Changed the directDraw error reporting so that +// it works properly. Also, created the mouse +// sprite depending upon whether the hardware can +// blt or not. +// +// 1.11 19-Mar-97 PRP Fixed a bug which was causing the mouse sprite +// to be freed up each frame and therefore +// decompressed and re-loaded each frame. +// +// 1.12 20-Mar-97 PRP Added a function to reset the render code when +// the control panel is entered. +// +// 1.13 09-Apr-97 PRP Made the mouse animation wrap back to the +// seventh frame. +// +// 1.14 10-Apr-97 PRP Added parameter to define whether mouse flashes +// or not. +// +// 1.15 23-Jul-97 JEL Added CheckForMouseEvents() to return no. of events outstanding +// +// +// Functions +// --------- +// +// -------------------------------------------------------------------------- +// +// _mouseEvent *MouseEvent(void) +// +// The address of a _mouseEvent pointer is passed in. If there is a mouse +// event in the queue, a the value of the mouse event pointer is set to the +// address of the event, otherwise, the mouse event pointer is set to NULL. +// +// -------------------------------------------------------------------------- +// +// int32 SetMouseAnim(uint8 *ma, int32 size) +// +// A pointer to a valid mouse animation is passed in, along with the size of +// the header plus sprite data. Remember to check that the function has +// successfully completed, as memory allocation is required. +// Pass NULL in to clear the mouse sprite. +// +// -------------------------------------------------------------------------- +// +// int32 SetLuggageAnim(uint8 *ma, int32 size) +// +// A pointer to a valid luggage animation is passed in, along with the size of +// the header plus sprite data. Remember to check that the function has +// successfully completed, as memory allocation is required. +// Pass NULL in to clear the luggage sprite. Luggage sprites are of the same +// format as mouse sprites. +// +// -------------------------------------------------------------------------- +// +// int32 AnimateMouse(void) +// +// This function animates the current mouse pointer. If no pointer is +// currently defined, an error code is returned. +// +//============================================================================= + + +#define WIN32_LEAN_AND_MEAN + +//#include <windows.h> +//#include <windowsx.h> + +//#include "ddraw.h" + +#include "driver96.h" + +#include "d_draw.h" +#include "render.h" +#include "menu.h" + + + +#define MAX_MOUSE_EVENTS 16 +#define MOUSEFLASHFRAME 6 + + +typedef struct +{ + uint8 runTimeComp; // type of runtime compression used for the frame data + uint8 noAnimFrames; // number of frames in the anim + int8 xHotSpot; + int8 yHotSpot; + uint8 mousew; + uint8 mouseh; +} _mouseAnim; + + +int16 mousex; +int16 mousey; + +static uint8 mouseBacklog = 0; +static uint8 mouseLogPos = 0; +static uint8 mouseFrame; +static uint8 luggageFrame = 0; +static uint8 *mouseSprite = NULL; +static _mouseAnim *mouseAnim = NULL; +static _mouseAnim *luggageAnim = NULL; +static _mouseEvent mouseLog[MAX_MOUSE_EVENTS]; +static int32 *mouseOffsets; +static int32 *luggageOffset; +//static LPDIRECTDRAWSURFACE *mouseSurfaces; +//static LPDIRECTDRAWSURFACE luggageSurface = NULL; + + + + + + + +void ResetRenderEngine(void) + +{ + + memset(myScreenBuffer, 0, RENDERWIDE * RENDERDEEP); + parallaxScrollx = 0; + parallaxScrolly = 0; + scrollx = 0; + scrolly = 0; + +} + + + + +// -------------------------------------------------------------------------- +// Logs the mouse button event passed in buttons. The button events are +// defined as RD_LEFTBUTTONDOWN, RD_LEFTBUTTONUP, RD_RIGHTBUTTONDOWN and +// RD_RIGHTBUTTONUP. +// -------------------------------------------------------------------------- +void LogMouseEvent(uint16 buttons) + +{ + + _mouseEvent *me; + + + if (mouseBacklog == MAX_MOUSE_EVENTS-1) // We need to leave the one which is + { // the current event alone! + return; + } + + me = &mouseLog[(mouseBacklog + mouseLogPos) % MAX_MOUSE_EVENTS]; + me->buttons = buttons; + mouseBacklog += 1; + +} + + + + + + +int32 DecompressMouse(uint8 *decomp, uint8 *comp, int32 size) + +{ + + int32 i = 0; + + while (i < size) + { + if (*comp > 183) + { + *decomp++ = *comp++; + i += 1; + } + else + { + memset(decomp, 0, *comp); + decomp += *comp; + i += *comp++; + } + } + return(RD_OK); +} + + + +// -------------------------------------------------------------------------- +// Draws the mouse sprite to the back buffer. +// -------------------------------------------------------------------------- +int32 DrawMouse(void) + +{ + warning("stub DrawMouse"); +/* + uint8 *src, *dst; + int16 i; + int16 xoff=0, yoff=0; + uint8 *decompSprite; + DDSURFACEDESC ddsd; + HRESULT hr; + RECT rs, rd; + + + + if (luggageAnim) + { + + if (luggageSurface == NULL) + { + // Create the luggage surface. + memset(&ddsd, 0, sizeof(DDSURFACEDESC)); + ddsd.dwSize = sizeof(DDSURFACEDESC); + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + if (dxHalCaps & RDCAPS_SRCBLTCKEY) + ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; + else + ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + + ddsd.dwWidth = luggageAnim->mousew; + ddsd.dwHeight = luggageAnim->mouseh; + hr = IDirectDraw2_CreateSurface(lpDD2, &ddsd, &luggageSurface, NULL); + if (hr != DD_OK) + { + if (hr == DDERR_OUTOFVIDEOMEMORY) + { + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + hr = IDirectDraw2_CreateSurface(lpDD2, &ddsd, &luggageSurface, NULL); + } + if (hr != DD_OK) + { + DirectDrawError("Cannot create mouse surface", hr); + return(hr); + } + } + // Set the surface blt source colour key + hr = IDirectDrawSurface2_SetColorKey(luggageSurface, DDCKEY_SRCBLT, &blackColorKey); + + // Copy the data into the surfaces. + decompSprite = (uint8 *) malloc(luggageAnim->mousew * luggageAnim->mouseh); + if (decompSprite == NULL) + return(RDERR_OUTOFMEMORY); +// DecompressMouse(decompSprite, (uint8 *) luggageAnim + *mouseOffsets, luggageAnim->mousew * luggageAnim->mouseh); + DecompressMouse(decompSprite, (uint8 *) luggageAnim + *luggageOffset, luggageAnim->mousew * luggageAnim->mouseh); + memset(&ddsd, 0, sizeof(DDSURFACEDESC)); + ddsd.dwSize = sizeof(DDSURFACEDESC); + hr = IDirectDrawSurface2_Lock(luggageSurface, NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr != DD_OK) + { + IDirectDrawSurface2_Restore(luggageSurface); + hr = IDirectDrawSurface2_Lock(luggageSurface, NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr != DD_OK) + { + DirectDrawError("Unable to lock luggage surface", hr); + return(hr); + } + } + dst = ddsd.lpSurface; + src = decompSprite; + for (i=0; i<luggageAnim->mouseh; i++) + { + memcpy(dst, src, luggageAnim->mousew); + dst += ddsd.lPitch; + src += luggageAnim->mousew; + } + IDirectDrawSurface2_Unlock(luggageSurface, ddsd.lpSurface); + free(decompSprite); + } + + + rd.top = mousey + MENUDEEP - luggageAnim->yHotSpot; + rd.bottom = rd.top + luggageAnim->mouseh; + rd.left = mousex - luggageAnim->xHotSpot; + rd.right = rd.left + luggageAnim->mousew; + + rs.left = 0; + rs.right = luggageAnim->mousew; + rs.top = 0; + rs.bottom = luggageAnim->mouseh; + + if (rd.left < 0) + { + rs.left = 0 - rd.left; + rd.left = 0; + } + if (rd.top < 0) + { + rs.top = 0 - rd.top; + rd.top = 0; + } + if (rd.right > RENDERWIDE) + { + rs.right -= (rd.right - RENDERWIDE); + rd.right = RENDERWIDE; + } + if (rd.bottom > ALIGNRENDERDEEP) + { + rs.bottom -= (rd.bottom - ALIGNRENDERDEEP); + rd.bottom = ALIGNRENDERDEEP; + } + + hr = IDirectDrawSurface2_Blt(lpBackBuffer, &rd, luggageSurface, &rs, DDBLT_WAIT | DDBLT_KEYSRC, NULL); + if (hr = DDERR_SURFACELOST) + { + IDirectDrawSurface2_Release(luggageSurface); + luggageSurface = NULL; + } + + } + + if (mouseAnim == NULL) + { + return(RD_OK); + } + + + // Decompress the mouse sprite onto the directDraw surface, if it is not + // there already. + if (*(mouseSurfaces + mouseFrame) == NULL) + { + + // Create the mouse surface. + memset(&ddsd, 0, sizeof(DDSURFACEDESC)); + ddsd.dwSize = sizeof(DDSURFACEDESC); + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + if (dxHalCaps & RDCAPS_SRCBLTCKEY) + ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; + else + ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + + ddsd.dwWidth = mouseAnim->mousew; + ddsd.dwHeight = mouseAnim->mouseh; + hr = IDirectDraw2_CreateSurface(lpDD2, &ddsd, mouseSurfaces + mouseFrame, NULL); + if (hr != DD_OK) + { + if (hr == DDERR_OUTOFVIDEOMEMORY) + { + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + hr = IDirectDraw2_CreateSurface(lpDD2, &ddsd, mouseSurfaces + mouseFrame, NULL); + } + if (hr != DD_OK) + { + DirectDrawError("Cannot create mouse surface", hr); + return(hr); + } + } + // Set the surface blt source colour key + hr = IDirectDrawSurface2_SetColorKey(*(mouseSurfaces + mouseFrame), DDCKEY_SRCBLT, &blackColorKey); + + // Copy the data into the surfaces. + decompSprite = (uint8 *) malloc(mouseAnim->mousew * mouseAnim->mouseh); + if (decompSprite == NULL) + return(RDERR_OUTOFMEMORY); + DecompressMouse(decompSprite, mouseSprite, mouseAnim->mousew * mouseAnim->mouseh); + memset(&ddsd, 0, sizeof(DDSURFACEDESC)); + ddsd.dwSize = sizeof(DDSURFACEDESC); + hr = IDirectDrawSurface2_Lock(*(mouseSurfaces + mouseFrame), NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr != DD_OK) + { + IDirectDrawSurface2_Restore(*(mouseSurfaces + mouseFrame)); + hr = IDirectDrawSurface2_Lock(*(mouseSurfaces + mouseFrame), NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr != DD_OK) + { + DirectDrawError("Cannot lock mouse surface", hr); + return(hr); + } + } + dst = ddsd.lpSurface; + src = decompSprite; + for (i=0; i<mouseAnim->mouseh; i++) + { + memcpy(dst, src, mouseAnim->mousew); + dst += ddsd.lPitch; + src += mouseAnim->mousew; + } + IDirectDrawSurface2_Unlock(*(mouseSurfaces + mouseFrame), ddsd.lpSurface); + free(decompSprite); + } + + + rd.top = mousey + MENUDEEP - mouseAnim->yHotSpot; + rd.bottom = rd.top + mouseAnim->mouseh; + rd.left = mousex - mouseAnim->xHotSpot; + rd.right = rd.left + mouseAnim->mousew; + + rs.left = 0; + rs.right = mouseAnim->mousew; + rs.top = 0; + rs.bottom = mouseAnim->mouseh; + + if (rd.left < 0) + { + rs.left = 0 - rd.left; + rd.left = 0; + } + if (rd.top < 0) + { + rs.top = 0 - rd.top; + rd.top = 0; + } + if (rd.right > RENDERWIDE) + { + rs.right -= (rd.right - RENDERWIDE); + rd.right = RENDERWIDE; + } + if (rd.bottom > ALIGNRENDERDEEP) + { + rs.bottom -= (rd.bottom - ALIGNRENDERDEEP); + rd.bottom = ALIGNRENDERDEEP; + } + + hr = IDirectDrawSurface2_Blt(lpBackBuffer, &rd, *(mouseSurfaces + mouseFrame), &rs, DDBLT_WAIT | DDBLT_KEYSRC, NULL); + if (hr == DDERR_SURFACELOST) + { + IDirectDrawSurface2_Release(*(mouseSurfaces + mouseFrame)); + *(mouseSurfaces + mouseFrame) = NULL; + } +*/ + return(RD_OK); + +} + + + +_mouseEvent *MouseEvent(void) + +{ + _mouseEvent *me; + + if (mouseBacklog) + { + me = &mouseLog[mouseLogPos]; + if (++mouseLogPos == MAX_MOUSE_EVENTS) + { + mouseLogPos = 0; + } + mouseBacklog -= 1; + return(me); + } + + return(NULL); + +} + + +uint8 CheckForMouseEvents(void) // (James23july97) +{ + return (mouseBacklog); // return the number of mouse events waiting +} + + +int32 AnimateMouse(void) + +{ + if (mouseAnim) + { + if (++mouseFrame == mouseAnim->noAnimFrames) + { + mouseFrame = MOUSEFLASHFRAME; + } + mouseSprite = (uint8 *) mouseAnim + *(mouseOffsets+mouseFrame); + } + else + { + return(RDERR_UNKNOWN); + } + + return(RD_OK); + +} + + + +int32 SetMouseAnim(uint8 *ma, int32 size, int32 mouseFlash) + +{ + warning("stub SetMouseAnim( %d, %d )", size, mouseFlash); +/* + int32 i; + + if (mouseAnim) + { + for (i=0; i<mouseAnim->noAnimFrames; i++) + { + if (*(mouseSurfaces + i)) + { + IDirectDrawSurface2_Release(*(mouseSurfaces + i)); + *(mouseSurfaces + i) = NULL; + } + } + + free(mouseAnim); + mouseAnim = NULL; + free(mouseSurfaces); + mouseSurfaces = NULL; + } + + if (ma) + { + if (mouseFlash == RDMOUSE_FLASH) + mouseFrame = 0; + else + mouseFrame = MOUSEFLASHFRAME; + mouseAnim = malloc(size); + if (mouseAnim == NULL) + { + return(RDERR_OUTOFMEMORY); + } + else + { + memcpy((uint8 *) mouseAnim, ma, size); + mouseOffsets = (int32 *) ((uint8 *) mouseAnim + sizeof(_mouseAnim)); + AnimateMouse(); + mouseSurfaces = (LPDIRECTDRAWSURFACE *) malloc(mouseAnim->noAnimFrames * sizeof(LPDIRECTDRAWSURFACE)); + if (mouseSurfaces == NULL) + return(RDERR_OUTOFMEMORY); + memset(mouseSurfaces, 0, sizeof(LPDIRECTDRAWSURFACE) * mouseAnim->noAnimFrames); + } + } +*/ + return(RD_OK); + +} + + +int32 SetLuggageAnim(uint8 *ma, int32 size) + +{ + warning("stub SetLugggeAnim"); +/* + + if (luggageAnim) + { + free(luggageAnim); + luggageAnim = NULL; + } + + if (ma) + { + luggageAnim = malloc(size); + if (luggageAnim == NULL) + { + return(RDERR_OUTOFMEMORY); + } + else + { + memcpy((uint8 *) luggageAnim, ma, size); + luggageOffset = (int32 *) ((uint8 *) luggageAnim + sizeof(_mouseAnim)); + AnimateMouse(); + } + } +*/ + return(RD_OK); + +} + + |