20 const char *bindstr
, *text
;
41 k_guitrick_type_ollie
,
42 k_guitrick_type_trick
,
43 k_guitrick_type_backflip
,
49 mdl_context model_icons
;
53 mdl_submesh
*icons
[ k_gui_icon_count
];
58 void gui_helper_action( const char *bindstr
, const char *text
){
59 if( gui
.helper_count
>= vg_list_size(gui
.helpers
) ){
60 vg_error( "Too many helpers\n" );
64 struct gui_helper
*helper
= &gui
.helpers
[ gui
.helper_count
++ ];
65 helper
->bindstr
= bindstr
;
72 if( v3_dist2(localplayer
.rb
.co
,gui
.trick_co
) > 2.0f
){
73 gui
.trick_type
= k_guitrick_type_none
;
76 if( gui
.trick_type
== k_guitrick_type_pump
){
77 gui_helper_action(axis_display_string(k_sraxis_grab
),"Crouch");
79 else if( gui
.trick_type
== k_guitrick_type_backflip
){
80 gui_helper_action(joystick_display_string(k_srjoystick_steer
,1),"Flip");
82 else if( gui
.trick_type
== k_guitrick_type_ollie
){
83 gui_helper_action(button_display_string(k_srbind_jump
),"Ollie");
85 else if( gui
.trick_type
== k_guitrick_type_trick
){
86 gui_helper_action(button_display_string(k_srbind_trick0
),"Shuvit");
87 gui_helper_action(button_display_string(k_srbind_trick1
),"Kickflip");
88 gui_helper_action(button_display_string(k_srbind_trick2
),"Tre-Flip");
90 else if( gui
.trick_type
== k_guitrick_type_isc
){
91 gui_helper_action(button_display_string(k_srbind_camera
),"Camera");
92 gui_helper_action(button_display_string(k_srbind_use
), "Skate/Walk");
104 m4x4_zero( ortho
.mtx
.p
);
105 ortho
.mtx
.p
[0][0] = 2.0f
* rl
;
106 ortho
.mtx
.p
[1][1] = 2.0f
* tb
;
107 ortho
.mtx
.p
[3][0] = (fr
+ fl
) * -rl
;
108 ortho
.mtx
.p
[3][1] = (ft
+ fb
) * -tb
;
109 ortho
.mtx
.p
[3][3] = 1.0f
;
110 m4x3_identity( ortho
.transform
);
111 camera_update_view( &ortho
);
112 m4x4_mul( ortho
.mtx
.p
, ortho
.mtx
.v
, ortho
.mtx
.pv
); /* HACK */
113 camera_finalize( &ortho
);
120 font3d_bind( &gui
.font
, &ortho
);
122 m4x3_identity( mmdl
);
123 shader_model_font_uMdl( mmdl
);
125 mesh_bind( &gui
.icons_mesh
);
126 shader_model_font_uColour( (v4f
){1.0f
,1.0f
,1.0f
,1.0f
} );
127 glActiveTexture( GL_TEXTURE0
);
128 glBindTexture( GL_TEXTURE_2D
, gui
.icons_texture
);
129 shader_model_font_uTexMain( 0 );
131 for( u32 i
=0; i
<gui
.icon_draw_count
; i
++ ){
132 struct icon_call
*call
= &gui
.icon_draw_buffer
[i
];
133 shader_model_font_uOffset( call
->location
);
135 mdl_submesh
*sm
= gui
.icons
[ call
->icon
];
137 mdl_draw_submesh( sm
);
140 gui
.icon_draw_count
= 0;
146 gui
.factive
= vg_lerpf( gui
.factive
, gui
.helper_count
?1.0f
:0.0f
,
147 vg
.time_frame_delta
*2.0f
);
149 if( gui
.factive
> 0.01f
){
150 /* draw bottom bar */
152 glDisable(GL_DEPTH_TEST
);
153 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
154 glBlendEquation(GL_FUNC_ADD
);
156 shader_blitcolour_use();
157 shader_blitcolour_uColour( (v4f
){ 0.0f
, 0.0f
, 0.0f
, gui
.factive
*0.8f
} );
161 f64 loc_t
= (vg
.time_real
- gui
.location_time
) / 5.0;
162 if( (loc_t
< 1.0) && (gui
.location_time
!= 0.0) ){
163 /* yep this code is a mess, i dont care anymore */
165 glDisable(GL_DEPTH_TEST
);
166 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
167 glBlendEquation(GL_FUNC_ADD
);
169 f32 t
= 1.0f
-vg_minf(1.0f
,vg_minf(loc_t
*20.0f
,2.0f
-loc_t
*2.0f
)),
170 o
= 1.0f
-t
*t
*(2.0f
-t
);
172 shader_blitcolour_use();
173 shader_blitcolour_uColour( (v4f
){ 0.0f
, 0.0f
, 0.0f
, o
*0.5f
} );
177 scale
= dy
*0x1p
-4f
*0.5f
;
179 m3x3_identity( mmdl
);
180 m3x3_scale( mmdl
, (v3f
){scale
,scale
,scale
} );
183 f32 pad
= dy
*0x1p
-4f
*0.125f
;
184 f32 w
= font3d_string_width( &gui
.font
,2,gui
.location
);
186 mmdl
[3][0] = fr
*0.5f
- w
*scale
*0.5f
;
187 mmdl
[3][1] = 0.3f
*ft
+pad
*2.0f
;
189 font3d_bind( &gui
.font
, &ortho
);
190 shader_model_font_uColour( (v4f
){1.2f
,1.2f
,1.2f
,o
} );
191 font3d_simple_draw( &gui
.font
, 2, k_font_shader_default
,
192 gui
.location
, &ortho
, mmdl
);
195 font3d_bind( &gui
.font
, &ortho
);
198 scale
= dy
*0x1p
-4f
*0.75f
;
200 m3x3_identity( mmdl
);
201 m3x3_scale( mmdl
, (v3f
){scale
,scale
,scale
} );
204 float pad
= dy
*0x1p
-4f
*0.125f
;
205 mmdl
[3][0] = pad
*2.0f
;
208 for( u32 i
=0; i
<gui
.helper_count
; i
++ ){
209 struct gui_helper
*helper
= &gui
.helpers
[i
];
211 shader_model_font_uColour( (v4f
){1.0f
,1.0f
,1.0f
,1.0f
} );
213 struct font3d_render render
= {
216 .shader
= k_font_shader_default
218 font3d_begin( helper
->bindstr
, &ortho
, mmdl
, &render
);
219 font3d_draw( &render
);
221 const char *make_smaller
= "\x02\xaf\x03 ";
222 render
.u8pch
= (const u8
*)make_smaller
;
223 font3d_draw( &render
);
225 render
.u8pch
= (u8
*)helper
->text
;
226 font3d_draw( &render
);
228 float w
= render
.offset
[0]+1.0f
;
229 mmdl
[3][0] += w
*scale
;
232 gui
.helper_count
= 0;
236 int gui_location_print_ccmd( int argc
, const char *argv
[] ){
240 vg_strnull( &str
, new_loc
, 64 );
241 for( int i
=0; i
<argc
; i
++ ){
242 vg_strcat( &str
, argv
[i
] );
243 vg_strcat( &str
, " " );
245 if( !strcmp(gui
.location
,new_loc
) ) return 0;
246 vg_strncpy( new_loc
, gui
.location
, 64, k_strncpy_always_add_null
);
247 gui
.location_time
= vg
.time_real
;
252 static int gui_showtrick_ccmd( int argc
, const char *argv
[] ){
254 enum guitrick_type type
= k_guitrick_type_none
;
255 if( !strcmp( argv
[0], "pump" ) ) type
= k_guitrick_type_pump
;
256 else if( !strcmp( argv
[0], "flip" ) ) type
= k_guitrick_type_backflip
;
257 else if( !strcmp( argv
[0], "ollie" ) ) type
= k_guitrick_type_ollie
;
258 else if( !strcmp( argv
[0], "trick" ) ) type
= k_guitrick_type_trick
;
259 else if( !strcmp( argv
[0], "misc" ) ) type
= k_guitrick_type_isc
;
261 gui
.trick_type
= type
;
262 v3_copy( localplayer
.rb
.co
, gui
.trick_co
);
268 static void gui_draw_icon( enum gui_icon icon
, v2f co
, f32 size
){
269 if( gui
.icon_draw_count
== vg_list_size(gui
.icon_draw_buffer
) )
272 struct icon_call
*call
= &gui
.icon_draw_buffer
[ gui
.icon_draw_count
++ ];
275 call
->location
[0] = co
[0] * (f32
)vg
.window_x
;
276 call
->location
[1] = co
[1] * (f32
)vg
.window_y
;
277 call
->location
[2] = 0.0f
;
278 call
->location
[3] = size
* (f32
)vg
.window_x
;
281 static mdl_submesh
*gui_find_icon( const char *name
){
282 mdl_mesh
*mesh
= mdl_find_mesh( &gui
.model_icons
, name
);
284 if( mesh
->submesh_count
){
285 return mdl_arritm( &gui
.model_icons
.submeshs
, mesh
->submesh_start
);
292 static void gui_init(void){
293 font3d_load( &gui
.font
, "models/rs_font.mdl", vg_mem
.rtmemory
);
294 vg_console_reg_cmd( "gui_location", gui_location_print_ccmd
, NULL
);
295 vg_console_reg_cmd( "showtrick", gui_showtrick_ccmd
, NULL
);
298 void *alloc
= vg_mem
.rtmemory
;
299 mdl_open( &gui
.model_icons
, "models/rs_icons.mdl", alloc
);
300 mdl_load_metadata_block( &gui
.model_icons
, alloc
);
302 gui
.icons
[ k_gui_icon_tick
] = gui_find_icon( "icon_tick" );
303 gui
.icons
[ k_gui_icon_exclaim
] = gui_find_icon( "icon_exclaim" );
304 gui
.icons
[ k_gui_icon_board
] = gui_find_icon( "icon_board" );
305 gui
.icons
[ k_gui_icon_world
] = gui_find_icon( "icon_world" );
306 gui
.icons
[ k_gui_icon_rift
] = gui_find_icon( "icon_rift" );
308 vg_linear_clear( vg_mem
.scratch
);
309 if( !mdl_arrcount( &gui
.model_icons
.textures
) )
310 vg_fatal_error( "No texture in menu file" );
311 mdl_texture
*tex0
= mdl_arritm( &gui
.model_icons
.textures
, 0 );
312 void *data
= vg_linear_alloc( vg_mem
.scratch
, tex0
->file
.pack_size
);
313 mdl_fread_pack_file( &gui
.model_icons
, &tex0
->file
, data
);
314 vg_tex2d_load_qoi_async( data
, tex0
->file
.pack_size
,
315 VG_TEX2D_LINEAR
|VG_TEX2D_CLAMP
,
316 &gui
.icons_texture
);
318 mdl_async_load_glmesh( &gui
.model_icons
, &gui
.icons_mesh
);
319 mdl_close( &gui
.model_icons
);