1
/********************************************************************/
3
/* L I QQ U U I DD W W A RR 555 */
4
/* L I Q Q U U I D D W W A A R R 5 */
5
/* L I Q Q U U I D D W W W AAA RR 55 */
6
/* L I Q Q U U I D D WW WW A A R R 5 */
7
/* LLL I Q Q U I DD W W A A R R 55 */
17
/* U U TIRET FF O O O O T */
21
/********************************************************************/
23
/*****************************************************************************/
24
/* Liquid War is a unique multiplayer wargame */
25
/* Copyright (C) 1998-2002 Christian Mauduit */
27
/* This program is free software; you can redistribute it and/or modify */
28
/* it under the terms of the GNU General Public License as published by */
29
/* the Free Software Foundation; either version 2 of the License, or */
30
/* (at your option) any later version. */
32
/* This program is distributed in the hope that it will be useful, */
33
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
34
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
35
/* GNU General Public License for more details. */
37
/* You should have received a copy of the GNU General Public License */
38
/* along with this program; if not, write to the Free Software */
39
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
41
/* Liquid War homepage : http://www.ufoot.org/liquidwar */
42
/* Contact author : ufoot@ufoot.org */
43
/*****************************************************************************/
45
/********************************************************************/
47
/* contenu : reprogrammation de qq fonctions d'allegro */
48
/* date de modif : 3 mai 98 */
49
/********************************************************************/
51
/*==================================================================*/
53
/*==================================================================*/
60
/*==================================================================*/
61
/* variables globales */
62
/*==================================================================*/
64
/*==================================================================*/
65
/* variables statiques */
66
/*==================================================================*/
67
extern void _draw_scrollable_frame (DIALOG *d,
68
int listsize, int offset, int height,
69
int fg_color, int bg);
70
extern int isspace(int c);
72
/*==================================================================*/
74
/*==================================================================*/
76
/*------------------------------------------------------------------*/
78
/*------------------------------------------------------------------*/
80
static void dotted_rect(int x1, int y1, int x2, int y2, int fg, int bg)
82
int x = ((x1+y1) & 1) ? 1 : 0;
85
for (c=x1; c<=x2; c++) {
86
putpixel(screen, c, y1, (((c+y1) & 1) == x) ? fg : bg);
87
putpixel(screen, c, y2, (((c+y2) & 1) == x) ? fg : bg);
90
for (c=y1+1; c<y2; c++) {
91
putpixel(screen, x1, c, (((c+x1) & 1) == x) ? fg : bg);
92
putpixel(screen, x2, c, (((c+x2) & 1) == x) ? fg : bg);
97
* Helper function to draw a textbox object.
99
static void my_draw_textbox
100
(char *thetext, int *listsize, int draw, int offset,
101
int wword, int tabsize, int x, int y, int w, int h,
102
int disabled, int fore, int deselect, int disable)
112
char *printed = text;
113
char *scanned = text;
114
char *oldscan = text;
121
usetc(s+usetc(s, '.'), 0);
122
usetc(text+usetc(text, ' '), 0);
123
usetc(space+usetc(space, ' '), 0);
125
/* find the correct text */
126
if (thetext != NULL) {
131
/* do some drawing setup */
133
/* initial start blanking at the top */
134
rectfill(screen, x+2, y+2, x+w-1, y1-1, deselect);
137
/* choose the text color */
143
/* loop over the entire string */
147
/* find the next break */
148
while (ugetc(scanned)) {
149
/* check for a forced break */
150
if (ugetc(scanned) == '\n') {
151
scanned += uwidth(scanned);
153
/* we are done parsing the line end */
157
/* the next character length */
158
usetc(s+usetc(s, ugetc(scanned)), 0);
159
len = text_length(font, s);
161
/* modify length if its a tab */
162
if (ugetc(s) == '\t')
163
len = tabsize * text_length(font, space);
165
/* check for the end of a line by excess width of next char */
166
if (width+len >= ww) {
167
/* we have reached end of line do we go back to find start */
169
/* remember where we were */
172
/* go backwards looking for start of word */
173
while (!uisspace(ugetc(scanned))) {
174
/* don't wrap too far */
175
if (scanned == printed) {
176
/* the whole line is filled, so stop here */
180
/* look further backwards to wrap */
181
tmp = ptmp = printed;
182
while (tmp < scanned) {
188
/* put the space at the end of the line */
190
scanned += uwidth(scanned);
192
/* check for endline at the convenient place */
193
if (ugetc(scanned) == '\n')
194
scanned += uwidth(scanned);
196
/* we are done parsing the line end */
199
/* the character can be added */
200
scanned += uwidth(scanned);
204
/* check if we are to print it */
205
if ((draw) && (line >= offset) && (y1+text_height(font) < (y+h-1))) {
208
/* the initial blank bit */
209
rectfill(screen, x+2, y1, x1-1, y1+text_height(font), deselect);
211
/* print up to the marked character */
212
while (printed != scanned) {
213
/* do special stuff for each charater */
214
switch (ugetc(printed)) {
218
/* don't print endlines in the text */
221
/* possibly expand the tabs */
223
for (i=0; i<tabsize; i++) {
224
usetc(s+usetc(s, ' '), 0);
225
textout(screen, font, s, x1, y1, -1);
226
x1 += text_length(font, s);
230
/* print a normal charater */
232
if (printed != ignore) {
233
usetc(s+usetc(s, ugetc(printed)), 0);
234
textout(screen, font, s, x1, y1, -1);
235
x1 += text_length(font, s);
239
/* goto the next character */
240
printed += uwidth(printed);
242
/* the last blank bit */
244
rectfill(screen, x1, y1, x+w-1, y1+text_height(font)-1, deselect);
246
/* print the line end */
247
y1 += text_height(font);
251
/* we have done a line */
254
/* check if we are at the end of the string */
255
if (!ugetc(printed)) {
256
/* the under blank bit */
258
rectfill(screen, x+1, y1, x+w-1, y+h-1, deselect);
260
/* tell how many lines we found */
270
* A text box object. The dp field points to a char * which is the text
271
* to be displayed in the text box. If the text is long, there will be
272
* a vertical scrollbar on the right hand side of the object which can
273
* be used to scroll through the text. The default is to print the text
274
* with word wrapping, but if the D_SELECTED flag is set, the text will
275
* be printed with character wrapping. The d1 field is used internally
276
* to store the number of lines of text, and d2 is used to store how far
277
* it has scrolled through the text.
279
int my_textbox_proc(int msg, DIALOG *d, int c)
282
int fg_color = (d->flags & D_DISABLED) ? gui_mg_color : d->fg;
284
/* calculate the actual height */
285
height = (d->h-4) / text_height(font);
289
/* tell the object to sort of draw, but only calculate the listsize */
290
my_draw_textbox(d->dp, &d->d1,
291
0, /* DONT DRAW anything */
292
d->d2, !(d->flags & D_SELECTED), 8,
293
d->x, d->y, d->w, d->h,
294
(d->flags & D_DISABLED),
297
if (d->d1 > height) {
305
/* now do the actual drawing */
306
my_draw_textbox(d->dp, &d->d1, 1, d->d2,
307
!(d->flags & D_SELECTED), 8,
308
d->x, d->y, d->w-bar-1, d->h,
309
(d->flags & D_DISABLED),
310
fg_color, d->bg, gui_mg_color);
312
/* draw the frame around */
313
_draw_scrollable_frame(d, d->d1, d->d2, height, fg_color, d->bg);
317
return d_textbox_proc (msg,d,c);
320
int my_button_proc(int msg, DIALOG *d, int c)
327
if (d->flags & D_SELECTED) {
330
state2 = (d->flags & D_DISABLED) ? gui_mg_color : d->fg;
334
state1 = (d->flags & D_DISABLED) ? gui_mg_color : d->fg;
338
rectfill(screen, d->x+1+g, d->y+1+g, d->x+d->w-2+g, d->y+d->h-2+g, state2);
339
rect(screen, d->x+g, d->y+g, d->x+d->w-1+g, d->y+d->h-1+g, state1);
341
gui_textout(screen, d->dp, d->x+d->w/2+g, d->y+d->h/2-text_height(font)/2+g, /*state1*/ -1, TRUE);
343
if (d->flags & D_SELECTED) {
344
vline(screen, d->x, d->y, d->y+d->h-1, d->bg);
345
hline(screen, d->x, d->y, d->x+d->w-1, d->bg);
348
vline(screen, d->x+d->w, d->y+1, d->y+d->h-1, d->fg);
349
hline(screen, d->x+1, d->y+d->h, d->x+d->w, d->fg);
351
if ((d->flags & D_GOTFOCUS) &&
352
(!(d->flags & D_SELECTED) || !(d->flags & D_EXIT)))
353
dotted_rect(d->x+1+g, d->y+1+g, d->x+d->w-2+g, d->y+d->h-2+g, state1, state2);
356
else return d_button_proc (msg,d,c);
360
* Simple dialog procedure: draws the text string which is pointed to by dp.
362
int my_text_proc(int msg, DIALOG *d, int c)
366
gui_textout(screen, d->dp, d->x, d->y, -1, FALSE);
373
* Simple dialog procedure: draws the text string which is pointed to by dp,
374
* centering it around the object's x coordinate.
376
int my_ctext_proc(int msg, DIALOG *d, int c)
380
gui_textout(screen, d->dp, d->x, d->y, -1, TRUE);
388
* A slider control object. This object returns a value in d2, in the
389
* range from 0 to d1. It will display as a vertical slider if h is
390
* greater than or equal to w; otherwise, it will display as a horizontal
391
* slider. dp can contain an optional bitmap to use for the slider handle;
392
* dp2 can contain an optional callback function, which is called each
393
* time d2 changes. The callback function should have the following
396
* int function(void *dp3, int d2);
398
* The d_slider_proc object will return the value of the callback function.
400
int my_slider_proc(int msg, DIALOG *d, int c)
402
BITMAP *slhan = NULL;
404
int sfg; /* slider foreground color */
405
int vert = TRUE; /* flag: is slider vertical? */
406
int hh = 7; /* handle height (width for horizontal sliders) */
407
int hmar; /* handle margin */
408
int slp; /* slider position */
409
int mp; /* mouse position */
411
int slx, sly, slh, slw;
415
int pgupkey, pgdnkey;
418
fixed slratio, slmax, slpos;
419
int (*proc)(void *cbpointer, int d2value);
421
/* check for slider direction */
425
/* set up the metrics for the control */
427
slhan = (BITMAP *)d->dp;
435
irange = (vert) ? d->h : d->w;
436
slmax = itofix(irange-hh);
437
slratio = slmax / (d->d1);
438
slpos = slratio * d->d2;
444
sfg = (d->flags & D_DISABLED) ? gui_mg_color : d->fg;
447
rectfill(screen, d->x, d->y, d->x+d->w/2-2, d->y+d->h, d->bg);
448
rectfill(screen, d->x+d->w/2-1, d->y, d->x+d->w/2+1, d->y+d->h, sfg);
449
rectfill(screen, d->x+d->w/2+2, d->y, d->x+d->w, d->y+d->h, d->bg);
452
rectfill(screen, d->x, d->y, d->x+d->w, d->y+d->h/2-2, d->bg);
453
rectfill(screen, d->x, d->y+d->h/2-1, d->x+d->w, d->y+d->h/2+1, sfg);
454
rectfill(screen, d->x, d->y+d->h/2+2, d->x+d->w, d->y+d->h, d->bg);
457
rect(screen, d->x, d->y, d->x+d->w, d->y+d->h, sfg);
458
/* ligne du desssus ajoutee par moi pour le cadre */
460
/* okay, background and slot are drawn, now draw the handle */
463
slx = d->x+(d->w/2)-(slhan->w/2);
464
sly = d->y+d->h-(hh+slp);
468
sly = d->y+(d->h/2)-(slhan->h/2);
470
draw_sprite(screen, slhan, slx, sly);
473
/* draw default handle */
476
sly = d->y+d->h-(hh+slp);
487
rectfill(screen, slx+2, sly, slx+(slw-2), sly+slh, sfg);
488
vline(screen, slx+1, sly+1, sly+slh-1, sfg);
489
vline(screen, slx+slw-1, sly+1, sly+slh-1, sfg);
490
vline(screen, slx, sly+2, sly+slh-2, sfg);
491
vline(screen, slx+slw, sly+2, sly+slh-2, sfg);
492
vline(screen, slx+1, sly+2, sly+slh-2, d->bg);
493
hline(screen, slx+2, sly+1, slx+slw-2, d->bg);
494
putpixel(screen, slx+2, sly+2, d->bg);
497
if (d->flags & D_GOTFOCUS)
498
dotted_rect(d->x+1, d->y+1, d->x+d->w-1, d->y+d->h-1, sfg, d->bg);
499
/* coord du dotted rect modifiee par moi , cad +1 et -2 */
507
if (!(d->flags & D_GOTFOCUS))
513
/* handle movement keys to move slider */
535
else if (c == downkey)
537
else if (c == pgdnkey)
539
else if (c == pgupkey)
541
else if (c == homekey)
543
else if (c == endkey)
544
delta = d->d1 - d->d2;
553
slpos = slratio*d->d2;
555
if ((slp != oldpos) || (d->d2 <= 0) || (d->d2 >= d->d1))
564
retval = D_USED_CHAR;
566
/* call callback function here */
569
retval |= (*proc)(d->dp3, d->d2);
573
SEND_MESSAGE(d, MSG_DRAW, 0);
579
/* track the mouse until it is released */
587
mp = (d->y+d->h-hmar)-msy;
589
mp = msx-(d->x+hmar);
595
slmax = fdiv(slpos, slratio);
596
newpos = fixtoi(slmax);
597
if (newpos != oldpos) {
600
/* call callback function here */
601
if (d->dp2 != NULL) {
603
retval |= (*proc)(d->dp3, d->d2);
606
if (d->d2 != oldpos) {
608
SEND_MESSAGE(d, MSG_DRAW, 0);
613
/* let other objects continue to animate */
614
broadcast_dialog_message(MSG_IDLE, 0);
623
* An editable text object (the dp field points to the string). When it
624
* has the input focus (obtained by clicking on it with the mouse), text
625
* can be typed into this object. The d1 field specifies the maximum
626
* number of characters that it will accept, and d2 is the text cursor
627
* position within the string.
629
int my_edit_proc(int msg, DIALOG *d, int c)
631
int f, l, p, w, x, fg;
642
/* calculate maximal number of displayable characters */
647
x = text_length(font, buf);
651
for (p=d->d2; p>=0; p--) {
654
x += text_length(font, buf);
675
fg = (d->flags & D_DISABLED) ? gui_mg_color : d->fg;
686
buf[0] = s[p] ? s[p] : ' ';
687
w = text_length(font, buf);
690
f = ((p == d->d2) && (d->flags & D_GOTFOCUS));
691
text_mode(f ? d->fg : d->bg); /* modif de chez tonton */
692
textout(screen, font, buf, d->x+x, d->y, f ? d->bg : d->fg);
694
textout(screen, font, buf, d->x+x, d->y, -1); /* idem chez tata*/
698
rectfill(screen, d->x+x, d->y, d->x+d->w-1, d->y+text_height(font)-1, d->bg);
713
x += text_length(font, buf);
717
d->d2 = MID(0, p, l);
719
SEND_MESSAGE(d, MSG_DRAW, 0);
729
if ((c >> 8) == KEY_LEFT) {
730
if (d->d2 > 0) d->d2--;
732
else if ((c >> 8) == KEY_RIGHT) {
733
if (d->d2 < l) d->d2++;
735
else if ((c >> 8) == KEY_HOME) {
738
else if ((c >> 8) == KEY_END) {
741
else if ((c >> 8) == KEY_DEL) {
743
for (p=d->d2; s[p]; p++)
746
else if ((c >> 8) == KEY_BACKSPACE) {
749
for (p=d->d2; s[p]; p++)
753
else if ((c >> 8) == KEY_ENTER) {
754
if (d->flags & D_EXIT) {
756
SEND_MESSAGE(d, MSG_DRAW, 0);
765
if ((c >= 32) && (c <= 255)) {
779
/* if we changed something, better redraw... */
781
SEND_MESSAGE(d, MSG_DRAW, 0);
789
/*------------------------------------------------------------------*/
790
BITMAP *my_create_bitmap (int w, int h)
794
bmp=create_bitmap (w,h);
796
my_exit (EXIT_CODE_MEM_TROUBLE);