/** * @brief Prints text on the screen. * * @usage gfx.print( nil, "Hello World!", 50, 50, colour.new("Red") ) -- Displays text in red at 50,50. * @usage gfx.print( true, "Hello World!", 50, 50, col, 100 ) -- Displays text to a maximum of 100 pixels wide. * @usage gfx.print( true, str, 50, 50, col, 100, true ) -- Displays centered text to a maximum of 100 pixels. * * @luaparam small Whether or not to use a small font. * @luaparam str String to print. * @luaparam x X position to print at. * @luaparam y Y position to print at. * @luaparam col Colour to print text. * @luaparam max Optional parameter to indicate maximum width to render up to. * @luaparam center Optional boolean parameter indicating whether or not to center it. * @luafunc print( small, str, x, y, col, max, center ) */ static int gfxL_print( lua_State *L ) { glFont *font; const char *str; double x, y; LuaColour *lc; int max, mid; /* Parse parameters. */ font = lua_toboolean(L,1) ? &gl_smallFont : &gl_defFont; str = luaL_checkstring(L,2); x = luaL_checknumber(L,3); y = luaL_checknumber(L,4); lc = luaL_checkcolour(L,5); if (lua_gettop(L) >= 6) max = luaL_checkinteger(L,6); else max = 0; mid = lua_toboolean(L,7); /* Render. */ if (mid) gl_printMidRaw( font, max, x, y, &lc->col, str ); else if (max > 0) gl_printMaxRaw( font, max, x, y, &lc->col, str ); else gl_printRaw( font, x, y, &lc->col, str ); return 0; }
/** * @brief Renders a button widget. * * @param btn WIDGET_BUTTON widget to render. * @param bx Base X position. * @param by Base Y position. */ static void btn_render( Widget* btn, double bx, double by ) { glColour *c, *dc, *lc; double x, y; x = bx + btn->x; y = by + btn->y; /* set the colours */ if (btn->dat.btn.disabled==1) { lc = &cGrey60; c = &cGrey20; dc = &cGrey40; } else { switch (btn->status) { case WIDGET_STATUS_NORMAL: lc = &cGrey80; c = &cGrey60; dc = &cGrey40; break; case WIDGET_STATUS_MOUSEOVER: lc = &cGrey90; c = &cGrey70; dc = &cGrey50; break; case WIDGET_STATUS_MOUSEDOWN: lc = &cGrey90; c = &cGrey50; dc = &cGrey70; break; default: break; } } /* shaded base */ if (btn->dat.btn.disabled==1) { toolkit_drawRect( x, y, btn->w, 0.4*btn->h, dc, NULL ); toolkit_drawRect( x, y+0.4*btn->h, btn->w, 0.6*btn->h, dc, c ); } else { toolkit_drawRect( x, y, btn->w, 0.6*btn->h, dc, c ); toolkit_drawRect( x, y+0.6*btn->h, btn->w, 0.4*btn->h, c, NULL ); } /* inner outline */ toolkit_drawOutline( x, y, btn->w, btn->h, 0., lc, c ); /* outter outline */ toolkit_drawOutline( x, y, btn->w, btn->h, 1., &cBlack, NULL ); gl_printMidRaw( NULL, (int)btn->w, bx + (double)SCREEN_W/2. + btn->x, by + (double)SCREEN_H/2. + btn->y + (btn->h - gl_defFont.h)/2., &cDarkRed, btn->dat.btn.display ); }
/** * @brief Renders a news widget. * * @param bx Base X position to render at. * @param by Base Y positoin to render at. * @param w Width of the widget. * @param h Height of the widget. */ static void news_render( double bx, double by, double w, double h, void *data ) { (void) data; int i; unsigned int t; double y, dt; t = SDL_GetTicks(); /* Calculate offset. */ if (!news_drag) { dt = (double)(t-news_tick)/1000.; news_pos += dt * 25.; } news_tick = t; /* Make sure user isn't silly and drags it to negative values. */ if (news_pos < 0.) news_pos += (news_font->h + 5.) * news_nlines + h + 3; /* background */ gl_renderRect( bx, by, w, h, &cBlack ); /* Render the text. */ i = (int)(news_pos / (news_font->h + 5.)); if (i > news_nlines + (int)(h/(news_font->h + 5.)) + 3) { news_pos = 0.; return; } /* Get start position. */ y = news_pos - (i+1) * (news_font->h + 5.) - 10.; /* Draw loop. */ while (i >= 0) { /* Skip in line isn't valid. */ if (i >= news_nlines) { i--; y += news_font->h + 5.; continue; } gl_printMidRaw( news_font, w-40., bx+10 + (double)SCREEN_W/2., by+y + (double)SCREEN_H/2., &cConsole, news_lines[i] ); /* Increment line and position. */ i--; y += news_font->h + 5.; } }
/** * @brief Renders the overlays. */ void omsg_render( double dt ) { int i, j; double x, y; omsg_t *omsg; glFont *font; glColour col; /* Case nothing to do. */ if (omsg_array == NULL) return; /* Center. */ x = omsg_center_x - omsg_center_w/2.; y = omsg_center_y; /* Render. */ for (i=0; i<array_size(omsg_array); i++) { omsg = &omsg_array[i]; /* Check if time to erase. */ omsg->duration -= dt; if (omsg->duration < 0.) { omsg_free( omsg ); array_erase( &omsg_array, &omsg[0], &omsg[1] ); i--; continue; } /* Must have a message. */ if (omsg->msg == NULL) continue; /* Render. */ font = omsg_getFont( omsg->font ); memcpy( &col, omsg->col, sizeof(glColour) ); if (omsg->duration < 1.) col.a = omsg->duration; for (j=0; j<omsg->nlines; j++) { y -= font->h * 1.5; if (j>0) gl_printRestoreLast(); gl_printMidRaw( font, omsg_center_w, x, y, &col, omsg->msg[j] ); } } }
/** * @brief Renders a text widget. * * @param txt Text widget to render. * @param bx Base X position. * @param by Base Y position. */ static void txt_render( Widget* txt, double bx, double by ) { /* Must have text to display. */ if (txt->dat.txt.text==NULL) return; if (txt->dat.txt.centered) gl_printMidRaw( txt->dat.txt.font, txt->w, bx + (double)SCREEN_W/2. + txt->x, by + (double)SCREEN_H/2. + txt->y, txt->dat.txt.colour, txt->dat.txt.text ); else gl_printTextRaw( txt->dat.txt.font, txt->w, txt->h, bx + (double)SCREEN_W/2. + txt->x, by + (double)SCREEN_H/2. + txt->y, txt->dat.txt.colour, txt->dat.txt.text ); }
/** * @brief Displays text centered in position and width. * * Will truncate if text is too long. * * @param ft_font Font to use (NULL defaults to gl_defFont) * @param width Width of area to center in. * @param x X position to display text at. * @param y Y position to display text at. * @param c Colour to use for text (NULL defaults to white). * @param fmt Text to display formatted like printf. * @return The number of characters it had to truncate. */ int gl_printMid( const glFont *ft_font, const int width, double x, const double y, const glColour* c, const char *fmt, ... ) { /*float h = ft_font->h / .63;*/ /* slightly increase fontsize */ char text[256]; /* holds the string */ va_list ap; if (fmt == NULL) return -1; else { /* convert the symbols to text */ va_start(ap, fmt); vsnprintf(text, 256, fmt, ap); va_end(ap); } return gl_printMidRaw( ft_font, width, x, y, c, text ); }
/** * @brief Renders an image array. * * @param iar Image array widget to render. * @param bx Base X position. * @param by Base Y position. */ static void iar_render( Widget* iar, double bx, double by ) { int i,j, pos; double x,y, w,h, xcurs,ycurs; double scroll_pos; int xelem, yelem; double xspace; glColour *c, *dc, *lc, tc, fontcolour; int is_selected; int tw; double d; /* * Calculations. */ /* position */ x = bx + iar->x; y = by + iar->y; /* element dimensions */ iar_getDim( iar, &w, &h ); /* number of elements */ xelem = iar->dat.iar.xelem; yelem = iar->dat.iar.yelem; xspace = (double)(((int)iar->w - 10) % (int)w) / (double)(xelem + 1); /* background */ toolkit_drawRect( x, y, iar->w, iar->h, &cBlack, NULL ); /* * Scrollbar. */ d = h * (yelem - (int)(iar->h / h)); if (fabs(d) < 1e-05) scroll_pos = 0.; else scroll_pos = iar->dat.iar.pos / d; toolkit_drawScrollbar( x + iar->w - 10., y, 10., iar->h, scroll_pos ); /* * Main drawing loop. */ gl_clipRect( x, y, iar->w, iar->h ); ycurs = y + iar->h - h + iar->dat.iar.pos; for (j=0; j<yelem; j++) { xcurs = x + xspace; for (i=0; i<xelem; i++) { /* Get position. */ pos = j*xelem + i; /* Out of elements. */ if ((pos) >= iar->dat.iar.nelements) break; is_selected = (iar->dat.iar.selected == pos) ? 1 : 0; fontcolour = cWhite; /* Draw background. */ if (is_selected) toolkit_drawRect( xcurs + 2., ycurs + 2., w - 5., h - 5., &cDConsole, NULL ); else if (iar->dat.iar.background != NULL) { toolkit_drawRect( xcurs + 2., ycurs + 2., w - 5., h - 5., &iar->dat.iar.background[pos], NULL ); tc = iar->dat.iar.background[pos]; if (((tc.r + tc.g + tc.b) / 3) > 0.5) fontcolour = cBlack; } /* image */ if (iar->dat.iar.images[pos] != NULL) gl_blitScale( iar->dat.iar.images[pos], xcurs + 5., ycurs + gl_smallFont.h + 7., iar->dat.iar.iw, iar->dat.iar.ih, NULL ); /* caption */ if (iar->dat.iar.captions[pos] != NULL) gl_printMidRaw( &gl_smallFont, iar->dat.iar.iw, xcurs + 5., ycurs + 5., (is_selected) ? &cBlack : &fontcolour, iar->dat.iar.captions[pos] ); /* quantity. */ if (iar->dat.iar.quantity != NULL) { if (iar->dat.iar.quantity[pos] != NULL) { /* Rectangle to highlight better. */ tw = gl_printWidthRaw( &gl_smallFont, iar->dat.iar.quantity[pos] ); if (is_selected) tc = cDConsole; else if (iar->dat.iar.background != NULL) tc = iar->dat.iar.background[pos]; else tc = cBlack; tc.a = 0.75; toolkit_drawRect( xcurs + 2., ycurs + 5. + iar->dat.iar.ih, tw + 4., gl_smallFont.h + 4., &tc, NULL ); /* Quantity number. */ gl_printMaxRaw( &gl_smallFont, iar->dat.iar.iw, xcurs + 5., ycurs + iar->dat.iar.ih + 7., &fontcolour, iar->dat.iar.quantity[pos] ); } } /* Slot type. */ if (iar->dat.iar.slottype != NULL) { if (iar->dat.iar.slottype[pos] != NULL) { /* Rectangle to highlight better. Width is a hack due to lack of monospace font. */ tw = gl_printWidthRaw( &gl_smallFont, "M" ); if (is_selected) tc = cDConsole; else if (iar->dat.iar.background != NULL) tc = iar->dat.iar.background[pos]; else tc = cBlack; tc.a = 0.75; toolkit_drawRect( xcurs + iar->dat.iar.iw - 6., ycurs + 5. + iar->dat.iar.ih, tw + 2., gl_smallFont.h + 4., &tc, NULL ); /* Slot size letter. */ gl_printMaxRaw( &gl_smallFont, iar->dat.iar.iw, xcurs + iar->dat.iar.iw - 4., ycurs + iar->dat.iar.ih + 7., &fontcolour, iar->dat.iar.slottype[pos] ); } } /* outline */ if (is_selected) { lc = &cWhite; c = &cGrey80; dc = &cGrey60; } else { lc = toolkit_colLight; c = toolkit_col; dc = toolkit_colDark; } toolkit_drawOutline( xcurs + 2., ycurs + 2., w - 4., h - 4., 1., lc, c ); toolkit_drawOutline( xcurs + 2., ycurs + 2., w - 4., h - 4., 2., dc, NULL ); xcurs += w + xspace; } ycurs -= h; } gl_unclipRect(); /* * Final outline. */ toolkit_drawOutline( x+1, y+1, iar->w-2, iar->h-2, 1., toolkit_colLight, toolkit_col ); toolkit_drawOutline( x+1, y+1, iar->w-2, iar->h-2, 2., toolkit_colDark, NULL ); }
/** * @brief Renders a window border. * * @param w Window to render */ static void window_renderBorder( Window* w ) { int i; GLint cx, cy; double x, y; glColour *lc, *c, *dc, *oc; GLint vertex[31*4]; GLfloat colours[31*4]; /* position */ x = w->x - (double)SCREEN_W/2.; y = w->y - (double)SCREEN_H/2.; /* colours */ lc = &cGrey90; c = &cGrey70; dc = &cGrey50; oc = &cGrey30; /* * Case fullscreen. */ if (window_isFlag( w, WINDOW_FULLSCREEN )) { /* Background. */ toolkit_drawRect( x, y, w->w, 0.6*w->h, dc, c ); toolkit_drawRect( x, y+0.6*w->h, w->w, 0.4*w->h, c, NULL ); /* Name. */ gl_printMidRaw( &gl_defFont, w->w, x + (double)SCREEN_W/2., y + w->h - 20. + (double)SCREEN_H/2., &cBlack, w->name ); return; } /* * window shaded bg */ /* main body */ toolkit_drawRect( x+21, y, w->w-42., 0.6*w->h, dc, c ); toolkit_drawRect( x+21, y+0.6*w->h, w->w-42., 0.4*w->h, c, NULL ); glShadeModel(GL_SMOOTH); /* Both sides. */ gl_vboActivateOffset( toolkit_vbo, GL_COLOR_ARRAY, toolkit_vboColourOffset, 4, GL_FLOAT, 0 ); gl_vboActivateOffset( toolkit_vbo, GL_VERTEX_ARRAY, 0, 2, GL_INT, 0 ); /* Colour is shared. */ colours[0] = c->r; colours[1] = c->g; colours[2] = c->r; colours[3] = c->a; for (i=0; i<7; i++) { colours[4 + 4*i + 0] = dc->r; colours[4 + 4*i + 1] = dc->g; colours[4 + 4*i + 2] = dc->r; colours[4 + 4*i + 3] = dc->a; } for (i=0; i<8; i++) { colours[32 + 4*i + 0] = c->r; colours[32 + 4*i + 1] = c->g; colours[32 + 4*i + 2] = c->r; colours[32 + 4*i + 3] = c->a; } gl_vboSubData( toolkit_vbo, toolkit_vboColourOffset, sizeof(GLfloat) * 4*16, colours ); /* Left side vertex. */ cx = x; cy = y; vertex[0] = cx + 21; vertex[1] = cy + 0.6*w->h; vertex[2] = cx + 21; vertex[3] = cy; vertex[4] = cx + 15; vertex[5] = cy + 1; vertex[6] = cx + 10; vertex[7] = cy + 3; vertex[8] = cx + 6; vertex[9] = cy + 6; vertex[10] = cx + 3; vertex[11] = cy + 10; vertex[12] = cx + 1; vertex[13] = cy + 15; vertex[14] = cx; vertex[15] = cy + 21; vertex[16] = cx; vertex[17] = cy + 0.6*w->h; vertex[18] = cx; cy = y + w->h; vertex[19] = cy - 21; vertex[20] = cx + 1; vertex[21] = cy - 15; vertex[22] = cx + 3; vertex[23] = cy - 10; vertex[24] = cx + 6; vertex[25] = cy - 6; vertex[26] = cx + 10; vertex[27] = cy - 3; vertex[28] = cx + 15; vertex[29] = cy - 1; vertex[30] = cx + 21; vertex[31] = cy; gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*16, vertex ); glDrawArrays( GL_POLYGON, 0, 16 ); /* Right side vertex. */ cx = x + w->w; cy = y; vertex[0] = cx - 21; vertex[1] = cy + 0.6*w->h; vertex[2] = cx - 21; vertex[3] = cy; vertex[4] = cx - 15; vertex[5] = cy + 1; vertex[6] = cx - 10; vertex[7] = cy + 3; vertex[8] = cx - 6; vertex[9] = cy + 6; vertex[10] = cx - 3; vertex[11] = cy + 10; vertex[12] = cx - 1; vertex[13] = cy + 15; vertex[14] = cx; vertex[15] = cy + 21; vertex[16] = cx; vertex[17] = cy + 0.6*w->h; vertex[18] = cx; cy = y + w->h; vertex[19] = cy - 21; vertex[20] = cx - 1; vertex[21] = cy - 15; vertex[22] = cx - 3; vertex[23] = cy - 10; vertex[24] = cx - 6; vertex[25] = cy - 6; vertex[26] = cx - 10; vertex[27] = cy - 3; vertex[28] = cx - 15; vertex[29] = cy - 1; vertex[30] = cx - 21; vertex[31] = cy; gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*16, vertex ); glDrawArrays( GL_POLYGON, 0, 16 ); /* * inner outline */ /* Colour. */ for (i=0; i<7; i++) { colours[4*i + 0] = c->r; colours[4*i + 1] = c->g; colours[4*i + 2] = c->b; colours[4*i + 3] = c->a; } for (; i<7+16; i++) { colours[4*i + 0] = lc->r; colours[4*i + 1] = lc->g; colours[4*i + 2] = lc->b; colours[4*i + 3] = lc->a; } for (; i<7+16+8; i++) { colours[4*i + 0] = c->r; colours[4*i + 1] = c->g; colours[4*i + 2] = c->b; colours[4*i + 3] = c->a; } gl_vboSubData( toolkit_vbo, toolkit_vboColourOffset, sizeof(GLfloat) * 4*31, colours ); /* Vertex. */ /* Left side. */ cx = x + 1; cy = y + 1; vertex[0] = cx + 21; vertex[1] = cy; vertex[2] = cx + 15; vertex[3] = cy + 1; vertex[4] = cx + 10; vertex[5] = cy + 3; vertex[6] = cx + 6; vertex[7] = cy + 6; vertex[8] = cx + 3; vertex[9] = cy + 10; vertex[10] = cx + 1; vertex[11] = cy + 15; vertex[12] = cx; vertex[13] = cy + 21; vertex[14] = cx; vertex[15] = cy + 0.6*w->h - 1; cy = y + w->h - 1; vertex[16] = cx; vertex[17] = cy - 21; vertex[18] = cx + 1; vertex[19] = cy - 15; vertex[20] = cx + 3; vertex[21] = cy - 10; vertex[22] = cx + 6; vertex[23] = cy - 6; vertex[24] = cx + 10; vertex[25] = cy - 3; vertex[26] = cx + 15; vertex[27] = cy - 1; vertex[28] = cx + 21; vertex[29] = cy; /* Right side via top. */ cx = x + w->w - 1; cy = y + w->h - 1; vertex[30] = cx - 21; vertex[31] = cy; vertex[32] = cx - 15; vertex[33] = cy - 1; vertex[34] = cx - 10; vertex[35] = cy - 3; vertex[36] = cx - 6; vertex[37] = cy - 6; vertex[38] = cx - 3; vertex[39] = cy - 10; vertex[40] = cx - 1; vertex[41] = cy - 15; vertex[42] = cx; vertex[43] = cy - 21; cy = y + 1; vertex[44] = cx; vertex[45] = cy + 0.6*w->h - 1; vertex[46] = cx; vertex[47] = cy + 21; vertex[48] = cx - 1; vertex[49] = cy + 15; vertex[50] = cx - 3; vertex[51] = cy + 10; vertex[52] = cx - 6; vertex[53] = cy + 6; vertex[54] = cx - 10; vertex[55] = cy + 3; vertex[56] = cx - 15; vertex[57] = cy + 1; vertex[58] = cx - 21; vertex[59] = cy; cx = x + 1; cy = y + 1; vertex[60] = cx + 21; vertex[61] = cy; gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*31, vertex ); glDrawArrays( GL_LINE_LOOP, 0, 31 ); /* * outter outline */ glShadeModel(GL_FLAT); /* Colour. */ for (i=0; i<31; i++) { colours[4*i + 0] = oc->r; colours[4*i + 1] = oc->g; colours[4*i + 2] = oc->b; colours[4*i + 3] = oc->a; } gl_vboSubData( toolkit_vbo, toolkit_vboColourOffset, sizeof(GLfloat) * 4*31, colours ); /* Vertex. */ /* Left side. */ cx = x; cy = y; vertex[0] = cx + 21; vertex[1] = cy; vertex[2] = cx + 15; vertex[3] = cy + 1; vertex[4] = cx + 10; vertex[5] = cy + 3; vertex[6] = cx + 6; vertex[7] = cy + 6; vertex[8] = cx + 3; vertex[9] = cy + 10; vertex[10] = cx + 1; vertex[11] = cy + 15; vertex[12] = cx; vertex[13] = cy + 21; vertex[14] = cx; vertex[15] = cy + 0.6*w->h; cy = y + w->h; vertex[16] = cx; vertex[17] = cy - 21; vertex[18] = cx + 1; vertex[19] = cy - 15; vertex[20] = cx + 3; vertex[21] = cy - 10; vertex[22] = cx + 6; vertex[23] = cy - 6; vertex[24] = cx + 10; vertex[25] = cy - 3; vertex[26] = cx + 15; vertex[27] = cy - 1; vertex[28] = cx + 21; vertex[29] = cy; /* Right side via top. */ cx = x + w->w; cy = y + w->h; vertex[30] = cx - 21; vertex[31] = cy; vertex[32] = cx - 15; vertex[33] = cy - 1; vertex[34] = cx - 10; vertex[35] = cy - 3; vertex[36] = cx - 6; vertex[37] = cy - 6; vertex[38] = cx - 3; vertex[39] = cy - 10; vertex[40] = cx - 1; vertex[41] = cy - 15; vertex[42] = cx; vertex[43] = cy - 21; cy = y; vertex[44] = cx; vertex[45] = cy + 0.6*w->h; vertex[46] = cx; vertex[47] = cy + 21; vertex[48] = cx - 1; vertex[49] = cy + 15; vertex[50] = cx - 3; vertex[51] = cy + 10; vertex[52] = cx - 6; vertex[53] = cy + 6; vertex[54] = cx - 10; vertex[55] = cy + 3; vertex[56] = cx - 15; vertex[57] = cy + 1; vertex[58] = cx - 21; vertex[59] = cy; cx = x; cy = y; vertex[60] = cx + 21; vertex[61] = cy; gl_vboSubData( toolkit_vbo, 0, sizeof(GLint) * 2*31, vertex ); glDrawArrays( GL_LINE_LOOP, 0, 31 ); /* Clean up. */ gl_vboDeactivate(); /* * render window name */ gl_printMidRaw( &gl_defFont, w->w, x + (double)SCREEN_W/2., y + w->h - 20. + (double)SCREEN_H/2., &cBlack, w->name ); }