diff options
author | rubidium <rubidium@openttd.org> | 2007-01-02 19:19:48 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2007-01-02 19:19:48 +0000 |
commit | 013df98f79866a75f367853c9e436f3c5c79f645 (patch) | |
tree | ad4a63860df2626b22f77e7dac712e958bea54cb /src/fileio.c | |
parent | 3d32fd3f4bfaceb8a48530fbc2f4bd5db2752596 (diff) | |
download | openttd-013df98f79866a75f367853c9e436f3c5c79f645.tar.xz |
(svn r7759) -Merge: makefile rewrite. This merge features:
- A proper ./configure, so everything needs to be configured only once, not for every make.
- Usage of makedepend when available. This greatly reduces the time needed for generating the dependencies.
- A generator for all project files. There is a single file with sources, which is used to generate Makefiles and the project files for MSVC.
- Proper support for OSX universal binaries.
- Object files for non-MSVC compiles are also placed in separate directories, making is faster to switch between debug and release compiles and it does not touch the directory with the source files.
- Functionality to make a bundle of all needed files for for example a nightly or distribution of a binary with all needed GRFs and language files.
Note: as this merge moves almost all files, it is recommended to make a backup of your working copy before updating your working copy.
Diffstat (limited to 'src/fileio.c')
-rw-r--r-- | src/fileio.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/fileio.c b/src/fileio.c new file mode 100644 index 000000000..2a09916ea --- /dev/null +++ b/src/fileio.c @@ -0,0 +1,151 @@ +/* $Id$ */ + +#include "stdafx.h" +#include "openttd.h" +#include "fileio.h" +#include "functions.h" +#include "string.h" +#include "macros.h" +#include "variables.h" + +/*************************************************/ +/* FILE IO ROUTINES ******************************/ +/*************************************************/ + +#define FIO_BUFFER_SIZE 512 + +typedef struct { + byte *buffer, *buffer_end; ///< position pointer in local buffer and last valid byte of buffer + uint32 pos; ///< current (system) position in file + FILE *cur_fh; ///< current file handle + FILE *handles[64]; ///< array of file handles we can have open + byte buffer_start[FIO_BUFFER_SIZE]; ///< local buffer when read from file +} Fio; + +static Fio _fio; + +// Get current position in file +uint32 FioGetPos(void) +{ + return _fio.pos + (_fio.buffer - _fio.buffer_start) - FIO_BUFFER_SIZE; +} + +void FioSeekTo(uint32 pos, int mode) +{ + if (mode == SEEK_CUR) pos += FioGetPos(); + _fio.buffer = _fio.buffer_end = _fio.buffer_start + FIO_BUFFER_SIZE; + _fio.pos = pos; + fseek(_fio.cur_fh, _fio.pos, SEEK_SET); +} + +// Seek to a file and a position +void FioSeekToFile(uint32 pos) +{ + FILE *f = _fio.handles[pos >> 24]; + assert(f != NULL); + _fio.cur_fh = f; + FioSeekTo(GB(pos, 0, 24), SEEK_SET); +} + +byte FioReadByte(void) +{ + if (_fio.buffer == _fio.buffer_end) { + _fio.pos += FIO_BUFFER_SIZE; + fread(_fio.buffer = _fio.buffer_start, 1, FIO_BUFFER_SIZE, _fio.cur_fh); + } + return *_fio.buffer++; +} + +void FioSkipBytes(int n) +{ + for (;;) { + int m = min(_fio.buffer_end - _fio.buffer, n); + _fio.buffer += m; + n -= m; + if (n == 0) break; + FioReadByte(); + n--; + } +} + +uint16 FioReadWord(void) +{ + byte b = FioReadByte(); + return (FioReadByte() << 8) | b; +} + +uint32 FioReadDword(void) +{ + uint b = FioReadWord(); + return (FioReadWord() << 16) | b; +} + +void FioReadBlock(void *ptr, uint size) +{ + FioSeekTo(FioGetPos(), SEEK_SET); + _fio.pos += size; + fread(ptr, 1, size, _fio.cur_fh); +} + +static inline void FioCloseFile(int slot) +{ + if (_fio.handles[slot] != NULL) { + fclose(_fio.handles[slot]); + _fio.handles[slot] = NULL; + } +} + +void FioCloseAll(void) +{ + int i; + + for (i = 0; i != lengthof(_fio.handles); i++) + FioCloseFile(i); +} + +bool FioCheckFileExists(const char *filename) +{ + FILE *f = FioFOpenFile(filename); + if (f == NULL) return false; + + fclose(f); + return true; +} + +FILE *FioFOpenFile(const char *filename) +{ + FILE *f; + char buf[MAX_PATH]; + + snprintf(buf, lengthof(buf), "%s%s", _paths.data_dir, filename); + + f = fopen(buf, "rb"); +#if !defined(WIN32) + if (f == NULL) { + strtolower(buf + strlen(_paths.data_dir) - 1); + f = fopen(buf, "rb"); + +#if defined SECOND_DATA_DIR + // tries in the 2nd data directory + if (f == NULL) { + snprintf(buf, lengthof(buf), "%s%s", _paths.second_data_dir, filename); + strtolower(buf + strlen(_paths.second_data_dir) - 1); + f = fopen(buf, "rb"); + } +#endif + } +#endif + + return f; +} + +void FioOpenFile(int slot, const char *filename) +{ + FILE *f = FioFOpenFile(filename); + + if (f == NULL) error("Cannot open file '%s%s'", _paths.data_dir, filename); + + FioCloseFile(slot); // if file was opened before, close it + _fio.handles[slot] = f; + FioSeekToFile(slot << 24); +} |