mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-27 04:35:52 +01:00
205 lines
9.1 KiB
C
205 lines
9.1 KiB
C
|
/*
|
||
|
* LWSDK Header File
|
||
|
* Copyright 1999, NewTek, Inc.
|
||
|
*
|
||
|
* LWIO.H -- LightWave Save and Load State
|
||
|
*
|
||
|
* This header contains the definition of the structures needed to
|
||
|
* perform I/O from a LightWave server.
|
||
|
*/
|
||
|
#ifndef LWSDK_IO_H
|
||
|
#define LWSDK_IO_H
|
||
|
|
||
|
#include <lwtypes.h>
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Data may be loaded and saved in binary or text files. Text files
|
||
|
* are often scene files, and binary files are often object files.
|
||
|
*
|
||
|
* In BINARY mode, the external form contains raw bytes having any
|
||
|
* value from 0 to 255. Reads and writes are entirely based on the
|
||
|
* number of bytes requested.
|
||
|
*
|
||
|
* In ASCII mode, all data bytes must be in the extended ASCII range
|
||
|
* of 32 to 255. Values outside this range are ignored or undefined.
|
||
|
*/
|
||
|
#define LWIO_BINARY 0
|
||
|
#define LWIO_ASCII 1
|
||
|
#define LWIO_OBJECT LWIO_BINARY
|
||
|
#define LWIO_SCENE LWIO_ASCII
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Blocks of data can be marked with identifiers. In BINARY mode the
|
||
|
* four-byte ID code is used, and in ASCII mode the string token (which
|
||
|
* should not contain spaces) is used.
|
||
|
*/
|
||
|
typedef struct st_LWBlockIdent {
|
||
|
LWID id;
|
||
|
const char *token;
|
||
|
} LWBlockIdent;
|
||
|
|
||
|
|
||
|
/*
|
||
|
* This structure is used when the server is writing its state to
|
||
|
* the external store. The 'writeData' is the first argument to all
|
||
|
* the callback functions.
|
||
|
*
|
||
|
* write execute a raw write to the store. In BINARY mode, the
|
||
|
* number of bytes indicated by 'len' is written directly to
|
||
|
* the output. In ASCII mode the input buffer is treated as
|
||
|
* a null-terminated string and the length is computed from
|
||
|
* that. The string is written with a newline at the end.
|
||
|
*
|
||
|
* writeI1 write an array of different sized and typed integers to
|
||
|
* writeI2 the store. In BINARY mode the 'n' numbers are written as
|
||
|
* writeI4 1, 2 or 4 btype elements in "big-endian" (Motorola)
|
||
|
* writeU1 format. In ASCII mode, all 'n' numbers are written to a
|
||
|
* writeU2 single line, the signed values in decimal and the unsigned
|
||
|
* writeU4 values in hexadecimal. A newline is written after the
|
||
|
* list of numbers unless the writing is done inside a leaf
|
||
|
* block.
|
||
|
*
|
||
|
* writeStr write a null-terminated string to the store. In ASCII
|
||
|
* mode the string may be contained in double quotes.
|
||
|
*
|
||
|
* writeID write an identifier token to the store. In BINARY mode
|
||
|
* this is the four-byte ID code, while in ASCII mode this
|
||
|
* is the string token.
|
||
|
*
|
||
|
* beginBlk start a nested data block. The block is identified by
|
||
|
* the ID codes defined in the LWBlockIdent, and the 'leaf'
|
||
|
* flag is true if this block will not contain other blocks.
|
||
|
*
|
||
|
* endBlk end the current data block.
|
||
|
*
|
||
|
* depth return the current block nesting level, where zero means
|
||
|
* we've entered no blocks.
|
||
|
*/
|
||
|
typedef struct st_LWSaveState {
|
||
|
int ioMode;
|
||
|
void *writeData;
|
||
|
void (*write) (void *data, const char *, int len);
|
||
|
|
||
|
void (*writeI1) (void *data, const char *, int n);
|
||
|
void (*writeI2) (void *data, const short *, int n);
|
||
|
void (*writeI4) (void *data, const long *, int n);
|
||
|
void (*writeU1) (void *data, const unsigned char *, int n);
|
||
|
void (*writeU2) (void *data, const unsigned short *, int n);
|
||
|
void (*writeU4) (void *data, const unsigned long *, int n);
|
||
|
void (*writeFP) (void *data, const float *, int n);
|
||
|
void (*writeStr) (void *data, const char *);
|
||
|
void (*writeID) (void *data, const LWBlockIdent *);
|
||
|
|
||
|
void (*beginBlk) (void *data, const LWBlockIdent *, int leaf);
|
||
|
void (*endBlk) (void *data);
|
||
|
int (*depth) (void *data);
|
||
|
} LWSaveState;
|
||
|
|
||
|
|
||
|
/*
|
||
|
* This structure is used when the server is reading its state from
|
||
|
* the external store. The 'readData' is the first argument to all
|
||
|
* the callback functions.
|
||
|
*
|
||
|
* read execute a raw read of the store. In binary mode, 'len'
|
||
|
* bytes are read directly from the store. In ASCII mode, up
|
||
|
* to 'len' bytes of the current line are read from the
|
||
|
* store, perhaps leaving more bytes to be read later. The
|
||
|
* return value is the number of bytes read on the current
|
||
|
* line (which may be zero), or -1 for end of data.
|
||
|
*
|
||
|
* readI1 read an array of integers of various types and formats,
|
||
|
* readI2 returning the number of integers successfully read. In
|
||
|
* readI4 BINARY mode a sequence of 'n' single, double or quad bytes
|
||
|
* readU1 are read from the stream and interpreted as "big-endian"
|
||
|
* readU2 (Motorola) format words. In ASCII mode, the numbers are
|
||
|
* readU4 read from the current line, in decimal for signed values
|
||
|
* and in hexadecimal for unsigned values.
|
||
|
*
|
||
|
* readFP read an array of floating point numbers from the store.
|
||
|
* The return value is the number of values read.
|
||
|
*
|
||
|
* readStr read a string from the store. In ASCII mode double quotes
|
||
|
* will be removed.
|
||
|
*
|
||
|
* readID read an identifier token from the store. In BINARY this is
|
||
|
* just a four-byte code value, but in ASCII this in the string
|
||
|
* token which will be matched with its longword code.
|
||
|
*
|
||
|
* findBlk read ahead looking for the next block. The array of block
|
||
|
* identifiers includes all the blocks that could be expected
|
||
|
* and is terminated with a null ID code. If a reconginized
|
||
|
* block is found in the file, it's ID code is returned. A
|
||
|
* zero return indicates no more valid blocks.
|
||
|
*
|
||
|
* endBlk complete reading the current open block.
|
||
|
*
|
||
|
* depth return the current block nesting level, where zero means
|
||
|
* we've entered no blocks.
|
||
|
*/
|
||
|
typedef struct st_LWLoadState {
|
||
|
int ioMode;
|
||
|
void *readData;
|
||
|
int (*read) (void *data, char *, int len);
|
||
|
|
||
|
int (*readI1) (void *data, char *, int n);
|
||
|
int (*readI2) (void *data, short *, int n);
|
||
|
int (*readI4) (void *data, long *, int n);
|
||
|
int (*readU1) (void *data, unsigned char *, int n);
|
||
|
int (*readU2) (void *data, unsigned short *, int n);
|
||
|
int (*readU4) (void *data, unsigned long *, int n);
|
||
|
int (*readFP) (void *data, float *, int n);
|
||
|
int (*readStr) (void *data, char *, int max);
|
||
|
LWID (*readID) (void *data, const LWBlockIdent *);
|
||
|
|
||
|
LWID (*findBlk) (void *data, const LWBlockIdent *);
|
||
|
void (*endBlk) (void *data);
|
||
|
int (*depth) (void *data);
|
||
|
} LWLoadState;
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Macros make the call format easier to write.
|
||
|
*/
|
||
|
#define LWSAVE_I1(lwss,p,n) (*(lwss)->writeI1)((lwss)->writeData,p,n)
|
||
|
#define LWSAVE_I2(lwss,p,n) (*(lwss)->writeI2)((lwss)->writeData,p,n)
|
||
|
#define LWSAVE_I4(lwss,p,n) (*(lwss)->writeI4)((lwss)->writeData,p,n)
|
||
|
#define LWSAVE_U1(lwss,p,n) (*(lwss)->writeU1)((lwss)->writeData,p,n)
|
||
|
#define LWSAVE_U2(lwss,p,n) (*(lwss)->writeU2)((lwss)->writeData,p,n)
|
||
|
#define LWSAVE_U4(lwss,p,n) (*(lwss)->writeU4)((lwss)->writeData,p,n)
|
||
|
#define LWSAVE_FP(lwss,p,n) (*(lwss)->writeFP)((lwss)->writeData,p,n)
|
||
|
#define LWSAVE_STR(lwss,p) (*(lwss)->writeStr)((lwss)->writeData,p)
|
||
|
#define LWSAVE_ID(lwss,b) (*(lwss)->writeID)((lwss)->writeData,b)
|
||
|
#define LWSAVE_BEGIN(lwss,b,l) (*(lwss)->beginBlk)((lwss)->writeData,b,l)
|
||
|
#define LWSAVE_END(lwss) (*(lwss)->endBlk)((lwss)->writeData)
|
||
|
#define LWSAVE_DEPTH(lwss) (*(lwss)->depth)((lwss)->writeData)
|
||
|
|
||
|
#define LWLOAD_I1(lwls,p,n) (*(lwls)->readI1)((lwls)->readData,p,n)
|
||
|
#define LWLOAD_I2(lwls,p,n) (*(lwls)->readI2)((lwls)->readData,p,n)
|
||
|
#define LWLOAD_I4(lwls,p,n) (*(lwls)->readI4)((lwls)->readData,p,n)
|
||
|
#define LWLOAD_U1(lwls,p,n) (*(lwls)->readU1)((lwls)->readData,p,n)
|
||
|
#define LWLOAD_U2(lwls,p,n) (*(lwls)->readU2)((lwls)->readData,p,n)
|
||
|
#define LWLOAD_U4(lwls,p,n) (*(lwls)->readU4)((lwls)->readData,p,n)
|
||
|
#define LWLOAD_FP(lwls,p,n) (*(lwls)->readFP)((lwls)->readData,p,n)
|
||
|
#define LWLOAD_STR(lwls,p,n) (*(lwls)->readStr)((lwls)->readData,p,n)
|
||
|
#define LWLOAD_ID(lwls,b) (*(lwls)->readID)((lwls)->readData,b)
|
||
|
#define LWLOAD_FIND(lwls,b) (*(lwls)->findBlk)((lwls)->readData,b)
|
||
|
#define LWLOAD_END(lwls) (*(lwls)->endBlk)((lwls)->readData)
|
||
|
#define LWLOAD_DEPTH(lwls) (*(lwls)->depth)((lwls)->readData)
|
||
|
|
||
|
|
||
|
#define LWFILEIOFUNCS_GLOBAL "File IO"
|
||
|
#define LWIO_BINARY_IFF 0x8C0000
|
||
|
|
||
|
typedef struct st_LWFileIOFuncs {
|
||
|
LWSaveState * (*openSave) (const char *name, int ioMode);
|
||
|
void (*closeSave)(LWSaveState *save);
|
||
|
LWLoadState * (*openLoad) (const char *name, int ioMode);
|
||
|
void (*closeLoad)(LWLoadState *load);
|
||
|
} LWFileIOFuncs;
|
||
|
|
||
|
#endif
|
||
|
|