aboutsummaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/animator.c55
-rw-r--r--src/engine/animator.h14
-rw-r--r--src/engine/draw_screen.c14
-rw-r--r--src/engine/entity.c22
-rw-r--r--src/engine/entity.h46
-rw-r--r--src/engine/level_const.c9
-rw-r--r--src/engine/maths.h1
-rw-r--r--src/engine/player_controller.c169
-rw-r--r--src/engine/types.h44
9 files changed, 207 insertions, 167 deletions
diff --git a/src/engine/animator.c b/src/engine/animator.c
new file mode 100644
index 0000000..1af8dde
--- /dev/null
+++ b/src/engine/animator.c
@@ -0,0 +1,55 @@
+#include "engine/animator.h"
+#include "engine/entity.h"
+#include "engine/maths.h"
+#include "ppu/consts.h"
+#include "ppu/ppu.h"
+
+
+#define hh_white_palette 6
+
+void hh_animate_hit(hh_s_rendering* in, bool hit) {
+ if (hit) {
+ in->fam.palette_index = hh_white_palette;
+ } else {
+ in->fam.palette_index = in->palette;
+ }
+}
+
+void hh_animate(hh_s_rendering* in, uint16_t start, uint16_t end, uint8_t step) {
+ if (in->fam.palette_index >= start && in->fam.palette_index < end) {
+ in->fam.palette_index += step;
+ } else {// rollover
+ in->fam.palette_index = start;
+ }
+}
+
+//TODO: if entity not inside of screen, don't update idx
+uint16_t hh_update_sprite(uint16_t idx, hh_entity* in, vec_cor cam) {
+ hh_animate_hit(&in->render, in->is_hit);
+ hh_s_ppu_loc_fam_entry temp = in->render.fam;
+ for (int y = 0; y < CEILI(in->size.y,16); y++) {
+ temp.position_y = CLAMP(in->pos.y - cam.y + y*HH_PPU_SPRITE_HEIGHT, -16, HH_PPU_SCREEN_HEIGHT);
+ for (int x = 0; x < CEILI(in->size.x,16); x++) {
+ temp.position_x = CLAMP(in->pos.x - cam.x + x*HH_PPU_SPRITE_WIDTH, -16, HH_PPU_SCREEN_WIDTH);
+ hh_ppu_update_foreground(++idx, temp);
+ temp.tilemap_index++;
+ }
+ }
+ return idx;
+}
+
+
+// void hh_update_sprite(hh_entity* in, vec_cor cam) {
+// hh_animate_hit(&in->render, in->is_hit);
+// // uint16_t idx = in->render.ppu_foreground_index;
+// uint16_t idx = 0;
+// hh_s_ppu_loc_fam_entry temp = in->render.fam;
+// for (int y = 0; y < CEILI(in->size.y,16); y++) {
+// temp.position_y = CLAMP(in->pos.y - cam.y + y*HH_PPU_SPRITE_HEIGHT, -16, HH_PPU_SCREEN_HEIGHT);
+// for (int x = 0; x < CEILI(in->size.x,16); x++) {
+// temp.position_x = CLAMP(in->pos.x - cam.x + x*HH_PPU_SPRITE_WIDTH, -16, HH_PPU_SCREEN_WIDTH);
+// hh_ppu_update_foreground(idx++, temp);
+// temp.tilemap_index++;
+// }
+// }
+// }
diff --git a/src/engine/animator.h b/src/engine/animator.h
new file mode 100644
index 0000000..10fa321
--- /dev/null
+++ b/src/engine/animator.h
@@ -0,0 +1,14 @@
+#pragma once
+#include <stdint.h>
+
+#include "ppu/types.h"
+#include "engine/types.h"
+#include "engine/entity.h"
+
+/** @brief flashes sprite white, also needs to be called next frame */
+void hh_animate_hit(hh_s_rendering*, bool hit);
+/** @brief updates current animation frame */
+void hh_animate(hh_s_rendering*, uint16_t start, uint16_t end, uint8_t step);
+
+/** @brief passively updates sprite*/
+uint16_t hh_update_sprite(uint16_t idx, hh_entity* in, vec_cor cam);
diff --git a/src/engine/draw_screen.c b/src/engine/draw_screen.c
index d1d7a04..823c284 100644
--- a/src/engine/draw_screen.c
+++ b/src/engine/draw_screen.c
@@ -15,12 +15,12 @@ void hh_update_screen(vec2 view, vec2 player){
int current_tile_x = view.x / HH_PPU_SPRITE_WIDTH;
int offset_py = view.y - (offsetY / 40 * HH_PPU_SPRITE_HEIGHT);
int offset_px = view.x - offsetX * HH_PPU_SPRITE_WIDTH;
- static int prev_ofsset = 0;
+ static int prev_offset = 0;
int size = MIN(HH_PPU_BG_CANVAS_TILES_H,level.size.x) * MIN(HH_PPU_BG_CANVAS_TILES_V,level.size.y);
- if( (offset_py == 0 || offset_py > 230) && level.size.y > level.size.x && prev_ofsset != offset_py){
+ if( (offset_py == 0 || offset_py > 230) && level.size.y > level.size.x && prev_offset != offset_py){
if(offset_py==0){
- offsetY = (current_tile_y-14) * level.size.x;
+ offsetY = MAX(current_tile_y-14,0) * level.size.x;
}
else{
offsetY = current_tile_y * level.size.x;
@@ -35,12 +35,12 @@ void hh_update_screen(vec2 view, vec2 player){
.tilemap_index = level.place[offsetY + BAM_index],
});
}
- prev_ofsset = offset_py;
+ prev_offset = offset_py;
}
- else if ((offset_px == 0 || offset_px > 310) && level.size.x > level.size.y && prev_ofsset != offset_px)
+ else if ((offset_px == 0 || offset_px > 310) && level.size.x > level.size.y && prev_offset != offset_px)
{
if(offset_px==0){
- offsetX = current_tile_x - 14;
+ offsetX = MAX((current_tile_x - 14),0);
}
else{
offsetX = current_tile_x;
@@ -57,7 +57,7 @@ void hh_update_screen(vec2 view, vec2 player){
}
}
- prev_ofsset = offset_px;
+ prev_offset = offset_px;
}
void hh_setup_screen(hh_level_entity currentlevel){
diff --git a/src/engine/entity.c b/src/engine/entity.c
index 535759d..58b62c9 100644
--- a/src/engine/entity.c
+++ b/src/engine/entity.c
@@ -45,18 +45,18 @@ void hh_solve_collision(vec2 pos_environment, hh_entity* entity){
}
hh_entity hh_background_collision (hh_entity temp_old_entity,hh_entity temp_new_entity){
- temp_old_entity.is_grounded = false;
+ temp_new_entity.is_grounded = false;
// solves x collision
if (temp_old_entity.vel.x <= 0) {
if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_old_entity.pos.y + 0})) ||
- hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_old_entity.pos.y + 15}))) {
+ hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_old_entity.pos.y + (temp_old_entity.size.y-1)}))) {
temp_new_entity.pos.x = (temp_new_entity.pos.x & ~15) + 16,
temp_new_entity.vel.x = 0;
}
} else {
- if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 16, .y=temp_old_entity.pos.y + 0})) ||
- hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 16, .y=temp_old_entity.pos.y + 15}))) {
+ if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + temp_old_entity.size.x, .y=temp_old_entity.pos.y + 0})) ||
+ hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + temp_old_entity.size.x, .y=temp_old_entity.pos.y + (temp_old_entity.size.y-1)}))) {
temp_new_entity.pos.x = temp_new_entity.pos.x & ~15, // <-- magic comma, NOT TOUCHY
temp_new_entity.vel.x = 0;
}
@@ -65,20 +65,22 @@ hh_entity hh_background_collision (hh_entity temp_old_entity,hh_entity temp_new_
//solves y collision
if (temp_old_entity.vel.y <= 0) {
if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_new_entity.pos.y + 0})) ||
- hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 15, .y=temp_new_entity.pos.y + 0}))) {
+ hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + (temp_new_entity.size.x-1), .y=temp_new_entity.pos.y + 0}))) {
temp_new_entity.pos.y = (temp_new_entity.pos.y & ~15) + 16,
temp_new_entity.vel.y = 0;
}
} else {
- if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_new_entity.pos.y + 15})) ||
- hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 15, .y=temp_new_entity.pos.y + 15}))) {
+ if (hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + 0, .y=temp_new_entity.pos.y + (temp_new_entity.size.y-1)})) ||
+ hh_colidable(hh_world_to_tile((vec2){.x=temp_new_entity.pos.x + (temp_new_entity.size.x-1), .y=temp_new_entity.pos.y + (temp_new_entity.size.y-1)}))) {
temp_new_entity.pos.y = temp_new_entity.pos.y & ~15,
temp_new_entity.vel.y = 0;
- temp_old_entity.is_grounded = true;
+ temp_new_entity.is_grounded = true;
}
}
- temp_old_entity.pos = temp_new_entity.pos;
- temp_old_entity.vel = temp_new_entity.vel;
+ temp_old_entity = temp_new_entity;
+ // temp_old_entity.is_grounded = temp_new_entity.is_grounded;
+ // temp_old_entity.pos = temp_new_entity.pos;
+ // temp_old_entity.vel = temp_new_entity.vel;
return temp_old_entity;
}
diff --git a/src/engine/entity.h b/src/engine/entity.h
index cad6ba4..68b450d 100644
--- a/src/engine/entity.h
+++ b/src/engine/entity.h
@@ -5,47 +5,11 @@
#include <stdio.h>
#include "ppu/types.h"
-
#include "engine/maths.h"
+#include "engine/types.h"
+// #include "engine/animator.h"
-typedef uint8_t hh_idx_t;
-
-typedef enum {
- fire, ice, poison
-}hh_e_damage_t;
-
-typedef struct {
- hh_s_ppu_loc_fam_entry fam; //screen
- hh_idx_t frame0;
- hh_idx_t palette;
-
-}hh_s_rendering;
-
-typedef struct {
- int8_t hp;
- int8_t dmg;
- hh_e_damage_t dmg_type;
- int8_t speed_x, speed_y;
-
-} hh_s_atributes;
-
-
-typedef struct {
- vec2 pos, vel, vec;
- bool is_grounded;
- bool is_hit;
- uint8_t radius;
- int8_t hp;
- int8_t speed;
- hh_s_rendering render;
- //armor/block?
-}hh_entity;
-
-typedef struct {
- hh_entity p;
- hh_s_atributes atr;
-}hh_s_player;
-
+// TODO: make a sprite update function (and required data structs?)
/// @brief detect for collision enity and eviroment
/// @param pos1 position of environment tile to be checked
@@ -63,7 +27,7 @@ void hh_solve_collision(vec2 pos_environment, hh_entity* entity);
/// @param temp_old_entity old data of entity
/// @param temp_new_entity new data of entity where it wants to go to
/// @return updated new entity where it actually can go to
-hh_entity hh_background_collision (hh_entity temp_old_entity, hh_entity temp_new_entity);
+hh_entity hh_background_collision(hh_entity temp_old_entity, hh_entity temp_new_entity);
/// @brief solve collision of player with enemy
/// @param temp_player data of player
@@ -77,6 +41,6 @@ hh_entity hh_enemy_collision(hh_entity temp_player, hh_entity temp_enemy);
/// @param radius_1 radius of first object (entity)
/// @param radius_2 radius of second object (entity)
/// @return true if objects collids
-bool hh_distance_circles (vec2 object_1, vec2 object_2, int radius_1, int radius_2);
+bool hh_distance_circles(vec2 object_1, vec2 object_2, int radius_1, int radius_2);
diff --git a/src/engine/level_const.c b/src/engine/level_const.c
index 5ba0187..3847ad8 100644
--- a/src/engine/level_const.c
+++ b/src/engine/level_const.c
@@ -1,5 +1,6 @@
#include "engine/level_const.h"
+#include <stdio.h>
hh_g_all_levels hh_init_game_levels(){
hh_g_all_levels levels;
@@ -14,6 +15,10 @@ hh_g_all_levels hh_init_game_levels(){
levels.level[1].hh_level_completed=false;
FILE *fp = fopen("../test/bin/level1_test.bin", "rb");
+ if (fp == NULL) {
+ printf("level1_test.bin not found!\n");
+ return levels;
+ }
fseek(fp, 0, SEEK_END);
int size = ftell(fp) / sizeof(int);
fseek(fp, (0 * sizeof(int)) + sizeof(int), SEEK_SET);
@@ -22,6 +27,10 @@ hh_g_all_levels hh_init_game_levels(){
fclose(fp);
FILE *lvl2 = fopen("../test/bin/level2_test.bin", "rb");
+ if (lvl2 == NULL) {
+ printf("level2_test.bin not found!\n");
+ return levels;
+ }
fseek(lvl2, 0, SEEK_END);
size = ftell(lvl2) / sizeof(int);
fseek(lvl2, (0 * sizeof(int)) + sizeof(int), SEEK_SET);
diff --git a/src/engine/maths.h b/src/engine/maths.h
index bef287e..6f66042 100644
--- a/src/engine/maths.h
+++ b/src/engine/maths.h
@@ -20,3 +20,4 @@ vec_cor vec_cor2cen(vec_cen in, vec2 halfDistance);
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#define CLAMP(N,LOWER,UPPER) (MIN(MAX(LOWER, N), UPPER))
+#define CEILI(numerator, denominator) (numerator / denominator + (numerator % denominator != 0))
diff --git a/src/engine/player_controller.c b/src/engine/player_controller.c
index 647b00c..cec28df 100644
--- a/src/engine/player_controller.c
+++ b/src/engine/player_controller.c
@@ -3,35 +3,52 @@
#include "engine/draw_screen.h"
#include "engine/sprite_controller.h"
#include "engine/player_controller.h"
-
#include "input.h"
+#include "engine/animator.h"
#include "engine/bullet.h"
void hh_player_actions() {
- static Bullet bullet ={
- .isActive=false,
- };
static hh_entity player={
.hp = 4,
.speed = 6,
.is_grounded = false,
.is_hit = false,
.radius = 8,
- .pos = (vec2){32,32},
+ .pos = (vec2){128+16,32},
.vel = (vec2){0,0},
- .vec = (vec2){0,0},
+ .size = (vec2){32,32},
.render = {
.frame0 = 80,
.palette = 3,
+ .ppu_foreground_index = 0,
.fam = (hh_s_ppu_loc_fam_entry){
.horizontal_flip = false,
.vertical_flip = false,
- .palette_index = 2,
- .tilemap_index = 60,
+ .palette_index = 3,
+ .tilemap_index = 80,
}
}
}, player_new = {0};
+ static hh_entity bullet={
+// .hp = 4,
+ .speed = 6,
+ .is_grounded = true,
+ .is_hit = false,
+ .radius = 8,
+ .pos = (vec2){-16,-16},
+ .vel = (vec2){0,0},
+ .render = {
+ .frame0 = 84,
+ .palette = 3,
+ .fam = (hh_s_ppu_loc_fam_entry){
+ .horizontal_flip = false,
+ .vertical_flip = false,
+ .palette_index = 7,
+ .tilemap_index = 84,
+ }
+ }
+ };
static hh_entity enemy={
.hp = 4,
@@ -41,10 +58,11 @@ void hh_player_actions() {
.radius = 8,
.pos = (vec2){128,48},
.vel = (vec2){0,0},
- .vec = (vec2){0,0},
+ .size = (vec2){16,16},
.render = {
.frame0 = 20,
.palette = 7,
+ .ppu_foreground_index = 16,
.fam = (hh_s_ppu_loc_fam_entry){
.horizontal_flip = false,
.vertical_flip = false,
@@ -117,13 +135,6 @@ void hh_player_actions() {
} else if (player.vel.y < 6){
player.vel.y += 1; //gravity
}
-
- if(g_hh_controller_p1.button_secondary==true){
- shootBullet(player.pos,&bullet);
- }
- updateBullet(&bullet,5);
-
-
/*
player.vel = (vec2){.x = (-1 * g_hh_controller_p1.dpad_left) + (1 * g_hh_controller_p1.dpad_right),
@@ -140,33 +151,7 @@ void hh_player_actions() {
.y = player.vel.y,
};
- player_new = hh_enemy_collision(player, enemy);
-
-
- // const int8_t maa = 3;
- // const int8_t mbb = -3;
- // if (g_hh_controller_p1.dpad_up)
- //
- // if (g_hh_controller_p1.dpad_down)
- //
- // if (g_hh_controller_p1.dpad_left) {
- // player.vel.x += mbb;
- // // g_hh_demo_balls[0].horizontal_flip = true;
- // }
- // if (g_hh_controller_p1.dpad_right) {
- // player.vel.x += maa;
- // // g_hh_demo_balls[0].horizontal_flip = true;
- // }
- // if (g_hh_controller_p1.button_primary /*&& player.is_grounded*/) //JUMP
- // player.vel.y += -6;
- // // // if (g_hh_controller_p1.button_secondary)
-
- // player.vel.y += 1; //gravity
-
-
- //END OF VECTOR CHANGES
- // player.vel.y = CLAMP(player.vel.y,-32,32);
- // player.vel.x = CLAMP(player.vel.x,-32,32);
+ player_new = hh_enemy_collision(player, enemy);
player_new.pos = (vec2){
.x = player.pos.x + player_new.vel.x,
@@ -174,77 +159,43 @@ void hh_player_actions() {
};
-
- // const uint8_t empty = 0;
- // hh_s_tiles tiles[9];
- // const vec2 tile_offset[9] = {
- // (vec2){-16,-16},(vec2){0,-16},(vec2){+16,-16},
- // (vec2){-16,0}, (vec2){0,0}, (vec2){+16,0},
- // (vec2){-16,+16},(vec2){0,+16},(vec2){+16,+16},
- // };
- // for (int i = 0; i < 9; i++) {
- // vec2 temp_pos = vec_add(player.pos, tile_offset[i]);
- // temp_pos =(vec2){
- // .x = temp_pos.x,
- // .y = temp_pos.y,
- // };
- // hh_s_tiles tile = {
- // .pos = temp_pos,
- // .idx = hh_world_to_tile(temp_pos)
- // };
- // if(hh_colidable(tile.idx)) {
- // tiles[i]=tile;
- // // printf(" collidable near!");
- // } else {
- // tiles[i].idx = 0;
- // }
- // }
- /*
- 012
- 345
- 678
- */
- // for (int i = 0; i < 9; i++)
- // {
- // if (tiles[i].idx != 0){
- // hh_solve_collision(tiles[i].pos, &player);
- // }
- // }
-
- player = hh_background_collision ( player, player_new);
+ player = hh_background_collision( player, player_new);
- //player = player_new;
-
vec_cor cam_pos;//value in tiles
- // cam_pos = (vec2){0,0};
- cam_pos = hh_update_camera(player.pos,(vec2){0,0},(vec2){.x=20*16,.y=30*16});//TODO: remove magic number(s)
- // printf("%i, %i:%i, %i\n",player.pos.x,player.pos.y,cam_pos.x,cam_pos.y);
- hh_draw_screen(cam_pos);
+ cam_pos = hh_draw_screen(player.pos);
+ hh_shoot_bullet(player.pos, cam_pos ,&bullet);
+ uint16_t idx = 16;
+ idx = hh_update_sprite(idx, &player, cam_pos);
+ idx = hh_update_sprite(idx, &enemy, cam_pos);
+
+ idx =16;
+
+ // TODO: make this a function call
// update player sprite on ppu
- player.render.fam.position_x = (player.pos.x-cam_pos.x);
- player.render.fam.position_y = (player.pos.y-cam_pos.y);
-
- enemy.render.fam.position_x = (enemy.pos.x-cam_pos.x);
- enemy.render.fam.position_y = (enemy.pos.y-cam_pos.y);
-
- player.render.fam.tilemap_index = 2;//TODO: these two lines should be redundant
- player.render.fam.palette_index = 7;
- // hh_ppu_update_foreground(0, player.render.fam);
-
- for (int i = 0; i < 4; i++)
- {
- hh_s_ppu_loc_fam_entry temp = player.render.fam;
- temp.position_x = player.render.fam.position_x+(!(player.vel.x>0)?-1:1)*(i%2?8:-8);
- temp.position_y = player.render.fam.position_y+(i>1?0:-16);
- temp.tilemap_index = player.render.frame0 + i;
- temp.palette_index = player.render.palette;
- temp.horizontal_flip = !(player.vel.x>0);
- hh_ppu_update_foreground(i,temp);
- }
-
+ // player.render.fam.position_x = (player.pos.x-cam_pos.x);
+ // player.render.fam.position_y = (player.pos.y-cam_pos.y);
+
+ // enemy.render.fam.position_x = (enemy.pos.x-cam_pos.x);
+ // enemy.render.fam.position_y = (enemy.pos.y-cam_pos.y);
- hh_ppu_update_foreground(4, enemy.render.fam);
+ // TODO: make this loop a function call
+ // for (int i = 0; i < 4; i++)
+ // {
+ // hh_s_ppu_loc_fam_entry temp = player.render.fam;
+ // temp.position_x = player.render.fam.position_x+(!(player.vel.x>0)?-1:1)*(i%2?8:-8);
+ // temp.position_y = player.render.fam.position_y+(i>1?0:-16);
+ // temp.tilemap_index = player.render.fam.tilemap_index + i;
+ // temp.horizontal_flip = !(player.vel.x>0);
+ // hh_ppu_update_foreground(i,temp);
+
+ // // hh_s_ppu_loc_fam_entry temp = {
+ // // .position_x = player.render.fam.position_x+(!(player.vel.x>0)?-1:1)*(i%2?8:-8)
+ // // };
+
+ // }
+
+ // hh_ppu_update_foreground(4, enemy.render.fam);
}
diff --git a/src/engine/types.h b/src/engine/types.h
new file mode 100644
index 0000000..00b381b
--- /dev/null
+++ b/src/engine/types.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "engine/maths.h"
+
+typedef uint8_t hh_ppu_fg_idx;
+// typedef uint16_t hh_bg_idx;
+
+typedef enum {
+ fire, ice, poison
+}hh_e_damage_t;
+
+
+typedef struct {
+ int8_t hp;
+ int8_t dmg;
+ hh_e_damage_t dmg_type;
+ int8_t speed_x, speed_y;
+
+} hh_s_atributes;
+
+
+typedef struct {
+ hh_s_ppu_loc_fam_entry fam; //screen
+ uint16_t frame0;
+ uint16_t palette;
+ uint16_t ppu_foreground_index;
+
+}hh_s_rendering;
+
+typedef struct {
+ vec2 pos, vel, size;
+ bool is_grounded;
+ bool is_hit;
+ uint8_t radius;
+ int8_t hp;
+ int8_t speed;
+ hh_s_rendering render;
+
+}hh_entity;
+
+typedef struct {
+ hh_entity p;
+ hh_s_atributes atr;
+}hh_s_player;