error.[ch]: fix keyword usage
[0verkill.git] / sprite.c
blob22af99ff3e20735c97dfb924c4613a3383eecd8c
1 #include <string.h>
2 #include <ctype.h>
3 #include <stdlib.h>
4 #include <stdio.h>
6 #ifndef WIN32
7 #include "config.h"
8 #endif
10 #include "sprite.h"
11 #include "blit.h"
12 #include "data.h"
13 #include "console.h"
14 #include "cfg.h"
15 #include "error.h"
19 /* allocate memory for screenbuffer */
20 void init_sprites(void)
22 init_blit();
25 void shutdown_sprites(void)
27 shutdown_blit();
31 /* write visible window of playing area into screenbuffer */
32 void show_window(int x,int y)
34 int a,loffs,roffs;
35 int prec2=y*AREA_X;
37 if (x+SCREEN_X<=0)return;
38 if (y+SCREEN_Y<=0)return;
40 loffs=x<0?-x:0;
41 roffs=x+SCREEN_X>AREA_X?x+SCREEN_X-AREA_X:0;
42 #ifdef TRI_D
43 switch (tri_d)
45 case 0: /* normal part */
46 for(a=(y<0?-y:0);a<SCREEN_Y&&(y+a)<AREA_Y;a++)
48 int prec=a*SCREEN_X;
49 int prec1=a*AREA_X;
51 memcpy(screen+prec+loffs,area+loffs+x+prec2+prec1,SCREEN_X-loffs-roffs);
52 memcpy(screen_a+prec+loffs,area_a+loffs+x+prec2+prec1,SCREEN_X-loffs-roffs);
54 break;
56 case 1: /* 3d part */
57 memset(screen2_a,0,SCREEN_X*SCREEN_Y);
58 memset(screen2,0,SCREEN_X*SCREEN_Y);
59 for(a=(y<0?-y:0);a<SCREEN_Y&&(y+a)<AREA_Y;a++)
61 int b;
62 int prec=a*SCREEN_X;
63 int prec1=a*AREA_X;
65 for (b=0;b<SCREEN_X-loffs-roffs;b++)
67 int offs;
68 int prec4=loffs+x+prec2+prec1+b;
70 switch((area_a[prec4])&240)
72 case TYPE_BACKGROUND:
73 offs=-1;
74 break;
76 case TYPE_FOREGROUND:
77 case TYPE_JUMP_FOREGROUND:
78 offs=1;
79 break;
81 default:
82 offs=0;
83 break;
86 if (offs!=1&&(!area[prec4]||area[prec4]==' '))continue;
88 if ((b+offs+loffs)<0||(loffs+b+offs)>=SCREEN_X)continue;
89 screen2[prec+loffs+b+offs]=area[prec4];
90 screen2_a[prec+loffs+b+offs]=area_a[prec4];
93 break;
95 #else
96 for(a=(y<0?-y:0);a<SCREEN_Y&&(y+a)<AREA_Y;a++)
98 int prec=a*SCREEN_X;
99 int prec1=a*AREA_X;
101 memcpy(screen+prec+loffs,area+loffs+x+prec2+prec1,SCREEN_X-loffs-roffs);
102 memcpy(screen_a+prec+loffs,area_a+loffs+x+prec2+prec1,SCREEN_X-loffs-roffs);
104 #endif
108 /* write one scanline of a bitmap to given memory */
109 #ifdef HAVE_INLINE
110 inline void
111 #else
112 void
113 #endif
114 put_line(int xs, int ys,unsigned char *scrn,unsigned char *attr,int x,int y,struct line *l,unsigned char type,unsigned char plastic)
116 int a,b=xs*y;
117 if (y>=ys||y<0)return;
118 for (a=0;a<l->len&&x+a<xs;a++)
120 if (!l->attr[a])continue;
121 if ( plastic&&x+a+b>=0&&
122 ((attr[x+a+b]&240)==TYPE_FOREGROUND||
123 (attr[x+a+b]&240)==TYPE_JUMP_FOREGROUND)
124 ) continue;
125 if (x+a<0)continue;
126 scrn[x+a+b]=l->bmp[a];
127 attr[x+a+b]=(l->attr[a])|type;
131 /* put image to given memory */
132 #ifdef HAVE_INLINE
133 inline void
134 #else
135 void
136 #endif
137 _put_sprite(int xs, int ys, unsigned char *scrn,unsigned char *attr,int x,int y,struct pos *p,unsigned char type,unsigned char plastic)
139 int a;
140 for (a=0;a<p->n;a++)
141 put_line(xs,ys,scrn,attr,x+p->xo,a+y+p->yo,p->lines+a,type,plastic);
144 /* put image into screenbuffer */
145 #ifdef HAVE_INLINE
146 inline void
147 #else
148 void
149 #endif
150 put_sprite(int x, int y, struct pos *p,unsigned char plastic)
152 unsigned char *sc,*at;
153 #ifdef TRI_D
154 sc=(TRI_D_ON&&tri_d)?screen2:screen;
155 at=(TRI_D_ON&&tri_d)?screen2_a:screen_a;
156 #else
157 sc=screen;
158 at=screen_a;
159 #endif
160 _put_sprite(SCREEN_X,SCREEN_Y,sc,at,x,y,p,0,plastic);
164 /* ancillary function for converting color from file notation to value 0-15 */
165 int _conv_color(int c)
167 int a=tolower(c);
168 if (a>='a'&&a<='f')return 10+a-'a';
169 if (a>='0'&&a<='9')return a-'0';
170 /* space or other character is blank attr */
171 return 0;
175 /* load sprite from a file */
176 void load_sprite(char * filename,struct sprite *s)
178 #define CURP (s->n_positions-1)
179 #define CURL (s->positions[CURP].n-1)
180 FILE *f;
181 int x,a;
182 static char buffer[8192];
183 char *p,*q;
184 int step=0; /*0=expecting 'p', 1=expecting 'l', 2=expecting 'a', 3=expecting 'p' or 's' or 'l', 4=expecting end */
186 s->positions=DUMMY;
187 s->n_positions=0;
189 #ifndef WIN32
190 if (!(f=fopen(filename,"rb")))
191 #else
192 if (fopen_s(&f,filename,"rb") != 0)
193 #endif
195 char msg[256];
196 snprintf(msg,256,"Error opening file \"%s\"!\n",filename);
197 ERROR(msg);
198 EXIT(1);
200 while(fgets(buffer,8191,f))
202 x=strlen(buffer);
203 if (buffer[x-1]==10)buffer[x-1]=0;
204 switch(*buffer)
206 case 0:
207 goto skip;
209 case '#': /* comment */
210 break;
212 case 'p':
213 if (step!=0&&step!=3)
215 char msg[256];
216 snprintf(msg,256,"Syntax error in file \"%s\".\n",filename);
217 ERROR(msg);
218 EXIT(1);
220 step=1;
221 s->n_positions++;
222 s->positions=mem_realloc(s->positions,s->n_positions*sizeof(struct pos));
223 if (!s->positions)
225 ERROR("Memory allocation error!\n");
226 EXIT(1);
228 s->positions[CURP].n=0;
229 s->positions[CURP].lines=0;
230 s->n_steps=0;
231 s->steps=0;
232 s->positions[CURP].xo=strtol(buffer+1,&p,0);
233 s->positions[CURP].yo=strtol(p+1,&q,0);
234 break;
236 case 'l':
237 if (step!=1&&step!=3)
239 char msg[256];
240 snprintf(msg,256,"Syntax error in file \"%s\".\n",filename);
241 ERROR(msg);
242 EXIT(1);
244 step=2;
245 if (!(s->positions[CURP].n))s->positions[CURP].lines=DUMMY;
246 s->positions[CURP].n++;
247 s->positions[CURP].lines=mem_realloc(s->positions[CURP].lines,s->positions[CURP].n*sizeof(struct line));
248 if (!s->positions[CURP].lines)
250 ERROR("Memory allocation error!\n");
251 EXIT(1);
253 s->positions[CURP].lines[CURL].len=strlen(buffer+1);
254 if (!s->positions[CURP].lines[CURL].len)break; /* empty line, we have nothing to do */
255 s->positions[CURP].lines[CURL].bmp=mem_alloc(s->positions[CURP].lines[CURL].len);
256 if (!s->positions[CURP].lines[CURL].bmp)
258 ERROR("Memory allocation error!\n");
259 EXIT(1);
261 memcpy(s->positions[CURP].lines[CURL].bmp,buffer+1,s->positions[CURP].lines[CURL].len);
262 break;
264 case 'a':
265 if (step!=2)
267 char msg[256];
268 snprintf(msg,256,"Syntax error in file \"%s\".\n",filename);
269 ERROR(msg);
270 EXIT(1);
272 step=3;
273 /* UGH, co to tady je??????? */
274 if (!s->positions[CURP].lines)
276 ERROR("Memory allocation error!\n");
277 EXIT(1);
279 if (!s->positions[CURP].lines[CURL].len)break; /* empty line, we have nothing to do */
280 s->positions[CURP].lines[CURL].attr=mem_alloc(s->positions[CURP].lines[CURL].len);
281 if (!s->positions[CURP].lines[CURL].attr)
283 ERROR("Memory allocation error!\n");
284 EXIT(1);
286 x=strlen(buffer+1);
287 if (x>s->positions[CURP].lines[CURL].len)x=s->positions[CURP].lines[CURL].len;
288 for (a=0;a<x;a++)
289 s->positions[CURP].lines[CURL].attr[a]=_conv_color(buffer[1+a]);
290 memset(s->positions[CURP].lines[CURL].attr+x,0,s->positions[CURP].lines[CURL].len-x);
291 break;
293 case 's':
294 if (step!=3)
296 char msg[256];
297 snprintf(msg,256,"Syntax error in file \"%s\".\n",filename);
298 ERROR(msg);
299 EXIT(1);
301 step=4;
302 for(q=buffer,p=buffer+1;*q&&*q!=10;*q==','?p=q+1:0)
304 x=strtol(p,&q,0);
305 if (x<0||x>CURP)
307 char txt[256];
309 snprintf(txt,256,"Error loading sprite \"%s\". Undefined position %d.\n",filename,x);
310 ERROR(txt);
311 EXIT(1);
313 if (!(s->n_steps))s->steps=DUMMY;
314 s->n_steps++;
315 s->steps=mem_realloc(s->steps,s->n_steps*sizeof(unsigned short));
316 if (!s->steps)
318 ERROR("Memory allocation error!\n");
319 EXIT(1);
321 s->steps[s->n_steps-1]=x;
323 break;
325 default:
327 char msg[256];
328 snprintf(msg,256,"Syntax error in file \"%s\"!\n",filename);
329 ERROR(msg);
330 EXIT(1);
333 skip: ;
335 if (step!=4)
337 char msg[256];
338 snprintf(msg,256,"Unexpected end of file in \"%s\".\n",filename);
339 ERROR(msg);
340 EXIT(1);
342 fclose(f);
346 static void free_line(struct line* line)
348 if(line->len)
350 mem_free(line->attr);
351 mem_free(line->bmp);
356 static void free_pos(struct pos *pos)
358 int a;
359 for (a=0;a<(pos->n);a++)
360 free_line((pos->lines)+a);
361 mem_free(pos->lines);
365 void free_sprite(struct sprite*sp)
367 int a;
369 for (a=0;a<(sp->n_positions);a++)
370 free_pos((sp->positions)+a);
372 if (sp->n_steps){mem_free(sp->steps);mem_free(sp->positions);}