From e3689dcf3c44f0eae6f7b36767229cb0ad6b0390 Mon Sep 17 00:00:00 2001 From: julesgrc0 Date: Wed, 6 Mar 2024 17:04:09 +0100 Subject: [PATCH] update camera system for android --- android/.idea/.gitignore | 2 + android/app/src/main/AndroidManifest.xml | 4 +- src/core/utils/camera.c | 76 ++++++++++++++++++------ src/core/utils/camera.h | 23 +++++-- src/core/utils/smooth.c | 11 +++- src/core/utils/smooth.h | 2 +- src/screens/game/bridge.c | 18 ++++-- src/screens/game/game.c | 27 +++++---- src/screens/menu/menu.c | 20 ++++++- src/stdafx.h | 2 +- src/terrain/break.c | 16 ++++- src/terrain/break.h | 2 +- 12 files changed, 153 insertions(+), 50 deletions(-) diff --git a/android/.idea/.gitignore b/android/.idea/.gitignore index 26d3352..8f00030 100644 --- a/android/.idea/.gitignore +++ b/android/.idea/.gitignore @@ -1,3 +1,5 @@ # Default ignored files /shelf/ /workspace.xml +# GitHub Copilot persisted chat sessions +/copilot/chatSessions diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 94189f8..f8e5402 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -5,8 +5,6 @@ + tools:targetApi="30"> position = VEC(x, y); + camera->target_position = VEC(x, y); +#else camera->matrix = malloc(sizeof(float) * 16); if (camera->matrix == NULL) { LOG("failed to allocate memory for camera matrix"); @@ -31,7 +35,7 @@ w_camera *create_camera(float x, float y) { camera->matrix[13] = m.m13; camera->matrix[14] = m.m14; camera->matrix[15] = m.m15; - +#endif return camera; } void destroy_camera(w_camera *camera) { @@ -39,41 +43,78 @@ void destroy_camera(w_camera *camera) { LOG("camera (null) already destroyed"); return; } - sfree(camera->matrix); free(camera); } -void add_camera_vec(w_camera *camera, Vector2 vec) { - camera_x(camera) -= vec.x; - camera_y(camera) -= vec.y; -} -void set_camera_vec(w_camera *camera, Vector2 vec) { - camera_x(camera) = -vec.x; - camera_y(camera) = -vec.y; -} -void set_camera_center(w_camera *camera, Vector2 vec) { - camera_x(camera) = -vec.x + RENDER_W / 2; - camera_y(camera) = -vec.y + RENDER_H / 2; -} -Vector2 get_camera_vec(w_camera *camera) { - return VEC(-camera_x(camera), -camera_y(camera)); -} + Vector2 get_camera_center(w_camera *camera) { +#if defined(WISPY_ANDROID) + return VEC(camera->position.x + RENDER_W / 2, + camera->position.y + RENDER_H / 2); +#else return VEC(-camera_x(camera) + RENDER_W / 2, -camera_y(camera) + RENDER_H / 2); +#endif +} +void set_camera_center(w_camera *camera, Vector2 center) { +#if defined(WISPY_ANDROID) + camera->position = VEC(center.x - RENDER_W / 2, center.y - RENDER_H / 2); +#else + camera_x(camera) = -center.x + RENDER_W / 2; + camera_y(camera) = -center.y + RENDER_H / 2; +#endif } + Vector2 get_camera_object_center(w_camera *camera, Rectangle object) { +#if defined(WISPY_ANDROID) + return VEC(camera->position.x + object.x + (RENDER_W - object.width) / 2, + camera->position.y + object.y + (RENDER_H - object.height) / 2); +#else return VEC(-camera_x(camera) + object.x + (RENDER_W - object.width) / 2, -camera_y(camera) + object.y + (RENDER_H - object.height) / 2); +#endif } Rectangle get_camera_view(w_camera *camera) { +#if defined(WISPY_ANDROID) + return RECT(camera->position.x, camera->position.y, RENDER_W, RENDER_H); +#else return RECT(-camera_x(camera), -camera_y(camera), RENDER_W, RENDER_H); +#endif } Rectangle get_camera_view_with_gap(w_camera *camera) { +#if defined(WISPY_ANDROID) + return RECT(camera->position.x - RENDER_CUBE_GAP * CUBE_W, + camera->position.y - RENDER_CUBE_GAP * CUBE_H, + RENDER_W + RENDER_CUBE_GAP * CUBE_W * 2, + RENDER_H + RENDER_CUBE_GAP * CUBE_H * 2); +#else return RECT(-camera_x(camera) - RENDER_CUBE_GAP * CUBE_W, -camera_y(camera) - RENDER_CUBE_GAP * CUBE_H, RENDER_W + RENDER_CUBE_GAP * CUBE_W * 2, RENDER_H + RENDER_CUBE_GAP * CUBE_H * 2); +#endif +} + +#if defined(WISPY_ANDROID) +Rectangle get_rectangle_camera(Rectangle rect, w_camera *camera) { + return RECT(rect.x - camera->position.x, rect.y - camera->position.y, + rect.width, rect.height); +} +Vector2 get_vector_camera(Vector2 vec, w_camera *camera) { + return VEC(vec.x - camera->position.x, vec.y - camera->position.y); +} +#else +void add_camera_vec(w_camera *camera, Vector2 vec) { + camera_x(camera) -= vec.x; + camera_y(camera) -= vec.y; } +void set_camera_vec(w_camera *camera, Vector2 vec) { + camera_x(camera) = -vec.x; + camera_y(camera) = -vec.y; +} +Vector2 get_camera_vec(w_camera *camera) { + return VEC(camera_x(camera), camera_y(camera)); +} + void begin_camera(w_camera *camera) { rlDrawRenderBatchActive(); rlLoadIdentity(); @@ -83,3 +124,4 @@ void end_camera() { rlDrawRenderBatchActive(); rlLoadIdentity(); } +#endif \ No newline at end of file diff --git a/src/core/utils/camera.h b/src/core/utils/camera.h index 2cb136a..b863684 100644 --- a/src/core/utils/camera.h +++ b/src/core/utils/camera.h @@ -1,26 +1,39 @@ #pragma once #include "../../stdafx.h" +#if defined(WISPY_WINDOWS) || defined(WISPY_LINUX) #define camera_x(camera) (camera->matrix[12]) #define camera_y(camera) (camera->matrix[13]) +#endif typedef struct w_camera { +#if defined(WISPY_ANDROID) + Vector2 position; +#else float *matrix; +#endif Vector2 target_position; } w_camera; w_camera *create_camera(float x, float y); void destroy_camera(w_camera *camera); -void add_camera_vec(w_camera *camera, Vector2 vec); -void set_camera_vec(w_camera *camera, Vector2 vec); -void set_camera_center(w_camera *camera, Vector2 vec); - -Vector2 get_camera_vec(w_camera *camera); +void set_camera_center(w_camera *camera, Vector2 center); Vector2 get_camera_center(w_camera *camera); +Vector2 get_camera_object_center(w_camera *camera, Rectangle object); Rectangle get_camera_view(w_camera *camera); Rectangle get_camera_view_with_gap(w_camera *camera); + +#if defined(WISPY_ANDROID) +Rectangle get_rectangle_camera(Rectangle rect, w_camera *camera); +Vector2 get_vector_camera(Vector2 vec, w_camera *camera); +#else +void add_camera_vec(w_camera *camera, Vector2 vec); +void set_camera_vec(w_camera *camera, Vector2 vec); +Vector2 get_camera_vec(w_camera *camera); + void begin_camera(w_camera *camera); void end_camera(); +#endif \ No newline at end of file diff --git a/src/core/utils/smooth.c b/src/core/utils/smooth.c index 1689e49..4a78631 100644 --- a/src/core/utils/smooth.c +++ b/src/core/utils/smooth.c @@ -9,9 +9,14 @@ void smooth_rect(Rectangle *box, Rectangle target, float move) { smooth_float(box->x, target.x, move); smooth_float(box->y, target.y, move); } -void smooth_camera(w_camera *camera, Vector2 target, float move) { - smooth_float(camera_x(camera), -target.x, move); - smooth_float(camera_y(camera), -target.y, move); +void smooth_camera(w_camera *camera, float move) { +#if defined(WISPY_ANDROID) + smooth_float(camera->position.x, camera->target_position.x, move); + smooth_float(camera->position.y, camera->target_position.y, move); +#else + smooth_float(camera_x(camera), camera->target_position.x, move); + smooth_float(camera_y(camera), camera->target_position.y, move); +#endif } Vector2 vec_block_round(Vector2 vec) { return VEC(roundf(vec.x / (float)CUBE_W) * (float)CUBE_W, diff --git a/src/core/utils/smooth.h b/src/core/utils/smooth.h index 5f89f74..f84a4be 100644 --- a/src/core/utils/smooth.h +++ b/src/core/utils/smooth.h @@ -9,6 +9,6 @@ void smooth_vec(Vector2 *position, Vector2 target, float move); void smooth_rect(Rectangle *box, Rectangle target, float move); -void smooth_camera(w_camera *camera, Vector2 target, float move); +void smooth_camera(w_camera *camera, float move); Vector2 vec_block_round(Vector2 vec); diff --git a/src/screens/game/bridge.c b/src/screens/game/bridge.c index 242d276..2448778 100644 --- a/src/screens/game/bridge.c +++ b/src/screens/game/bridge.c @@ -7,6 +7,7 @@ w_bridge *create_bridge() { return NULL; } memset(td, 0, sizeof(w_bridge)); + td->force_update = true; td->chunk_group = create_chunkgroup(CHUNK_GROUP_MID_LEN); if (td->chunk_group == NULL) { @@ -32,7 +33,11 @@ w_bridge *create_bridge() { return NULL; } set_camera_center(td->camera, get_player_center(td->player)); +#if defined(WISPY_ANDROID) + td->camera->target_position = td->camera->position; +#else td->camera->target_position = get_camera_vec(td->camera); +#endif td->ctrl = create_controls(); if (td->ctrl == NULL) { @@ -42,6 +47,9 @@ w_bridge *create_bridge() { td->is_active = true; #if defined(WISPY_WINDOWS) || defined(WISPY_LINUX) + + update_bridge(td); + #if defined(WISPY_WINDOWS) QueryPerformanceFrequency(&td->time_frequency); QueryPerformanceCounter(&td->time_start); @@ -110,7 +118,11 @@ void physics_update_bridge(w_bridge *td) { void update_bridge(w_bridge *td) { if (td->ctrl->key != 0 || + #if defined(WISPY_ANDROID) + !Vector2Equals(td->camera->target_position, td->camera->position) || + #else !Vector2Equals(td->camera->target_position, get_camera_vec(td->camera)) || + #endif td->force_update) { if (!update_chunkview(td->chunk_view, td->chunk_group, td->camera)) { @@ -126,15 +138,13 @@ void update_bridge(w_bridge *td) { #if defined(WISPY_WINDOWS) QueryPerformanceCounter(&td->time_end); if (td->time_end.QuadPart - td->time_start.QuadPart >= - td->time_frequency.QuadPart * PHYSICS_TICK) - { + td->time_frequency.QuadPart * PHYSICS_TICK) { QueryPerformanceCounter(&td->time_start); #elif defined(WISPY_LINUX) clock_gettime(CLOCK_MONOTONIC, &td->time_end); if ((td->time_end.tv_sec - td->time_start.tv_sec) + (td->time_end.tv_nsec - td->time_start.tv_nsec) / 1000000000.0 >= - PHYSICS_TICK) - { + PHYSICS_TICK) { clock_gettime(CLOCK_MONOTONIC, &td->time_start); #else { diff --git a/src/screens/game/game.c b/src/screens/game/game.c index 36655d9..87faeea 100644 --- a/src/screens/game/game.c +++ b/src/screens/game/game.c @@ -74,15 +74,13 @@ void game_screen(w_state *state) { while (!WindowShouldClose() && td->is_active) { #if defined(WISPY_ANDROID) update_controls(td->ctrl); - set_camera_vec(td->camera, VEC(roundf(td->camera->target_position.x), - roundf(td->camera->target_position.y))); - + td->camera->position = td->camera->target_position; bstate = update_blockbreaker(bb, td->ctrl, td->player, PHYSICS_TICK); update_bridge(td); #else update_controls(td->ctrl); float speed = GetFrameTime() * PLAYER_SPEED; - smooth_camera(td->camera, td->camera->target_position, speed); + smooth_camera(td->camera, speed); smooth_vec(&player_position, td->player->position, Vector2Distance(td->player->position, player_position) * speed); #endif @@ -100,19 +98,26 @@ void game_screen(w_state *state) { (Color){66, 135, 245, 255}, (Color){142, 184, 250, 255}); +#if defined(WISPY_WINDOWS) || defined(WISPY_LINUX) begin_camera(td->camera); +#endif + for (unsigned int i = 0; i < td->chunk_view->len; i++) { - DrawTexturePro(block_textures[td->chunk_view->blocks[i].block.type - 1], - td->chunk_view->blocks[i].src, - td->chunk_view->blocks[i].dst, VEC_ZERO, 0, - td->chunk_view->blocks[i].light); + DrawTexturePro( + block_textures[td->chunk_view->blocks[i].block.type - 1], + td->chunk_view->blocks[i].src, +#if defined(WISPY_ANDROID) + get_rectangle_camera(td->chunk_view->blocks[i].dst, td->camera), +#else + td->chunk_view->blocks[i].dst, +#endif + VEC_ZERO, 0, td->chunk_view->blocks[i].light); } - #if defined(WISPY_WINDOWS) || defined(WISPY_LINUX) bstate = update_blockbreaker(bb, td->ctrl, td->player, GetFrameTime()); #endif if (bstate == BS_BREAKING) { - draw_blockbreaker(bb); + draw_blockbreaker(bb, td->camera); } else if (bstate == BS_BROKEN) { td->force_update = true; } @@ -124,7 +129,9 @@ void game_screen(w_state *state) { VEC_ZERO, 0, WHITE); #endif +#if defined(WISPY_WINDOWS) || defined(WISPY_LINUX) end_camera(); +#endif #if defined(WISPY_ANDROID) DrawTexturePro(player_textures[td->player->state], td->player->src, diff --git a/src/screens/menu/menu.c b/src/screens/menu/menu.c index 984fa0d..1731d52 100644 --- a/src/screens/menu/menu.c +++ b/src/screens/menu/menu.c @@ -55,8 +55,13 @@ void menu_screen(w_state *state) { angle += speed; angle = fmodf(angle, 360.f); +#if defined(WISPY_ANDROID) + camera->position.x += sinf(angle) * 1000.f * speed; + camera->position.y += cosf(angle) * 1000.f * speed; +#else add_camera_vec(camera, VEC(sinf(angle) * 1000.f * speed, cosf(angle) * 1000.f * speed)); +#endif update_chunkview(view, grp, camera); update_chunkview_lighting(view, get_camera_center(camera), @@ -67,13 +72,24 @@ void menu_screen(w_state *state) { DrawRectangleGradientV(0, 0, RENDER_W, RENDER_H, (Color){66, 135, 245, 255}, (Color){142, 184, 250, 255}); +#if defined(WISPY_WINDOWS) || defined(WISPY_LINUX) begin_camera(camera); +#endif + for (unsigned int i = 0; i < view->len; i++) { DrawTexturePro(block_textures[view->blocks[i].block.type - 1], - view->blocks[i].src, view->blocks[i].dst, VEC_ZERO, 0, - view->blocks[i].light); + view->blocks[i].src, +#if defined(WISPY_ANDROID) + get_rectangle_camera(view->blocks[i].dst, camera), +#else + view->blocks[i].dst, +#endif + VEC_ZERO, 0, view->blocks[i].light); } + +#if defined(WISPY_WINDOWS) || defined(WISPY_LINUX) end_camera(); +#endif if (update_button(play_button)) { is_active = false; diff --git a/src/stdafx.h b/src/stdafx.h index ecf6f7f..85a69b8 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -132,7 +132,7 @@ printf(__VA_ARGS__); \ printf("\n"); #elif defined(_DEBUG) && defined(WISPY_ANDROID) -#define LOG(...) __android_log_print(ANDROID_LOG_INFO, "WISPY", __VA_ARGS__); +#define LOG(...) __android_log_print(ANDROID_LOG_INFO, "WISPY_INFO", __VA_ARGS__); #else #define LOG(...) #endif // _DEBUG diff --git a/src/terrain/break.c b/src/terrain/break.c index fae12b4..7bcfa81 100644 --- a/src/terrain/break.c +++ b/src/terrain/break.c @@ -25,7 +25,12 @@ w_blockbreaker *create_blockbreaker(w_state *state, w_chunkview *chunk_view, Vector2 get_mouse_block(w_camera *camera) { Vector2 mouse = Vector2Add(VEC(FORMAT_W(GetMouseX()), FORMAT_H(GetMouseY())), +#if defined(WISPY_ANDROID) + camera->position); +#else get_camera_vec(camera)); +#endif + return Vector2Subtract(mouse, VEC((CUBE_W / 2), (CUBE_H / 2))); } @@ -86,10 +91,15 @@ w_breakstate update_blockbreaker(w_blockbreaker *bb, w_controls *ctrl, return BS_NONE; } -void draw_blockbreaker(w_blockbreaker *bb) { +void draw_blockbreaker(w_blockbreaker *bb, w_camera *camera) { DrawTexturePro(bb->textures[bb->stage], CUBE_SRC_RECT, - RECT(bb->position.x, bb->position.y, CUBE_W, CUBE_H), VEC_ZERO, - 0, Fade(WHITE, 0.5)); +#if defined(WISPY_ANDROID) + RECT(bb->position.x - camera->position.x, + bb->position.y - camera->position.y, CUBE_W, CUBE_H), +#else + RECT(bb->position.x, bb->position.y, CUBE_W, CUBE_H), +#endif + VEC_ZERO, 0, Fade(WHITE, 0.5)); } void destroy_blockbreaker(w_blockbreaker *bb) { diff --git a/src/terrain/break.h b/src/terrain/break.h index 2e4cc25..c13e124 100644 --- a/src/terrain/break.h +++ b/src/terrain/break.h @@ -36,6 +36,6 @@ w_blockbreaker *create_blockbreaker(w_state *state, w_chunkview *chunk_view, w_breakstate update_blockbreaker(w_blockbreaker *bb, w_controls *ctrl, w_player *player, float dt); -void draw_blockbreaker(w_blockbreaker *bb); +void draw_blockbreaker(w_blockbreaker *bb, w_camera* camera); void destroy_blockbreaker(w_blockbreaker *bb);