d943c2d07a13c55831527a4954d3031031dc913d
[carveJwlIkooP6JGAAIwe30JlM.git] / skaterift.c
1 /*
2 * =============================================================================
3 *
4 * Copyright . . . -----, ,----- ,---. .---.
5 * 2021-2023 |\ /| | / | | | | /|
6 * | \ / | +-- / +----- +---' | / |
7 * | \ / | | / | | \ | / |
8 * | \/ | | / | | \ | / |
9 * ' ' '--' [] '----- '----- ' ' '---' SOFTWARE
10 *
11 * =============================================================================
12 */
13
14 #define SR_NETWORKED
15 #define VG_DEVWINDOW
16 #include "common.h"
17 #include "conf.h"
18 #include "steam.h"
19 #include "render.h"
20 #include "audio.h"
21 #include "world.h"
22 #include "font.h"
23 #include "player.h"
24
25 VG_STATIC struct player_avatar localplayer_avatar;
26 VG_STATIC struct player_model localplayer_models[3];
27 VG_STATIC struct player_board localplayer_boards[1];
28
29 #include "network.h"
30 #include "menu.h"
31 #include "vehicle.h"
32
33 #define DEV_AARON
34 #ifdef DEV_AARON
35 static rb_object aaron={
36 .type=k_rb_shape_box,
37 .rb.bbx = {{ -2.0f, -1.0f, -1.0f }, { 2.0f, 1.0f, 1.0f }}
38 };
39 #endif
40
41 int main( int argc, char *argv[] )
42 {
43 vg_mem.use_libc_malloc = 0;
44 vg_set_mem_quota( 160*1024*1024 );
45 vg_enter( argc, argv, "Voyager Game Engine" );
46 return 0;
47 }
48
49 VG_STATIC void highscores_save_at_exit(void)
50 {
51 highscores_serialize_all();
52 }
53
54 VG_STATIC void vg_launch_opt(void)
55 {
56 }
57
58 VG_STATIC void vg_preload(void)
59 {
60 g_conf_init();
61
62 vg_info(" Copyright . . . -----, ,----- ,---. .---. \n" );
63 vg_info(" 2021-2023 |\\ /| | / | | | | /| \n" );
64 vg_info(" | \\ / | +-- / +----- +---' | / | \n" );
65 vg_info(" | \\ / | | / | | \\ | / | \n" );
66 vg_info(" | \\/ | | / | | \\ | / | \n" );
67 vg_info(" ' ' '--' [] '----- '----- ' ' '---' "
68 "SOFTWARE\n" );
69
70 highscores_init( 2000, 50 );
71 if( !highscores_read() )
72 highscores_create_db();
73
74 vg_loader_step( NULL, highscores_save_at_exit );
75
76 steam_init();
77 vg_loader_step( NULL, steam_end );
78 vg_loader_step( network_init, network_end );
79
80 #ifdef DEV_AARON
81 q_identity( aaron.rb.q );
82 v3_zero( aaron.rb.w );
83 v3_zero( aaron.rb.co );
84 v3_zero( aaron.rb.v );
85 rb_init_object( &aaron );
86 #endif
87 }
88
89 VG_STATIC void load_playermodels(void)
90 {
91 player_model_load( &localplayer_models[0], "models/ch_new.mdl" );
92 player_model_load( &localplayer_models[1], "models/ch_outlaw.mdl" );
93 player_model_load( &localplayer_models[2], "models/ch_jordan.mdl" );
94
95 player_board_load( &localplayer_boards[0], "models/board_fish.mdl" );
96
97 /* FIXME: hack */
98 shader_model_character_view_register();
99 shader_model_board_view_register();
100 }
101
102 void temp_update_playermodel(void){
103 player__use_model( &localplayer, &localplayer_models[cl_playermdl_id] );
104 }
105
106 VG_STATIC void vg_load(void)
107 {
108 vg_loader_step( render_init, NULL );
109 vg_loader_step( menu_init, NULL );
110 vg_loader_step( world_init, NULL );
111 vg_loader_step( vehicle_init, NULL );
112 vg_loader_step( font3d_init, NULL );
113
114 font3d_load( &world_global.font, "models/rs_font.mdl", vg_mem.rtmemory );
115
116 vg_loader_step( player_init, NULL );
117 vg_loader_step( player_ragdoll_init, NULL );
118
119 /* ----------------- */
120 vg_loader_step( load_playermodels, NULL );
121
122 /* player setup */
123 player__create( &localplayer );
124 player_avatar_load( &localplayer_avatar, "models/ch_new.mdl" );
125 player__use_avatar( &localplayer, &localplayer_avatar );
126 player__use_model( &localplayer, &localplayer_models[cl_playermdl_id] );
127 player__use_board( &localplayer, &localplayer_boards[0] );
128 player__bind( &localplayer );
129
130 /* --------------------- */
131
132 vg_bake_shaders();
133 vg_loader_step( audio_init, audio_free );
134
135 /* 'systems' are completely loaded now */
136
137 /* load home world */
138
139 #if 1
140 world_load( 0, "maps/mp_spawn.mdl" );
141 #else
142 world_load( 0, "maps/mp_mtzero.mdl" );
143 #endif
144
145 #if 0
146 world_load( &world_global.worlds[1], "maps/mp_gridmap.mdl" );
147 world_link_nonlocal_gates( 0, 1 );
148 world_load( &world_global.worlds[2], "maps/mp_mtzero.mdl" );
149 world_link_nonlocal_gates( 0, 2 );
150 #endif
151
152 vg_console_load_autos();
153 }
154
155 VG_STATIC void vg_start(void)
156 {
157 localplayer.viewable_world = get_active_world();
158 localplayer_cmd_respawn( 1, (const char *[]){ "start" } );
159 }
160
161 VG_STATIC void draw_origin_axis(void)
162 {
163 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 1.0f, 0.0f, 0.0f }, 0xffff0000 );
164 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 1.0f, 0.0f }, 0xff00ff00 );
165 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 0.0f, 1.0f }, 0xff0000ff );
166 }
167
168 VG_STATIC void vg_update(void)
169 {
170 steam_update();
171
172 if( vg.is_loaded ){
173 draw_origin_axis();
174 network_update();
175
176 player__pre_update( &localplayer );
177
178 world_update( get_active_world(), localplayer.rb.co );
179 audio_ambient_sprites_update( get_active_world(), localplayer.rb.co );
180 }
181 }
182
183 VG_STATIC void vg_update_fixed(void)
184 {
185 if( vg.is_loaded ){
186 world_routes_fixedupdate( get_active_world() );
187
188 player__update( &localplayer );
189 vehicle_update_fixed();
190
191 #ifdef DEV_AARON
192 world_instance *world = get_active_world();
193 rb_solver_reset();
194 rb_ct *buf = rb_global_buffer();
195
196 int l = rb_box__scene( aaron.rb.to_world, aaron.rb.bbx,
197 NULL, &world->rb_geo.inf.scene, buf );
198 for( int j=0; j<l; j++ ){
199 buf[j].rba = &aaron.rb;
200 buf[j].rbb = &world->rb_geo.rb;
201 }
202 rb_contact_count += l;
203 rb_presolve_contacts( rb_contact_buffer, rb_contact_count );
204
205 for( int j=0; j<8; j++ ){
206 rb_solve_contacts( rb_contact_buffer, rb_contact_count );
207 }
208
209 rb_iter( &aaron.rb );
210 rb_update_transform( &aaron.rb );
211 #endif
212
213 }
214 }
215
216 VG_STATIC void vg_update_post(void)
217 {
218 if( vg.is_loaded ){
219 player__post_update( &localplayer );
220
221 float dist;
222 int sample_index;
223 world_audio_sample_distances( localplayer.rb.co, &sample_index, &dist );
224
225 audio_lock();
226 vg_dsp.echo_distances[sample_index] = dist;
227
228 v3f ears = { 1.0f,0.0f,0.0f };
229 m3x3_mulv( main_camera.transform, ears, ears );
230 v3_copy( ears, vg_audio.external_listener_ears );
231 v3_copy( main_camera.transform[3], vg_audio.external_listener_pos );
232
233 if( localplayer.gate_waiting ){
234 m4x3_mulv( localplayer.gate_waiting->transport,
235 vg_audio.external_listener_pos,
236 vg_audio.external_listener_pos );
237 }
238
239 v3_copy( localplayer.rb.v, vg_audio.external_lister_velocity );
240 audio_unlock();
241
242 menu_update();
243 vehicle_update_post();
244
245 #ifdef DEV_AARON
246 SDL_Scancode sc = SDL_GetScancodeFromKey( SDLK_q );
247 if( vg_input.sdl_keys[sc] ){
248 m4x3_mulv( main_camera.transform, (v3f){0.0f,0.0f,-3.0f},
249 aaron.rb.co );
250
251 v3_zero( aaron.rb.v );
252 v3_zero( aaron.rb.w );
253 rb_update_transform( &aaron.rb );
254 }
255
256 rb_object_debug( &aaron, VG__PINK );
257 #endif
258 }
259 }
260
261 VG_STATIC void vg_framebuffer_resize( int w, int h )
262 {
263 render_fb_resize();
264 }
265
266 VG_STATIC void present_view_with_post_processing(void)
267 {
268 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
269 glViewport( 0,0, vg.window_x, vg.window_y );
270
271 glEnable(GL_BLEND);
272 glDisable(GL_DEPTH_TEST);
273 glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
274 glBlendEquation(GL_FUNC_ADD);
275
276 v2f inverse;
277 render_fb_inverse_ratio( gpipeline.fb_main, inverse );
278
279 if( cl_blur ){
280 shader_blitblur_use();
281 shader_blitblur_uTexMain( 0 );
282 shader_blitblur_uTexMotion( 1 );
283 shader_blitblur_uBlurStrength( cl_blur_strength /
284 (vg.time_frame_delta*60.0) );
285 shader_blitblur_uInverseRatio( inverse );
286
287 v2f menu_blurring;
288 v2_muls( (v2f){ 0.04f, 0.001f }, menu_opacity, menu_blurring );
289 shader_blitblur_uOverrideDir( menu_blurring );
290
291 render_fb_bind_texture( gpipeline.fb_main, 0, 0 );
292 render_fb_bind_texture( gpipeline.fb_main, 1, 1 );
293 }
294 else{
295 shader_blit_use();
296 shader_blit_uTexMain( 0 );
297 shader_blit_uInverseRatio( inverse );
298 render_fb_bind_texture( gpipeline.fb_main, 0, 0 );
299 }
300
301 render_fsquad();
302 }
303
304 VG_STATIC void render_player_transparent(void)
305 {
306 static camera small_cam; /* DOES NOT NEED TO BE STATIC BUT MINGW
307 SAIS OTHERWISE */
308
309 m4x3_copy( main_camera.transform, small_cam.transform );
310
311 small_cam.fov = main_camera.fov;
312 small_cam.nearz = 0.05f;
313 small_cam.farz = 60.0f;
314
315 camera_update_view( &small_cam );
316 camera_update_projection( &small_cam );
317 camera_finalize( &small_cam );
318
319 /* Draw player to window buffer and blend background ontop */
320 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
321 glViewport( 0,0, vg.window_x, vg.window_y );
322 player__render( &small_cam, &localplayer );
323 }
324
325 VG_STATIC void render_scene(void)
326 {
327 render_fb_bind( gpipeline.fb_main, 1 );
328 glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
329 glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
330
331 /* Draw world */
332 glEnable( GL_DEPTH_TEST );
333
334 world_instance *view_world = localplayer.viewable_world;
335
336 if( view_world == NULL ){
337 glClearColor( 0.25f, 0.25f, 0.0f, 1.0f );
338 glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
339 return;
340 }
341
342 world_prerender( view_world );
343 render_world( view_world, &main_camera, 0 );
344
345 render_water_texture( view_world, &main_camera, 0 );
346 render_fb_bind( gpipeline.fb_main, 1 );
347 render_water_surface( view_world, &main_camera );
348 }
349
350 VG_STATIC void render_scene_gate_subview(void)
351 {
352 render_fb_bind( gpipeline.fb_main, 1 );
353 world_instance *view_world = localplayer.viewable_world;
354
355 int depth = 1;
356 if( localplayer.gate_waiting ) depth = 0;
357 render_world_gates( view_world, &main_camera, depth );
358 }
359
360 VG_STATIC void render_main_game(void)
361 {
362 #if 0
363 static float fov = 60.0f;
364 float fov_target = vg_lerpf( 90.0f, 110.0f, cl_fov );
365
366 if( player.controller == k_player_controller_skate )
367 fov_target = vg_lerpf( 97.0f, 135.0f, cl_fov );
368
369 if( cl_menu )
370 fov_target = menu_fov_target;
371 fov = vg_lerpf( fov, fov_target, vg.frame_delta * 2.0f );
372 fov = freecam? 60.0f: fov;
373
374 main_camera.fov = fov;
375 #endif
376
377 player__pre_render( &localplayer );
378
379 v3_lerp( localplayer.cam.pos, menu_camera_pos, menu_opacity,
380 main_camera.pos );
381 main_camera.angles[0] =
382 vg_alerpf( localplayer.cam.angles[0], menu_camera_angles[0],
383 menu_opacity );
384 main_camera.angles[1] =
385 vg_lerpf ( localplayer.cam.angles[1], menu_camera_angles[1],
386 menu_opacity );
387
388 main_camera.fov = vg_lerpf( localplayer.cam.fov, menu_smooth_fov,
389 menu_opacity );
390 main_camera.nearz = 0.1f;
391 main_camera.farz = 2100.0f;
392
393 camera_update_transform( &main_camera );
394
395 if( localplayer.gate_waiting ){
396 m3x3_mul( localplayer.basis_gate, main_camera.transform,
397 main_camera.transform );
398 }
399 else{
400 m3x3_mul( localplayer.basis, main_camera.transform,
401 main_camera.transform );
402 }
403
404 camera_update_view( &main_camera );
405 camera_update_projection( &main_camera );
406 camera_finalize( &main_camera );
407
408 /* ========== Begin Frame ========== */
409
410 render_scene();
411
412 if( cl_menu ) {
413 //glClear( GL_DEPTH_BUFFER_BIT );
414 menu_render_bg();
415 glEnable( GL_DEPTH_TEST );
416 }
417
418 render_player_transparent();
419 render_scene_gate_subview();
420
421 present_view_with_post_processing();
422
423 if( cl_menu )
424 menu_render_fg( &main_camera );
425
426 /* =========== End Frame =========== */
427 }
428
429 VG_STATIC void vg_render(void)
430 {
431 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
432
433 glViewport( 0,0, vg.window_x, vg.window_y );
434 glDisable( GL_DEPTH_TEST );
435
436 glClearColor( 1.0f, 0.0f, 0.0f, 0.0f );
437 glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
438
439 render_main_game();
440
441 m4x4_copy( main_camera.mtx.pv, vg.pv );
442
443 /* Other shite */
444 glDisable(GL_BLEND);
445 glDisable(GL_DEPTH_TEST);
446 vg_lines_drawall();
447 glViewport( 0,0, vg.window_x, vg.window_y );
448 }
449
450 VG_STATIC void vg_ui(void)
451 {
452 #if 0
453 player__im_gui( &localplayer );
454 #endif
455 world_instance *world = get_active_world();
456 menu_crap_ui();
457
458 render_view_framebuffer_ui();
459 }