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] =
48 static rtexturepool_t *uitexturepool;
50 static void ui_start(void)
54 uitexturepool = R_AllocTexturePool();
55 // ui_mousepointer = Draw_CachePic("ui/mousepointer.lmp");
56 for (i = 0;i < 256;i++)
58 if (pointerimage[i] == '.')
67 buffer[i][0] = (pointerimage[i] - '0') * 16;
68 buffer[i][1] = (pointerimage[i] - '0') * 16;
69 buffer[i][2] = (pointerimage[i] - '0') * 16;
73 ui_mousepointertexture = R_LoadTexture(uitexturepool, "mousepointer", 16, 16, &buffer[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE);
74 ui_mouse_x = vid.conwidth * 0.5;
75 ui_mouse_y = vid.conheight * 0.5;
79 static void ui_shutdown(void)
81 // ui_mousepointer = NULL;
82 ui_mousepointertexture = NULL;
84 R_FreeTexturePool(&uitexturepool);
87 static void ui_newmap(void)
91 static mempool_t *uimempool;
95 uimempool = Mem_AllocPool("UI");
97 Cvar_RegisterVariable(&ui_showname);
98 R_RegisterModule("UI", ui_start, ui_shutdown, ui_newmap);
101 void ui_mouseupdate(float x, float y)
105 ui_mouse_x = bound(0, x, vid.conwidth);
106 ui_mouse_y = bound(0, y, vid.conheight);
110 void ui_mouseupdaterelative(float x, float y)
116 ui_mouse_x = bound(0, ui_mouse_x, vid.conwidth);
117 ui_mouse_y = bound(0, ui_mouse_y, vid.conheight);
121 ui_t *ui_create(void)
124 ui = Mem_Alloc(uimempool, sizeof(*ui));
126 Sys_Error("ui_create: unable to allocate memory for new ui\n");
127 memset(ui, 0, sizeof(*ui));
131 void ui_free(ui_t *ui)
137 void ui_clear(ui_t *ui)
144 ui_t *ui, char *basename, int number,
145 float x, float y, qpic_t *pic, char *string,
146 float left, float top, float width, float height,
147 void(*leftkey)(void *nativedata1, void *nativedata2, float data1, float data2),
148 void(*rightkey)(void *nativedata1, void *nativedata2, float data1, float data2),
149 void(*enterkey)(void *nativedata1, void *nativedata2, float data1, float data2),
150 void(*mouseclick)(void *nativedata1, void *nativedata2, float data1, float data2, float xfrac, float yfrac),
151 void *nativedata1, void *nativedata2, float data1, float data2
157 snprintf(itemname, sizeof(itemname), "%s%04d", basename, number);
158 for (it = ui->items, i = 0;i < ui->item_count;it++, i++)
159 if (it->name == NULL || !strncmp(itemname, it->name, 32))
161 if (i == ui->item_count)
163 if (i == MAX_UI_ITEMS)
165 Con_Printf("ui_item: ran out of UI item slots\n");
170 memset(it, 0, sizeof(ui_item_t));
171 strncpy(it->name, itemname, 32);
175 it->flags |= ITEM_DRAWABLE;
177 it->draw_string = string;
181 if (leftkey || rightkey || enterkey || mouseclick)
183 it->flags |= ITEM_CLICKABLE;
184 it->click_x = x + left;
185 it->click_y = y + top;
186 it->click_x2 = it->click_x + width;
187 it->click_y2 = it->click_y + height;
188 it->leftkey = leftkey;
189 it->rightkey = rightkey;
190 it->enterkey = enterkey;
191 it->mouseclick = mouseclick;
192 if (it->mouseclick == NULL)
193 it->mouseclick = (void *)it->enterkey;
194 if (it->leftkey == NULL)
195 it->leftkey = it->enterkey;
196 if (it->rightkey == NULL)
197 it->rightkey = it->enterkey;
198 it->nativedata1 = nativedata1;
199 it->nativedata2 = nativedata2;
203 void ui_item_remove(ui_t *ui, char *basename, int number)
208 snprintf(itemname, sizeof(itemname), "%s%04d", basename, number);
209 for (it = ui->items, i = 0;i < ui->item_count;it++, i++)
210 if (it->name && !strncmp(itemname, it->name, 32))
212 if (i < ui->item_count)
216 ui_item_t *ui_hititem(float x, float y)
221 for (j = 0;j < MAX_UI_COUNT;j++)
222 if ((ui = ui_list[j]))
223 for (it = ui->items, i = 0;i < ui->item_count;it++, i++)
224 if (it->name[0] && (it->flags & ITEM_CLICKABLE))
225 if (x >= it->click_x && y >= it->click_y && x < it->click_x2 && y < it->click_y2)
230 int ui_uiactive(ui_t *ui)
233 for (i = 0;i < MAX_UI_COUNT;i++)
234 if (ui_list[i] == ui)
239 void ui_activate(ui_t *ui, int yes)
247 for (i = 0;i < MAX_UI_COUNT;i++)
249 if (ui_list[i] == NULL)
256 Con_Printf("ui_activate: ran out of active ui list items\n");
260 for (i = 0;i < MAX_UI_COUNT;i++)
262 if (ui_list[i] == ui)
271 int ui_isactive(void)
277 for (j = 0;j < MAX_UI_COUNT;j++)
278 if ((ui = ui_list[j]))
285 #define UI_QUEUE_SIZE 256
286 static byte ui_keyqueue[UI_QUEUE_SIZE];
287 static int ui_keyqueuepos = 0;
289 void ui_leftkeyupdate(int pressed)
291 static int key = false;
292 if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE)
293 ui_keyqueue[ui_keyqueuepos++] = UIKEY_LEFT;
297 void ui_rightkeyupdate(int pressed)
299 static int key = false;
300 if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE)
301 ui_keyqueue[ui_keyqueuepos++] = UIKEY_RIGHT;
305 void ui_upkeyupdate(int pressed)
307 static int key = false;
308 if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE)
309 ui_keyqueue[ui_keyqueuepos++] = UIKEY_UP;
313 void ui_downkeyupdate(int pressed)
315 static int key = false;
316 if (pressed && !key && ui_keyqueuepos < UI_QUEUE_SIZE)
317 ui_keyqueue[ui_keyqueuepos++] = UIKEY_DOWN;
321 void ui_mousebuttonupdate(int button, int pressed)
323 if (button < 0 || button >= UI_MOUSEBUTTONS)
325 if (button == 0 && ui_mousebutton[button] && !pressed)
326 ui_mouseclick = true;
327 ui_mousebutton[button] = pressed;
332 ui_item_t *startitem, *it;
335 ui_mouse_x = bound(0, ui_mouse_x, vid.conwidth);
336 ui_mouse_y = bound(0, ui_mouse_y, vid.conheight);
338 if ((ui_active = ui_isactive()))
340 // validate currently selected item
341 if(ui_list[ui_keyui] == NULL)
343 while (ui_list[ui_keyui] == NULL)
344 ui_keyui = (ui_keyui + 1) % MAX_UI_COUNT;
347 ui_keyitem = bound(0, ui_keyitem, ui_list[ui_keyui]->item_count - 1);
348 startitem = ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem];
349 if ((ui_keyrealitem->flags & ITEM_CLICKABLE) == 0)
353 // FIXME: cycle through UIs as well as items in a UI
354 ui_keyitem = (ui_keyitem - 1) % ui_list[ui_keyui]->item_count - 1;
355 ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem];
357 while (ui_keyrealitem != startitem && (ui_keyrealitem->flags & ITEM_CLICKABLE) == 0);
363 for (i = 0;i < ui_keyqueuepos;i++)
365 startitem = ui_keyrealitem;
366 switch(ui_keyqueue[i])
375 ui_keyui = (ui_keyui - 1) % MAX_UI_COUNT;
376 while(ui_list[ui_keyui] == NULL);
377 ui_keyitem = ui_list[ui_keyui]->item_count - 1;
379 ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem];
381 while (ui_keyrealitem != startitem && (ui_keyrealitem->flags & ITEM_CLICKABLE) == 0);
387 if (ui_keyitem >= ui_list[ui_keyui]->item_count)
390 ui_keyui = (ui_keyui + 1) % MAX_UI_COUNT;
391 while(ui_list[ui_keyui] == NULL);
394 ui_keyrealitem = &ui_list[ui_keyui]->items[ui_keyitem];
396 while (ui_keyrealitem != startitem && (ui_keyrealitem->flags & ITEM_CLICKABLE) == 0);
399 if (ui_keyrealitem->leftkey)
400 ui_keyrealitem->leftkey(ui_keyrealitem->nativedata1, ui_keyrealitem->nativedata2, ui_keyrealitem->data1, ui_keyrealitem->data2);
403 if (ui_keyrealitem->rightkey)
404 ui_keyrealitem->rightkey(ui_keyrealitem->nativedata1, ui_keyrealitem->nativedata2, ui_keyrealitem->data1, ui_keyrealitem->data2);
407 if (ui_keyrealitem->enterkey)
408 ui_keyrealitem->enterkey(ui_keyrealitem->nativedata1, ui_keyrealitem->nativedata2, ui_keyrealitem->data1, ui_keyrealitem->data2);
415 if (ui_mouseclick && (it = ui_hititem(ui_mouse_x, ui_mouse_y)) && it->mouseclick)
416 it->mouseclick(it->nativedata1, it->nativedata2, it->data1, it->data2, ui_mouse_x - it->click_x, ui_mouse_y - it->click_y);
419 ui_mouseclick = false;
427 if (ui_alive && ui_active)
429 for (j = 0;j < MAX_UI_COUNT;j++)
430 if ((ui = ui_list[j]))
432 for (i = 0, it = ui->items;i < ui->item_count;i++, it++)
433 if (it->flags & ITEM_DRAWABLE)
436 Draw_Pic(it->draw_x, it->draw_y, it->draw_pic);
438 Draw_String(it->draw_x, it->draw_y, it->draw_string, 9999);
441 if ((it = ui_hititem(ui_mouse_x, ui_mouse_y)))
444 Draw_AdditivePic(it->draw_x, it->draw_y, it->draw_pic);
446 Draw_AdditiveString(it->draw_x, it->draw_y, it->draw_string, 9999);
447 if (ui_showname.integer)
448 Draw_String(ui_mouse_x, ui_mouse_y + 16, it->name, 9999);
453 Draw_AdditivePic(it->draw_x, it->draw_y, it->draw_pic);
455 Draw_AdditiveString(it->draw_x, it->draw_y, it->draw_string, 9999);
457 // Draw_Pic(ui_mouse_x, ui_mouse_y, ui_mousepointer);
458 Draw_GenericPic(ui_mousepointertexture, 1, 1, 1, 1, ui_mouse_x, ui_mouse_y, 16, 16);