1 /* Tower Toppler - Nebulus
2  * Copyright (C) 2000-2012  Andreas R�ver
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  */
18 
19 #include "txtsys.h"
20 #include "screen.h"
21 #include "keyb.h"
22 #include "menu.h"
23 #include <stdlib.h>
24 #include <string.h>
25 
textsystem(char * title,menuopt_callback_proc pr)26 textsystem::textsystem(char *title, menuopt_callback_proc pr)
27 {
28   if (title) {
29     this->title = new char[strlen(title)+1];
30     strcpy(this->title, title);
31   } else this->title = NULL;
32 
33   numlines = 0;
34   max_length = 0;
35   lines = NULL;
36   mproc = pr;
37   xoffs = yoffs = disp_xoffs = disp_yoffs = 0;
38   ystart = (title) ? FONTHEI + 15 : 0;
39   shownlines = ((SCREENHEI - ystart) / FONTHEI) + 1;
40 }
41 
~textsystem()42 textsystem::~textsystem()
43 {
44   int i;
45 
46   if (lines && numlines) {
47     for (i = 0; i < numlines; i++)
48       if (lines[i])
49         delete [] lines[i];
50     delete [] lines;
51   }
52   if (title) delete [] title;
53 }
54 
addline(char * line)55 void textsystem::addline(char *line)
56 {
57   int olen;
58 
59   char **tmp = new char *[numlines+1];
60   if (!tmp) return;
61 
62   if (lines) {
63     memcpy(tmp, lines, sizeof(char *) * numlines);
64     delete [] lines;
65   }
66 
67   if (line && (strlen(line)>0)) {
68     tmp[numlines] = new char[strlen(line)+1];
69     strcpy(tmp[numlines], line);
70   } else tmp[numlines] = NULL;
71 
72   lines = tmp;
73   numlines++;
74 
75   if (line) {
76     olen = scr_formattextlength(0,0,line);
77     if (olen < 0) olen = 0;
78   }
79   else olen = 0;
80 
81   if (max_length < olen) max_length = olen;
82 }
83 
run()84 void textsystem::run()
85 {
86   bool ende = false;
87   SDLKey key = SDLK_UNKNOWN;
88 
89   do {
90     (void)key_readkey();
91 
92     draw();
93 
94     key = key_sdlkey();
95 
96     switch (key_sdlkey2conv(key, false)) {
97     case up_key:
98       if (yoffs >= FONTHEI) yoffs -= FONTHEI;
99       else yoffs = 0;
100       break;
101     case down_key:
102       if (yoffs + (shownlines*FONTHEI) < (numlines*FONTHEI)) yoffs += FONTHEI;
103       else yoffs = (numlines - shownlines+1)*FONTHEI;
104       break;
105     case break_key:
106       ende = true;
107       break;
108     case left_key:
109       if (xoffs >= FONTWID) xoffs -= FONTWID;
110       else xoffs = 0;
111       break;
112     case right_key:
113       if (xoffs <= max_length-SCREENWID-FONTWID) xoffs += FONTWID;
114       else xoffs = max_length-SCREENWID;
115       break;
116     default:
117       switch (key) {
118       case SDLK_PAGEUP:
119         if (yoffs >= shownlines*FONTHEI) yoffs -= shownlines*FONTHEI;
120         else yoffs = 0;
121         break;
122       case SDLK_SPACE:
123       case SDLK_PAGEDOWN:
124         if ((yoffs/FONTHEI) + (shownlines*2) <= numlines)
125           yoffs += shownlines*FONTHEI;
126         else yoffs = (numlines - shownlines+1)*FONTHEI;
127         break;
128       case SDLK_HOME:
129         yoffs = 0;
130         break;
131       case SDLK_END:
132         yoffs = (numlines - shownlines+1)*FONTHEI;
133         break;
134       case SDLK_RETURN:
135       case SDLK_ESCAPE:
136         ende = true;
137         break;
138       default: break;
139       }
140     }
141 
142   } while (!ende);
143 }
144 
145 void
draw()146 textsystem::draw()
147 {
148   char pointup[2], pointdown[2], pointleft[2], pointright[2];
149 
150   pointup[0] = fontptrup;
151   pointup[1] = 0;
152   pointdown[0] = fontptrdown;
153   pointdown[1] = 0;
154   pointleft[0] = fontptrleft;
155   pointleft[1] = 0;
156   pointright[0] = fontptrright;
157   pointright[1] = 0;
158 
159   if (mproc)
160     (*mproc) (NULL);
161 
162   if (title)
163     scr_writetext_center(5, title);
164 
165   if (disp_yoffs < yoffs) {
166     disp_yoffs += ((yoffs - disp_yoffs+3) / 4)+1;
167     if (disp_yoffs > yoffs) disp_yoffs = yoffs;
168   } else if (disp_yoffs > yoffs) {
169     disp_yoffs -= ((disp_yoffs - yoffs+3) / 4)+1;
170     if (disp_yoffs < yoffs) disp_yoffs = yoffs;
171   }
172 
173   if (disp_xoffs < xoffs) {
174     disp_xoffs += ((xoffs - disp_xoffs) / 4)+1;
175     if (disp_xoffs > xoffs) disp_xoffs = xoffs;
176   } else if (disp_xoffs > xoffs) {
177     disp_xoffs -= ((disp_xoffs - xoffs) / 4)+1;
178     if (disp_xoffs < xoffs) disp_xoffs = xoffs;
179   }
180 
181   scr_setclipping(0, ystart, SCREENWID, SCREENHEI);
182   for (int k = 0; k <= shownlines; k++)
183     if (k+(disp_yoffs / FONTHEI) < numlines) {
184       if (lines[k+(disp_yoffs / FONTHEI)])
185         scr_writeformattext(-disp_xoffs,
186                             k*FONTHEI + ystart - (disp_yoffs % FONTHEI),
187                             lines[k+(disp_yoffs / FONTHEI)]);
188     }
189 
190   scr_setclipping();
191 
192   if (disp_yoffs > 0)
193     scr_writetext(SCREENWID-FONTWID, 34, pointup);
194   if ((disp_yoffs / FONTHEI) + shownlines < numlines)
195     scr_writetext(SCREENWID-FONTWID, SCREENHEI-FONTHEI, pointdown);
196 
197   if (disp_xoffs > 0)
198     scr_writetext(FONTWID, 5, pointleft);
199   if (disp_xoffs < max_length - SCREENWID)
200     scr_writetext(SCREENWID-FONTWID, 5, pointright);
201 
202   scr_swap();
203   dcl_wait();
204 }
205