/** * @brief Renders a image widget. * * @param img Image widget to render. * @param bx Base X position. * @param by Base Y position. */ static void img_render( Widget* img, double bx, double by ) { double x,y; double w,h; /* Fanciness. */ if (img->dat.img.image == NULL) return; /* Values. */ x = bx + img->x; y = by + img->y; w = img->w; h = img->h; /* * image */ gl_blitScale( img->dat.img.image, x, y, w, h, img->dat.img.colour ); if (img->dat.img.border) { /* inner outline (outwards) */ toolkit_drawOutline( x, y+1, img->dat.img.image->sw-1, img->dat.img.image->sh-1, 1., toolkit_colLight, toolkit_col ); /* outer outline */ toolkit_drawOutline( x, y+1, img->dat.img.image->sw-1, img->dat.img.image->sh-1, 2., toolkit_colDark, NULL ); } }
/** * @brief Renders the background images. */ static void background_renderImages( background_image_t *bkg_arr ) { int i; background_image_t *bkg; double px,py, x,y, xs,ys, z; /* Must have an image array created. */ if (bkg_arr == NULL) return; /* Render images in order. */ for (i=0; i<array_size(bkg_arr); i++) { bkg = &bkg_arr[i]; cam_getPos( &px, &py ); x = px + (bkg->x - px) * bkg->move - bkg->scale*bkg->image->sw/2.; y = py + (bkg->y - py) * bkg->move - bkg->scale*bkg->image->sh/2.; gl_gameToScreenCoords( &xs, &ys, x, y ); z = cam_getZoom(); z *= bkg->scale; gl_blitScale( bkg->image, xs, ys, z*bkg->image->sw, z*bkg->image->sh, &bkg->col ); } }
/** * @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 Displays the introduction sequence. * * @brief text Path of text file to use. * @brief mus Type of music to use (run through music.lua). * @return 0 on success. */ int intro_display( const char *text, const char *mus ) { double offset; /* distance from bottom of the top line. */ double line_height; /* # pixels per line. */ int lines_per_screen; /* max appearing lines on the screen. */ scroll_buf_t *sb_arr; /* array of lines to render. */ scroll_buf_t *sb_list; /* list " " " " */ double vel = 16.; /* velocity: speed of text. */ int stop = 0; /* stop the intro. */ unsigned int tcur, tlast; /* timers. */ double delta; /* time diff from last render to this one. */ int line_index = 0; /* index into the big list of intro lines. */ intro_img_t side_image; /* image to go along with the text. */ intro_img_t transition; /* image for transitioning. */ /* Load the introduction. */ if (intro_load(text) < 0) return -1; /* Change music to intro music. */ if (mus != NULL) music_choose(mus); /* We need to clear key repeat to avoid infinite loops. */ toolkit_clearKey(); /* Enable keyrepeat just for the intro. */ SDL_EnableKeyRepeat( conf.repeat_delay, conf.repeat_freq ); /* Do a few calculations to figure out how many lines can be present on the screen at any given time. */ line_height = (double)intro_font.h * 1.3; lines_per_screen = (int)(SCREEN_H / line_height + 1.5); /* round up + 1 */ sb_arr = (scroll_buf_t*)malloc( sizeof(scroll_buf_t) * lines_per_screen ); /* Force the first line to be loaded immediately. */ offset = line_height; /* Create a cycle of lines. */ sb_list = arrange_scroll_buf( sb_arr, lines_per_screen ); /* Unset the side image. */ initialize_image( &side_image ); initialize_image( &transition ); tlast = SDL_GetTicks(); while (!stop) { tcur = SDL_GetTicks(); delta = (double)(tcur - tlast) / 1000.; tlast = tcur; /* Increment position. */ offset += vel * delta; while (! (offset < line_height)) { /* One line has scrolled off, and another one on. */ if (line_index < intro_nlines) { switch (intro_lines[line_index][0]) { case 't': /* plain ol' text. */ sb_list->text = &intro_lines[line_index][1]; offset -= line_height; sb_list = sb_list->next; break; case 'i': /* fade in image. */ intro_fade_image_in( &side_image, &transition, &intro_lines[line_index][1] ); break; case 'o': /* fade out image. */ if (NULL == side_image.tex) { WARN("Tried to fade out without an image." ); break; } side_image.fade_rate = -0.1; side_image.c.a = 0.99; break; default: /* unknown. */ break; } ++line_index; } else { sb_list->text = NULL; offset -= line_height; sb_list = sb_list->next; } } /* while (offset > line_height) */ /* Fade the side image. */ if (side_image.tex != NULL && side_image.c.a < 1.0) { side_image.c.a += delta * vel * side_image.fade_rate; if (transition.tex != NULL && transition.fade_rate > 0.0) { transition.c.a += delta * vel * transition.fade_rate; } if (side_image.c.a > 1.0) { /* Faded in... */ side_image.c.a = 1.0; side_image.fade_rate = 0.0; } else if (side_image.c.a < 0.0) { /* Faded out... */ gl_freeTexture( side_image.tex ); if (transition.tex != NULL) { side_image.tex = transition.tex; side_image.c.a = transition.c.a; side_image.y = transition.y; side_image.fade_rate = 0.1; transition.tex = NULL; transition.c.a = 1.0; } else { side_image.c.a = 1.0; side_image.tex = NULL; side_image.fade_rate = 0.0; } } } /* Clear stuff. */ glClear(GL_COLOR_BUFFER_BIT); /* Only thing we actually care about updating is music. */ music_update( 0. ); /* Draw text. */ stop = intro_draw_text( sb_list, offset, line_height ); if (NULL != side_image.tex) { /* Draw the image next to the text. */ gl_blitScale( side_image.tex, side_image.x, side_image.y, side_image.tex->w, side_image.tex->h, &side_image.c ); } if (NULL != transition.tex && transition.c.a > 0.0) { /* Draw the image in transition. */ gl_blitScale( transition.tex, transition.x, transition.y, transition.tex->w, transition.tex->h, &transition.c ); } /* Display stuff. */ SDL_GL_SwapBuffers(); SDL_Delay(10); /* No need to burn CPU. */ /* Handle user events. */ intro_event_handler( &stop, &offset, &vel ); } /* while (!stop) */ /* free malloc'd memory. */ free( sb_arr ); if (NULL != side_image.tex) { gl_freeTexture( side_image.tex ); } if (NULL != transition.tex) { gl_freeTexture( transition.tex ); } /* Disable intro's key repeat. */ SDL_EnableKeyRepeat( 0, 0 ); /* Stop music, normal music will start shortly after. */ music_stop(); /* Clean up after the introduction. */ intro_cleanup(); return 0; }
/** * @brief Renders the load screen with message. * * @param done Amount done (1. == completed). * @param msg Loading screen message. */ void loadscreen_render( double done, const char *msg ) { glColour col; double bx,by, bw,bh; double x,y, w,h, rh; /* Clear background. */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Draw stars. */ space_renderStars( 0. ); /* * Dimensions. */ /* Image. */ bw = 512.; bh = 512.; bx = (SCREEN_W-bw)/2.; by = (SCREEN_H-bh)/2.; /* Loading bar. */ w = gl_screen.w * 0.4; h = gl_screen.h * 0.02; rh = h + gl_defFont.h + 4.; x = -w/2.; if (SCREEN_H < 768) y = -h/2.; else y = -bw/2 - rh - 5.; /* Draw loading screen image. */ if (loading != NULL) gl_blitScale( loading, bx, by, bw, bh, NULL ); /* Draw progress bar. */ /* BG. */ col.r = cBlack.r; col.g = cBlack.g; col.b = cBlack.b; col.a = 0.7; gl_renderRect( x-2., y-2., w+4., rh+4., &col ); /* FG. */ col.r = cDConsole.r; col.g = cDConsole.g; col.b = cDConsole.b; col.a = 0.2; gl_renderRect( x+done*w, y, (1.-done)*w, h, &col ); col.r = cConsole.r; col.g = cConsole.g; col.b = cConsole.b; col.a = 0.7; gl_renderRect( x, y, done*w, h, &col ); /* Draw text. */ gl_printRaw( &gl_defFont, x + gl_screen.w/2., y + gl_screen.h/2 + 2. + h, &cConsole, msg ); /* Flip buffers. */ SDL_GL_SwapBuffers(); }