added cl_screen.c/h (eventually most 2D stuff should be moved here)
[divverent/darkplaces.git] / cl_screen.c
1
2 #include "quakedef.h"
3
4 static byte menuplyr_pixels[4096];
5
6 void CL_Screen_Init(void)
7 {
8         qpic_t *dat;
9
10         // HACK HACK HACK
11         // load the image data for the player image in the config menu
12         dat = (qpic_t *)COM_LoadFile ("gfx/menuplyr.lmp", false);
13         if (!dat)
14                 Sys_Error("unable to load gfx/menuplyr.lmp");
15         SwapPic (dat);
16
17         if (dat->width*dat->height <= 4096)
18                 memcpy (menuplyr_pixels, dat->data, dat->width * dat->height);
19         else
20                 Con_Printf("gfx/menuplyr.lmp larger than 4k buffer");
21         free(dat);
22 }
23
24 void DrawQ_Clear(void)
25 {
26         r_refdef.drawqueuesize = 0;
27 }
28
29 void DrawQ_Pic(float x, float y, char *picname, float width, float height, float red, float green, float blue, float alpha, int flags)
30 {
31         int size;
32         drawqueue_t *dq;
33         if (alpha < (1.0f / 255.0f))
34                 return;
35         size = sizeof(*dq) + ((strlen(picname) + 1 + 3) & ~3);
36         if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE)
37                 return;
38         red = bound(0, red, 1);
39         green = bound(0, green, 1);
40         blue = bound(0, blue, 1);
41         alpha = bound(0, alpha, 1);
42         dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
43         dq->size = size;
44         dq->command = DRAWQUEUE_PIC;
45         dq->flags = flags;
46         dq->color = ((unsigned int) (red * 255.0f) << 24) | ((unsigned int) (green * 255.0f) << 16) | ((unsigned int) (blue * 255.0f) << 8) | ((unsigned int) (alpha * 255.0f));
47         dq->x = x;
48         dq->y = y;
49         // if these are not zero, they override the pic's size
50         dq->scalex = width;
51         dq->scaley = height;
52         strcpy((char *)(dq + 1), picname);
53         r_refdef.drawqueuesize += dq->size;
54 }
55
56 void DrawQ_String(float x, float y, char *string, int maxlen, float scalex, float scaley, float red, float green, float blue, float alpha, int flags)
57 {
58         int size, len;
59         drawqueue_t *dq;
60         char *out;
61         if (alpha < (1.0f / 255.0f))
62                 return;
63         if (maxlen < 1)
64                 len = strlen(string);
65         else
66                 for (len = 0;len < maxlen && string[len];len++);
67         for (;len > 0 && string[0] == ' ';string++, x += scalex, len--);
68         for (;len > 0 && string[len - 1] == ' ';len--);
69         if (len < 1)
70                 return;
71         if (x >= vid.conwidth || y >= vid.conheight || x < (-scalex * maxlen) || y < (-scaley))
72                 return;
73         size = sizeof(*dq) + ((len + 1 + 3) & ~3);
74         if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE)
75                 return;
76         red = bound(0, red, 1);
77         green = bound(0, green, 1);
78         blue = bound(0, blue, 1);
79         alpha = bound(0, alpha, 1);
80         dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
81         dq->size = size;
82         dq->command = DRAWQUEUE_STRING;
83         dq->flags = flags;
84         dq->color = ((unsigned int) (red * 255.0f) << 24) | ((unsigned int) (green * 255.0f) << 16) | ((unsigned int) (blue * 255.0f) << 8) | ((unsigned int) (alpha * 255.0f));
85         dq->x = x;
86         dq->y = y;
87         dq->scalex = scalex;
88         dq->scaley = scaley;
89         out = (char *)(dq + 1);
90         memcpy(out, string, len);
91         out[len] = 0;
92         r_refdef.drawqueuesize += dq->size;
93 }
94
95 void DrawQ_Fill (float x, float y, float w, float h, float red, float green, float blue, float alpha, int flags)
96 {
97         int size;
98         drawqueue_t *dq;
99         if (alpha < (1.0f / 255.0f))
100                 return;
101         size = sizeof(*dq) + 4;
102         if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE)
103                 return;
104         red = bound(0, red, 1);
105         green = bound(0, green, 1);
106         blue = bound(0, blue, 1);
107         alpha = bound(0, alpha, 1);
108         dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
109         dq->size = size;
110         dq->command = DRAWQUEUE_PIC;
111         dq->flags = flags;
112         dq->color = ((unsigned int) (red * 255.0f) << 24) | ((unsigned int) (green * 255.0f) << 16) | ((unsigned int) (blue * 255.0f) << 8) | ((unsigned int) (alpha * 255.0f));
113         dq->x = x;
114         dq->y = y;
115         dq->scalex = w;
116         dq->scaley = h;
117         // empty pic name
118         *((char *)(dq + 1)) = 0;
119         r_refdef.drawqueuesize += dq->size;
120 }
121
122 //only used for the player color selection menu
123 void DrawQ_PicTranslate (int x, int y, char *picname, byte *translation)
124 {
125         int i, c;
126         unsigned int trans[4096];
127         cachepic_t *pic;
128
129         pic = Draw_CachePic(picname);
130         if (pic == NULL)
131                 return;
132
133         c = pic->width * pic->height;
134         if (c > 4096)
135         {
136                 Con_Printf("DrawQ_PicTranslate: image larger than 4k buffer\n");
137                 return;
138         }
139
140         for (i = 0;i < c;i++)
141                 trans[i] = d_8to24table[translation[menuplyr_pixels[i]]];
142
143         // FIXME: this is renderer stuff?
144         R_UpdateTexture (pic->tex, (byte *)trans);
145
146         DrawQ_Pic(x, y, picname, 0, 0, 1, 1, 1, 1, 0);
147 }
148
149 void V_CalcRefdef (void);
150 void CL_UpdateScreen(void)
151 {
152         DrawQ_Clear();
153
154         SHOWLMP_drawall();
155
156         V_UpdateBlends();
157         V_CalcRefdef ();
158
159         SCR_UpdateScreen();
160 }
161
162 void CL_Screen_NewMap(void)
163 {
164         SHOWLMP_clear();
165 }
166
167 //=============================================================================
168
169 // LordHavoc: SHOWLMP stuff
170 #define SHOWLMP_MAXLABELS 256
171 typedef struct showlmp_s
172 {
173         qboolean        isactive;
174         float           x;
175         float           y;
176         char            label[32];
177         char            pic[128];
178 }
179 showlmp_t;
180
181 showlmp_t showlmp[SHOWLMP_MAXLABELS];
182
183 void SHOWLMP_decodehide(void)
184 {
185         int i;
186         byte *lmplabel;
187         lmplabel = MSG_ReadString();
188         for (i = 0;i < SHOWLMP_MAXLABELS;i++)
189                 if (showlmp[i].isactive && strcmp(showlmp[i].label, lmplabel) == 0)
190                 {
191                         showlmp[i].isactive = false;
192                         return;
193                 }
194 }
195
196 void SHOWLMP_decodeshow(void)
197 {
198         int i, k;
199         byte lmplabel[256], picname[256];
200         float x, y;
201         strcpy(lmplabel,MSG_ReadString());
202         strcpy(picname, MSG_ReadString());
203         if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk
204         {
205                 x = MSG_ReadByte();
206                 y = MSG_ReadByte();
207         }
208         else
209         {
210                 x = MSG_ReadShort();
211                 y = MSG_ReadShort();
212         }
213         k = -1;
214         for (i = 0;i < SHOWLMP_MAXLABELS;i++)
215                 if (showlmp[i].isactive)
216                 {
217                         if (strcmp(showlmp[i].label, lmplabel) == 0)
218                         {
219                                 k = i;
220                                 break; // drop out to replace it
221                         }
222                 }
223                 else if (k < 0) // find first empty one to replace
224                         k = i;
225         if (k < 0)
226                 return; // none found to replace
227         // change existing one
228         showlmp[k].isactive = true;
229         strcpy(showlmp[k].label, lmplabel);
230         strcpy(showlmp[k].pic, picname);
231         showlmp[k].x = x;
232         showlmp[k].y = y;
233 }
234
235 void SHOWLMP_drawall(void)
236 {
237         int i;
238         if (cl.worldmodel)
239                 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
240                         if (showlmp[i].isactive)
241                                 DrawQ_Pic(showlmp[i].x, showlmp[i].y, showlmp[i].pic, 0, 0, 1, 1, 1, 1, 0);
242 }
243
244 void SHOWLMP_clear(void)
245 {
246         int i;
247         for (i = 0;i < SHOWLMP_MAXLABELS;i++)
248                 showlmp[i].isactive = false;
249 }