File Coverage

blib/lib/Games/Console.pm
Criterion Covered Total %
statement 116 182 63.7
branch 30 76 39.4
condition 12 31 38.7
subroutine 19 31 61.2
pod 22 28 78.5
total 199 348 57.1


line stmt bran cond sub pod time code
1              
2             # Games-Console - a 2D quake-style console
3              
4             package Games::Console;
5              
6             # (C) by Tels
7              
8 2     2   146368 use strict;
  2         4  
  2         58  
9 2     2   13 use vars qw/$VERSION/;
  2         3  
  2         3514  
10              
11             $VERSION = '0.04';
12              
13             ##############################################################################
14             # methods
15              
16             sub new
17             {
18             # create a new console
19 1     1 1 884 my $class = shift;
20              
21 1         2 my $self = { };
22 1         3 bless $self, $class;
23            
24 1         2 my $args = $_[0];
25 1 50       5 $args = { @_ } unless ref $args eq 'HASH';
26              
27 1   50     13 $self->{background_color} = $args->{background} || [0.4, 0.6, 1];
28 1   50     8 $self->{background_alpha} = $args->{background_alpha} || 0.5;
29              
30 1   50     6 $self->{text_color} = $args->{text_color} || [ 0.4, 0.6, 0.8 ];
31 1   50     6 $self->{text_alpha} = $args->{text_alpha} || 0.8;
32            
33 1   50     5 $self->{max_msg} = $args->{backbuffer_size} || 100;
34            
35 1         2 $self->{font} = $args->{font};
36              
37             # maximum height/width in percent
38 1   50     6 $self->{width} = abs($self->{width} || 100);
39 1   50     8 $self->{height} = abs($args->{height} || 50);
40 1 50       3 $self->{width} = 100 if $self->{width} > 100;
41 1 50       6 $self->{height} = 100 if $self->{height} > 100;
42            
43 1         2 $self->{screen_width} = 640;
44 1         2 $self->{screen_height} = 480;
45            
46 1         3 $self->{direction} = 1;
47             # in percent per second (50 means it takes 2 seconds to open console)
48 1         1 $self->{speed} = 50;
49            
50 1         13 $self->{start_percent} = 0; # started moving at this percentage
51 1         1 $self->{start_time} = 0; # and this time
52 1         2 $self->{cur_percent} = 0; # cur percent visible
53              
54 1         3 $self->{messages} = [];
55            
56 1         2 $self->{spacing_y} = 0;
57 1         2 $self->{border_x} = 5;
58 1         2 $self->{border_y} = 5;
59 1   50     6 $self->{prompt} = $args->{prompt} || '> ';
60 1   50     5 $self->{cursor} = $args->{cursor} || '_';
61            
62 1         1 $self->{offset} = 0;
63            
64 1         2 $self->{last_cursor} = 0;
65 1   50     4 $self->{cursor_time} = abs($args->{cursor_time} || 300);
66            
67 1         2 $self->{current_input} = ''; # what user entered until ENTER key is pressed
68 1         6 $self->{last_input} = [ ];
69 1         3 $self->{last_input_pos} = 0;
70 1         2 $self->{max_last_input} = 64;
71              
72 1         1 $self->{cur_height} = 0; # invisble
73 1         2 $self;
74             }
75              
76             sub close
77             {
78 0     0 1 0 my $self = shift;
79              
80 0 0       0 $self->{direction} = -1 if $self->{visible};
81             }
82              
83             sub open
84             {
85 0     0 1 0 my $self = shift;
86              
87 0         0 $self->{direction} = 1; $self->{visible} = 1;
  0         0  
88 0         0 $self->{start_time} = shift;
89 0         0 $self->{start_percent} = $self->{cur_percent};
90             }
91              
92             sub toggle
93             {
94 0     0 1 0 my $self = shift;
95              
96 0 0       0 if (!$self->{visible})
97             {
98 0         0 $self->{direction} = 1; $self->{visible} = 1;
  0         0  
99             }
100             else
101             {
102 0         0 $self->{direction} = - $self->{direction};
103 0 0       0 $self->{direction} = -1 if $self->{direction} == 0;
104             }
105 0         0 $self->{start_time} = shift;
106 0         0 $self->{start_percent} = $self->{cur_percent};
107             }
108              
109             sub visible
110             {
111             # make immidiately visible/invisible
112 0     0 1 0 my $self = shift;
113              
114 0 0       0 if (@_ > 0)
115             {
116 0 0       0 my $v = $_[0] ? 1 : 0;
117 0 0 0     0 if ($self->{visible} && !$v)
    0 0        
118             {
119 0         0 $self->{direction} = 0;
120 0         0 $self->{cur_percent} = 0;
121             }
122             elsif (!$self->{visible} && $v)
123             {
124 0         0 $self->{direction} = 1;
125 0         0 $self->{start_percent} = 0;
126 0         0 $self->{start_time} = shift;
127             }
128 0         0 $self->{visible} = $v;
129             }
130 0         0 $self->{visible};
131             }
132              
133             sub render
134             {
135 0     0 1 0 my ($self,$current_time) = @_;
136              
137 0 0       0 return unless $self->{visible};
138              
139 0 0       0 if ($self->{direction} != 0)
140             {
141 0         0 $self->{cur_percent} = $self->{start_percent} +
142             $self->{direction} * ($current_time - $self->{start_time}) *
143             $self->{speed} / 100;
144             }
145              
146 0 0       0 if ($self->{cur_percent} < 0)
147             {
148             # fully closed
149 0         0 $self->{cur_percent} = 0;
150 0         0 $self->{start_percent} = 0;
151 0         0 $self->{direction} = 0;
152 0         0 $self->{visible} = 0;
153 0         0 return;
154             }
155              
156 0 0       0 if ($self->{cur_percent} > 100)
157             {
158             # fully open
159 0         0 $self->{cur_percent} = 100;
160 0         0 $self->{direction} = 0;
161             }
162            
163             # calculate height/width
164 0         0 my $w = $self->{width} * $self->{screen_width} / 100;
165 0         0 my $h = ($self->{cur_percent} / 100)
166             * $self->{height} * $self->{screen_height} / 100;
167              
168 0         0 $self->_render( 0, $self->{screen_height}, $w, $h, $current_time );
169              
170             }
171              
172             sub _render
173             {
174             # prepare the output, render the background and the text
175 0     0   0 my ($self,$x,$y,$w,$h,$time) = @_;
176              
177             }
178              
179             sub message
180             {
181 1     1 1 1 my ($self,$msg) = @_;
182              
183 1         2 my $m = $self->{messages}; # shortcut
184              
185 1         3 push @$m, [ $msg ];
186              
187 1         3 shift @$m while (scalar @$m > $self->{max_msg});
188            
189 1         3 $self;
190             }
191              
192             sub screen_width
193             {
194 0     0 0 0 my $self = shift;
195              
196 0 0       0 if (@_ > 0)
197             {
198 0         0 $self->{screen_width} = $_[0];
199 0         0 $self->{font}->screen_width($_[0]);
200             }
201 0         0 $self->{screen_width};
202             }
203              
204             sub screen_height
205             {
206 0     0 0 0 my $self = shift;
207              
208 0 0       0 if (@_ > 0)
209             {
210 0         0 $self->{screen_height} = $_[0];
211 0         0 $self->{font}->screen_height($_[0]);
212             }
213 0         0 $self->{screen_height};
214             }
215              
216             sub background_color
217             {
218 0     0 1 0 my $self = shift;
219              
220 0 0       0 $self->{background_color} = shift if @_ > 0;
221 0         0 $self->{background_color};
222             }
223              
224             sub text_color
225             {
226 1     1 1 342 my $self = shift;
227              
228 1 50       5 $self->{text_color} = shift if @_ > 0;
229 1         18 $self->{text_color};
230             }
231              
232             sub background_alpha
233             {
234 1     1 1 2 my $self = shift;
235              
236 1 50       4 $self->{background_alpha} = shift if @_ > 0;
237 1         4 $self->{background_alpha};
238             }
239              
240             sub text_alpha
241             {
242 0     0 1 0 my $self = shift;
243              
244 0 0       0 $self->{text_alpha} = shift if @_ > 0;
245 0         0 $self->{text_alpha};
246             }
247              
248             sub width
249             {
250 5     5 0 7 my $self = shift;
251              
252 5 100       12 if (@_ > 0)
253             {
254 4         6 $self->{width} = abs(shift);
255 4 100       9 $self->{width} = 100 if $self->{width} > 100;
256             }
257 5         15 $self->{width};
258             }
259              
260             sub height
261             {
262 4     4 0 7 my $self = shift;
263              
264 4 100       11 if (@_ > 0)
265             {
266 3         6 $self->{height} = abs(shift);
267 3 100       10 $self->{height} = 100 if $self->{height} > 100;
268             }
269 4         16 $self->{height};
270             }
271              
272             sub speed
273             {
274 4     4 1 5 my $self = shift;
275              
276 4 100       11 if (@_ > 0)
277             {
278 3         4 $self->{speed} = abs(shift);
279 3 100       7 $self->{speed} = 100 if $self->{speed} > 100;
280             }
281 4         513 $self->{speed};
282             }
283              
284             sub backbuffer_size
285             {
286 0     0 1 0 my $self = shift;
287              
288 0 0       0 $self->{max_msg} = abs(shift) if @_ > 0;
289 0         0 $self->{max_msg};
290             }
291              
292             sub cursor
293             {
294 2     2 1 3 my $self = shift;
295              
296 2 100       7 $self->{cursor} = $_[0] if @_ > 0;
297 2         7 $self->{cursor};
298             }
299              
300             sub prompt
301             {
302 2     2 1 3 my $self = shift;
303              
304 2 100       8 $self->{prompt} = $_[0] if @_ > 0;
305 2         8 $self->{prompt};
306             }
307              
308             sub backspace
309             {
310 4     4 1 6 my $self = shift;
311              
312 4 100       10 if ($self->{current_input} ne '')
313             {
314 3         6 substr($self->{current_input},-1,1) = '';
315             }
316 4         14 $self->{current_input};
317             }
318              
319             sub autocomplete
320             {
321 0     0 0 0 my $self = shift;
322            
323 0         0 $self->{last_input_pos} = 0;
324             }
325              
326             sub input
327             {
328             # get/set the current_input buffer
329 5     5 1 8 my $self = shift;
330              
331 5 50       16 if (@_ > 0)
332             {
333 5         8 my $m = $self->{last_input};
334 5         10 unshift @$m, $self->{current_input};
335 5         13 pop @$m while (scalar @$m > $self->{max_last_input});
336 5         6 $self->{current_input} = $_[0];
337 5         5 $self->{last_input_pos} = 0;
338             }
339 5         17 $self->{current_input};
340             }
341              
342             sub last_input
343             {
344             # set the current_input buffer to the last entered input
345 1     1 0 2 my $self = shift;
346 1   50     7 my $dir = shift || 0;
347              
348 1         2 my $m = $self->{last_input};
349              
350 1         2 my $pos = $self->{last_input_pos};
351 1 50 33     8 if ($pos < 0 || $pos >= scalar @$m)
352             {
353 0         0 $self->{current_input} = '';
354             }
355             else
356             {
357 1 50       5 $self->{current_input} = $m->[$pos] if scalar @$m > 0;
358             }
359 1 50       3 if ($dir >= 0)
360             {
361 1 50       4 $pos++ if $pos < scalar @$m;
362             }
363             else
364             {
365 0 0       0 $pos-- if $pos >= 0;
366             }
367 1         2 $self->{last_input_pos} = $pos;
368 1         4 $self->{current_input};
369             }
370              
371             sub add_input
372             {
373             # add more text to the current_input buffer
374 1     1 1 2 my $self = shift;
375              
376 1         4 $self->{current_input} .= $_[0];
377             }
378              
379             sub scroll
380             {
381 1     1 1 1 my ($self,$ofs) = @_;
382              
383 1         2 $self->{offset} += $ofs;
384 1         15 print $self->{offset},"\n";
385 1 50       5 $self->{offset} = 0 if $self->{offset} < 0;
386 1         3 $self->{offset} = scalar @{$self->{messages}}
  1         5  
387 1 50       2 if $self->{offset} >= scalar @{$self->{messages}};
388 1         13 print $self->{offset},"\n";
389 1         5 $self->{offset};
390             }
391              
392             sub offset
393             {
394 2     2 1 2 my ($self) = @_;
395              
396 2         7 $self->{offset};
397             }
398              
399             sub messages
400             {
401             # return number of messages in backbuffer
402 2     2 1 2 my $self = shift;
403              
404 2         2 scalar @{$self->{messages}};
  2         7  
405             }
406              
407             sub clear
408             {
409             # clear backbuffer
410 1     1 1 2 my $self = shift;
411              
412 1         2 $self->{messages} = [];
413 1         2 $self;
414             }
415              
416             1;
417              
418             __END__