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