Clean up menus and text drawing
FossilOrigin-Name: f17992369e439fa68605017c6ffb0d11eece9d29a4cdb5768656bd874248d623
This commit is contained in:
parent
623076a034
commit
0bd8f1920f
14 changed files with 331 additions and 225 deletions
|
@ -11,7 +11,7 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
@property (nonatomic) bool loaded;
|
||||
|
||||
- (bool)loadWithIRI:(OFIRI *)IRI;
|
||||
- (void)renderWithLight:(OFVector3D &)light
|
||||
- (void)renderWithLight:(OFVector3D)light
|
||||
frame:(int)frame
|
||||
range:(int)range
|
||||
x:(float)x
|
||||
|
|
14
src/MD2.mm
14
src/MD2.mm
|
@ -24,6 +24,12 @@ struct md2_frame {
|
|||
md2_vertex vertices[1];
|
||||
};
|
||||
|
||||
static float
|
||||
snap(int sn, float f)
|
||||
{
|
||||
return sn ? (float)(((int)(f + sn * 0.5f)) & (~(sn - 1))) : f;
|
||||
}
|
||||
|
||||
@implementation MD2 {
|
||||
int _numGlCommands;
|
||||
int *_glCommands;
|
||||
|
@ -103,12 +109,6 @@ struct md2_frame {
|
|||
}
|
||||
}
|
||||
|
||||
float
|
||||
snap(int sn, float f)
|
||||
{
|
||||
return sn ? (float)(((int)(f + sn * 0.5f)) & (~(sn - 1))) : f;
|
||||
}
|
||||
|
||||
- (void)scaleWithFrame:(int)frame scale:(float)scale snap:(int)sn
|
||||
{
|
||||
_mverts[frame] = new OFVector3D[_numVerts];
|
||||
|
@ -125,7 +125,7 @@ snap(int sn, float f)
|
|||
}
|
||||
}
|
||||
|
||||
- (void)renderWithLight:(OFVector3D &)light
|
||||
- (void)renderWithLight:(OFVector3D)light
|
||||
frame:(int)frame
|
||||
range:(int)range
|
||||
x:(float)x
|
||||
|
|
16
src/Menu.h
Normal file
16
src/Menu.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#import <ObjFW/ObjFW.h>
|
||||
|
||||
OF_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class MenuItem;
|
||||
|
||||
@interface Menu : OFObject
|
||||
@property (readonly, nonatomic) OFString *name;
|
||||
@property (readonly) OFMutableArray<MenuItem *> *items;
|
||||
@property (nonatomic) int mwidth;
|
||||
@property (nonatomic) int menusel;
|
||||
|
||||
- (instancetype)initWithName:(OFString *)name;
|
||||
@end
|
||||
|
||||
OF_ASSUME_NONNULL_END
|
13
src/Menu.m
Normal file
13
src/Menu.m
Normal file
|
@ -0,0 +1,13 @@
|
|||
#import "Menu.h"
|
||||
|
||||
@implementation Menu
|
||||
- (instancetype)initWithName:(OFString *)name
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
_name = [name copy];
|
||||
_items = [[OFMutableArray alloc] init];
|
||||
|
||||
return self;
|
||||
}
|
||||
@end
|
7
src/MenuItem.h
Normal file
7
src/MenuItem.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#import <ObjFW/ObjFW.h>
|
||||
|
||||
@interface MenuItem : OFObject
|
||||
@property (readonly, nonatomic) OFString *text, *action;
|
||||
|
||||
- (instancetype)initWithText:(OFString *)text action:(OFString *)action;
|
||||
@end
|
31
src/MenuItem.m
Normal file
31
src/MenuItem.m
Normal file
|
@ -0,0 +1,31 @@
|
|||
#import "MenuItem.h"
|
||||
|
||||
@implementation MenuItem
|
||||
- (instancetype)initWithText:(OFString *)text action:(OFString *)action
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
_text = [text copy];
|
||||
_action = [action copy];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (OFComparisonResult)compare:(id)otherObject
|
||||
{
|
||||
MenuItem *otherItem;
|
||||
|
||||
if (![otherObject isKindOfClass:[MenuItem class]])
|
||||
@throw [OFInvalidArgumentException exception];
|
||||
|
||||
int x = (int)_text.longLongValue;
|
||||
int y = (int)otherItem.text.longLongValue;
|
||||
|
||||
if (x > y)
|
||||
return OFOrderedAscending;
|
||||
if (x < y)
|
||||
return OFOrderedDescending;
|
||||
|
||||
return OFOrderedSame;
|
||||
}
|
||||
@end
|
|
@ -107,8 +107,10 @@ renderscore(dynent *d)
|
|||
sprintf_s(scorelines.add().s)("%d\t%s\t%d\t%s\t%s", d->frags,
|
||||
d->state == CS_LAGGED ? "LAG" : lag, d->ping, d->team,
|
||||
d->state == CS_DEAD ? name : d->name);
|
||||
menumanual(0, scorelines.length() - 1, scorelines.last().s);
|
||||
};
|
||||
@autoreleasepool {
|
||||
menumanual(0, scorelines.length() - 1, @(scorelines.last().s));
|
||||
}
|
||||
}
|
||||
|
||||
const int maxteams = 4;
|
||||
char *teamname[maxteams];
|
||||
|
@ -141,7 +143,7 @@ renderscores()
|
|||
if (!demoplayback)
|
||||
renderscore(player1);
|
||||
loopv(players) if (players[i]) renderscore(players[i]);
|
||||
sortmenu(0, scorelines.length());
|
||||
sortmenu();
|
||||
if (m_teammode) {
|
||||
teamsused = 0;
|
||||
loopv(players) addteamscore(players[i]);
|
||||
|
@ -152,11 +154,13 @@ renderscores()
|
|||
{
|
||||
sprintf_sd(sc)("[ %s: %d ]", teamname[j], teamscore[j]);
|
||||
strcat_s(teamscores, sc);
|
||||
};
|
||||
menumanual(0, scorelines.length(), "");
|
||||
menumanual(0, scorelines.length() + 1, teamscores);
|
||||
};
|
||||
};
|
||||
}
|
||||
menumanual(0, scorelines.length(), @"");
|
||||
@autoreleasepool {
|
||||
menumanual(0, scorelines.length() + 1, @(teamscores));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sendmap/getmap commands, should be replaced by more intuitive map downloading
|
||||
|
||||
|
|
|
@ -85,13 +85,15 @@ renderconsole() // render buffer taking into account time & scrolling
|
|||
refs[nd++] = conlines[i].cref;
|
||||
if (nd == ndraw)
|
||||
break;
|
||||
};
|
||||
}
|
||||
@autoreleasepool {
|
||||
loopj(nd)
|
||||
{
|
||||
draw_text(refs[j], FONTH / 3,
|
||||
draw_text(@(refs[j]), FONTH / 3,
|
||||
(FONTH / 4 * 5) * (nd - j - 1) + FONTH / 3, 2);
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// keymap is defined externally in keymap.cfg
|
||||
|
||||
|
@ -164,11 +166,12 @@ void
|
|||
history(int n)
|
||||
{
|
||||
static bool rec = false;
|
||||
|
||||
if (!rec && n >= 0 && n < vhistory.length()) {
|
||||
rec = true;
|
||||
execute(vhistory[vhistory.length() - n - 1]);
|
||||
rec = false;
|
||||
};
|
||||
}
|
||||
}
|
||||
COMMAND(history, ARG_1INT)
|
||||
|
||||
|
|
140
src/menus.mm
140
src/menus.mm
|
@ -2,22 +2,14 @@
|
|||
|
||||
#include "cube.h"
|
||||
|
||||
struct mitem {
|
||||
char *text, *action;
|
||||
};
|
||||
#include <memory>
|
||||
|
||||
struct gmenu {
|
||||
char *name;
|
||||
vector<mitem> items;
|
||||
int mwidth;
|
||||
int menusel;
|
||||
};
|
||||
#import "Menu.h"
|
||||
#import "MenuItem.h"
|
||||
|
||||
vector<gmenu> menus;
|
||||
|
||||
int vmenu = -1;
|
||||
|
||||
ivector menustack;
|
||||
static OFMutableArray<OFNumber *> *menuStack;
|
||||
static OFMutableArray<Menu *> *menus;
|
||||
static int vmenu = -1;
|
||||
|
||||
void
|
||||
menuset(int menu)
|
||||
|
@ -29,59 +21,54 @@ menuset(int menu)
|
|||
}
|
||||
|
||||
void
|
||||
showmenu(OFString *name_)
|
||||
{
|
||||
@autoreleasepool {
|
||||
const char *name = name_.UTF8String;
|
||||
loopv(menus) if (i > 1 && strcmp(menus[i].name, name) == 0)
|
||||
showmenu(OFString *name)
|
||||
{
|
||||
int i = 0;
|
||||
for (Menu *menu in menus) {
|
||||
if (i > 1 && [menu.name isEqual:name]) {
|
||||
menuset(i);
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
COMMAND(showmenu, ARG_1STR)
|
||||
|
||||
int
|
||||
menucompare(mitem *a, mitem *b)
|
||||
{
|
||||
int x = atoi(a->text);
|
||||
int y = atoi(b->text);
|
||||
if (x > y)
|
||||
return -1;
|
||||
if (x < y)
|
||||
return 1;
|
||||
return 0;
|
||||
};
|
||||
|
||||
void
|
||||
sortmenu(int start, int num)
|
||||
sortmenu()
|
||||
{
|
||||
qsort(&menus[0].items[start], num, sizeof(mitem),
|
||||
(int(__cdecl *)(const void *, const void *))menucompare);
|
||||
};
|
||||
[menus[0].items sort];
|
||||
}
|
||||
|
||||
void refreshservers();
|
||||
|
||||
bool
|
||||
rendermenu()
|
||||
{
|
||||
@autoreleasepool {
|
||||
if (vmenu < 0) {
|
||||
menustack.setsize(0);
|
||||
[menuStack removeAllObjects];
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
if (vmenu == 1)
|
||||
refreshservers();
|
||||
gmenu &m = menus[vmenu];
|
||||
sprintf_sd(title)(vmenu > 1 ? "[ %s menu ]" : "%s", m.name);
|
||||
int mdisp = m.items.length();
|
||||
|
||||
Menu *m = menus[vmenu];
|
||||
OFString *title;
|
||||
if (vmenu > 1)
|
||||
title =
|
||||
[OFString stringWithFormat:@"[ %@ menu ]", m.name];
|
||||
else
|
||||
title = m.name;
|
||||
int mdisp = m.items.count;
|
||||
int w = 0;
|
||||
loopi(mdisp)
|
||||
{
|
||||
int x = text_width(m.items[i].text);
|
||||
if (x > w)
|
||||
w = x;
|
||||
};
|
||||
}
|
||||
int tw = text_width(title);
|
||||
if (tw > w)
|
||||
w = tw;
|
||||
|
@ -95,48 +82,47 @@ rendermenu()
|
|||
y += FONTH * 2;
|
||||
if (vmenu) {
|
||||
int bh = y + m.menusel * step;
|
||||
blendbox(
|
||||
x - FONTH, bh - 10, x + w + FONTH, bh + FONTH + 10, false);
|
||||
};
|
||||
blendbox(x - FONTH, bh - 10, x + w + FONTH,
|
||||
bh + FONTH + 10, false);
|
||||
}
|
||||
loopj(mdisp)
|
||||
{
|
||||
draw_text(m.items[j].text, x, y, 2);
|
||||
y += step;
|
||||
};
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
newmenu(OFString *name)
|
||||
{
|
||||
@autoreleasepool {
|
||||
gmenu &menu = menus.add();
|
||||
menu.name = newstring(name.UTF8String);
|
||||
menu.menusel = 0;
|
||||
}
|
||||
if (menus == nil)
|
||||
menus = [[OFMutableArray alloc] init];
|
||||
|
||||
[menus addObject:[[Menu alloc] initWithName:name]];
|
||||
}
|
||||
COMMAND(newmenu, ARG_1STR)
|
||||
|
||||
void
|
||||
menumanual(int m, int n, char *text)
|
||||
menumanual(int m, int n, OFString *text)
|
||||
{
|
||||
if (!n)
|
||||
menus[m].items.setsize(0);
|
||||
mitem &mitem = menus[m].items.add();
|
||||
mitem.text = text;
|
||||
mitem.action = "";
|
||||
if (n == 0)
|
||||
[menus[m].items removeAllObjects];
|
||||
|
||||
MenuItem *item = [[MenuItem alloc] initWithText:text action:@""];
|
||||
[menus[m].items addObject:item];
|
||||
}
|
||||
|
||||
void
|
||||
menuitem(OFString *text, OFString *action)
|
||||
{
|
||||
@autoreleasepool {
|
||||
gmenu &menu = menus.last();
|
||||
mitem &mi = menu.items.add();
|
||||
mi.text = newstring(text.UTF8String);
|
||||
mi.action =
|
||||
action.length > 0 ? newstring(action.UTF8String) : mi.text;
|
||||
}
|
||||
Menu *menu = menus.lastObject;
|
||||
|
||||
MenuItem *item =
|
||||
[[MenuItem alloc] initWithText:text
|
||||
action:(action.length > 0 ? action : text)];
|
||||
[menu.items addObject:item];
|
||||
}
|
||||
COMMAND(menuitem, ARG_2STR)
|
||||
|
||||
|
@ -145,18 +131,23 @@ menukey(int code, bool isdown)
|
|||
{
|
||||
if (vmenu <= 0)
|
||||
return false;
|
||||
|
||||
int menusel = menus[vmenu].menusel;
|
||||
if (isdown) {
|
||||
if (code == SDLK_ESCAPE) {
|
||||
menuset(-1);
|
||||
if (!menustack.empty())
|
||||
menuset(menustack.pop());
|
||||
|
||||
if (menuStack.count > 0) {
|
||||
menuset(menuStack.lastObject.intValue);
|
||||
[menuStack removeLastObject];
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (code == SDLK_UP || code == -4)
|
||||
menusel--;
|
||||
else if (code == SDLK_DOWN || code == -5)
|
||||
menusel++;
|
||||
int n = menus[vmenu].items.length();
|
||||
int n = menus[vmenu].items.count;
|
||||
if (menusel < 0)
|
||||
menusel = n - 1;
|
||||
else if (menusel >= n)
|
||||
|
@ -164,16 +155,23 @@ menukey(int code, bool isdown)
|
|||
menus[vmenu].menusel = menusel;
|
||||
} else {
|
||||
if (code == SDLK_RETURN || code == -2) {
|
||||
char *action = menus[vmenu].items[menusel].action;
|
||||
OFString *action = menus[vmenu].items[menusel].action;
|
||||
if (vmenu == 1) {
|
||||
@autoreleasepool {
|
||||
connects(@(getservername(menusel)));
|
||||
}
|
||||
}
|
||||
menustack.add(vmenu);
|
||||
|
||||
if (menuStack == nil)
|
||||
menuStack = [[OFMutableArray alloc] init];
|
||||
|
||||
[menuStack addObject:@(vmenu)];
|
||||
menuset(-1);
|
||||
execute(action, true);
|
||||
|
||||
std::unique_ptr<char> copy(strdup(action.UTF8String));
|
||||
execute(copy.get(), true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ executable('client',
|
|||
'KeyMapping.m',
|
||||
'MD2.mm',
|
||||
'MapModelInfo.m',
|
||||
'Menu.m',
|
||||
'MenuItem.m',
|
||||
'client.mm',
|
||||
'clientextras.mm',
|
||||
'clientgame.mm',
|
||||
|
|
11
src/protos.h
11
src/protos.h
|
@ -30,8 +30,8 @@ extern void processInitQueue(void);
|
|||
// menus
|
||||
extern bool rendermenu();
|
||||
extern void menuset(int menu);
|
||||
extern void menumanual(int m, int n, char *text);
|
||||
extern void sortmenu(int start, int num);
|
||||
extern void menumanual(int m, int n, OFString *text);
|
||||
extern void sortmenu();
|
||||
extern bool menukey(int code, bool isdown);
|
||||
extern void newmenu(OFString *name);
|
||||
|
||||
|
@ -143,9 +143,10 @@ extern void fatal(OFString *s, OFString *o = @"");
|
|||
extern void *alloc(int s);
|
||||
|
||||
// rendertext
|
||||
extern void draw_text(char *str, int left, int top, int gl_num);
|
||||
extern void draw_textf(char *fstr, int left, int top, int gl_num, ...);
|
||||
extern int text_width(char *str);
|
||||
extern void draw_text(OFString *string, int left, int top, int gl_num);
|
||||
extern void draw_textf(
|
||||
OFConstantString *format, int left, int top, int gl_num, ...);
|
||||
extern int text_width(OFString *string);
|
||||
extern void draw_envbox(int t, int fogdist);
|
||||
|
||||
// editing
|
||||
|
|
|
@ -361,18 +361,21 @@ gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater)
|
|||
dblend -= curtime / 3;
|
||||
if (dblend < 0)
|
||||
dblend = 0;
|
||||
};
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
@autoreleasepool {
|
||||
char *command = getcurcommand();
|
||||
char *player = playerincrosshair();
|
||||
|
||||
if (command)
|
||||
draw_textf("> %s_", 20, 1570, 2, command);
|
||||
draw_textf(@"> %s_", 20, 1570, 2, command);
|
||||
else if (closeent[0])
|
||||
draw_text(closeent, 20, 1570, 2);
|
||||
draw_text(@(closeent), 20, 1570, 2);
|
||||
else if (player)
|
||||
draw_text(player, 20, 1570, 2);
|
||||
draw_text(@(player), 20, 1570, 2);
|
||||
}
|
||||
|
||||
renderscores();
|
||||
if (!rendermenu()) {
|
||||
|
@ -387,7 +390,7 @@ gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater)
|
|||
glColor3ub(255, 0, 0);
|
||||
else if (player1->health <= 50)
|
||||
glColor3ub(255, 128, 0);
|
||||
};
|
||||
}
|
||||
float chsize = (float)crosshairsize;
|
||||
glTexCoord2d(0.0, 0.0);
|
||||
glVertex2f(VIRTW / 2 - chsize, VIRTH / 2 - chsize);
|
||||
|
@ -398,7 +401,7 @@ gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater)
|
|||
glTexCoord2d(0.0, 1.0);
|
||||
glVertex2f(VIRTW / 2 - chsize, VIRTH / 2 + chsize);
|
||||
glEnd();
|
||||
};
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
|
@ -410,22 +413,22 @@ gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater)
|
|||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
glOrtho(0, VIRTW * 3 / 2, VIRTH * 3 / 2, 0, -1, 1);
|
||||
draw_textf("fps %d", 3200, 2390, 2, curfps);
|
||||
draw_textf("wqd %d", 3200, 2460, 2, nquads);
|
||||
draw_textf("wvt %d", 3200, 2530, 2, curvert);
|
||||
draw_textf("evt %d", 3200, 2600, 2, xtraverts);
|
||||
};
|
||||
draw_textf(@"fps %d", 3200, 2390, 2, curfps);
|
||||
draw_textf(@"wqd %d", 3200, 2460, 2, nquads);
|
||||
draw_textf(@"wvt %d", 3200, 2530, 2, curvert);
|
||||
draw_textf(@"evt %d", 3200, 2600, 2, xtraverts);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
if (player1->state == CS_ALIVE) {
|
||||
glPushMatrix();
|
||||
glOrtho(0, VIRTW / 2, VIRTH / 2, 0, -1, 1);
|
||||
draw_textf("%d", 90, 827, 2, player1->health);
|
||||
draw_textf(@"%d", 90, 827, 2, player1->health);
|
||||
if (player1->armour)
|
||||
draw_textf("%d", 390, 827, 2, player1->armour);
|
||||
draw_textf(@"%d", 390, 827, 2, player1->armour);
|
||||
draw_textf(
|
||||
"%d", 690, 827, 2, player1->ammo[player1->gunselect]);
|
||||
@"%d", 690, 827, 2, player1->ammo[player1->gunselect]);
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
glOrtho(0, VIRTW, VIRTH, 0, -1, 1);
|
||||
|
@ -442,10 +445,10 @@ gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater)
|
|||
};
|
||||
drawicon((float)(g * 64), (float)r, 1220, 1650);
|
||||
glPopMatrix();
|
||||
};
|
||||
}
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -100,40 +100,57 @@ short char_coords[96][4] = {
|
|||
};
|
||||
|
||||
int
|
||||
text_width(char *str)
|
||||
text_width(OFString *string)
|
||||
{
|
||||
@autoreleasepool {
|
||||
const char *str = string.UTF8String;
|
||||
size_t len = string.UTF8StringLength;
|
||||
|
||||
int x = 0;
|
||||
for (int i = 0; str[i] != 0; i++) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
int c = str[i];
|
||||
if (c == '\t') {
|
||||
x = (x + PIXELTAB) / PIXELTAB * PIXELTAB;
|
||||
continue;
|
||||
};
|
||||
}
|
||||
|
||||
if (c == '\f')
|
||||
continue;
|
||||
|
||||
if (c == ' ') {
|
||||
x += FONTH / 2;
|
||||
continue;
|
||||
};
|
||||
}
|
||||
|
||||
c -= 33;
|
||||
if (c < 0 || c >= 95)
|
||||
continue;
|
||||
|
||||
int in_width = char_coords[c][2] - char_coords[c][0];
|
||||
x += in_width + 1;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_textf(char *fstr, int left, int top, int gl_num, ...)
|
||||
draw_textf(OFConstantString *format, int left, int top, int gl_num, ...)
|
||||
{
|
||||
sprintf_sdlv(str, gl_num, fstr);
|
||||
@autoreleasepool {
|
||||
va_list arguments;
|
||||
va_start(arguments, gl_num);
|
||||
OFString *str = [[OFString alloc] initWithFormat:format
|
||||
arguments:arguments];
|
||||
va_end(arguments);
|
||||
draw_text(str, left, top, gl_num);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_text(char *str, int left, int top, int gl_num)
|
||||
draw_text(OFString *string, int left, int top, int gl_num)
|
||||
{
|
||||
@autoreleasepool {
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
glBindTexture(GL_TEXTURE_2D, gl_num);
|
||||
glColor3ub(255, 255, 255);
|
||||
|
@ -145,20 +162,28 @@ draw_text(char *str, int left, int top, int gl_num)
|
|||
float in_left, in_top, in_right, in_bottom;
|
||||
int in_width, in_height;
|
||||
|
||||
for (i = 0; str[i] != 0; i++) {
|
||||
const char *str = string.UTF8String;
|
||||
size_t len = string.UTF8StringLength;
|
||||
for (i = 0; i < len; i++) {
|
||||
int c = str[i];
|
||||
|
||||
if (c == '\t') {
|
||||
x = (x - left + PIXELTAB) / PIXELTAB * PIXELTAB + left;
|
||||
x = (x - left + PIXELTAB) / PIXELTAB *
|
||||
PIXELTAB +
|
||||
left;
|
||||
continue;
|
||||
};
|
||||
}
|
||||
|
||||
if (c == '\f') {
|
||||
glColor3ub(64, 255, 128);
|
||||
continue;
|
||||
};
|
||||
}
|
||||
|
||||
if (c == ' ') {
|
||||
x += FONTH / 2;
|
||||
continue;
|
||||
};
|
||||
}
|
||||
|
||||
c -= 33;
|
||||
if (c < 0 || c >= 95)
|
||||
continue;
|
||||
|
@ -186,6 +211,7 @@ draw_text(char *str, int left, int top, int gl_num)
|
|||
x += in_width + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// also Don's code, so goes in here too :)
|
||||
|
||||
|
|
|
@ -243,10 +243,10 @@ checkpings()
|
|||
sgetstr();
|
||||
strcpy_s(si.sdesc, text);
|
||||
break;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sicompare(const serverinfo *a, const serverinfo *b)
|
||||
|
@ -254,7 +254,7 @@ sicompare(const serverinfo *a, const serverinfo *b)
|
|||
return a->ping > b->ping
|
||||
? 1
|
||||
: (a->ping < b->ping ? -1 : strcmp(a->name, b->name));
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
refreshservers()
|
||||
|
@ -285,11 +285,13 @@ refreshservers()
|
|||
si.name);
|
||||
}
|
||||
si.full[50] = 0; // cut off too long server descriptions
|
||||
menumanual(1, i, si.full);
|
||||
@autoreleasepool {
|
||||
menumanual(1, i, @(si.full));
|
||||
}
|
||||
if (!--maxmenu)
|
||||
return;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
servermenu()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue