From 7e292b36e4cec68e45a98c8bb8500fe3a72e8aa3 Mon Sep 17 00:00:00 2001 From: johns <> Date: Sun, 13 Aug 2000 15:23:02 +0000 Subject: [PATCH] Tileset structure changed, many hardcoded stuff removed. --- src/include/tileset.h | 59 +++- src/map/Makefile | 2 +- src/map/map.cpp | 16 +- src/map/map_draw.cpp | 6 +- src/map/map_rock.cpp | 25 +- src/map/map_wall.cpp | 17 +- src/map/map_wood.cpp | 20 +- src/map/script_map.cpp | 83 ++--- src/map/script_tileset.cpp | 138 ++++++++ src/map/tileset.cpp | 637 +++++++++++++++++++++++++++---------- src/stratagus/script.cpp | 4 +- 11 files changed, 720 insertions(+), 287 deletions(-) create mode 100644 src/map/script_tileset.cpp diff --git a/src/include/tileset.h b/src/include/tileset.h index 343c65617..1cc9f0345 100644 --- a/src/include/tileset.h +++ b/src/include/tileset.h @@ -9,11 +9,10 @@ // FreeCraft - A free fantasy real time strategy game engine // /**@name tileset.h - The tileset headerfile. */ -/* -** (c) Copyright 1998-2000 by Lutz Sammer -** -** $Id$ -*/ +// +// (c) Copyright 1998-2000 by Lutz Sammer +// +// $Id$ #ifndef __TILESET_H__ #define __TILESET_H__ @@ -27,26 +26,34 @@ #define TileSizeX 32 /// Size of a tile in X #define TileSizeY 32 /// Size of a tile in Y +//#define MaxTilesInTileset 1024 /// Current limit of tiles in tileset +#define MaxTilesInTileset 3072 /// Current limit of tiles in tileset + +#if 0 + #define TILE_PER_ROW 16 /// tiles stored in an image row #define TILE_ROWS 24 /// tiles rows in the image #define TILE_COUNT (TILE_PER_ROW*TILE_ROWS) +#endif + + /** ** These are used for lookup tiles types ** mainly used for the FOW implementation of the seen woods/rocks */ enum _tile_type_ { TileTypeUnknown, /// unknown tile type - TileTypeNoWood, /// no wood tile + TileTypeNoWood, /// UNUSED: no wood tile TileTypeWood, /// any wood tile TileTypeGrass, /// any grass tile - TileTypeNoRock, /// no rock tile + TileTypeNoRock, /// UNUSED: no rock tile TileTypeRock, /// any rock tile TileTypeCoast, /// any coast tile - TileTypeHWall, /// any human wall tile - TileTypeOWall, /// any orc wall tile - TileTypeNoWall, /// no wall tile - TileTypeWater /// any water tile + TileTypeHumanWall, /// any human wall tile + TileTypeOrcWall, /// any orc wall tile + TileTypeNoWall, /// UNUSED: no wall tile + TileTypeWater, /// any water tile }; /** @@ -56,18 +63,33 @@ typedef struct _tileset_ { char* Ident; /// tileset identifier char* Name; /// name for future extensions char* File; /// file containing image data + const unsigned short* Table; /// pud to internal conversion table - unsigned char* TileTypeTable; /// lookup tile type - unsigned FirstWoodTile; /// first wood tile - unsigned NoWoodTile; /// tile placed where wood is gone - unsigned FirstRockTile; /// first rock tile :) - unsigned NoRockTile; /// tile placed where rocks are gone + unsigned char* TileTypeTable; /// for fast lookup of tile type + unsigned short* AnimationTable; /// Tile Animation sequences + +#if 1 + // FIXME: old code should be complete removed. unsigned HumanWall100Tile; /// 100% wall unsigned HumanWall50Tile; /// 100% wall unsigned HumanNoWallTile; /// tile placed where walls are gone unsigned OrcWall100Tile; /// 100% wall unsigned OrcWall50Tile; /// 100% wall unsigned OrcNoWallTile; /// tile placed where walls are gone +#endif + + unsigned ExtraTrees[6]; /// extra tree tiles for removed + unsigned TopOneTree; /// tile for one tree top + unsigned MidOneTree; /// tile for one tree middle + unsigned BotOneTree; /// tile for one tree bottom + unsigned RemovedTree; /// tile placed where trees are gone + unsigned GrowingTree[2]; /// Growing tree tiles + + unsigned ExtraRocks[6]; /// extra rock tiles for removed + unsigned TopOneRock; /// tile for one rock top + unsigned MidOneRock; /// tile for one rock middle + unsigned BotOneRock; /// tile for one rock bottom + unsigned RemovedRock; /// tile placed where rocks are gone } Tileset; // FIXME: this #define's should be removed @@ -85,6 +107,7 @@ typedef struct _tileset_ { -- Variables ----------------------------------------------------------------------------*/ +extern char** TilesetWcNames; /// Mapping wc-number 2 symbol extern Tileset Tilesets[TilesetMax]; /// Tileset information /*---------------------------------------------------------------------------- @@ -92,6 +115,10 @@ extern Tileset Tilesets[TilesetMax]; /// Tileset information ----------------------------------------------------------------------------*/ extern void LoadTileset(void); /// Load tileset definition +extern void SaveTileset(FILE*); /// Save the tileset configuration +extern void CleanTileset(void); /// Cleanup the tileset module + +extern void TilesetCclRegister(void); /// Register CCL features for tileset /*---------------------------------------------------------------------------- -- Predicates diff --git a/src/map/Makefile b/src/map/Makefile index 85470e5c4..aef7e78fc 100644 --- a/src/map/Makefile +++ b/src/map/Makefile @@ -23,6 +23,6 @@ MODULE = map OBJS = map.$(OE) map_draw.$(OE) ccl_map.$(OE) \ map_fog.$(OE) map_rock.$(OE) map_wood.$(OE) map_wall.$(OE) \ - minimap.$(OE) tileset.$(OE) + minimap.$(OE) tileset.$(OE) ccl_tileset.$(OE) include $(TOPDIR)/Common.mk diff --git a/src/map/map.cpp b/src/map/map.cpp index 4b607576b..fc44c23bd 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -80,11 +80,11 @@ global void MapMarkSeenTile( int x, int y ) // handle WOODs - if ( st != TheMap.Tileset->NoWoodTile - && t == TheMap.Tileset->NoWoodTile ) { + if ( st != TheMap.Tileset->RemovedTree + && t == TheMap.Tileset->RemovedTree ) { MapFixWood( x, y ); - } else if ( st == TheMap.Tileset->NoWoodTile - && t != TheMap.Tileset->NoWoodTile ) { + } else if ( st == TheMap.Tileset->RemovedTree + && t != TheMap.Tileset->RemovedTree ) { FixWood( x, y ); } else if ( MapWoodChk( x, y ) ) { FixWood( x, y ); @@ -94,12 +94,12 @@ global void MapMarkSeenTile( int x, int y ) // handle WALLs #define ISTILEWALL(tile) \ - (TheMap.Tileset->TileTypeTable[(tile)] == TileTypeHWall \ - || TheMap.Tileset->TileTypeTable[(tile)] == TileTypeOWall) + (TheMap.Tileset->TileTypeTable[(tile)] == TileTypeHumanWall \ + || TheMap.Tileset->TileTypeTable[(tile)] == TileTypeOrcWall) - if ( ISTILEWALL(st) && !ISTILEWALL(st) ) + if ( ISTILEWALL(st) && !ISTILEWALL(t) ) MapFixWall( x, y ); - else if ( !ISTILEWALL(st) && ISTILEWALL(st) ) + else if ( !ISTILEWALL(st) && ISTILEWALL(t) ) FixWall( x, y ); else if ( MapWallChk( x, y, -1 ) ) { FixWall( x, y ); diff --git a/src/map/map_draw.cpp b/src/map/map_draw.cpp index a7df7d238..4a50db02d 100644 --- a/src/map/map_draw.cpp +++ b/src/map/map_draw.cpp @@ -67,7 +67,7 @@ typedef struct _tile_cache { ** Contains pointer, if the tile is cached. ** FIXME: could save memory here and only use how many tiles exits. */ -local TileCache* TileCached[TILE_COUNT]; +local TileCache* TileCached[MaxTilesInTileset]; /** ** Number of tile caches. @@ -92,7 +92,7 @@ local struct dl_head TileCacheLRU[1] = { ** Contains pointer, to last video position, where this tile was drawn. ** FIXME: could save memory here and only use how many tiles exits. */ -local void* TileCached[TILE_COUNT]; +local void* TileCached[MaxTilesInTileset]; #endif @@ -1259,7 +1259,7 @@ global void MapColorCycle(void) TileCache* cache; // FIXME: the easy version just remove color cycling tiles from cache. - for( i=0; i<TILE_COUNT; ++i ) { + for( i=0; i<TheMap.TileCount; ++i ) { if( TheMap.Tileset->TileTypeTable[i]==TileTypeWater ) { if( (cache=TileCached[i]) ) { DebugLevel3("Flush\n"); diff --git a/src/map/map_rock.cpp b/src/map/map_rock.cpp index 8a4a35e3a..76f8f94c1 100644 --- a/src/map/map_rock.cpp +++ b/src/map/map_rock.cpp @@ -32,16 +32,17 @@ -- Declarations ----------------------------------------------------------------------------*/ - // FIXME: -1 is hack should be fixed later -#define FIRST_ROCK_TILE (TheMap.Tileset->FirstRockTile-1) - /*---------------------------------------------------------------------------- -- Variables ----------------------------------------------------------------------------*/ -local const int RockTable[16] = { +/** +** Table for rock removable. +*/ +global int RockTable[20] = { // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F -1, 22, -1, 1, 20, 21, 3, 2, -1, 9, -1, 23, 6, 8, 5, 36 + ,7, 10, 11, 4 }; /*---------------------------------------------------------------------------- @@ -93,16 +94,14 @@ local int FixRock(int x,int y) // used by MapRemoveRock and PreprocessMap // Vladi: still to filter tiles w. corner empties -- note: the original // tiles and order are not perfect either. It's a hack but is enough and // looks almost fine. - if (MapRockChk(x+1,y-1) == 0) tile = 7; else - if (MapRockChk(x+1,y+1) == 0) tile = 10; else - if (MapRockChk(x-1,y+1) == 0) tile = 11; else - if (MapRockChk(x-1,y-1) == 0) tile = 4; else - tile = RockTable[15]; // not required really + if (MapRockChk(x+1,y-1) == 0) tile = RockTable[16]; else + if (MapRockChk(x+1,y+1) == 0) tile = RockTable[17]; else + if (MapRockChk(x-1,y+1) == 0) tile = RockTable[18]; else + if (MapRockChk(x-1,y-1) == 0) tile = RockTable[19]; else + tile = RockTable[15]; // not required really } - tile += FIRST_ROCK_TILE; mf=TheMap.Fields+x+y*TheMap.Width; - if ( mf->SeenTile == tile) { return 0; } @@ -134,7 +133,7 @@ global void MapRemoveRock(unsigned x,unsigned y) mf=TheMap.Fields+x+y*TheMap.Width; - mf->Tile=TheMap.Tileset->NoRockTile; + mf->Tile=TheMap.Tileset->RemovedRock; mf->Flags &= ~(MapFieldRocks|MapFieldUnpassable); UpdateMinimapXY(x,y); // FIXME: should be done if visible? @@ -146,7 +145,7 @@ global void MapRemoveRock(unsigned x,unsigned y) if( mf->Flags&MapFieldVisible ) { #endif MustRedraw|=RedrawMaps; - // FIXME: Should we do this? MapMarkSeenTile(x,y); + // FIXME: didn't make it better MapMarkSeenTile(x,y); } } diff --git a/src/map/map_wall.cpp b/src/map/map_wall.cpp index 23433f614..3a5cfe2a2 100644 --- a/src/map/map_wall.cpp +++ b/src/map/map_wall.cpp @@ -46,6 +46,12 @@ local int WallTable[16] = { // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F 0, 4, 2, 7, 1, 5, 3, 8, 9, 14, 11, 16, 10, 15, 13, 17 +/* + 0x90 + 0x92 + 0xA0 + 0x94 +*/ }; /*---------------------------------------------------------------------------- @@ -76,7 +82,7 @@ global int MapWallChk(int x,int y,int walltype) // used by FixWall, walltype==-1 t=TheMap.Tileset->TileTypeTable[ TheMap.Fields[(x)+(y)*TheMap.Width].SeenTile]; if (walltype == -1) { - return t == TileTypeHWall || t == TileTypeOWall ; + return t == TileTypeHumanWall || t == TileTypeOrcWall ; } return t == walltype; } @@ -87,12 +93,17 @@ global int FixWall(int x,int y) // used by MapRemoveWall and PreprocessMap int walltype; MapField* mf; + // + // Outside the map + // if( x<0 || y<0 || x>=TheMap.Width || y>=TheMap.Height ) { return 0; } mf=TheMap.Fields+(x)+(y)*TheMap.Width; walltype = TheMap.Tileset->TileTypeTable[mf->SeenTile]; - if ( walltype != TileTypeHWall && walltype != TileTypeOWall ) return 0; + if ( walltype != TileTypeHumanWall && walltype != TileTypeOrcWall ) { + return 0; + } #define WALL(xx,yy) (MapWallChk(xx,yy,walltype) != 0) tile = 0; @@ -103,7 +114,7 @@ global int FixWall(int x,int y) // used by MapRemoveWall and PreprocessMap tile = WallTable[tile]; - if (walltype == TileTypeHWall) + if (walltype == TileTypeHumanWall) { if (mf->Value < WALL_50HP) tile += TheMap.Tileset->HumanWall50Tile; diff --git a/src/map/map_wood.cpp b/src/map/map_wood.cpp index 622e577bf..57320c6ce 100644 --- a/src/map/map_wood.cpp +++ b/src/map/map_wood.cpp @@ -35,12 +35,9 @@ global int ForestRegeneration; /// Forest regeneration /** -** Table for wood removable +** Table for wood removable. */ -local int WoodTable[16] = { -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F - -1, 22, -1, 1, 20, 21, 3, 2, -1, 9, -1, 23, 6, 8, 5, 4 -}; +global int WoodTable[16]; /*---------------------------------------------------------------------------- -- Functions @@ -88,9 +85,6 @@ global int FixWood(int x,int y) // used by MapRemoveWood2 and PreprocessMap if (tile == -1) { MapRemoveWood(x,y); } else { - // DON'T work EGCC failure tile += TheMap.Tileset->FirstWoodTile; - tile += 0x65; - DebugLevel3(__FUNCTION__":%x\n", TheMap.Tileset->FirstWoodTile); mf=TheMap.Fields+x+y*TheMap.Width; if ( mf->SeenTile == tile) { return 0; @@ -123,7 +117,7 @@ global void MapRemoveWood(unsigned x,unsigned y) mf=TheMap.Fields+x+y*TheMap.Width; - mf->Tile=TheMap.Tileset->NoWoodTile; + mf->Tile=TheMap.Tileset->RemovedTree; mf->Flags &= ~(MapFieldForest|MapFieldUnpassable); mf->Value=0; @@ -160,23 +154,23 @@ global void RegenerateForest(void) for( x=0; x<TheMap.Width; ++x ) { for( y=0; y<TheMap.Height; ++y ) { mf=TheMap.Fields+x+y*TheMap.Width; - if( mf->Tile==TheMap.Tileset->NoWoodTile ) { + if( mf->Tile==TheMap.Tileset->RemovedTree ) { if( mf->Value>=ForestRegeneration || ++mf->Value==ForestRegeneration ) { if( x && !(mf->Flags&(MapFieldWall|MapFieldUnpassable |MapFieldLandUnit|MapFieldBuilding)) ) { tmp=mf-TheMap.Width; - if( tmp->Tile==TheMap.Tileset->NoWoodTile + if( tmp->Tile==TheMap.Tileset->RemovedTree && tmp->Value>=ForestRegeneration && !(tmp->Flags&(MapFieldWall|MapFieldUnpassable |MapFieldLandUnit|MapFieldBuilding)) ) { DebugLevel0("Real place wood\n"); - tmp->Tile=121; + tmp->Tile=TheMap.Tileset->TopOneTree; tmp->Value=0; tmp->Flags|=MapFieldForest|MapFieldUnpassable; - mf->Tile=123; + mf->Tile=TheMap.Tileset->BotOneTree; mf->Value=0; mf->Flags|=MapFieldForest|MapFieldUnpassable; #ifdef NEW_FOW diff --git a/src/map/script_map.cpp b/src/map/script_map.cpp index a777da70d..b52b035cf 100644 --- a/src/map/script_map.cpp +++ b/src/map/script_map.cpp @@ -9,11 +9,10 @@ // FreeCraft - A free fantasy real time strategy game engine // /**@name ccl_map.c - The map ccl functions. */ -/* -** (c) Copyright 1999,2000 by Lutz Sammer -** -** $Id$ -*/ +// +// (c) Copyright 1999,2000 by Lutz Sammer +// +// $Id$ //@{ @@ -29,7 +28,6 @@ #if defined(USE_CCL) || defined(USE_CCL2) // { #include "ccl.h" -#include "tileset.h" #include "map.h" #include "minimap.h" @@ -51,6 +49,23 @@ local SCM CclRevealMap(void) return SCM_UNSPECIFIED; } +/** +** Set fog of war on/off. +** +** @param flag True = turning fog of war on, false = off. +** +** @returns The old state of fog of war. +*/ +local SCM CclSetFogOfWar(SCM flag) +{ + int old; + + old=TheMap.NoFogOfWar; + TheMap.NoFogOfWar=gh_scm2bool(flag); + + return gh_int2scm(old); +} + /** ** Enable fog of war. */ @@ -199,57 +214,6 @@ local SCM CclForestRegeneration(SCM speed) return SCM_UNSPECIFIED; } -//............................................................................. -//. Tables -//............................................................................. - -/** -** Parse tileset definition. -** -** @param slot Slot name -** @param name Reference name -** @param file Graphic file -** @param table Conversion table -*/ -local SCM CclTileset(SCM slot,SCM name,SCM file,SCM table) -{ - int type; - int i; - unsigned short* wp; - - if( !gh_symbol_p(slot) ) { - fprintf(stderr,"Illegal tileset slot name\n"); - return SCM_UNSPECIFIED; - } - if( slot==gh_symbol2scm("tileset-summer") ) { - type=TilesetSummer; - } else if( slot==gh_symbol2scm("tileset-winter") ) { - type=TilesetWinter; - } else if( slot==gh_symbol2scm("tileset-wasteland") ) { - type=TilesetWasteland; - } else if( slot==gh_symbol2scm("tileset-swamp") ) { - type=TilesetSwamp; - } else { - fprintf(stderr,"Wrong tileset slot name\n"); - return SCM_UNSPECIFIED; - } - Tilesets[type].Name=gh_scm2newstr(name,NULL); - Tilesets[type].File=gh_scm2newstr(file,NULL); - - // CONVERT TABLE!! - if( gh_vector_length(table)!=2528 ) { // 0x9E0 - fprintf(stderr,"Wrong conversion table length\n"); - return SCM_UNSPECIFIED; - } - - Tilesets[type].Table=wp=malloc(sizeof(*Tilesets[type].Table)*2528); - for( i=0; i<2528; ++i ) { - wp[i]=gh_scm2int(gh_vector_ref(table,gh_int2scm(i))); - } - - return SCM_UNSPECIFIED; -} - /** ** Register CCL features for map. */ @@ -257,6 +221,8 @@ global void MapCclRegister(void) { gh_new_procedure0_0("reveal-map",CclRevealMap); + gh_new_procedure1_0("set-fog-of-war!",CclSetFogOfWar); + gh_new_procedure0_0("fog-of-war",CclFogOfWar); gh_new_procedure0_0("no-fog-of-war",CclNoFogOfWar); @@ -265,13 +231,12 @@ global void MapCclRegister(void) gh_new_procedure0_0("original-fog-of-war",CclOriginalFogOfWar); gh_new_procedure0_0("gray-fog-of-war",CclGrayFogOfWar); + gh_new_procedure1_0("fog-of-war-contrast",CclFogOfWarContrast); gh_new_procedure1_0("fog-of-war-brightness",CclFogOfWarBrightness); gh_new_procedure1_0("fog-of-war-saturation",CclFogOfWarSaturation); gh_new_procedure1_0("forest-regeneration",CclForestRegeneration); - - gh_new_procedure4_0("tileset",CclTileset); } #endif // } defined(USE_CCL) || defined(USE_CCL2) diff --git a/src/map/script_tileset.cpp b/src/map/script_tileset.cpp new file mode 100644 index 000000000..aadf03b2e --- /dev/null +++ b/src/map/script_tileset.cpp @@ -0,0 +1,138 @@ +// ___________ _________ _____ __ +// \_ _____/______ ____ ____ \_ ___ \____________ _/ ____\/ |_ +// | __) \_ __ \_/ __ \_/ __ \/ \ \/\_ __ \__ \\ __\\ __\ +// | \ | | \/\ ___/\ ___/\ \____| | \// __ \| | | | +// \___ / |__| \___ >\___ >\______ /|__| (____ /__| |__| +// \/ \/ \/ \/ \/ +// ______________________ ______________________ +// T H E W A R B E G I N S +// FreeCraft - A free fantasy real time strategy game engine +// +/**@name ccl_tileset.c - The tileset ccl functions. */ +// +// (c) Copyright 2000 by Lutz Sammer +// +// $Id$ + +//@{ + +/*---------------------------------------------------------------------------- +-- Includes +----------------------------------------------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> + +#include "freecraft.h" + +#if defined(USE_CCL) || defined(USE_CCL2) // { + +#include "ccl.h" +#include "tileset.h" + +/*---------------------------------------------------------------------------- +-- Functions +----------------------------------------------------------------------------*/ + +/** +** Parse tileset definition. +** +** @param slot Slot name +** @param name Reference name +** @param file Graphic file +** @param table Conversion table +*/ +local SCM CclTileset(SCM slot,SCM name,SCM file,SCM table) +{ + int type; + int i; + unsigned short* wp; + + if( !gh_symbol_p(slot) ) { + fprintf(stderr,"Illegal tileset slot name\n"); + return SCM_UNSPECIFIED; + } + if( slot==gh_symbol2scm("tileset-summer") ) { + type=TilesetSummer; + } else if( slot==gh_symbol2scm("tileset-winter") ) { + type=TilesetWinter; + } else if( slot==gh_symbol2scm("tileset-wasteland") ) { + type=TilesetWasteland; + } else if( slot==gh_symbol2scm("tileset-swamp") ) { + type=TilesetSwamp; + } else { + fprintf(stderr,"Wrong tileset slot name\n"); + return SCM_UNSPECIFIED; + } + Tilesets[type].Name=gh_scm2newstr(name,NULL); + Tilesets[type].File=gh_scm2newstr(file,NULL); + + // CONVERT TABLE!! + if( gh_vector_length(table)!=2528 ) { // 0x9E0 + fprintf(stderr,"Wrong conversion table length\n"); + return SCM_UNSPECIFIED; + } + + Tilesets[type].Table=wp=malloc(sizeof(*Tilesets[type].Table)*2528); + for( i=0; i<2528; ++i ) { + wp[i]=gh_scm2int(gh_vector_ref(table,gh_int2scm(i))); + } + + return SCM_UNSPECIFIED; +} + +/** +** Define tileset mapping from original number to internal symbol +** +*/ +local SCM CclDefineTilesetWcNames(SCM list) +{ + int i; + char** cp; + + i=gh_length(list); + if( (cp=TilesetWcNames) ) { // Free all old names + while( *cp ) { + free(*cp++); + } + free(TilesetWcNames); + } + + // + // Get new table. + // + TilesetWcNames=cp=malloc((i+1)*sizeof(char*)); + while( i-- ) { + *cp++=gh_scm2newstr(gh_car(list),NULL); + list=gh_cdr(list); + } + *cp=NULL; + + return SCM_UNSPECIFIED; +} + +/** +** Define tileset +** +*/ +local SCM CclDefineTileset(SCM list) +{ + // FIXME: write this + return list; +} + +/** +** Register CCL features for tileset. +*/ +global void TilesetCclRegister(void) +{ + // FIXME: will be removed + gh_new_procedure4_0("tileset",CclTileset); + + gh_new_procedureN("define-tileset-wc-names",CclDefineTilesetWcNames); + gh_new_procedureN("define-tileset",CclDefineTileset); +} + +#endif // } defined(USE_CCL) || defined(USE_CCL2) + +//@} diff --git a/src/map/tileset.cpp b/src/map/tileset.cpp index 8eedc2194..65f89bc69 100644 --- a/src/map/tileset.cpp +++ b/src/map/tileset.cpp @@ -9,14 +9,17 @@ // FreeCraft - A free fantasy real time strategy game engine // /**@name tileset.c - The tileset. */ -/* -** (c) Copyright 1998-2000 by Lutz Sammer -** -** $Id$ -*/ +// +// (c) Copyright 1998-2000 by Lutz Sammer +// +// $Id$ //@{ +/*---------------------------------------------------------------------------- +-- Includes +----------------------------------------------------------------------------*/ + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -26,9 +29,21 @@ #include "map.h" /*---------------------------------------------------------------------------- --- Tileset +-- Variables ----------------------------------------------------------------------------*/ +extern int WoodTable[16]; /// Table for wood removable. +extern int RockTable[20]; /// Table for rock removable. + +/** +** Mapping of wc numbers to our internal symbols. +** The numbers are used in puds. +** 0=summer, 1=winter, 2=wasteland, 3=swamp. +*/ +global char** TilesetWcNames; + +#if 1 // FIXME: only support ccl version. + /** ** Table to convert summer pud tile numbers to internal. */ @@ -1317,129 +1332,10 @@ local const unsigned short TileTableWasteland[0x9E0] = { 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, }; - -// FIXME: following tables are almost empty: only forest fields are correct -// FIXME: JOHNS most things could be computed - /** -** Table to get information about the summer tile features. +** Count of available Tilesets. */ -local unsigned char TileTypeTableSummer[TILE_COUNT] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // FOW tiles - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // walls - 7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8, // walls - 8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7, // walls - 7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8, // walls - 8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9, // walls - 9,9,9,9,9,9,2,2,2,2,2,2,2,2,2,2, // wood - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2, // forest - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,5,5, // forest - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // rocks - 5,5,5,5,5,5,4,5,5,5,5,5,5,5,5,5, // rocks - 5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0, // rocks - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -/** -** Table to get information about the winter tile features. -*/ -local unsigned char TileTypeTableWinter[TILE_COUNT] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // FOW tiles - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // walls - 7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8, // walls - 8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7, // walls - 7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8, // walls - 8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9, // walls - 9,9,9,9,9,9,2,2,2,2,2,2,2,2,2,2, // wood - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2, // forest - 2,2,2,2,2,2,2,2,2,5,5,5,5,5,5,5, // forest - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // rocks - 5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,0, // rocks - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -/** -** Table to get information about the wasteland tile features. -*/ -local unsigned char TileTypeTableWasteland[TILE_COUNT] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // FOW tiles - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // walls - 7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8, // walls - 8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7, // walls - 7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8, // walls - 8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9, // walls - 9,9,9,9,9,9,2,2,2,2,2,2,2,2,2,2, // wood - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2, // forest - 2,2,2,2,2,2,2,2,2,2,2,5,5,5,5,5, // forest - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // rocks - 5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5, // rocks - 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -/** -** Table to get information about the swamp tile features. -*/ -local unsigned char TileTypeTableSwamp[TILE_COUNT] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // FOW tiles - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // walls - 7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8, // walls - 8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7, // walls - 7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8, // walls - 8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9, // walls - 9,9,9,9,9,9,2,2,2,2,2,2,2,2,2,2, // wood - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2, // forest - 2,2,2,2,2,2,2,2,2,5,5,5,5,5,5,5, // forest - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, // rocks - 5,4,5,5,5,5,5,5,5,5,5,5,5,5,5,0, // rocks - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; +global int TilesetsCount=4; /** ** Tileset information. @@ -1448,69 +1344,157 @@ local unsigned char TileTypeTableSwamp[TILE_COUNT] = { */ global Tileset Tilesets[TilesetMax] = { { - "tileset-summer", - "summer", "graphic/tileset/summer.png" + "tileset-summer" + ,"summer" +#ifdef NEW_NAMES + ,"graphic/tilesets/summer/terrain/summer.png" +#else + ,"graphic/tileset/summer.png" +#endif ,TileTableSummer - ,TileTypeTableSummer - ,101, 126 - ,142, 142+24 + ,NULL + ,NULL +#if 1 ,16,52,88 ,34,70,88 +#endif + ,{ 115, 116, 117, 118, 119, 120 } + ,121, 122, 123 + ,126 + ,{ -1 ,-1 } + ,{ 153, 154, 155, 156, 157, 158 } + ,161, 162, 163 + ,166 }, { "tileset-winter", "winter", "graphic/tileset/winter.png" ,TileTableWinter - ,TileTypeTableWinter - ,101, 126 - ,137, 137+24 + ,NULL + ,NULL +#if 1 ,16,52,88 ,34,70,88 +#endif + ,{ 115, 116, 117, 118, 119, 120 } + ,121, 122, 123 + ,126 + ,{ -1 ,-1 } + ,{ 148, 149, 150, 151, 152, 153 } + ,156, 157, 158 + ,161 }, { "tileset-wasteland", "wasteland", "graphic/tileset/wasteland.png" ,TileTableWasteland - ,TileTypeTableWasteland - ,101, 126 - ,139, 139+24 + ,NULL + ,NULL +#if 1 ,16,52,88 ,34,70,88 +#endif + ,{ 115, 116, 117, 118, 119, 120 } + ,121, 122, 123 + ,126 + ,{ -1 ,-1 } + ,{ 150, 151, 152, 153, 154, 155 } + ,158, 159, 160 + ,163 }, { "tileset-swamp", "swamp", "graphic/tileset/swamp.png" ,TileTableSwamp - ,TileTypeTableSwamp - ,101, 126 - ,136, 136+24 + ,NULL + ,NULL +#if 1 ,16,52,88 ,34,70,88 +#endif + ,{ 115, 116, 117, 118, 119, 120 } + ,121, 122, 123 + ,126 + ,{ -1 ,-1 } + ,{ 147, 148, 149, 150, 151, 152 } + ,155, 156, 157 + ,160 }, }; +#endif + +/*---------------------------------------------------------------------------- +-- Functions +----------------------------------------------------------------------------*/ + /** ** Load tileset and setup TheMap for this tileset. +** +** @see TheMap, @see Tilesets */ global void LoadTileset(void) { int i; int n; int tile; + int gap; + int tiles_per_row; unsigned char* data; + const unsigned short* table; - TheMap.Tileset=&Tilesets[TheMap.Terrain]; + //TheMap.Tileset=&Tilesets[TheMap.Terrain]; + // + // Find the tileset. + // + for( i=0; i<TilesetsCount; ++i ) { + if( !strcmp(TilesetWcNames[TheMap.Terrain],Tilesets[i].Ident) ) { + break; + } + } + if( i==TilesetsCount ) { + fprintf(stderr,"Tileset `%s' not available\n" + ,TilesetWcNames[TheMap.Terrain]); + exit(-1); + } + TheMap.Tileset=&Tilesets[i]; + + // + // Load and prepare the tileset + // TheMap.TileData=LoadGraphic(TheMap.Tileset->File); // // Calculate number of tiles in graphic tile // - TheMap.TileCount=n=(TheMap.TileData->Width*TheMap.TileData->Height) - /(TileSizeX*TileSizeY); + if( TheMap.TileData->Width==626 ) { + // FIXME: allow 1 pixel gap between the tiles!! + gap=1; + tiles_per_row=(TheMap.TileData->Width+1)/(TileSizeX+1); + TheMap.TileCount=n=tiles_per_row*((TheMap.TileData->Height+1) + /(TileSizeY+1)); + } else if( TheMap.TileData->Width==527 ) { + // FIXME: allow 1 pixel gap between the tiles!! + gap=1; + tiles_per_row=(TheMap.TileData->Width+1)/(TileSizeX+1); + TheMap.TileCount=n=tiles_per_row*((TheMap.TileData->Height+1) + /(TileSizeY+1)); + } else { + gap=0; + tiles_per_row=TheMap.TileData->Width/TileSizeX; + TheMap.TileCount=n=tiles_per_row*(TheMap.TileData->Height + /TileSizeY); + } + + DebugLevel2Fn(" %d Tiles in file %s, pro row %d\n" + ,TheMap.TileCount,TheMap.Tileset->File,tiles_per_row); + + if( n>MaxTilesInTileset ) { + fprintf(stderr,"Too many tiles in tileset. Increase MaxTilesInTileset and recompile.\n"); + exit(-1); + } - DebugLevel3(__FUNCTION__": %d Tiles in file %s\n" - ,TheMap.TileCount,TheMap.Tileset->File); // // Precalculate the graphic starts of the tiles @@ -1522,15 +1506,19 @@ global void LoadTileset(void) } // - // Convert the graphic data into faster format + // Convert the graphic data into faster format // for( tile=0; tile<n; ++tile ) { unsigned char* s; unsigned char* d; - s=((char*)TheMap.TileData->Frames)+((tile%TILE_PER_ROW)*TileSizeX) - +((tile/TILE_PER_ROW)*TileSizeY)*TheMap.TileData->Width; - d=data+tile*TileSizeX*TileSizeY; + s=((char*)TheMap.TileData->Frames) + +((tile%tiles_per_row)*(TileSizeX+gap)) + +((tile/tiles_per_row)*(TileSizeY+gap))*TheMap.TileData->Width; + d=TheMap.Tiles[tile]; + if( d!=data+tile*TileSizeX*TileSizeY ) { + abort(); + } for( i=0; i<TileSizeY; ++i ) { memcpy(d,s,TileSizeX*sizeof(unsigned char)); d+=TileSizeX; @@ -1540,36 +1528,345 @@ global void LoadTileset(void) free(TheMap.TileData->Frames); // release old memory TheMap.TileData->Frames=data; - - // FIXME: the complete TileTypeTableXXX can be calculated. + TheMap.TileData->Width=TileSizeX; + TheMap.TileData->Height=TileSizeY*n; // - // Mark water tiles, used for color cycling + // Build the TileTypeTable + // + // FIXME: types are currently hardcoded, use the supplied flags. + // + + table=TheMap.Tileset->Table; + TheMap.Tileset->TileTypeTable + =calloc(n,sizeof(*TheMap.Tileset->TileTypeTable)); + + // + // Solid tiles // for( i=0; i<0x10; ++i ) { - tile=TheMap.Tileset->Table[0x010+i]; // solid light water - if( tile ) { - TheMap.Tileset->TileTypeTable[tile] - =TileTypeWater; + if( (tile=table[0x010+i]) ) { // solid light water + TheMap.Tileset->TileTypeTable[tile]=TileTypeWater; } - tile=TheMap.Tileset->Table[0x020+i]; // solid dark water - if( tile ) { - TheMap.Tileset->TileTypeTable[tile] - =TileTypeWater; + if( (tile=table[0x020+i]) ) { // solid dark water + TheMap.Tileset->TileTypeTable[tile]=TileTypeWater; + } + if( (tile=table[0x030+i]) ) { // solid light coast + TheMap.Tileset->TileTypeTable[tile]=TileTypeCoast; + } + if( (tile=table[0x040+i]) ) { // solid dark coast + TheMap.Tileset->TileTypeTable[tile]=TileTypeCoast; + } + if( (tile=table[0x050+i]) ) { // solid light ground + TheMap.Tileset->TileTypeTable[tile]=TileTypeGrass; + } + if( (tile=table[0x060+i]) ) { // solid dark ground + TheMap.Tileset->TileTypeTable[tile]=TileTypeGrass; + } + if( (tile=table[0x070+i]) ) { // solid forest + TheMap.Tileset->TileTypeTable[tile]=TileTypeWood; + } + if( (tile=table[0x080+i]) ) { // solid rocks + TheMap.Tileset->TileTypeTable[tile]=TileTypeRock; + } + + if( i<3 && (tile=table[0x090+i]) ) { // solid human walls + TheMap.Tileset->TileTypeTable[tile]=TileTypeHumanWall; + } + if( i<3 && (tile=table[0x0A0+i]) ) { // solid orc walls + TheMap.Tileset->TileTypeTable[tile]=TileTypeOrcWall; + } + if( i<3 && (tile=table[0x0B0+i]) ) { // solid human walls + TheMap.Tileset->TileTypeTable[tile]=TileTypeHumanWall; + } + if( i<3 && (tile=table[0x0C0+i]) ) { // solid orc walls + TheMap.Tileset->TileTypeTable[tile]=TileTypeOrcWall; + } + + // 00,D0,E0,F0 Unused + } + + // + // Mixed tiles + // + for( i=0; i<0xE0; ++i ) { + if( (tile=table[0x100+i]) ) { // mixed water + TheMap.Tileset->TileTypeTable[tile]=TileTypeWater; + } + if( (tile=table[0x200+i]) ) { // mixed water/coast + TheMap.Tileset->TileTypeTable[tile]=TileTypeWater; + } + if( (tile=table[0x300+i]) ) { // mixed coast + TheMap.Tileset->TileTypeTable[tile]=TileTypeCoast; + } + if( (tile=table[0x400+i]) ) { // mixed rocks/coast + TheMap.Tileset->TileTypeTable[tile]=TileTypeRock; + } + if( (tile=table[0x500+i]) ) { // mixed ground/coast + TheMap.Tileset->TileTypeTable[tile]=TileTypeCoast; + } + if( (tile=table[0x600+i]) ) { // mixed ground + TheMap.Tileset->TileTypeTable[tile]=TileTypeGrass; + } + if( (tile=table[0x700+i]) ) { // mixed forest/ground + TheMap.Tileset->TileTypeTable[tile]=TileTypeWood; + } + if( (((i&0xF0)==0x40 || (i&0xF0)==0x90) && (i&0xF)<5) + || (i&0xF)<3 ) { + if( (tile=table[0x800+i]) ) { // mixed human wall + TheMap.Tileset->TileTypeTable[tile]=TileTypeHumanWall; + } + if( (tile=table[0x900+i]) ) { // mixed orc wall + TheMap.Tileset->TileTypeTable[tile]=TileTypeOrcWall; + } } } - for( i=0; i<0x100; ++i ) { - tile=TheMap.Tileset->Table[0x100+i]; // mixed water - if( tile ) { - TheMap.Tileset->TileTypeTable[tile] - =TileTypeWater; + + // + // mark the special tiles + // + for( i=0; i<6; ++i ) { + if( (tile=TheMap.Tileset->ExtraTrees[i]) ) { + TheMap.Tileset->TileTypeTable[tile]=TileTypeWood; } - tile=TheMap.Tileset->Table[0x200+i]; // mixed water/coast - if( tile ) { - TheMap.Tileset->TileTypeTable[tile] - =TileTypeWater; + if( (tile=TheMap.Tileset->ExtraRocks[i]) ) { + TheMap.Tileset->TileTypeTable[tile]=TileTypeRock; } } + if( (tile=TheMap.Tileset->TopOneTree) ) { + TheMap.Tileset->TileTypeTable[tile]=TileTypeWood; + } + if( (tile=TheMap.Tileset->MidOneTree) ) { + TheMap.Tileset->TileTypeTable[tile]=TileTypeWood; + } + if( (tile=TheMap.Tileset->BotOneTree) ) { + TheMap.Tileset->TileTypeTable[tile]=TileTypeWood; + } + if( (tile=TheMap.Tileset->TopOneRock) ) { + TheMap.Tileset->TileTypeTable[tile]=TileTypeRock; + } + if( (tile=TheMap.Tileset->MidOneRock) ) { + TheMap.Tileset->TileTypeTable[tile]=TileTypeRock; + } + if( (tile=TheMap.Tileset->BotOneRock) ) { + TheMap.Tileset->TileTypeTable[tile]=TileTypeRock; + } + +#if 0 + for( i=0; i<TheMap.TileCount; ++i ) { + printf("%d,",TheMap.Tileset->TileTypeTable[i]); + if( (i&0x0F)==0xF ) { + printf("\n"); + } + } +#endif + + // + // Build wood removement table. + // + WoodTable[ 0]= -1; + WoodTable[ 1]= TheMap.Tileset->BotOneTree; + WoodTable[ 2]= -1; + WoodTable[ 3]= table[0x710]; + WoodTable[ 4]= TheMap.Tileset->TopOneTree; + WoodTable[ 5]= TheMap.Tileset->MidOneTree; + WoodTable[ 6]= table[0x770]; + WoodTable[ 7]= table[0x790]; + WoodTable[ 8]= -1; + WoodTable[ 9]= table[0x700]; + WoodTable[10]= -1; + WoodTable[11]= table[0x720]; + WoodTable[12]= table[0x730]; + WoodTable[13]= table[0x740]; + WoodTable[14]= table[0x7B0]; + WoodTable[15]= table[0x7D0]; + + // + // Build rock removement table. + // + RockTable[ 0]= -1; + RockTable[ 1]= TheMap.Tileset->BotOneRock; + RockTable[ 2]= -1; + RockTable[ 3]= table[0x410]; + RockTable[ 4]= TheMap.Tileset->TopOneRock; + RockTable[ 5]= TheMap.Tileset->MidOneRock; + RockTable[ 6]= table[0x470]; + RockTable[ 7]= table[0x490]; + RockTable[ 8]= -1; + RockTable[ 9]= table[0x400]; + RockTable[10]= -1; + RockTable[11]= table[0x420]; + RockTable[12]= table[0x430]; + RockTable[13]= table[0x440]; + RockTable[14]= table[0x4B0]; + RockTable[15]= table[0x080]; + + RockTable[16]= table[0x4C0]; + RockTable[17]= table[0x460]; + RockTable[18]= table[0x4A0]; + RockTable[19]= table[0x4D0]; +} + +/** +** Save solid part of tileset. +*/ +local void SaveTilesetSolid(FILE* file,const unsigned short* table + ,const char* name,const char* flag,int start) +{ + int i; + int j; + int n; + + fprintf(file," ( 'solid \"%s\" %s\n #(",name,flag); + for( n=15; n>=0 && !table[start+n] ; n-- ) { + } + i=6; + for( j=0; j<=n; ++j ) { + i+=fprintf(file," %3d",table[start+j]); + } + i+=fprintf(file,"))"); + + while( (i+=8)<80 ) { + fprintf(file,"\t"); + } + fprintf(file,"; %03X\n",start); +} + +/** +** Save mixed part of tileset. +*/ +local void SaveTilesetMixed(FILE* file,const unsigned short* table + ,const char* name1,const char* name2,const char* flag,int start) +{ + int x; + int i; + int j; + int n; + + if( start>=0x9E0 ) { + return; + } + fprintf(file," ( 'mixed \"%s\" \"%s\" %s\n",name1,name2,flag); + for( x=0; x<0x100; x+=0x10 ) { + if( start+x>=0x9E0 ) { + break; + } + fprintf(file," #("); + for( n=15; n>=0 && !table[start+x+n] ; n-- ) { + } + i=6; + for( j=0; j<=n; ++j ) { + i+=fprintf(file," %3d",table[start+x+j]); + } + if( x==0xF0 || (start==0x900 && x==0xD0)) { + i+=fprintf(file,"))"); + } else { + i+=fprintf(file,")"); + } + + while( (i+=8)<80 ) { + fprintf(file,"\t"); + } + fprintf(file,"; %03X\n",start+x); + } +} + +/** +** Save the current tileset. +** +** @param file Output file. +*/ +global void SaveTileset(FILE* file) +{ + const unsigned short* table; + const Tileset* tileset; + int i; + + tileset=TheMap.Tileset; + fprintf(file,"\n;;; -----------------------------------------\n"); + fprintf(file,";;; MODULE: tileset $Id$\n"); + + fprintf(file,"(define-tileset\n '%s",tileset->Ident); + i=strlen(tileset->Ident); + if( i<5 ) { + fputc('\t',file); + } + if( i<13 ) { + fputc('\t',file); + } + fprintf(file,"\t\"%s\"",tileset->Name); + i=strlen(tileset->Name); + if( i<7 ) { + fputc('\t',file); + } + fprintf(file,"\t\"%s\"\n",tileset->File); + fprintf(file," ;; Slots\n '(( 'special\t\t;; Can't be in pud\n"); + fprintf(file," 'extra-trees #( %d %d %d %d %d %d )\n" + ,tileset->ExtraTrees[0] ,tileset->ExtraTrees[1] + ,tileset->ExtraTrees[2] ,tileset->ExtraTrees[3] + ,tileset->ExtraTrees[4] ,tileset->ExtraTrees[5]); + fprintf(file," 'top-one-tree %d 'mid-one-tree %d 'bot-one-tree %d\n" + ,tileset->TopOneTree ,tileset->MidOneTree ,tileset->BotOneTree); + fprintf(file," 'removed-tree %d\n",tileset->RemovedTree); + fprintf(file," 'growing-tree #( %d %d )\n" + ,tileset->GrowingTree[0] ,tileset->GrowingTree[1]); + fprintf(file," 'extra-rocks #( %d %d %d %d %d %d )\n" + ,tileset->ExtraRocks[0] ,tileset->ExtraRocks[1] + ,tileset->ExtraRocks[2] ,tileset->ExtraRocks[3] + ,tileset->ExtraRocks[4] ,tileset->ExtraRocks[5]); + fprintf(file," 'top-one-rock %d 'mid-one-rock %d 'bot-one-rock %d\n" + ,tileset->TopOneRock ,tileset->MidOneRock ,tileset->BotOneRock); + fprintf(file," 'removed-rock %d )\n",tileset->RemovedRock); + + table=TheMap.Tileset->Table; + // + // Solids + // + SaveTilesetSolid(file,table,"unused", "", 0x00); + SaveTilesetSolid(file,table,"light-water", "'water", 0x10); + SaveTilesetSolid(file,table,"dark-water", "'water", 0x20); + SaveTilesetSolid(file,table,"light-coast", "'no-building", 0x30); + SaveTilesetSolid(file,table,"dark-coast", "'no-building", 0x40); + SaveTilesetSolid(file,table,"light-grass", "", 0x50); + SaveTilesetSolid(file,table,"dark-grass", "", 0x60); + SaveTilesetSolid(file,table,"forest", "'forest", 0x70); + SaveTilesetSolid(file,table,"rocks", "'rock", 0x80); + SaveTilesetSolid(file,table,"human-closed-wall", "'wall", 0x90); + SaveTilesetSolid(file,table,"orc-closed-wall", "'wall", 0xA0); + SaveTilesetSolid(file,table,"human-open-wall", "'wall", 0xB0); + SaveTilesetSolid(file,table,"orc-open-wall", "'wall", 0xC0); + SaveTilesetSolid(file,table,"unused", "", 0xD0); + SaveTilesetSolid(file,table,"unused", "", 0xE0); + SaveTilesetSolid(file,table,"unused", "", 0xF0); + + // + // Mixeds + // + SaveTilesetMixed(file,table,"dark-water","light-water","'water", 0x100); + SaveTilesetMixed(file,table,"light-water","light-coast","'coast", 0x200); + SaveTilesetMixed(file,table,"dark-coast","light-coast","'no-building",0x300); + SaveTilesetMixed(file,table,"rocks","light-coast","'rock", 0x400); + SaveTilesetMixed(file,table,"light-coast","light-ground","'no-building",0x500); + SaveTilesetMixed(file,table,"dark-ground","light-ground","", 0x600); + SaveTilesetMixed(file,table,"forest","light-ground","'forest", 0x700); + SaveTilesetMixed(file,table,"human-wall","dark-ground","'wall", 0x800); + SaveTilesetMixed(file,table,"orc-wall","dark-ground","'wall", 0x900); + fprintf(file," )\n"); + fprintf(file," ;; Animated tiles\n"); + fprintf(file," '( #( ) ))\n"); +} + +/** +** Cleanup the tileset module. +** +** NOTE: this didn't frees the configuration memory. +*/ +global void CleanTileset(void) +{ + VideoFree(TheMap.TileData); + IfDebug( TheMap.TileData=NULL; ); + free(TheMap.Tiles); + IfDebug( TheMap.Tiles=NULL; ); } //@} diff --git a/src/stratagus/script.cpp b/src/stratagus/script.cpp index b8e8686a5..842cc7f65 100644 --- a/src/stratagus/script.cpp +++ b/src/stratagus/script.cpp @@ -734,7 +734,7 @@ local SCM CclFreeCraftMap(SCM list) } for( i=0; i<l; ++i ) { TheMap.Fields[i].Tile= - Tilesets[TilesetSummer].Table[ + Tilesets[0].Table[ gh_scm2int(gh_vector_ref(value,gh_int2scm(i))) ]; } @@ -859,6 +859,7 @@ local void gh_main_prog(int argc,char* argv[]) gh_new_procedureN("missile-type",CclMissileType); + TilesetCclRegister(); MapCclRegister(); PathfinderCclRegister(); UnitButtonCclRegister(); @@ -979,6 +980,7 @@ global void CclInit(void) init_lsubr("missile-type",CclMissileType); + TilesetCclRegister(); MapCclRegister(); PathfinderCclRegister(); UnitButtonCclRegister();