source: abuse/trunk/src/director.cpp @ 682

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

core: rename vec2i to ivec2 and update matrix.h from Lol Engine.

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