Menus in the console version should be unchanged. Let me know if this is not the case.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7258 c06c8d41-db1a-0410-9941-cceddc491573
MADTICUXDKQB7EKTXG7J2OIJGUM7A437FRWIBRA3BIVEKXEXHO6AC
F3UFN3NCLA2WEQ5LX63MMEVXFWYHEV6ZYLDEB6DG7D2GRU3BPOPAC
YHC3WZ5ATCJCQQ4CMWJA2IDPSY6FQZP7HJL6JI5WXETTY54BJU2AC
ZGWMTQ4GG7W5HDVHPQCWJIUK4LK4PS3CDOOIQSFANTU33D45DCPAC
Q3B3UVMYEVC4YJUPYVSNTR4DJH4E6J4JJDHZNT5LNOCHCPPMEMXAC
PBTLQZHBQK5TAIO7SNSCKSHOQQ65CFFI55OTTETV7FG2FCJOXKHQC
NDE6CROMCVOJRMRMEID7QISFPZKUK2VCV6ISP5OEQRBH7EIXUIEQC
XKNRIFG2ULQLAAQ5GC4RBZPOERV73DLCNILEA5EP37JLIX5EP3OQC
MV5USMLTBKVRWBAD67UFJ2BS4Y5HEOMYASRSB44DS24BBMRP75RQC
3SQQ4MM6YO4I37CQ6GIBIX6BXAEVHNVNHPVMR3PPBBNO454D6XWQC
YOYZ4BX35Y63XVQGBYN3DL2PJ53H6Z5PHCOL5QTRH2ZKHZCGMD3QC
UL7XFKMUX3WIU4O2LZANK4ECJ654UZPDBFGNXUEYZYOLKBYBCG6AC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
UUF2MSD5MZSKPFENQNJA4QSXVTSEVME43FIY5BE2TDJQ3O3RYHKAC
LDBTCT5WIPLJPZWXS2RUQ26QKISCUUTLO77M464WOE6VSYSNPKYAC
P4V66RMIZAPCZJW23HDYDUAPMHN664U3KK4DYBYC7FZSWRGPVMPAC
FCL7KOWXA5O3GLMDR22JCGMTHMZ57C4WQIJKBIIUQV3LI2CI3X7AC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
B7EE54F23AM4BECQ7GENNC4MHIPH6YVMOXOGZAQUZJKDJYGL7RAQC
25CH7HH4LKXFIZ75YNMXS3TSXO6O27DYSOPLOD45K4OCNFWLS4LQC
BK6MGPSEAEMU4URBAPKY3VTKK6JC6IZVN5CNOSN2UPTIOWQYEWLQC
2PAHDAPDO6PN4FNGB5N7CQNEGHSE3NOGPXYZMIAOJC4VW34FRVOAC
YH23OR26YDA6C5K74QRWHROMTPGRNZHTHE4HJGPC3JVNAJ62CHGAC
3NUVKRHPHENI7JNHDDIHZ4FESSZ2Z5XJZVB56ZCXPGMP7O3JCM3QC
IHOKNI4O7EEW4UBMKHP6XOZNEIQSW4AYOT4O3JXUIXNNR553IQAQC
2N5AKUYV6EUUT254C47WSHZKD7FGN65JKJ3RCKSDP74XJIHIFMDQC
CV2Q7Y3P7SRU5ARIMVDLNVZV4VIMCBYOLIMS6HK6IK3WW4DGIIIAC
AU3E5FTABBHFZAZHLGA3UUR5TCTRLDOEMAKTGGEWKCQVH77I3SYAC
3D6NWJ44UYHLZMD3BOQIWXJUEGITAVCHK6Z2WWDQONVQC4HSBRXQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
BWAQ3FHBBM6G3K3KYP75CRTR343RDQZJRYX5ZGYUEXYBAC3APDLAC
GBLEVRUADUFICPSVEHPVBQAMWGQODKFYS2UAANEHKMUPZWMPLGNQC
while (m_region_crt->ey + m_region_menu_inv->wy > m_windowsz.y)
{
m_region_crt->resize(m_region_crt->mx, m_region_crt->my - 1);
}
while (m_region_crt->ex > m_windowsz.x)
{
m_region_crt->resize(m_region_crt->mx - 1, m_region_crt->my);
}
m_region_menu_inv->place(0, m_region_crt->ey, margin);
m_region_menu_inv->resize_to_fit(m_windowsz.x, m_windowsz.y -
m_region_menu_inv->sy);
// Depending on the font, the menu inventory may hold fewer items
// than the crt menu can display. Decrease the lines if necessary.
const int ex = 3;
if (m_region_crt->my - ex > m_region_menu_inv->mx)
m_region_crt->resize(m_region_crt->mx, m_region_menu_inv->mx + ex);
void TilesFramework::update_menu_inventory(unsigned int slot,
const item_def &item,
bool selected, char key)
{
InventoryTile desc;
_fill_item_info(desc, item);
desc.key = key;
desc.idx = (desc.flag & TILEI_FLAG_FLOOR) ? item.index() :
letter_to_index(key);
if (selected)
desc.flag |= TILEI_FLAG_SELECT;
m_region_menu_inv->update_slot(slot, desc);
}
};
class MenuEntry;
class MenuRegion : public Region
{
public:
MenuRegion(ImageManager *im, FTFont *entry);
virtual int handle_mouse(MouseEvent &event);
virtual void render();
virtual void clear();
int maxpagesize() const;
void set_entry(int index, const std::string &s, int colour, const MenuEntry *me);
void set_offset(int lines);
void set_more(const formatted_string &more);
protected:
virtual void on_resize();
virtual void place_entries();
int mouse_entry(int x, int y);
struct MenuRegionEntry
{
formatted_string text;
int tile;
TextureID texture;
int sx, ex, sy, ey;
bool selected;
bool heading;
char key;
bool valid;
};
ImageManager *m_image;
FTFont *m_font_entry;
formatted_string m_more;
int m_mouse_idx;
bool m_dirty;
std::vector<MenuRegionEntry> m_entries;
ShapeBuffer m_shape_buf;
LineBuffer m_line_buf;
FontBuffer m_font_buf;
TileBuffer m_tile_buf;
// TODO enne - clicking on menu items? We could probably
// determine which items were clicked based on text size.
return 0;
}
MenuRegion::MenuRegion(ImageManager *im, FTFont *entry) :
m_image(im), m_font_entry(entry), m_mouse_idx(-1),
m_dirty(false), m_font_buf(entry), m_tile_buf(NULL)
{
ASSERT(m_image);
ASSERT(m_font_entry);
dx = 1;
dy = 1;
m_entries.resize(128);
}
int MenuRegion::mouse_entry(int x, int y)
{
if (m_dirty)
place_entries();
for (unsigned int i = 0; i < m_entries.size(); i++)
{
if (!m_entries[i].valid)
continue;
if (x >= m_entries[i].sx && x <= m_entries[i].ex
&& y >= m_entries[i].sy && y <= m_entries[i].ey)
{
return i;
}
}
return -1;
}
int MenuRegion::handle_mouse(MouseEvent &event)
{
m_mouse_idx = -1;
int x, y;
if (!mouse_pos(event.px, event.py, x, y))
return 0;
if (event.event == MouseEvent::MOVE)
{
int old_idx = m_mouse_idx;
m_mouse_idx = mouse_entry(x, y);
if (old_idx == m_mouse_idx)
return 0;
const VColour mouse_colour(160, 160, 160, 255);
m_line_buf.clear();
if (!m_entries[m_mouse_idx].heading && m_entries[m_mouse_idx].key)
{
m_line_buf.add_square(m_entries[m_mouse_idx].sx-1,
m_entries[m_mouse_idx].sy,
m_entries[m_mouse_idx].ex+1,
m_entries[m_mouse_idx].ey+1,
mouse_colour);
}
return 0;
}
if (event.event == MouseEvent::PRESS)
{
switch (event.button)
{
case MouseEvent::LEFT:
{
int entry = mouse_entry(x, y);
if (entry == -1)
return 0;
return m_entries[entry].key;
}
#if 0
// TODO enne - these events are wonky on OS X.
// TODO enne - fix menus so that mouse wheeling doesn't easy exit
case MouseEvent::SCROLL_UP:
return CK_UP;
case MouseEvent::SCROLL_DOWN:
return CK_DOWN;
#endif
default:
return 0;
}
}
const int heading_indent = 10;
const int tile_ident = 20;
const int text_indent = 58;
const unsigned int max_tile_height = 32;
const int column_width = mx / 2;
const int entry_buffer = 1;
const VColour selected_colour(50, 50, 10, 255);
m_font_buf.clear();
m_tile_buf.clear();
m_shape_buf.clear();
m_line_buf.clear();
TextureID tex = TEX_MAX;
int height = 2;
bool mouse_selected = false;
for (unsigned int i = 0; i < m_entries.size(); i++)
{
if (!m_entries[i].valid)
{
m_entries[i].sx = 0;
m_entries[i].sy = 0;
m_entries[i].ex = 0;
m_entries[i].ey = 0;
continue;
}
m_entries[i].sy = height;
int text_start = 0;
int text_height = height;
if (m_entries[i].heading)
{
mouse_selected = false;
m_entries[i].sx = heading_indent;
text_start = heading_indent;
height += m_font_entry->char_height();
}
else if (m_entries[i].tile)
{
m_entries[i].sx = tile_ident;
text_start = text_indent;
int entry_height =
std::max(max_tile_height, m_font_entry->char_height());
height += entry_height;
text_height += (entry_height - m_font_entry->char_height()) / 2;
ASSERT(m_entries[i].texture == tex || tex == TEX_MAX);
tex = m_entries[i].texture;
m_tile_buf.set_tex(&m_image->m_textures[tex]);
m_tile_buf.add(m_entries[i].tile, m_entries[i].sx, m_entries[i].sy);
}
else
{
m_entries[i].sx = text_start + text_indent;
height += m_font_entry->char_height();
}
std::string unfrm = m_entries[i].text.tostring();
m_entries[i].ex = text_start + m_font_entry->string_width(unfrm.c_str());
m_entries[i].ex = std::max(m_entries[i].ex, column_width);
m_entries[i].ey = height;
m_font_buf.add(m_entries[i].text, text_start, text_height);
if (m_entries[i].selected)
{
m_shape_buf.add(m_entries[i].sx-1, m_entries[i].sy-1,
m_entries[i].ex+1, m_entries[i].ey+1,
selected_colour);
}
height += entry_buffer;
}
int lines = count_linebreaks(m_more);
int more_height = (lines + 1) * m_font_entry->char_height();
m_font_buf.add(m_more, sx + ox, ey - oy - more_height);
}
void MenuRegion::render()
{
if (m_dirty)
place_entries();
glLoadIdentity();
glTranslatef(sx + ox, sy + oy, 0);
glScalef(dx, dy, 1);
m_shape_buf.draw();
m_line_buf.draw();
m_tile_buf.draw();
m_font_buf.draw();
}
void MenuRegion::clear()
{
m_shape_buf.clear();
m_line_buf.clear();
m_tile_buf.clear();
m_font_buf.clear();
m_more.clear();
for (unsigned int i = 0; i < m_entries.size(); i++)
{
m_entries[i].valid = false;
}
m_mouse_idx = -1;
}
void MenuRegion::set_entry(int idx, const std::string &str, int colour,
const MenuEntry *me)
{
if (idx >= (int)m_entries.size())
{
int new_size = m_entries.size();
while (idx >= new_size)
new_size *= 2;
m_entries.resize(new_size);
}
MenuRegionEntry &e = m_entries[idx];
e.valid = true;
e.text.clear();
e.text.textcolor(colour);
e.text += formatted_string::parse_string(str);
e.heading = (me->level == MEL_TITLE || me->level == MEL_SUBTITLE);
e.selected = me->selected();
e.key = me->hotkeys.size() > 0 ? me->hotkeys[0] : 0;
e.sx = e.sy = e.ex = e.ey = 0;
if (!me->tile(e.tile, e.texture))
e.tile = 0;
m_dirty = true;
}
void MenuRegion::on_resize()
{
m_dirty = true;
}
int MenuRegion::maxpagesize() const
{
// TODO enne - this could be much smarter. Also, columns?
return my / 32 - 2;
}
void MenuRegion::set_offset(int lines)
{
oy = (lines - 1) * m_font_entry->char_height();
}
void MenuRegion::set_more(const formatted_string &more)
{
m_more.clear();
m_more += more;
m_dirty = true;
}
{ 0, 0, 0}, // BLACK
{ 0, 82, 255}, // BLUE
{100, 185, 70}, // GREEN
{ 0, 180, 180}, // CYAN
{255, 48, 0}, // RED
{238, 92, 238}, // MAGENTA
{165, 91, 0}, // BROWN
{162, 162, 162}, // LIGHTGREY
{ 82, 82, 82}, // DARKGREY
{ 82, 102, 255}, // LIGHTBLUE
{ 82, 255, 82}, // LIGHTGREEN
{ 82, 255, 255}, // LIGHTCYAN
{255, 82, 82}, // LIGHTRED
{255, 82, 255}, // LIGHTMAGENTA
{255, 255, 82}, // YELLOW
{255, 255, 255} // WHITE
VColour( 0, 0, 0), // BLACK
VColour( 0, 82, 255), // BLUE
VColour(100, 185, 70), // GREEN
VColour( 0, 180, 180), // CYAN
VColour(255, 48, 0), // RED
VColour(238, 92, 238), // MAGENTA
VColour(165, 91, 0), // BROWN
VColour(162, 162, 162), // LIGHTGREY
VColour( 82, 82, 82), // DARKGREY
VColour( 82, 102, 255), // LIGHTBLUE
VColour( 82, 255, 82), // LIGHTGREEN
VColour( 82, 255, 255), // LIGHTCYAN
VColour(255, 82, 82), // LIGHTRED
VColour(255, 82, 255), // LIGHTMAGENTA
VColour(255, 255, 82), // YELLOW
VColour(255, 255, 255) // WHITE
verts[i].r = term_colours[box_colour][0];
verts[i].g = term_colours[box_colour][1];
verts[i].b = term_colours[box_colour][2];
verts[i].r = term_colours[box_colour].r;
verts[i].g = term_colours[box_colour].g;
verts[i].b = term_colours[box_colour].b;
void FTFont::store(FontBuffer &buf, float &x, float &y,
const std::string &str, const VColour &col)
{
for (unsigned int i = 0; i < str.size(); i++)
{
char c = str[i];
if (c == '\n')
{
y += m_max_advance.y;
}
else
{
store(buf, x, y, c, col);
}
}
}
void FTFont::store(FontBuffer &buf, float &x, float &y,
const formatted_string &fs)
{
int colour = LIGHTGREY;
for (unsigned int i = 0; i < fs.ops.size(); i++)
{
switch (fs.ops[i].type)
{
case FSOP_COLOUR:
// Only foreground colors for now...
colour = fs.ops[i].x & 0xF;
break;
case FSOP_TEXT:
store(buf, x, y, fs.ops[i].text, term_colours[colour]);
break;
default:
case FSOP_CURSOR:
break;
}
}
}
void FTFont::store(FontBuffer &buf, float &x, float &y,
char c, const VColour &col)
{
if (!m_glyphs[c].renderable)
{
x += m_glyphs[c].advance;
return;
}
int this_width = m_glyphs[c].width;
float pos_sx = x + m_glyphs[c].offset;
float pos_sy = y;
float pos_ex = pos_sx + this_width;
float pos_ey = y + m_max_advance.y;
float tex_sx = (float)(c % 16) / 16.0f;
float tex_sy = (float)(c / 16) / 16.0f;
float tex_ex = tex_sx + (float)this_width / (float)m_tex.width();
float tex_ey = tex_sy + (float)m_max_advance.y / (float)m_tex.height();
{
PTCVert &v = buf.get_next();
v.col = col;
v.pos_x = pos_sx;
v.pos_y = pos_sy;
v.tex_x = tex_sx;
v.tex_y = tex_sy;
}
{
PTCVert &v = buf.get_next();
v.col = col;
v.pos_x = pos_sx;
v.pos_y = pos_ey;
v.tex_x = tex_sx;
v.tex_y = tex_ey;
}
{
PTCVert &v = buf.get_next();
v.col = col;
v.pos_x = pos_ex;
v.pos_y = pos_ey;
v.tex_x = tex_ex;
v.tex_y = tex_ey;
}
{
PTCVert &v = buf.get_next();
v.col = col;
v.pos_x = pos_ex;
v.pos_y = pos_sy;
v.tex_x = tex_ex;
v.tex_y = tex_sy;
}
x += m_glyphs[c].advance;
}
/*
* File: tilebuf.h
* Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC
*
* Modified for Crawl Reference by $Author: ennewalker $ on $Date: 2008-03-07 $
*/
#ifndef TILEBUF_H
#define TILEBUF_H
class FTFont;
class formatted_string;
class GenericTexture;
class TilesTexture;
#include <vector>
struct VColour
{
VColour() {}
VColour(unsigned char _r, unsigned char _g, unsigned char _b,
unsigned char _a = 255) : r(_r), g(_g), b(_b), a(_a) {}
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
static VColour white;
static VColour black;
static VColour transparent;
};
struct PTCVert
{
float pos_x;
float pos_y;
float tex_x;
float tex_y;
VColour col;
};
struct PTVert
{
float pos_x;
float pos_y;
float tex_x;
float tex_y;
};
struct PCVert
{
float pos_x;
float pos_y;
VColour col;
};
// V: vertex data
template<class V>
class VertBuffer
{
public:
VertBuffer(const GenericTexture *tex, int prim);
void add(const V& vert);
V& get_next();
void draw() const;
void clear();
protected:
std::vector<V> m_verts;
const GenericTexture *m_tex;
int m_prim;
};
class FontBuffer : public VertBuffer<PTCVert>
{
public:
FontBuffer(FTFont *font);
void add(const formatted_string &fs, float x, float y);
void add(const std::string &s, const VColour &col, float x, float y);
protected:
FTFont *m_font;
};
class TileBuffer : public VertBuffer<PTVert>
{
public:
TileBuffer(const TilesTexture *tex);
void add(int idx, float x, float y);
// Note: this could invalidate previous additions if they were
// from a different texture.
void set_tex(const TilesTexture *tex);
};
class ShapeBuffer : public VertBuffer<PCVert>
{
public:
ShapeBuffer();
void add(float sx, float sy, float ex, float ey, const VColour &c);
};
class LineBuffer : public VertBuffer<PCVert>
{
public:
LineBuffer();
void add(float sx, float sy, float ex, float ey, const VColour &c);
void add_square(float sx, float sy, float ex, float ey, const VColour &c);
};
/////////////////////////////////////////////////////////////////////////////
// template implementation
template<class V>
inline VertBuffer<V>::VertBuffer(const GenericTexture *tex, int prim) :
m_tex(tex), m_prim(prim)
{
}
template<class V>
inline void VertBuffer<V>::add(const V& vert)
{
m_verts.push_back(vert);
}
template<class V>
inline V& VertBuffer<V>::get_next()
{
int last = m_verts.size();
m_verts.resize(last + 1);
return (m_verts[last]);
}
template<class V>
inline void VertBuffer<V>::clear()
{
m_verts.clear();
}
#endif
/*
* File: tilebuf.cc
* Summary: Vertex buffer implementaions
*
* Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC
*
* Modified for Crawl Reference by $Author: ennewalker $ on $Date: 2008-10-11 $
*/
#include "tilebuf.h"
#include "tilefont.h"
#include "tilesdl.h"
#include <SDL.h>
#include <SDL_opengl.h>
/////////////////////////////////////////////////////////////////////////////
// VColour
VColour VColour::white(255, 255, 255, 255);
VColour VColour::black(0, 0, 0, 255);
VColour VColour::transparent(0, 0, 0, 0);
/////////////////////////////////////////////////////////////////////////////
// VertBuffer
static bool _valid(int num_verts, int prim)
{
switch (prim)
{
case GL_QUADS:
return (num_verts % 4 == 0);
case GL_TRIANGLES:
return (num_verts % 3 == 0);
case GL_LINES:
return (num_verts % 2 == 0);
case GL_POINTS:
return (true);
default:
return (false);
}
}
template<>
void VertBuffer<PTVert>::draw() const
{
if (m_verts.size() == 0)
return;
ASSERT(_valid(m_verts.size(), m_prim));
ASSERT(m_tex);
GLState state;
state.array_vertex = true;
state.array_texcoord = true;
state.blend = true;
state.texture = true;
GLStateManager::set(state);
m_tex->bind();
glVertexPointer(2, GL_FLOAT, sizeof(PTVert), &m_verts[0].pos_x);
glTexCoordPointer(2, GL_FLOAT, sizeof(PTVert), &m_verts[0].tex_x);
glDrawArrays(m_prim, 0, m_verts.size());
}
template<>
void VertBuffer<PCVert>::draw() const
{
if (m_verts.size() == 0)
return;
ASSERT(_valid(m_verts.size(), m_prim));
ASSERT(!m_tex);
GLState state;
state.array_vertex = true;
state.array_colour = true;
state.blend = true;
state.texture = true;
GLStateManager::set(state);
glVertexPointer(2, GL_FLOAT, sizeof(PCVert), &m_verts[0].pos_x);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PCVert), &m_verts[0].col);
glDrawArrays(m_prim, 0, m_verts.size());
}
template<>
void VertBuffer<PTCVert>::draw() const
{
if (m_verts.size() == 0)
return;
ASSERT(_valid(m_verts.size(), m_prim));
ASSERT(m_tex);
GLState state;
state.array_vertex = true;
state.array_texcoord = true;
state.array_colour = true;
state.blend = true;
state.texture = true;
GLStateManager::set(state);
m_tex->bind();
glVertexPointer(2, GL_FLOAT, sizeof(PTCVert), &m_verts[0].pos_x);
glTexCoordPointer(2, GL_FLOAT, sizeof(PTCVert), &m_verts[0].tex_x);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PTCVert), &m_verts[0].col);
glDrawArrays(m_prim, 0, m_verts.size());
}
/////////////////////////////////////////////////////////////////////////////
// FontBuffer
FontBuffer::FontBuffer(FTFont *font) :
VertBuffer<PTCVert>(font->font_tex(), GL_QUADS), m_font(font)
{
ASSERT(m_font);
ASSERT(m_tex);
}
void FontBuffer::add(const formatted_string &fs, float x, float y)
{
m_font->store(*this, x, y, fs);
ASSERT(_valid(m_verts.size(), m_prim));
}
void FontBuffer::add(const std::string &s, const VColour &col, float x, float y)
{
m_font->store(*this, x, y, s, col);
ASSERT(_valid(m_verts.size(), m_prim));
}
/////////////////////////////////////////////////////////////////////////////
// TileBuffer
TileBuffer::TileBuffer(const TilesTexture *t) : VertBuffer<PTVert>(t, GL_QUADS)
{
}
void TileBuffer::add(int idx, float x, float y)
{
const tile_info &inf = ((TilesTexture*)m_tex)->get_info(idx);
float pos_sx = x + inf.offset_x;
float pos_sy = y + inf.offset_y;
float pos_ex = pos_sx + (inf.ex - inf.sx);
float pos_ey = pos_sy + (inf.ey - inf.sy);
float fwidth = m_tex->width();
float fheight = m_tex->height();
float tex_sx = inf.sx / fwidth;
float tex_sy = inf.sy / fheight;
float tex_ex = inf.ex / fwidth;
float tex_ey = inf.ey / fheight;
{
PTVert &v = get_next();
v.pos_x = pos_sx;
v.pos_y = pos_sy;
v.tex_x = tex_sx;
v.tex_y = tex_sy;
}
{
PTVert &v = get_next();
v.pos_x = pos_sx;
v.pos_y = pos_ey;
v.tex_x = tex_sx;
v.tex_y = tex_ey;
}
{
PTVert &v = get_next();
v.pos_x = pos_ex;
v.pos_y = pos_ey;
v.tex_x = tex_ex;
v.tex_y = tex_ey;
}
{
PTVert &v = get_next();
v.pos_x = pos_ex;
v.pos_y = pos_sy;
v.tex_x = tex_ex;
v.tex_y = tex_sy;
}
ASSERT(_valid(m_verts.size(), m_prim));
}
void TileBuffer::set_tex(const TilesTexture *tex)
{
ASSERT(tex);
m_tex = tex;
}
/////////////////////////////////////////////////////////////////////////////
// ShapeBuffer
ShapeBuffer::ShapeBuffer() : VertBuffer<PCVert>(NULL, GL_QUADS)
{
}
void ShapeBuffer::add(float pos_sx, float pos_sy, float pos_ex, float pos_ey,
const VColour &col)
{
{
PCVert &v = get_next();
v.pos_x = pos_sx;
v.pos_y = pos_sy;
v.col = col;
}
{
PCVert &v = get_next();
v.pos_x = pos_sx;
v.pos_y = pos_ey;
v.col = col;
}
{
PCVert &v = get_next();
v.pos_x = pos_ex;
v.pos_y = pos_ey;
v.col = col;
}
{
PCVert &v = get_next();
v.pos_x = pos_ex;
v.pos_y = pos_sy;
v.col = col;
}
ASSERT(_valid(m_verts.size(), m_prim));
}
/////////////////////////////////////////////////////////////////////////////
// LineBuffer
LineBuffer::LineBuffer() : VertBuffer<PCVert>(NULL, GL_LINES)
{
}
void LineBuffer::add(float pos_sx, float pos_sy, float pos_ex, float pos_ey,
const VColour &col)
{
{
PCVert &v = get_next();
v.pos_x = pos_sx;
v.pos_y = pos_sy;
v.col = col;
}
{
PCVert &v = get_next();
v.pos_x = pos_ex;
v.pos_y = pos_ey;
v.col = col;
}
ASSERT(_valid(m_verts.size(), m_prim));
}
void LineBuffer::add_square(float sx, float sy, float ex, float ey,
const VColour &col)
{
add(sx, sy, ex, sy, col);
add(ex, sy, ex, ey, col);
add(ex, ey, sx, ey, col);
add(sx, ey, sx, sy, col);
}
void draw_stock_item(int index, const MenuEntry *me) const
{
// Skip inventory draw function, as tiles code can't currently
// handle drawing items that aren't in mitm or in inventory.
Menu::draw_stock_item(index, me);
}
class MenuDisplay
{
public:
MenuDisplay(Menu *menu);
virtual ~MenuDisplay() {}
virtual void draw_stock_item(int index, const MenuEntry *me) = 0;
virtual void set_offset(int lines) = 0;
virtual void draw_more() = 0;
protected:
Menu *m_menu;
};
class MenuDisplayText : public MenuDisplay
{
public:
MenuDisplayText(Menu *menu);
virtual void draw_stock_item(int index, const MenuEntry *me);
virtual void draw_more();
virtual void set_offset(int lines) { m_starty = lines; }
protected:
int m_starty;
};
class MenuDisplayTile : public MenuDisplay
{
public:
MenuDisplayTile(Menu *menu);
virtual void draw_stock_item(int index, const MenuEntry *me);
virtual void set_offset(int lines);
virtual void draw_more();
};
MenuDisplayText::MenuDisplayText(Menu *menu) : MenuDisplay(menu), m_starty(1)
{
}
void MenuDisplayText::draw_stock_item(int index, const MenuEntry *me)
{
textattr(m_menu->item_colour(index, me));
if (m_menu->get_flags() & MF_ALLOW_FORMATTING)
formatted_string::parse_string(me->get_text()).display();
else
{
std::string text = me->get_text();
if ((int) text.length() > get_number_of_cols())
text = text.substr(0, get_number_of_cols());
cprintf("%s", text.c_str());
}
}
void MenuDisplayText::draw_more()
{
cgotoxy(1, m_menu->get_y_offset() + m_menu->get_pagesize() -
count_linebreaks(m_menu->get_more()));
m_menu->get_more().display();
}
#ifdef USE_TILE
MenuDisplayTile::MenuDisplayTile(Menu *menu) : MenuDisplay(menu)
{
m_menu->set_maxpagesize(tiles.get_menu()->maxpagesize());
}
void MenuDisplayTile::draw_stock_item(int index, const MenuEntry *me)
{
int colour = m_menu->item_colour(index, me);
std::string text = me->get_text();
tiles.get_menu()->set_entry(index, text, colour, me);
}
void MenuDisplayTile::set_offset(int lines)
{
tiles.get_menu()->set_offset(lines);
}
void MenuDisplayTile::draw_more()
{
tiles.get_menu()->set_more(m_menu->get_more());
}
#endif
{
cgotoxy( 1, y_offset + pagesize - count_linebreaks(more) );
more.display();
}
mdisplay->draw_more();
textattr( item_colour(index, items[index]) );
if ( flags & MF_ALLOW_FORMATTING )
formatted_string::parse_string(items[index]->get_text()).display();
else
{
std::string text = items[index]->get_text();
if ((int) text.length() > get_number_of_cols())
text = text.substr(0, get_number_of_cols());
cprintf( "%s", text.c_str() );
}
mdisplay->draw_stock_item(index, me);
#ifdef USE_TILE
const InvEntry *ie = dynamic_cast<const InvEntry*>(me);
if (ie && me->quantity > 0)
{
char key = ie->hotkeys.size() > 0 ? ie->hotkeys[0] : 0;
tiles.update_menu_inventory(get_entry_index(ie), *ie->item, ie->selected(), key);
}
#endif
if (quantity <= 0)
return false;
idx = tileidx_item(*item);
tex = TEX_DEFAULT;