Let sprite and rectangle cursor be handled independently from other sources

This commit is contained in:
stephanr 2001-07-05 23:48:28 +00:00
parent c9988c51ac
commit 823e1e3938
10 changed files with 570 additions and 664 deletions

View file

@ -1,6 +1,6 @@
## ___________ _________ _____ __
## \_ _____/______ ____ ____ \_ ___ \____________ _/ ____\/ |_
## | __) \_ __ \_/ __ \_/ __ \/ \ \/\_ __ \__ \\ __\\ __\
## | __) \_ __ \_/ __ \_/ __ \/ \ \/\_ __ \__ \ __\ __\
## | \ | | \/\ ___/\ ___/\ \____| | \// __ \| | | |
## \___ / |__| \___ >\___ >\______ /|__| (____ /__| |__|
## \/ \/ \/ \/ \/
@ -8,241 +8,70 @@
## T H E W A R B E G I N S
## FreeCraft - A free fantasy real time strategy game engine
##
## Rules.make - Make RULES (GNU MAKE) (included from Makefile).
##
## (c) Copyright 1998-2001 by Lutz Sammer
##
## FreeCraft 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.
##
## FreeCraft 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.
##
## $Id$
##
############################################################################
# Configurable:
# Choose what you want to include and the correct
# version. Minimal is now the default.
############################################################################
#------------------------------------------------------------------------------
# Uncomment next to add threaded sound support
# You should have a thread safe X11 (libc6 or glibc)
# Any modern linux distribution are thread safe.
# Don't enable, if you use SDL sound support.
#THREAD = -D_REENTRANT -DUSE_THREAD
#THREADLIB = -lpthread
#------------------------------------------------------------------------------
# Video driver part
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# SDL - Simple DirectMedia Layer configuration (any >=1.0.0)
SDL_CFLAGS = $(shell sdl-config --cflags)
SDLLIB = $(shell sdl-config --static-libs)
#SDLLIB = $(shell sdl-config --libs)
# Without SDL Sound (only not win32)
#SDL = -DUSE_SDL $(SDL_CFLAGS)
# With SDL Sound
SDL = -DUSE_SDL -DUSE_SDLA $(SDL_CFLAGS)
#------------------------------------------------------------------------------
# Uncomment the next for the normal X11 support.
VIDEO = -DUSE_X11
VIDEOLIB = -lXext -lX11 -ldl
#------------------------------------------------------------------------------
# Uncomment th next to get svgalib support.
#VIDEO = -DUSE_SVGALIB
#VIDEOLIB = -lvga -lm -ldl
#------------------------------------------------------------------------------
# Uncomment one of the next for the SDL support.
# Uncomment the next for the generic SDL support.
#VIDEO = $(SDL)
#VIDEOLIB = $(SDLLIB)
# Uncomment the next for the SDL X11/SVGALIB support.
# (sdl-config --static-libs didn't work correct.)
VIDEO = $(SDL)
VIDEOLIB = $(SDLLIB) -lXext -lX11 -lXxf86dga -lXxf86vm -lvga -lvgagl -ldl -lesd -lm -lslang -lgpm
# Uncomment the next for the win32/cygwin support. (not working?)
#VIDEO = -DUSE_WIN32 $(SDL)
#VIDEOLIB = $(SDLLIB)
# Uncomment the next for the win32/mingw32 support.
#VIDEO = -DUSE_WIN32 $(SDL)
#VIDEOLIB = $(SDLLIB) -lwsock32 -Wl,--stack,33554432
# Uncomment the next for the BeOS SDL support.
#VIDEO = -DUSE_BEOS $(SDL)
#VIDEOLIB = $(SDLLIB)
#------------------------------------------------------------------------------
# Sound driver part
#------------------------------------------------------------------------------
# See above the USE_SDLA option.
# Comment next if you want to remove sound support.
DSOUND = -DWITH_SOUND
#------------------------------------------------------------------------------
# File I/O part
#------------------------------------------------------------------------------
# Choose which compress you like
# The win32 port didn't support BZ2LIB
# None
#ZDEFS =
#ZLIBS =
# GZ compression
ZDEFS = -DUSE_ZLIB
ZLIBS = -lz
# BZ2 compression
#ZDEFS = -DUSE_BZ2LIB
#ZLIBS = -lbz2
# GZ + BZ2 compression
ZDEFS = -DUSE_ZLIB -DUSE_BZ2LIB
ZLIBS = -lz -lbz2
#------------------------------------------------------------------------------
# May be required on some distributions for libpng and libz!
# extra linker flags and include directory
# -L/usr/lib
XLDFLAGS = -L/usr/X11R6/lib -L/usr/local/lib \
-L$(TOPDIR)/libpng-1.0.5 -L$(TOPDIR)/zlib-1.1.3
XIFLAGS = -I/usr/X11R6/include -I/usr/local/include \
-I$(TOPDIR)/libpng-1.0.5 -I$(TOPDIR)/zlib-1.1.3
#------------------------------------------------------------------------------
# Support for SIOD (scheme interpreter)
# C C L - Craft Configuration Language
CCL = -DUSE_CCL
CCLLIB = -lm
#------------------------------------------------------------------------------
# Uncomment next to profile
#PROFILE= -pg
# Compile Version
VERSION= '-DVERSION="1.17pre1-build14"'
############################################################################
# below this, nothing should be changed!
# Libraries needed to build tools
TOOLLIBS=$(XLDFLAGS) -lpng -lz -lm $(THREADLIB)
# Libraries needed to build freecraft
CLONELIBS=$(XLDFLAGS) -lpng -lz -lm \
$(THREADLIB) $(CCLLIB) $(VIDEOLIB) $(ZLIBS)
DISTLIST=$(TOPDIR)/distlist
TAGS=$(TOPDIR)/src/tags
# LINUX
OUTFILE=$(TOPDIR)/freecraft
ARCH=linux
OE=o
EXE=
# WIN32
#OUTFILE=$(TOPDIR)/freecraft$(EXE)
#ARCH=win32
#OE=o
#EXE=.exe
## architecture-dependant objects
#ARCHOBJS=stdmman.$(OE) svgalib.$(OE) unix_lib.$(OE) bitm_lnx.$(OE)
## include flags
IFLAGS= -I$(TOPDIR)/src/include $(XIFLAGS)
## define flags
DEBUG= -DDEBUG -DREFS_DEBUG # -DFLAG_DEBUG
##
## There are some still not well tested code parts or branches.
## UNITS_ON_MAP: Faster lookup of units
## NEW_MAPDRAW: Stephans new map draw code
## NEW_AI: New better improved AI code
## This aren't working:
## NEW_FOW: New fog of war code, should work correct
## NEW_SHIPS: New correct ship movement.
## NEW_NETMENUS: Include new network menues.
DFLAGS= $(THREAD) $(CCL) $(VERSION) $(VIDEO) $(ZDEFS) $(DSOUND) $(DEBUG) \
-DHAVE_EXPANSION -DUNIT_ON_MAP -DNEW_AI -D_NEW_NETMENUS -DBPP8_IRGB # -DNEW_MAPDRAW=1 -DNEW_FOW -DNEW_SHIPS
## choose optimise level
#CFLAGS=-g -O0 $(PROFILE) -pipe -Wcast-align -Wall -Werror $(IFLAGS) $(DFLAGS)
#CFLAGS=-g -O1 $(PROFILE) -pipe -Wcast-align -Wall -Werror $(IFLAGS) $(DFLAGS)
CFLAGS=-g -O2 $(PROFILE) -pipe -Wcast-align -Wall -Werror $(IFLAGS) $(DFLAGS)
#CFLAGS=-g -O3 $(PROFILE) -pipe -Wcast-align -Wall -Werror $(IFLAGS) $(DFLAGS)
#CFLAGS=-g -O3 $(PROFILE) -pipe -Wcast-align -Wall $(IFLAGS) $(DFLAGS)
#CFLAGS=-g -O6 -pipe -fconserve-space -fexpensive-optimizations -ffast-math $(IFLAGS) $(DFLAGS)
#-- Production
#CFLAGS=-O6 -pipe -fomit-frame-pointer -fconserve-space -fexpensive-optimizations -ffast-math $(IFLAGS) $(DFLAGS)
#CFLAGS=-O6 -pipe -fomit-frame-pointer -fconserve-space -fexpensive-optimizations -ffast-math $(IFLAGS) $(DFLAGS) -static
# GCC 3.0
#CFLAGS=-g -O3 $(PROFILE) -pipe -Wcast-align -W -Wredundant-decls -Wno-sign-compare -Wall -Wno-comment $(IFLAGS) $(DFLAGS)
#CC=gcc-3.0
CC=cc
#CC=gcc272
# Compile commands
CC=gcc
RM=rm -f
MAKE=make
# TAGS 5.0
CTAGSFLAGS=--c-types=defmpstuvx -a -f
#CTAGSFLAGS=-i defmpstuvFS -a -f
#CTAGSFLAGS=-i defptvS -a -f
# Use SIOD support
CCL = -DUSE_CCL
CCLLIB = -lm
#
# Locks versions with symbolic name
#
# Video support
VIDEO = -DUSE_X11
VIDEOLIB = -lXext -lX11 -ldl
# Sound support
DSOUND = -DWITH_SOUND
# Compression support
ZDEFS = -DUSE_ZLIB -DUSE_BZ2LIB
ZLIBS = -lz -lbz2
XLDFLAGS = -L/usr/X11R6/lib -L/usr/local/lib
XIFLAGS = -I/usr/X11R6/include -I/usr/local/include
#####################################################################
# Don't change anything below here unless you know what you're doing!
VERSION= '-DVERSION="1.17pre1-build14"'
PROFILE=
TOOLLIBS=$(XLDFLAGS) -lpng -lz -lm $(THREADLIB)
CLONELIBS=$(XLDFLAGS) -lpng -lz -lm \
$(THREADLIB) $(CCLLIB) $(VIDEOLIB) $(ZLIBS)
DISTLIST=$(TOPDIR)/distlist
TAGS=$(TOPDIR)/src/tags
# Linux
EXE=
OUTFILE=$(TOPDIR)/freecraft
ARCH=linux
OE=o
#ARCHOBJS=stdmman.$(OE) svgalib.$(OE) unix_lib.$(OE) bitm_lnx.$(OE)
IFLAGS= -I$(TOPDIR)/src/include $(XIFLAGS)
DFLAGS= $(THREAD) $(CCL) $(VERSION) \
$(VIDEO) $(ZDEFS) $(DSOUND) \
$(DEBUG)
CFLAGS=-O2 -pipe -fomit-frame-pointer -fconserve-space -fexpensive-optimizations -ffast-math $(IFLAGS) $(DFLAGS) -DUNIT_ON_MAP -DNEW_AI
CFLAGS=-g -pipe -fconserve-space $(IFLAGS) $(DFLAGS) -DUNIT_ON_MAP -DNEW_AI
CTAGSFLAGS=-i defptvS -a -f
# Locks versions with a symbolic name
LOCKVER= rcs -q -n$(NAME)
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
@ar cru $(TOPDIR)/src/libclone.a $@
#------------
# Source code documentation
#
# Source code documentation
DOXYGEN= doxygen
DOCIFY= docify
DOCPP= doc++
# Still didn't work
#DOCIFY= /root/doc++-3.4.2/src/docify
#DOCPP= /root/doc++-3.4.2/src/doc++
%.doc: %.c
@$(TOPDIR)/tools/aledoc $< | $(DOCIFY) > $*-c.doc 2>/dev/null
%.doc: %.h
@$(TOPDIR)/tools/aledoc $< | $(DOCIFY) > $*-h.doc 2>/dev/null

View file

@ -168,11 +168,6 @@ extern int CursorY; /// cursor position on screen Y
extern int CursorStartX; /// rectangle started on screen X
extern int CursorStartY; /// rectangle started on screen Y
extern int OldCursorX; /// saved cursor position on screen X
extern int OldCursorY; /// saved cursor position on screen Y
extern int OldCursorW; /// saved cursor width in pixel
extern int OldCursorH; /// saved cursor height in pixel
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
@ -183,20 +178,14 @@ extern void LoadCursors(const char* racename);
/// Cursor-type by identifier
extern CursorType* CursorTypeByIdent(const char* ident);
/// Draw cursor on screen in position x,y
extern void DrawCursor(const CursorType* type,int x,int y,int frame);
/// Destroy the cursor background (for menu use!)
extern void DestroyCursorBackground(void);
/// Hide the cursor
extern void HideCursor(void);
/// Draw any cursor
extern void DrawAnyCursor(void);
/// Hide any cursor
extern int HideAnyCursor(void);
extern void HideAnyCursor(void);
/// Invalidate given area and check if cursor won't need any
extern void InvalidateAreaAndCheckCursor( int x, int y, int w, int h );
/// Invalidate (remaining) cursor areas
extern void InvalidateCursorAreas(void);
/// Initialize the cursor module
extern void InitCursors(void);

View file

@ -985,6 +985,7 @@ extern void VideoDrawTransRectangleClip(SysColors color,int x,int y
/// Does ColorCycling..
extern void (*ColorCycle)(void);
/*----------------------------------------------------------------------------
-- Macros
----------------------------------------------------------------------------*/
@ -1054,6 +1055,7 @@ extern void (*ColorCycle)(void);
#define VideoSaveFree(o) \
do { if( (o) ) ((o)->Type->Free)((o)); } while( 0 )
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/

View file

@ -203,14 +203,13 @@ global void DebugTestDisplay(void)
*/
global void UpdateDisplay(void)
{
int update_old_cursor;
if (!MustRedraw) {
return;
}
VideoLockScreen(); // prepare video write
if (MustRedraw) {
update_old_cursor=HideAnyCursor(); // remove cursor
} else {
update_old_cursor = 0;
}
HideAnyCursor(); // remove cursor (when available)
if( MustRedraw&RedrawMap ) {
if (InterfaceState == IfaceStateNormal) {
@ -311,84 +310,72 @@ global void UpdateDisplay(void)
DrawMenu(CurrentMenu);
}
// FIXME: this could be written better, less drawing
if( update_old_cursor && MustRedraw!=-1 ) {
// Draw restored area only if not same.
if( OldCursorX!=(CursorX-GameCursor->HotX)
|| OldCursorY!=(CursorY-GameCursor->HotY)
|| OldCursorW!=VideoGraphicWidth(GameCursor->Sprite)
|| OldCursorH!=VideoGraphicHeight(GameCursor->Sprite) ) {
InvalidateArea(OldCursorX,OldCursorY,OldCursorW,OldCursorH);
}
}
if (!MustRedraw) {
VideoUnlockScreen(); // End write access
return;
}
DrawAnyCursor();
VideoUnlockScreen(); // End write access
//
// Update changes to X11.
//
if( MustRedraw==-1 ) {
Invalidate();
// refresh entire screen, so no further invalidate needed
InvalidateAreaAndCheckCursor(0,0,VideoWidth,VideoHeight);
} else {
if( MustRedraw&RedrawMap ) {
// FIXME: split into small parts see RedrawTile and RedrawRow
InvalidateArea(TheUI.MapX,TheUI.MapY
InvalidateAreaAndCheckCursor(
TheUI.MapX,TheUI.MapY
,TheUI.MapEndX-TheUI.MapX+1,TheUI.MapEndY-TheUI.MapY+1);
}
if( (MustRedraw&RedrawFiller1) && TheUI.Filler1.Graphic ) {
InvalidateArea(TheUI.Filler1X,TheUI.Filler1Y
InvalidateAreaAndCheckCursor(
TheUI.Filler1X,TheUI.Filler1Y
,TheUI.Filler1.Graphic->Width
,TheUI.Filler1.Graphic->Height);
}
if( MustRedraw&RedrawMenuButton ) {
InvalidateArea(TheUI.MenuButtonX,TheUI.MenuButtonY
if(MustRedraw&RedrawMenuButton ) {
InvalidateAreaAndCheckCursor(
TheUI.MenuButtonX,TheUI.MenuButtonY
,TheUI.MenuButton.Graphic->Width
,TheUI.MenuButton.Graphic->Height);
}
if( MustRedraw&RedrawMinimapBorder ) {
InvalidateArea(TheUI.MinimapX,TheUI.MinimapY
InvalidateAreaAndCheckCursor(
TheUI.MinimapX,TheUI.MinimapY
,TheUI.Minimap.Graphic->Width,TheUI.Minimap.Graphic->Height);
} else if( (MustRedraw&RedrawMinimap)
|| (MustRedraw&RedrawMinimapCursor) ) {
// FIXME: Redraws too much of the minimap
InvalidateArea(TheUI.MinimapX+24,TheUI.MinimapY+2
InvalidateAreaAndCheckCursor(
TheUI.MinimapX+24,TheUI.MinimapY+2
,MINIMAP_W,MINIMAP_H);
}
if( MustRedraw&RedrawInfoPanel ) {
InvalidateArea(TheUI.InfoPanelX,TheUI.InfoPanelY
InvalidateAreaAndCheckCursor(
TheUI.InfoPanelX,TheUI.InfoPanelY
,TheUI.InfoPanelW,TheUI.InfoPanelH);
}
if( MustRedraw&RedrawButtonPanel ) {
InvalidateArea(TheUI.ButtonPanelX,TheUI.ButtonPanelY
InvalidateAreaAndCheckCursor(
TheUI.ButtonPanelX,TheUI.ButtonPanelY
,TheUI.ButtonPanel.Graphic->Width
,TheUI.ButtonPanel.Graphic->Height);
}
if( MustRedraw&RedrawResources ) {
InvalidateArea(TheUI.ResourceX,TheUI.ResourceY
InvalidateAreaAndCheckCursor(
TheUI.ResourceX,TheUI.ResourceY
,TheUI.Resource.Graphic->Width
,TheUI.Resource.Graphic->Height);
}
if( MustRedraw&RedrawStatusLine || MustRedraw&RedrawCosts ) {
InvalidateArea(TheUI.StatusLineX,TheUI.StatusLineY
InvalidateAreaAndCheckCursor(
TheUI.StatusLineX,TheUI.StatusLineY
,TheUI.StatusLine.Graphic->Width
,TheUI.StatusLine.Graphic->Height);
}
/* if (MustRedraw) */ {
// FIXME: JOHNS: That didn't work: if (MustRedraw&RedrawCursor)
DebugLevel3Fn("%d,%d,%d,%d\n",CursorX-GameCursor->HotX
,CursorY-GameCursor->HotY
,VideoGraphicWidth(GameCursor->Sprite)
,VideoGraphicHeight(GameCursor->Sprite));
InvalidateArea(CursorX-GameCursor->HotX,CursorY-GameCursor->HotY
,VideoGraphicWidth(GameCursor->Sprite)
,VideoGraphicHeight(GameCursor->Sprite));
}
// And now as very last.. checking if the cursor needs a refresh
InvalidateCursorAreas();
}
}

View file

@ -1160,8 +1160,9 @@ global void DrawMenu(int MenuId)
*/
local void StartMenusSetBackground(Menuitem *mi __attribute__((unused)))
{
HideCursor();
DestroyCursorBackground();
//Doesn't seem to be needed
//HideAnyCursor();
// FIXME: make this configurable from CCL.
DisplayPicture("graphics/ui/Menu background without title.png");
}
@ -1256,7 +1257,6 @@ local void MultiScenSelectMenu(void)
local void SinglePlayerGameMenu(void)
{
DestroyCursorBackground();
GuiGameStarted = 0;
ProcessMenu(MENU_CUSTOM_GAME_SETUP, 1);
if (GuiGameStarted) {
@ -1312,7 +1312,6 @@ local void JoinNetGameMenu(void)
EnterServerIPMenuItems[1].d.input.maxch = 24;
EnterServerIPMenuItems[2].flags |= MenuButtonDisabled;
ProcessMenu(MENU_NET_ENTER_SERVER_IP, 1);
DestroyCursorBackground();
StartMenusSetBackground(NULL);
if (EnterServerIPMenuItems[1].d.input.nch == 0) {
return;
@ -1330,7 +1329,6 @@ local void JoinNetGameMenu(void)
local void NetConnectingCancel(void)
{
DestroyCursorBackground();
StartMenusSetBackground(NULL);
NetworkExitClientConnect();
NetLocalState = ccs_unreachable; // Trigger TerminateNetConnect() to call us again and end the menu
@ -1345,7 +1343,6 @@ local void TerminateNetConnect(void)
}
DebugLevel1Fn("NetLocalState %d\n", NetLocalState);
NetConnectRunning = 2;
DestroyCursorBackground();
GuiGameStarted = 0;
ProcessMenu(MENU_NET_MULTI_CLIENT, 1);
if (GuiGameStarted) {
@ -1357,7 +1354,6 @@ local void TerminateNetConnect(void)
local void CreateNetGameMenu(void)
{
DestroyCursorBackground();
GuiGameStarted = 0;
ProcessMenu(MENU_NET_MULTI_SETUP, 1);
if (GuiGameStarted) {
@ -1377,7 +1373,6 @@ local void MultiPlayerGameMenu(void)
EnterNameMenuItems[1].d.input.maxch = 15;
EnterNameMenuItems[2].flags &= ~MenuButtonDisabled;
ProcessMenu(MENU_ENTER_NAME, 1);
DestroyCursorBackground();
StartMenusSetBackground(NULL);
if (EnterNameMenuItems[1].d.input.nch == 0) {
return;
@ -1735,7 +1730,6 @@ local void ScenSelectCancel(void)
local void GameCancel(void)
{
DestroyCursorBackground();
StartMenusSetBackground(NULL);
FreeMapInfo(ScenSelectPudInfo);
ScenSelectPudInfo = NULL;
@ -2750,8 +2744,7 @@ global void ProcessMenu(int MenuId, int Loop)
}
InterfaceState = IfaceStateMenu;
HideCursor();
DestroyCursorBackground();
HideAnyCursor();
MustRedraw |= RedrawCursor;
CursorState = CursorStatePoint;
GameCursor = TheUI.Point.Cursor;

View file

@ -45,10 +45,17 @@
#include "interface.h"
#include "ui.h"
#include "intern_video.h"
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
/**
** Number of bytes needed for current video-mode
*/
local int memsize;
/**
** Cursor-type type definition
*/
@ -64,31 +71,82 @@ global CursorType* Cursors;
global CursorStates CursorState;/// current cursor state (point,...)
global int CursorAction; /// action for selection
global int CursorValue; /// value for CursorAction (spell type f.e.)
global UnitType* CursorBuilding;/// building cursor
global CursorType* GameCursor; /// current shown cursor-type
//Event changed mouse position, can alter at any moment
global int CursorX; /// cursor position on screen X
global int CursorY; /// cursor position on screen Y
global int CursorStartX; /// rectangle started on screen X
global int CursorStartY; /// rectangle started on screen Y
global int OldCursorX; /// saved cursor position on screen X
global int OldCursorY; /// saved cursor position on screen Y
global int OldCursorW; /// saved cursor width in pixel
global int OldCursorH; /// saved cursor height in pixel
local int OldCursorSize; /// size of saved cursor image
local void* OldCursorImage; /// background saved behind cursor
local int OldCursorRectangleX; /// saved cursor position on screen X
local int OldCursorRectangleY; /// saved cursor position on screen Y
local int OldCursorRectangleW; /// saved cursor width in pixel
local int OldCursorRectangleH; /// saved cursor height in pixel
local void* OldCursorRectangle; /// background saved behind rectangle
/*--- DRAW BUILDING CURSOR ------------------------------------------------*/
local int BuildingCursor=0; /// Flag (0/1): last cursor was building
// area of tiles covered by building cursor (SX,SY;EX,EY)
local int BuildingCursorSX; /// FIXME: docu
local int BuildingCursorSY; /// FIXME: docu
local int BuildingCursorEX; /// FIXME: docu
local int BuildingCursorEY; /// FIXME: docu
global UnitType* CursorBuilding;/// building cursor
/*--- DRAW SPRITE CURSOR ---------------------------------------------------*/
// Saved area after draw cursor, needed later to hide it again
// (OldCursorW!=0 denotes it's defined)
local int OldCursorInvalidate=0;/// flag (0/1): if cursor need invalidate
local int OldCursorX; /// saved cursor position on screen X
local int OldCursorY; /// saved cursor position on screen Y
local int OldCursorW=0; /// saved cursor width in pixel
local int OldCursorH; /// saved cursor height in pixel
global CursorType* GameCursor; /// current shown cursor-type
// Area which is already hidden, but needed for invalidate
// (HiddenCursorW!=0 denotes it's defined)
local int HiddenCursorX; /// saved cursor position on screen X
local int HiddenCursorY; /// saved cursor position on screen Y
local int HiddenCursorW=0; /// saved cursor width in pixel
local int HiddenCursorH; /// saved cursor height in pixel
/// Memory re-use, so can be defined although no save present!
local unsigned int OldCursorSize; /// size of saved cursor image
local void* OldCursorImage; /// background saved behind cursor
/// Function pointer: Save background behind cursor
local void (*SaveCursorBackground)(int,int,int,int);
/**
** Function pointer: Save 2D image behind sprite cursor
**
** @param x Screen X pixels coordinate for left-top corner.
** @param y Screen Y pixels coordinate for left-top corner.
** @param w Width in pixels for image starting at left-top.
** @param h Height in pixels for image starting at left-top.
**
** @note the complete image should be in Screen (no clipping) and
** non-empty
** ( x>=0,y>=0,w>0,h>0,(x+w-1)<=VideoWidth,(y+h-1)<=VideoHeight )
*/
local void (*SaveCursorBackground)(int x,int y,int w,int h);
/// Function pointer: Load background behind cursor
local void (*LoadCursorBackground)(int,int,int,int);
local void (*LoadCursorBackground)(int x,int y,int w,int h);
/*--- DRAW RECTANGLE CURSOR ------------------------------------------------*/
// Saved area after draw rectangle, needed later to hide it again
// (OldCursorRectangleW!=0 denotes it's defined)
local int OldCursorRectangleInvalidate=0;/// flag (0/1): ..need invalidate
local int OldCursorRectangleX; /// saved cursor position on screen X
local int OldCursorRectangleY; /// saved cursor position on screen Y
local int OldCursorRectangleW=0; /// saved cursor width in pixel
local int OldCursorRectangleH; /// saved cursor height in pixel
local void* OldCursorRectangle; /// background saved behind rectangle
// Area which is already hidden, but needed for invalidate
// (HiddenCursorRectangleW!=0 denotes it's defined)
local int HiddenCursorRectangleX; /// saved cursor position on screen X
local int HiddenCursorRectangleY; /// saved cursor position on screen Y
local int HiddenCursorRectangleW=0; /// saved cursor width in pixel
local int HiddenCursorRectangleH; /// saved cursor height in pixel
/**
** Function pointer: Save rectangle behind cursor
@ -119,7 +177,6 @@ local void (*LoadCursorRectangle)(int x,int y,int w,int h);
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
/**
** Load all cursor sprites.
**
@ -188,11 +245,11 @@ global CursorType* CursorTypeByIdent(const char* ident)
}
/*----------------------------------------------------------------------------
-- Internal Functions
-- DRAW RECTANGLE CURSOR
----------------------------------------------------------------------------*/
/**
** FIXME: docu missing, better use an inline function.
** Puts stored 'image' from SAVECURSORRECTANGLE back on the screen.
** Note w and h are both > 0
**
** FIXME: this kind of macros are hard to single step with gdb.
** FIXME: inline functions should have the same speed and are debugable.
@ -216,7 +273,9 @@ global CursorType* CursorTypeByIdent(const char* ident)
}
/**
** FIXME: docu missing, better use an inline function.
** Saves 'image' of screen overlapped by rectangle cursor, to be able to
** restore it later using LOADCURSORRECTANGLE.
** Note w and h > 0
**
** FIXME: this kind of macros are hard to single step with gdb.
** FIXME: inline functions should have the same speed and are debugable.
@ -244,9 +303,7 @@ global CursorType* CursorTypeByIdent(const char* ident)
*/
local void LoadCursorRectangle8(int x,int y,int w,int h)
{
if( w && h ) {
LOADCURSORRECTANGLE(VideoMemory8,VMemType8,x,y,w,h);
}
}
/** Restore cursor rectangle for 16bpp frame buffer.
@ -255,9 +312,7 @@ local void LoadCursorRectangle8(int x,int y,int w,int h)
*/
local void LoadCursorRectangle16(int x,int y,int w,int h)
{
if( w && h ) {
LOADCURSORRECTANGLE(VideoMemory16,VMemType16,x,y,w,h);
}
}
/** Restore cursor rectangle for 24bpp frame buffer.
@ -266,9 +321,7 @@ local void LoadCursorRectangle16(int x,int y,int w,int h)
*/
local void LoadCursorRectangle24(int x,int y,int w,int h)
{
if( w && h ) {
LOADCURSORRECTANGLE(VideoMemory24,VMemType24,x,y,w,h);
}
}
/** Restore cursor rectangle for 32bpp frame buffer.
@ -277,9 +330,7 @@ local void LoadCursorRectangle24(int x,int y,int w,int h)
*/
local void LoadCursorRectangle32(int x,int y,int w,int h)
{
if( w && h ) {
LOADCURSORRECTANGLE(VideoMemory32,VMemType32,x,y,w,h);
}
}
/** Save cursor rectangle for 8bpp frame buffer.
@ -288,9 +339,7 @@ local void LoadCursorRectangle32(int x,int y,int w,int h)
*/
local void SaveCursorRectangle8(int x,int y,int w,int h)
{
if( w && h ) {
SAVECURSORRECTANGLE(VideoMemory8,VMemType8,x,y,w,h);
}
}
/** Save cursor rectangle for 16bpp frame buffer.
@ -299,9 +348,7 @@ local void SaveCursorRectangle8(int x,int y,int w,int h)
*/
local void SaveCursorRectangle16(int x,int y,int w,int h)
{
if( w && h ) {
SAVECURSORRECTANGLE(VideoMemory16,VMemType16,x,y,w,h);
}
}
/** Save cursor rectangle for 24bpp frame buffer.
@ -310,9 +357,7 @@ local void SaveCursorRectangle16(int x,int y,int w,int h)
*/
local void SaveCursorRectangle24(int x,int y,int w,int h)
{
if( w && h ) {
SAVECURSORRECTANGLE(VideoMemory24,VMemType24,x,y,w,h);
}
}
/** Save cursor rectangle for 32bpp frame buffer.
@ -321,11 +366,60 @@ local void SaveCursorRectangle24(int x,int y,int w,int h)
*/
local void SaveCursorRectangle32(int x,int y,int w,int h)
{
if( w && h ) {
SAVECURSORRECTANGLE(VideoMemory32,VMemType32,x,y,w,h);
}
/**
** Draw rectangle cursor when visible, defined by
** OldCursorRectangleW (!=0),..
** Pre: for this to work OldCursorRectangleW should be 0 upfront
*/
local void DrawVisibleRectangleCursor(int x,int y,int x1,int y1)
{
int w;
int h;
//
// Clip to map window.
// FIXME: should re-use CLIP_RECTANGLE in some way from linedraw.c ?
//
if( x1<TheUI.MapX ) {
x1=TheUI.MapX;
} else if( x1>TheUI.MapEndX ) {
x1=TheUI.MapEndX;
}
if( y1<TheUI.MapY ) {
y1=TheUI.MapY;
} else if( y1>TheUI.MapEndY ) {
y1=TheUI.MapEndY;
}
if( x>x1 ) {
x=x1;
w=CursorStartX-x+1;
} else {
w=x1-x+1;
}
if( y>y1 ) {
y=y1;
h=CursorStartY-y+1;
} else {
h=y1-y+1;
}
if ( w && h )
{
SaveCursorRectangle(OldCursorRectangleX=x,OldCursorRectangleY=y,
OldCursorRectangleW=w,OldCursorRectangleH=h);
VideoDrawRectangleClip(ColorGreen,x,y,w,h);
OldCursorRectangleInvalidate=1;
}
}
/*----------------------------------------------------------------------------
-- DRAW SPRITE CURSOR
----------------------------------------------------------------------------*/
/**
** Restore cursor background for 8bpp frame buffer.
**
@ -424,19 +518,9 @@ local void LoadCursorBackground32(int x,int y,int w,int h)
*/
local void SaveCursorBackground8(int x,int y,int w,int h)
{
int i;
VMemType8* dp;
VMemType8* sp;
i=w*h*sizeof(VMemType8);
if( OldCursorSize<i ) {
if( OldCursorImage ) {
OldCursorImage=realloc(OldCursorImage,i);
} else {
OldCursorImage=malloc(i);
}
OldCursorSize=i;
}
dp=OldCursorImage;
sp=VideoMemory8+y*VideoWidth+x;
while( h-- ) {
@ -456,19 +540,9 @@ local void SaveCursorBackground8(int x,int y,int w,int h)
*/
local void SaveCursorBackground16(int x,int y,int w,int h)
{
int i;
VMemType16* dp;
const VMemType16* sp;
i=w*h*sizeof(VMemType16);
if( OldCursorSize<i ) {
if( OldCursorImage ) {
OldCursorImage=realloc(OldCursorImage,i);
} else {
OldCursorImage=malloc(i);
}
OldCursorSize=i;
}
dp=OldCursorImage;
sp=VideoMemory16+y*VideoWidth+x;
while( h-- ) {
@ -488,19 +562,9 @@ local void SaveCursorBackground16(int x,int y,int w,int h)
*/
local void SaveCursorBackground24(int x,int y,int w,int h)
{
int i;
VMemType24* dp;
const VMemType24* sp;
i=w*h*sizeof(VMemType24);
if( OldCursorSize<i ) {
if( OldCursorImage ) {
OldCursorImage=realloc(OldCursorImage,i);
} else {
OldCursorImage=malloc(i);
}
OldCursorSize=i;
}
dp=OldCursorImage;
sp=VideoMemory24+y*VideoWidth+x;
while( h-- ) {
@ -520,19 +584,9 @@ local void SaveCursorBackground24(int x,int y,int w,int h)
*/
local void SaveCursorBackground32(int x,int y,int w,int h)
{
int i;
VMemType32* dp;
const VMemType32* sp;
i=w*h*sizeof(VMemType32);
if( OldCursorSize<i ) {
if( OldCursorImage ) {
OldCursorImage=realloc(OldCursorImage,i);
} else {
OldCursorImage=malloc(i);
}
OldCursorSize=i;
}
dp=OldCursorImage;
sp=VideoMemory32+y*VideoWidth+x;
while( h-- ) {
@ -542,49 +596,10 @@ local void SaveCursorBackground32(int x,int y,int w,int h)
}
}
/**
** Save image behind cursor.
*/
local void SaveCursor(void)
{
int w;
int h;
int x;
int y;
x=OldCursorX;
w=OldCursorW;
if( x<0 ) {
w-=x;
x=0;
}
if( w>VideoWidth-x) { // normalize width
w=VideoWidth-x;
}
if( !w ) {
return;
}
y=OldCursorY;
h=OldCursorH;
if( y<0 ) {
w-=y;
y=0;
}
if( h>VideoHeight-y ) { // normalize height
h=VideoHeight-y;
}
if( !h ) {
return;
}
SaveCursorBackground(x,y,w,h);
}
/**
** Destroy image behind cursor.
*/
global void DestroyCursorBackground(void)
local void DestroyCursorBackground(void)
{
if (OldCursorImage) {
free(OldCursorImage);
@ -594,94 +609,51 @@ global void DestroyCursorBackground(void)
}
/**
** Restore image behind cursor.
*/
local void RestoreCursor(void)
{
int w;
int h;
int x;
int y;
if( !OldCursorImage ) { // no cursor saved
return;
}
// FIXME: I should better store the correct values on save.
x=OldCursorX;
w=OldCursorW;
if( x<0 ) {
w-=x;
x=0;
}
if( w>VideoWidth-x) { // normalize width
w=VideoWidth-x;
}
if( !w ) {
return;
}
y=OldCursorY;
h=OldCursorH;
if( y<0 ) {
w-=y;
y=0;
}
if( h>VideoHeight-y ) { // normalize height
h=VideoHeight-y;
}
if( !h ) {
return;
}
LoadCursorBackground(x,y,w,h);
}
/**
** Draw cursor.
** Draw (sprite) cursor when visible, defined by
** OldCursorW (!=0),..
** Pre: for this to work OldCursorW should be 0 upfront
**
** @param type Cursor-type of the cursor to draw.
** @param x Screen x pixel position.
** @param y Screen y pixel position.
** @param frame Animation frame # of the cursor.
*/
global void DrawCursor(const CursorType* type,int x,int y,int frame)
local void DrawCursor(const CursorType* type,int x,int y,int frame)
{
unsigned int size,w,h;
int spritex,spritey;
//
// Save cursor position and size, for faster cursor redraw.
//
OldCursorX=x-=type->HotX;
OldCursorY=y-=type->HotY;
OldCursorW=VideoGraphicWidth(type->Sprite);
OldCursorH=VideoGraphicHeight(type->Sprite);
spritex=(x-=type->HotX);
spritey=(y-=type->HotY);
w=VideoGraphicWidth(type->Sprite);
h=VideoGraphicHeight(type->Sprite);
/* FIXME: SaveCusor done before rectangle
SaveCursor();
*/
VideoDrawClip(type->Sprite,frame,x,y);
}
//Reserve enough memory for background of sprite (also for future calls)
size=(unsigned int)w*(unsigned int)h*memsize;
if( OldCursorSize<size ) {
if( OldCursorImage ) {
OldCursorImage=realloc(OldCursorImage,size);
} else {
OldCursorImage=malloc(size);
}
OldCursorSize=size;
}
/**
** Hide cursor.
*/
global void HideCursor(void)
{
RestoreCursor();
//Save (seen) area behind sprite
CLIP_RECTANGLE(x,y,w,h);
SaveCursorBackground(OldCursorX=x,OldCursorY=y,OldCursorW=w,OldCursorH=h);
//Draw sprite (using its own clipping) FIXME: prevent clipping twice
VideoDrawClip(type->Sprite,frame,spritex,spritey);
OldCursorInvalidate=1;
}
/*----------------------------------------------------------------------------
-- DRAW CURSOR
-- DRAW BUILDING CURSOR
----------------------------------------------------------------------------*/
local int RectangleCursor; /// Flag: last cursor was rectangle
local int BuildingCursor; /// Flag: last cursor was building
// area of tiles covered by building cursor (SX,SY;EX,EY)
local int BuildingCursorSX; /// FIXME: docu
local int BuildingCursorSY; /// FIXME: docu
local int BuildingCursorEX; /// FIXME: docu
local int BuildingCursorEY; /// FIXME: docu
/**
** Draw cursor for selecting building position.
*/
@ -787,131 +759,224 @@ local void DrawBuildingCursor(void)
}
}
/*----------------------------------------------------------------------------
-- DRAW/HIDE CURSOR (interface for the outside world)
----------------------------------------------------------------------------*/
/**
** Draw rectangle cursor.
*/
global void DrawRectangleCursor(void)
{
int x;
int y;
int w;
int h;
int x1;
int y1;
//
// Clip to map window.
//
x1=CursorX;
if( x1<TheUI.MapX ) {
x1=TheUI.MapX;
} else if( x1>TheUI.MapEndX ) {
x1=TheUI.MapEndX;
}
y1=CursorY;
if( y1<TheUI.MapY ) {
y1=TheUI.MapY;
} else if( y1>TheUI.MapEndY ) {
y1=TheUI.MapEndY;
}
x=CursorStartX;
if( x>x1 ) {
x=x1;
w=CursorStartX-x+1;
} else {
w=x1-x+1;
}
y=CursorStartY;
if( y>y1 ) {
y=y1;
h=CursorStartY-y+1;
} else {
h=y1-y+1;
}
#ifdef NEW_MAPDRAW
SaveCursorRectangle(OldCursorRectangleX=x,OldCursorRectangleY=y,
OldCursorRectangleW=w,OldCursorRectangleH=h);
VideoDrawHLine(ColorGreen,x,y,w);
VideoDrawVLine(ColorGreen,x,y+1,--h);
VideoDrawHLine(ColorGreen,x+1,y+h,--w);
VideoDrawVLine(ColorGreen,x+w,y,h);
#else
//FIXME VideoDrawRectangleClip uses different definition for w and h
VideoDrawRectangleClip(ColorGreen,x,y,w-1,h-1);
#endif
}
/**
** Draw the cursor
** Draw the cursor and prepare tobe restored by HideAnyCursor again.
** Note: This function can be called, without calling HideAnyCursor first,
** which means that this function should re-use/free memory of the
** last call.
** When calling multiple times, the old cursor is expected to be
** overdrawn by something else (else HideAnyCursor is needed!)
** Also the cursors are not invalidated (refresh on real screen)
** here, but this is done by InvalidateCursorAreas.
**
** FIXME: event handler should be temporary stopped while copying
** CursorX,CursorY,.. because between two copy commands another
** event can occure, which let invalid mouse position be delivered.
*/
global void DrawAnyCursor(void)
{
RectangleCursor=BuildingCursor=0;
/*FIXME: temporary, as SaveCursor must happen before rectangle
*/
OldCursorX=CursorX-GameCursor->HotX;
OldCursorY=CursorY-GameCursor->HotY;
OldCursorW=VideoGraphicWidth(GameCursor->Sprite);
OldCursorH=VideoGraphicHeight(GameCursor->Sprite);
SaveCursor();
// Disable any previous drawn cursor
OldCursorInvalidate=OldCursorW=
OldCursorRectangleInvalidate=OldCursorRectangleW=
BuildingCursor=0;
//
// Selecting rectangle
// First, Selecting rectangle
//
if( CursorState==CursorStateRectangle
&& (CursorStartX!=CursorX || CursorStartY!=CursorY) ) {
DrawRectangleCursor();
RectangleCursor=1;
} else
DrawVisibleRectangleCursor(CursorStartX,CursorStartY,CursorX,CursorY);
}
//
// Selecting position for building
// Or Selecting position for building
//
if( CursorBuilding && CursorOn==CursorOnMap ) {
else if( CursorBuilding && CursorOn==CursorOnMap ) {
DrawBuildingCursor();
BuildingCursor=1;
}
//
// Normal cursor.
// Last, Normal cursor.
// This will also save (part of) drawn rectangle cursor, but that's ok.
//
DrawCursor(GameCursor,CursorX,CursorY,0);
}
/**
** Remove old cursor from display.
** (in the opposite direction of DrawAnyCursor)
** Note: this function can be called, without calling DrawAnyCursor first,
** which means that cursors shouldn't be restored twice.
** As cursors are, like DrawAnyCursor, not invalidated here, it
** still needs to be done by InvalidateCursorAreas.
*/
global int HideAnyCursor(void)
global void HideAnyCursor(void)
{
if( RectangleCursor ) {
LoadCursorRectangle(OldCursorRectangleX,OldCursorRectangleY,
OldCursorRectangleW,OldCursorRectangleH);
}
if( BuildingCursor ) {
//NOTE: this will restore tiles themselves later in next video update
MarkDrawAreaMap(BuildingCursorSX,BuildingCursorSY,
BuildingCursorEX,BuildingCursorEY);
//
// First, Normal cursor (might restore part of rectangle cursor also).
//
if( OldCursorW ) {
// restore area of visible cursor
LoadCursorBackground(OldCursorX,OldCursorY,OldCursorW,OldCursorH);
// save hidden area to be invalidated
HiddenCursorX=OldCursorX;
HiddenCursorY=OldCursorY;
HiddenCursorW=OldCursorW;
HiddenCursorH=OldCursorH;
// Denote cursor no longer visible
OldCursorW=0;
}
//
// Cursor complete on map and map must be redrawn, no restore.
//StephanR: but prevented when not entire map is redrawn ;)
// Last, Selecting rectangle
//
#ifndef NEW_MAPDRAW
if( OldCursorX>=TheUI.MapX
&& OldCursorX+OldCursorW-1<=TheUI.MapEndX
&& OldCursorY>=TheUI.MapY
&& OldCursorY+OldCursorH-1<=TheUI.MapEndY
&& (MustRedraw&RedrawMap)
&& (InterfaceState != IfaceStateMenu) ) {
return 0;
if( OldCursorRectangleW ) {
// restore area of visible cursor
LoadCursorRectangle(OldCursorRectangleX,OldCursorRectangleY,
OldCursorRectangleW,OldCursorRectangleH);
// save hidden area to be invalidated
HiddenCursorRectangleX=OldCursorRectangleX;
HiddenCursorRectangleY=OldCursorRectangleY;
HiddenCursorRectangleW=OldCursorRectangleW;
HiddenCursorRectangleH=OldCursorRectangleH;
// Denote cursor no longer visible
OldCursorRectangleW=0;
}
#endif
HideCursor();
return 1;
//
// Or Selecting position for building
//
else if( BuildingCursor ) {
//NOTE: this will restore tiles themselves later in next video update
MarkDrawAreaMap(BuildingCursorSX,BuildingCursorSY,
BuildingCursorEX,BuildingCursorEY);
BuildingCursor=0;
}
}
/**
** Let an area be invalidated, but remembering if cursor is automaticly
** invalidated with this area.
** Note: building-cursor is already invalidated by redraw-map
**
** @param x left-top x-position of area on screen
** @param y left-top y-position of area on screen
** @param w width of area on screen
** @param h height of area on screen
*/
global void InvalidateAreaAndCheckCursor( int x, int y, int w, int h )
{
int dx,dy;
//Invalidate area
InvalidateArea(x,y,w,h);
//Now check if cursor sprite is inside it, then no need for invalidate
if ( OldCursorInvalidate )
{
dx = OldCursorX-x;
dy = OldCursorY-y;
if ( dx >= 0 && dy >= 0 && (w-dx) >= OldCursorW && (h-dy) >= OldCursorH )
OldCursorInvalidate = 0;
}
//Now check if previously hidden cursor sprite is inside it..
if ( HiddenCursorW )
{
dx = HiddenCursorX-x;
dy = HiddenCursorY-y;
if ( dx >= 0 && dy >= 0 &&
(w-dx) >= HiddenCursorW && (h-dy) >= HiddenCursorH )
HiddenCursorW = 0;
}
//Now check if cursor rectangle is inside it..
if ( OldCursorRectangleInvalidate )
{
dx = OldCursorRectangleX-x;
dy = OldCursorRectangleY-y;
if ( dx >= 0 && dy >= 0 &&
(w-dx) >= OldCursorRectangleW && (h-dy) >= OldCursorRectangleH )
OldCursorRectangleInvalidate = 0;
}
//Now check if previously hidden cursor rectangle is inside it..
if ( HiddenCursorRectangleW )
{
dx = HiddenCursorRectangleX-x;
dy = HiddenCursorRectangleY-y;
if ( dx >= 0 && dy >= 0 &&
(w-dx) >= HiddenCursorRectangleW && (h-dy) >= HiddenCursorRectangleH )
HiddenCursorRectangleW = 0;
}
}
/**
** Invalidate only the sides of a given rectangle (not its contents)
**
** @param x left-top x-position of rectangle on screen
** @param y left-top y-position of rectangle on screen
** @param w width of rectangle on screen
** @param h height of rectangle on screen
*/
local void InvalidateRectangle(int x, int y, int w, int h)
{
InvalidateArea(x,y,w,1); // top side
if ( --h > 0 )
{
InvalidateArea(x,y+h,w,1); // bottom side
if ( --h > 0 )
{
InvalidateArea(x,++y,1,h); // left side
if ( --w > 0 )
InvalidateArea(x+w,y,1,h); // right side
}
}
}
/**
** Let the (remaining) areas taken by the cursors, as determined by
** DrawAnyCursor and InvalidateAreaAndCheckcursor, be invalidated.
** Note: building-cursor is already invalidated by redraw-map
*/
global void InvalidateCursorAreas(void)
{
//Invalidate cursor sprite
if ( OldCursorInvalidate )
{
InvalidateArea(OldCursorX,OldCursorY,OldCursorW,OldCursorH);
OldCursorInvalidate=0;
}
//Invalidate hidden cursor sprite
if ( HiddenCursorW )
{
InvalidateArea(HiddenCursorX,HiddenCursorY,HiddenCursorW,HiddenCursorH);
HiddenCursorW=0;
}
//Invalidate cursor rectangle
if ( OldCursorRectangleInvalidate )
{
InvalidateRectangle(OldCursorRectangleX,OldCursorRectangleY,
OldCursorRectangleW,OldCursorRectangleH);
OldCursorRectangleInvalidate=0;
}
//Invalidate hidden cursor rectangle
if ( HiddenCursorRectangleW )
{
InvalidateRectangle(HiddenCursorRectangleX,HiddenCursorRectangleY,
HiddenCursorRectangleW,HiddenCursorRectangleH);
HiddenCursorRectangleW=0;
}
}
/**
@ -922,8 +987,6 @@ global int HideAnyCursor(void)
*/
global void InitCursors(void)
{
int memsize;
if( OldCursorRectangle ) { // memory of possible previous video-setting?
free( OldCursorRectangle );
}

View file

@ -36,6 +36,7 @@
#include "freecraft.h"
#include "video.h"
#include "iolib.h"
#include "intern_video.h"
/*----------------------------------------------------------------------------
-- Declarations
@ -241,49 +242,6 @@ local void VideoDrawSub8to32(
}
}
/**
** Clip to clipping rectangle.
**
** @param w width to display
** @param h height to display
** @param x X screen position
** @param y Y screen position
*/
#define DO_CLIPPING(w,h,x,y) \
do { \
int f; \
\
if( x<ClipX1 ) { \
f=ClipX1-x; \
x=ClipX1; \
if( w<f ) { /* outside */ \
return; \
} \
w-=f; \
} \
if( (x+w)>ClipX2 ) { \
if( w<ClipX2-x ) { /* outside */ \
return; \
} \
w=ClipX2-x; \
} \
\
if( y<ClipY1 ) { \
f=ClipY1-y; \
y=ClipY1; \
if( h<f ) { /* outside */ \
return; \
} \
h-=f; \
} \
if( (y+h)>ClipY2 ) { \
if( h<ClipY2-y ) { /* outside */ \
return; \
} \
h=ClipY2-y; \
} \
} while( 0 )
/**
** Video draw part of 8bit graphic clipped into 8 bit framebuffer.
**
@ -299,7 +257,7 @@ local void VideoDrawSub8to8Clip(
const Graphic* graphic,int gx,int gy,unsigned w,unsigned h,
int x,int y)
{
DO_CLIPPING(w,h,x,y);
CLIP_RECTANGLE(x,y,w,h);
VideoDrawSub8to8(graphic,gx,gy,w,h,x,y);
}
@ -318,7 +276,7 @@ local void VideoDrawSub8to16Clip(
const Graphic* graphic,int gx,int gy,unsigned w,unsigned h,
int x,int y)
{
DO_CLIPPING(w,h,x,y);
CLIP_RECTANGLE(x,y,w,h);
VideoDrawSub8to16(graphic,gx,gy,w,h,x,y);
}
@ -337,7 +295,7 @@ local void VideoDrawSub8to24Clip(
const Graphic* graphic,int gx,int gy,unsigned w,unsigned h,
int x,int y)
{
DO_CLIPPING(w,h,x,y);
CLIP_RECTANGLE(x,y,w,h);
VideoDrawSub8to24(graphic,gx,gy,w,h,x,y);
}
@ -356,7 +314,7 @@ local void VideoDrawSub8to32Clip(
const Graphic* graphic,int gx,int gy,unsigned w,unsigned h,
int x,int y)
{
DO_CLIPPING(w,h,x,y);
CLIP_RECTANGLE(x,y,w,h);
VideoDrawSub8to32(graphic,gx,gy,w,h,x,y);
}

123
src/video/intern_video.h Normal file
View file

@ -0,0 +1,123 @@
// ___________ _________ _____ __
// \_ _____/______ ____ ____ \_ ___ \____________ _/ ____\/ |_
// | __) \_ __ \_/ __ \_/ __ \/ \ \/\_ __ \__ \\ __\\ __\
// | \ | | \/\ ___/\ ___/\ \____| | \// __ \| | | |
// \___ / |__| \___ >\___ >\______ /|__| (____ /__| |__|
// \/ \/ \/ \/ \/
// ______________________ ______________________
// T H E W A R B E G I N S
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name intern_video.h - The video headerfile for video sources only. */
//
// (c) Copyright 1999-2001 by Lutz Sammer
//
// FreeCraft 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.
//
// FreeCraft 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.
//
// $Id$
#ifndef __INTERN_VIDEO_H__
#define __INTERN_VIDEO_H__
//@{
/*----------------------------------------------------------------------------
-- Documentation
----------------------------------------------------------------------------*/
/**
** THIS HEADER FILE SHOULD ONLY BE INCLUDED BY SOURCE-FILES IN VIDEO !!!
**
** This delivers an interface to basic video operations in video.c, while
** keeping these detailed operations out of the main include-file video.h
**
** FIXME: Currently some interfaces listed in video.h should be moved in
** here, this includes possible "extern" declarations in source-files
** themselves.
**
*/
/*----------------------------------------------------------------------------
-- Includes
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
-- Declarations
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
/// Direct acces to clipping rectangle for macro CLIP_RECTANGLE
extern int ClipX1; /// current clipping top left
extern int ClipY1; /// current clipping top left
extern int ClipX2; /// current clipping bottom right
extern int ClipY2; /// current clipping bottom right
/*----------------------------------------------------------------------------
-- Macros
----------------------------------------------------------------------------*/
/**
** Clip to clipping rectangle.
** FIXME: not easy to debug, but making it a function needs:
** - pointers to be able to alter given arguments
** - special return value to denote 'outside' clipping region
** (which is now handled by a simple return in caller function)
**
** @param w unsigned int width to display
** @param h unsigned int height to display
** @param x int X screen position
** @param y int Y screen position
*/
#define CLIP_RECTANGLE(x,y,width,height) { \
unsigned int f; \
if( x<ClipX1 ) { \
f=ClipX1-x; \
if( width<=f ) { \
return; \
} \
width-=f; \
x=ClipX1; \
} \
if( (x+width)>ClipX2+1 ) { \
if( x>ClipX2 ) { \
return; \
} \
width=ClipX2-x+1; \
} \
if( y<ClipY1 ) { \
f=ClipY1-y; \
if( height<=f ) { \
return; \
} \
height-=f; \
y=ClipY1; \
} \
if( (y+height)>ClipY2+1 ) { \
if( y>ClipY2 ) { \
return; \
} \
height=ClipY2-y+1; \
} \
}
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
//@}
#endif // !__INTERN_VIDEO_H__

View file

@ -36,6 +36,8 @@
#include "freecraft.h"
#include "video.h"
#include "intern_video.h"
/*----------------------------------------------------------------------------
-- Declarations
----------------------------------------------------------------------------*/
@ -51,15 +53,6 @@ typedef enum {
ClipCodeRight = 8
} ClipCode;
/*----------------------------------------------------------------------------
-- Externals
----------------------------------------------------------------------------*/
extern int ClipX1; /// current clipping top left
extern int ClipY1; /// current clipping top left
extern int ClipX2; /// current clipping bottom right
extern int ClipY2; /// current clipping bottom right
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
@ -4513,38 +4506,6 @@ local void DrawTransRectangle32(SysColors color,int x,int y
}
}
#define CLIP_RECTANGLE(x,y,width,height) { \
unsigned f; \
if( x<ClipX1 ) { \
f=ClipX1-x; \
if( width<=f ) { \
return; \
} \
width-=f; \
x=ClipX1; \
} \
if( (x+width)>ClipX2+1 ) { \
if( x>ClipX2 ) { \
return; \
} \
width=ClipX2-x+1; \
} \
if( y<ClipY1 ) { \
f=ClipY1-y; \
if( height<=f ) { \
return; \
} \
height-=f; \
y=ClipY1; \
} \
if( (y+height)>ClipY2+1 ) { \
if( y>ClipY2 ) { \
return; \
} \
height=ClipY2-y+1; \
} \
}
/**
** Draw rectangle clipped.
**

View file

@ -35,12 +35,13 @@
#include "freecraft.h"
#include "video.h"
#include "map.h"
#include "ui.h"
#include "cursor.h"
#include "iolib.h"
#include "intern_video.h"
#ifdef USE_SDL
#include <SDL/SDL.h>
#endif