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, by
8 * Jonathan Clark, or by Sam Hocevar.
9 */
10
11 #if defined HAVE_CONFIG_H
12 # include "config.h"
13 #endif
14
15 #include "common.h"
16
17 #include "director.h"
18 #include "game.h"
19 #include "lisp.h"
20 #include "fonts.h"
21
22 director scene_director;
23
scroll_text(char * Text)24 void director::scroll_text(char *Text)
25 { text=Text;
26 text_y=the_game->first_view->cy2-the_game->first_view->cy1+1;
27 }
28
director()29 director::director()
30 {
31 tleft=ttop=tright=tbottom=pan_xv=pan_yv=0;
32 text_step=-2;
33 frame_speed=100;
34 scroll_speed=60;
35 pan_speed=60;
36 scene_abort=0;
37 }
38
39 extern unsigned char *white_light;
40
41
42
text_draw(int y,int x1,int y1,int x2,int y2,char const * buf,JCFont * font,uint8_t * cmap,char color)43 int text_draw(int y, int x1, int y1, int x2, int y2, char const *buf, JCFont *font, uint8_t *cmap, char color)
44 {
45 int cx1, cy1, cx2, cy2, word_size, word_len;
46 screen->GetClip(cx1, cy1, cx2, cy2);
47 screen->InClip(x1,y1,x2+1,y2+1);
48 int h=font->height()+2,w=font->width(),x=x1,dist;
49 y+=y1;
50 char const *word_start;
51
52 while (buf && *buf)
53 {
54 do
55 {
56 if (*buf=='\\' && buf[1]=='n')
57 {
58 x=x1;
59 y+=h*2;
60 buf+=2;
61 }
62
63 // skip space
64 if (*buf==' ' || *buf=='\r' || *buf=='\n' || *buf=='\t')
65 {
66 x+=w;
67 while (*buf==' ' || *buf=='\r' || *buf=='\n' || *buf=='\t') // skip space until next word
68 buf++;
69 }
70
71 word_start=buf;
72 for (word_len=0,word_start=buf,word_size=0; *buf && *buf!=' ' && *buf!='\r' && *buf!='\n' &&
73 *buf!='\t' && (*buf!='\\' || buf[1]!='n'); buf++,word_size+=w,word_len++);
74
75 if (word_size<x2-x1) // make sure the word can fit on the screen
76 {
77 if (word_size+x>x2) // does word not fit on line?
78 {
79 y+=h; // go to next line
80 x=x1;
81 }
82 }
83
84
85 if (y+h<y1) // word on screen yet?
86 x+=word_size;
87
88 } while (*buf && y+h<y1); // if not on screen yet, fetch next word
89
90 dist=31;
91 if (y-y1<dist)
92 {
93 if (y-y1<1) dist=0;
94 else dist=y-y1;
95 }
96
97 if (y2-y<dist)
98 {
99 if (y2-y<1) dist=0;
100 else dist=y2-y;
101 }
102
103 int c=cmap[dist];
104 if (y>y2) { buf=NULL; }
105 else
106 {
107 while (word_len--)
108 {
109 font->put_char(screen,x+1,y+1,*word_start,0);
110 font->put_char(screen,x,y,*word_start,c);
111 word_start++;
112 x+=w;
113 }
114 }
115
116 }
117 screen->SetClip(cx1,cy1,cx2,cy2);
118 return (y<=y1);
119 }
120
wait(void * arg)121 void director::wait(void *arg)
122 {
123 if (scene_abort) return ;
124 pan_time=frame_time=text_time=NULL;
125 int done=0;
126 LSymbol *pan_symbol = LSymbol::FindOrCreate("pan"),
127 *text_symbol = LSymbol::FindOrCreate("text");
128
129 JCFont *font=wm->font();
130
131 do
132 {
133 the_game->draw_map(the_game->first_view);
134 time_marker cur_time;
135
136 if (pan_steps)
137 {
138 if (pan_time)
139 {
140 if ((int)(cur_time.diff_time(pan_time)*1000)>pan_speed)
141 {
142 the_game->pan(pan_xv,pan_yv);
143 pan_steps--;
144 delete pan_time;
145 if (pan_steps)
146 pan_time=new time_marker;
147 else pan_time=NULL;
148 }
149 } else pan_time=new time_marker;
150 } else if (arg==pan_symbol) done=1;
151
152 if (text)
153 {
154 if (text_draw(text_y,
155 the_game->first_view->cx1+tleft,
156 the_game->first_view->cy1+ttop,
157 the_game->first_view->cx2-tright,
158 the_game->first_view->cy2-tbottom,text,font,
159 white_light+32*256,
160 wm->bright_color()
161
162 ))
163 text=NULL;
164 if (text_time)
165 {
166 if ((int)(cur_time.diff_time(text_time)*1000)>scroll_speed)
167 {
168 text_y+=text_step;
169 delete text_time;
170 if (text)
171 text_time=new time_marker;
172 else
173 text_time=NULL;
174 }
175 } else text_time=new time_marker;
176 } else if (arg==text_symbol) done=1;
177
178 wm->flush_screen();
179 while (wm->event_waiting())
180 {
181 event ev;
182 wm->get_event(ev);
183 if (ev.type==EV_KEY)
184 {
185 switch (ev.key)
186 {
187 case JK_UP :
188 case JK_LEFT :
189 {
190 if (scroll_speed>=20)
191 scroll_speed-=20;
192 else text_step--;
193 }
194 break;
195 case JK_RIGHT :
196 case JK_DOWN :
197 {
198 if (text_step<-2)
199 text_step++;
200 else if (scroll_speed<200) scroll_speed+=20;
201 break;
202 case JK_ESC : set_abort(1); done=1; break;
203 case JK_ENTER : done=1; break;
204 }
205 }
206 }
207 }
208 } while (!done);
209 if (pan_time) delete pan_time;
210 if (frame_time) delete frame_time;
211 if (text_time) delete text_time;
212 }
213
214