1 /**
2  * Graphics - sprites management
3 
4  * Copyright (C) 2007, 2008  Sylvain Beucler
5 
6  * This file is part of GNU FreeDink
7 
8  * GNU FreeDink is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 3 of the
11  * License, or (at your option) any later version.
12 
13  * GNU FreeDink is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17 
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see
20  * <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef _GFX_SPRITES_H
24 #define _GFX_SPRITES_H
25 
26 #include "SDL.h"
27 #include "rect.h"
28 
29 #ifdef __cplusplus
30 extern "C"
31 {
32 #endif
33 
34 /* Max number of sprites, minus 1 (GFX_k is indexed from 1) */
35 #define MAX_SPRITES 4000
36 #define MAX_FRAMES_PER_SEQUENCE 50
37 /* Max number of frames the engine was ever abused to load in one
38    sequence (with a buffer overflow on other 'seq' fields). According
39    to a study of existing D-Mods in 2009, the highest frame number is
40    69 (in "The Green Voice in my Head Part I v3.0"). The engine would
41    accept up to 1000 frames but it would probably mess the memory too
42    much. */
43 #define MAX_FRAMES_PER_ABUSED_SEQUENCE 69
44 #define MAX_SEQUENCES 1000 /* Max # of sprite animations */
45 
46   /* Store sprites info */
47   struct pic_info
48   {
49     /*   LPDIRECTDRAWSURFACE k; // Sprites */
50 
51     rect box;     // Dimensions (0,0,width,height)
52     rect hardbox; // Square where Dink can't block if sprite is hard
53 
54     int yoffset;  // Center of the picture
55     int xoffset;
56   };
57 
58   struct GFX_pic_info
59   {
60     SDL_Surface *k; // Sprites
61     /* TODO: move pic_info to GFX_pic_info; if possible, replace 'box'
62        with k->h and k->w in the code */
63   };
64 
65   /* Sequence description */
66   struct sequence
67   {
68     char* ini;      // matching dink.ini (or init()) line
69     char is_active;  // does it contain something
70     short len;        // number of initial frames in this sequence
71                     // - inaccurate if the sequence is modified by 'set_frame_frame'
72     /* frame: index in GFX_k for the each frame, indexed from 1, ended
73        by '0'. If -1, loop from beginning. Now this one is tricky: the
74        original engine's load_sprite() can load non-animated sequences
75        of more than MAX_FRAMES_PER_SEQUENCE (up to 1000) at the
76        expense of a non-critical buffer overflow in 'delay' and
77        'special'.  */
78     short frame[MAX_FRAMES_PER_ABUSED_SEQUENCE+1+1];
79     short delay[MAX_FRAMES_PER_ABUSED_SEQUENCE+1]; // frame duration, indexed from 1
80     unsigned char special[MAX_FRAMES_PER_ABUSED_SEQUENCE+1]; // does this frame 'hit' enemies, indexed from 1
81   };
82 
83   extern struct pic_info k[MAX_SPRITES];
84   extern struct GFX_pic_info GFX_k[MAX_SPRITES];
85   extern struct sequence seq[MAX_SEQUENCES];
86 
87   extern void sprites_unload(void);
88   extern void load_sprite_pak(char seq_path_prefix[100], int seq_no, int speed, int xoffset, int yoffset,
89 			      rect hardbox, int flags, int samedir);
90   extern void load_sprites(char seq_path_prefix[100], int seq_no, int speed, int xoffset, int yoffset,
91 			   rect hardbox, int flags);
92   extern void seq_set_ini(int seq_no, char *line);
93 
94 #ifdef __cplusplus
95 }
96 #endif
97 
98 #endif
99