Optimized display, only needed tiles and units are redrawn. from Stephan RasenBergver

This commit is contained in:
johns 2001-02-08 20:53:54 +00:00
parent 5384f8180f
commit 66437b8d45
33 changed files with 1028 additions and 547 deletions

View file

@ -1,4 +1,6 @@
Rules.make
freecraft
gmon.out
save_file_of_freecraft.ccl
srcdoc
.depend

View file

@ -1,6 +1,6 @@
## ___________ _________ _____ __
## \_ _____/______ ____ ____ \_ ___ \____________ _/ ____\/ |_
## | __) \_ __ \_/ __ \_/ __ \/ \ \/\_ __ \__ \ __\ __\
## | __) \_ __ \_/ __ \_/ __ \/ \ \/\_ __ \__ \\ __\\ __\
## | \ | | \/\ ___/\ ___/\ \____| | \// __ \| | | |
## \___ / |__| \___ >\___ >\______ /|__| (____ /__| |__|
## \/ \/ \/ \/ \/
@ -8,71 +8,241 @@
## 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).
##
## (c) Copyright 1998-2001 by Lutz Sammer
##
## $Id$
##
# Compile commands
CC=gcc
RM=rm -f
MAKE=make
############################################################################
# Configurable:
# Choose what you want to include and the correct
# version. Minimal is now the default.
############################################################################
# Use SIOD support
CCL = -DUSE_CCL2
CCLLIB = -lm -ldl
# Uncomment next to get guile with gtk (and choose your gtklib version)
# NO LONGER SUPPORTED
#GUILEGTK = -DGUILE_GTK $(shell gtk-config --cflags)
#GUILEGTK = -DGUILE_GTK -I/usr/X11R6/include -I/usr/lib/glib/include
#GUILEGTKLIB = -lguilegtk-1.2 $(shell gtk-config --libs)
#------------------------------------------------------------------------------
# Uncomment next for a version with guile (GNU scheme interpreter)
# (and choose your guile version)
# NO LONGER SUPPORTED
# guile 1.3 latest version
# -lreadline -lncurses are needed with the distribution SuSe 5.3
#GUILE_CFLAGS = $(shell guile-config compile)
#GUILE = -DUSE_CCL $(GUILEGTK) $(GUILE_CFLAGS)
#GUILELIB = $(GUILEGTKLIB) $(shell guile-config link) -lreadline -lncurses
#GUILELIB = $(GUILEGTKLIB) $(shell guile-config link)
# guile
#CCL = $(GUILE)
#CCLLIB = $(GUILELIB)
#------------------------------------------------------------------------------
# Comment next for a version without SIOD (scheme interpreter)
#
# Try to use siod (currently default)
CCL = -DUSE_CCL2
CCLLIB = -lm
#------------------------------------------------------------------------------
# Uncomment next to add threaded sound support
# You should have a thread safe X11 (libc6 or glibc)
#THREAD = -D_REENTRANT -DUSE_THREAD
#THREADLIB = -lpthread
#------------------------------------------------------------------------------
# Choose correct version of glib (needed for gtk)
# Should work with >= 1.2
#GLIB_CFLAGS = $(shell glib-config glib --cflags)
#GLIBLIB = $(shell glib-config glib --libs)
#GLIB = -DUSE_GLIB $(GLIB_CFLAGS)
#------------------------------------------------------------------------------
# Video driver part
#------------------------------------------------------------------------------
# Uncomment the next for the normal X11 support.
# Video support
VIDEO = -DUSE_X11
VIDEOLIB = -lXext -lX11 -ldl
VIDEOLIB = -lXext -lX11 -ldl
# Uncomment the next to get the support for SDL.
# Old SDL <1.0.0
#SDL_CFLAGS =
#SDLLIB = -lSDL -ldl -lpthread
# New SDL >=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 SDL X11/SVGALIB support.
VIDEO = $(SDL)
VIDEOLIB = $(SDLLIB) -lXext -lX11 -lXxf86dga -lXxf86vm -lvga -lvgagl -ldl -lesd -lm -lslang -lgpm
# Choose next to get svgalib support.
#VIDEO = -DUSE_SVGALIB
#VIDEOLIB = -lvga -lm -ldl
# 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
#------------------------------------------------------------------------------
# Sound driver part
#------------------------------------------------------------------------------
# Comment next if you want to remove sound support.
# Sound support
DSOUND = -DWITH_SOUND
# Compression support
#------------------------------------------------------------------------------
# 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
#####################################################################
# Don't change anything below here unless you know what you're doing!
#------------------------------------------------------------------------------
# Uncomment next to profile
#PROFILE= -pg
VERSION= '-DVERSION="1.17pre1-build7"'
PROFILE=
# Version
VERSION= '-DVERSION="1.17pre1-build9"'
############################################################################
# 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)
$(THREADLIB) $(CCLLIB) $(GLIBLIB) $(VIDEOLIB) $(ZLIBS)
DISTLIST=$(TOPDIR)/distlist
TAGS=$(TOPDIR)/src/tags
# Linux
EXE=
# 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)
DFLAGS= $(THREAD) $(CCL) $(VERSION) \
$(VIDEO) $(ZDEFS) $(DSOUND) \
$(DEBUG)
CFLAGS=-g $(IFLAGS) $(DFLAGS) -DSLOW_INPUT -DUNIT_ON_MAP
## 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
## MEW_ORDERS: Johns new none memory leaking order code
## NEW_MAPDRAW: Stephans new map draw code
## NEW_NAMES: New unit names without copyleft problems
## NEW_FOW: New fog of war code, should work correct
## NEW_AI: New better improved AI code
DFLAGS= $(THREAD) $(CCL) $(VERSION) $(GLIB) $(VIDEO) $(ZDEFS) $(DSOUND) \
$(DEBUG) -DUNIT_ON_MAP -DNEW_MAPDRAW #-DNEW_ORDERS -DNEW_NAMES -DNEW_FOW -DNEW_AI
## 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
CC=gcc
RM=rm -f
MAKE=make
## JOHNS: my ctags didn't support
#CTAGSFLAGS=-i defmpstuvFS -a -f
CTAGSFLAGS=-i defptvS -a -f
# Locks versions with a symbolic name
#
# Locks versions with 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

@ -10,7 +10,7 @@
//
/**@name action_build.c - The build building action. */
//
// (c) Copyright 1998,2000 by Lutz Sammer
// (c) Copyright 1998,2000,2001 by Lutz Sammer
//
// $Id$
@ -107,7 +107,7 @@ global void HandleActionBuild(Unit* unit)
++x;
++y;
}
//
// Check if the building could be build there.
//
@ -167,14 +167,14 @@ global void HandleActionBuild(Unit* unit)
DestroyUnit(temp); // Destroy oil patch
}
RemoveUnit(unit);
RemoveUnit(unit);/* automaticly: CheckUnitToBeDrawn(unit) */
unit->X=x;
unit->Y=y;
unit->Command.Action=UnitActionStill;
if( UnitVisible(build) ) {
MustRedraw|=RedrawMaps;
}
CheckUnitToBeDrawn(build);
MustRedraw|=RedrawMinimap;
}
/**
@ -219,7 +219,7 @@ global void HandleActionBuilded(Unit* unit)
//
// Check if building ready.
//
if( unit->Command.Data.Builded.Sum>=unit->Stats->HitPoints
if( unit->Command.Data.Builded.Sum>=unit->Stats->HitPoints
|| unit->HP>=unit->Stats->HitPoints ) {
if( unit->HP>unit->Stats->HitPoints ) {
unit->HP=unit->Stats->HitPoints;
@ -258,16 +258,13 @@ global void HandleActionBuilded(Unit* unit)
}
// FIXME: Vladi: this is just a hack to test wall fixing,
// FIXME: also not sure if the right place...
// FIXME: also not sure if the right place...
// FIXME: Johns: and now this is also slow
if ( unit->Type == UnitTypeByIdent("unit-orc-wall")
|| unit->Type == UnitTypeByIdent("unit-human-wall")) {
MapSetWall(unit->X, unit->Y,
unit->Type == UnitTypeByIdent("unit-human-wall"));
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
RemoveUnit( unit );
RemoveUnit(unit);/* automaticly: CheckUnitToBeDrawn(unit) */
UnitLost(unit);
ReleaseUnit(unit);
return;
@ -281,9 +278,7 @@ global void HandleActionBuilded(Unit* unit)
} else if( unit->Player==ThisPlayer ) {
UpdateButtonPanel();
}
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
return;
}
@ -291,19 +286,18 @@ global void HandleActionBuilded(Unit* unit)
// Update building states
//
if( unit->Command.Data.Builded.Sum*2>=unit->Stats->HitPoints ) {
if( (unit->Frame!=1 || unit->Constructed)
&& UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
if( (unit->Frame!=1 || unit->Constructed) ) {
CheckUnitToBeDrawn(unit);
}
unit->Constructed=0;
unit->Frame=1;
} else if( unit->Command.Data.Builded.Sum*4>=unit->Stats->HitPoints ) {
if( unit->Frame!=1 && UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
if( unit->Frame!=1 ) {
CheckUnitToBeDrawn(unit);
}
unit->Frame=1;
}
unit->Wait=5;
if( IsSelected(unit) ) {
MustRedraw|=RedrawInfoPanel;

View file

@ -137,11 +137,11 @@ local int ChopWood(Unit* unit)
//
#if 0
// FIXME: johns+cade: this didn't work with the current code
if( unit->NextCommand[0].Action==UnitActionHarvest
if( unit->NextCommand[0].Action==UnitActionHarvest
|| unit->NextCommand[0].Action==UnitActionMineGold ) {
unit->SubAction=0;
return 0;
}
}
#endif
//
@ -184,9 +184,7 @@ local int ChopWood(Unit* unit)
//
// Update the display.
//
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
if( IsSelected(unit) ) {
UpdateButtonPanel();
MustRedraw|=RedrawButtonPanel;
@ -333,7 +331,7 @@ local int ReturnWithWood(Unit* unit)
unit->Wait=MAX_UNIT_WAIT;
}
unit->Value=WAIT_FOR_WOOD-unit->Wait;
return 1;
}
@ -367,9 +365,7 @@ local int WaitInWoodDeposit(Unit* unit)
unit->Command.Data.Move.DX=unit->Command.Data.Move.SX;
unit->Command.Data.Move.DY=unit->Command.Data.Move.SY;
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
unit->Wait=1;
unit->WoodToHarvest=CHOP_FOR_WOOD;
return 1;

View file

@ -212,9 +212,7 @@ local int HaulInOilWell(Unit* unit)
unit->Command.Action=UnitActionHaulOil;
}
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
if( IsSelected(unit) ) {
UpdateButtonPanel();
MustRedraw|=RedrawButtonPanel;
@ -362,9 +360,7 @@ local int WaitForOilDeliver(Unit* unit)
unit->Command.Action=UnitActionHaulOil;
}
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
unit->Wait=1;
unit->SubAction=0;
return 1;

View file

@ -51,7 +51,7 @@ local int MoveToGoldMine(Unit* unit)
if( HandleActionMove(unit)>=0 ) { // reached end-point?
return 0;
}
// FIXME: HandleActionMove return this: reached nearly, use it!
unit->Command.Action=UnitActionMineGold;
@ -194,9 +194,7 @@ local int MineInGoldmine(Unit* unit)
,unit->X,unit->Y
,unit->Type->Type,unit->Type->Name);
}
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
if( IsSelected(unit) ) {
UpdateButtonPanel();
MustRedraw|=RedrawButtonPanel;
@ -233,7 +231,7 @@ local int MoveToGoldDeposit(Unit* unit)
if( HandleActionMove(unit)>=0 ) { // reached end-point?
return 0;
}
// FIXME: HandleActionMove return this: reached nearly, use it!
unit->Command.Action=UnitActionMineGold;
@ -281,7 +279,7 @@ local int MoveToGoldDeposit(Unit* unit)
if( unit->Player==ThisPlayer ) {
MustRedraw|=RedrawResources;
}
if( unit->Type==UnitTypeOrcWorkerWithGold ) {
unit->Type=UnitTypeOrcWorker;
} else if( unit->Type==UnitTypeHumanWorkerWithGold ) {
@ -344,9 +342,7 @@ local int StoreGoldInDeposit(Unit* unit)
unit->Command.Action=UnitActionMineGold;
}
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
unit->Wait=1;
unit->SubAction=0;
return 1;

View file

@ -207,9 +207,9 @@ local int ActionMoveGeneric(Unit* unit,const Animation* move)
unit->Frame+=move[state].Frame;
unit->Wait=move[state].Sleep;
if( (move[state].Pixel || move[state].Frame) && UnitVisible(unit) ) {
if( (move[state].Pixel || move[state].Frame) ) {
// FIXME: Must do better flags.
MustRedraw|=RedrawMap;
CheckUnitToBeDrawn(unit);
}
if( move[state].Flags&AnimationReset ) {

View file

@ -115,8 +115,8 @@ local void RepairUnit(Unit* unit,Unit* goal)
//
PlayerSubCosts(player,costs);
if( UnitVisible(goal) ) {
MustRedraw|=RedrawMaps;
if ( CheckUnitToBeDrawn(goal) ) {
MustRedraw|=RedrawMinimap;
}
if( IsSelected(goal) ) { // Update panel if unit is selected
MustRedraw|=RedrawInfoPanel;

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name action_stand.c - The stand ground action. */
/*
** (c) Copyright 2000 by Lutz Sammer
**
** $Id$
*/
//
// (c) Copyright 2000,2001 by Lutz Sammer
//
// $Id$
//@{
@ -97,7 +96,7 @@ global void HandleActionStandGround(Unit* unit)
if( type->Type==UnitCritter ) {
int x;
int y;
x=unit->X;
y=unit->Y;
switch( (SyncRand()>>12)&15 ) {
@ -116,7 +115,7 @@ global void HandleActionStandGround(Unit* unit)
x=0;
} else if( x>=TheMap.Width ) {
x=TheMap.Width-1;
}
}
if( y<0 ) {
y=0;
} else if( y>=TheMap.Height ) {
@ -141,7 +140,7 @@ global void HandleActionStandGround(Unit* unit)
//
// Workers and mage didn't attack automatic
// removed with standground && !type->CowerWorker && !type->CowerMage
// removed with standground && !type->CowerWorker && !type->CowerMage
if( type->CanAttack ) {
//
// Units attacks in attacking range.
@ -179,16 +178,12 @@ global void HandleActionStandGround(Unit* unit)
case 0: // Turn clockwise
unit->Direction+=NextDirection;
UnitUpdateHeading(unit);
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
break;
case 1: // Turn counter clockwise
unit->Direction-=NextDirection;
UnitUpdateHeading(unit);
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
break;
default: // does nothing
break;

View file

@ -101,7 +101,7 @@ global void ActionStillGeneric(Unit* unit,int ground)
if( type->Critter && type==UnitTypeCritter ) {
int x;
int y;
x=unit->X;
y=unit->Y;
switch( (SyncRand()>>12)&15 ) {
@ -120,7 +120,7 @@ global void ActionStillGeneric(Unit* unit,int ground)
x=0;
} else if( x>=TheMap.Width ) {
x=TheMap.Width-1;
}
}
if( y<0 ) {
y=0;
} else if( y>=TheMap.Height ) {
@ -262,16 +262,12 @@ global void ActionStillGeneric(Unit* unit,int ground)
case 0: // Turn clockwise
unit->Direction+=NextDirection;
UnitUpdateHeading(unit);
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
break;
case 1: // Turn counter clockwise
unit->Direction-=NextDirection;
UnitUpdateHeading(unit);
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
break;
default: // does nothing
break;

View file

@ -67,9 +67,8 @@ global int UnitShowAnimation(Unit* unit,const Animation* animation)
unit->IY+=animation[state].Pixel;
unit->Wait=animation[state].Sleep;
if( (animation[state].Frame || animation[state].Pixel)
&& UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
if( (animation[state].Frame || animation[state].Pixel) ) {
CheckUnitToBeDrawn(unit);
}
flags=animation[state].Flags;

View file

@ -128,7 +128,7 @@ typedef struct _world_map_ {
unsigned Terrain; /// terrain type (summer,winter,...)
Tileset* Tileset; /// tileset data
unsigned TileCount; /// how many tiles are available
unsigned TileCount; /// how many tiles are available
unsigned char** Tiles; /// pointer to tile data
Graphic* TileData; /// tiles graphic for map
@ -188,6 +188,15 @@ extern void DrawMapBackground(int x,int y);
/// Build tables for map.
extern void InitMap(void);
/// Mark position inside screenmap be drawn for next display update.
extern int MarkDrawPosMap( int x, int y );
/// Denote wether area in map is overlapping
extern int AreaVisibleInMap( int sx, int sy, int ex, int ey );
/// Set overlapping area as entries in MustRedrawRow and MustRedrawTile
extern int MarkDrawAreaMap( int sx, int sy, int ex, int ey );
/// Set all entries in MustRedrawRow and MustRedrawTile
extern void MarkDrawEntireMap(void);
//
// in map_fog.c
//

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name ui.h - The user interface header file. */
/*
** (c) Copyright 1999,2000 by Lutz Sammer
**
** $Id$
*/
//
// (c) Copyright 1999-2001 by Lutz Sammer
//
// $Id$
#ifndef __UI_H__
#define __UI_H__
@ -111,7 +110,7 @@ typedef struct _ui_ {
int IconH; /// icon H position
int TextX; /// text X position
int TextY; /// text Y position
} Resources[MaxCosts];
} Resources[MaxCosts];
struct {
char* File; /// Filename
@ -165,10 +164,10 @@ typedef struct _ui_ {
// The map
int MapX; /// big map screen X position
int MapY; /// big map screen Y position
/// map width for current mode (MapX+14*32 for 640x480)
unsigned MapWidth;
/// map height for current mode (MapY+14*32 for 640x480)
unsigned MapHeight;
/// map width for current mode (MapX+14*32-1 for 640x480)
unsigned MapEndX;
/// map height for current mode (MapY+14*32-1 for 640x480)
unsigned MapEndY;
// The menu button
struct {
@ -199,7 +198,7 @@ typedef struct _ui_ {
/// used for displaying unit training queues
Button Buttons2[6];
// FIXME: could use different sounds/speach for the errors
// FIXME: could use different sounds/speach for the errors
// Is in gamesounds?
// SoundConfig PlacementError; /// played on placements errors
// SoundConfig PlacementSuccess; /// played on placements success

View file

@ -432,6 +432,11 @@ extern void NearestOfUnit(const Unit* unit,int tx,int ty,int *dx,int *dy);
/// FIXME: more docu
extern int UnitVisible(const Unit* unit);
/// FIXME: more docu
extern int CheckUnitToBeDrawn(const Unit* unit);
/// FIXME: more docu
extern void GetUnitMapArea( const Unit* unit,
int *sx, int *sy, int *ex, int *ey );
/// FIXME: more docu
extern void RemoveUnit(Unit* unit);
/// Increment mana of all magic units each second.
extern void UnitIncrementMana(void);

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name map.c - The map. */
/*
** (c) Copyright 1998-2000 by Lutz Sammer
**
** $Id$
*/
//
// (c) Copyright 1998-2001 by Lutz Sammer
//
// $Id$
//@{
@ -143,6 +142,9 @@ global void RevealMap(void)
*/
global void MapSetViewpoint(int x,int y)
{
if (x==MapX && y==MapY)
return;
if( x<0 ) {
MapX=0;
} else if( x>TheMap.Width-MapWidth ) {
@ -157,7 +159,8 @@ global void MapSetViewpoint(int x,int y)
} else {
MapY=y;
}
MustRedraw|=RedrawMaps|RedrawMinimapCursor;
MarkDrawEntireMap();
MustRedraw|=RedrawMinimap|RedrawMinimapCursor;
}
/**

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name map_draw.c - The map drawing. */
/*
** (c) Copyright 1999,2000 by Lutz Sammer
**
** $Id$
*/
//
// (c) Copyright 1999-2001 by Lutz Sammer
//
// $Id$
//@{
@ -252,7 +251,7 @@ global void VideoDraw16Tile32(const unsigned char* data,int x,int y)
da=VideoWidth;
dp=VideoMemory16+x+y*VideoWidth;
IfDebug(
IfDebug(
if( ((long)sp)&1 ) {
DebugLevel0("Not aligned memory\n");
}
@ -306,7 +305,7 @@ global void VideoDraw24Tile32(const unsigned char* data,int x,int y)
da=VideoWidth;
dp=VideoMemory24+x+y*VideoWidth;
IfDebug(
IfDebug(
if( ((long)sp)&1 ) {
DebugLevel0("Not aligned memory\n");
}
@ -542,7 +541,7 @@ local void FillCache24AndDraw32(const unsigned char* data,VMemType24* cache
va=VideoWidth;
vp=VideoMemory24+x+y*VideoWidth;
IfDebug(
IfDebug(
if( ((long)sp)&1 ) {
DebugLevel0("Not aligned memory\n");
}
@ -603,7 +602,7 @@ local void FillCache32AndDraw32(const unsigned char* data,VMemType32* cache
va=VideoWidth;
vp=VideoMemory32+x+y*VideoWidth;
IfDebug(
IfDebug(
if( ((long)sp)&1 ) {
DebugLevel0("Not aligned memory\n");
}
@ -1284,11 +1283,129 @@ global void MapColorCycle(void)
}
}
/**
** Mark position inside screenmap be drawn for next display update.
**
** @param x,y position in Map to be checked.
**
** @return True if inside and marked, false otherwise.
*/
global int MarkDrawPosMap( int x, int y ) {
if ( (x-=MapX)>=0 && (y-=MapY)>=0 && x<MapWidth && y<MapHeight ) {
#ifdef NEW_MAPDRAW
MustRedrawRow[y]=MustRedrawTile[y*MapWidth+x]=NEW_MAPDRAW;
#endif
MustRedraw|=RedrawMap;
return 1;
}
return 0;
}
/**
** Denote wether area in screenmap is overlapping
**
** @param sx,sy,ex,ey area in Map to be checked.
**
** @return True if overlapping, false otherwise.
*/
global int AreaVisibleInMap( int sx, int sy, int ex, int ey ) {
return ( sx>=MapX && sy>=MapY && ex<MapX+MapWidth && ey<MapY+MapHeight );
}
/**
**
** Mark overlapping area with screenmap be drawn for next display update.
**
** @param sx,sy,ex,ey area in Map to be checked.
** @return True if overlapping and marked, false otherwise.
**
*/
global int MarkDrawAreaMap( int sx, int sy, int ex, int ey ) {
if ( (ex-=MapX)>=0 && (ey-=MapY)>=0 &&
(sx-=MapX)<MapWidth && (sy-=MapY)<MapHeight ) {
#ifdef NEW_MAPDRAW
char *row, *tile;
// Get area in screenmap
if ( sx < 0 )
sx = 0;
if ( ex >= MapWidth )
ex = MapWidth-1;
if ( sy < 0 )
sy = 0;
if ( ey >= MapHeight )
ey = MapHeight-1;
// Denote area in screenmap
row = MustRedrawRow + sy;
tile = MustRedrawTile + sy*MapWidth+sx;
ex -= sx; //now: ex=width+1
ey -= sy; // ey=height+1
do
{
row[ey]=NEW_MAPDRAW;
sx = ex;
do tile[sx]=NEW_MAPDRAW;
while ( --sx >= 0 );
tile += MapWidth;
}
while ( --ey >= 0 );
#endif
MustRedraw|=RedrawMap;
return 1;
}
return 0;
}
/**
**
** Enable entire map be drawn for next display update.
**
*/
global void MarkDrawEntireMap(void)
{
#ifdef NEW_MAPDRAW
int i;
for( i=0; i<MapHeight; ++i ) {
MustRedrawRow[i]=1;
}
for( i=0; i<MapHeight*MapWidth; ++i ) {
MustRedrawTile[i]=1;
}
#endif
MustRedraw|=RedrawMap;
}
/**
** Draw the map backgrounds.
**
** @param x Map viewpoint x position.
** @param y Map viewpoint y position.
**
** StephanR: variables explained below for screen:
** *---------------------------------------*
** | |
** | *-----------------------* |<-TheUi.MapY,dy (in pixels)
** | | | | | | | | | |
** | | | | | | | | | |
** | |---+---+---+---+---+---| | |
** | | | | | | | | | |MapHeight (in tiles)
** | | | | | | | | | |
** | |---+---+---+---+---+---| | |
** | | | | | | | | | |
** | | | | | | | | | |
** | *-----------------------* |<-ey,TheUI.MapEndY (in pixels)
** | |
** | |
** *---------------------------------------*
** ^ ^
** dx|-----------------------|ex,TheUI.MapEndX (in pixels)
** TheUI.MapX MapWidth (in tiles)
** (in pixels)
*/
global void DrawMapBackground(int x,int y)
{
@ -1312,22 +1429,30 @@ global void DrawMapBackground(int x,int y)
redraw_row=MustRedrawRow; // flags must redraw or not
redraw_tile=MustRedrawTile;
ex=TheUI.MapX+MapWidth*TileSizeX;
ex=TheUI.MapEndX;
sy=y*TheMap.Width;
dy=TheUI.MapY;
ey=dy+MapHeight*TileSizeX;
ey=TheUI.MapEndY;
while( dy<ey ) {
while( dy<=ey ) {
if( *redraw_row++ ) { // row must be redrawn
sx=x+sy;
dx=TheUI.MapX;
while( dx<ex ) {
while( dx<=ex ) {
//
// draw only tiles which must be drawn
//
if( *redraw_tile++) {
if( *redraw_tile++ ) {
// FIXME: unexplored fields could be drawn faster
MapDrawTile(TheMap.Fields[sx].SeenTile,dx,dy);
// StephanR: debug-mode denote tiles that are redrawn
#if NEW_MAPDRAW > 1
VideoDrawRectangle( redraw_tile[-1] > 1
? ColorWhite
: ColorRed,
dx, dy, 32, 32 );
#endif
}
++sx;
dx+=TileSizeX;

View file

@ -361,12 +361,12 @@ global void MapUpdateVisible(void)
#ifdef NEW_FOW
MapMarkSight(unit->Player,unit->X+unit->Type->TileWidth/2
,unit->Y+unit->Type->TileHeight/2
,unit->Stats->SightRange*(unit->Revealer == 0)
,unit->Stats->SightRange*(unit->Revealer == 0)
+ 12*(unit->Revealer != 0));
#else
MapMarkSight(unit->X+unit->Type->TileWidth/2
,unit->Y+unit->Type->TileHeight/2
,unit->Stats->SightRange*(unit->Revealer == 0)
,unit->Stats->SightRange*(unit->Revealer == 0)
+ 12*(unit->Revealer != 0));
#endif
}
@ -1431,8 +1431,8 @@ global void DrawMapFogOfWar(int x,int y)
int ex;
int dy;
int ey;
const char* redraw_row;
const char* redraw_tile;
char* redraw_row;
char* redraw_tile;
#ifdef TIMEIT
u_int64_t sv=rdtsc();
u_int64_t ev;
@ -1441,17 +1441,27 @@ global void DrawMapFogOfWar(int x,int y)
redraw_row=MustRedrawRow; // flags must redraw or not
redraw_tile=MustRedrawTile;
ex=TheUI.MapX+MapWidth*TileSizeX;
ex=TheUI.MapEndX;
sy=y*TheMap.Width;
dy=TheUI.MapY;
ey=dy+MapHeight*TileSizeX;
ey=TheUI.MapEndY;
while( dy<=ey ) {
if( *redraw_row ) { // row must be redrawn
#if NEW_MAPDRAW > 1
(*redraw_row)--;
#else
*redraw_row=0;
#endif
while( dy<ey ) {
if( *redraw_row++ ) { // row must be redrawn
sx=x+sy;
dx=TheUI.MapX;
while( dx<ex ) {
if( *redraw_tile++ ) {
while( dx<=ex ) {
if( *redraw_tile ) {
#if NEW_MAPDRAW > 1
(*redraw_tile)--;
#else
*redraw_tile=0;
#ifdef NEW_FOW
if( TheMap.Fields[sx].Explored&(1<<ThisPlayer->Player) ) {
DrawFogOfWarTile(sx,sy,dx,dy);
@ -1465,13 +1475,16 @@ global void DrawMapFogOfWar(int x,int y)
VideoDrawTile(TheMap.Tiles[UNEXPLORED_TILE],dx,dy);
}
#endif
#endif
}
++redraw_tile;
++sx;
dx+=TileSizeX;
}
} else {
redraw_tile+=MapWidth;
}
++redraw_row;
sy+=TheMap.Width;
dy+=TileSizeY;
}

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name map_rock.c - The map rock handling. */
/*
** (c) Copyright 1999,2000 by Vladi
**
** $Id$
*/
//
// (c) Copyright 1999-2001 by Vladi Shabanski
//
// $Id$
//@{
@ -52,7 +51,7 @@ global int RockTable[20] = {
/**
** Check if the tile type is rock.
**
** Used by @see FixRock and @see PreprocessMap
** Used by @see FixRock and @see PreprocessMap
*/
local int MapRockChk(int x,int y)
{
@ -144,7 +143,8 @@ global void MapRemoveRock(unsigned x,unsigned y)
#else
if( mf->Flags&MapFieldVisible ) {
#endif
MustRedraw|=RedrawMaps;
MarkDrawPosMap(x,y);
MustRedraw|=RedrawMinimap;
// FIXME: didn't make it better MapMarkSeenTile(x,y);
}
}

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name map_wall.c - The map wall handling. */
/*
** (c) Copyright 1999,2000 by Vladi
**
** $Id$
*/
//
// (c) Copyright 1999-2001 by Vladi Shabanski
//
// $Id$
//@{
@ -173,7 +172,8 @@ global void MapRemoveWall(unsigned x,unsigned y)
#else
if( mf->Flags&MapFieldVisible ) {
#endif
MustRedraw|=RedrawMaps;
MarkDrawPosMap(x,y);
MustRedraw|=RedrawMinimap;
MapMarkSeenTile(x,y);
}
}
@ -206,7 +206,8 @@ global void MapSetWall(unsigned x,unsigned y,int humanwall)
#else
if( mf->Flags&MapFieldVisible ) {
#endif
MustRedraw|=RedrawMaps;
MarkDrawPosMap(x,y);
MustRedraw|=RedrawMinimap;
MapMarkSeenTile(x,y);
}
}

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name map_wood.c - The map wood handling. */
/*
** (c) Copyright 1999,2000 by Vladi
**
** $Id$
*/
//
// (c) Copyright 1999-2001 by Vladi Shabanski
//
// $Id$
//@{
@ -46,7 +45,7 @@ global int WoodTable[16];
/**
** Check if the tile type is wood.
**
** Used by @see MapFixWood and @see PreprocessMap
** Used by @see MapFixWood and @see PreprocessMap
*/
global int MapWoodChk(int x,int y)
{
@ -128,7 +127,8 @@ global void MapRemoveWood(unsigned x,unsigned y)
#else
if( mf->Flags&MapFieldVisible ) {
#endif
MustRedraw|=RedrawMaps;
MarkDrawPosMap(x,y);
MustRedraw|=RedrawMinimap;
MapMarkSeenTile(x,y);
}
}
@ -160,7 +160,7 @@ global void RegenerateForest(void)
if( x && !(mf->Flags&(MapFieldWall|MapFieldUnpassable
|MapFieldLandUnit|MapFieldBuilding)) ) {
tmp=mf-TheMap.Width;
if( tmp->Tile==TheMap.Tileset->RemovedTree
if( tmp->Tile==TheMap.Tileset->RemovedTree
&& tmp->Value>=ForestRegeneration
&& !(tmp->Flags&(MapFieldWall|MapFieldUnpassable
|MapFieldLandUnit|MapFieldBuilding)) ) {

View file

@ -10,7 +10,7 @@
//
/**@name mainloop.c - The main game loop. */
//
// (c) Copyright 1998-2000 by Lutz Sammer
// (c) Copyright 1998-2001 by Lutz Sammer
//
// $Id$
@ -62,6 +62,35 @@ global enum _scroll_state_ MouseScrollState=ScrollNone;
// Functions
//----------------------------------------------------------------------------
local void move_up( int step )
{
if( MapY>step) {
MapY-=step;
}
else MapY=0;
}
local void move_left( int step )
{
if( MapX>step) {
MapX-=step;
}
else MapX=0;
}
local void move_down( int step )
{
if( MapY<TheMap.Height-MapHeight-step ) {
MapY+=step;
}
else MapY=TheMap.Height-MapHeight;
}
local void move_right( int step )
{
if( MapX<TheMap.Width-MapWidth-step ) {
MapX+=step;
}
else MapX=TheMap.Width-MapWidth;
}
/**
** Handle scrolling area.
**
@ -69,175 +98,56 @@ global enum _scroll_state_ MouseScrollState=ScrollNone;
** @param FastScroll Flag scroll faster.
**
** FIXME: Support dynamic acceleration of scroll speed.
** StephanR: above needs one row+column of tiles extra to be
** drawn (clipped), which also needs to be supported
** by various functions using MustRedrawTile,..
*/
local void DoScrollArea(enum _scroll_state_ TempScrollState, int FastScroll)
{
switch( TempScrollState ) {
case ScrollUp:
if( MapY ) {
if( FastScroll ) {
if( MapY<MapHeight/2 ) {
MapY=0;
} else {
MapY-=MapHeight/2;
}
} else {
--MapY;
}
MustRedraw|=RedrawMaps|RedrawCursors;
}
break;
int stepx,stepy;
case ScrollDown:
if( MapY<TheMap.Height-MapHeight ) {
if( FastScroll ) {
if( MapY<TheMap.Height-MapHeight-MapHeight/2 ) {
MapY+=MapHeight/2;
} else {
MapY=TheMap.Height-MapHeight;
}
} else {
++MapY;
}
MustRedraw|=RedrawMaps|RedrawCursors;
}
break;
case ScrollLeft:
if( MapX ) {
if( FastScroll ) {
if( MapX<MapWidth/2 ) {
MapX=0;
} else {
MapX-=MapWidth/2;
}
} else {
--MapX;
}
MustRedraw|=RedrawMaps|RedrawCursors;
}
break;
case ScrollLeftUp:
if( MapX ) {
if( FastScroll ) {
if( MapX<MapWidth/2 ) {
MapX=0;
} else {
MapX-=MapWidth/2;
}
} else {
--MapX;
}
MustRedraw|=RedrawMaps|RedrawCursors;
}
if( MapY ) {
if( FastScroll ) {
if( MapY<MapHeight/2 ) {
MapY=0;
} else {
MapY-=MapHeight/2;
}
} else {
--MapY;
}
MustRedraw|=RedrawMaps|RedrawCursors;
}
break;
case ScrollLeftDown:
if( MapX ) {
if( FastScroll ) {
if( MapX<MapWidth/2 ) {
MapX=0;
} else {
MapX-=MapWidth/2;
}
} else {
--MapX;
}
MustRedraw|=RedrawMaps|RedrawCursors;
}
if( MapY<TheMap.Height-MapHeight ) {
if( FastScroll ) {
if( MapY<TheMap.Height-MapHeight-MapHeight/2 ) {
MapY+=MapHeight/2;
} else {
MapY=TheMap.Height-MapHeight;
}
} else {
++MapY;
}
MustRedraw|=RedrawMaps|RedrawCursors;
}
break;
case ScrollRight:
if( MapX<TheMap.Width-MapWidth ) {
if( FastScroll ) {
if( MapX<TheMap.Width-MapWidth-MapWidth/2 ) {
MapX+=MapWidth/2;
} else {
MapX=TheMap.Width-MapWidth;
}
} else {
++MapX;
}
MustRedraw|=RedrawMaps|RedrawMinimapCursor;
}
break;
case ScrollRightUp:
if( MapX<TheMap.Width-MapWidth ) {
if( FastScroll ) {
if( MapX<TheMap.Width-MapWidth-MapWidth/2 ) {
MapX+=MapWidth/2;
} else {
MapX=TheMap.Width-MapWidth;
}
} else {
++MapX;
}
MustRedraw|=RedrawMaps|RedrawMinimapCursor;
}
if( MapY ) {
if( FastScroll ) {
if( MapY<MapHeight/2 ) {
MapY=0;
} else {
MapY-=MapHeight/2;
}
} else {
--MapY;
}
MustRedraw|=RedrawMaps|RedrawCursors;
}
break;
case ScrollRightDown:
if( MapX<TheMap.Width-MapWidth ) {
if( FastScroll ) {
if( MapX<TheMap.Width-MapWidth-MapWidth/2 ) {
MapX+=MapWidth/2;
} else {
MapX=TheMap.Width-MapWidth;
}
} else {
++MapX;
}
MustRedraw|=RedrawMaps|RedrawMinimapCursor;
}
if( MapY<TheMap.Height-MapHeight ) {
if( FastScroll ) {
if( MapY<TheMap.Height-MapHeight-MapHeight/2 ) {
MapY+=MapHeight/2;
} else {
MapY=TheMap.Height-MapHeight;
}
} else {
++MapY;
}
MustRedraw|=RedrawMaps|RedrawCursors;
}
break;
default:
break;
if( FastScroll ) {
stepx=MapWidth/2;
stepy=MapHeight/2;
}
else {
stepx=stepy=1;// dynamic: let these variables increase upto FastScroll..
}
switch( TempScrollState ) {
case ScrollUp:
move_up( stepy );
break;
case ScrollDown:
move_down( stepy );
break;
case ScrollLeft:
move_left( stepx );
break;
case ScrollLeftUp:
move_left( stepx );
move_up( stepy );
break;
case ScrollLeftDown:
move_left( stepx );
move_down( stepy );
break;
case ScrollRight:
move_right( stepx );
break;
case ScrollRightUp:
move_right( stepx );
move_up( stepy );
break;
case ScrollRightDown:
move_right( stepx );
move_down( stepy );
break;
default:
return; // skip marking map
}
MarkDrawEntireMap();
MustRedraw|=RedrawMinimap|RedrawCursors;
}
/**
@ -262,6 +172,7 @@ global void UpdateDisplay(void)
if( MustRedraw&RedrawMap ) {
if (InterfaceState == IfaceStateNormal) {
#ifndef NEW_MAPDRAW
int i;
// FIXME: only needed until flags are correct set
@ -271,20 +182,21 @@ global void UpdateDisplay(void)
for( i=0; i<MapHeight*MapWidth; ++i ) {
MustRedrawTile[i]=1;
}
#endif
SetClipping(TheUI.MapX,TheUI.MapY,TheUI.MapWidth,TheUI.MapHeight);
SetClipping(TheUI.MapX,TheUI.MapY,TheUI.MapEndX,TheUI.MapEndY);
DrawMapBackground(MapX,MapY);
DrawUnits();
DrawMapFogOfWar(MapX,MapY);
DrawMissiles();
DrawConsole();
SetClipping(0,0,VideoWidth,VideoHeight);
SetClipping(0,0,VideoWidth-1,VideoHeight-1);
}
// FIXME: trick17! must find a better solution
// Resources over map!
if( TheUI.MapX<TheUI.ResourceX && TheUI.MapWidth>TheUI.ResourceX ) {
if( TheUI.MapX<=TheUI.ResourceX && TheUI.MapEndX>=TheUI.ResourceX ) {
MustRedraw|=RedrawResources;
}
}
@ -358,7 +270,7 @@ global void UpdateDisplay(void)
// 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)
if( OldCursorX!=(CursorX-GameCursor->HotX)
|| OldCursorY!=(CursorY-GameCursor->HotY)
|| OldCursorW!=VideoGraphicWidth(GameCursor->Sprite)
|| OldCursorH!=VideoGraphicHeight(GameCursor->Sprite) ) {
@ -389,7 +301,7 @@ global void UpdateDisplay(void)
if( MustRedraw&RedrawMap ) {
// FIXME: split into small parts see RedrawTile and RedrawRow
InvalidateArea(TheUI.MapX,TheUI.MapY
,TheUI.MapWidth-TheUI.MapX,TheUI.MapHeight-TheUI.MapY);
,TheUI.MapEndX-TheUI.MapX+1,TheUI.MapEndY-TheUI.MapY+1);
}
if( (MustRedraw&RedrawFiller1) && TheUI.Filler1.Graphic ) {
InvalidateArea(TheUI.Filler1X,TheUI.Filler1Y
@ -430,7 +342,7 @@ global void UpdateDisplay(void)
,TheUI.StatusLine.Graphic->Height);
}
/* if (MustRedraw) */ {
// FIXME: JOHNS: That didn't work: if (MustRedraw&RedrawCursor)
// 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));
@ -441,6 +353,17 @@ global void UpdateDisplay(void)
}
}
/**
** Enable everything to be drawn for next display update.
** Used at start of mainloop (and possible refresh as user option)
**
*/
local void EnableDrawRefresh(void)
{
MustRedraw=RedrawEverything;
MarkDrawEntireMap();
}
/**
** Game main loop.
**
@ -454,7 +377,7 @@ global void UpdateDisplay(void)
global void GameMainLoop(void)
{
SetVideoSync();
MustRedraw=RedrawEverything;
EnableDrawRefresh();
GameCursor=&Cursors[CursorTypePoint];
for( ;; ) {

View file

@ -185,7 +185,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"fireball.png",
32,32,
{ "fireball hit" },
MissileClassPointToPoint,
MissileClassPointToPoint,
1,
},
{ MissileTypeType,
@ -193,7 +193,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"flame shield.png",
32,32,
{ NULL },
MissileClassFlameShield,
MissileClassFlameShield,
1,
},
{ MissileTypeType,
@ -210,7 +210,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"death and decay.png",
32,32,
{ NULL },
MissileClassDeathDecay,
MissileClassDeathDecay,
1,
},
{ MissileTypeType,
@ -218,7 +218,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"big cannon.png",
16,16,
{ "explosion" },
MissileClassPointToPoint,
MissileClassPointToPoint,
1,
"missile-cannon-tower-explosion", NULL,
},
@ -227,7 +227,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"exorcism.png",
48,48,
{ NULL },
MissileClassPointToPoint,
MissileClassPointToPoint,
1,
},
{ MissileTypeType,
@ -235,7 +235,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"heal effect.png",
48,48,
{ NULL },
MissileClassStayWithDelay,
MissileClassStayWithDelay,
1,
},
{ MissileTypeType,
@ -251,7 +251,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"rune.png",
16,16,
{ NULL },
MissileClassStayWithDelay,
MissileClassStayWithDelay,
5,
},
{ MissileTypeType,
@ -259,7 +259,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"tornado.png",
56,56,
{ NULL },
MissileClassWhirlwind,
MissileClassWhirlwind,
1,
},
{ MissileTypeType,
@ -276,7 +276,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"ballista bolt.png",
64,64,
{ "explosion" },
MissileClassPointToPoint,
MissileClassPointToPoint,
1,
"missile-impact", NULL,
},
@ -285,7 +285,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"arrow.png",
40,40,
{ "bow-hit" },
MissileClassPointToPoint,
MissileClassPointToPoint,
1,
},
{ MissileTypeType,
@ -293,7 +293,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"axe.png",
32,32,
{ "bow-hit" },
MissileClassPointToPoint,
MissileClassPointToPoint,
1,
},
{ MissileTypeType,
@ -301,7 +301,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"submarine missile.png",
40,40,
{ "explosion" },
MissileClassPointToPoint,
MissileClassPointToPoint,
1,
"missile-impact", NULL,
},
@ -310,7 +310,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"turtle missile.png",
40,40,
{ "explosion" },
MissileClassPointToPoint,
MissileClassPointToPoint,
1,
"missile-impact", NULL,
},
@ -319,7 +319,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"small fire.png",
32,48,
{ NULL },
MissileClassFire,
MissileClassFire,
8,
},
{ MissileTypeType,
@ -327,15 +327,15 @@ global MissileType MissileTypes[MissileTypeMax] = {
"big fire.png",
48,48,
{ NULL },
MissileClassFire,
8,
MissileClassFire,
8,
},
{ MissileTypeType,
"missile-impact",
"ballista-catapult impact.png",
48,48,
{ NULL },
MissileClassStayWithDelay,
MissileClassStayWithDelay,
1,
},
{ MissileTypeType,
@ -343,7 +343,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"normal spell.png",
32,32,
{ NULL },
MissileClassStayWithDelay,
MissileClassStayWithDelay,
1,
},
{ MissileTypeType,
@ -351,7 +351,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"explosion.png",
64,64,
{ NULL },
MissileClassStayWithDelay,
MissileClassStayWithDelay,
1,
},
{ MissileTypeType,
@ -368,7 +368,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"cannon explosion.png",
32,32,
{ NULL },
MissileClassStayWithDelay,
MissileClassStayWithDelay,
1,
},
{ MissileTypeType,
@ -376,7 +376,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"cannon-tower explosion.png",
32,32,
{ NULL },
MissileClassStayWithDelay,
MissileClassStayWithDelay,
1,
},
{ MissileTypeType,
@ -384,7 +384,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
"daemon fire.png",
32,32,
{ NULL },
MissileClassPointToPoint,
MissileClassPointToPoint,
1,
},
{ MissileTypeType,
@ -400,7 +400,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
NULL,
32,32,
{ NULL },
MissileClassNone,
MissileClassNone,
1,
},
{ MissileTypeType,
@ -424,7 +424,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
NULL,
32,32,
{ NULL },
MissileClassCustom,
MissileClassCustom,
1,
},
{ MissileTypeType,
@ -432,7 +432,7 @@ global MissileType MissileTypes[MissileTypeMax] = {
NULL,
32,32,
{ NULL },
MissileClassNone,
MissileClassNone,
1,
},
};
@ -514,7 +514,7 @@ global MissileType* MissileTypeByIdent(const char* ident)
type=(MissileType**)hash_find(MissileHash,(char*)ident);
if( type ) {
if( type ) {
return *type;
}
@ -604,14 +604,14 @@ local int CalculateDamageStats( const UnitStats* attacker_stats,
int damage;
int basic_damage = attacker_stats->BasicDamage;
int piercing_damage = attacker_stats->PiercingDamage;
if (bloodlust)
{
basic_damage *= 2;
piercing_damage *= 2;
printf("bloodlust\n");
}
damage=-goal_stats->Armor;
damage+= basic_damage;
if( damage<0 ) {
@ -806,15 +806,30 @@ global void FireMissile(Unit* unit)
// Damage of missile
//
missile->SourceUnit=unit;
unit->Refs++;
unit->Refs++;
}
/**
** Check missile visibility.
** Get area of tiles covered by missile
**
** @param missile Missile pointer to check if visible.
** @param missile Missile to be checked and set.
** @return sx,sy,ex,ey defining area in Map
*/
local void GetMissileMapArea( const Missile* missile,
int *sx, int *sy, int *ex, int *ey )
{
*sx=missile->X/TileSizeX;
*sy=missile->Y/TileSizeY;
*ex=(missile->X+missile->Type->Width)/TileSizeX;
*ey=(missile->Y+missile->Type->Height)/TileSizeY;
}
/**
** Check missile visibility.
**
** @return Returns true if visibile, false otherwise.
** @param missile Missile pointer to check if visible.
**
** @return Returns true if visibile, false otherwise.
*/
local int MissileVisible(const Missile* missile)
{
@ -822,14 +837,9 @@ local int MissileVisible(const Missile* missile)
int tileMaxX;
int tileMinY;
int tileMaxY;
tileMinX=missile->X/TileSizeX;
tileMinY=missile->Y/TileSizeY;
tileMaxX=(missile->X+missile->Type->Width)/TileSizeX;
tileMaxY=(missile->Y+missile->Type->Height)/TileSizeY;
if ( (tileMinX>(MapX+MapWidth)) || (tileMaxX<MapX)
|| (tileMinY>MapY+MapHeight) || (tileMaxY<MapY)) {
return 0;
GetMissileMapArea(missile,&tileMinX,&tileMinY,&tileMaxX,&tileMaxY);
if ( !AreaVisibleInMap(tileMinX,tileMinY,tileMaxX,tileMaxY) ) {
return 0;
}
DebugLevel3Fn("Missile bounding box %d %d %d %d (Map %d %d %d %d)\n",
tileMinX,tileMaxX,tileMinY,tileMaxY,
@ -837,6 +847,20 @@ local int MissileVisible(const Missile* missile)
return 1;
}
/**
** Check and sets if missile must be drawn on screen-map
**
** @param missile Missile to be checked.
** @return True if map marked to be drawn, false otherwise.
*/
local int CheckMissileToBeDrawn(const Missile* missile)
{
int sx,sy,ex,ey;
GetMissileMapArea( missile, &sx, &sy, &ex, &ey );
return MarkDrawAreaMap( sx, sy, ex, ey );
}
/**
** Draw missile.
*/
@ -1099,7 +1123,7 @@ global void MissileHit(const Missile* missile)
}
if ( BlizzardMissileHit && goal == missile->SourceUnit )
return; // blizzard cannot hit owner unit
BlizzardMissileHit = 0;
BlizzardMissileHit = 0;
if ( missile->Damage )
HitUnit(goal,missile->Damage); // direct damage, spells mostly
else
@ -1123,11 +1147,11 @@ global void MissileActions(void)
if( missile->Wait-- ) {
continue;
}
if ( missile->TTL != -1 ) {
missile->TTL--; // overall time to live if specified
}
if ( missile->Controller ) {
missile->Controller( missile );
}
@ -1141,12 +1165,8 @@ global void MissileActions(void)
missile->Wait=missile->Type->Speed;
continue; // custom missiles are handled by Controller() only
}
if (MissileVisible(missile)) {
// check before movement
MustRedraw|=RedrawMap;
// FIXME: must mark the exact tile, for more optimazation
}
CheckMissileToBeDrawn(missile); //StephanR FIXME:needed here?
switch( missile->Type->Class ) {
//
@ -1254,9 +1274,9 @@ global void MissileActions(void)
}
}
break;
case MissileClassDeathDecay:
//NOTE: vladi: this is exact copy of MissileClassStayWithDelay
case MissileClassDeathDecay:
//NOTE: vladi: this is exact copy of MissileClassStayWithDelay
// but with check for blizzard-type hit (friendly fire:))
missile->Wait=missile->Type->Speed;
if( ++missile->Frame
@ -1266,7 +1286,7 @@ global void MissileActions(void)
missile->Type=MissileFree;
}
break;
case MissileClassWhirlwind:
missile->Wait=missile->Type->Speed;
missile->Frame++;
@ -1356,10 +1376,9 @@ global void MissileActions(void)
}
if (missile->Type!=MissileFree && MissileVisible(missile)) {
if (missile->Type!=MissileFree) {
// check after movement
MustRedraw|=RedrawMap;
// FIXME: must mark the exact tile, for more optimazation
CheckMissileToBeDrawn(missile);
}
}
}

View file

@ -53,9 +53,12 @@ global Unit* Selected[MaxSelectable] = {
*/
global void UnSelectAll(void)
{
Unit *u;
while( NumSelected ) {
Selected[--NumSelected]->Selected=0;
Selected[NumSelected]=NoUnitP; // FIXME: only needed for old code
u=Selected[--NumSelected];
Selected[NumSelected]=NoUnitP; // FIXME: only needed for old code
u->Selected=0;
CheckUnitToBeDrawn(u);
}
}
@ -67,14 +70,16 @@ global void UnSelectAll(void)
*/
global void ChangeSelectedUnits(Unit** units,int count)
{
Unit *u;
int i;
DebugCheck( count>MaxSelectable );
UnSelectAll();
for( i=0; i<count; i++ ) {
Selected[i]=units[i];
Selected[i]->Selected=1;
Selected[i]=u=units[i];
u->Selected=1;
CheckUnitToBeDrawn(u);
}
NumSelected=count;
}
@ -92,7 +97,7 @@ global int SelectUnit(Unit* unit)
{
return 0; // Revealers cannot be selected
}
if( NumSelected == MaxSelectable ) {
return 0;
}
@ -103,6 +108,7 @@ global int SelectUnit(Unit* unit)
Selected[NumSelected++]=unit;
unit->Selected=1;
CheckUnitToBeDrawn(unit);
return 1;
}
@ -139,6 +145,7 @@ global void UnSelectUnit(Unit* unit)
}
Selected[NumSelected]=NoUnitP; // FIXME: only needed for old code
unit->Selected=0;
CheckUnitToBeDrawn(unit);
}
/**
@ -183,6 +190,7 @@ global int SelectUnitsByType(Unit* base)
DebugLevel3Fn(" (%d)\n",base->UnitType->Type);
// select all visible units.
// StephanR: should be (MapX,MapY,MapX+MapWidth-1,MapY+MapHeight-1) ???
r=SelectUnits(MapX-1,MapY-1,MapX+MapWidth+1,MapY+MapHeight+1,table);
// if unit is a cadaver or hidden (not on map)
@ -201,6 +209,7 @@ global int SelectUnitsByType(Unit* base)
Selected[0]=base;
base->Selected=1;
NumSelected=1;
CheckUnitToBeDrawn(base);
// if unit isn't belonging to the player, or is a static unit
// (like a building), only 1 unit can be selected at the same time.
@ -226,6 +235,7 @@ global int SelectUnitsByType(Unit* base)
}
Selected[NumSelected++]=unit;
unit->Selected=1;
CheckUnitToBeDrawn(unit);
if( NumSelected==MaxSelectable ) {
break;
}
@ -327,7 +337,7 @@ global int AddSelectedUnitsInRectangle(int tx,int ty,int w,int h)
return NumSelected;
}
// Check if the original selected unit (if it's alone) is ours,
// Check if the original selected unit (if it's alone) is ours,
// and can be selectable by rectangle.
// In this case, do nothing.
if( NumSelected == 1 &&
@ -392,12 +402,12 @@ global int SelectUnitsInRectangle(int tx,int ty,int w,int h)
}
// FIXME: Can we get this?
#ifdef NEW_ORDERS
if( !unit->Removed && unit->Orders[0].Action!=UnitActionDie ) {
if( !unit->Removed && unit->Orders[0].Action!=UnitActionDie ) {
SelectSingleUnit(unit);
return 1;
}
#else
if( !unit->Removed && unit->Command.Action!=UnitActionDie ) {
if( !unit->Removed && unit->Command.Action!=UnitActionDie ) {
SelectSingleUnit(unit);
return 1;
}

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name clone.c - The main file. */
/*
** (c) Copyright 1998-2001 by Lutz Sammer
**
** $Id$
*/
//
// (c) Copyright 1998-2001 by Lutz Sammer
//
// $Id$
//@{
@ -294,7 +293,7 @@ Use it at your own risk.\n"
//
// Show title screen.
//
SetClipping(0,0,VideoWidth,VideoHeight);
SetClipping(0,0,VideoWidth-1,VideoHeight-1);
if( TitleScreen ) {
DisplayPicture(TitleScreen);
}
@ -307,7 +306,7 @@ Use it at your own risk.\n"
UpdateStats();
InitUnitTypes();
//
//
// Inital menues require some gfx..
//
LoadRGB(GlobalPalette, strdcat(FreeCraftLibPath, "/summer.rgb"));

View file

@ -549,7 +549,7 @@ global void DrawMessage(void)
DrawText(TheUI.MapX+8,TheUI.MapY+8 + z*16,GameFont,Messages[z] );
}
if ( MessagesCount < 1 )
SameMessageCount = 0;
SameMessageCount = 0;
}
/**
@ -590,8 +590,8 @@ global int CheckRepeatMessage( const char* msg )
// NOTE: vladi: yep it's a tricky one, but should work fine prbably :)
sprintf( temp, "Last message repeated ~<%d~> times", n+1 );
AddMessage( temp );
}
return 0;
}
return 0;
}
/**
@ -609,7 +609,9 @@ global void SetMessage( char* fmt, ... )
if ( CheckRepeatMessage( temp ) )
return;
AddMessage( temp );
MustRedraw|=RedrawMessage|RedrawMap;
MustRedraw|=RedrawMessage;
//FIXME: for performance the minimal area covered by msg's should be used
MarkDrawEntireMap();
MessageFrameTimeout = FrameCounter + MESSAGES_TIMEOUT;
}
@ -634,17 +636,19 @@ global void SetMessage2( int x, int y, char* fmt, ... )
{
AddMessage( temp );
}
if ( MessagesEventCount == MESSAGES_MAX )
ShiftMessagesEvent();
strcpy( MessagesEvent[ MessagesEventCount ], temp );
MessagesEventX[ MessagesEventCount ] = x;
MessagesEventY[ MessagesEventCount ] = y;
MessagesEventIndex = MessagesEventCount;
MessagesEventCount++;
MustRedraw|=RedrawMessage|RedrawMap;
MustRedraw|=RedrawMessage;
//FIXME: for performance the minimal area covered by msg's should be used
MarkDrawEntireMap();
MessageFrameTimeout = FrameCounter + MESSAGES_TIMEOUT;
}

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name menubuttons.c - The menu buttons. */
/*
** (c) Copyright 1999,2000 by Andreas Arens
**
** $Id$
*/
//
// (c) Copyright 1999-2001 by Andreas Arens
//
// $Id$
//@{
@ -55,7 +54,7 @@ local void GameMenuSave(void);
local void GameMenuEnd(void);
local void GameMenuReturn(void);
local void StartMenusSetBackground(Menuitem *mi);
local void StartMenusSetBackground(Menuitem *mi);
local void NameLineDrawFunc(Menuitem *mi);
local void EnterNameAction(Menuitem *mi, int key);
local void EnterNameCancel(void);
@ -591,7 +590,7 @@ local void DrawPulldown(Menuitem *mi, unsigned mx, unsigned my)
h *= i;
while (i--) {
PushClipping();
SetClipping(0,0,x+w,VideoHeight);
SetClipping(0,0,x+w,VideoHeight-1);
VideoDrawClip(MenuButtonGfx.Sprite, rb, x-1, y-1 + oh*i);
PopClipping();
text = mi->d.pulldown.options[i];
@ -615,9 +614,9 @@ local void DrawPulldown(Menuitem *mi, unsigned mx, unsigned my)
SetDefaultTextColors(rc,rc);
}
}
PushClipping();
SetClipping(0,0,x+w-20,VideoHeight);
SetClipping(0,0,x+w-20,VideoHeight-1);
VideoDrawClip(MenuButtonGfx.Sprite, rb, x-1, y-1);
PopClipping();
VideoDraw(MenuButtonGfx.Sprite, MBUTTON_DOWN_ARROW + rb - MBUTTON_PULLDOWN, x-1 + w-20, y-2);
@ -659,12 +658,12 @@ local void DrawListbox(Menuitem *mi, unsigned mx, unsigned my)
if (flags&MenuButtonDisabled) {
rb--;
}
}
i = mi->d.listbox.nlines;
s = mi->d.listbox.startline;
while (i--) {
PushClipping();
SetClipping(0,0,x+w,VideoHeight);
SetClipping(0,0,x+w,VideoHeight-1);
VideoDrawClip(MenuButtonGfx.Sprite, rb, x-1, y-1 + 18*i);
PopClipping();
if (!(flags&MenuButtonDisabled)) {
@ -711,14 +710,14 @@ local void DrawVSlider(Menuitem *mi, unsigned mx, unsigned my)
if (flags&MenuButtonDisabled) {
PushClipping();
SetClipping(0,0,VideoWidth,y + h - 20);
SetClipping(0,0,VideoWidth-1,y + h - 20);
VideoDrawClip(MenuButtonGfx.Sprite, MBUTTON_S_VCONT - 1, x, y - 2);
PopClipping();
VideoDraw(MenuButtonGfx.Sprite, MBUTTON_UP_ARROW - 1, x, y - 2);
VideoDraw(MenuButtonGfx.Sprite, MBUTTON_DOWN_ARROW - 1, x, y + h - 20);
} else {
PushClipping();
SetClipping(0,0,VideoWidth,y + h - 20);
SetClipping(0,0,VideoWidth-1,y + h - 20);
VideoDrawClip(MenuButtonGfx.Sprite, MBUTTON_S_VCONT, x, y - 2);
PopClipping();
if (mi->d.vslider.cflags&MI_CFLAGS_UP) {
@ -770,9 +769,9 @@ local void DrawInput(Menuitem *mi, unsigned mx, unsigned my)
rb--;
SetDefaultTextColors(FontGrey,FontGrey);
}
PushClipping();
SetClipping(0,0,x+w,VideoHeight);
SetClipping(0,0,x+w,VideoHeight-1);
VideoDrawClip(MenuButtonGfx.Sprite, rb, x-1, y-1);
PopClipping();
text = mi->d.input.buffer;
@ -890,7 +889,7 @@ local void GameMenuReturn(void)
MustRedraw &= ~RedrawMenu;
InterfaceState = IfaceStateNormal;
ClearStatusLine();
MustRedraw |= RedrawMap;
MarkDrawEntireMap(); //FIXME: some tiles could be left as they were?
GamePaused = 0;
}
@ -991,7 +990,7 @@ local void MultiPlayerGameMenu(void)
if (EnterNameMenuItems[1].d.input.nch == 0) {
return;
}
NameBuf[EnterNameMenuItems[1].d.input.nch] = 0; // Now finally here is the name
strcpy(NetworkName, NameBuf);
// Here we really go...
@ -1348,7 +1347,7 @@ local void CustomGameCancel(void)
FreePudInfo(ScenSelectPudInfo);
ScenSelectPudInfo = NULL;
EndMenu();
}
local void CustomGameStart(void)
@ -2017,7 +2016,7 @@ global void ProcessMenu(int MenuId, int Loop)
Menu *menu;
Menuitem *mi;
int CurrentMenuSave = -1, MenuButtonUnderCursorSave = -1, MenuButtonCurSelSave = -1;
// Recursion protection:
if (Loop) {
CurrentMenuSave = CurrentMenu;
@ -2138,7 +2137,7 @@ global void InitMenus(unsigned int race)
// ARI FIXME: Hack to disable Expansion Gfx..
// also shows how to add new tilesets....
CustomGameMenuItems[14].d.pulldown.noptions = 4;
}
}

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name mouse.c - The mouse handling. */
/*
** (c) Copyright 1998-2000 by Lutz Sammer
**
** $Id$
*/
//
// (c) Copyright 1998-2001 by Lutz Sammer
//
// $Id$
//@{
@ -229,7 +228,7 @@ global void DoRightButton(int x,int y)
dest=TargetOnMapTile(unit,x,y);
if( dest ) {
dest->Blink=3;
if( dest->Player==ThisPlayer ||
if( dest->Player==ThisPlayer ||
dest->Player->Player==PlayerNumNeutral) {
// FIXME: lokh: maybe we should add the ally players here
// FIXME: don't work must check repairable first
@ -400,14 +399,14 @@ local void HandleMouseOn(int x,int y)
//
// Map
//
if( x>=TheUI.MapX && x<TheUI.MapWidth
&& y>=TheUI.MapY && y<TheUI.MapHeight ) {
if( x>=TheUI.MapX && x<=TheUI.MapEndX
&& y>=TheUI.MapY && y<=TheUI.MapEndY ) {
CursorOn=CursorOnMap;
} else {
CursorOn=-1;
}
//
//
// Scrolling Region Handling
// FIXME: perhaps I should change the complete scroll handling.
// FIXME: show scrolling cursor only, if scrolling is possible
@ -541,7 +540,7 @@ global void UIHandleMouseMove(int x,int y)
{
UnitUnderCursor = NULL;
}
//
// Selecting target.
//
@ -581,7 +580,7 @@ global void UIHandleMouseMove(int x,int y)
}
GameCursor=&Cursors[CursorTypeGlass];
}
#ifdef FLAG_DEBUG // ARI: Disabled by introducing flag debug!
IfDebug( DrawMouseCoordsOnMap(x,y); );
#endif
@ -795,21 +794,21 @@ local void SendSpellCast(int x,int y)
int i;
Unit* unit;
Unit* dest;
dest=UnitOnMapTile(x,y);
DebugLevel3Fn("SpellCast on: %p (%d,%d)\n", dest, x, y);
/* NOTE: Vladi:
This is a high-level function, it sends target spot and unit
(if exists). All checks are performed at spell cast handle
(if exists). All checks are performed at spell cast handle
function which will cancel function if cannot be executed
*/
for( i=0; i<NumSelected; i++ ) {
unit=Selected[i];
if( !unit->Type->CanCastSpell )
if( !unit->Type->CanCastSpell )
continue; // this unit cannot cast spell
if( dest && unit == dest )
if( dest && unit == dest )
continue; // no unit can cast spell on himself
// CursorValue here holds the spell type id
// CursorValue here holds the spell type id
SendCommandSpellCast(unit,x,y,dest,CursorValue,!(KeyModifiers&ModifierShift));
}
}
@ -852,7 +851,7 @@ local void SendCommand(int x,int y)
case B_Demolish:
SendDemolish(x,y);
break;
case B_SpellCast:
case B_SpellCast:
SendSpellCast(x,y);
break;
default:
@ -947,7 +946,7 @@ global void UIHandleButtonDown(int b)
,CursorX,CursorY,CursorBuilding-UnitTypes);
// FIXME: error messages
if( CanBuildUnitType(Selected[0],CursorBuilding,x,y)
if( CanBuildUnitType(Selected[0],CursorBuilding,x,y)
// FIXME: vladi: should check all building footprint
// but not just MAPEXPLORED(x,y)
&& IsMapFieldExplored(x,y) ) {
@ -987,7 +986,7 @@ global void UIHandleButtonDown(int b)
unit->Blink=3;
} else { // if not not click on building -- green cross
MakeMissile(MissileTypeGreenCross
,MapX*TileSizeX+CursorX-TheUI.MapX
,MapX*TileSizeX+CursorX-TheUI.MapX
,MapY*TileSizeY+CursorY-TheUI.MapY,0,0);
}
DoRightButton(Screen2MapX(CursorX),Screen2MapY(CursorY));
@ -1151,7 +1150,7 @@ global void UIHandleButtonUp(int b)
} else if( Selected[0]->Burning ) {
// FIXME: use GameSounds.Burning
PlayGameSound(SoundIdForName("burning"),MaxSampleVolume);
} else if( Selected[0]->Player==ThisPlayer
} else if( Selected[0]->Player==ThisPlayer
|| Selected[0]->Player->Race==PlayerRaceNeutral ) {
PlayUnitSound(Selected[0],VoiceSelected);
} else {

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name ccl_ui.c - The ui ccl functions. */
/*
** (c) Copyright 1999,2000 by Lutz Sammer
**
** $Id$
*/
//
// (c) Copyright 1999-2001 by Lutz Sammer
//
// $Id$
//@{
@ -605,14 +604,24 @@ local SCM CclDefineUI(SCM list)
y=gh_scm2int(value);
ui->MapX=x;
ui->MapY=y;
if ( ui->MapX < 0 || ui->MapY < 0 ) {
fprintf(stderr,"map top-left point expected\n");
return SCM_UNSPECIFIED;
}
value=gh_car(temp);
temp=gh_cdr(temp);
x=gh_scm2int(value);
value=gh_car(temp);
temp=gh_cdr(temp);
y=gh_scm2int(value);
ui->MapWidth=x;
ui->MapHeight=y;
//StephanR: note that the bottom-right point is one pixel off
ui->MapEndX=x - 1;
ui->MapEndY=y - 1;
if ( ui->MapEndX < 0 || ui->MapEndY < 0 ||
ui->MapEndX < ui->MapX || ui->MapEndY < ui->MapY ) {
fprintf(stderr,"map bottom-right point expected\n");
return SCM_UNSPECIFIED;
}
// MenuButton
temp=gh_car(list);
@ -743,7 +752,7 @@ local SCM CclDefineUI(SCM list)
y=gh_scm2int(value);
ui->Buttons2[i].Height=y;
}
return SCM_UNSPECIFIED;
}
@ -753,7 +762,7 @@ local SCM CclDefineUI(SCM list)
local SCM CclMouseScrollSpeed(SCM num)
{
int speed;
speed=gh_scm2int(num);
if (speed < 1 || speed > FRAMES_PER_SECOND) {
SpeedMouseScroll=MOUSE_SCROLL_SPEED;
@ -768,7 +777,7 @@ local SCM CclMouseScrollSpeed(SCM num)
local SCM CclKeyScrollSpeed(SCM num)
{
int speed;
speed=gh_scm2int(num);
if (speed < 1 || speed > FRAMES_PER_SECOND) {
SpeedKeyScroll=KEY_SCROLL_SPEED;
@ -847,7 +856,7 @@ global void UserInterfaceCclRegister(void)
gh_new_procedure0_0("right-button-attacks",CclRightButtonAttacks);
gh_new_procedure0_0("right-button-moves",CclRightButtonMoves);
gh_new_procedure0_0("fancy-buildings",CclFancyBuildings);
}
#endif // } USE_CCL

View file

@ -9,11 +9,10 @@
// FreeCraft - A free fantasy real time strategy game engine
//
/**@name ui.c - The user interface globals. */
/*
** (c) Copyright 1999,2000 by Lutz Sammer and Andreas Arens
**
** $Id$
*/
//
// (c) Copyright 1999-2001 by Lutz Sammer and Andreas Arens
//
// $Id$
//@{
@ -397,8 +396,8 @@ global void InitUserInterface(void)
//
// Calculations
//
MapWidth=(TheUI.MapWidth-TheUI.MapX)/TileSizeX;
MapHeight=(TheUI.MapHeight-TheUI.MapY)/TileSizeY;
MapWidth=(TheUI.MapEndX-TheUI.MapX+TileSizeX)/TileSizeX;
MapHeight=(TheUI.MapEndY-TheUI.MapY+TileSizeY)/TileSizeY;
}
//@}

View file

@ -50,7 +50,7 @@
----------------------------------------------------------------------------*/
global Unit* UnitSlots[MAX_UNIT_SLOTS]; /// All possible units
global Unit** UnitSlotFree; /// First free unit slot
global Unit** UnitSlotFree; /// First free unit slot
local Unit* ReleasedHead; /// List of released units.
local Unit** ReleasedTail; /// List tail of released units.
@ -459,7 +459,7 @@ global void RemoveUnit(Unit* unit)
DebugLevel3Fn("%Zd %p %p\n",UnitNumber(unit),unit,unit->Next);
UnitCacheRemove(unit);
#ifdef UNIT_ON_MAP
if( 0 ) {
if( 0 ) {
Unit* list;
list=TheMap.Fields[unit->Y*TheMap.Width+unit->X].Here.Units;
@ -475,9 +475,7 @@ global void RemoveUnit(Unit* unit)
#endif
MustRedraw|=RedrawMinimap;
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
}
CheckUnitToBeDrawn(unit);
}
/**
@ -517,7 +515,7 @@ global void UnitLost(const Unit* unit)
MustRedraw |= RedrawResources;
} else if( type==UnitTypeByIdent("unit-elven-lumber-mill")
|| type==UnitTypeByIdent("unit-troll-lumber-mill") ) {
if( !(HaveUnitTypeByIdent(player,"unit-elven-lumber-mill")
+HaveUnitTypeByIdent(player
,"unit-elven-lumber-mill")) ) {
@ -765,6 +763,58 @@ global int UnitVisible(const Unit* unit)
#endif
}
/**
** StephanR: Get area of tiles covered by unit, including its displacement
**
** @param unit Unit to be checked and set.
** @return sx,sy,ex,ey defining area in Map
*/
global void GetUnitMapArea( const Unit* unit,
int *sx, int *sy, int *ex, int *ey )
{
*sx = unit->X - (unit->IX < 0);
*ex = *sx + unit->Type->TileWidth - !unit->IX;
*sy = unit->Y - (unit->IY < 0);
*ey = *sy + unit->Type->TileHeight - !unit->IY;
}
/**
** Check and sets if unit must be drawn on screen-map
**
** @param unit Unit to be checked.
** @return True if map marked to be drawn, false otherwise.
*/
global int CheckUnitToBeDrawn(const Unit* unit)
{
#ifdef NEW_MAPDRAW
int sx,sy,ex,ey;
// in debug-mode check unsupported displacement exceeding an entire Tile
// FIXME: displacement could always be made positive and smaller than Tile
#if NEW_MAPDRAW > 1
if ( unit->IX <= -TileSizeX || unit->IX >= TileSizeX ||
unit->IY <= -TileSizeY || unit->IY >= TileSizeY )
printf( "internal error in CheckUnitToBeDrawn\n" );
#endif
GetUnitMapArea( unit, &sx, &sy, &ex, &ey );
// FIXME: extra tiles added here for attached statusbar/mana/shadow/..
sx--;sy--;ex++;ey++;
if ( MarkDrawAreaMap( sx, sy, ex, ey ) ) {
// MustRedraw|=RedrawMinimap;
return 1;
}
#else
if( UnitVisible( unit ) ) {
MustRedraw|=RedrawMap;
return 1;
}
#endif
return 0;
}
// FIXME: perhaps I should write a function UnitSelectable?
/**
@ -792,14 +842,14 @@ global void UnitIncrementMana(void)
unit->Mana++;
// some frames delayed done my color cycling
if( 0 && UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
if( 0 ) {
CheckUnitToBeDrawn(unit);
}
if( unit->Selected ) {
MustRedraw|=RedrawInfoPanel;
}
}
//
// decrease spells effects time
//
@ -807,7 +857,7 @@ global void UnitIncrementMana(void)
unit->Bloodlust--;
if ( unit->Haste > 0 )
unit->Haste--;
if ( unit->Slow > 0 )
if ( unit->Slow > 0 )
unit->Slow--;
if ( unit->Invisible > 0 )
unit->Invisible--;
@ -841,8 +891,8 @@ global void UnitIncrementHealth(void)
++unit->HP; // FIXME: how fast do we regenerate
// some frames delayed done my color cycling
if( 0 && UnitVisible(unit) ) {
MustRedraw|=RedrawMap;
if( 0 ) {
CheckUnitToBeDrawn(unit);
}
if( unit->Selected ) {
MustRedraw|=RedrawInfoPanel;
@ -998,7 +1048,7 @@ global void RescueUnits(void)
}
}
}
}
}
}
}
@ -1036,7 +1086,7 @@ local int myatan(int val)
** @param delta_x Delta X.
** @param delta_y Delta Y.
**
** @returns Angle (0..255)
** @returns Angle (0..255)
*/
global int DirectionToHeading(int delta_x,int delta_y)
{
@ -1194,9 +1244,7 @@ found:
#endif
MustRedraw|=RedrawMinimap;
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMaps;
}
CheckUnitToBeDrawn(unit);
}
/**
@ -1306,9 +1354,7 @@ global void DropOutNearest(Unit* unit,int gx,int gy,int addx,int addy)
#endif
MustRedraw|=RedrawMinimap;
if( UnitVisible(unit) ) {
MustRedraw|=RedrawMaps;
}
CheckUnitToBeDrawn(unit);
return;
}
++addy;
@ -2226,7 +2272,7 @@ global void HitUnit(Unit* unit,int damage)
{ //NOTE: vladi: units with active UnholyArmour are invulnerable
return;
}
type=unit->Type;
if( !unit->Attacked ) {
if( unit->Player==ThisPlayer ) {

View file

@ -17,7 +17,7 @@
// Real quad tree.
// Priority search tree.
//
// (c) Copyright 1998-2000 by Lutz Sammer
// (c) Copyright 1998-2001 by Lutz Sammer
//
// $Id$
@ -445,6 +445,7 @@ local int SelectQuadTreeLeaf(QuadTreeLeaf* leaf,QuadTreeValue** table,int index)
/**
** Select all values in a node.
** StephanR: why x1<=i,y1<=j and not x2>=i,y2>=j ???
*/
local int SelectQuadTreeNode(QuadTreeNode* node,int kx,int ky,int levels
,int x1,int y1,int x2,int y2,QuadTreeValue** table,int index)
@ -649,9 +650,7 @@ global void UnitCacheChange(Unit* unit)
*/
global int UnitCacheSelect(int x1,int y1,int x2,int y2,Unit** table)
{
int i;
int j;
int n;
int i,j,n,sx,sy,ex,ey;
Unit* unit;
//
@ -670,6 +669,7 @@ global int UnitCacheSelect(int x1,int y1,int x2,int y2,Unit** table)
y2=TheMap.Height;
}
/StephanR: seems to be within (i-1,j-1;x2,y2) ???
n=QuadTreeSelect(PositionCache,i,j,x2,y2,table);
//
@ -677,12 +677,10 @@ global int UnitCacheSelect(int x1,int y1,int x2,int y2,Unit** table)
//
for( i=j=0; i<n; ++i ) {
unit=table[i];
if( unit->X+unit->Type->TileWidth<=x1 || unit->X>x2
|| unit->Y+unit->Type->TileHeight<=y1 || unit->Y>y2 ) {
continue;
}
table[j++]=unit;
GetUnitMapArea( unit, &sx, &sy, &ex, &ey );
if( ex>=x1 && sx<=x2 && ey>=y1 && sy<=y2 ) {
table[j++]=unit;
}
}
return j;
@ -872,7 +870,7 @@ global int UnitCacheSelect(int x1,int y1,int x2,int y2,Unit** table)
for( n=0; y<y2; ++y ) {
mf=TheMap.Fields+y*TheMap.Width+x;
for( i=x; i<x2; ++i ) {
for( unit=mf->Here.Units; unit; unit=unit->Next ) {
IfDebug(
if( !unit->Type ) {

View file

@ -10,7 +10,7 @@
//
/**@name cursor.c - The cursors. */
//
// (c) Copyright 1998,2000 by Lutz Sammer
// (c) Copyright 1998,2000,2001 by Lutz Sammer
//
// $Id$
@ -138,16 +138,131 @@ 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
global int OldCursorSize; /// size of saved cursor image
global void* OldCursorImage; /// background saved behind cursor
global void* OldCursorImage; /// background saved behind cursor
global int OldCursorRectangleX; /// saved cursor position on screen X
global int OldCursorRectangleY; /// saved cursor position on screen Y
global int OldCursorRectangleW; /// saved cursor width in pixel
global int OldCursorRectangleH; /// saved cursor height in pixel
global void* OldCursorRectangle=NULL; /// background saved behind rectangle
/// Function pointer: Save background behind cursor
local void (*SaveCursorBackground)(int,int,int,int);
/// Function pointer: Load background behind cursor
local void (*LoadCursorBackground)(int,int,int,int);
/* Function pointer: Save rectangle behind 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 rectangle starting at left-top.
** @param h Height in pixels for rectangle starting at left-top.
**Pre: the complete rectangle 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 (*SaveCursorRectangle)(int x,int y,int w,int h);
/* Function pointer: Load rectangle behind cursor
** @param x Screen X pixels coordinate.
** @param y Screen Y pixels coordinate.
** @param w Width in pixels.
** @param h Height in pixels.
**Pre: rectangle previously saved with SaveCursorRectangle(x,y,w,h)
*/
local void (*LoadCursorRectangle)(int x,int y,int w,int h);
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
#define LOADCURSORRECTANGLE(video,memtype,x,y,w,h) { \
const memtype* sp; \
memtype* dp; \
sp=OldCursorRectangle; \
dp=video+y*VideoWidth+x; \
memcpy(dp,sp,w*sizeof(memtype)); \
if ( --h ) { \
sp+=w; \
dp+=VideoWidth; \
while( --h ) { \
*dp = *sp++; \
dp[w-1] = *sp++; \
dp+=VideoWidth; \
} \
memcpy(dp,sp,w*sizeof(memtype)); \
} \
}
#define SAVECURSORRECTANGLE(video,memtype,x,y,w,h) { \
const memtype* sp; \
memtype* dp; \
sp=video+y*VideoWidth+x; \
dp=OldCursorRectangle; \
memcpy(dp,sp,w*sizeof(memtype)); \
if ( --h ) { \
dp+=w; \
sp+=VideoWidth; \
while( --h ) { \
*dp++ = *sp; \
*dp++ = sp[w-1]; \
sp+=VideoWidth; \
} \
memcpy(dp,sp,w*sizeof(memtype)); \
} \
}
/** Restore cursor rectangle for 8bpp frame buffer.
** (See description function pointer LoadCursorRectangle)
*/
local void LoadCursorRectangle8(int x,int y,int w,int h) {
LOADCURSORRECTANGLE(VideoMemory8,VMemType8,x,y,w,h);
}
/** Restore cursor rectangle for 16bpp frame buffer.
** (See description function pointer LoadCursorRectangle)
*/
local void LoadCursorRectangle16(int x,int y,int w,int h) {
LOADCURSORRECTANGLE(VideoMemory16,VMemType16,x,y,w,h);
}
/** Restore cursor rectangle for 24bpp frame buffer.
** (See description function pointer LoadCursorRectangle)
*/
local void LoadCursorRectangle24(int x,int y,int w,int h) {
LOADCURSORRECTANGLE(VideoMemory24,VMemType24,x,y,w,h);
}
/** Restore cursor rectangle for 32bpp frame buffer.
** (See description function pointer LoadCursorRectangle)
*/
local void LoadCursorRectangle32(int x,int y,int w,int h) {
LOADCURSORRECTANGLE(VideoMemory32,VMemType32,x,y,w,h);
}
/** Save cursor rectangle for 8bpp frame buffer.
** (See description function pointer SaveCursorRectangle)
*/
local void SaveCursorRectangle8(int x,int y,int w,int h) {
SAVECURSORRECTANGLE(VideoMemory8,VMemType8,x,y,w,h);
}
/** Save cursor rectangle for 16bpp frame buffer.
** (See description function pointer SaveCursorRectangle)
*/
local void SaveCursorRectangle16(int x,int y,int w,int h) {
SAVECURSORRECTANGLE(VideoMemory16,VMemType16,x,y,w,h);
}
/** Save cursor rectangle for 24bpp frame buffer.
** (See description function pointer SaveCursorRectangle)
*/
local void SaveCursorRectangle24(int x,int y,int w,int h) {
SAVECURSORRECTANGLE(VideoMemory24,VMemType24,x,y,w,h);
}
/** Save cursor rectangle for 32bpp frame buffer.
** (See description function pointer SaveCursorRectangle)
*/
local void SaveCursorRectangle32(int x,int y,int w,int h) {
SAVECURSORRECTANGLE(VideoMemory32,VMemType32,x,y,w,h);
}
/**
** Restore cursor background for 8bpp frame buffer.
@ -516,7 +631,9 @@ global void DrawCursor(CursorType* type,int x,int y,int frame)
OldCursorW=VideoGraphicWidth(type->Sprite);
OldCursorH=VideoGraphicHeight(type->Sprite);
/* FIXME: SaveCusor done before rectangle
SaveCursor();
*/
VideoDrawClip(type->Sprite,frame,x,y);
}
@ -535,6 +652,12 @@ global void HideCursor(void)
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;
local int BuildingCursorSY;
local int BuildingCursorEX;
local int BuildingCursorEY;
/**
** Draw cursor for selecting building position.
*/
@ -553,16 +676,17 @@ local void DrawBuildingCursor(void)
int h;
int mask;
x=((CursorX-TheUI.MapX)/TileSizeX)*TileSizeX+TheUI.MapX; // Align to grid
y=((CursorY-TheUI.MapY)/TileSizeY)*TileSizeY+TheUI.MapY;
mx=Screen2MapX(x);
my=Screen2MapY(y);
// Align to grid
x=CursorX-(CursorX-TheUI.MapX)%TileSizeX;
y=CursorY-(CursorY-TheUI.MapY)%TileSizeY;
BuildingCursorSX=mx=Screen2MapX(x);
BuildingCursorSY=my=Screen2MapY(y);
//
// Draw building
//
PushClipping();
SetClipping(TheUI.MapX,TheUI.MapY,TheUI.MapWidth,TheUI.MapHeight);
SetClipping(TheUI.MapX,TheUI.MapY,TheUI.MapEndX,TheUI.MapEndY);
GraphicPlayerPixels(ThisPlayer,CursorBuilding->Sprite);
DrawUnitType(CursorBuilding,0,x,y);
PopClipping();
@ -609,10 +733,12 @@ local void DrawBuildingCursor(void)
}
h=CursorBuilding->TileHeight;
BuildingCursorEY=my+h-1;
if( my+h>MapY+MapHeight ) { // reduce to view limits
h=MapY+MapHeight-my;
}
w0=CursorBuilding->TileWidth; // reduce to view limits
BuildingCursorEX=mx+w0-1;
if( mx+w0>MapX+MapWidth ) {
w0=MapX+MapWidth-mx;
}
@ -654,32 +780,42 @@ global void DrawRectangleCursor(void)
x1=CursorX;
if( x1<TheUI.MapX ) {
x1=TheUI.MapX;
} else if( x1>=TheUI.MapWidth ) {
x1=TheUI.MapWidth-1;
} else if( x1>TheUI.MapEndX ) {
x1=TheUI.MapEndX;
}
y1=CursorY;
if( y1<TheUI.MapY ) {
y1=TheUI.MapY;
} else if( y1>=TheUI.MapHeight ) {
y1=TheUI.MapHeight-1;
} else if( y1>TheUI.MapEndY ) {
y1=TheUI.MapEndY;
}
x=CursorStartX;
if( x>x1 ) {
x=x1;
w=CursorStartX-x;
w=CursorStartX-x+1;
} else {
w=x1-x;
w=x1-x+1;
}
y=CursorStartY;
if( y>y1 ) {
y=y1;
h=CursorStartY-y;
h=CursorStartY-y+1;
} else {
h=y1-y;
h=y1-y+1;
}
VideoDrawRectangleClip(ColorGreen,x,y,w,h);
#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
}
/**
@ -689,6 +825,14 @@ 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();
//
// Selecting rectangle
//
@ -717,52 +861,77 @@ global void DrawAnyCursor(void)
*/
global int HideAnyCursor(void)
{
if( RectangleCursor || BuildingCursor ) {
MustRedraw|=RedrawMap;
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);
}
//
// Cursor complete on map and map must be redrawn, no restore.
//StephanR: but prevented when not entire map is redrawn ;)
//
#ifndef NEW_MAPDRAW
if( OldCursorX>=TheUI.MapX
&& OldCursorX+OldCursorW<TheUI.MapWidth
&& OldCursorX+OldCursorW-1<=TheUI.MapEndX
&& OldCursorY>=TheUI.MapY
&& OldCursorY+OldCursorH<TheUI.MapHeight
&& OldCursorY+OldCursorH-1<=TheUI.MapEndY
&& (MustRedraw&RedrawMap)
&& (InterfaceState != IfaceStateMenu) ) {
return 0;
}
#endif
HideCursor();
return 1;
}
/**
** Setup the cursor part.
**FIXME: Now max possible memory for OldCursorRectangle, to be limited to Map?
*/
global void InitCursor(void)
{
int memsize;
free( OldCursorRectangle ); // memory of possible previous video-setting?
switch( VideoDepth ) {
case 8:
SaveCursorBackground=SaveCursorBackground8;
LoadCursorBackground=LoadCursorBackground8;
memsize=sizeof(VMemType8);
SaveCursorRectangle=SaveCursorRectangle8;
LoadCursorRectangle=LoadCursorRectangle8;
break;
case 15:
case 16:
SaveCursorBackground=SaveCursorBackground16;
LoadCursorBackground=LoadCursorBackground16;
memsize=sizeof(VMemType16);
SaveCursorRectangle=SaveCursorRectangle16;
LoadCursorRectangle=LoadCursorRectangle16;
break;
case 24:
SaveCursorBackground=SaveCursorBackground24;
LoadCursorBackground=LoadCursorBackground24;
memsize=sizeof(VMemType24);
SaveCursorRectangle=SaveCursorRectangle24;
LoadCursorRectangle=LoadCursorRectangle24;
break;
case 32:
SaveCursorBackground=SaveCursorBackground32;
LoadCursorBackground=LoadCursorBackground32;
memsize=sizeof(VMemType32);
SaveCursorRectangle=SaveCursorRectangle32;
LoadCursorRectangle=LoadCursorRectangle32;
break;
default:
DebugLevel0(__FUNCTION__": unsupported %d bpp\n",VideoDepth);
abort();
}
OldCursorRectangle=malloc((2*VideoWidth+2*(VideoHeight-2))*memsize);
}
//@}

View file

@ -102,6 +102,8 @@ global int ClipX2; /// current clipping bottom right
global int ClipY2; /// current clipping bottom right
local Clip* Clips; /// stack of all clips.
local Clip* ClipsGarbage = NULL; /// garbage-list of available clips.
extern PaletteLink *palette_list;
@ -159,7 +161,7 @@ global void SetClipping(int left,int top,int right,int bottom)
{
if( left>right ) { left^=right; right^=left; left^=right; }
if( top>bottom ) { top^=bottom; bottom^=top; top^=bottom; }
if( left<0 ) left=0;
else if( left>=VideoWidth ) left=VideoWidth-1;
if( top<0 ) top=0;
@ -168,7 +170,7 @@ global void SetClipping(int left,int top,int right,int bottom)
else if( right>=VideoWidth ) right=VideoWidth-1;
if( bottom<0 ) bottom=0;
else if( bottom>=VideoHeight ) bottom=VideoHeight-1;
ClipX1=left;
ClipY1=top;
ClipX2=right;
@ -182,7 +184,11 @@ global void PushClipping(void)
{
Clip* clip;
clip=malloc(sizeof(Clip));
if(( clip=ClipsGarbage ))
ClipsGarbage=ClipsGarbage->Next;
else
clip=malloc(sizeof(Clip));
clip->Next=Clips;
clip->X1=ClipX1;
clip->Y1=ClipY1;
@ -205,7 +211,9 @@ global void PopClipping(void)
ClipY1=clip->Y1;
ClipX2=clip->X2;
ClipY2=clip->Y2;
free(clip);
clip->Next = ClipsGarbage;
ClipsGarbage = clip;
} else {
ClipX1=0;
ClipY1=0;
@ -262,7 +270,7 @@ global void LoadRGB(Palette *pal, const char *name)
{
FILE *fp;
int i;
if((fp=fopen(name,"rb")) == NULL) {
fprintf(stderr,"Can't load palette %s\n",name);
exit(-1);
@ -273,7 +281,7 @@ global void LoadRGB(Palette *pal, const char *name)
pal[i].g=fgetc(fp)<<2;
pal[i].b=fgetc(fp)<<2;
}
fclose(fp);
}
@ -327,7 +335,7 @@ global void ColorCycle8(void)
((VMemType8*)(current_link->Palette))[i+1];
}
((VMemType8*)(current_link->Palette))[47]=x;
x=((VMemType8*)(current_link->Palette))[240];
for( i=240; i<244; ++i ) { // units/icons color cycle
((VMemType8*)(current_link->Palette))[i]=
@ -336,7 +344,7 @@ global void ColorCycle8(void)
((VMemType8*)(current_link->Palette))[244]=x;
current_link = current_link->Next;
}
} else {
} else {
//
// Color cycle tileset palette
@ -347,20 +355,20 @@ global void ColorCycle8(void)
pixels[i] = pixels[i+1];
}
pixels[47] = x;
x=Pixels8[38];
for( i=38; i<47; ++i ) { // tileset color cycle
Pixels8[i]=Pixels8[i+1];
}
Pixels8[47]=x;
x=Pixels8[240];
for( i=240; i<244; ++i ) { // units/icons color cycle
Pixels8[i]=Pixels8[i+1];
}
Pixels8[244]=x;
}
MapColorCycle(); // FIXME: could be little more informativer
MustRedraw|=RedrawMap|RedrawInfoPanel;
}
@ -387,7 +395,7 @@ global void ColorCycle16(void)
((VMemType16*)(current_link->Palette))[i+1];
}
((VMemType16*)(current_link->Palette))[47]=x;
x=((VMemType16*)(current_link->Palette))[240];
for( i=240; i<244; ++i ) { // units/icons color cycle
((VMemType16*)(current_link->Palette))[i]=
@ -396,7 +404,7 @@ global void ColorCycle16(void)
((VMemType16*)(current_link->Palette))[244]=x;
current_link = current_link->Next;
}
} else {
} else {
//
// Color cycle tileset palette
@ -407,7 +415,7 @@ global void ColorCycle16(void)
pixels[i] = pixels[i+1];
}
pixels[47] = x;
x=Pixels16[38];
for( i=38; i<47; ++i ) { // tileset color cycle
Pixels16[i]=Pixels16[i+1];
@ -447,7 +455,7 @@ global void ColorCycle24(void)
((VMemType24*)(current_link->Palette))[i+1];
}
((VMemType24*)(current_link->Palette))[47]=x;
x=((VMemType24*)(current_link->Palette))[240];
for( i=240; i<244; ++i ) { // units/icons color cycle
((VMemType24*)(current_link->Palette))[i]=
@ -456,7 +464,7 @@ global void ColorCycle24(void)
((VMemType24*)(current_link->Palette))[244]=x;
current_link = current_link->Next;
}
} else {
} else {
//
// Color cycle tileset palette
@ -467,13 +475,13 @@ global void ColorCycle24(void)
pixels[i] = pixels[i+1];
}
pixels[47] = x;
x=Pixels24[38];
for( i=38; i<47; ++i ) { // tileset color cycle
Pixels24[i]=Pixels24[i+1];
}
Pixels24[47]=x;
x=Pixels24[240];
for( i=240; i<244; ++i ) { // units/icons color cycle
Pixels24[i]=Pixels24[i+1];
@ -507,7 +515,7 @@ global void ColorCycle32(void)
((VMemType32*)(current_link->Palette))[i+1];
}
((VMemType32*)(current_link->Palette))[47]=x;
x=((VMemType32*)(current_link->Palette))[240];
for( i=240; i<244; ++i ) { // units/icons color cycle
((VMemType32*)(current_link->Palette))[i]=
@ -516,7 +524,7 @@ global void ColorCycle32(void)
((VMemType32*)(current_link->Palette))[244]=x;
current_link = current_link->Next;
}
} else {
} else {
//
// Color cycle tileset palette
@ -527,13 +535,13 @@ global void ColorCycle32(void)
pixels[i] = pixels[i+1];
}
pixels[47] = x;
x=Pixels32[38];
for( i=38; i<47; ++i ) { // tileset color cycle
Pixels32[i]=Pixels32[i+1];
}
Pixels32[47]=x;
x=Pixels32[240];
for( i=240; i<244; ++i ) { // units/icons color cycle
Pixels32[i]=Pixels32[i+1];