scummvm/sword2/driver/_mouse.cpp
Jonathan Gray a05c4bda0f -Werror cleanup
svn-id: r9230
2003-07-28 07:22:40 +00:00

620 lines
15 KiB
C++

/* 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 "stdafx.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);
}