2012-09-23 18:11:08 +00:00
|
|
|
#ifndef OPENMW_ESM_LAND_H
|
|
|
|
#define OPENMW_ESM_LAND_H
|
2010-02-25 13:03:03 +00:00
|
|
|
|
2014-03-05 16:08:58 +00:00
|
|
|
#include <stdint.h>
|
2012-09-17 07:37:50 +00:00
|
|
|
|
2012-09-23 18:41:41 +00:00
|
|
|
#include "esmcommon.hpp"
|
2010-02-25 13:03:03 +00:00
|
|
|
|
2011-04-06 16:11:08 +00:00
|
|
|
namespace ESM
|
|
|
|
{
|
2012-09-30 20:51:54 +00:00
|
|
|
|
|
|
|
class ESMReader;
|
|
|
|
class ESMWriter;
|
|
|
|
|
2010-02-25 13:03:03 +00:00
|
|
|
/*
|
|
|
|
* Landscape data.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct Land
|
|
|
|
{
|
2013-09-24 11:17:28 +00:00
|
|
|
static unsigned int sRecordId;
|
|
|
|
|
2012-04-01 19:29:49 +00:00
|
|
|
Land();
|
2012-04-04 19:05:19 +00:00
|
|
|
~Land();
|
2012-04-01 19:29:49 +00:00
|
|
|
|
2012-09-17 07:37:50 +00:00
|
|
|
int mFlags; // Only first four bits seem to be used, don't know what
|
2011-04-06 16:11:08 +00:00
|
|
|
// they mean.
|
2012-09-17 07:37:50 +00:00
|
|
|
int mX, mY; // Map coordinates.
|
2013-01-20 18:07:33 +00:00
|
|
|
int mPlugin; // Plugin index, used to reference the correct material palette.
|
2010-02-25 13:03:03 +00:00
|
|
|
|
2011-04-06 16:11:08 +00:00
|
|
|
// File context. This allows the ESM reader to be 'reset' to this
|
|
|
|
// location later when we are ready to load the full data set.
|
2012-03-27 08:20:22 +00:00
|
|
|
ESMReader* mEsm;
|
2012-09-17 07:37:50 +00:00
|
|
|
ESM_Context mContext;
|
2010-02-25 13:03:03 +00:00
|
|
|
|
2012-09-17 07:37:50 +00:00
|
|
|
bool mHasData;
|
|
|
|
int mDataTypes;
|
2012-09-21 08:12:16 +00:00
|
|
|
int mDataLoaded;
|
2010-02-25 13:03:03 +00:00
|
|
|
|
2012-06-11 18:02:03 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
DATA_VNML = 1,
|
|
|
|
DATA_VHGT = 2,
|
|
|
|
DATA_WNAM = 4,
|
|
|
|
DATA_VCLR = 8,
|
|
|
|
DATA_VTEX = 16
|
|
|
|
};
|
2012-01-21 16:59:08 +00:00
|
|
|
|
|
|
|
// number of vertices per side
|
|
|
|
static const int LAND_SIZE = 65;
|
|
|
|
|
|
|
|
// cell terrain size in world coords
|
|
|
|
static const int REAL_SIZE = 8192;
|
|
|
|
|
|
|
|
// total number of vertices
|
|
|
|
static const int LAND_NUM_VERTS = LAND_SIZE * LAND_SIZE;
|
|
|
|
|
|
|
|
static const int HEIGHT_SCALE = 8;
|
|
|
|
|
2012-01-21 17:59:12 +00:00
|
|
|
//number of textures per side of land
|
|
|
|
static const int LAND_TEXTURE_SIZE = 16;
|
|
|
|
|
|
|
|
//total number of textures per land
|
|
|
|
static const int LAND_NUM_TEXTURES = LAND_TEXTURE_SIZE * LAND_TEXTURE_SIZE;
|
|
|
|
|
2012-01-21 16:59:08 +00:00
|
|
|
#pragma pack(push,1)
|
|
|
|
struct VHGT
|
|
|
|
{
|
2012-09-17 07:37:50 +00:00
|
|
|
float mHeightOffset;
|
|
|
|
int8_t mHeightData[LAND_NUM_VERTS];
|
2012-09-21 05:36:18 +00:00
|
|
|
short mUnk1;
|
|
|
|
char mUnk2;
|
2012-01-21 16:59:08 +00:00
|
|
|
};
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
2013-12-06 06:36:16 +00:00
|
|
|
typedef signed char VNML;
|
2012-01-21 16:59:08 +00:00
|
|
|
|
|
|
|
struct LandData
|
|
|
|
{
|
2012-09-17 07:37:50 +00:00
|
|
|
float mHeightOffset;
|
|
|
|
float mHeights[LAND_NUM_VERTS];
|
2013-12-06 06:36:16 +00:00
|
|
|
VNML mNormals[LAND_NUM_VERTS * 3];
|
2012-09-17 07:37:50 +00:00
|
|
|
uint16_t mTextures[LAND_NUM_TEXTURES];
|
2012-02-29 23:05:22 +00:00
|
|
|
|
2012-09-17 07:37:50 +00:00
|
|
|
bool mUsingColours;
|
|
|
|
char mColours[3 * LAND_NUM_VERTS];
|
|
|
|
int mDataTypes;
|
2012-04-06 19:04:30 +00:00
|
|
|
|
2014-10-27 14:34:37 +00:00
|
|
|
// WNAM appears to contain the global map image for this cell. Probably a palette-based format,
|
|
|
|
// since there's only 1 byte for each pixel.
|
|
|
|
// Currently unused (global map is drawn on the fly in OpenMW, takes ~1/2 second at startup for Morrowind.esm).
|
|
|
|
// The problem with using the original data is that we would need to exactly replicate the TES CS's algorithm
|
|
|
|
// for drawing the global map in OpenCS, in order to get seamless edges when creating landmass mods.
|
2012-09-20 16:33:30 +00:00
|
|
|
uint8_t mWnam[81];
|
|
|
|
short mUnk1;
|
|
|
|
uint8_t mUnk2;
|
|
|
|
|
2012-04-06 19:04:30 +00:00
|
|
|
void save(ESMWriter &esm);
|
2012-09-21 05:36:18 +00:00
|
|
|
static void transposeTextureData(uint16_t *in, uint16_t *out);
|
2012-01-21 16:59:08 +00:00
|
|
|
};
|
|
|
|
|
2012-09-17 07:37:50 +00:00
|
|
|
LandData *mLandData;
|
2012-01-21 16:59:08 +00:00
|
|
|
|
2011-04-06 16:11:08 +00:00
|
|
|
void load(ESMReader &esm);
|
2013-09-16 10:32:35 +00:00
|
|
|
void save(ESMWriter &esm) const;
|
2012-01-21 16:59:08 +00:00
|
|
|
|
2014-10-08 15:17:31 +00:00
|
|
|
void blank() {}
|
|
|
|
|
2012-01-21 16:59:08 +00:00
|
|
|
/**
|
|
|
|
* Actually loads data
|
|
|
|
*/
|
2012-09-21 08:12:16 +00:00
|
|
|
void loadData(int flags);
|
2012-04-04 19:05:19 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Frees memory allocated for land data
|
|
|
|
*/
|
|
|
|
void unloadData();
|
2012-04-04 19:39:21 +00:00
|
|
|
|
2012-09-21 08:12:16 +00:00
|
|
|
/// Check if given data type is loaded
|
|
|
|
/// \todo reimplement this
|
|
|
|
bool isDataLoaded(int flags) {
|
|
|
|
return (mDataLoaded & flags) == flags;
|
|
|
|
}
|
|
|
|
|
2012-04-04 19:39:21 +00:00
|
|
|
private:
|
|
|
|
Land(const Land& land);
|
|
|
|
Land& operator=(const Land& land);
|
2012-09-21 08:12:16 +00:00
|
|
|
|
|
|
|
/// Loads data and marks it as loaded
|
|
|
|
/// \return true if data is actually loaded from file, false otherwise
|
|
|
|
/// including the case when data is already loaded
|
|
|
|
bool condLoad(int flags, int dataFlag, void *ptr, unsigned int size);
|
2010-02-25 13:03:03 +00:00
|
|
|
};
|
2012-04-04 19:39:21 +00:00
|
|
|
|
2010-02-25 13:03:03 +00:00
|
|
|
}
|
|
|
|
#endif
|