diff --git a/src/input.c b/src/input.c index 9e04a80..fc4a176 100644 --- a/src/input.c +++ b/src/input.c @@ -198,8 +198,12 @@ void input_set_layer_button_state(input_layer_t layer, button_t button, float st } void input_set_button_state(button_t button, float state) { - error_if(button < 0 || button >= INPUT_BUTTON_MAX, "Invalid input button %d", button); + if (sbs > 0) + // do not process buttons twice per frame + return; + + error_if(button < 0 || button >= INPUT_BUTTON_MAX, "Invalid input button %d", button); input_set_layer_button_state(INPUT_LAYER_SYSTEM, button, state); input_set_layer_button_state(INPUT_LAYER_USER, button, state); diff --git a/src/render.h b/src/render.h index 74d96cc..c7affa6 100644 --- a/src/render.h +++ b/src/render.h @@ -38,7 +38,7 @@ vec2i_t render_size(void); void render_frame_prepare(void); void render_frame_end(void); -void render_set_view(vec3_t pos, vec3_t angles); +void render_set_view(vec3_t pos, vec3_t angles, float lrdist); void render_set_view_2d(void); void render_set_model_mat(mat4_t *m); void render_set_depth_write(bool enabled); diff --git a/src/render_gl.c b/src/render_gl.c index f09b49b..0b781e6 100644 --- a/src/render_gl.c +++ b/src/render_gl.c @@ -21,7 +21,7 @@ #include #endif - +int sbs = 0; // -1:left +1:rigth 0:no-sbs #include @@ -437,7 +437,7 @@ void render_init(vec2i_t screen_size) { prg_game = shader_game_init(); use_program(prg_game); - render_set_view(vec3(0, 0, 0), vec3(0, 0, 0)); + render_set_view(vec3(0, 0, 0), vec3(0, 0, 0), 0/*lrdist*/); render_set_model_mat(&mat4_identity()); glEnable(GL_CULL_FACE); @@ -575,15 +575,19 @@ vec2i_t render_size(void) { void render_frame_prepare(void) { use_program(prg_game); glBindFramebuffer(GL_FRAMEBUFFER, backbuffer); - glViewport(0, 0, backbuffer_size.x, backbuffer_size.y); + glViewport(sbs? (sbs + 1) * backbuffer_size.x / 4: 0, 0, backbuffer_size.x / (!!sbs + 1), backbuffer_size.y); glBindTexture(GL_TEXTURE_2D, atlas_texture); glUniform2f(prg_game->uniform.screen, 0, 0); glEnable(GL_DEPTH_TEST); glDepthMask(true); glDisable(GL_POLYGON_OFFSET_FILL); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if (sbs <= 0) + { + // only when rendering total of left + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } glEnable(GL_DEPTH_TEST); } @@ -599,8 +603,12 @@ void render_frame_end(void) { glUniform1f(prg_post->uniform.time, system_cycle_time()); glUniform2f(prg_post->uniform.screen_size, screen_size.x, screen_size.y); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if (sbs <= 0) + { + // only when rendering total of left + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } rgba_t white = rgba(128,128,128,255); tris_buffer[tris_len++] = (tris_t){ @@ -638,13 +646,14 @@ void render_flush(void) { } -void render_set_view(vec3_t pos, vec3_t angles) { +void render_set_view(vec3_t pos, vec3_t angles, float lrdist) { render_flush(); render_set_depth_write(true); render_set_depth_test(true); view_mat = mat4_identity(); - mat4_set_translation(&view_mat, vec3(0, 0, 0)); + mat4_set_translation(&view_mat, vec3(-lrdist, 0, 0)); + mat4_set_roll_pitch_yaw(&view_mat, vec3(angles.x, -angles.y + M_PI, angles.z + M_PI)); mat4_translate(&view_mat, vec3_inv(pos)); mat4_set_yaw_pitch_roll(&sprite_mat, vec3(-angles.x, angles.y - M_PI, 0)); diff --git a/src/system.c b/src/system.c index 7440ba5..4d3918a 100644 --- a/src/system.c +++ b/src/system.c @@ -43,11 +43,23 @@ void system_update(void) { cycle_time -= 3600 * M_PI; } + // render total (sbs==0) or left (sbs==-1) + render_frame_prepare(); game_update(); render_frame_end(); + + if (sbs) + { + sbs = 1; // now render right + render_frame_prepare(); + game_update(); + render_frame_end(); + sbs = -1; + } + input_clear(); mem_temp_check(); } diff --git a/src/utils.h b/src/utils.h index dcebb31..bb9fe7b 100644 --- a/src/utils.h +++ b/src/utils.h @@ -4,6 +4,8 @@ #include #include "types.h" +extern int sbs; // side by side -1:left 0:no-sbs +1:right + #ifdef WIN32 #undef min #undef max diff --git a/src/wipeout/game.c b/src/wipeout/game.c index f2c16bc..8bd139c 100755 --- a/src/wipeout/game.c +++ b/src/wipeout/game.c @@ -417,6 +417,9 @@ save_t save = { [A_THRUST] = {INPUT_KEY_X, INPUT_GAMEPAD_A}, [A_FIRE] = {INPUT_KEY_Z, INPUT_GAMEPAD_X}, [A_CHANGE_VIEW] = {INPUT_KEY_A, INPUT_GAMEPAD_Y}, + [A_TOGGLE_SBS] = {INPUT_KEY_I, INPUT_INVALID}, + [A_SBS_MORE] = {INPUT_KEY_P, INPUT_INVALID}, + [A_SBS_LESS] = {INPUT_KEY_O, INPUT_INVALID}, }, .analog_response = 2, // Exponent for stick turn input diff --git a/src/wipeout/game.h b/src/wipeout/game.h index 98e789c..2dd46ae 100755 --- a/src/wipeout/game.h +++ b/src/wipeout/game.h @@ -29,6 +29,9 @@ typedef enum { A_THRUST, A_FIRE, A_CHANGE_VIEW, + A_TOGGLE_SBS, + A_SBS_MORE, + A_SBS_LESS, NUM_GAME_ACTIONS, A_MENU_UP, diff --git a/src/wipeout/main_menu.c b/src/wipeout/main_menu.c index 7dd0b3f..b54cb0c 100755 --- a/src/wipeout/main_menu.c +++ b/src/wipeout/main_menu.c @@ -37,7 +37,7 @@ static struct { } models; static void draw_model(Object *model, vec2_t offset, vec3_t pos, float rotation) { - render_set_view(vec3(0,0,0), vec3(0, -M_PI, -M_PI)); + render_set_view(vec3(0,0,0), vec3(0, -M_PI, -M_PI), 0/*lrdist*/); render_set_screen_position(offset); mat4_t mat = mat4_identity(); mat4_set_translation(&mat, pos); @@ -263,7 +263,9 @@ static void page_options_controls_init(menu_t *menu) { menu_page_add_button(page, A_THRUST, "THRUST", page_options_controls_set_init); menu_page_add_button(page, A_FIRE, "FIRE", page_options_controls_set_init); menu_page_add_button(page, A_CHANGE_VIEW, "VIEW", page_options_controls_set_init); - + menu_page_add_button(page, A_TOGGLE_SBS, "3D SBS", page_options_controls_set_init); + menu_page_add_button(page, A_SBS_MORE, "SBS MORE", page_options_controls_set_init); + menu_page_add_button(page, A_SBS_LESS, "SBS LESS", page_options_controls_set_init); menu_page_add_toggle(page, save.analog_response - 1, "ANALOG RESPONSE", analog_response, len(analog_response), toggle_analog_response); } diff --git a/src/wipeout/menu.c b/src/wipeout/menu.c index 4cd005a..818a373 100644 --- a/src/wipeout/menu.c +++ b/src/wipeout/menu.c @@ -84,6 +84,8 @@ void menu_update(menu_t *menu) { // Handle menu entry selecting int last_index = page->index; int selected_data = 0; + if (sbs <= 0) + { if (page->entries_len > 0) { if (flags_is(page->layout_flags, MENU_HORIZONTAL)) { if (input_pressed(A_MENU_LEFT)) { @@ -114,7 +116,7 @@ void menu_update(menu_t *menu) { } selected_data = page->entries[page->index].data; } - + } if (page->draw_func) { page->draw_func(menu, selected_data); } @@ -193,6 +195,8 @@ void menu_update(menu_t *menu) { } } + if (sbs <= 0) + { // Handle back buttons if (input_pressed(A_MENU_BACK) || input_pressed(A_MENU_QUIT)) { if (menu->index != 0) { @@ -201,6 +205,7 @@ void menu_update(menu_t *menu) { } return; } + } if (page->entries_len == 0) { return; @@ -210,6 +215,8 @@ void menu_update(menu_t *menu) { // Handle toggle entries menu_entry_t *entry = &page->entries[page->index]; + if (sbs <= 0) + { if (entry->type == MENU_ENTRY_TOGGLE) { if (input_pressed(A_MENU_LEFT)) { sfx_play(SFX_MENU_SELECT); @@ -242,4 +249,5 @@ void menu_update(menu_t *menu) { } } } + } } diff --git a/src/wipeout/race.c b/src/wipeout/race.c index 85ed783..131dafd 100755 --- a/src/wipeout/race.c +++ b/src/wipeout/race.c @@ -29,6 +29,7 @@ static bool menu_is_scroll_text = false; static bool has_show_credits = false; static float attract_start_time; static menu_t *active_menu = NULL; +static float lrdist = 150; void race_init(void) { ingame_menus_load(); @@ -68,6 +69,8 @@ void race_init(void) { } void race_update(void) { + if (sbs <= 0) + { if (is_paused) { if (!active_menu) { active_menu = pause_menu_init(); @@ -101,9 +104,22 @@ void race_update(void) { } } + if (input_pressed(A_TOGGLE_SBS)) { + sbs = sbs? 0: -1; + } + if (input_pressed(A_SBS_MORE)) { + lrdist += 10; + printf("+sbs = %g\n", lrdist); + } + if (input_pressed(A_SBS_LESS)) { + lrdist -= 10; + printf("-sbs = %g\n", lrdist); + } + } + // Draw 3D - render_set_view(g.camera.position, g.camera.angle); + render_set_view(g.camera.position, g.camera.angle, lrdist * sbs); render_set_screen_position(g.camera.shake); render_set_cull_backface(false);