4 cvar_t ui_showname = {0, "ui_showname", "0"};
6 #define ITEM_CLICKABLE 1
7 #define ITEM_DRAWABLE 2
15 #define UI_MOUSEBUTTONS 3
17 static int ui_alive, ui_active;
18 static float ui_mouse_x, ui_mouse_y;
19 static int ui_mousebutton[UI_MOUSEBUTTONS], ui_mouseclick;
20 static int ui_keyui, ui_keyitem;
21 static ui_item_t *ui_keyrealitem;
23 static ui_t *ui_list[MAX_UI_COUNT];
25 //static qpic_t *ui_mousepointer;
26 static rtexture_t *ui_mousepointertexture;
28 static byte pointerimage[256] =
30 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
31 0x02, 0x06, 0x07, 0x07, 0x07, 0x07, 0x06, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32 0x02, 0x06, 0x05, 0x05, 0x05, 0x04, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
33 0x02, 0x06, 0x05, 0x05, 0x04, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
34 0x02, 0x06, 0x05, 0x04, 0x05, 0x06, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
35 0x02, 0x06, 0x04, 0x01, 0x04, 0x05, 0x06, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
36 0x02, 0x05, 0x01, 0xFF, 0x01, 0x04, 0x05, 0x06, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
37 0x02, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0x04, 0x05, 0x06, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
38 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x04, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
39 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
40 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
41 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
42 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
43 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
44 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
45 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
50 // ui_mousepointer = Draw_CachePic("ui/mousepointer.lmp");
51 ui_mousepointertexture = R_LoadTexture("mousepointer", 16, 16, pointerimage, TEXF_ALPHA | TEXF_PRECACHE);
52 ui_mouse_x = vid.width * 0.5;
53 ui_mouse_y = vid.height * 0.5;
57 void ui_shutdown(void)
59 // ui_mousepointer = NULL;
60 ui_mousepointertexture = NULL;
70 Cvar_RegisterVariable(&ui_showname);
71 R_RegisterModule("UI", ui_start, ui_shutdown, ui_newmap);
74 void ui_mouseupdate(float x, float y)
78 ui_mouse_x = bound(0, x, vid.width);
79 ui_mouse_y = bound(0, y, vid.height);
83 void ui_mouseupdaterelative(float x, float y)
89 ui_mouse_x = bound(0, ui_mouse_x, vid.width);
90 ui_mouse_y = bound(0, ui_mouse_y, vid.height);
97 ui = qmalloc(sizeof(*ui));
99 Sys_Error("ui_create: unable to allocate memory for new ui\n");
100 memset(ui, 0, sizeof(*ui));
104 void ui_free(ui_t *ui)
110 void ui_clear(ui_t *ui)
117 ui_t *ui, char *basename, int number,
118 float x, float y, qpic_t *pic,
119 float left, float top, float width, float height,
120 void(*leftkey)(void *nativedata1, void *nativedata2, float data1, float data2),
121 void(*rightkey)(void *nativedata1, void *nativedata2, float data1, float data2),
122 void(*enterkey)(void *nativedata1, void *nativedata2, float data1, float data2),
123 void(*mouseclick)(void *nativedata1, void *nativedata2, float data1, float data2, float xfrac, float yfrac),
124 void *nativedata1, void *nativedata2, float data1, float data2
130 snprintf(itemname, sizeof(itemname), "%s%04d", basename, number);
131 for (it = ui->items, i = 0;i < ui->item_count;it++, i++)
132 if (it->name == NULL || !strncmp(itemname, it->name, 32))
134 if (i == ui->item_count)
136 if (i == MAX_UI_ITEMS)
138 Con_Printf("ui_item: ran out of UI item slots\n");
143 strncpy(it->name, itemname, 32);
145 if (leftkey || rightkey || enterkey || mouseclick)
146 it->flags |= ITEM_CLICKABLE;
148 it->flags |= ITEM_DRAWABLE;
151 it->click_x = x + left;
152 it->click_y = y + top;
153 it->click_x2 = it->click_x + width;
154 it->click_y2 = it->click_y + height;
155 it->leftkey = leftkey;
156 it->rightkey = rightkey;
157 it->enterkey = enterkey;
158 it->mouseclick = mouseclick;
159 if (it->mouseclick == NULL)
160 it->mouseclick = (void *)it->enterkey;
161 if (it->leftkey == NULL)
162 it->leftkey = it->enterkey;
163 if (it->rightkey == NULL)
164 it->rightkey = it->enterkey;
165 it->nativedata1 = nativedata1;
166 it->nativedata2 = nativedata2;
169 void ui_item_remove(ui_t *ui, char *basename, int number)
174 snprintf(itemname, sizeof(itemname), "%s%04d", basename, number);
175 for (it = ui->items, i = 0;i < ui->item_count;it++, i++)
176 if (it->name && !strncmp(itemname, it->name, 32))
178 if (i < ui->item_count)
182 ui_item_t *ui_hititem(float x, float y)
187 for (j = 0;j < MAX_UI_COUNT;j++)
188 if ((ui = ui_list[j]))
189 for (it = ui->items, i = 0;i < ui->item_count;it++, i++)
190 if (it->name[0] && (it->flags & ITEM_CLICKABLE))
191 if (x >= it->click_x && y >= it->click_y && x < it->click_x2 && y < it->click_y2)
196 int ui_uiactive(ui_t *ui)
199 for (i = 0;i < MAX_UI_COUNT;i++)
200 if (ui_list[i] == ui)
205 void ui_activate(ui_t *ui, int yes)
213 for (i = 0;i < MAX_UI_COUNT;i++)
215 if (ui_list[i] == NULL)
222 Con_Printf("ui_activate: ran out of active ui list items\n");
226 for (i = 0;i < MAX_UI_COUNT;i++)
228 if (ui_list[i] == ui)
237 int ui_isactive(void)
243 for (j = 0;j < MAX_UI_COUNT;j++)
244 if ((ui = ui_list[j]))
251 #define UI_QUEUE_SIZE 256
252 static byte ui_keyqueue[UI_QUEUE_SIZE];
253 static int ui_keyqueuepos = 0;
255 void ui_leftkeyupdate(int pressed)
257 static int key = false;
258 if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE)
259 ui_keyqueue[ui_keyqueuepos++] = UIKEY_LEFT;
263 void ui_rightkeyupdate(int pressed)
265 static int key = false;
266 if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE)
267 ui_keyqueue[ui_keyqueuepos++] = UIKEY_RIGHT;
271 void ui_upkeyupdate(int pressed)
273 static int key = false;
274 if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE)
275 ui_keyqueue[ui_keyqueuepos++] = UIKEY_UP;
279 void ui_downkeyupdate(int pressed)
281 static int key = false;
282 if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE)
283 ui_keyqueue[ui_keyqueuepos++] = UIKEY_DOWN;
287 void ui_mousebuttonupdate(int button, int pressed)
289 if (button < 0 || button >= UI_MOUSEBUTTONS)
291 if (button == 0 && ui_mousebutton[button] && !pressed)
292 ui_mouseclick = true;
293 ui_mousebutton[button] = pressed;
298 ui_item_t *startitem, *it;
301 ui_mouse_x = bound(0, ui_mouse_x, vid.width);
302 ui_mouse_y = bound(0, ui_mouse_y, vid.height);
304 if ((ui_active = ui_isactive()))
306 // validate currently selected item
307 if(ui_list[ui_keyui] == NULL)
309 while (ui_list[ui_keyui] == NULL)
310 ui_keyui = (ui_keyui + 1) % MAX_UI_COUNT;
313 ui_keyitem = bound(0, ui_keyitem, ui_list[ui_keyui]->item_count - 1);
314 startitem = ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem];
315 if ((ui_keyrealitem->flags & ITEM_CLICKABLE) == 0)
319 // FIXME: cycle through UIs as well as items in a UI
320 ui_keyitem = (ui_keyitem - 1) % ui_list[ui_keyui]->item_count - 1;
321 ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem];
323 while (ui_keyrealitem != startitem && (ui_keyrealitem->flags & ITEM_CLICKABLE) == 0);
329 for (i = 0;i < ui_keyqueuepos;i++)
331 startitem = ui_keyrealitem;
332 switch(ui_keyqueue[i])
341 ui_keyui = (ui_keyui - 1) % MAX_UI_COUNT;
342 while(ui_list[ui_keyui] == NULL);
343 ui_keyitem = ui_list[ui_keyui]->item_count - 1;
345 ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem];
347 while (ui_keyrealitem != startitem && (ui_keyrealitem->flags & ITEM_CLICKABLE) == 0);
353 if (ui_keyitem >= ui_list[ui_keyui]->item_count)
356 ui_keyui = (ui_keyui + 1) % MAX_UI_COUNT;
357 while(ui_list[ui_keyui] == NULL);
360 ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem];
362 while (ui_keyrealitem != startitem && (ui_keyrealitem->flags & ITEM_CLICKABLE) == 0);
365 if (ui_keyrealitem->leftkey)
366 ui_keyrealitem->leftkey(ui_keyrealitem->nativedata1, ui_keyrealitem->nativedata2, ui_keyrealitem->data1, ui_keyrealitem->data2);
369 if (ui_keyrealitem->rightkey)
370 ui_keyrealitem->rightkey(ui_keyrealitem->nativedata1, ui_keyrealitem->nativedata2, ui_keyrealitem->data1, ui_keyrealitem->data2);
373 if (ui_keyrealitem->enterkey)
374 ui_keyrealitem->enterkey(ui_keyrealitem->nativedata1, ui_keyrealitem->nativedata2, ui_keyrealitem->data1, ui_keyrealitem->data2);
381 if (ui_mouseclick && (it = ui_hititem(ui_mouse_x, ui_mouse_y)) && it->mouseclick)
382 it->mouseclick(it->nativedata1, it->nativedata2, it->data1, it->data2, ui_mouse_x - it->click_x, ui_mouse_y - it->click_y);
385 ui_mouseclick = false;
393 if (ui_alive && ui_active)
395 for (j = 0;j < MAX_UI_COUNT;j++)
396 if ((ui = ui_list[j]))
398 for (i = 0, it = ui->items;i < ui->item_count;i++, it++)
399 if (it->flags & ITEM_DRAWABLE)
400 Draw_Pic(it->draw_x, it->draw_y, it->draw_pic);
402 if ((it = ui_hititem(ui_mouse_x, ui_mouse_y)))
404 Draw_AdditivePic(it->draw_x, it->draw_y, it->draw_pic);
405 if (ui_showname.value)
406 Draw_String(ui_mouse_x, ui_mouse_y + 16, it->name, 9999);
410 Draw_AdditivePic(it->draw_x, it->draw_y, it->draw_pic);
412 // Draw_Pic(ui_mouse_x, ui_mouse_y, ui_mousepointer);
413 Draw_GenericPic(ui_mousepointertexture, 1, 1, 1, 1, ui_mouse_x, ui_mouse_y, 16, 16);