update helpers/location to 'frosted' ui
[carveJwlIkooP6JGAAIwe30JlM.git] / ent_miniworld.c
1 #include "entity.h"
2 #include "ent_miniworld.h"
3 #include "world_render.h"
4 #include "world_load.h"
5 #include "input.h"
6 #include "gui.h"
7 #include "menu.h"
8 #include "audio.h"
9
10 struct global_miniworld global_miniworld;
11
12 entity_call_result ent_miniworld_call( world_instance *world, ent_call *call )
13 {
14 ent_miniworld *miniworld = mdl_arritm( &world->ent_miniworld,
15 mdl_entity_id_id(call->id) );
16
17 int world_id = world - world_static.instances;
18
19 if( call->function == 0 ) /* zone() */
20 {
21 const char *uid = mdl_pstr( &world->meta, miniworld->pstr_world );
22 skaterift_load_world_command( 1, (const char *[]){ uid } );
23
24 mdl_transform_m4x3( &miniworld->transform, global_miniworld.mmdl );
25 global_miniworld.active = miniworld;
26
27 gui_helper_clear();
28 vg_str text;
29
30 if( gui_new_helper( input_button_list[k_srbind_miniworld_resume], &text ))
31 vg_strcat( &text, "Enter World" );
32
33 return k_entity_call_result_OK;
34 }
35 else if( call->function == 1 )
36 {
37 global_miniworld.active = NULL;
38 gui_helper_clear();
39
40 if( miniworld->proxy )
41 {
42 ent_prop *prop = mdl_arritm( &world->ent_prop,
43 mdl_entity_id_id(miniworld->proxy) );
44 prop->flags &= ~0x1;
45 }
46
47 return k_entity_call_result_OK;
48 }
49 else
50 return k_entity_call_result_unhandled;
51 }
52
53 static void miniworld_icon( vg_camera *cam, enum gui_icon icon,
54 v3f pos, f32 size)
55 {
56 m4x3f mmdl;
57 v3_copy( cam->transform[2], mmdl[2] );
58 mmdl[2][1] = 0.0f;
59 v3_normalize( mmdl[2] );
60 v3_copy( (v3f){0,1,0}, mmdl[1] );
61 v3_cross( mmdl[1], mmdl[2], mmdl[0] );
62 m4x3_mulv( global_miniworld.mmdl, pos, mmdl[3] );
63
64 shader_model_font_uMdl( mmdl );
65 shader_model_font_uOffset( (v4f){0,0,0,20.0f*size} );
66
67 m4x4f m4mdl;
68 m4x3_expand( mmdl, m4mdl );
69 m4x4_mul( cam->mtx_prev.pv, m4mdl, m4mdl );
70 shader_model_font_uPvmPrev( m4mdl );
71
72 mdl_submesh *sm = gui.icons[ icon ];
73 if( sm )
74 mdl_draw_submesh( sm );
75 }
76
77 void ent_miniworld_render( world_instance *host_world, vg_camera *cam )
78 {
79 if( host_world != &world_static.instances[k_world_purpose_hub] )
80 return;
81
82 ent_miniworld *miniworld = global_miniworld.active;
83
84 if( !miniworld )
85 return;
86
87 world_instance *dest_world = &world_static.instances[k_world_purpose_client];
88
89 int rendering = 1;
90 if( dest_world->status != k_world_status_loaded )
91 rendering = 0;
92
93 if( miniworld->proxy ){
94 ent_prop *prop = mdl_arritm( &host_world->ent_prop,
95 mdl_entity_id_id(miniworld->proxy) );
96 if( !rendering )
97 prop->flags &= ~0x1;
98 else
99 prop->flags |= 0x1;
100 }
101
102
103 if( !rendering )
104 return;
105
106 render_world_override( dest_world, host_world, global_miniworld.mmdl, cam,
107 NULL, (v4f){dest_world->tar_min,10000.0f,0.0f,0.0f} );
108 render_world_routes( dest_world, host_world,
109 global_miniworld.mmdl, cam, 0, 1 );
110
111 /* icons
112 * ---------------------*/
113 font3d_bind( &gui.font, k_font_shader_default, 0, NULL, cam );
114 mesh_bind( &gui.icons_mesh );
115
116 glActiveTexture( GL_TEXTURE0 );
117 glBindTexture( GL_TEXTURE_2D, gui.icons_texture );
118 shader_model_font_uTexMain( 0 );
119 shader_model_font_uColour( (v4f){1,1,1,1} );
120
121 miniworld_icon( cam, k_gui_icon_player, dest_world->player_co,
122 1.0f + sinf(vg.time)*0.2f );
123
124 for( u32 i=0; i<mdl_arrcount(&dest_world->ent_challenge); i++ ){
125 ent_challenge *challenge = mdl_arritm( &dest_world->ent_challenge, i );
126
127 enum gui_icon icon = k_gui_icon_exclaim;
128 if( challenge->status )
129 icon = k_gui_icon_tick;
130
131 miniworld_icon( cam, icon, challenge->transform.co, 1.0f );
132 }
133
134 for( u32 i=0; i<mdl_arrcount(&dest_world->ent_route); i++ ){
135 ent_route *route = mdl_arritm( &dest_world->ent_route, i );
136
137 if( route->flags & k_ent_route_flag_achieve_gold ){
138 miniworld_icon( cam, k_gui_icon_rift_run_gold,
139 route->board_transform[3],1.0f);
140 }
141 else if( route->flags & k_ent_route_flag_achieve_silver ){
142 miniworld_icon( cam, k_gui_icon_rift_run_silver,
143 route->board_transform[3],1.0f);
144 }
145 }
146
147 for( u32 i=0; i<mdl_arrcount(&dest_world->ent_route); i++ ){
148 ent_route *route = mdl_arritm( &dest_world->ent_route, i );
149
150 v4f colour;
151 v4_copy( route->colour, colour );
152 v3_muls( colour, 1.6666f, colour );
153 shader_model_font_uColour( colour );
154 miniworld_icon( cam, k_gui_icon_rift_run, route->board_transform[3],1.0f);
155 }
156 }
157
158 void ent_miniworld_preupdate(void)
159 {
160 world_instance *hub = world_current_instance(),
161 *dest = &world_static.instances[k_world_purpose_client];
162
163 ent_miniworld *miniworld = global_miniworld.active;
164
165 if( (localplayer.subsystem != k_player_subsystem_walk) ||
166 (global_miniworld.transition) ||
167 (world_static.active_instance != k_world_purpose_hub) ||
168 (!miniworld) ||
169 (dest->status != k_world_status_loaded) ||
170 (skaterift.activity != k_skaterift_default)) {
171 return;
172 }
173
174 if( button_down( k_srbind_miniworld_resume ) ){
175 if( skaterift.demo_mode ){
176 if( world_static.instance_addons[1]->flags & ADDON_REG_PREMIUM ){
177 skaterift.activity = k_skaterift_menu;
178 menu.page = 0xffffffff;
179 menu_open_page( "Premium", k_ent_menuitem_stack_append );
180 return;
181 }
182 }
183
184 global_miniworld.transition = 1;
185 global_miniworld.t = 0.0f;
186 global_miniworld.cam = skaterift.cam;
187
188 world_switch_instance(1);
189 srinput.state = k_input_state_resume;
190 menu.disable_open = 0;
191 gui_helper_clear();
192 audio_lock();
193 audio_oneshot( &audio_ui[2], 1.0f, 0.0f );
194 audio_unlock();
195 }
196 }
197
198 void ent_miniworld_goback(void)
199 {
200 audio_lock();
201 audio_oneshot( &audio_ui[2], 1.0f, 0.0f );
202 audio_unlock();
203
204 global_miniworld.transition = -1;
205 global_miniworld.t = 1.0f;
206
207 global_miniworld.cam = skaterift.cam;
208 vg_m4x3_transform_camera( global_miniworld.mmdl, &global_miniworld.cam );
209 world_switch_instance(0);
210 }