diff options
Diffstat (limited to 'source')
| -rwxr-xr-x | source/main.cpp | 420 | 
1 files changed, 286 insertions, 134 deletions
diff --git a/source/main.cpp b/source/main.cpp index 214ddff..3aba2d3 100755 --- a/source/main.cpp +++ b/source/main.cpp @@ -77,9 +77,9 @@ enum GameScreen {  };  enum PMoveState { -  NO_MOVE       = 0, -  MOVE          = 1, -  FALL_MOVE     = 2, +    NO_MOVE       = 0, +    MOVE          = 1, +    FALL_MOVE     = 2,  };  enum PlatformKey { @@ -113,7 +113,6 @@ static r32 entity_z[10];  static Vec3 entity_colors[10];  struct Entity { -    // @todo: set a base resolution and design the game elements around it      s32 id;      ENTITY_TYPE type;      // raw property values in pixels @@ -217,14 +216,40 @@ void enforce_frame_rate(FrameTimer *ft, u32 target) {    }  } +struct GameplayState { + +    r32 jump_count; +    r64 jump_timer; +    r32 fall_accelx; +    r32 move_accelx; +    r32 max_speedx; +    r32 freefall_accel; +    r32 jump_force; +    r32 effective_force; + +    Vec2 camera_pan_slow; + +    Vec2 player_velocity; + +    Vec2 p_move_dir; +    Vec2 p_motion_dir; +}; +  struct GameState { +    SDL_Window *window;      // the default size the game is designed around      Vec2 screen_size; +    // base resolution game is designed for +    Vec2 source_dims; +    // current resolution game needs to be scaled (up/down) to +    Vec2 render_dims;      // the scaling factor to increase/decrease size of game assets      Vec2 render_scale;      // the smallest size a unit can be. This scales with render_scale      Vec2 atom_size;      Rect camera_bounds; +    Vec2 cam_lt_limit; +    Vec2 cam_rb_limit;      // level      // 0: in progress, 1: complete @@ -241,6 +266,7 @@ struct GameState {      b8 mouse_down;      b8 mouse_up;      // gameplay +    GameplayState gameplay;      b8 flip_gravity;      b8 inside_teleporter;      b8 teleporting; @@ -298,6 +324,22 @@ Entity get_entity_by_id(GameState state, u32 id) {      return res;  } +void resize_level_elements(GameState *state) { +    for (u32 i = 0; i < state->game_level.entity_count; i++) { +	Entity e = state->game_level.entities[i]; +	e.position = Vec3{ +	    e.raw_position.x * state->render_scale.x, +	    e.raw_position.y * state->render_scale.y, +	    e.raw_position.z +	}; +	e.size = e.raw_size * state->atom_size; +	e.bounds = rect(e.position.v2(), e.size); + +	state->game_level.entities[i] = e; +    } + +} +  void load_level(GameState *state, Arena *level_arena, Str256 level_path) {      // @step: initialise level state variables      arena_clear(level_arena); @@ -461,9 +503,9 @@ void setup_level(GameState *state, GLRenderer *renderer, Arena *arena)      load_level(state, arena, level_path);      Entity goal = state->game_level.entities[state->goal.index]; -    Vec2 scr_dims;      renderer->cam_pos.x = goal.position.x - (state->screen_size.x/2.0f * state->render_scale.x);      renderer->cam_pos.y = goal.position.y - (state->screen_size.y/2.0f * state->render_scale.y); +      state->effective_force = 0.0f;      state->player_velocity = Vec2{0.0f, 0.0f};      state->gravity_diry = 1.0f; @@ -489,21 +531,25 @@ Vec2 get_move_dir(Controller c) {    return dir;  } -void update_camera(GLRenderer *renderer) { -  if (renderer->cam_update == true) { -    renderer->cam_view = camera_create4m( -      renderer->cam_pos,  -      add3v(renderer->cam_pos, renderer->cam_look),  -      renderer->preset_up_dir +void update_camera(GameState *state) { +  if (state->renderer.cam_update == true) { +    state->renderer.cam_view = camera_create4m( +      state->renderer.cam_pos,  +      add3v(state->renderer.cam_pos, state->renderer.cam_look),  +      state->renderer.preset_up_dir      ); -    renderer->cam_update = false; +    state->renderer.cam_update = false; +    state->camera_bounds = rect( +	    state->renderer.cam_pos.v2(),  +	    state->render_dims +	    );    }  }  Vec2 get_screen_position_from_percent(GameState state, Vec2 v) {    Vec2 screen_pos = v; -  screen_pos.x = state.render_scale.x*state.screen_size.x*v.x/100.0f; -  screen_pos.y = state.render_scale.y*state.screen_size.y*v.y/100.0f; +  screen_pos.x = state.screen_size.x*v.x/100.0f; +  screen_pos.y = state.screen_size.y*v.y/100.0f;    return screen_pos;  } @@ -581,9 +627,10 @@ Vec2 ui_get_text_dims(GLRenderer renderer, char *text, r32 font_size) {  // for an immediate mode button  ButtonState ui_button(GameState state, UiButton button) {      ButtonState btn_state = ButtonState::NONE; -    Vec2 pos = get_screen_position_from_percent( -	state, button.position.v2() -    ); +    Vec2 pos = Vec2{ +        button.position.x, button.position.y +    }; +      Vec2 quad_size = button.size * state.render_scale;      // @step: get text size and position @@ -689,8 +736,6 @@ Vec2 ui_center_text(  }  void ui_dropdown_button(GameState state, UiDropdownButton *dropdown) { -    r32 font_size = dropdown->font_size * state.render_scale.y; -      // @component: value_box      Vec3 value_pos = Vec3{  	dropdown->position.x*state.render_scale.x, @@ -700,6 +745,8 @@ void ui_dropdown_button(GameState state, UiDropdownButton *dropdown) {      Vec2 value_size = dropdown->size*state.render_scale; +    r32 font_size = value_size.y * 0.6f; +      Vec3 value_pos_adjusted = value_pos;      value_pos_adjusted.x += value_size.x/2.0f;      value_pos_adjusted.y += value_size.y/2.0f; @@ -749,7 +796,7 @@ void ui_dropdown_button(GameState state, UiDropdownButton *dropdown) {      Vec2 value_text_pos = ui_center_text(  	    state,  	    value_text, -	    dropdown->font_size, +	    font_size,  	    value_pos.v2(),  	    value_size); @@ -768,7 +815,7 @@ void ui_dropdown_button(GameState state, UiDropdownButton *dropdown) {  		value_text_pos.y,  		value_pos.z},  	    Vec3{0.0f, 0.0f, 0.0f}, -	    dropdown->font_size); +	    font_size);      // @component: dropdown_option      if (dropdown->is_toggled) { @@ -813,7 +860,7 @@ void ui_dropdown_button(GameState state, UiDropdownButton *dropdown) {  	    Vec2 txt_pos = ui_center_text(  		    state,  		    dropdown_text, -		    dropdown->font_size, +		    font_size,  		    option_pos.v2(),  		    option_size); @@ -836,17 +883,79 @@ void ui_dropdown_button(GameState state, UiDropdownButton *dropdown) {  			txt_pos.y,  			option_pos.z},  		    Vec3{0.0f, 0.0f, 0.0f}, -		    dropdown->font_size); +		    font_size);  	}      }  } +void init_gameplay_variables(GameState *state) { +    Vec2 motion_scale = state->render_scale*2.0f; + +    state->gameplay.jump_count = 1; +    state->gameplay.jump_timer = 0; +    state->gameplay.fall_accelx = 3.0f*motion_scale.x; +    state->gameplay.move_accelx = 4.0f*motion_scale.x; +    state->gameplay.max_speedx = 5.0f*motion_scale.x; +    state->gameplay.freefall_accel = -11.8f*motion_scale.y; +    state->gameplay.jump_force = 6.5f*motion_scale.y; +    state->gameplay.effective_force = 0.0f; + +    state->gameplay.camera_pan_slow = Vec2{2.0f, 2.0f}*motion_scale; +    state->gameplay.player_velocity = Vec2{0.0f, 0.0f}; +    state->gameplay.p_move_dir = Vec2{0.0f, 0.0f}; +    state->gameplay.p_motion_dir = Vec2{0.0f, 0.0f}; +} + +void init_display_elements(GameState *state) { + +    glViewport(0, 0, state->render_dims.x, state->render_dims.y); +    // ========== +    // setup text +    // setup stb_truetype stuff + + +    state->screen_size = state->render_dims; +    state->atom_size = Vec2{64.0f, 64.0f}*state->render_scale; +    init_gameplay_variables(state); +    resize_level_elements(state); + +    // update camera position on rescaled goal +    state->renderer.cam_proj = orthographic4m( +	    0.0f, (r32)state->render_dims.x, +	    0.0f, (r32)state->render_dims.y, +	    0.1f, 15.0f); +    state->renderer.cam_update = 1; +    state->renderer.ui_cam.update = 1; +    state->renderer.ui_cam.proj = state->renderer.cam_proj; +    state->camera_bounds = rect( +	    state->renderer.cam_pos.v2(), +	    state->screen_size); +    state->cam_lt_limit = get_screen_position_from_percent( +	    *state, Vec2{30.0f, 70.0f} +	    ); + +    state->cam_rb_limit = get_screen_position_from_percent( +	    *state, Vec2{70.0f, 30.0f} +	    ); + +} + +void update_resolution(GameState *state, IVec2 resolution) { +    state->render_dims = Vec2{(r32)resolution.x, (r32)resolution.y}; +    state->render_scale = state->render_dims/state->source_dims; +    s32 display_ind = SDL_GetWindowDisplayIndex(state->window); +    SDL_SetWindowSize(state->window, resolution.x, resolution.y); +    init_display_elements(state); +} +  // @section: main  int main(int argc, char* argv[])  { -    Vec2 scr_dims = Vec2{1920, 1080}; +    Vec2 source_dims = Vec2{1920, 1080}; -    Vec2 render_dims = Vec2{1920, 1080}; +    GameState state = {0}; +    state.source_dims = source_dims; +    state.render_dims = Vec2{1920, 1080};    {        // entity configs setup @@ -881,12 +990,13 @@ int main(int argc, char* argv[])    SDL_Window* window = SDL_CreateWindow("simple platformer",                                          SDL_WINDOWPOS_UNDEFINED,                                           SDL_WINDOWPOS_UNDEFINED, -                                        render_dims.x, render_dims.y, +                                        state.render_dims.x, state.render_dims.y,                                          SDL_WINDOW_OPENGL  //					| SDL_WINDOW_FULLSCREEN_DESKTOP  					); +  state.window = window; -  SDL_GLContext context = SDL_GL_CreateContext(window); +  SDL_GLContext context = SDL_GL_CreateContext(state.window);    if (!context)    {      printf("ERROR :: OpenGL context creation failed: %s\n", SDL_GetError()); @@ -902,7 +1012,6 @@ int main(int argc, char* argv[])    // vsync controls: 0 = OFF | 1 = ON (Default)    SDL_GL_SetSwapInterval(0); -  GameState state = {0};    enum GameScreen game_screen = GAMEPLAY;    GLRenderer *renderer = &state.renderer;    memset(renderer, 0, sizeof(GLRenderer)); @@ -948,7 +1057,8 @@ int main(int argc, char* argv[])    gl_setup_line_batch(renderer, cq_batch_sp); -  Vec2 render_scale = Vec2{(r32)render_dims.x/scr_dims.x, (r32)render_dims.y/scr_dims.y}; +  Vec2 render_scale = Vec2{(r32)state.render_dims.x/source_dims.x, (r32)state.render_dims.y/source_dims.y}; +  // @todo: classify variables that require reloading on resolution change  {      // ==========      // setup text @@ -960,7 +1070,6 @@ int main(int argc, char* argv[])      renderer->ui_text.sp = ui_text_sp;      renderer->ui_text.chunk_size = 128; -    renderer->ui_text.pixel_size = 32*render_scale.x;      renderer->ui_text.transforms = (Mat4*)malloc(        renderer->ui_text.chunk_size*sizeof(Mat4)      ); @@ -971,6 +1080,7 @@ int main(int argc, char* argv[])        128*sizeof(TextChar)      ); +    renderer->ui_text.pixel_size = 32*render_scale.x;      gl_setup_text(&renderer->ui_text);  } @@ -987,19 +1097,18 @@ int main(int argc, char* argv[])      add3v(renderer->cam_pos, renderer->cam_look), renderer->preset_up_dir    );    renderer->cam_proj = orthographic4m( -    0.0f, (r32)render_dims.x, -    0.0f, (r32)render_dims.y, +    0.0f, (r32)state.render_dims.x, +    0.0f, (r32)state.render_dims.y,      0.1f, 15.0f    );    // fixed_screen_camera    renderer->ui_cam.update = 1;    renderer->ui_cam.pos = renderer->cam_pos;    renderer->ui_cam.look = renderer->cam_look; -  renderer->ui_cam.view = renderer->cam_view; +  renderer->ui_cam.view = diag4m(1.0f);    renderer->ui_cam.proj = renderer->cam_proj;    // ui stuff -      UiDropdownButton resolution_select = {0};      resolution_select.font_size = 24.0f;      resolution_select.size = Vec2{120.0f, 40.0f}; @@ -1007,7 +1116,7 @@ int main(int argc, char* argv[])      resolution_select.bgd_color_secondary = Vec3{0.6f, 0.6f, 0.6f};      resolution_select.bgd_color_hover = Vec3{0.8f, 0.8f, 0.8f};      resolution_select.bgd_color_pressed = Vec3{0.4f, 0.4f, 0.4f}; -    resolution_select.option_count = 3; +    resolution_select.option_count = 4;      // @todo: Remove this memory allocation method      // Use a lifetime tied arena      resolution_select.options =  (Str256 *)malloc( @@ -1018,6 +1127,13 @@ int main(int argc, char* argv[])      resolution_select.options[0] = str256("2560 x 1440");      resolution_select.options[1] = str256("1920 x 1080");      resolution_select.options[2] = str256("1280 x 720"); +    resolution_select.options[3] = str256("1024 x 728"); +    IVec2 resolution_options[4] = { +	IVec2{2560, 1440}, +	IVec2{1920, 1080}, +	IVec2{1280, 720}, +	IVec2{1024, 768} +    };    // @thinking: level object handling    // there should be a most smallest supported unit @@ -1025,40 +1141,19 @@ int main(int argc, char* argv[])    // object placement should be in pixels     // in order to scale to different resolutions it should be multiplied by    // scaling factor -  Vec2 atom_size = Vec2{64.0f, 64.0f}*render_scale; - -  state.atom_size = atom_size; -  state.screen_size = scr_dims; +  state.atom_size = Vec2{64.0f, 64.0f}*render_scale;    state.render_scale = render_scale; -  Vec2 camera_screen_size = state.screen_size * state.render_scale; +  state.screen_size = state.render_dims;    state.level_path_base = str256(base_level_path);    // @section: gameplay variables -  u32 jump_count = 1; -  r64 jump_timer = 0; -  r32 motion_scale = 2.0f*state.render_scale.x; -  state.gravity_diry = 1.0f; -  r32 fall_accelx = 3.0f*motion_scale; -  r32 move_accelx = 4.0f*motion_scale; -  r32 max_speedx = 5.0f*motion_scale; -  r32 freefall_accel = -11.8f*motion_scale; -  r32 jump_force = 6.5f*motion_scale; -  state.effective_force = 0.0f; -  Vec2 camera_pan_slow = Vec2{2.0f, 2.0f}*motion_scale; - -  state.player_velocity = Vec2{0.0f, 0.0f}; -  Vec2 p_move_dir = Vec2{0.0f, 0.0f}; -  // direction in which player is effectively travelling -  Vec2 p_motion_dir = Vec2{0.0f, 0.0f}; - - -  // @todo: rename rect members (makes more sense) -  // tl -> lt -  // br -> rb -  state.camera_bounds = rect(renderer->cam_pos.v2(), camera_screen_size); +  init_gameplay_variables(&state); + +  state.camera_bounds = rect( +	  renderer->cam_pos.v2(),  +	  state.screen_size);    // @section: level elements -      // @step: init_level_arena    size_t max_level_entities = 255;    size_t arena_mem_size = GB(1); @@ -1069,12 +1164,10 @@ int main(int argc, char* argv[])    setup_level(&state, &state.renderer, &level_arena);    // gameplay camera movement stuff -  Vec2 cam_lt_limit = {0}; -  Vec2 cam_rb_limit = {0}; -  cam_lt_limit = get_screen_position_from_percent( +  state.cam_lt_limit = get_screen_position_from_percent(      state, Vec2{30.0f, 70.0f}    ); -  cam_rb_limit = get_screen_position_from_percent( +  state.cam_rb_limit = get_screen_position_from_percent(      state, Vec2{70.0f, 30.0f}    ); @@ -1114,14 +1207,20 @@ int main(int argc, char* argv[])  	case (SDL_MOUSEBUTTONUP):  	    {  		SDL_GetMouseState(&state.mouse_position.x, &state.mouse_position.y); -		state.mouse_position.y = render_dims.y - state.mouse_position.y; +		state.mouse_position.y = state.render_dims.y - state.mouse_position.y; + +		//state.mouse_position.x = state.mouse_position.x * (r32)state.render_scale.x; +	      	//state.mouse_position.y = state.mouse_position.y * (r32)state.render_scale.y;  		state.mouse_down = 0;  		state.mouse_up = 1;  	    } break;  	case (SDL_MOUSEBUTTONDOWN):  	    {  		u32 btn_x = SDL_GetMouseState(&state.mouse_position.x, &state.mouse_position.y); -		state.mouse_position.y = render_dims.y - state.mouse_position.y; +		state.mouse_position.y = state.render_dims.y - state.mouse_position.y; + +		//state.mouse_position.x = state.mouse_position.x * (r32)state.render_scale.x; +	      	//state.mouse_position.y = state.mouse_position.y * (r32)state.render_scale.y;  		if (SDL_BUTTON(btn_x) == SDL_BUTTON(SDL_BUTTON_LEFT)) {  		    state.mouse_down = 1;  		    state.mouse_up = 0; @@ -1131,13 +1230,16 @@ int main(int argc, char* argv[])  	  {  	      SDL_GetMouseState(&state.mouse_position.x, &state.mouse_position.y);  	      // flip mouse y to map it Y at Top -> Y at Bottom (like in maths) -	      state.mouse_position.y = render_dims.y - state.mouse_position.y; +	      state.mouse_position.y = state.render_dims.y - state.mouse_position.y; + +	      //state.mouse_position.x = state.mouse_position.x * (r32)state.render_scale.x; +	      //state.mouse_position.y = state.mouse_position.y * (r32)state.render_scale.y;  	      // get mouse world position  	      mouse_position_world.x = state.mouse_position.x + (s32)renderer->cam_pos.x;  	      mouse_position_world.y = state.mouse_position.y + (s32)renderer->cam_pos.y;  	      // clamp mouse position based off of the grids we draw (this will make level object placement easier) -	      mouse_position_clamped.x = mouse_position_world.x - ((mouse_position_world.x) % (s32)(atom_size.x)); -	      mouse_position_clamped.y = mouse_position_world.y - ((mouse_position_world.y) % (s32)(atom_size.y)); +	      mouse_position_clamped.x = mouse_position_world.x - ((mouse_position_world.x) % (s32)(state.atom_size.x)); +	      mouse_position_clamped.y = mouse_position_world.y - ((mouse_position_world.y) % (s32)(state.atom_size.y));  	  } break;          case (SDL_KEYDOWN): @@ -1151,14 +1253,20 @@ int main(int argc, char* argv[])  		s32 display_ind = SDL_GetWindowDisplayIndex(window);  		SDL_Rect win_rect;  		s8 res = SDL_GetDisplayBounds(display_ind, &win_rect); +		win_rect.w = 1920; +		win_rect.h = 1080;  		if (!res) { -		    static bool fullscreen = true; +		    static bool fullscreen = false;  		    int desktop_flag = fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP; -		    SDL_SetWindowFullscreen(window, desktop_flag); -		    int ww, wh = 0; -		    SDL_SetWindowSize(window, render_dims.x, render_dims.y); +		    Vec2 resolution = fullscreen ? Vec2{1280, 720}: Vec2{(r32)win_rect.w, (r32)win_rect.h}; +		    //SDL_SetWindowFullscreen(window, desktop_flag); + +		    state.render_dims = resolution; +		    SDL_SetWindowSize(window, state.render_dims.x, state.render_dims.y);  		    fullscreen = !fullscreen; -		    // @note: I may need to recreate the entire opengl context and what not + +		    //state.render_scale = state.source_dims/state.render_dims; +		    init_display_elements(&state);  		}  		int brk = 1; @@ -1262,17 +1370,17 @@ int main(int argc, char* argv[])  	{  	  is_gravity = !is_gravity;  	  state.player_velocity = Vec2{0.0f, 0.0f}; -	  p_move_dir.x = 0.0f; +	  state.gameplay.p_move_dir.x = 0.0f;  	  state.effective_force = 0.0f; -	  p_motion_dir = {0}; +	  state.gameplay.p_motion_dir = {0};  	}  	if (controller.move_up)  	{ -	  p_move_dir.y = 1.0f; +	  state.gameplay.p_move_dir.y = 1.0f;  	}  	if (controller.move_down)  	{ -	  p_move_dir.y = -1.0f; +	  state.gameplay.p_move_dir.y = -1.0f;  	}  	PlatformKey horizontal_move = PK_NIL; @@ -1288,30 +1396,31 @@ int main(int argc, char* argv[])  	if (horizontal_move == PK_A && controller.move_left)   	{ -	  p_move_dir.x = -1.0f; +	  state.gameplay.p_move_dir.x = -1.0f;  	  is_key_down_x = true;  	}   	if (horizontal_move == PK_D && controller.move_right)   	{ -	  p_move_dir.x = 1.0f; +	  state.gameplay.p_move_dir.x = 1.0f;  	  is_key_down_x = true;  	} -	if (controller.jump && jump_count > 0 && jump_timer > 100.0f) { +	if (controller.jump && state.gameplay.jump_count > 0 &&  +		state.gameplay.jump_timer > 100.0f) {  	    controller.jump = 1; -	    jump_count--; -	    jump_timer = 0.0f; +	    state.gameplay.jump_count--; +	    state.gameplay.jump_timer = 0.0f;  	} else {  	    controller.jump = 0;  	}  	// jump increment -	jump_timer += timer.tDeltaMS; +	state.gameplay.jump_timer += timer.tDeltaMS;  	if (is_collide_bottom == 1 && state.gravity_diry > 0.0f) { -	    jump_count = 1; +	    state.gameplay.jump_count = 1;  	}  	if (is_collide_top == 1 && state.gravity_diry < 0.0f) { -	    jump_count = 1; +	    state.gameplay.jump_count = 1;  	} @@ -1325,7 +1434,7 @@ int main(int argc, char* argv[])  	    state.flip_gravity = 0;  	}  	Vec2 pd_1 = Vec2{0.0f, 0.0f}; -	p_motion_dir = {0}; +	state.gameplay.p_motion_dir = {0};  	if (collidey)  	{  	  state.player_velocity.y = 0.0f; @@ -1346,18 +1455,24 @@ int main(int argc, char* argv[])  		  state.effective_force = 0.0f;  	      } else if (is_key_down_x) {  		  r32 updated_force = ( -			  state.effective_force + p_move_dir.x*move_accelx*timer.tDelta +			  state.effective_force + ( +			      state.gameplay.p_move_dir.x * +			      state.gameplay.move_accelx * +			      timer.tDelta +			      )  			  );  		  updated_force = clampf( -			  updated_force, -max_speedx, max_speedx +			  updated_force,  +			  -state.gameplay.max_speedx,  +			  state.gameplay.max_speedx  			  );  		  state.effective_force = updated_force;  	      } else {  		  r32 friction = 0.0f;  		  if (state.effective_force > 0.0f) { -		    friction = -move_accelx*timer.tDelta; +		    friction = -state.gameplay.move_accelx*timer.tDelta;  		  } else if (state.effective_force < 0.0f) { -		    friction = move_accelx*timer.tDelta; +		    friction = state.gameplay.move_accelx*timer.tDelta;  		  }  		  r32 updated_force = state.effective_force + friction;  		  state.effective_force = ( @@ -1376,22 +1491,30 @@ int main(int argc, char* argv[])  		  // allow more immediate feeling force, instead of the jump adding into net_force  		  // which gives off, more of a floaty feeling.  		  r32 threshed_force = roundf(net_force); -		  b8 move_dir_different = (threshed_force >= 0 && p_move_dir.x < 0) || (threshed_force <= 0 && p_move_dir.x > 0); +		  b8 move_dir_different = (threshed_force >= 0 && state.gameplay.p_move_dir.x < 0) || (threshed_force <= 0 && state.gameplay.p_move_dir.x > 0);  		  if (move_dir_different) { -		      active_force = p_move_dir.x*fall_accelx/2.0f; +		      active_force = ( +			      state.gameplay.p_move_dir.x * +			      state.gameplay.fall_accelx/2.0f +			      );  		      net_force = active_force;  		  }  	      } else {  		  if (is_key_down_x) {  		      // player is slowing down, in that case, we allow this movement. -		      b8 move_dir_opposite = (net_force > 0 && p_move_dir.x < 0) || (net_force < 0 && p_move_dir.x > 0); -		      if (move_dir_opposite || ABS(net_force) < fall_accelx*0.15f) +		      b8 move_dir_opposite = (net_force > 0 && state.gameplay.p_move_dir.x < 0) || (net_force < 0 && state.gameplay.p_move_dir.x > 0); +		      if (move_dir_opposite ||  +			      ABS(net_force) < state.gameplay.fall_accelx*0.15f)  		      { -			  active_force = p_move_dir.x*fall_accelx*timer.tDelta; -			  net_force = clampf(net_force + active_force, -fall_accelx, fall_accelx); +			  active_force = state.gameplay.p_move_dir.x * +			      state.gameplay.fall_accelx * timer.tDelta; +			  net_force = clampf( +				  net_force + active_force,  +				  -state.gameplay.fall_accelx,  +				  state.gameplay.fall_accelx);  		      }  		  }  -		  if (ABS(net_force) >= fall_accelx) { +		  if (ABS(net_force) >= state.gameplay.fall_accelx) {  		      // @note: air resistance   		      // (arbitrary force in opposite direction to reduce speed)  		      // reason: seems that it would work well for the case where @@ -1403,9 +1526,9 @@ int main(int argc, char* argv[])  		      b8 is_force_neg = state.effective_force < 0.0f;  		      r32 friction = 0.0f;  		      if (is_force_pos) { -			friction = -fall_accelx*timer.tDelta; +			friction = -state.gameplay.fall_accelx*timer.tDelta;  		      } else if (is_force_neg) { -			friction = fall_accelx*timer.tDelta; +			friction = state.gameplay.fall_accelx*timer.tDelta;  		      }  		      net_force += friction;  		  } @@ -1418,13 +1541,13 @@ int main(int argc, char* argv[])  	    // horizontal motion setting  	    r32 dx1 = state.effective_force;  	    if ( dx1 == 0.0f ) { -	      p_move_dir.x = 0.0f; +	      state.gameplay.p_move_dir.x = 0.0f;  	    }  	    if (dx1 < 0.0f) { -	      p_motion_dir.x = -1.0f; +	      state.gameplay.p_motion_dir.x = -1.0f;  	    } else if (dx1 > 0.0f) { -	      p_motion_dir.x = 1.0f; +	      state.gameplay.p_motion_dir.x = 1.0f;  	    }  	    state.player_velocity.x = dx1;  	    pd_1.x = dx1; @@ -1433,18 +1556,21 @@ int main(int argc, char* argv[])  	  {  	    // vertical motion when falling  	    r32 dy1 = state.player_velocity.y;  -	    dy1 = dy1 + state.gravity_diry * freefall_accel * timer.tDelta; +	    dy1 = dy1 + ( +		    state.gravity_diry *  +		    state.gameplay.freefall_accel *  +		    timer.tDelta);  	    if (controller.jump) { -	      dy1 = state.gravity_diry*jump_force; +	      dy1 = state.gravity_diry*state.gameplay.jump_force;  	      if (!collidey) {  		  // if we are in the air, the jump force is 75% of normal -		  dy1 = state.gravity_diry * jump_force * 0.75f; +		  dy1 = state.gravity_diry * state.gameplay.jump_force * 0.75f;  	      }  	    }  	    if (dy1 < state.gravity_diry * -0.01f) { -	      p_motion_dir.y = -state.gravity_diry; +	      state.gameplay.p_motion_dir.y = -state.gravity_diry;  	    } else if (dy1 > state.gravity_diry * 0.01f) { -	      p_motion_dir.y = state.gravity_diry; +	      state.gameplay.p_motion_dir.y = state.gravity_diry;  	    }  	    state.player_velocity.y = dy1;  	    pd_1.y = dy1; @@ -1456,14 +1582,14 @@ int main(int argc, char* argv[])  	    Vec2 dir = get_move_dir(controller);  	    pd_1 = dir * 8.0f * render_scale.x;  	    if (pd_1.x < 0.0f) { -	      p_motion_dir.x = -1.0f; +	      state.gameplay.p_motion_dir.x = -1.0f;  	    } else if (pd_1.x > 0.0f) { -	      p_motion_dir.x = 1.0f; +	      state.gameplay.p_motion_dir.x = 1.0f;  	    }  	    if (pd_1.y < 0.0f) { -	      p_motion_dir.y = -1.0f; +	      state.gameplay.p_motion_dir.y = -1.0f;  	    } else if (pd_1.y > 0.0f) { -	      p_motion_dir.y = 1.0f; +	      state.gameplay.p_motion_dir.y = 1.0f;  	    }  	} @@ -1694,8 +1820,14 @@ int main(int argc, char* argv[])  		r32 stepx_multiplier = player_camera_offset.x < 0 ? -1.0f : 1.0f;  		r32 stepy_multiplier = player_camera_offset.y < 0 ? -1.0f : 1.0f; -		r32 camera_stepx = stepx_multiplier * MIN(ABS(player_camera_offset.x), camera_pan_slow.x); -		r32 camera_stepy = stepy_multiplier * MIN(ABS(player_camera_offset.y), camera_pan_slow.y); +		r32 camera_stepx = stepx_multiplier * MIN( +			ABS(player_camera_offset.x),  +			state.gameplay.camera_pan_slow.x +			); +		r32 camera_stepy = stepy_multiplier * MIN( +			ABS(player_camera_offset.y),  +			state.gameplay.camera_pan_slow.y +			);  		Vec2 distance_scaler;	      		{ @@ -1731,25 +1863,33 @@ int main(int argc, char* argv[])  	    } -	    b8 player_moving_up = p_motion_dir.y == state.gravity_diry*1 && !is_collide_y; -	    b8 player_moving_down = p_motion_dir.y == state.gravity_diry*-1 && !is_collide_y; +	    b8 player_moving_up = ( +		    state.gameplay.p_motion_dir.y == state.gravity_diry*1 &&  +		    !is_collide_y +		    ); +	    b8 player_moving_down = ( +		    state.gameplay.p_motion_dir.y == state.gravity_diry*-1 &&  +		    !is_collide_y +		    );  	    player_camera_offset = player.position.v2() - renderer->cam_pos.v2();  	    // @step: player moving at edges of the screen -	    if (player_camera_offset.x <= cam_lt_limit.x && p_motion_dir.x == -1) { +	    if (player_camera_offset.x <= state.cam_lt_limit.x &&  +		    state.gameplay.p_motion_dir.x == -1) {  		renderer->cam_pos.x += pd_1.x;  		renderer->cam_update = 1;  	    } -	    if (player_camera_offset.y >= cam_lt_limit.y &&  +	    if (player_camera_offset.y >= state.cam_lt_limit.y &&   		    player_moving_up) {  		renderer->cam_pos.y += pd_1.y;  		renderer->cam_update = 1;  	    } -	    if (player_camera_offset.x >= cam_rb_limit.x && p_motion_dir.x == 1) { +	    if (player_camera_offset.x >= state.cam_rb_limit.x &&  +		    state.gameplay.p_motion_dir.x == 1) {  		renderer->cam_pos.x += pd_1.x;  		renderer->cam_update = 1;  	    } -	    if (player_camera_offset.y <= cam_rb_limit.y &&  +	    if (player_camera_offset.y <= state.cam_rb_limit.y &&   		    player_moving_down) {  		renderer->cam_pos.y += pd_1.y;  		renderer->cam_update = 1; @@ -1767,7 +1907,10 @@ int main(int argc, char* argv[])  		    renderer->preset_up_dir  		    );  	    renderer->cam_update = false; -	    state.camera_bounds = rect(renderer->cam_pos.v2(), camera_screen_size); +	    state.camera_bounds = rect( +		    renderer->cam_pos.v2(),  +		    state.render_dims +		    );  	}      } @@ -1780,9 +1923,9 @@ int main(int argc, char* argv[])      if (game_screen == GAMEPLAY) {  	{  	    // @step: draw vertical lines -	    s32 line_index = (s32)state.camera_bounds.lb.x/atom_size.x; -	    for (s32 x = state.camera_bounds.lb.x; x <= state.camera_bounds.rt.x; x += atom_size.x) { -		s32 offset = line_index*atom_size.x - x; +	    s32 line_index = (s32)state.camera_bounds.lb.x/state.atom_size.x; +	    for (s32 x = state.camera_bounds.lb.x; x <= state.camera_bounds.rt.x; x += state.atom_size.x) { +		s32 offset = line_index*state.atom_size.x - x;  		Vec3 start = Vec3{   		    (r32)(x + offset),   		    state.camera_bounds.lb.y,  @@ -1804,10 +1947,12 @@ int main(int argc, char* argv[])  		line_index++;  	    } -	    line_index = (s32)state.camera_bounds.lb.y/atom_size.y; +	    line_index = (s32)state.camera_bounds.lb.y/state.atom_size.y;  	    // @step: draw horizontal lines -	    for (s32 y = state.camera_bounds.lb.y; y <= state.camera_bounds.rt.y; y += atom_size.x) { -		s32 offset = line_index * atom_size.y - y; +	    for (s32 y = state.camera_bounds.lb.y;  +		    y <= state.camera_bounds.rt.y;  +		    y += state.atom_size.x) { +		s32 offset = line_index * state.atom_size.y - y;  		Vec3 start = Vec3{  		    state.camera_bounds.lb.x,   			(r32)(y + offset),  @@ -1880,19 +2025,19 @@ int main(int argc, char* argv[])  	    button.bgd_color_pressed = Vec3{1.0f, 0.5f, 0.5f};  	    button.text = str256("Resume"); -	    button.position = Vec3{10.0f, 40.0f, entity_z[TEXT]};  +	    button.position = Vec3{200.0f, 440.0f, entity_z[TEXT]};  	    if (ui_button(state, button) == ButtonState::CLICK) {  		game_screen = GAMEPLAY;  	    }  	    button.text = str256("Settings"); -	    button.position = Vec3{10.0f, 32.0f, entity_z[TEXT]}; +	    button.position = Vec3{200.0f, 340.0f, entity_z[TEXT]};  	    if (ui_button(state, button) == ButtonState::CLICK) {  		game_screen = SETTINGS_MENU;  	    }  	    button.text = str256("Quit"); -	    button.position = Vec3{10.0f, 24.0f, entity_z[TEXT]}; +	    button.position = Vec3{200.0f, 240.0f, entity_z[TEXT]};  	    if (ui_button(state, button) == ButtonState::CLICK) {  		game_running = 0;  	    } @@ -1911,7 +2056,11 @@ int main(int argc, char* argv[])  		u32 ms_font_size = 24.0f * state.render_scale.y;  		gl_render_text(  		    renderer, "Resolution",  -		    Vec3{800, 800, entity_z[TEXT]},  +		    Vec3{ +			800*state.render_scale.x,  +			800*state.render_scale.y,  +			entity_z[TEXT] +		    },   		    Vec3{0.0f, 0.0f, 0.0f}, ms_font_size  		); @@ -1921,6 +2070,9 @@ int main(int argc, char* argv[])  		    entity_z[TEXT]  		};  		ui_dropdown_button(state, &resolution_select); +		u32 resolution_index = resolution_select.selected_option_index; +		IVec2 new_resolution = resolution_options[resolution_index]; +		update_resolution(&state, new_resolution);  	    }      }  | 
