diff --git a/src/config.h b/src/config.h index 18c1ce41..733585fe 100644 --- a/src/config.h +++ b/src/config.h @@ -5,8 +5,9 @@ * system. */ #define RESOURCES_EMBEDDED !(DEVELOPER) -//#define ASPECT_RATIO (16.0 / 9.0) -#define ASPECT_RATIO (4.0 / 3.0) +#define DEFAULT_CAMERA_WIDTH (6) +#define DEFAULT_CAMERA_ASPECT_RATIO (16.0 / 9.0) + #define PIXELS_PER_UNIT 256 #define GAME_FPS 50 diff --git a/src/entity.h b/src/entity.h index 97a59649..0ba06d81 100644 --- a/src/entity.h +++ b/src/entity.h @@ -95,7 +95,7 @@ struct entity { /* ENTITY_PROP_CAMERA */ struct entity_handle camera_follow; struct xform camera_target_xform; /* Calculated from camera_follow */ - f32 camera_zoom; + struct v2 camera_size; f32 camera_lerp; /* Rate at which camera xform approaches target xform */ u32 camera_lerp_gen; u32 camera_applied_lerp_gen_plus_one; /* Calculated */ diff --git a/src/game.c b/src/game.c index 7d13a81f..e7abda6b 100644 --- a/src/game.c +++ b/src/game.c @@ -205,7 +205,10 @@ INTERNAL void game_update(void) entity_enable_prop(e, ENTITY_PROP_CAMERA); entity_enable_prop(e, ENTITY_PROP_CAMERA_ACTIVE); e->camera_follow = player_ent->handle; - e->camera_zoom = 1; + + f32 width = (f32)DEFAULT_CAMERA_WIDTH; + f32 height = width / (f32)DEFAULT_CAMERA_ASPECT_RATIO; + e->camera_size = V2(width, height); } /* Sound ent */ @@ -473,8 +476,12 @@ INTERNAL void game_update(void) ent->camera_target_xform.og = target_pos; #else /* "Look" style camera */ + f32 aspect_ratio = 1.0; + if (!v2_eq(ent->camera_size, V2(0, 0))) { + aspect_ratio = ent->camera_size.x / ent->camera_size.y; + } f32 ratio_y = 0.33f; - f32 ratio_x = ratio_y / (f32)ASPECT_RATIO; + f32 ratio_x = ratio_y / aspect_ratio; struct v2 camera_focus_dir = v2_mul_v2(follow->player_aim, V2(ratio_x, ratio_y)); struct v2 camera_focus_pos = v2_add(follow->world_xform.og, camera_focus_dir); ent->camera_target_xform.og = camera_focus_pos; diff --git a/src/renderer_d3d11.c b/src/renderer_d3d11.c index 7fd20cde..4f6d2adb 100644 --- a/src/renderer_d3d11.c +++ b/src/renderer_d3d11.c @@ -655,7 +655,6 @@ void renderer_canvas_release(struct renderer_canvas *canvas) arena_release(&buffer->index_arena); /* FIXME: Clear GPU buffers */ - } } diff --git a/src/settings.c b/src/settings.c index 880e2927..0891718c 100644 --- a/src/settings.c +++ b/src/settings.c @@ -98,7 +98,7 @@ struct sys_window_settings settings_default_window_settings(struct sys_window *w struct v2 monitor_size = sys_window_get_monitor_size(window); i32 width = 1280; - i32 height = math_round(width / (f32)ASPECT_RATIO); + i32 height = math_round(width / (f32)DEFAULT_CAMERA_ASPECT_RATIO); i32 x = math_round(monitor_size.x / 2.f - width / 2); i32 y = math_round(monitor_size.y / 2.f - height / 2); diff --git a/src/user.c b/src/user.c index 23c3a022..f49acd9f 100644 --- a/src/user.c +++ b/src/user.c @@ -38,7 +38,6 @@ GLOBAL struct { struct renderer_canvas *world_canvas; struct renderer_canvas *viewport_bg_canvas; struct renderer_canvas *viewport_canvas; - struct xform world_view_last_frame; struct xform world_view; struct blend_tick *head_free_blend_tick; @@ -342,33 +341,7 @@ INTERNAL void user_update(void) f64 cur_time = sys_timestamp_seconds(sys_timestamp()); L.dt = max_f64(0.0, cur_time - L.time); L.time += L.dt; - - /* Calculate screen & viewport dimensions */ - { - /* Get screen dimensions */ - L.screen_size = sys_window_get_size(L.window); - - /* Enforce viewport at aspect ratio */ - f32 aspect_ratio = ASPECT_RATIO; - f32 width = L.screen_size.x; - f32 height = L.screen_size.y; - if (width / height > aspect_ratio) { - width = height * aspect_ratio; - } else { - height = (f32)math_ceil(width / aspect_ratio); - } - L.viewport_size = V2(width, height); - - /* Center viewport in window */ - f32 x = 0; - f32 y = 0; - x = math_round(L.screen_size.x / 2 - width / 2); - y = math_round(L.screen_size.y / 2 - height / 2); - L.viewport_screen_offset = V2(x, y); - - /* Get center */ - L.viewport_center = v2_mul(L.viewport_size, 0.5); - } + L.screen_size = sys_window_get_size(L.window); /* ========================== * * Produce interpolated tick @@ -426,7 +399,7 @@ INTERNAL void user_update(void) e->sprite_xform = xform_lerp(e0->sprite_xform, e1->sprite_xform, tick_blend); e->animation_time_in_frame = math_lerp_f64(e0->animation_time_in_frame, e1->animation_time_in_frame, (f64)tick_blend); - e->camera_zoom = math_lerp(e0->camera_zoom, e1->camera_zoom, tick_blend); + e->camera_size = v2_lerp(e0->camera_size, e1->camera_size, tick_blend); e->camera_target_xform = xform_lerp(e0->camera_target_xform, e1->camera_target_xform, tick_blend); } } @@ -497,7 +470,6 @@ INTERNAL void user_update(void) /* Update mouse pos */ if (event->kind == SYS_EVENT_KIND_CURSOR_MOVE) { L.screen_cursor = event->cursor_position; - L.viewport_cursor = v2_sub(L.screen_cursor, L.viewport_screen_offset);; } /* Update bind states */ @@ -548,12 +520,6 @@ INTERNAL void user_update(void) } } - /* ========================== * - * Update view - * ========================== */ - - L.world_view_last_frame = L.world_view; - if (L.bind_states[USER_BIND_KIND_DEBUG_DRAW].num_presses > 0) { L.debug_draw = !L.debug_draw; } @@ -562,6 +528,46 @@ INTERNAL void user_update(void) L.debug_camera = !L.debug_camera; } + + /* ========================== * + * Update viewport + * ========================== */ + + /* Calculate screen viewport dimensions */ + if (L.debug_camera) { + L.viewport_size = L.screen_size; + L.viewport_screen_offset = V2(0, 0); + } else { + + /* Determine viewport size by camera & window dimensions */ + f32 aspect_ratio = 1.0; + if (!v2_eq(active_camera->camera_size, V2(0, 0))) { + aspect_ratio = active_camera->camera_size.x / active_camera->camera_size.y; + } + f32 width = L.screen_size.x; + f32 height = L.screen_size.y; + if (width / height > aspect_ratio) { + width = height * aspect_ratio; + } else { + height = (f32)math_ceil(width / aspect_ratio); + } + L.viewport_size = V2(width, height); + + /* Center viewport in window */ + f32 x = 0; + f32 y = 0; + x = math_round(L.screen_size.x / 2 - width / 2); + y = math_round(L.screen_size.y / 2 - height / 2); + L.viewport_screen_offset = V2(x, y); + } + + L.viewport_center = v2_mul(L.viewport_size, 0.5); + L.viewport_cursor = v2_sub(L.screen_cursor, L.viewport_screen_offset); + + /* ========================== * + * Update view + * ========================== */ + if (L.debug_camera) { /* Pan view */ if (L.bind_states[USER_BIND_KIND_PAN].is_held) { @@ -602,13 +608,18 @@ INTERNAL void user_update(void) } else { struct v2 center = active_camera->world_xform.og; f32 rot = xform_get_rotation(active_camera->world_xform); - f32 zoom = active_camera->camera_zoom; - zoom = zoom > 0 ? zoom : 1; + + /* Scale view into viewport based on camera size */ + struct v2 size = L.viewport_size; + if (!v2_eq(active_camera->camera_size, V2(0, 0))) { + size = v2_div_v2(size, active_camera->camera_size); + } + f32 scale = min_f32(size.x, size.y); struct trs trs = TRS( .t = v2_sub(L.viewport_center, center), .r = rot, - .s = v2_mul(V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT), zoom) + .s = V2(scale, scale) ); struct v2 pivot = center;