This repository was archived by the owner on Feb 27, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 511
/
Copy pathDIALOG.CPP
790 lines (692 loc) · 34.2 KB
/
DIALOG.CPP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
/*
** Command & Conquer(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* $Header: F:\projects\c&c\vcs\code\dialog.cpv 2.17 16 Oct 1995 16:51:50 JOE_BOSTIC $ */
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : DIALOG.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : September 10, 1993 *
* *
* Last Update : May 18, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Clip_Text_Print -- Prints text with clipping and <TAB> support. *
* Dialog_Box -- draws a dialog background box *
* Display_Place_Building -- Displays the "place building" dialog box. *
* Display_Select_Target -- Displays the "choose target" prompt. *
* Display_Status -- Display the player scenario status box. *
* Draw_Box -- Displays a highlighted box. *
* Fancy_Text_Print -- Prints text with a drop shadow. *
* Redraw_Needed -- Determine if sidebar needs to be redrawn. *
* Render_Bar_Graph -- Renders a specified bargraph. *
* Simple_Text_Print -- Prints text with a drop shadow. *
* Window_Box -- Draws a fancy box over the specified window. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* Dialog_Box -- draws a dialog background box *
* *
* INPUT: *
* x,y,w,h the usual *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 01/26/1995 BR : Created. *
*=============================================================================================*/
void Dialog_Box(int x, int y, int w, int h)
{
Draw_Box( x, y, w, h, BOXSTYLE_GREEN_BORDER, true);
}
/***********************************************************************************************
* Draw_Box -- Displays a highlighted box. *
* *
* This will draw a highlighted box to the logicpage. It can *
* optionally fill the box with a color as well. This is a low level *
* function and thus, it doesn't do any graphic mode color adjustments. *
* *
* INPUT: x,y -- Upper left corner of the box to be drawn (pixels). *
* *
* w,h -- Width and height of box (in pixels). *
* *
* up -- Is the box rendered in the "up" stated? *
* *
* filled-- Is the box to be filled. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/28/1991 JLB : Created. *
* 05/30/1992 JLB : Embedded color codes. *
* 07/31/1992 JLB : Depressed option added. *
*=============================================================================================*/
extern void CC_Texture_Fill (void const *shapefile, int shapenum, int xpos, int ypos, int width, int height);
void Draw_Box(int x, int y, int w, int h, BoxStyleEnum up, bool filled)
{
static BoxStyleType const ButtonColors[BOXSTYLE_COUNT] = {
//Filler, Shadow, Hilite, Corner colors
{ LTGREY, WHITE, DKGREY, LTGREY}, // 0 Button is down.
{ LTGREY, DKGREY, WHITE, LTGREY}, // 1 Button is up w/border.
{ LTBLUE, BLUE, LTCYAN, LTBLUE}, // 2 Raised blue.
{ DKGREY, WHITE, BLACK, DKGREY}, // 3 Button is disabled down.
{ DKGREY, BLACK, WHITE, LTGREY}, // 4 Button is disabled up.
{ LTGREY, DKGREY, WHITE, LTGREY}, // 5 Button is up w/arrows.
//{ CC_GREEN_BKGD, CC_LIGHT_GREEN, CC_GREEN_SHADOW, CC_GREEN_CORNERS }, // 6 Button is down.
//{ CC_GREEN_BKGD, CC_GREEN_SHADOW, CC_LIGHT_GREEN, CC_GREEN_CORNERS }, // 7 Button is up w/border.
{ CC_GREEN_BKGD, 14, 12, 13 }, // 6 Button is down.
{ CC_GREEN_BKGD, 12, 14, 13 }, // 7 Button is up w/border.
{ DKGREY, WHITE, BLACK, DKGREY}, // 8 Button is disabled down.
{ DKGREY, BLACK, LTGREY, DKGREY}, // 9 Button is disabled up.
//{ BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 10 List box.
//{ BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 11 Menu box.
{ BLACK, 14, 14, BLACK}, // 10 List box.
{ BLACK, 14, 14, BLACK}, // 11 Menu box.
};
w--;
h--;
BoxStyleType const &style = ButtonColors[up];
if (filled) {
if (style.Filler == CC_GREEN_BKGD){
CC_Texture_Fill (MixFileClass::Retrieve("BTEXTURE.SHP"), InMainLoop, x, y, w, h);
}else{
LogicPage->Fill_Rect( x, y, x+w, y+h, style.Filler);
}
}
switch ( up ) {
case ( BOXSTYLE_GREEN_BOX ):
LogicPage->Draw_Rect(x, y, x+w, y+h, style.Highlight);
break;
case ( BOXSTYLE_GREEN_BORDER ):
LogicPage->Draw_Rect(x+1, y+1, x+w-1, y+h-1, style.Highlight);
break;
default:
LogicPage->Draw_Line(x, y+h, x+w, y+h, style.Shadow);
LogicPage->Draw_Line(x+w, y, x+w, y+h, style.Shadow);
LogicPage->Draw_Line(x, y, x+w, y, style.Highlight);
LogicPage->Draw_Line(x, y, x, y+h, style.Highlight);
LogicPage->Put_Pixel(x, y+h, style.Corner);
LogicPage->Put_Pixel(x+w, y, style.Corner);
break;
}
}
/***********************************************************************************************
* Format_Window_String -- Separates a String into Lines. *
* This function will take a long string and break it up into lines *
* which are not longer then the window width. Any character < ' ' is *
* considered a new line marker and will be replaced by a NULL. *
* *
* INPUT: char *String - string to be formated. *
* int maxlinelen - Max length of any line in pixels. *
* *
* OUTPUT: int - number of lines string is. *
* *
* WARNINGS: The string passed in will be modified - NULLs will be put *
* into each position that will be a new line. *
* *
* HISTORY: *
* 03/27/1992 SB : Created. *
* 05/18/1995 JLB : Greatly revised for new font system. *
*=============================================================================================*/
int Format_Window_String(char * string, int maxlinelen, int & width, int & height)
{
int linelen;
int lines = 0;
width = 0;
height = 0;
// In no string was passed in, then there are no lines.
if (!string) return(0);
// While there are more letters left divide the line up.
while (*string) {
linelen = 0;
height += FontHeight + FontYSpacing;
lines++;
// While the current line is less then the max length...
while (linelen < maxlinelen && *string != '\r' && *string != '\0') {
linelen += Char_Pixel_Width(*string++);
}
// if the line is to long...
if (linelen >= maxlinelen) {
/*
** Back up to an appropriate location to break.
*/
while (*string != ' ' && *string != '\r' && *string != '\0') {
linelen -= Char_Pixel_Width(*string--);
}
}
/*
** Record the largest width of the worst case string.
*/
if (linelen > width) {
width = linelen;
}
/*
** Force a break at the end of the line.
*/
if (*string) {
*string++ = '\r';
}
}
return(lines);
}
/***********************************************************************************************
* Window_Box -- Draws a fancy box over the specified window. *
* *
* This routine will draw a fancy (shaded) box over the specified *
* window. This is the effect used to give the polished look to *
* screen rectangles without having to use art. *
* *
* INPUT: window -- Specified window to fill and border. *
* *
* style -- The style to render the window. *
* *
* OUTPUT: none *
* *
* WARNINGS: The rendering is done to the LogicPage. *
* *
* HISTORY: *
* 03/03/1992 JLB : Created. *
* 07/31/1992 JLB : Cool raised border effect. *
* 06/08/1994 JLB : Takes appropriate enumeration parameters. *
*=============================================================================================*/
void Window_Box(WindowNumberType window, BoxStyleEnum style)
{
int x,y,w,h; // Window dimensions.
int border; // Width of border.
static int _border[BOXSTYLE_COUNT][2] = {
{0,0}, // 0 Simple beveled edge.
{2,4}, // 1 Wide raised border.
{1,1}, // 2 Thick beveled edge.
{2,1}, // 3 Thin raised border.
{0,0}, // 4 Simple beveled edge.
{20,0}, // 5 Simple beveled edge.
{0,0}, // 6 Simple beveled edge.
{2,4}, // 7 Wide raised border.
{0,0}, // 8 Simple beveled edge.
{20,0}, // 9 Simple beveled edge.
{0,1} // 10 Simple 1 pixel box.
};
x = WindowList[window][WINDOWX]<<3;
y = WindowList[window][WINDOWY];
w = WindowList[window][WINDOWWIDTH]<<3;
h = WindowList[window][WINDOWHEIGHT];
/*
** If it is to be rendered to the seenpage, then
** hide the mouse.
*/
if (LogicPage == (&SeenBuff)) Conditional_Hide_Mouse(x,y,x+w,y+h);
Draw_Box(x, y, w, h, style, true);
border = _border[style][1];
/*
** Draw the second border if requested.
*/
if (border) {
Draw_Box(x+border, y+border, w-(border<<1), h-(border<<1), style, false);
}
/*
** Restore the mouse if it has been hidden and return.
*/
if (LogicPage == &SeenBuff) Conditional_Show_Mouse();
}
/***********************************************************************************************
* Simple_Text_Print -- Prints text with a drop shadow. *
* *
* This routine functions like Text_Print, but will render a drop *
* shadow (in black). *
* *
* INPUT: text -- Pointer to text to render. *
* *
* x,y -- Pixel coordinate for to print text. *
* *
* fore -- Foreground color. *
* *
* back -- Background color. *
* *
* flag -- Text print control flags. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/24/1991 JLB : Created. *
* 10/26/94 JLB : Handles font X spacing in a more friendly manner. *
*=============================================================================================*/
void Simple_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag)
{
static int yspace=0; // Y spacing adjustment for font.
static int xspace=0; // Spacing adjustment for font.
void const * font=0; // Font to use.
////////////////#if (0)
static unsigned char _textfontpal[16][16] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 26, 25, 24 },
{ 0,135, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 136,135,119, 2 },
{ 0,159, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 143,159,41 ,167 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0,157, 0, 0, 0, 0, 0, 0, 0, 0, 0,180, 180,157,158, 5 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0,179, 0, 0, 0, 0, 0, 0, 0, 0, 0,180, 180,179,178,176 },
{ 0,123, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 122,123,125,127 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 },
{ 0, 1, 4,166, 41, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 },
{ 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
static unsigned char _textpalmedium[16] = {
0, 25, 119,41, 0, 158,0, 178, 125,0, 202,0, 0, 0, 0, 0
};
static unsigned char _textpalbright[16] = {
0, 24, 2, 4, 0, 5, 0, 176, 127,0, 201,0, 0, 0, 0, 0
};
///////////////////////#endif //(0)
int point; // Requested font size.
int shadow; // Requested shadow value.
unsigned char fontpalette[16]; // Working font palette array.
memset(&fontpalette[0], back, 16);
if ((flag & 0xf) == TPF_VCR) {
fontpalette[3] = 12;
fontpalette[9] = 15;
fontpalette[10] = 200;
fontpalette[11] = 201;
fontpalette[12] = 202;
fontpalette[13] = 203;
fontpalette[14] = 204;
fontpalette[15] = 205;
}
char *tempstr = NULL;
if (text){
/*
** remove any 0xff characters from the string
*/
tempstr = new char [strlen (text)+1];
char *tempptr = tempstr;
for ( int i=0 ; i<strlen(text)+1 ; i++ ) {
if (text[i] != -1){
*tempptr = text[i];
tempptr++;
}
}
}
/*
** A gradient font always requires special fixups for the palette.
*/
if ((flag & 0xf) == TPF_6PT_GRAD ||
(flag & 0xf) == TPF_GREEN12_GRAD ||
(flag & 0xf) == TPF_GREEN12) {
/*
** If a gradient palette was requested, then fill in the font palette array
** according to the color index specified.
*/
if (flag & TPF_USE_GRAD_PAL) {
memcpy(&fontpalette[0], _textfontpal[ (fore & 0x0f) ], 16);
} else {
/*
** Special adjustment for fonts that have gradient artwork. When there is
** no special gradient effect desired, then set the font color based on the
** forground color specified.
*/
memset(&fontpalette[4], fore, 12);
}
if (flag & TPF_MEDIUM_COLOR) {
fore = _textpalmedium[fore & 0x0F];
memset(&fontpalette[4], fore, 12);
}else{
if (flag & TPF_BRIGHT_COLOR) {
fore = _textpalbright[fore & 0x0F];
memset(&fontpalette[4], fore, 12);
}else{
fore = fontpalette[1];
}
}
}
/*
** Change the current font if it differs from the font desired.
*/
point = (flag & (TextPrintType)0x000F);
xspace = 1;
yspace = 0;
switch (point) {
case TPF_GREEN12:
font = Green12FontPtr;
break;
case TPF_GREEN12_GRAD:
font = Green12GradFontPtr;
break;
case TPF_MAP:
font = MapFontPtr;
xspace -= 1;
break;
case TPF_VCR:
font = VCRFontPtr;
break;
case TPF_6PT_GRAD:
font = GradFont6Ptr;
xspace -= 1;
//yspace -= 1;
break;
case TPF_3POINT:
xspace += 1;
font = Font3Ptr;
flag = flag & ~(TPF_DROPSHADOW|TPF_FULLSHADOW|TPF_NOSHADOW);
break;
case TPF_6POINT:
font = Font6Ptr;
xspace -= 1;
//yspace -= 1;
break;
case TPF_8POINT:
font = Font8Ptr;
xspace -= 2;
yspace -= 4;
break;
case TPF_LED:
xspace -= 4;
font = FontLEDPtr;
break;
default:
font = FontPtr;
break;
}
/*
** Change the current font palette according to the dropshadow flags.
*/
shadow = (flag & (TPF_NOSHADOW|TPF_DROPSHADOW|TPF_FULLSHADOW|TPF_LIGHTSHADOW));
switch (shadow) {
/*
** The text is rendered plain.
*/
case TPF_NOSHADOW:
fontpalette[2] = back;
fontpalette[3] = back;
xspace -= 1;
yspace -= 2;
break;
/*
** The text is rendered with a simple
** drop shadow.
*/
case TPF_DROPSHADOW:
fontpalette[2] = BLACK;
fontpalette[3] = back;
xspace -= 1;
break;
/*
** Special engraved text look for the options
** dialog system.
*/
case TPF_LIGHTSHADOW:
fontpalette[2] = ((14 * 16) + 7)+1;
fontpalette[3] = back;
xspace -= 1;
break;
/*
** Each letter is surrounded by black. This is used
** when the text will be over a non-plain background.
*/
case TPF_FULLSHADOW:
fontpalette[2] = BLACK;
fontpalette[3] = BLACK;
xspace -= 1;
break;
default:
break;
}
fontpalette[0] = back;
fontpalette[1] = fore;
/*
** Set the font and spacing according to the values they should be.
*/
FontXSpacing = xspace;
FontYSpacing = yspace;
Set_Font(font);
Set_Font_Palette(fontpalette);
/*
** Display the (centered) message if there is one.
*/
if (text && *text) {
switch (flag & (TPF_CENTER|TPF_RIGHT)) {
case TPF_CENTER:
x -= String_Pixel_Width(tempstr)>>1;
break;
case TPF_RIGHT:
x -= String_Pixel_Width(tempstr);
break;
default:
break;
}
if ((unsigned)x < SeenBuff.Get_Width() && (unsigned)y < SeenBuff.Get_Height()) {
LogicPage->Print(tempstr, x, y, fore, back);
}
}
if (tempstr){
delete [] tempstr;
}
}
/***********************************************************************************************
* Fancy_Text_Print -- Prints text with a drop shadow. *
* *
* This routine functions like Text_Print, but will render a drop *
* shadow (in black). *
* *
* INPUT: text -- Text number to print. *
* *
* x,y -- Pixel coordinate for to print text. *
* *
* fore -- Foreground color. *
* *
* back -- Background color. *
* *
* flag -- Text print control flags. *
* *
* OUTPUT: none *
* *
* WARNINGS: This routine is much slower than normal text print and *
* if rendered to the SEENPAGE, the intermediate rendering *
* steps could be visible. *
* *
* HISTORY: *
* 11/29/1994 JLB : Created *
*=============================================================================================*/
void Fancy_Text_Print(int text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...)
{
char buffer[512]; // Working staging buffer.
va_list arg; // Argument list var.
/*
** If the text number is valid, then process it.
*/
if (text != TXT_NONE) {
va_start(arg, flag);
/*
** The text string must be locked since the vsprintf function doesn't know
** how to handle EMS pointers.
*/
char const * tptr = Text_String(text);
vsprintf(buffer, tptr, arg);
va_end(arg);
Simple_Text_Print(buffer, x, y, fore, back, flag);
} else {
/*
** Just the flags are to be changed, since the text number is TXT_NONE.
*/
Simple_Text_Print((char const *)0, x, y, fore, back, flag);
}
}
/***********************************************************************************************
* Fancy_Text_Print -- Prints text with a drop shadow. *
* *
* This routine functions like Text_Print, but will render a drop *
* shadow (in black). *
* *
* INPUT: text -- Pointer to text to render. *
* *
* x,y -- Pixel coordinate for to print text. *
* *
* fore -- Foreground color. *
* *
* back -- Background color. *
* *
* flag -- Text print control flags. *
* *
* OUTPUT: none *
* *
* WARNINGS: This routine is much slower than normal text print and *
* if rendered to the SEENPAGE, the intermediate rendering *
* steps could be visible. *
* *
* HISTORY: *
* 12/24/1991 JLB : Created. *
* 10/26/94 JLB : Handles font X spacing in a more friendly manner. *
* 11/29/1994 JLB : Separated actual draw action. *
*=============================================================================================*/
void Fancy_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...)
{
char buffer[512]; // Working staging buffer.
va_list arg; // Argument list var.
/*
** If there is a valid text string pointer then build the final string into the
** working buffer before sending it to the simple string printing routine.
*/
if (text) {
/*
** Since vsprintf doesn't know about EMS pointers, be sure to surround this
** call with locking code.
*/
va_start(arg, flag);
vsprintf(buffer, text, arg);
va_end(arg);
Simple_Text_Print(buffer, x, y, fore, back, flag);
} else {
/*
** Just the flags are desired to be changed, so call the simple print routine with
** a NULL text pointer.
*/
Simple_Text_Print((char const *)0, x, y, fore, back, flag);
}
}
/***********************************************************************************************
* Clip_Text_Print -- Prints text with clipping and <TAB> support. *
* *
* Use this routine to print text that that should be clipped at an arbitrary right margin *
* as well as possibly recognizing <TAB> characters. Typical users of this routine would *
* be list boxes. *
* *
* INPUT: text -- Reference to the text to print. *
* *
* x,y -- Pixel coordinate of the upper left corner of the text position. *
* *
* fore -- The foreground color to use. *
* *
* back -- The background color to use. *
* *
* flag -- The text print flags to use. *
* *
* width -- The maximum pixel width to draw the text. Extra characters beyond this *
* point will not be printed. *
* *
* tabs -- Optional pointer to a series of pixel tabstop positions. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/21/1995 JLB : Created. *
*=============================================================================================*/
void Conquer_Clip_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, unsigned width, int const * tabs)
{
char buffer[512];
if (text) {
strcpy(buffer, text);
/*
** Set the font and spacing characteristics according to the flag
** value passed in.
*/
Simple_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, flag);
char * source = &buffer[0];
unsigned offset = 0;
int processing = true;
while (processing && offset < width) {
char * ptr = strchr(source, '\t');
/*
** Zap the tab character. It will be processed later.
*/
if (ptr) {
*ptr = '\0';
}
if (*source) {
/*
** Scan forward until the end of the string is reached or the
** maximum width, whichever comes first.
*/
int w = 0;
char * bptr = source;
do {
w += Char_Pixel_Width(*bptr++);
} while(*bptr && offset+w < width);
/*
** If the maximum width has been exceeded, then remove the last
** character and signal that further processing is not necessary.
*/
if (offset+w >= width) {
bptr--;
w -= Char_Pixel_Width(*bptr);
*bptr = '\0';
processing = 0;
}
/*
** Print this text block and advance the offset accordingly.
*/
Simple_Text_Print(source, x+offset, y, fore, back, flag);
offset += w;
}
/*
** If a <TAB> was the terminator for this text block, then advance
** to the next tabstop.
*/
if (ptr) {
if (tabs) {
while (offset > *tabs) {
tabs++;
}
offset = *tabs;
} else {
offset = ((offset+1 / 50) + 1) * 50;
}
source = ptr+1;
} else {
break;
}
}
}
}