source: abuse/trunk/src/imlib/specs.h @ 539

Last change on this file since 539 was 539, checked in by Sam Hocevar, 8 years ago

imlib: implement a small spec file dumper. "abuse -export foo.spe" will
extract the contents of the file and create PCX files from the images.

  • Property svn:keywords set to Id
File size: 6.8 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5 *
6 *  This software was released into the Public Domain. As with most public
7 *  domain software, no warranty is made or implied by Crack dot Com or
8 *  Jonathan Clark.
9 */
10
11#ifndef __SPECS_HPP_
12#define __SPECS_HPP_
13
14#include <stdio.h>
15#include <fcntl.h>
16#include <stdlib.h>
17#include <stdint.h>
18#include <string.h>
19
20#include "linked.h"
21
22extern char const *spec_types[];
23
24enum
25{
26    SPEC_INVALID_TYPE = 0,
27    SPEC_COLOR_TABLE,
28    SPEC_PALETTE,
29    SPEC_, /* Unused */
30    SPEC_IMAGE,
31    SPEC_FORETILE,
32    SPEC_BACKTILE,
33    SPEC_CHARACTER,
34    SPEC_MORPH_POINTS_8,
35    SPEC_MORPH_POINTS_16,
36    SPEC_GRUE_OBJS,
37    SPEC_EXTERN_SFX,
38    SPEC_DMX_MUS,
39    SPEC_PATCHED_MORPH,
40    SPEC_NORMAL_FILE,
41    SPEC_COMPRESS1_FILE,
42    SPEC_VECTOR_IMAGE,
43    SPEC_LIGHT_LIST,
44    SPEC_GRUE_FGMAP,
45    SPEC_GRUE_BGMAP,
46    SPEC_DATA_ARRAY,
47    SPEC_CHARACTER2,
48    SPEC_PARTICLE,
49    SPEC_EXTERNAL_LCACHE,
50};
51
52#define SPEC_SIGNATURE    "SPEC1.0"
53#define SPEC_SIG_SIZE     8
54
55#define SPEC_FLAG_LINK    1
56
57#define SPEC_SEARCH_INSIDE_OUTSIDE 1
58#define SPEC_SEARCH_OUTSIDE_INSIDE 2
59#define SPEC_SEARCH_INSIDE_ONLY    3
60
61/*  struct spec_header
62 *  {
63 *      char signature[8];
64 *      uint16_t entries_count;
65 *      struct entry
66 *      {
67 *          uint8_t type;
68 *          uint8_t name_length;
69 *          char name[name_length];
70 *          uint8_t flags;
71 *          if (flags & LINK)
72 *          {
73 *              uint8_t filename_length;
74 *              char filename[filename_length];
75 *          }
76 *          else
77 *          {
78 *              uint32_t data_size;
79 *              uint32_t offset;
80 *          }
81 *      } entries[entries_count];
82 *  }
83 */
84
85void set_spec_main_file(char const *filename, int search_order=SPEC_SEARCH_OUTSIDE_INSIDE);
86
87void set_filename_prefix(char const *prefix);
88char *get_filename_prefix();
89void set_save_filename_prefix(char const *prefix);
90char *get_save_filename_prefix();
91#define JFILE_CLONED 1
92
93class bFILE     // base file type which other files should be derived from (jFILE & NFS for now)
94{
95  protected :
96  unsigned char *rbuf,*wbuf;
97  unsigned long rbuf_start,rbuf_end,rbuf_size,
98                wbuf_end,wbuf_size;                // can't seek while writing!
99  int flush_writes();                             // returns 0 on failure, else # of bytes written
100
101  virtual int unbuffered_read(void *buf, size_t count)  = 0;
102  virtual int unbuffered_write(void const *buf, size_t count) = 0;
103  virtual int unbuffered_tell()                         = 0;
104  virtual int unbuffered_seek(long offset, int whence)  = 0;   // whence=SEEK_SET, SEEK_CUR,
105                                                               // SEEK_END, ret=0=success
106  virtual int allow_read_buffering();
107  virtual int allow_write_buffering();
108  public :
109  bFILE();
110  virtual int open_failure() = 0;
111  int read(void *buf, size_t count);        // returns number of bytes read, calls unbuffer_read
112  int write(void const *buf, size_t count); // returns number of bytes written
113  int seek(long offset, int whence);        // whence=SEEK_SET, SEEK_CUR, SEEK_END, ret=0=success
114  int tell();
115  virtual int file_size() = 0;
116
117  virtual ~bFILE();
118
119    // read and write using little-endianness
120    uint16_t read_uint16();
121    uint32_t read_uint32();
122    uint8_t read_uint8();
123    double read_double();
124    void write_uint16(uint16_t x);
125    void write_uint32(uint32_t x);
126    void write_uint8(uint8_t x);
127    void write_double(double x);
128};
129
130class jFILE : public bFILE     // this file type will use virtual opens inside of a spe
131{
132  char *fname;
133  char *tmp_write_name;
134  int access;
135  int fd,flags;
136  long start_offset,file_length;    // offset of file from actual file begining
137
138  long current_offset;  // current offset
139
140public :
141    int get_fd() const { return fd; }
142
143  void open_internal(char const *filename, char const *mode, int flags);
144  void open_external(char const *filename, char const *mode, int flags);
145
146  jFILE(char const *filename, char const *access_string);      // same as fopen parameters
147  jFILE(FILE *file_pointer);                      // assumes fp is at begining of file
148  virtual int open_failure() { return fd<0; }
149  virtual int unbuffered_read(void *buf, size_t count);       // returns number of bytes read
150  virtual int unbuffered_write(void const *buf, size_t count);     // returns number of bytes written
151  virtual int unbuffered_seek(long offset, int whence);      // whence=SEEK_SET, SEEK_CUR,
152                                                             // SEEK_END, ret=0=success
153  virtual int unbuffered_tell();
154  virtual int file_size() { return file_length; }
155  virtual ~jFILE();
156} ;
157
158class spec_entry
159{
160public :
161  char *name;
162  unsigned long size,offset;
163  unsigned char type;
164
165  spec_entry(unsigned char spec_type,
166             char const *object_name,
167             char const *link_filename,
168             unsigned long data_size,
169             unsigned long data_offset)
170  { type = spec_type;
171    name = strdup(object_name);
172    size = data_size;
173    offset = data_offset;
174  }
175  void print();
176  ~spec_entry() { if (name) free(name); }
177} ;
178
179
180class spec_directory
181{
182public :
183  void startup(bFILE *fp);
184
185  int total;
186  spec_entry **entries;
187  void *data;
188  long size;
189//  spec_directory(char *filename);  ; ; not allowed anymore, user must construct file first!
190  spec_directory(FILE *fp);
191  spec_directory(bFILE *fp);
192  spec_directory();
193  spec_entry *find(char const *name);
194  spec_entry *find(char const *name, int type);
195  spec_entry *find(int type);
196  long find_number(char const *name);
197  long find_number(int type);
198  void remove(spec_entry *e);
199  void add_by_hand(spec_entry *e);
200  void calc_offsets();
201  long data_start_offset();  // returns the first offset past directory items
202  long data_end_offset();    // this should be the end of the file
203  long type_total(int type);
204  jFILE *write(char const *filename);
205  int    write(bFILE *fp);
206  void print();
207  void delete_entries();   // if the directory was created by hand instead of by file
208  ~spec_directory();
209
210  static void extract(char const *name);
211} ;
212
213/*jFILE *add_directory_entry(char *filename,
214                         unsigned short data_type,
215                         char *data_name,
216                         unsigned long data_size,
217                         char *link_filename=NULL); */
218
219uint16_t read_uint16(FILE *fp);
220uint32_t read_uint32(FILE *fp);
221uint8_t read_uint8(FILE *fp);
222
223void write_uint16(FILE *fp, uint16_t x);
224void write_uint32(FILE *fp, uint32_t x);
225void write_uint8(FILE *fp, uint8_t x);
226
227void set_spec_main_file(char *filename, int Search_order);
228void set_file_opener(bFILE *(*open_fun)(char const *, char const *));
229void set_no_space_handler(void (*handle_fun)());
230bFILE *open_file(char const *filename, char const *mode);
231#endif
232
Note: See TracBrowser for help on using the repository browser.