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