naev 0.11.5
gui.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <stdlib.h>
11
12#include "physfs.h"
13
14#include "naev.h"
17#include "gui.h"
18
19#include "ai.h"
20#include "camera.h"
21#include "comm.h"
22#include "conf.h"
23#include "dialogue.h"
24#include "economy.h"
25#include "quadtree.h"
26#include "font.h"
27#include "gui_omsg.h"
28#include "gui_osd.h"
29#include "hook.h"
30#include "input.h"
31#include "intro.h"
32#include "land.h"
33#include "log.h"
34#include "map.h"
35#include "map_overlay.h"
36#include "menu.h"
37#include "mission.h"
38#include "music.h"
39#include "ndata.h"
40#include "nebula.h"
41#include "nfile.h"
42#include "nlua.h"
43#include "nlua_gfx.h"
44#include "nlua_gui.h"
45#include "nlua_misn.h"
46#include "nlua_tex.h"
47#include "nlua_tk.h"
48#include "nluadef.h"
49#include "nmath.h"
50#include "nstring.h"
51#include "ntime.h"
52#include "nxml.h"
53#include "opengl.h"
54#include "pause.h"
55#include "pilot.h"
56#include "pilot.h"
57#include "player.h"
58#include "render.h"
59#include "rng.h"
60#include "sound.h"
61#include "space.h"
62#include "spfx.h"
63#include "start.h"
64#include "toolkit.h"
65#include "unidiff.h"
66
67#define XML_GUI_ID "GUIs"
68#define XML_GUI_TAG "gui"
70#define RADAR_BLINK_PILOT 0.5
71#define RADAR_BLINK_SPOB 1.
73/* some blinking stuff. */
74static double blink_pilot = 0.;
75static double blink_spob = 0.;
76static double animation_dt = 0.;
78/* for VBO. */
79static gl_vbo *gui_radar_select_vbo = NULL;
80
81static int gui_getMessage = 1;
82static char *gui_name = NULL;
85extern unsigned int land_wid;
90static nlua_env gui_env = LUA_NOREF;
91static int gui_L_mclick = 0;
92static int gui_L_mmove = 0;
97static double gui_viewport_x = 0.;
98static double gui_viewport_y = 0.;
99static double gui_viewport_w = 0.;
100static double gui_viewport_h = 0.;
107typedef struct Radar_ {
108 double w;
109 double h;
110 double x;
111 double y;
112 RadarShape shape;
113 double res;
114} Radar;
115/* radar resolutions */
116#define RADAR_RES_MAX 300.
117#define RADAR_RES_REF 100.
118#define RADAR_RES_MIN 10.
119#define RADAR_RES_INTERVAL 10.
120static Radar gui_radar;
121
122/* needed to render properly */
123static double gui_xoff = 0.;
124static double gui_yoff = 0.;
126/* messages */
127static const int mesg_max = 128;
128static int mesg_pointer = 0;
129static int mesg_viewpoint = -1;
130static const double mesg_timeout = 15.;
136typedef struct Mesg_ {
137 char *str;
138 double t;
140} Mesg;
141static Mesg* mesg_stack = NULL;
142static int gui_mesg_w = 0;
143static int gui_mesg_x = 0;
144static int gui_mesg_y = 0;
146/* Calculations to speed up borders. */
147static double gui_tr = 0.;
148static double gui_br = 0.;
149static double gui_tl = 0.;
150static double gui_bl = 0.;
152/* Intrinsic graphical stuff. */
153static glTexture *gui_ico_hail = NULL;
157/* Lua Stuff. */
158static int gui_lua_create = LUA_NOREF;
159static int gui_lua_render = LUA_NOREF;
160static int gui_lua_render_cooldown = LUA_NOREF;
161static int gui_lua_cooldown_end = LUA_NOREF;
162static int gui_lua_mouse_move = LUA_NOREF;
163static int gui_lua_mouse_click = LUA_NOREF;
164static int gui_lua_update_cargo = LUA_NOREF;
165static int gui_lua_update_nav = LUA_NOREF;
166static int gui_lua_update_target = LUA_NOREF;
167static int gui_lua_update_ship = LUA_NOREF;
168static int gui_lua_update_system = LUA_NOREF;
169static int gui_lua_update_faction = LUA_NOREF;
170static int gui_lua_update_effects = LUA_NOREF;
171
172/*
173 * prototypes
174 */
175/*
176 * external
177 */
178extern void weapon_minimap( const double res, const double w, const double h,
179 const RadarShape shape, double alpha );
180/*
181 * internal
182 */
183/* gui */
184static void gui_renderTargetReticles( const SimpleShader *shd, double x, double y, double radius, double angle, const glColour* c );
185static void gui_borderIntersection( double *cx, double *cy, double rx, double ry, double hw, double hh );
186/* Render GUI. */
187static void gui_renderPilotTarget (void);
188static void gui_renderSpobTarget (void);
189static void gui_renderBorder( double dt );
190static void gui_renderMessages( double dt );
191static const glColour *gui_getSpobColour( int i );
192static void gui_renderRadarOutOfRange( RadarShape sh, int w, int h, int cx, int cy, const glColour *col );
193static void gui_blink( double cx, double cy, double vr, const glColour *col, double blinkInterval, double blinkVar );
194static const glColour* gui_getPilotColour( const Pilot* p );
195static void gui_calcBorders (void);
196/* Lua GUI. */
197static int gui_doFunc( int func_ref, const char *func_name );
198static int gui_prepFunc( int func_ref, const char *func_name );
199static int gui_runFunc( const char *func, int nargs, int nret );
200
209
217void gui_messageInit( int width, int x, int y )
218{
219 gui_mesg_w = width;
220 gui_mesg_x = x;
221 gui_mesg_y = y;
222}
223
229void gui_messageScrollUp( int lines )
230{
231 int o;
232
233 /* Handle hacks. */
234 if (mesg_viewpoint == -1) {
236 return;
237 }
238
239 /* Get offset. */
241 if (o < 0)
242 o += mesg_max;
243 o = mesg_max - 2*conf.mesg_visible - o;
244
245 /* Calculate max line movement. */
246 if (lines > o)
247 lines = o;
248
249 /* Move viewpoint. */
251}
252
258void gui_messageScrollDown( int lines )
259{
260 int o;
261
262 /* Handle hacks. */
264 mesg_viewpoint = -1;
265 return;
266 }
267 else if (mesg_viewpoint == -1)
268 return;
269
270 /* Get offset. */
272 if (o < 0)
273 o += mesg_max;
274
275 /* Calculate max line movement. */
276 if (lines > o)
277 lines = o;
278
279 /* Move viewpoint. */
281}
282
288void player_messageToggle( int enable )
289{
290 gui_getMessage = enable;
291}
292
298void player_messageRaw( const char *str )
299{
301
302 /* Must be receiving messages. */
303 if (!gui_getMessage)
304 return;
305
306 gl_printLineIteratorInit( &iter, &gl_smallFont, str, gui_mesg_w - ((str[0] == '\t') ? 45 : 15) );
307 while (gl_printLineIteratorNext( &iter )) {
308 /* Move pointer. */
310 if (mesg_viewpoint != -1)
312
313 /* Add the new one */
314 free( mesg_stack[mesg_pointer].str );
315 if (iter.l_begin == 0) {
316 mesg_stack[mesg_pointer].str = strndup( &str[iter.l_begin], iter.l_end - iter.l_begin );
318 }
319 else {
320 mesg_stack[mesg_pointer].str = malloc( iter.l_end - iter.l_begin + 2 );
321 snprintf( mesg_stack[mesg_pointer].str, iter.l_end - iter.l_begin + 2, "\t%s", &str[iter.l_begin] );
322 gl_printStoreMax( &mesg_stack[mesg_pointer].restore, str, iter.l_begin );
323 }
325
326 iter.width = gui_mesg_w - 45; /* Remaining lines are tabbed so it's shorter. */
327 }
328}
329
335void player_message( const char *fmt, ... )
336{
337 va_list ap;
338 char *buf;
339
340 /* Must be receiving messages. */
341 if (!gui_getMessage)
342 return;
343
344 /* Add the new one */
345 va_start( ap, fmt );
346 /* Requires SDL2 >=2.0.18 */
347 SDL_vasprintf( &buf, fmt, ap );
348 va_end( ap );
349 player_messageRaw( buf );
350 free( buf );
351}
352
356static void gui_renderSpobTarget (void)
357{
358 double x,y, r;
359 const glColour *c;
360
361 /* no need to draw if pilot is dead */
362 if (player_isFlag(PLAYER_DESTROYED) || player_isFlag(PLAYER_CREATING) ||
363 (player.p == NULL) || pilot_isFlag(player.p,PILOT_DEAD))
364 return;
365
366 /* Make sure target exists. */
367 if ((player.p->nav_spob < 0) && (player.p->nav_hyperspace < 0)
368 && (player.p->nav_asteroid < 0))
369 return;
370
371 /* Make sure targets are still in range. */
372#if 0
375 return;
376 }
377#endif
378
379 /* Draw spob and jump point target graphics. */
380 if (player.p->nav_hyperspace >= 0) {
381 const JumpPoint *jp = &cur_system->jumps[player.p->nav_hyperspace];
382 if (jp_isKnown(jp)) {
383 c = &cGreen;
384 x = jp->pos.x;
385 y = jp->pos.y;
386 r = jumppoint_gfx->sw * 0.5;
387 gui_renderTargetReticles( &shaders.targetspob, x, y, r, 0., c );
388 }
389 }
390 if (player.p->nav_spob >= 0) {
391 const Spob *spob = cur_system->spobs[player.p->nav_spob];
392 c = spob_getColour( spob );
393 x = spob->pos.x;
394 y = spob->pos.y;
395 r = spob->radius;
396 gui_renderTargetReticles( &shaders.targetspob, x, y, r, 0., c );
397 }
398 if (player.p->nav_asteroid >= 0) {
400 const Asteroid *ast = &field->asteroids[player.p->nav_asteroid];
401 c = &cWhite;
402
403 x = ast->sol.pos.x;
404 y = ast->sol.pos.y;
405 r = ast->gfx->sw * 0.5;
406 gui_renderTargetReticles( &shaders.targetship, x, y, r, 0., c );
407 }
408}
409
420static void gui_renderTargetReticles( const SimpleShader *shd, double x, double y, double radius, double angle, const glColour* c )
421{
422 double rx, ry, r;
423 /* Must not be NULL. */
424 if (gui_target_spob == NULL)
425 return;
426
427 gl_gameToScreenCoords( &rx, &ry, x, y );
428 r = (double)radius * 1.2 * cam_getZoom();
429
430 glUseProgram(shd->program);
431 glUniform1f(shd->dt, animation_dt);
432 glUniform1f(shd->paramf, radius);
433 gl_renderShader( rx, ry, r, r, angle, shd, c, 1 );
434}
435
439static void gui_renderPilotTarget (void)
440{
441 Pilot *p;
442 const glColour *c;
443
444 /* Player is most likely dead. */
445 if (gui_target_pilot == NULL)
446 return;
447
448 /* Get the target. */
449 if (player.p->target != PLAYER_ID)
450 p = pilot_get(player.p->target);
451 else p = NULL;
452
453 /* Make sure pilot exists and is still alive. */
454 if ((p==NULL) || pilot_isFlag(p,PILOT_DEAD)) {
457 return;
458 }
459
460 /* Make sure target is still valid and in range. */
461 if (!pilot_validTarget( player.p, p )) {
464 return;
465 }
466
467 /* Draw the pilot target. */
468 if (pilot_isDisabled(p))
469 c = &cInert;
470 else if (pilot_isHostile(p))
471 c = &cHostile;
472 else if (pilot_isFriendly(p))
473 c = &cFriend;
474 else
475 c = &cNeutral;
476
477 gui_renderTargetReticles( &shaders.targetship, p->solid.pos.x, p->solid.pos.y, p->ship->gfx_space->sw * 0.5, p->solid.dir, c );
478}
479
492static void gui_borderIntersection( double *cx, double *cy, double rx, double ry, double hw, double hh )
493{
494 double a;
495 double w, h;
496
497 /* Get angle. */
498 a = atan2( ry, rx );
499 if (a < 0.)
500 a += 2.*M_PI;
501
502 /* Helpers. */
503 w = hw-7.;
504 h = hh-7.;
505
506 /* Handle by quadrant. */
507 if ((a > gui_tr) && (a < gui_tl)) { /* Top. */
508 *cx = h * (rx/ry);
509 *cy = h;
510 }
511 else if ((a > gui_tl) && (a < gui_bl)) { /* Left. */
512 *cx = -w;
513 *cy = -w * (ry/rx);
514 }
515 else if ((a > gui_bl) && (a < gui_br)) { /* Bottom. */
516 *cx = -h * (rx/ry);
517 *cy = -h;
518 }
519 else { /* Right. */
520 *cx = w;
521 *cy = w * (ry/rx);
522 }
523
524 /* Translate. */
525 *cx += hw;
526 *cy += hh;
527}
528
534static void gui_renderBorder( double dt )
535{
536 (void) dt;
537 int hw, hh;
538 double rx,ry;
539 double cx,cy;
540 const glColour *col;
541 Pilot *const* pilot_stack;
542
543 /* Get player position. */
544 hw = SCREEN_W/2;
545 hh = SCREEN_H/2;
546
547 /* Render borders to enhance contrast. */
548 gl_renderRect( 0., 0., 15., SCREEN_H, &cBlackHilight );
549 gl_renderRect( SCREEN_W - 15., 0., 15., SCREEN_H, &cBlackHilight );
550 gl_renderRect( 15., 0., SCREEN_W - 30., 15., &cBlackHilight );
551 gl_renderRect( 15., SCREEN_H - 15., SCREEN_W - 30., 15., &cBlackHilight );
552
553 /* Draw spobs. */
554 for (int i=0; i<array_size(cur_system->spobs); i++) {
555 const Spob *pnt = cur_system->spobs[i];
556
557 /* Skip if unknown. */
558 if (!spob_isKnown( pnt ))
559 continue;
560
561 /* Check if out of range. */
562 if (!gui_onScreenSpob( &rx, &ry, NULL, pnt )) {
563
564 /* Get border intersection. */
565 gui_borderIntersection( &cx, &cy, rx, ry, hw, hh );
566
567 col = gui_getSpobColour(i);
568 gl_renderCircle(cx, cy, 5, col, 0);
569 }
570 }
571
572 /* Draw jump routes. */
573 for (int i=0; i<array_size(cur_system->jumps); i++) {
574 const JumpPoint *jp = &cur_system->jumps[i];
575
576 /* Skip if unknown or exit-only. */
577 if (!jp_isUsable( jp ))
578 continue;
579
580 /* Check if out of range. */
581 if (!gui_onScreenSpob( &rx, &ry, jp, NULL )) {
582
583 /* Get border intersection. */
584 gui_borderIntersection( &cx, &cy, rx, ry, hw, hh );
585
586 if (i==player.p->nav_hyperspace)
587 col = &cGreen;
588 else
589 col = &cWhite;
590
591 gl_renderTriangleEmpty( cx, cy, -jp->angle, 10., 1., col );
592 }
593 }
594
595 /* Draw pilots. */
597 for (int i=1; i<array_size(pilot_stack); i++) { /* skip the player */
598 Pilot *plt = pilot_stack[i];
599
600 /* See if in sensor range. */
601 if (!pilot_inRangePilot(player.p, plt, NULL))
602 continue;
603
604 /* Check if out of range. */
605 if (!gui_onScreenPilot( &rx, &ry, plt )) {
606
607 /* Get border intersection. */
608 gui_borderIntersection( &cx, &cy, rx, ry, hw, hh );
609
610 col = gui_getPilotColour(plt);
611 gl_renderRectEmpty(cx-5, cy-5, 10, 10, col);
612 }
613 }
614}
615
624int gui_onScreenPilot( double *rx, double *ry, const Pilot *pilot )
625{
626 double z;
627 int cw, ch;
628 glTexture *tex;
629
630 z = cam_getZoom();
631
632 tex = pilot->ship->gfx_space;
633
634 /* Get relative positions. */
635 *rx = (pilot->solid.pos.x - player.p->solid.pos.x)*z;
636 *ry = (pilot->solid.pos.y - player.p->solid.pos.y)*z;
637
638 /* Correct for offset. */
639 *rx -= gui_xoff;
640 *ry -= gui_yoff;
641
642 /* Compare dimensions. */
643 cw = SCREEN_W/2 + tex->sw/2;
644 ch = SCREEN_H/2 + tex->sh/2;
645
646 if ((ABS(*rx) > cw) || (ABS(*ry) > ch))
647 return 0;
648
649 return 1;
650}
651
661int gui_onScreenSpob( double *rx, double *ry, const JumpPoint *jp, const Spob *pnt )
662{
663 double z;
664 int cw, ch;
665 glTexture *tex;
666
667 z = cam_getZoom();
668
669 if (jp == NULL) {
670 tex = pnt->gfx_space;
671 *rx = (pnt->pos.x - player.p->solid.pos.x)*z;
672 *ry = (pnt->pos.y - player.p->solid.pos.y)*z;
673 }
674 else {
675 tex = jumppoint_gfx;
676 *rx = (jp->pos.x - player.p->solid.pos.x)*z;
677 *ry = (jp->pos.y - player.p->solid.pos.y)*z;
678 }
679
680 /* Correct for offset. */
681 *rx -= gui_xoff;
682 *ry -= gui_yoff;
683
684 /* Compare dimensions. */
685 cw = SCREEN_W/2;
686 ch = SCREEN_H/2;
687 if (tex != NULL) {
688 cw += tex->sw/2;
689 ch += tex->sh/2;
690 }
691
692 if ((ABS(*rx) > cw) || (ABS(*ry) > ch))
693 return 0;
694
695 return 1;
696}
697
703void gui_renderReticles( double dt )
704{
705 (void) dt;
706
707 /* Player must be alive. */
708 if (player.p == NULL)
709 return;
710
711 /* Disable in cinematics. */
712 if (player_isFlag(PLAYER_CINEMATICS))
713 return;
714
717}
718
719static int can_jump = 0;
725void gui_render( double dt )
726{
727 double fade, direction;
728
729 /* If player is dead just render the cinematic mode. */
730 if (!menu_isOpen(MENU_MAIN) &&
731 (player_isFlag(PLAYER_DESTROYED) || player_isFlag(PLAYER_CREATING) ||
732 ((player.p != NULL) && pilot_isFlag(player.p,PILOT_DEAD)))) {
733 gl_viewport( 0., 0., SCREEN_W, SCREEN_H );
736 return;
737 }
738
739 /* Make sure player is valid. */
740 if (player.p == NULL)
741 return;
742
743 /* Cinematics mode. */
744 if (player_isFlag( PLAYER_CINEMATICS_GUI ))
745 return;
746
747 /*
748 * Countdown timers.
749 */
750 animation_dt += dt / dt_mod;
751 blink_pilot -= dt / dt_mod;
752 if (blink_pilot < 0.)
754 blink_spob -= dt / dt_mod;
755 if (blink_spob < 0.)
757
758 /* Render the border ships and targets. */
760
761 /* Set viewport. */
762 gl_viewport( 0., 0., gl_screen.rw, gl_screen.rh );
763
764 /* Run Lua. */
765 if (gui_env != LUA_NOREF) {
766 if (gui_prepFunc( gui_lua_render, "render" )==0) {
767 lua_pushnumber( naevL, dt );
768 lua_pushnumber( naevL, dt_mod );
769 gui_runFunc( "render", 2, 0 );
770 }
771 if (pilot_isFlag(player.p, PILOT_COOLDOWN)) {
772 if (gui_prepFunc( gui_lua_render_cooldown, "render_cooldown" )==0) {
773 lua_pushnumber( naevL, player.p->ctimer / player.p->cdelay );
774 lua_pushnumber( naevL, player.p->ctimer );
775 gui_runFunc( "render_cooldown", 2, 0 );
776 }
777 }
778 }
779
780 /* Messages. */
782
783 /* OSD. */
784 osd_render();
785
786 /* Noise when getting near a jump. */
787 if (player.p->nav_hyperspace >= 0) { /* hyperspace target */
788 /* Determine if we have to play the "enter hyperspace range" sound. */
790 if ((i != 0) && (i != can_jump))
791 if (!pilot_isFlag(player.p, PILOT_HYPERSPACE))
793 can_jump = i;
794 }
795
796 /* Determine if we need to fade in/out. */
797 fade = direction = 0.;
798 if (pilot_isFlag(player.p, PILOT_HYPERSPACE) &&
799 (player.p->ptimer < HYPERSPACE_FADEOUT)) {
800 fade = (HYPERSPACE_FADEOUT-player.p->ptimer) / HYPERSPACE_FADEOUT;
801 direction = VANGLE(player.p->solid.vel);
802 }
803 else if (pilot_isFlag(player.p, PILOT_HYP_END) &&
804 player.p->ptimer > 0.) {
805 fade = player.p->ptimer / HYPERSPACE_FADEIN;
806 direction = VANGLE(player.p->solid.vel) + M_PI;
807 }
808 /* Perform the fade. */
809 if (fade > 0.) {
810 mat4 projection = gl_view_matrix;
811
812 /* Set up the program. */
813 glUseProgram( shaders.jump.program );
814 glEnableVertexAttribArray( shaders.jump.vertex );
815 gl_vboActivateAttribOffset( gl_squareVBO, shaders.jump.vertex, 0, 2, GL_FLOAT, 0 );
816
817 /* Set up the projection. */
818 mat4_scale( &projection, gl_screen.nw, gl_screen.nh, 1. );
819
820 /* Pass stuff over. */
821 gl_uniformMat4( shaders.jump.projection, &projection );
822 glUniform1f( shaders.jump.progress, fade );
823 glUniform1f( shaders.jump.direction, direction );
824 glUniform2f( shaders.jump.dimensions, gl_screen.nw, gl_screen.nh );
825 glUniform1f( shaders.jump.brightness, conf.jump_brightness );
826
827 /* Set the subroutine. */
828 if (gl_has( OPENGL_SUBROUTINES )) {
829 if (cur_system->nebu_density > 0.)
830 glUniformSubroutinesuiv( GL_FRAGMENT_SHADER, 1, &shaders.jump.jump_func.jump_nebula );
831 else
832 glUniformSubroutinesuiv( GL_FRAGMENT_SHADER, 1, &shaders.jump.jump_func.jump_wind );
833 }
834
835 /* Draw. */
836 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
837
838 /* Clear state. */
839 glDisableVertexAttribArray( shaders.jump.vertex );
840 glUseProgram(0);
841
842 /* Check errors. */
843 gl_checkErr();
844 }
845
846 /* Reset viewport. */
848
849 /* Render messages. */
850 omsg_render( dt );
851}
852
857{
858 gui_doFunc( gui_lua_cooldown_end, "cooldown_end" );
859}
860
868int gui_radarInit( int circle, int w, int h )
869{
870 gui_radar.shape = circle ? RADAR_CIRCLE : RADAR_RECT;
871 gui_radar.w = w;
872 gui_radar.h = h;
874 return 0;
875}
876
883void gui_radarRender( double x, double y )
884{
885 int f;
886 Radar *radar;
887 mat4 view_matrix_prev;
888 Pilot *const* pilot_stack;
889
890 if (!conf.always_radar && ovr_isOpen())
891 return;
892
893 /* The global radar. */
894 radar = &gui_radar;
895 gui_radar.x = x;
896 gui_radar.y = y;
897
898 /* TODO: modifying gl_view_matrix like this is a bit of a hack */
899 /* TODO: use stencil test for RADAR_CIRCLE */
900 view_matrix_prev = gl_view_matrix;
901 if (radar->shape==RADAR_RECT) {
902 gl_clipRect( x, y, radar->w, radar->h );
903 mat4_translate( &gl_view_matrix,
904 x + radar->w/2., y + radar->h/2., 0 );
905 }
906 else if (radar->shape==RADAR_CIRCLE)
907 mat4_translate( &gl_view_matrix,
908 x, y, 0 );
909
910 /*
911 * spobs
912 */
913 for (int i=0; i<array_size(cur_system->spobs); i++)
914 if (i != player.p->nav_spob)
915 gui_renderSpob( i, radar->shape, radar->w, radar->h, radar->res, 1., 0 );
916 if (player.p->nav_spob > -1)
917 gui_renderSpob( player.p->nav_spob, radar->shape, radar->w, radar->h, radar->res, 1., 0 );
918
919 /*
920 * Jump points.
921 */
922 for (int i=0; i<array_size(cur_system->jumps); i++) {
923 JumpPoint *jp = &cur_system->jumps[i];
924 if (i != player.p->nav_hyperspace && jp_isUsable(jp))
925 gui_renderJumpPoint( i, radar->shape, radar->w, radar->h, radar->res, 1., 0 );
926 }
927 if (player.p->nav_hyperspace > -1)
928 gui_renderJumpPoint( player.p->nav_hyperspace, radar->shape, radar->w, radar->h, radar->res, 1., 0 );
929
930 /*
931 * weapons
932 */
933 weapon_minimap( radar->res, radar->w, radar->h,
934 radar->shape, 1. );
935
936 /* render the pilot */
938 f = 0;
939 for (int i=1; i<array_size(pilot_stack); i++) { /* skip the player */
940 if (pilot_stack[i]->id == player.p->target)
941 f = i;
942 else
943 gui_renderPilot( pilot_stack[i], radar->shape, radar->w, radar->h, radar->res, 0 );
944 }
945 /* render the targeted pilot */
946 if (f != 0)
947 gui_renderPilot( pilot_stack[f], radar->shape, radar->w, radar->h, radar->res, 0 );
948
949 /* Render the asteroids */
950 for (int i=0; i<array_size(cur_system->asteroids); i++) {
952 double range = EW_ASTEROID_DIST * player.p->stats.ew_detect; /* TODO don't hardcode. */
953 int ax, ay, r;
954 ax = round(player.p->solid.pos.x);
955 ay = round(player.p->solid.pos.y);
956 r = ceil(range);
957 asteroid_collideQueryIL( ast, &gui_qtquery, ax-r, ay-r, ax+r, ay+r );
958 for (int j=0; j<il_size(&gui_qtquery); j++) {
959 const Asteroid *a = &ast->asteroids[ il_get( &gui_qtquery, j, 0 ) ];
960 gui_renderAsteroid( a, radar->w, radar->h, radar->res, 0 );
961 }
962 }
963
964 /* Render the player. */
965 gui_renderPlayer( radar->res, 0 );
966
967 /* Undo the horrible hack. */
968 gl_view_matrix = view_matrix_prev;
969 if (radar->shape==RADAR_RECT)
971}
972
978void gui_radarGetRes( double* res )
979{
980 *res = gui_radar.res;
981}
982
987{
988 for (int i=0; i < mesg_max; i++)
989 free( mesg_stack[i].str );
990 memset( mesg_stack, 0, sizeof(Mesg)*mesg_max );
991}
992
998static void gui_renderMessages( double dt )
999{
1000 double x, y, h, hs, vx, vy, dy;
1001 int v, o;
1002 glColour c = {.r=1., .g=1., .b=1.};
1003 const glColour msgc = {.r=0., .g=0., .b=0., .a=0.6};
1004
1005 /* Coordinate translation. */
1006 x = gui_mesg_x;
1007 y = gui_mesg_y;
1008
1009 /* Handle viewpoint hacks. */
1010 v = mesg_viewpoint;
1011 if (v == -1)
1012 v = mesg_pointer;
1013
1014 /* Render background. */
1015 h = 0;
1016
1017 /* Set up position. */
1018 vx = x;
1019 vy = y;
1020
1021 /* Must be run here. */
1022 hs = 0.;
1023 o = 0;
1024 if (mesg_viewpoint != -1) {
1025 /* Data. */
1026 hs = h*(double)conf.mesg_visible/(double)mesg_max;
1028 if (o < 0)
1029 o += mesg_max;
1030 }
1031
1032 /* Render text. */
1033 for (int i=0; i<conf.mesg_visible; i++) {
1034 /* Reference translation. */
1035 int m = (v - i) % mesg_max;
1036 if (m < 0)
1037 m += mesg_max;
1038
1039 /* Timer handling. */
1040 if ((mesg_viewpoint != -1) || (mesg_stack[m].t >= 0.)) {
1041 /* Decrement timer. */
1042 if (mesg_viewpoint == -1)
1043 mesg_stack[m].t -= dt / dt_mod;
1044
1045 /* Only handle non-NULL messages. */
1046 if (mesg_stack[m].str != NULL) {
1047 if (mesg_stack[m].str[0] == '\t') {
1048 gl_printRestore( &mesg_stack[m].restore );
1049 dy = gl_printHeightRaw( &gl_smallFont, gui_mesg_w, &mesg_stack[m].str[1]) + 6;
1050 gl_renderRect( x-4., y-1., gui_mesg_w-13., dy, &msgc );
1051 gl_printMaxRaw( &gl_smallFont, gui_mesg_w - 45., x + 30, y + 3, &cFontWhite, -1., &mesg_stack[m].str[1] );
1052 } else {
1054 gl_renderRect( x-4., y-1., gui_mesg_w-13., dy, &msgc );
1055 gl_printMaxRaw( &gl_smallFont, gui_mesg_w - 15., x, y + 3, &cFontWhite, -1., mesg_stack[m].str );
1056 }
1057 h += dy;
1058 y += dy;
1059 }
1060 }
1061
1062 /* Increase position. */
1063 }
1064
1065 /* Render position. */
1066 if (mesg_viewpoint != -1) {
1067 /* Border. */
1068 c.a = 0.2;
1069 gl_renderRect( vx + gui_mesg_w-10., vy, 10, h, &c );
1070
1071 /* Inside. */
1072 c.a = 0.5;
1073 gl_renderRect( vx + gui_mesg_w-10., vy + hs/2. + (h-hs)*((double)o/(double)(mesg_max-conf.mesg_visible)), 10, hs, &c );
1074 }
1075}
1076
1085static const glColour* gui_getPilotColour( const Pilot* p )
1086{
1087 const glColour *col;
1088
1089 if (p->id == player.p->target)
1090 col = &cRadar_tPilot;
1091 else
1092 col = pilot_getColour(p);
1093
1094 return col;
1095}
1096
1107void gui_renderPilot( const Pilot* p, RadarShape shape, double w, double h, double res, int overlay )
1108{
1109 double x, y, scale, ssize;
1110 const glColour *col;
1111 int scanning;
1112
1113 /* Make sure is in range. */
1114 if (!pilot_validTarget( player.p, p ))
1115 return;
1116
1117 /* Get position. */
1118 if (overlay) {
1119 x = (p->solid.pos.x / res);
1120 y = (p->solid.pos.y / res);
1121 }
1122 else {
1123 x = ((p->solid.pos.x - player.p->solid.pos.x) / res);
1124 y = ((p->solid.pos.y - player.p->solid.pos.y) / res);
1125 }
1126 /* Get size. */
1127 ssize = sqrt( (double)ship_size( p->ship ) );
1128 scale = (ssize + 1.)/2. * (1. + RADAR_RES_REF / res );
1129
1130 /* Check if pilot in range. */
1131 if ( ((shape==RADAR_RECT) &&
1132 ((ABS(x) > (w+scale)/2.) || (ABS(y) > (h+scale)/2.)) ) ||
1133 ((shape==RADAR_CIRCLE) &&
1134 ((pow2(x)+pow2(y)) > pow2(w))) ) {
1135
1136 /* Draw little targeted symbol. */
1137 if (p->id == player.p->target && !overlay)
1138 gui_renderRadarOutOfRange( shape, w, h, x, y, &cRadar_tPilot );
1139 return;
1140 }
1141
1142 /* Transform coordinates into the 0,0 -> SCREEN_W, SCREEN_H range. */
1143 if (overlay) {
1144 double ox, oy;
1145 ovr_center( &ox, &oy );
1146 x += ox;
1147 y += oy;
1148 }
1149
1150 if (p->id == player.p->target)
1151 col = &cRadar_hilight;
1152 else
1153 col = gui_getPilotColour(p);
1154
1155 scale = MAX(scale+2.0, 3.5+ssize); /* Compensate for outline. */
1156 scanning = (pilot_isFlag(p,PILOT_SCANNING) && (p->target==PLAYER_ID));
1157
1158 if (pilot_isFlag(p, PILOT_HILIGHT) || scanning) {
1159 glColour highlighted = cRadar_hilight;
1160 highlighted.a = 0.3;
1161 glUseProgram( shaders.hilight.program );
1162 glUniform1f( shaders.hilight.dt, animation_dt );
1163 gl_renderShader( x, y, scale*2.0, scale*2.0, 0., &shaders.hilight, &highlighted, 1 );
1164 }
1165
1166 glUseProgram(shaders.pilotmarker.program);
1167 gl_renderShader( x, y, scale, scale, p->solid.dir, &shaders.pilotmarker, col, 1 );
1168
1169 /* Draw selection if targeted. */
1170 if (p->id == player.p->target)
1171 gui_blink( x, y, MAX(scale*2.,10.0), &cRadar_hilight, RADAR_BLINK_PILOT, blink_pilot);
1172
1173 /* Draw name. */
1174 if (overlay && pilot_isFlag(p, PILOT_HILIGHT)) {
1175 /* TODO try to minimize overlap here. */
1176 gl_printMarkerRaw( &gl_smallFont, x+scale+5., y-gl_smallFont.h/2., col, p->name );
1177 if (scanning) {
1178 glUseProgram( shaders.pilotscanning.program );
1179 gl_renderShader( x+scale+3., y+scale+gl_smallFont.h/2.+3., 5., 5., 1.5*animation_dt, &shaders.pilotscanning, col, 1 );
1180 }
1181 }
1182 else {
1183 /* Draw scanning icon. */
1184 if (scanning) {
1185 glUseProgram( shaders.pilotscanning.program );
1186 gl_renderShader( x+scale+3., y+scale+3., 5., 5., 1.5*animation_dt, &shaders.pilotscanning, col, 1 );
1187 }
1188 }
1189}
1190
1200void gui_renderAsteroid( const Asteroid* a, double w, double h, double res, int overlay )
1201{
1202 int i, j, targeted;
1203 double x, y, r, sx, sy;
1204 double px, py;
1205 const glColour *col;
1206
1207 /* Skip invisible asteroids */
1208 if (a->state != ASTEROID_FG)
1209 return;
1210
1211 /* Recover the asteroid and field IDs. */
1212 i = a->id;
1213 j = a->parent;
1214
1215 /* Make sure is in range. */
1216 if (!pilot_inRangeAsteroid( player.p, i, j ))
1217 return;
1218
1219 /* Get position. */
1220 if (overlay) {
1221 x = (a->sol.pos.x / res);
1222 y = (a->sol.pos.y / res);
1223 }
1224 else {
1225 x = ((a->sol.pos.x - player.p->solid.pos.x) / res);
1226 y = ((a->sol.pos.y - player.p->solid.pos.y) / res);
1227 }
1228
1229 /* Get size. */
1230 sx = 1.;
1231 sy = 1.;
1232
1233 /* Transform coordinates into the 0,0 -> SCREEN_W, SCREEN_H range. */
1234 if (overlay) {
1235 double ox, oy;
1236 ovr_center( &ox, &oy );
1237 x += ox;
1238 y += oy;
1239 w *= 2.;
1240 h *= 2.;
1241 }
1242
1243 /* Draw square. */
1244 px = MAX(x-sx, -w);
1245 py = MAX(y-sy, -h);
1246
1247 targeted = ((i==player.p->nav_asteroid) && (j==player.p->nav_anchor));
1248
1249 /* Colour depends if the asteroid is selected. */
1250 if (targeted)
1251 col = &cWhite;
1252 else
1253 col = &cGrey70;
1254
1255 //gl_renderRect( px, py, MIN( 2*sx, w-px ), MIN( 2*sy, h-py ), col );
1256 r = (sx+sy)/2.0+1.5;
1257 glUseProgram(shaders.asteroidmarker.program);
1258 gl_renderShader( px, py, r, r, 0., &shaders.asteroidmarker, col, 1 );
1259
1260 if (targeted)
1261 gui_blink( px, py, MAX(7., 2.0*r), col, RADAR_BLINK_PILOT, blink_pilot );
1262}
1263
1267void gui_renderPlayer( double res, int overlay )
1268{
1269 double x, y, r;
1270
1271 /* Based on gui_renderPilot but with larger fixed size (4x normal ship, but
1272 * the shader is actually quite smaller so it ends up being just a bit
1273 * larger than a capital ship.. */
1274 r = (sqrt(24.) + 1.)/2. * (1. + RADAR_RES_REF / res );
1275 if (overlay) {
1276 double ox, oy;
1277 ovr_center( &ox, &oy );
1278 x = player.p->solid.pos.x / res + ox;
1279 y = player.p->solid.pos.y / res + oy;
1280 r = MAX( 17., r );
1281 } else {
1282 x = y = 0.;
1283 r = MAX( 11., r );
1284 }
1285
1286 glUseProgram(shaders.playermarker.program);
1287 gl_renderShader( x, y, r, r, player.p->solid.dir, &shaders.playermarker, &cRadar_player, 1 );
1288}
1289
1296static const glColour *gui_getSpobColour( int i )
1297{
1298 const glColour *col;
1299 Spob *spob = cur_system->spobs[i];
1300
1301 if (i == player.p->nav_spob)
1302 col = &cRadar_tSpob;
1303 else
1304 col = spob_getColour( spob );
1305
1306 return col;
1307}
1308
1313{
1314 blink_pilot = 0.;
1315 blink_spob = 0.;
1316}
1317
1321static void gui_blink( double cx, double cy, double vr, const glColour *col, double blinkInterval, double blinkVar )
1322{
1323 if (blinkVar > blinkInterval/2.)
1324 return;
1325 glUseProgram(shaders.blinkmarker.program);
1326 gl_renderShader( cx, cy, vr, vr, 0., &shaders.blinkmarker, col, 1 );
1327}
1328
1332static void gui_renderRadarOutOfRange( RadarShape sh, int w, int h, int cx, int cy, const glColour *col )
1333{
1334 double a, x, y, x2, y2;
1335
1336 /* Draw a line like for pilots. */
1337 a = ANGLE(cx,cy);
1338 if (sh == RADAR_CIRCLE) {
1339 x = w * cos(a);
1340 y = w * sin(a);
1341 }
1342 else {
1343 int cxa, cya;
1344 cxa = ABS(cx);
1345 cya = ABS(cy);
1346 /* Determine position. */
1347 if (cy >= cxa) { /* Bottom */
1348 x = w/2. * (cx*1./cy);
1349 y = h/2.;
1350 } else if (cx >= cya) { /* Left */
1351 x = w/2.;
1352 y = h/2. * (cy*1./cx);
1353 } else if (cya >= cxa) { /* Top */
1354 x = -w/2. * (cx*1./cy);
1355 y = -h/2.;
1356 } else { /* Right */
1357 x = -w/2.;
1358 y = -h/2. * (cy*1./cx);
1359 }
1360 }
1361 x2 = x - .15 * w * cos(a);
1362 y2 = y - .15 * w * sin(a);
1363
1364 gl_renderLine( x, y, x2, y2, col );
1365}
1366
1372void gui_renderSpob( int ind, RadarShape shape, double w, double h, double res, double alpha, int overlay )
1373{
1374 GLfloat cx, cy, x, y, r, vr;
1375 glColour col;
1376 Spob *spob;
1377 const SimpleShader *shd;
1378 char buf[STRMAX_SHORT];
1379
1380 /* Make sure is known. */
1381 if (!spob_isKnown( cur_system->spobs[ind] ))
1382 return;
1383
1384 /* Default values. */
1385 spob = cur_system->spobs[ind];
1386 r = spob->radius / res;
1387 vr = overlay ? spob->mo.radius : MAX( r, 7.5 );
1388
1389 if (overlay) {
1390 cx = spob->pos.x / res;
1391 cy = spob->pos.y / res;
1392 }
1393 else {
1394 cx = (spob->pos.x - player.p->solid.pos.x) / res;
1395 cy = (spob->pos.y - player.p->solid.pos.y) / res;
1396 }
1397
1398 /* Check if in range. */
1399 if (shape == RADAR_CIRCLE) {
1400 x = ABS(cx)-r;
1401 y = ABS(cy)-r;
1402 /* Out of range. */
1403 if (x*x + y*y > pow2(w-2*r)) {
1404 if ((player.p->nav_spob == ind) && !overlay)
1405 gui_renderRadarOutOfRange( RADAR_CIRCLE, w, w, cx, cy, &cRadar_tSpob );
1406 return;
1407 }
1408 }
1409 else {
1410 if (shape == RADAR_RECT) {
1411 /* Out of range. */
1412 if ((ABS(cx) - r > w/2.) || (ABS(cy) - r > h/2.)) {
1413 if ((player.p->nav_spob == ind) && !overlay)
1414 gui_renderRadarOutOfRange( RADAR_RECT, w, h, cx, cy, &cRadar_tSpob );
1415 return;
1416 }
1417 }
1418 }
1419
1420 if (overlay) {
1421 double ox, oy;
1422 ovr_center( &ox, &oy );
1423 /* Transform coordinates. */
1424 cx += ox;
1425 cy += oy;
1426 w *= 2.;
1427 h *= 2.;
1428 }
1429
1430 /* Scale according to marker. */
1431 vr *= spob->marker_scale;
1432
1433 /* Is marked. */
1434 if (spob_isKnown( spob ) && spob_isFlag( spob, SPOB_MARKED )) {
1435 glColour highlighted = cRadar_hilight;
1436 highlighted.a = 0.3;
1437 glUseProgram( shaders.hilight.program );
1438 glUniform1f( shaders.hilight.dt, animation_dt );
1439 gl_renderShader( cx, cy, vr*3.0, vr*3.0, 0., &shaders.hilight, &highlighted, 1 );
1440 }
1441
1442 /* Get the colour. */
1443 col = *gui_getSpobColour(ind);
1444 col.a *= alpha;
1445
1446 /* Do the blink. */
1447 if (ind == player.p->nav_spob)
1448 gui_blink( cx, cy, vr*2., &col, RADAR_BLINK_SPOB, blink_spob);
1449
1450 if (spob->marker != NULL)
1451 shd = spob->marker;
1452 else if (spob_hasService(spob,SPOB_SERVICE_LAND))
1453 shd = &shaders.spobmarker_earth;
1454 else
1455 shd = &shaders.spobmarker_empty;
1456
1457 glUseProgram(shd->program);
1458 gl_renderShader( cx, cy, vr, vr, 0., shd, &col, 1 );
1459
1460 if (overlay) {
1461 snprintf( buf, sizeof(buf), "%s%s", spob_getSymbol(spob), spob_name(spob) );
1462 gl_printMarkerRaw( &gl_smallFont, cx+spob->mo.text_offx, cy+spob->mo.text_offy, &col, buf );
1463 }
1464}
1465
1477void gui_renderJumpPoint( int ind, RadarShape shape, double w, double h, double res, double alpha, int overlay )
1478{
1479 GLfloat cx, cy, x, y, r, vr;
1480 glColour col;
1481 char buf[STRMAX_SHORT];
1482 StarSystem *s;
1483 JumpPoint *jp = &cur_system->jumps[ind];
1484
1485 /* Check if known */
1486 if (!jp_isUsable(jp))
1487 return;
1488
1489 /* Default values. */
1490 r = jumppoint_gfx->sw/2. / res;
1491 vr = overlay ? jp->mo.radius : MAX( r, 5. );
1492 if (overlay) {
1493 cx = jp->pos.x / res;
1494 cy = jp->pos.y / res;
1495 }
1496 else {
1497 cx = (jp->pos.x - player.p->solid.pos.x) / res;
1498 cy = (jp->pos.y - player.p->solid.pos.y) / res;
1499 }
1500
1501 /* Check if in range. */
1502 if (shape == RADAR_RECT) {
1503 /* Out of range. */
1504 if ((ABS(cx) - r > w/2.) || (ABS(cy) - r > h/2.)) {
1505 if ((player.p->nav_hyperspace == ind) && !overlay)
1506 gui_renderRadarOutOfRange( RADAR_RECT, w, h, cx, cy, &cRadar_tSpob );
1507 return;
1508 }
1509 }
1510 else if (shape == RADAR_CIRCLE) {
1511 x = ABS(cx)-r;
1512 y = ABS(cy)-r;
1513 /* Out of range. */
1514 if (x*x + y*y > pow2(w-2*r)) {
1515 if ((player.p->nav_hyperspace == ind) && !overlay)
1516 gui_renderRadarOutOfRange( RADAR_CIRCLE, w, w, cx, cy, &cRadar_tSpob );
1517 return;
1518 }
1519 }
1520
1521 if (overlay) {
1522 double ox, oy;
1523 ovr_center( &ox, &oy );
1524 /* Transform coordinates. */
1525 cx += ox;
1526 cy += oy;
1527 }
1528
1529 /* See if far side is marked. */
1530 s = jp->target;
1531 if (sys_isMarked(s)) {
1532 glColour highlighted = cRadar_hilight;
1533 highlighted.a = 0.3;
1534 glUseProgram( shaders.hilight.program );
1535 glUniform1f( shaders.hilight.dt, animation_dt );
1536 gl_renderShader( cx, cy, vr*3.0, vr*3.0, 0., &shaders.hilight, &highlighted, 1 );
1537 }
1538
1539 if (ind == player.p->nav_hyperspace)
1540 col = cWhite;
1541 else if (jp_isFlag(jp, JP_HIDDEN))
1542 col = cRed;
1543 else
1544 col = cGreen;
1545 col.a *= alpha;
1546
1547 glUseProgram(shaders.jumpmarker.program);
1548 gl_renderShader( cx, cy, vr*1.5, vr*1.5, M_PI-jp->angle, &shaders.jumpmarker, &col, 1 );
1549
1550 /* Blink ontop. */
1551 if (ind == player.p->nav_hyperspace)
1552 gui_blink( cx, cy, vr*3., &col, RADAR_BLINK_SPOB, blink_spob );
1553
1554 /* Render name. */
1555 if (overlay) {
1556 snprintf(
1557 buf, sizeof(buf), "%s%s", jump_getSymbol(jp),
1558 sys_isKnown(jp->target) ? _(jp->target->name) : _("Unknown") );
1559 gl_printMarkerRaw( &gl_smallFont, cx+jp->mo.text_offx, cy+jp->mo.text_offy, &col, buf );
1560 }
1561}
1562
1566void gui_setViewport( double x, double y, double w, double h )
1567{
1568 gui_viewport_x = x;
1569 gui_viewport_y = y;
1570 gui_viewport_w = w;
1571 gui_viewport_h = h;
1572
1573 /* We now set the viewport. */
1576
1577 /* Run border calculations. */
1579}
1580
1585{
1588}
1589
1593static void gui_calcBorders (void)
1594{
1595 double w,h;
1596
1597 /* Precalculations. */
1598 w = SCREEN_W/2.;
1599 h = SCREEN_H/2.;
1600
1601 /*
1602 * Borders.
1603 */
1604 gui_tl = atan2( +h, -w );
1605 if (gui_tl < 0.)
1606 gui_tl += 2*M_PI;
1607 gui_tr = atan2( +h, +w );
1608 if (gui_tr < 0.)
1609 gui_tr += 2*M_PI;
1610 gui_bl = atan2( -h, -w );
1611 if (gui_bl < 0.)
1612 gui_bl += 2*M_PI;
1613 gui_br = atan2( -h, +w );
1614 if (gui_br < 0.)
1615 gui_br += 2*M_PI;
1616}
1617
1623int gui_init (void)
1624{
1625 /* radar */
1627
1628 /* Messages */
1629 gui_mesg_x = 20;
1630 gui_mesg_y = 30;
1631 gui_mesg_w = SCREEN_W - 400;
1632 if (mesg_stack == NULL) {
1633 mesg_stack = calloc(mesg_max, sizeof(Mesg));
1634 if (mesg_stack == NULL) {
1635 ERR(_("Out of Memory"));
1636 return -1;
1637 }
1638 }
1639
1640 /* VBO. */
1641 if (gui_radar_select_vbo == NULL) {
1642 GLfloat vertex[16];
1643 vertex[0] = -1.5;
1644 vertex[1] = 1.5;
1645 vertex[2] = -3.3;
1646 vertex[3] = 3.3;
1647 vertex[4] = 1.5;
1648 vertex[5] = 1.5;
1649 vertex[6] = 3.3;
1650 vertex[7] = 3.3;
1651 vertex[8] = 1.5;
1652 vertex[9] = -1.5;
1653 vertex[10] = 3.3;
1654 vertex[11] = -3.3;
1655 vertex[12] = -1.5;
1656 vertex[13] = -1.5;
1657 vertex[14] = -3.3;
1658 vertex[15] = -3.3;
1659 gui_radar_select_vbo = gl_vboCreateStatic( sizeof(GLfloat) * 16, vertex );
1660 }
1661
1662 /* OSD */
1663 osd_setup( 30., SCREEN_H-90., 150., 300. );
1664
1665 /* Set viewport. */
1667
1668 /* Icons. */
1669 gui_ico_hail = gl_newSprite( GUI_GFX_PATH"hail.webp", 5, 2, 0 );
1670
1671 /* Quadtrees. */
1672 il_create( &gui_qtquery, 1 );
1673
1674 return 0;
1675}
1676
1684static int gui_doFunc( int func_ref, const char *func_name )
1685{
1686 int ret;
1687 if (gui_env == LUA_NOREF)
1688 return -1;
1689
1690 ret = gui_prepFunc( func_ref, func_name );
1691 if (ret)
1692 return ret;
1693 return gui_runFunc( func_name, 0, 0 );
1694}
1695
1703static int gui_prepFunc( int func_ref, const char *func_name )
1704{
1705 (void) func_name;
1706#if DEBUGGING
1707 if (gui_env == LUA_NOREF) {
1708 WARN( _("GUI '%s': Trying to run GUI func '%s' but no GUI is loaded!"), gui_name, func_name );
1709 return -1;
1710 }
1711#endif /* DEBUGGING */
1712
1713 /* Must have a player. */
1714 if (player_isFlag(PLAYER_DESTROYED) || player_isFlag(PLAYER_CREATING) ||
1715 (player.p == NULL) || pilot_isFlag(player.p,PILOT_DEAD)) {
1716 return -1;
1717 }
1718
1719 /* Set up function. */
1720 lua_rawgeti( naevL, LUA_REGISTRYINDEX, func_ref );
1721#if DEBUGGING
1722 if (lua_isnil( naevL, -1 )) {
1723 WARN(_("GUI '%s': no function '%s' defined!"), gui_name, func_name );
1724 lua_pop(naevL,1);
1725 return -1;
1726 }
1727#endif /* DEBUGGING */
1728 return 0;
1729}
1730
1738static int gui_runFunc( const char* func, int nargs, int nret )
1739{
1740 /* Run the function. */
1741 int ret = nlua_pcall( gui_env, nargs, nret );
1742 if (ret != 0) { /* error has occurred */
1743 const char *err = (lua_isstring(naevL,-1)) ? lua_tostring(naevL,-1) : NULL;
1744 WARN(_("GUI '%s' Lua -> '%s': %s"), gui_name,
1745 func, (err) ? err : _("unknown error"));
1746 lua_pop(naevL,1);
1747 return ret;
1748 }
1749
1750 return ret;
1751}
1752
1756void gui_reload (void)
1757{
1758 if (gui_env == LUA_NOREF)
1759 return;
1760
1761 gui_load( gui_pick() );
1762}
1763
1767void gui_setCargo (void)
1768{
1769 gui_doFunc( gui_lua_update_cargo, "update_cargo" );
1770}
1771
1775void gui_setNav (void)
1776{
1777 gui_doFunc( gui_lua_update_nav, "update_nav" );
1778}
1779
1783void gui_setTarget (void)
1784{
1785 gui_doFunc( gui_lua_update_target, "update_target" );
1786}
1787
1791void gui_setShip (void)
1792{
1793 gui_doFunc( gui_lua_update_ship, "update_ship" );
1794}
1795
1799void gui_setSystem (void)
1800{
1801 gui_doFunc( gui_lua_update_system, "update_system" );
1802}
1803
1808{
1809 if (player.p != NULL && player.p->nav_spob != -1)
1810 gui_doFunc( gui_lua_update_faction, "update_faction" );
1811}
1812
1813void gui_updateEffects (void)
1814{
1815 if (player.p != NULL)
1816 gui_doFunc( gui_lua_update_effects, "update_effects" );
1817}
1818
1824void gui_setGeneric( const Pilot* pilot )
1825{
1826 if (gui_env == LUA_NOREF)
1827 return;
1828
1829 if (player_isFlag(PLAYER_DESTROYED) || player_isFlag(PLAYER_CREATING) ||
1830 (player.p == NULL) || pilot_isFlag(player.p,PILOT_DEAD))
1831 return;
1832
1833 if ((player.p->target != PLAYER_ID) && (pilot->id == player.p->target))
1834 gui_setTarget();
1835 else if (pilot_isPlayer(pilot)) {
1836 gui_setCargo();
1837 gui_setShip();
1838 }
1839}
1840
1844const char* gui_pick (void)
1845{
1846 const char* gui;
1847 /* Don't do set a gui if player is dead. This can be triggered through
1848 * naev_resize and can cause an issue if player is dead. */
1849 if ((player.p == NULL) || pilot_isFlag(player.p,PILOT_DEAD))
1850 gui = NULL;
1851 else if (player.gui != NULL)
1852 gui = player.gui;
1853 else
1854 gui = start_gui();
1855 return gui;
1856}
1857
1863int gui_exists( const char *name )
1864{
1865 char path[PATH_MAX];
1866 snprintf( path, sizeof(path), GUI_PATH"%s.lua", name );
1867 return PHYSFS_exists( path );
1868}
1869
1876int gui_load( const char *name )
1877{
1878 char *buf, path[PATH_MAX];
1879 size_t bufsize;
1880
1881 /* Set defaults. */
1882 gui_cleanup();
1883 if (name==NULL)
1884 return 0;
1885 gui_name = strdup(name);
1886
1887 /* Open file. */
1888 snprintf( path, sizeof(path), GUI_PATH"%s.lua", name );
1889 buf = ndata_read( path, &bufsize );
1890 if (buf == NULL) {
1891 WARN(_("Unable to find GUI '%s'."), path );
1892 return -1;
1893 }
1894
1895 /* Clean up. */
1896 nlua_freeEnv(gui_env);
1897 gui_env = LUA_NOREF;
1898
1899 /* Create Lua state. */
1900 gui_env = nlua_newEnv();
1905
1906 /* Run script. */
1907 if (nlua_dobufenv( gui_env, buf, bufsize, path ) != 0) {
1908 WARN(_("Failed to load GUI Lua: %s\n"
1909 "%s\n"
1910 "Most likely Lua file has improper syntax, please check"),
1911 path, lua_tostring(naevL,-1));
1912 nlua_freeEnv( gui_env );
1913 gui_env = LUA_NOREF;
1914 free(buf);
1915 return -1;
1916 }
1917 free(buf);
1918
1919 /* Load references. */
1920#define LUA_FUNC(funcname) gui_lua_##funcname = nlua_refenvtype( gui_env, #funcname, LUA_TFUNCTION );
1921 LUA_FUNC( create );
1922 LUA_FUNC( render );
1923 LUA_FUNC( render_cooldown );
1924 LUA_FUNC( cooldown_end );
1925 LUA_FUNC( mouse_move );
1926 LUA_FUNC( mouse_click );
1927 LUA_FUNC( update_cargo );
1928 LUA_FUNC( update_nav );
1929 LUA_FUNC( update_target );
1930 LUA_FUNC( update_ship );
1931 LUA_FUNC( update_system );
1932 LUA_FUNC( update_faction );
1933 LUA_FUNC( update_effects );
1934#undef LUA_FUNC
1935
1936 /* Run create function. */
1937 if (gui_doFunc( gui_lua_create, "create" )) {
1938 nlua_freeEnv( gui_env );
1939 gui_env = LUA_NOREF;
1940 }
1941
1942 /* Recreate land window if landed. */
1943 if (landed) {
1944 land_genWindows( 0 );
1946 }
1947
1948 return 0;
1949}
1950
1954void gui_cleanup (void)
1955{
1956 /* Disable mouse voodoo. */
1959
1960 /* Set the viewport. */
1962
1963 /* Set overlay bounds. */
1964 ovr_boundsSet( 0, 0, 0, 0 );
1965
1966 /* Reset FPS. */
1967 fps_setPos( 15., (double)(gl_screen.h-15-gl_defFontMono.h) );
1968
1969 /* Destroy offset. */
1970 gui_xoff = 0.;
1971 gui_yoff = 0.;
1972
1973 /* Destroy lua. */
1974 nlua_freeEnv( gui_env );
1975 gui_env = LUA_NOREF;
1976
1977 /* OMSG */
1978 omsg_position( SCREEN_W/2., SCREEN_H*2./3., SCREEN_W*2./3. );
1979
1980 /* Delete the name. */
1981 free(gui_name);
1982 gui_name = NULL;
1983
1984 /* Clear timers. */
1985 animation_dt = 0.;
1986
1987 /* Lua stuff. */
1988#define LUA_CLEANUP( varname ) if (varname!=LUA_NOREF) luaL_unref(naevL, LUA_REGISTRYINDEX, varname ); varname = LUA_NOREF
1989 LUA_CLEANUP( gui_lua_create );
1990 LUA_CLEANUP( gui_lua_render );
1991 LUA_CLEANUP( gui_lua_render_cooldown );
1992 LUA_CLEANUP( gui_lua_cooldown_end );
1993 LUA_CLEANUP( gui_lua_mouse_move );
1994 LUA_CLEANUP( gui_lua_mouse_click );
1995 LUA_CLEANUP( gui_lua_update_cargo );
1996 LUA_CLEANUP( gui_lua_update_nav );
1997 LUA_CLEANUP( gui_lua_update_target );
1998 LUA_CLEANUP( gui_lua_update_ship );
1999 LUA_CLEANUP( gui_lua_update_system );
2000 LUA_CLEANUP( gui_lua_update_faction );
2001 LUA_CLEANUP( gui_lua_update_effects );
2002#undef LUA_CLEANUP
2003}
2004
2008void gui_free (void)
2009{
2010 gui_cleanup();
2011
2012 for (int i = 0; i < mesg_max; i++)
2013 free( mesg_stack[i].str );
2014 free(mesg_stack);
2015 mesg_stack = NULL;
2016
2017 gl_vboDestroy( gui_radar_select_vbo );
2018 gui_radar_select_vbo = NULL;
2019
2020 osd_exit();
2021
2023 gui_ico_hail = NULL;
2025 gui_target_spob = NULL;
2027 gui_target_pilot = NULL;
2028
2029 il_destroy( &gui_qtquery );
2030
2031 omsg_cleanup();
2032}
2033
2039void gui_setRadarResolution( double res )
2040{
2041 gui_radar.res = CLAMP( RADAR_RES_MIN, RADAR_RES_MAX, res );
2042}
2043
2049void gui_setRadarRel( int mod )
2050{
2051 gui_radar.res += mod * RADAR_RES_INTERVAL;
2052 gui_setRadarResolution( gui_radar.res );
2053 player_message( _("#oRadar set to %.0fx.#0"), round(gui_radar.res) );
2054}
2055
2062void gui_getOffset( double *x, double *y )
2063{
2064 *x = gui_xoff;
2065 *y = gui_yoff;
2066}
2067
2072{
2073 return gui_ico_hail;
2074}
2075
2084
2093
2097static void gui_eventToScreenPos( int* sx, int* sy, int ex, int ey )
2098{
2099 gl_windowToScreenPos( sx, sy, ex, ey );
2100}
2101
2108int gui_radarClickEvent( SDL_Event* event )
2109{
2110 int mxr, myr, in_bounds;
2111 double x, y, cx, cy;
2112
2113 gui_eventToScreenPos( &mxr, &myr, event->button.x, event->button.y );
2114 if (gui_radar.shape == RADAR_RECT) {
2115 cx = gui_radar.x + gui_radar.w / 2.;
2116 cy = gui_radar.y + gui_radar.h / 2.;
2117 in_bounds = (2*ABS( mxr-cx ) <= gui_radar.w && 2*ABS( myr-cy ) <= gui_radar.h);
2118 }
2119 else {
2120 cx = gui_radar.x;
2121 cy = gui_radar.y;
2122 in_bounds = (pow2( mxr-cx ) + pow2( myr-cy ) <= pow2( gui_radar.w ));
2123 }
2124 if (!in_bounds)
2125 return 0;
2126 x = (mxr - cx) * gui_radar.res + player.p->solid.pos.x;
2127 y = (myr - cy) * gui_radar.res + player.p->solid.pos.y;
2128 return input_clickPos( event, x, y, 1., 10. * gui_radar.res, 15. * gui_radar.res );
2129}
2130
2137int gui_borderClickEvent( SDL_Event *event )
2138{
2139 unsigned int pid;
2140 double ang, angp, mouseang;
2141 int mx, my;
2142 int pntid, jpid, astid, fieid;
2143 double x, y;
2144 int autonav = (event->button.button == SDL_BUTTON_RIGHT) ? 1 : 0;
2145 double px = player.p->solid.pos.x;
2146 double py = player.p->solid.pos.y;
2147 gui_eventToScreenPos( &mx, &my, event->button.x, event->button.y );
2148 mx -= gui_viewport_x;
2149 my -= gui_viewport_y;
2150
2151 /* No intersection with border. */
2152 if (!((mx <= 15 || my <= 15 ) || (my >= gl_screen.h-15 || mx >= gl_screen.w-15)))
2153 return 0;
2154
2155 /* Border targeting is handled as a special case, as it uses angles,
2156 * not coordinates. */
2157 x = (mx - (gl_screen.w / 2.)) + px;
2158 y = (my - (gl_screen.h / 2.)) + py;
2159 mouseang = atan2(py - y, px - x);
2160 angp = pilot_getNearestAng( player.p, &pid, mouseang, 1 );
2161 ang = system_getClosestAng( cur_system, &pntid, &jpid, &astid, &fieid, x, y, mouseang );
2162
2163 if ((ABS(angle_diff(mouseang, angp)) > M_PI / 64) ||
2164 ABS(angle_diff(mouseang, ang)) < ABS(angle_diff(mouseang, angp)))
2165 pid = PLAYER_ID; /* Pilot angle is too great, or spob/jump is closer. */
2166 if (ABS(angle_diff(mouseang, ang)) > M_PI / 64 )
2167 jpid = pntid = astid = fieid = -1; /* Spob angle difference is too great. */
2168
2169 if (pid != PLAYER_ID) {
2170 if (input_clickedPilot(pid, autonav))
2171 return 1;
2172 }
2173 else if (pntid >= 0) { /* Spob is closest. */
2174 if (input_clickedSpob(pntid, autonav))
2175 return 1;
2176 }
2177 else if (jpid >= 0) { /* Jump point is closest. */
2178 if (input_clickedJump(jpid, autonav))
2179 return 1;
2180 }
2181 else if (astid >= 0) { /* Asteroid is closest. */
2182 if (input_clickedAsteroid(fieid, astid))
2183 return 1;
2184 }
2185
2186 return 0;
2187}
2188
2192int gui_handleEvent( SDL_Event *evt )
2193{
2194 int ret;
2195 int x, y;
2196
2197 if (player.p == NULL)
2198 return 0;
2199 if ((evt->type == SDL_MOUSEBUTTONDOWN) &&
2200 (pilot_isFlag(player.p,PILOT_HYP_PREP) ||
2201 pilot_isFlag(player.p,PILOT_HYP_BEGIN) ||
2202 pilot_isFlag(player.p,PILOT_HYPERSPACE)))
2203 return 0;
2204
2205 ret = 0;
2206 switch (evt->type) {
2207 /* Mouse motion. */
2208 case SDL_MOUSEMOTION:
2209 if (!gui_L_mmove)
2210 break;
2211 if (gui_prepFunc( gui_lua_mouse_move, "mouse_move" )==0) {
2212 gui_eventToScreenPos( &x, &y, evt->motion.x, evt->motion.y );
2213 lua_pushnumber( naevL, x );
2214 lua_pushnumber( naevL, y );
2215 gui_runFunc( "mouse_move", 2, 0 );
2216 }
2217 break;
2218
2219 /* Mouse click. */
2220 case SDL_MOUSEBUTTONDOWN:
2221 case SDL_MOUSEBUTTONUP:
2222 if (!gui_L_mclick)
2223 break;
2224 if (gui_prepFunc( gui_lua_mouse_click, "mouse_click" )==0) {
2225 lua_pushnumber( naevL, evt->button.button+1 );
2226 gui_eventToScreenPos( &x, &y, evt->button.x, evt->button.y );
2227 lua_pushnumber( naevL, x );
2228 lua_pushnumber( naevL, y );
2229 lua_pushboolean( naevL, (evt->type==SDL_MOUSEBUTTONDOWN) );
2230 gui_runFunc( "mouse_click", 4, 1 );
2231 ret = lua_toboolean( naevL, -1 );
2232 lua_pop( naevL, 1 );
2233 }
2234 break;
2235
2236 /* Not interested in the rest. */
2237 default:
2238 break;
2239 }
2240 return ret;
2241}
2242
2246void gui_mouseClickEnable( int enable )
2247{
2248 gui_L_mclick = enable;
2249}
2250
2254void gui_mouseMoveEnable( int enable )
2255{
2256 gui_L_mmove = enable;
2257}
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:168
double cam_getZoom(void)
Gets the camera zoom.
Definition camera.c:97
int gl_printHeightRaw(const glFont *ft_font, const int width, const char *text)
Gets the height of a non-formatted string.
Definition font.c:1027
void gl_printRestoreInit(glFontRestore *restore)
Initializes a restore structure.
Definition font.c:396
int gl_printLineIteratorNext(glPrintLineIterator *iter)
Updates iter with the next line's information.
Definition font.c:526
glFont gl_smallFont
Definition font.c:154
void gl_printRestore(const glFontRestore *restore)
Restores last colour from a restore structure.
Definition font.c:405
void gl_printLineIteratorInit(glPrintLineIterator *iter, const glFont *ft_font, const char *text, int width)
Initialize an iterator object for breaking text into lines.
Definition font.c:506
int gl_printMaxRaw(const glFont *ft_font, const int max, double x, double y, const glColour *c, double outlineR, const char *text)
Behaves like gl_printRaw but stops displaying text after a certain distance.
Definition font.c:721
glFont gl_defFontMono
Definition font.c:155
void gl_printStoreMax(glFontRestore *restore, const char *text, int max)
Stores the colour information from a piece of text limited to max characters.
Definition font.c:419
void gl_printMarkerRaw(const glFont *ft_font, double x, double y, const glColour *c, const char *text)
Wrapper for gl_printRaw for map overlay markers.
Definition font.c:673
static void gui_borderIntersection(double *cx, double *cy, double rx, double ry, double hw, double hh)
Gets the intersection with the border.
Definition gui.c:492
#define RADAR_BLINK_PILOT
Definition gui.c:70
static const int mesg_max
Definition gui.c:127
static int gui_mesg_w
Definition gui.c:142
static void gui_renderSpobTarget(void)
Sets up rendering of spob and jump point targeting reticles.
Definition gui.c:356
void gui_renderSpob(int ind, RadarShape shape, double w, double h, double res, double alpha, int overlay)
Draws the spobs in the minimap.
Definition gui.c:1372
int gui_radarClickEvent(SDL_Event *event)
Handles a click at a position in the current system.
Definition gui.c:2108
void gui_clearMessages(void)
Clears the GUI messages.
Definition gui.c:986
int gui_init(void)
Initializes the GUI system.
Definition gui.c:1623
static int gui_L_mmove
Definition gui.c:92
static double gui_yoff
Definition gui.c:124
static glTexture * gui_ico_hail
Definition gui.c:153
int gui_radarInit(int circle, int w, int h)
Initializes the radar.
Definition gui.c:868
void gui_setTarget(void)
Player just changed their pilot target.
Definition gui.c:1783
void gui_renderPlayer(double res, int overlay)
Renders the player cross on the radar or whatever.
Definition gui.c:1267
int gui_handleEvent(SDL_Event *evt)
Handles GUI events.
Definition gui.c:2192
static void gui_renderBorder(double dt)
Renders the ships/spobs in the border.
Definition gui.c:534
void gui_messageScrollDown(int lines)
Scrolls up the message box.
Definition gui.c:258
static int gui_prepFunc(int func_ref, const char *func_name)
Prepares to run a function.
Definition gui.c:1703
static Mesg * mesg_stack
Definition gui.c:141
glTexture * gui_hailIcon(void)
Gets the hail icon texture.
Definition gui.c:2071
void gui_setDefaults(void)
Definition gui.c:204
int gui_borderClickEvent(SDL_Event *event)
Handles clicks on the GUI border icons.
Definition gui.c:2137
unsigned int land_wid
Definition land.c:79
void gui_setSystem(void)
Player just changed their system.
Definition gui.c:1799
static int gui_mesg_x
Definition gui.c:143
static IntList gui_qtquery
Definition gui.c:83
const char * gui_pick(void)
Determines which GUI should be used.
Definition gui.c:1844
void gui_radarRender(double x, double y)
Renders the GUI radar.
Definition gui.c:883
void gui_setRadarRel(int mod)
Modifies the radar resolution.
Definition gui.c:2049
static void gui_eventToScreenPos(int *sx, int *sy, int ex, int ey)
Translates a mouse position from an SDL_Event to GUI coordinates.
Definition gui.c:2097
static void gui_renderRadarOutOfRange(RadarShape sh, int w, int h, int cx, int cy, const glColour *col)
Renders an out of range marker for the spob.
Definition gui.c:1332
void gui_renderAsteroid(const Asteroid *a, double w, double h, double res, int overlay)
Renders an asteroid in the GUI radar.
Definition gui.c:1200
#define RADAR_RES_INTERVAL
Definition gui.c:119
int gui_exists(const char *name)
Checks to see if a GUI exists.
Definition gui.c:1863
static int can_jump
Definition gui.c:719
static double gui_br
Definition gui.c:148
static double gui_tl
Definition gui.c:149
void gui_mouseMoveEnable(int enable)
Enables the mouse movement callback.
Definition gui.c:2254
void gui_messageScrollUp(int lines)
Scrolls up the message box.
Definition gui.c:229
static int mesg_viewpoint
Definition gui.c:129
void gui_mouseClickEnable(int enable)
Enables the mouse click callback.
Definition gui.c:2246
static const double mesg_timeout
Definition gui.c:130
static char * gui_name
Definition gui.c:82
void gui_updateFaction(void)
Player's relationship with a faction was modified.
Definition gui.c:1807
static void gui_renderMessages(double dt)
Renders the player's messages on screen.
Definition gui.c:998
int gui_load(const char *name)
Attempts to load the actual GUI.
Definition gui.c:1876
void gui_getOffset(double *x, double *y)
Gets the GUI offset.
Definition gui.c:2062
void weapon_minimap(const double res, const double w, const double h, const RadarShape shape, double alpha)
Draws the minimap weapons (used in player.c).
Definition weapon.c:204
static const glColour * gui_getSpobColour(int i)
Gets the colour of a spob.
Definition gui.c:1296
static double gui_xoff
Definition gui.c:123
void gui_targetPilotGFX(glTexture *gfx)
Sets the pilot target GFX.
Definition gui.c:2088
void gui_setShip(void)
Player just upgraded their ship or modified it.
Definition gui.c:1791
#define RADAR_RES_MAX
Definition gui.c:116
void gui_free(void)
Frees the gui stuff.
Definition gui.c:2008
void gui_messageInit(int width, int x, int y)
Initializes the message system.
Definition gui.c:217
void gui_clearViewport(void)
Resets the viewport.
Definition gui.c:1584
void gui_radarGetRes(double *res)
Outputs the radar's resolution.
Definition gui.c:978
void gui_reload(void)
Reloads the GUI.
Definition gui.c:1756
static double gui_tr
Definition gui.c:147
void gui_forceBlink(void)
Force sets the spob and pilot radar blink.
Definition gui.c:1312
int gui_onScreenPilot(double *rx, double *ry, const Pilot *pilot)
Takes a pilot and returns whether it's on screen, plus its relative position.
Definition gui.c:624
static double blink_pilot
Definition gui.c:74
static int gui_doFunc(int func_ref, const char *func_name)
Runs a GUI Lua function.
Definition gui.c:1684
static void gui_renderPilotTarget(void)
Renders the players pilot target.
Definition gui.c:439
void gui_cooldownEnd(void)
Notifies GUI scripts that the player broke out of cooldown.
Definition gui.c:856
static int gui_mesg_y
Definition gui.c:144
static const glColour * gui_getPilotColour(const Pilot *p)
Gets a pilot's colour, with a special colour for targets.
Definition gui.c:1085
void gui_renderJumpPoint(int ind, RadarShape shape, double w, double h, double res, double alpha, int overlay)
Renders a jump point on the minimap.
Definition gui.c:1477
int gui_onScreenSpob(double *rx, double *ry, const JumpPoint *jp, const Spob *pnt)
Takes a spob or jump point and returns whether it's on screen, plus its relative position.
Definition gui.c:661
void gui_cleanup(void)
Cleans up the GUI.
Definition gui.c:1954
void gui_renderPilot(const Pilot *p, RadarShape shape, double w, double h, double res, int overlay)
Renders a pilot in the GUI radar.
Definition gui.c:1107
static void gui_calcBorders(void)
Calculates and sets the GUI borders.
Definition gui.c:1593
static int mesg_pointer
Definition gui.c:128
static double gui_bl
Definition gui.c:150
static double gui_viewport_y
Definition gui.c:98
static int gui_runFunc(const char *func, int nargs, int nret)
Runs a function.
Definition gui.c:1738
#define RADAR_RES_MIN
Definition gui.c:118
void player_messageRaw(const char *str)
Adds a mesg to the queue to be displayed on screen.
Definition gui.c:298
#define RADAR_BLINK_SPOB
Definition gui.c:71
static int gui_getMessage
Definition gui.c:81
static double blink_spob
Definition gui.c:75
static void gui_blink(double cx, double cy, double vr, const glColour *col, double blinkInterval, double blinkVar)
Renders the spob blink around a position on the minimap.
Definition gui.c:1321
void gui_setNav(void)
Player just changed their nav computer target.
Definition gui.c:1775
void gui_renderReticles(double dt)
Renders the gui targeting reticles.
Definition gui.c:703
void gui_render(double dt)
Renders the player's GUI.
Definition gui.c:725
#define RADAR_RES_REF
Definition gui.c:117
void gui_setGeneric(const Pilot *pilot)
Calls trigger functions depending on who the pilot is.
Definition gui.c:1824
static glTexture * gui_target_spob
Definition gui.c:154
void gui_targetSpobGFX(glTexture *gfx)
Sets the spob target GFX.
Definition gui.c:2079
static double gui_viewport_w
Definition gui.c:99
void gui_setViewport(double x, double y, double w, double h)
Sets the viewport.
Definition gui.c:1566
static void gui_renderTargetReticles(const SimpleShader *shd, double x, double y, double radius, double angle, const glColour *c)
Renders spob and jump point targeting reticles.
Definition gui.c:420
static nlua_env gui_env
Definition gui.c:90
void player_message(const char *fmt,...)
Adds a mesg to the queue to be displayed on screen.
Definition gui.c:335
static int gui_L_mclick
Definition gui.c:91
void gui_setRadarResolution(double res)
Sets the radar resolution.
Definition gui.c:2039
static double gui_viewport_x
Definition gui.c:97
static double animation_dt
Definition gui.c:76
void gui_setCargo(void)
Player just changed their cargo.
Definition gui.c:1767
static double gui_viewport_h
Definition gui.c:100
void player_messageToggle(int enable)
Toggles if player should receive messages.
Definition gui.c:288
static glTexture * gui_target_pilot
Definition gui.c:155
int input_clickedPilot(unsigned int pilot, int autonav)
Performs an appropriate action when a pilot is clicked.
Definition input.c:1416
int input_clickPos(SDL_Event *event, double x, double y, double zoom, double minpr, double minr)
Handles a click at a position in the current system.
Definition input.c:1234
int input_clickedAsteroid(int field, int asteroid)
Performs an appropriate action when an asteroid is clicked.
Definition input.c:1400
int input_clickedSpob(int spob, int autonav)
Performs an appropriate action when a spob is clicked.
Definition input.c:1357
int input_clickedJump(int jump, int autonav)
Performs an appropriate action when a jump point is clicked.
Definition input.c:1322
int landed
Definition land.c:75
void land_genWindows(int load)
Recreates the land windows.
Definition land.c:957
void mat4_translate(mat4 *m, double x, double y, double z)
Translates a homogenous transformation matrix.
Definition mat4.c:99
void mat4_scale(mat4 *m, double x, double y, double z)
Scales a homogeneous transformation matrix.
Definition mat4.c:82
Handles the important game menus.
#define MENU_MAIN
Definition menu.h:9
#define menu_isOpen(f)
Definition menu.h:16
void fps_setPos(double x, double y)
Sets the position to display the FPS.
Definition naev.c:934
Header file with generic functions and naev-specifics.
#define CLAMP(a, b, x)
Definition naev.h:41
#define ABS(x)
Definition naev.h:36
#define pow2(x)
Definition naev.h:46
#define MAX(x, y)
Definition naev.h:39
#define PATH_MAX
Definition naev.h:50
void * ndata_read(const char *path, size_t *filesize)
Reads a file from the ndata (will be NUL terminated).
Definition ndata.c:154
int nlua_loadStandard(nlua_env env)
Loads the standard Naev Lua API.
Definition nlua.c:798
int nlua_loadGFX(nlua_env env)
Loads the graphics library.
Definition nlua_gfx.c:98
int nlua_loadGUI(nlua_env env)
Loads the GUI library.
Definition nlua_gui.c:60
int nlua_loadTk(nlua_env env)
Loads the Toolkit Lua library.
Definition nlua_tk.c:93
char * strndup(const char *s, size_t n)
Return a pointer to a new string, which is a duplicate of the string s (or, if necessary,...
Definition nstring.c:67
void gl_setDefViewport(int x, int y, int w, int h)
Sets the default viewport.
Definition opengl.c:597
void gl_defViewport(void)
Resets viewport to default.
Definition opengl.c:608
void gl_viewport(int x, int y, int w, int h)
Sets the opengl viewport.
Definition opengl.c:569
void gl_windowToScreenPos(int *sx, int *sy, int wx, int wy)
Translates the window position to screen position.
Definition opengl.c:616
glInfo gl_screen
Definition opengl.c:51
void gl_renderShader(double x, double y, double w, double h, double r, const SimpleShader *shd, const glColour *c, int center)
Renders a simple shader.
void gl_renderRect(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
void gl_renderLine(double x1, double y1, double x2, double y2, const glColour *c)
Draws a line.
void gl_gameToScreenCoords(double *nx, double *ny, double bx, double by)
Converts in-game coordinates to screen coordinates.
void gl_renderTriangleEmpty(double x, double y, double a, double s, double length, const glColour *c)
Renders a triangle at a given position.
void gl_unclipRect(void)
Clears the 2d clipping planes.
void gl_renderRectEmpty(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
void gl_clipRect(int x, int y, int w, int h)
Sets up 2d clipping planes around a rectangle.
void gl_renderCircle(double cx, double cy, double r, const glColour *c, int filled)
Draws a circle.
glTexture * gl_dupTexture(const glTexture *texture)
Duplicates a texture.
Definition opengl_tex.c:917
glTexture * gl_newSprite(const char *path, const int sx, const int sy, const unsigned int flags)
Loads the texture immediately, but also sets it as a sprite.
Definition opengl_tex.c:791
void gl_freeTexture(glTexture *texture)
Frees a texture.
Definition opengl_tex.c:862
void gl_vboDestroy(gl_vbo *vbo)
Destroys a VBO.
Definition opengl_vbo.c:246
void gl_vboActivateAttribOffset(gl_vbo *vbo, GLuint index, GLuint offset, GLint size, GLenum type, GLsizei stride)
Activates a VBO's offset.
Definition opengl_vbo.c:226
gl_vbo * gl_vboCreateStatic(GLsizei size, const void *data)
Creates a stream vbo.
Definition opengl_vbo.c:179
double dt_mod
Definition pause.c:23
int pilot_isHostile(const Pilot *p)
Checks to see if pilot is hostile to the player.
Definition pilot.c:678
int pilot_validTarget(const Pilot *p, const Pilot *target)
Checks to see if a pilot is a valid target for another pilot.
Definition pilot.c:237
int pilot_isFriendly(const Pilot *p)
Checks to see if pilot is friendly to the player.
Definition pilot.c:708
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
Definition pilot.c:620
const glColour * pilot_getColour(const Pilot *p)
Gets a pilot's colour.
Definition pilot.c:1284
static Pilot ** pilot_stack
Definition pilot.c:61
Pilot *const * pilot_getAll(void)
Gets the pilot stack.
Definition pilot.c:94
double pilot_getNearestAng(const Pilot *p, unsigned int *tp, double ang, int disabled)
Get the pilot closest to an angle extending from another pilot.
Definition pilot.c:567
void pilot_setTarget(Pilot *p, unsigned int id)
Sets the target of the pilot.
Definition pilot.c:1308
int pilot_inRangePilot(const Pilot *p, const Pilot *target, double *dist2)
Check to see if a pilot is in sensor range of another.
Definition pilot_ew.c:244
int pilot_inRangeSpob(const Pilot *p, int target)
Check to see if a spob is in sensor range of the pilot.
Definition pilot_ew.c:279
int pilot_inRangeAsteroid(const Pilot *p, int ast, int fie)
Check to see if an asteroid is in sensor range of the pilot.
Definition pilot_ew.c:309
int snd_jump
Definition player.c:98
void player_targetSpobSet(int id)
Sets the player's target spob.
Definition player.c:1485
Player_t player
Definition player.c:74
void player_soundPlayGUI(int sound, int once)
Plays a GUI sound (unaffected by time accel).
Definition player.c:875
static const double c[]
Definition rng.c:264
int ship_size(const Ship *s)
Gets the size of the ship.
Definition ship.c:316
double system_getClosestAng(const StarSystem *sys, int *pnt, int *jp, int *ast, int *fie, double x, double y, double ang)
Gets the feature nearest to directly ahead of a position in the system.
Definition space.c:766
int space_canHyperspace(const Pilot *p)
Checks to make sure if pilot is far enough away to hyperspace.
Definition space.c:469
const glColour * spob_getColour(const Spob *p)
Gets the spob colour.
Definition space.c:1922
const char * jump_getSymbol(const JumpPoint *jp)
Gets the jump point symbol.
Definition space.c:1260
const char * spob_getSymbol(const Spob *p)
Gets the spob symbol.
Definition space.c:1900
StarSystem * cur_system
Definition space.c:106
const char * spob_name(const Spob *p)
Gets the translated name of a spob.
Definition space.c:1752
glTexture * jumppoint_gfx
Definition space.c:107
void spfx_cinematic(void)
Sets the cinematic mode.
Definition spfx.c:1006
const char * start_gui(void)
Gets the module's starting ship was acquired.
Definition start.c:213
Represents an asteroid field anchor.
Definition asteroid.h:100
Asteroid * asteroids
Definition asteroid.h:105
Represents a single asteroid.
Definition asteroid.h:77
const glTexture * gfx
Definition asteroid.h:83
Solid sol
Definition asteroid.h:87
float text_offx
Definition space.h:59
float radius
Definition space.h:58
float text_offy
Definition space.h:60
On screen player message.
Definition gui.c:136
glFontRestore restore
Definition gui.c:139
char * str
Definition gui.c:137
double t
Definition gui.c:138
The representation of an in-game pilot.
Definition pilot.h:217
ShipStats stats
Definition pilot.h:294
unsigned int id
Definition pilot.h:218
int nav_hyperspace
Definition pilot.h:345
const Ship * ship
Definition pilot.h:226
int nav_anchor
Definition pilot.h:346
double ptimer
Definition pilot.h:368
Solid solid
Definition pilot.h:227
double cdelay
Definition pilot.h:287
double ctimer
Definition pilot.h:288
unsigned int target
Definition pilot.h:342
int nav_spob
Definition pilot.h:344
int nav_asteroid
Definition pilot.h:347
double jump_brightness
Definition conf.h:100
int always_radar
Definition conf.h:126
int mesg_visible
Definition conf.h:123
Pilot * p
Definition player.h:101
double radar_res
Definition player.h:120
char * gui
Definition player.h:119
Represents the player's radar.
Definition gui.c:107
double y
Definition gui.c:111
double res
Definition gui.c:113
double w
Definition gui.c:108
double h
Definition gui.c:109
RadarShape shape
Definition gui.c:112
double x
Definition gui.c:110
double ew_detect
Definition shipstats.h:244
glTexture * gfx_space
Definition ship.h:138
vec2 vel
Definition physics.h:48
double dir
Definition physics.h:46
vec2 pos
Definition physics.h:49
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Definition space.h:89
glTexture * gfx_space
Definition space.h:121
double radius
Definition space.h:95
double marker_scale
Definition space.h:97
const SimpleShader * marker
Definition space.h:96
vec2 pos
Definition space.h:94
MapOverlayPos mo
Definition space.h:132
Evil hack to allow restoring, yes it makes me cry myself to sleep.
Definition font.h:27
int h
Definition font.h:18
int w
Definition opengl.h:44
int rh
Definition opengl.h:51
int rw
Definition opengl.h:50
int h
Definition opengl.h:45
int nw
Definition opengl.h:47
int nh
Definition opengl.h:48
The state of a line iteration. This matches the process of rendering text into an on-screen box: An e...
Definition font.h:40
Abstraction for rendering sprite sheets.
Definition opengl_tex.h:36
double sw
Definition opengl_tex.h:46
double sh
Definition opengl_tex.h:47
Definition mat4.h:10
double y
Definition vec2.h:34
double x
Definition vec2.h:33
void window_lower(unsigned int wid)
Lowers a window (causes all other windows to appear above it).
Definition toolkit.c:2560