aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.gitignore1
-rw-r--r--src/demo.c183
-rw-r--r--src/demo.h35
-rw-r--r--src/ds.c15
-rw-r--r--src/ds.mk9
-rw-r--r--src/engine/TODO/combat.h9
-rw-r--r--src/engine/camera.c34
-rw-r--r--src/engine/camera.h6
-rw-r--r--src/engine/draw_screen.c62
-rw-r--r--src/engine/draw_screen.h21
-rw-r--r--src/engine/engine.c4
-rw-r--r--src/engine/entity.c46
-rw-r--r--src/engine/entity.h57
-rw-r--r--src/engine/level.h5
-rw-r--r--src/engine/maths.c19
-rw-r--r--src/engine/maths.h22
-rw-r--r--src/engine/player_controller.c167
-rw-r--r--src/engine/player_controller.h7
-rw-r--r--src/engine/sprite_controller.c22
-rw-r--r--src/engine/sprite_controller.h106
-rw-r--r--src/entity.h14
-rw-r--r--src/input.h21
-rw-r--r--src/main.c20
-rw-r--r--src/makefile16
-rw-r--r--src/ppu/internals.c75
-rw-r--r--src/ppu/ppu.c22
-rw-r--r--src/ppu/stm.c4
-rw-r--r--src/ppusim/input.c16
-rw-r--r--src/ppusim/mem.c4
-rw-r--r--src/ppusim/pixel.c77
-rw-r--r--src/ppusim/sim.c45
-rw-r--r--src/ppusim/sim.h3
-rw-r--r--src/ppusim/work.c40
-rw-r--r--src/ppusim/work.h1
-rw-r--r--src/stm32.mk34
-rw-r--r--src/stm32/input.c13
-rw-r--r--src/stm32/main.c3
-rw-r--r--src/stm32/setup.c197
-rw-r--r--src/stm32/setup.h24
-rw-r--r--src/stm32/stm32f0xx_hal_conf.h16
40 files changed, 1256 insertions, 219 deletions
diff --git a/src/.gitignore b/src/.gitignore
index d8325cf..504b995 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -4,3 +4,4 @@ main.bin
main
main.exe
static/
+*.bin
diff --git a/src/demo.c b/src/demo.c
index 019750a..95347cb 100644
--- a/src/demo.c
+++ b/src/demo.c
@@ -1,55 +1,154 @@
#include <math.h>
#include "demo.h"
+#include "input.h"
+#include "entity.h"
#include "ppu/ppu.h"
-#define HH_DEMO_BALL_COUNT 5
-hh_s_ppu_loc_fam_entry g_hh_demo_balls[HH_DEMO_BALL_COUNT];
+#include "engine/maths.h"
+#include "engine/camera.h"
+#include "engine/entity.h"
+#include "engine/draw_screen.h"
+#include "engine/player_controller.h"
+#include "engine/sprite_controller.h"
+
+
+hh_s_entity_player g_hh_player_1 = {
+ .pos_x = 31000, // 0b0000 0001 0011 0110
+ .pos_y = 21000,
+ .radius = 8,
+ .speed = 100,
+ .direction_x = 1,
+ .rotation = 8,
+ .in_air = false,
+};
+
+void hh_player_movement();
+
+uint16_t g_hh_pos_x; // 0b0000 0001 0011 0110
+uint16_t g_hh_pos_y;
+uint8_t g_hh_left = 0;
+uint8_t g_hh_right = 0;
+uint8_t g_hh_up = 0;
+uint8_t g_hh_down = 0;
+uint8_t g_hh_pos_x_bit[2];
+uint8_t g_hh_pos_y_bit[2];
+uint8_t g_hh_data_send[3];
+int g_hh_tile_x;
+int g_hh_tile_y;
+
+typedef struct {
+ vec2 pos;
+ uint8_t idx;
+}hh_s_tiles;
+
+
+hh_entity hh_g_player, hh_g_player_new;
void hh_demo_setup() {
- // load sprites
- hh_ppu_update_sprite(0, HH_DBG_SPRITE_BALL);
- hh_ppu_update_sprite(1, HH_DBG_SPRITE_CHECKERBOARD);
-
- // background pattern
- hh_ppu_update_color(0, 1, (hh_ppu_rgb_color_t) {0x4, 0x4, 0x4});
- for (unsigned i = 0; i < HH_PPU_BG_CANVAS_TILES_H * HH_PPU_BG_CANVAS_TILES_V; i++) {
- hh_ppu_update_background(i, (hh_s_ppu_loc_bam_entry) {
- .horizontal_flip = false,
- .vertical_flip = false,
- .palette_index = 0,
- .tilemap_index = 1,
- });
- }
- // cool colors
- hh_ppu_update_color(1, 1, (hh_ppu_rgb_color_t) {0xf, 0x0, 0xf});
- hh_ppu_update_color(2, 1, (hh_ppu_rgb_color_t) {0xf, 0xf, 0xf});
- hh_ppu_update_color(3, 1, (hh_ppu_rgb_color_t) {0xf, 0x0, 0x0});
- hh_ppu_update_color(4, 1, (hh_ppu_rgb_color_t) {0x0, 0xf, 0xf});
- hh_ppu_update_color(5, 1, (hh_ppu_rgb_color_t) {0x0, 0x0, 0xf});
-
- // balls
- for (unsigned i = 0; i < HH_DEMO_BALL_COUNT; i++) {
- g_hh_demo_balls[i].horizontal_flip = false;
- g_hh_demo_balls[i].vertical_flip = false;
- g_hh_demo_balls[i].palette_index = i+1;
- g_hh_demo_balls[i].tilemap_index = 0;
- }
+ hh_setup_palettes();
+ hh_setup_screen();
+
}
void hh_demo_loop(unsigned long frame) {
- // set background pattern position
- hh_ppu_update_aux((hh_s_ppu_loc_aux) {
- .bg_shift_x = (frame / 2) % HH_PPU_SPRITE_WIDTH,
- .bg_shift_y = (frame / 8) % HH_PPU_SPRITE_HEIGHT,
- .fg_fetch = 0,
- .sysreset = 0,
- });
-
- for (unsigned i = 0; i < HH_DEMO_BALL_COUNT; i++) {
- g_hh_demo_balls[i].position_x = HH_PPU_SCREEN_WIDTH/2 - HH_PPU_SPRITE_WIDTH/2 + (int)(60 * (double)sin((1*(double)frame / 10) + (double)i * 12));
- g_hh_demo_balls[i].position_y = HH_PPU_SCREEN_HEIGHT/2 - HH_PPU_SPRITE_HEIGHT/2 + (int)(30 * (double)sin((2*(double)frame / 10) + (double)i * 12));
- hh_ppu_update_foreground(i, g_hh_demo_balls[i]);
+
+ // hh_player_movement();
+
+ hh_player_actions();
+
+}
+
+// void sendData(uint8_t address, uint16_t data) {
+// uint8_t bitData[3];
+// bitData[2] = data & 0xff;
+// bitData[1] = (data >> 8);
+// bitData[0] = address; // first byte is address
+//
+// HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);
+// HAL_SPI_Transmit(&hspi1, bitData, 3, 100); //2*8 bit data
+// HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);
+// }
+
+void hh_player_movement() {
+ int8_t directionX = (-1 * g_hh_controller_p1.dpad_left) + (1 * g_hh_controller_p1.dpad_right); // -1 = L || 1 == R
+ int8_t directionY = (-1 * g_hh_controller_p1.dpad_up) + (1 * g_hh_controller_p1.dpad_down); // -1 = D || 1 == U
+
+ uint8_t i, j;
+ uint8_t rotation = 0; // 0-7
+
+ // rotation calc
+ for (i = -1; i < 2; i++) {
+ for (j = -1; j < 2; j++) {
+ if (directionX == i) {
+ if (directionY == j) {
+ if (i != 0 && j != 0) // dont update when player idle
+ {
+ g_hh_player_1.rotation = rotation;
+ }
+ }
+ }
+ rotation++;
+ }
+ }
+ // direction calc
+ if (directionX != 0) // update direction if player is not idle
+ {
+ g_hh_player_1.direction_x = directionX;
+ }
+ // collision map x-axis
+
+ // tile calc including radius and direction for background coliision
+
+ uint16_t tileColX;
+ uint16_t tileColY = (g_hh_player_1.pos_y / 100) / 16;
+ ;
+
+ // remaining space between grid and exact
+ uint8_t modTileX;
+ uint8_t modTileY;
+
+ if (g_hh_player_1.in_air == false && directionX != 0) {
+ if (directionX == 1) {
+ tileColX = ((g_hh_player_1.pos_x / 100) + g_hh_player_1.radius) / 16;
+ modTileX = (g_hh_player_1.pos_x + (100 * g_hh_player_1.radius)) % 1600;
+ } else if (directionX == -1) {
+ tileColX = ((g_hh_player_1.pos_x / 100) - g_hh_player_1.radius) / 16;
+ modTileX = (g_hh_player_1.pos_x - (100 * g_hh_player_1.radius)) % 1600;
+ }
+
+ if (HH_DEMO_HITBOX_TILEMAP[tileColY][tileColX + directionX] != 1) {
+ g_hh_player_1.pos_x = g_hh_player_1.pos_x + (directionX * g_hh_player_1.speed); // NEW x set
+ }
+
+ else if (HH_DEMO_HITBOX_TILEMAP[tileColY][tileColX + directionX] == 1) {
+ if (modTileX < g_hh_player_1.speed) {
+ g_hh_player_1.pos_x = g_hh_player_1.pos_x + (directionX * modTileX); // NEW x set
+ } else {
+ g_hh_player_1.pos_x = g_hh_player_1.pos_x + (directionX * g_hh_player_1.speed); // NEW x set
+ }
+ }
+
+ } else // if in air different all borders have to be checked
+ {
+ }
+
+
+ if(directionY != 0)
+ {
+ // g_hh_player_1.pos_y = g_hh_player_1.pos_y + (directionY * g_hh_player_1.speed * 2); // NEW x set
+ }
+ // collision map floor (y-axis) (falling)
+ // if falling no jump press (implement)
+ /*
+ tileColY = (( g_hh_player_1.pos_y / 100) + g_hh_player_1.radius) / 16; //bottom of player box
+ modTileY = 1;
+ if(HH_DEMO_HITBOX_TILEMAP[tileColY+1][tileColX] != 1) //rework after jumping
+ {
+ g_hh_player_1.pos_y = g_hh_player_1.pos_y + 5 ;// NEW y set //makew var gravity
+ //playerStat = falling; //for later use of graphics/sound
}
+ */
+ // else if(HH_DEMO_HITBOX_TILEMAP[])
}
diff --git a/src/demo.h b/src/demo.h
index 89436b5..ddf8403 100644
--- a/src/demo.h
+++ b/src/demo.h
@@ -42,3 +42,38 @@ static const hh_s_ppu_loc_sprite HH_DBG_SPRITE_CHECKERBOARD = {
0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0
};
+
+static const uint8_t HH_DEMO_HITBOX_TILEMAP[30][40] =
+ {
+ {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 },
+ {1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 ,1,1,1,1,1,1,1,1,1,1 }
+ };
+
diff --git a/src/ds.c b/src/ds.c
new file mode 100644
index 0000000..24ef58f
--- /dev/null
+++ b/src/ds.c
@@ -0,0 +1,15 @@
+#include "demo.h"
+#include "main.h"
+#include "ppu/ppu.h"
+
+void hh_setup() {
+ hh_ppu_init();
+
+ hh_demo_setup();
+}
+
+void hh_exit() {
+ g_hh_run = false;
+
+ hh_ppu_deinit();
+}
diff --git a/src/ds.mk b/src/ds.mk
index f70c1c9..57d1776 100644
--- a/src/ds.mk
+++ b/src/ds.mk
@@ -3,8 +3,13 @@ LD := gcc
LFLAGS += -lSDL2
+ifeq ($(HOST),Msys)
+SHARED_FLAGS += -I/mingw64/include
+endif
+
DESKTOP_SRCS += ppusim/sim.c \
ppusim/mem.c \
ppusim/pixel.c \
- ppusim/work.c
-
+ ppusim/work.c \
+ ds.c \
+ ppusim/input.c
diff --git a/src/engine/TODO/combat.h b/src/engine/TODO/combat.h
new file mode 100644
index 0000000..16c41f5
--- /dev/null
+++ b/src/engine/TODO/combat.h
@@ -0,0 +1,9 @@
+#include "hh_entity.h"
+
+
+// attacktypes:
+
+/// @brief basic attack
+/// @param dmg damage number
+/// @param target entity under attack (damage changes this hp value)
+void hh_attack_basic( int8_t dmg, hh_entity* target );
diff --git a/src/engine/camera.c b/src/engine/camera.c
new file mode 100644
index 0000000..e756bd4
--- /dev/null
+++ b/src/engine/camera.c
@@ -0,0 +1,34 @@
+#include "engine/camera.h"
+
+#include "ppu/consts.h"
+
+
+vec_cor hh_update_camera(vec_cen new, vec2 min, vec2 max){
+
+ //TODO: change floating point math to fix point math
+ //TODO: fix buggy y-axis ??
+
+ // new = vec_cen2cor(new,(vec2){.x=max.x/2,.y=max.y/2});
+ new = vec_cen2cor((vec2){.x=new.x+(HH_PPU_SPRITE_WIDTH/2),.y=(new.y+(HH_PPU_SPRITE_HEIGHT/2))*2},(vec2){.x=max.x/2,.y=max.y/2});
+ // new.x = new.x << HH_MATH_FIXED_POINT;
+ // new.y = new.y << HH_MATH_FIXED_POINT;
+ static vec_cor old;
+ // old.x = old.x << HH_MATH_FIXED_POINT;
+ // old.y = old.y << HH_MATH_FIXED_POINT;
+
+ // int16_t some = 0;
+ // some = some <<= HH_MATH_FIXED_POINT-1;
+
+ new.x = (int)((float)new.x*0.1f + (float)old.x*0.9f);
+ new.y = (int)((float)new.y*0.1f + (float)old.y*0.9f);
+
+ // old.x = old.x >> HH_MATH_FIXED_POINT;
+ // old.y = old.y >> HH_MATH_FIXED_POINT;
+
+
+ old.x = CLAMP(new.x,min.x,max.x);
+ old.y = CLAMP(new.y,min.y,max.y);
+
+ return old;
+}
+
diff --git a/src/engine/camera.h b/src/engine/camera.h
new file mode 100644
index 0000000..b3ffb52
--- /dev/null
+++ b/src/engine/camera.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "engine/maths.h"
+
+vec_cor hh_update_camera(vec_cor new, vec2 min, vec2 max);
+
diff --git a/src/engine/draw_screen.c b/src/engine/draw_screen.c
new file mode 100644
index 0000000..c4f3389
--- /dev/null
+++ b/src/engine/draw_screen.c
@@ -0,0 +1,62 @@
+#include "engine/draw_screen.h"
+#include "engine/sprite_controller.h"
+
+uint8_t hh_world_to_tile(vec2 pos){
+
+ FILE* level = fopen("../test/bin/level1_test.bin", "rb"); /* open binary file */
+ if (!level) { /* check if file opened successfully */
+ fprintf(stderr, "Error: Failed to open file.\n");
+ return 0;
+ }
+ int index = ((pos.y/16)*40 + pos.x/16);//TODO: remove magic number(s)
+ fseek(level, (index * sizeof(int)) + sizeof(int), SEEK_SET);
+ int tile;// = (int*)malloc(sizeof(int));
+ fread(&tile, sizeof(int), 1, level); // read 1 tile from binary
+
+ fclose(level);
+ // int val = tile;
+ // free(tile);
+ return tile;
+}
+
+
+// remeber old value to know which part to update.
+vec2 previousViewport = { .x = 0, .y = 0 };
+void hh_draw_screen(vec_cor viewport){
+ if (viewport.x == previousViewport.x && viewport.y == previousViewport.y) return;
+
+ hh_ppu_update_aux((hh_s_ppu_loc_aux){
+ .bg_shift_x = viewport.x,
+ .bg_shift_y = viewport.y,
+ .fg_fetch = 0,
+ .sysreset = 0,
+ });
+
+ // update previous viewport values
+ previousViewport = viewport;
+}
+
+void hh_setup_screen(){
+ //(HH_map_size_X*HH_map_size_Y)
+ int size = 2400; // max X = 40 en max Y = 80
+ FILE* level = fopen("../test/bin/level1_test.bin", "rb"); /* open binary file */
+ if (!level) { /* check if file opened successfully */
+ fprintf(stderr, "Error: Failed to open file.\n");
+ return;
+ }
+ fseek(level, (0* sizeof(int)) + sizeof(int), SEEK_SET);
+ int* tile = (int*)malloc(size*sizeof(int));
+ fread(tile, sizeof(int), size, level); // read 1 tile from binary
+
+ fclose(level);
+
+ for(int BAM_index = 0; BAM_index < size; BAM_index++){
+ hh_ppu_update_background(BAM_index, (hh_s_ppu_loc_bam_entry){
+ .horizontal_flip = false,
+ .vertical_flip = false,
+ .palette_index = hh_get_palette(tile[BAM_index]),
+ .tilemap_index = tile[BAM_index],
+ });
+ }
+ free(tile);
+}
diff --git a/src/engine/draw_screen.h b/src/engine/draw_screen.h
new file mode 100644
index 0000000..b181108
--- /dev/null
+++ b/src/engine/draw_screen.h
@@ -0,0 +1,21 @@
+#pragma once
+
+
+// every function call for drawing the screen goes here.
+#include "engine/maths.h"
+#include "ppu/ppu.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+
+#define HH_map_size_X 80
+#define HH_map_size_Y 60
+
+/** @brief return a single tile from world binary */
+uint8_t hh_world_to_tile(vec2 pos);
+/** @brief shift to level if viewport changed position */
+void hh_draw_screen(vec2 viewport);
+/** @brief send data to BAM memory from binary level */
+void hh_setup_screen();
diff --git a/src/engine/engine.c b/src/engine/engine.c
new file mode 100644
index 0000000..799ee7c
--- /dev/null
+++ b/src/engine/engine.c
@@ -0,0 +1,4 @@
+#include "engine/draw_screen.h"
+#include "engine/level.h"
+#include "engine/maths.h"
+#include "engine/sprite_controller.h"
diff --git a/src/engine/entity.c b/src/engine/entity.c
new file mode 100644
index 0000000..153e7e1
--- /dev/null
+++ b/src/engine/entity.c
@@ -0,0 +1,46 @@
+#include <stdbool.h>
+
+#include "engine/entity.h"
+#include "engine/maths.h"
+
+/*
+ PLAYER: (pos on X)
+ ,___,
+ | |
+ | X |
+ |___|
+
+*/
+
+bool hh_collision(vec_cor pos1, vec2 pos2){
+ if (pos2.x == CLAMP(pos2.x, pos1.x, pos1.x+16)){// hit x
+ return true;
+ }
+
+ if (pos2.y == CLAMP(pos2.y, pos1.y, pos1.y+16)){// hit y
+ return true;
+ }
+ return false;
+}
+
+void hh_solve_collision(vec2 pos_environment, hh_entity* entity){
+ if (!hh_collision(pos_environment,entity->pos))
+ return;
+
+ printf("BONK!/n");
+ // if (entity->vel.y > 0){
+ // entity->pos.y = MAX(entity->pos.y,pos_environment.y);
+ // entity->vel.y = 0;
+ // } else {
+ // entity->pos.y = MIN(entity->pos.y,pos_environment.y);
+ // entity->vel.y = 0;
+ // }
+ // if (entity->vel.x <= 0){
+ // entity->pos.x = MIN(entity->pos.x,pos_environment.x-16);
+ // entity->vel.x = 0;
+ // } else {
+ // entity->pos.x = MAX(entity->pos.x,pos_environment.x+16);
+ // entity->vel.x = 0;
+ // }
+}
+
diff --git a/src/engine/entity.h b/src/engine/entity.h
new file mode 100644
index 0000000..f45dae2
--- /dev/null
+++ b/src/engine/entity.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "ppu/types.h"
+
+#include "engine/maths.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;
+ 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;
+
+
+/// @brief detect for collision enity and eviroment
+/// @param pos1 position of environment tile to be checked
+/// @param pos2 position entity
+/// @return true if collision between enity and environment
+bool hh_collision(vec2 pos1, vec2 pos2);
+
+/// @brief solve collisions
+/// @param environment position
+/// @param entity position
+/// @return solved new entity position
+void hh_solve_collision(vec2 pos_environment, hh_entity* entity);
diff --git a/src/engine/level.h b/src/engine/level.h
new file mode 100644
index 0000000..8d610dd
--- /dev/null
+++ b/src/engine/level.h
@@ -0,0 +1,5 @@
+#pragma once
+//deal with loading/saving the correct level
+
+/** @brief */
+void hh_map_load();
diff --git a/src/engine/maths.c b/src/engine/maths.c
new file mode 100644
index 0000000..475bba2
--- /dev/null
+++ b/src/engine/maths.c
@@ -0,0 +1,19 @@
+#include "engine/maths.h"
+
+vec2 vec_add(vec2 a, vec2 b){
+ return (vec2){a.x + b.x, a.y + b.y};
+}
+
+vec_cor vec_cen2cor(vec_cen in, vec2 halfDistance){
+ return (vec_cor){
+ .x = in.x - halfDistance.x,
+ .y = in.y - halfDistance.y,
+ };
+}
+
+vec_cen vec_cor2cen(vec_cor in, vec2 halfDistance){
+ return (vec_cen){
+ .x = in.x + halfDistance.x,
+ .y = in.y + halfDistance.y,
+ };
+}
diff --git a/src/engine/maths.h b/src/engine/maths.h
new file mode 100644
index 0000000..bef287e
--- /dev/null
+++ b/src/engine/maths.h
@@ -0,0 +1,22 @@
+#pragma once
+#include <stdint.h>
+// #include <math.h>
+
+typedef struct {
+ int32_t x,y;
+} vec2;
+
+typedef vec2 vec_cen;//centered
+typedef vec2 vec_cor;//left upper corner
+
+vec2 vec_add(vec2 a, vec2 b);
+
+vec_cor vec_cen2cor(vec_cen in, vec2 halfDistance);
+vec_cor vec_cor2cen(vec_cen in, vec2 halfDistance);
+
+//fixed point at decimal 7lsb (world positions in pixels (with fixed decimal point))
+#define HH_MATH_FIXED_POINT 7
+
+#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))
diff --git a/src/engine/player_controller.c b/src/engine/player_controller.c
new file mode 100644
index 0000000..6735620
--- /dev/null
+++ b/src/engine/player_controller.c
@@ -0,0 +1,167 @@
+#include "ppu/types.h"
+#include "engine/camera.h"
+#include "engine/draw_screen.h"
+#include "engine/sprite_controller.h"
+#include "engine/player_controller.h"
+
+#include "demo.h"
+#include <stdio.h>
+
+#include "input.h"
+
+void hh_player_actions() {
+ static hh_entity player={
+ .hp = 4,
+ .speed = 6,
+ .is_grounded = false,
+ .pos = (vec2){32,32},
+ .vel = (vec2){0,0},
+ .vec = (vec2){0,0},
+ .render = {
+ .frame0 = 20,
+ .palette = 7,
+ .fam = (hh_s_ppu_loc_fam_entry){
+ .horizontal_flip = false,
+ .vertical_flip = false,
+ .palette_index = 7,
+ .tilemap_index = 2,
+ }
+ }
+ }, player_new = {0};
+
+ // hh_input_read();
+ player.vel = (vec2){.x = (-1 * g_hh_controller_p1.dpad_left) + (1 * g_hh_controller_p1.dpad_right),
+ .y = (-1 * g_hh_controller_p1.dpad_up) + (1 * g_hh_controller_p1.dpad_down) };
+ // 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.render.fam.palette_index = 7;
+ // player.render.fam.tilemap_index = 7;
+
+ // printf("%x ",player.render.fam.palette_index);
+
+ // 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.pos = (vec2){
+ .x = player.pos.x + player.vel.x,
+ .y = player.pos.y + player.vel.y,
+ };
+
+
+
+ // 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_new.is_grounded = false;
+
+ // solves x collision
+ if (player.vel.x <= 0) {
+ if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player.pos.y + 0})) ||
+ hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player.pos.y + 15}))) {
+ player_new.pos.x = (player_new.pos.x & ~15) + 16,
+ player_new.vel.x = 0;
+ }
+ } else {
+ if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 16, .y=player.pos.y + 0})) ||
+ hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 16, .y=player.pos.y + 15}))) {
+ player_new.pos.x = player_new.pos.x & ~15, // <-- magic comma, NOT TOUCHY
+ player_new.vel.x = 0;
+ }
+ }
+
+ //solves y collision
+ if (player.vel.y <= 0) {
+ if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player_new.pos.y + 0})) ||
+ hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player_new.pos.y + 15}))) {
+ player_new.pos.y = (player_new.pos.y & ~15) + 16,
+ player_new.vel.y = 0;
+ }
+ } else {
+ if (hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 0, .y=player_new.pos.y + 16})) ||
+ hh_colidable(hh_world_to_tile((vec2){.x=player_new.pos.x + 16, .y=player_new.pos.y + 15}))) {
+ player_new.pos.y = player_new.pos.y & ~15,
+ player_new.vel.y = 0;
+ player_new.is_grounded = true;
+ }
+ }
+
+ 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);
+ // 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);
+
+
+ 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);
+
+
+ hh_s_ppu_loc_fam_entry sprite = {
+ .position_x = 16,
+ .position_y = 16,
+ .palette_index = 7,
+ .tilemap_index = 2,
+ };
+ hh_ppu_update_foreground(1, sprite);
+
+}
+
diff --git a/src/engine/player_controller.h b/src/engine/player_controller.h
new file mode 100644
index 0000000..400c18e
--- /dev/null
+++ b/src/engine/player_controller.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "engine/maths.h"
+#include "engine/entity.h"
+// inputs
+
+void hh_player_actions();
diff --git a/src/engine/sprite_controller.c b/src/engine/sprite_controller.c
new file mode 100644
index 0000000..5d93cf8
--- /dev/null
+++ b/src/engine/sprite_controller.c
@@ -0,0 +1,22 @@
+#include <stdint.h>
+
+#include "engine/sprite_controller.h"
+#include "ppu/types.h"
+#include "ppu/consts.h"
+#include "ppu/ppu.h"
+
+uint8_t hh_get_palette(uint8_t tile_idx) {
+ return hh_g_sprite_palette[tile_idx];
+}
+
+void hh_setup_palettes(){
+ for (int idx = 0; idx < HH_PPU_PALETTE_COUNT; idx++) {
+ for (int col = 0; col < HH_PPU_PALETTE_COLOR_COUNT; col++) {
+ hh_ppu_update_color(idx,col,hh_g_palette[idx][col]);
+ }
+ }
+}
+
+bool hh_colidable(uint8_t tile_idx){
+ return (hh_get_palette(tile_idx) != 0);
+}
diff --git a/src/engine/sprite_controller.h b/src/engine/sprite_controller.h
new file mode 100644
index 0000000..001a459
--- /dev/null
+++ b/src/engine/sprite_controller.h
@@ -0,0 +1,106 @@
+#pragma once
+#include <stdint.h>
+
+#include "ppu/types.h"
+
+// handles sprites
+
+// Bg sprites
+
+// Fg or entity sprites
+
+//TODO: pack data inside of sprite_palette LUT
+//HH_PPU_PALETTE_COUNT
+#define HH_SPRITE_COUNT 40
+#define HH_PAL_IDX_SKY 0
+#define HH_PAL_IDX_BRICK 1
+const static uint8_t hh_g_sprite_palette[HH_SPRITE_COUNT] = {
+ 0,1,1,1,1,1,1,1,1,1, //1+9
+ 1,1,1,1,1,1,1,1,1,1, //6+4
+ 1,1,1,1,1,1,1,1,1, //9
+ 7,7,7,2,7,7,1,2,7
+ //other palettes here:
+};
+
+
+const static hh_ppu_loc_palette_table_t hh_g_palette = {
+ {//palette info here
+ {0x1,0x2,0x3},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0}},
+ {//Bricks
+ {0x1,0x2,0x3},//01
+ {0xd,0x8,0xa},//24
+ {0x0,0x0,0x1},//25
+ {0x1,0x1,0x1},//26
+ {0x1,0x1,0x2},//27
+ {0x2,0x2,0x3},//28
+ {0x3,0x4,0x5},//29
+ {0x5,0x1,0x7}},
+ {//slime
+ {0x1,0x2,0x3},
+ {0x1,0x3,0x2},
+ {0x4,0x8,0x3},
+ {0x7,0xa,0x4},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0}},
+ {
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0}},
+ {
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0}},
+ {
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0}},
+ {
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0},
+ {0x0,0x0,0x0}},
+ {
+ {0x0,0xf,0xf},
+ {0xf,0xf,0xf},
+ {0xf,0x0,0xf},
+ {0xf,0xf,0x0},
+ {0xf,0x0,0x0},
+ {0x0,0xf,0x0},
+ {0x0,0x0,0xf},
+ {0x0,0x0,0x0}}
+};
+
+void hh_setup_palettes();
+
+/** @brief return palette index that belongs to tilemap index */
+uint8_t hh_get_palette(uint8_t tile_idx);
+
+bool hh_colidable(uint8_t tile_idx);
diff --git a/src/entity.h b/src/entity.h
new file mode 100644
index 0000000..181182b
--- /dev/null
+++ b/src/entity.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef struct {
+ uint16_t pos_x;
+ uint16_t pos_y;
+ uint8_t radius;
+ uint8_t rotation; //45 degrees steps 0 == right 2 == down 4 == left 6 == up
+ uint8_t direction_x; //direction where its looking at in case no input;
+ int8_t speed; //10 default L/R MODifier
+ bool in_air;
+} hh_s_entity_player;
diff --git a/src/input.h b/src/input.h
new file mode 100644
index 0000000..90f0c61
--- /dev/null
+++ b/src/input.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <stdbool.h>
+
+/** @brief game controller state */
+typedef struct {
+ bool dpad_up;
+ bool dpad_down;
+ bool dpad_left;
+ bool dpad_right;
+ bool button_primary;
+ bool button_secondary;
+} hh_s_gamepad;
+
+/** @brief player 1's controller */
+extern hh_s_gamepad g_hh_controller_p1;
+/** @brief player 2's controller */
+extern hh_s_gamepad g_hh_controller_p2;
+
+/** @brief update g_hh_controller_p1 and 2 by reading buttons */
+void hh_input_read();
diff --git a/src/main.c b/src/main.c
index f4de225..191d5d9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,8 +1,8 @@
#include <stdlib.h>
-#include "main.h"
-#include "ppu/ppu.h"
#include "demo.h"
+#include "input.h"
+#include "main.h"
bool g_hh_run = true;
@@ -15,19 +15,7 @@ int main() {
void hh_ppu_vblank_interrupt() {
static unsigned long frame = 0;
- frame++;
-
+ hh_input_read();
hh_demo_loop(frame);
-}
-
-void hh_setup() {
- hh_ppu_init();
-
- hh_demo_setup();
-}
-
-void hh_exit() {
- g_hh_run = false;
-
- hh_ppu_deinit();
+ frame++;
}
diff --git a/src/makefile b/src/makefile
index 1f1dc65..d7d9087 100644
--- a/src/makefile
+++ b/src/makefile
@@ -4,6 +4,7 @@ TARGET = main
# platform is ds (desktop) or stm (stm32)
PLATFORM = ds
+# if your editor uses compile_commands.json for autocomplete, you should run `make compile_commands.json` again
HOST=$(strip $(shell uname -o))
@@ -29,7 +30,14 @@ CFLAGS += $(if $(DESKTOP), -DHH_TARGET_DESKTOP, )
LOCAL_SRCS += main.c \
ppu/internals.c \
ppu/ppu.c \
- demo.c
+ demo.c \
+ engine/engine.c \
+ engine/sprite_controller.c \
+ engine/player_controller.c \
+ engine/draw_screen.c \
+ engine/camera.c \
+ engine/maths.c \
+ engine/entity.c
CFLAGS += $(SHARED_FLAGS)
LFLAGS += $(SHARED_FLAGS)
@@ -74,14 +82,14 @@ flash: $(TARGET).bin
$(TARGET): $(OBJS)
$(LD) $^ $(LFLAGS) -o $@
-compile_commands.json:
+compile_commands.json: makefile stm32.mk ds.mk
compiledb make -Bn
../scripts/compiledb-full-path-mingw.sh compile_commands.json
PHONY += format
format:
- clang-format -i $(LOCAL_SRCS)
- clang-tidy --fix-errors $(LOCAL_SRCS)
+ clang-format -i $(LOCAL_SRCS) $(DESKTOP_SRCS)
+ clang-tidy --fix-errors $(LOCAL_SRCS) $(DESKTOP_SRCS)
PHONY += clean
clean:
diff --git a/src/ppu/internals.c b/src/ppu/internals.c
index 650ba3e..b8d3e27 100644
--- a/src/ppu/internals.c
+++ b/src/ppu/internals.c
@@ -1,8 +1,8 @@
#include <stdlib.h>
-#include "ppu/types.h"
-#include "ppu/internals.h"
#include "ppu/consts.h"
+#include "ppu/internals.h"
+#include "ppu/types.h"
bool hh_ppu_vram_valid_address(hh_ppu_addr_t addr) {
#pragma GCC diagnostic push
@@ -17,88 +17,59 @@ bool hh_ppu_vram_valid_address(hh_ppu_addr_t addr) {
}
void hh_ppu_vram_write(hh_s_ppu_vram_data data) {
- for (unsigned i = 0; i < data.size; i++)
- hh_ppu_vram_dwrite(data.offset + i, data.data[i]);
+ for (unsigned i = 0; i < data.size; i++) hh_ppu_vram_dwrite(data.offset + i, data.data[i]);
}
hh_s_ppu_vram_data hh_ppu_2nat_bam(hh_s_ppu_loc_bam_entry e) {
- hh_ppu_data_t* data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_BAM_ENTRY_SIZE);
+ hh_ppu_data_t *data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_BAM_ENTRY_SIZE);
- data[0] = HH_RESIZE(e.tilemap_index, 9, 0) << 0 |
- HH_RESIZE(e.palette_index, 2, 0) << 10 |
- e.vertical_flip << 13 |
- e.horizontal_flip << 14;
+ data[0] = HH_RESIZE(e.tilemap_index, 9, 0) << 0 | HH_RESIZE(e.palette_index, 2, 0) << 10 | e.vertical_flip << 13 | e.horizontal_flip << 14;
- hh_s_ppu_vram_data out = {
- .data = data,
- .size = HH_PPU_VRAM_FAM_ENTRY_SIZE
- };
+ hh_s_ppu_vram_data out = {.data = data, .size = HH_PPU_VRAM_FAM_ENTRY_SIZE};
return out;
}
hh_s_ppu_vram_data hh_ppu_2nat_fam(hh_s_ppu_loc_fam_entry e) {
- hh_ppu_data_t* data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_FAM_ENTRY_SIZE);
+ hh_ppu_data_t *data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_FAM_ENTRY_SIZE);
e.position_x += 16;
e.position_y += 16;
- data[0] = HH_RESIZE(e.tilemap_index, 9, 0) << 0 |
- HH_RESIZE(e.palette_index, 2, 0) << 10 |
- HH_RESIZE(e.position_y, 2, 0) << 13;
- data[1] = HH_RESIZE(e.position_y, 7, 3) << 0 |
- HH_RESIZE(e.position_x, 8, 0) << 5 |
- e.vertical_flip << 14 |
- e.horizontal_flip << 15;
-
- hh_s_ppu_vram_data out = {
- .data = data,
- .size = HH_PPU_VRAM_FAM_ENTRY_SIZE
- };
+ data[0] = HH_RESIZE(e.tilemap_index, 9, 0) << 0 | HH_RESIZE(e.palette_index, 2, 0) << 10 | HH_RESIZE(e.position_y, 2, 0) << 13;
+ data[1] = HH_RESIZE(e.position_y, 7, 3) << 0 | HH_RESIZE(e.position_x, 8, 0) << 5 | e.vertical_flip << 14 | e.horizontal_flip << 15;
+
+ hh_s_ppu_vram_data out = {.data = data, .size = HH_PPU_VRAM_FAM_ENTRY_SIZE};
return out;
}
hh_s_ppu_vram_data hh_ppu_2nat_aux(hh_s_ppu_loc_aux aux) {
- hh_ppu_data_t* data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_AUX_SIZE);
-
- data[0] = HH_RESIZE(aux.bg_shift_y, 7, 0) << 0 |
- HH_RESIZE(aux.bg_shift_x, 7, 0) << 8;
- data[1] = HH_RESIZE(aux.bg_shift_x, 8, 8) << 0 |
- aux.fg_fetch << 1 |
- aux.sysreset << 2;
-
- hh_s_ppu_vram_data out = {
- .data = data,
- .size = HH_PPU_VRAM_AUX_SIZE
- };
+ hh_ppu_data_t *data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_AUX_SIZE);
+
+ data[0] = HH_RESIZE(aux.bg_shift_y, 7, 0) << 0 | HH_RESIZE(aux.bg_shift_x, 7, 0) << 8;
+ data[1] = HH_RESIZE(aux.bg_shift_x, 8, 8) << 0 | aux.fg_fetch << 1 | aux.sysreset << 2;
+
+ hh_s_ppu_vram_data out = {.data = data, .size = HH_PPU_VRAM_AUX_SIZE};
return out;
}
hh_s_ppu_vram_data hh_ppu_2nat_sprite(const hh_ppu_loc_sprite_data_t sprite_data) {
- hh_ppu_data_t* data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_TMM_SPRITE_SIZE);
+ hh_ppu_data_t *data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_TMM_SPRITE_SIZE);
for (unsigned i = 0; i < HH_PPU_SPRITE_WIDTH * HH_PPU_SPRITE_HEIGHT; i++) {
- unsigned word = i / 5;
+ unsigned word = i / 5;
unsigned pixel = i % 5;
if (pixel == 0) data[word] = 0;
data[word] |= HH_RESIZE(sprite_data[i], 2, 0) << pixel * 3;
}
- hh_s_ppu_vram_data out = {
- .data = data,
- .size = HH_PPU_VRAM_TMM_SPRITE_SIZE
- };
+ hh_s_ppu_vram_data out = {.data = data, .size = HH_PPU_VRAM_TMM_SPRITE_SIZE};
return out;
}
hh_s_ppu_vram_data hh_ppu_2nat_color(hh_ppu_rgb_color_t rgb) {
- hh_ppu_data_t* data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_PAL_ENTRY_SIZE);
+ hh_ppu_data_t *data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_PAL_ENTRY_SIZE);
- data[0] = HH_RESIZE(rgb[0], 3, 0) << 8 |
- HH_RESIZE(rgb[1], 3, 0) << 4 |
- HH_RESIZE(rgb[2], 3, 0) << 0;
+ data[0] = HH_RESIZE(rgb[0], 3, 0) << 8 | HH_RESIZE(rgb[1], 3, 0) << 4 | HH_RESIZE(rgb[2], 3, 0) << 0;
- hh_s_ppu_vram_data out = {
- .data = data,
- .size = HH_PPU_VRAM_PAL_ENTRY_SIZE
- };
+ hh_s_ppu_vram_data out = {.data = data, .size = HH_PPU_VRAM_PAL_ENTRY_SIZE};
return out;
}
diff --git a/src/ppu/ppu.c b/src/ppu/ppu.c
index 5f33c55..df14b9f 100644
--- a/src/ppu/ppu.c
+++ b/src/ppu/ppu.c
@@ -1,52 +1,48 @@
#include <stdlib.h>
-#include "ppu/ppu.h"
-#include "ppu/internals.h"
#include "ppu/consts.h"
+#include "ppu/internals.h"
+#include "ppu/ppu.h"
void hh_ppu_update_foreground(unsigned index, hh_s_ppu_loc_fam_entry e) {
hh_s_ppu_vram_data s = hh_ppu_2nat_fam(e);
- s.offset = HH_PPU_VRAM_FAM_OFFSET + HH_PPU_VRAM_FAM_ENTRY_SIZE * index;
+ s.offset = HH_PPU_VRAM_FAM_OFFSET + HH_PPU_VRAM_FAM_ENTRY_SIZE * index;
hh_ppu_vram_write(s);
free(s.data);
}
void hh_ppu_update_background(unsigned index, hh_s_ppu_loc_bam_entry e) {
hh_s_ppu_vram_data s = hh_ppu_2nat_bam(e);
- s.offset = HH_PPU_VRAM_BAM_OFFSET + HH_PPU_VRAM_BAM_ENTRY_SIZE * index;
+ s.offset = HH_PPU_VRAM_BAM_OFFSET + HH_PPU_VRAM_BAM_ENTRY_SIZE * index;
hh_ppu_vram_write(s);
free(s.data);
}
void hh_ppu_update_sprite(unsigned tilemap_index, const hh_s_ppu_loc_sprite sprite) {
hh_s_ppu_vram_data s = hh_ppu_2nat_sprite(sprite);
- s.offset = HH_PPU_VRAM_TMM_OFFSET + HH_PPU_VRAM_TMM_SPRITE_SIZE * tilemap_index;
+ s.offset = HH_PPU_VRAM_TMM_OFFSET + HH_PPU_VRAM_TMM_SPRITE_SIZE * tilemap_index;
hh_ppu_vram_write(s);
free(s.data);
}
void hh_ppu_update_aux(hh_s_ppu_loc_aux aux) {
hh_s_ppu_vram_data a = hh_ppu_2nat_aux(aux);
- a.offset = HH_PPU_VRAM_AUX_OFFSET;
+ a.offset = HH_PPU_VRAM_AUX_OFFSET;
hh_ppu_vram_write(a);
free(a.data);
}
void hh_ppu_update_palette_table(hh_ppu_loc_palette_table_t table) {
- for(unsigned i = 0; i < HH_PPU_PALETTE_COUNT; i++)
- hh_ppu_update_palette(i, table[i]);
+ for (unsigned i = 0; i < HH_PPU_PALETTE_COUNT; i++) hh_ppu_update_palette(i, table[i]);
}
void hh_ppu_update_palette(unsigned palette_index, hh_ppu_loc_palette_data_t palette) {
- for(unsigned i = 0; i < HH_PPU_PALETTE_COLOR_COUNT; i++)
- hh_ppu_update_color(palette_index, i, palette[i]);
+ for (unsigned i = 0; i < HH_PPU_PALETTE_COLOR_COUNT; i++) hh_ppu_update_color(palette_index, i, palette[i]);
}
void hh_ppu_update_color(unsigned palette_index, unsigned color_index, hh_ppu_rgb_color_t color) {
hh_s_ppu_vram_data c = hh_ppu_2nat_color(color);
- c.offset = HH_PPU_VRAM_PAL_OFFSET +
- palette_index * HH_PPU_VRAM_PAL_ENTRY_SIZE * HH_PPU_PALETTE_COLOR_COUNT +
- color_index * HH_PPU_VRAM_PAL_ENTRY_SIZE;
+ c.offset = HH_PPU_VRAM_PAL_OFFSET + palette_index * HH_PPU_VRAM_PAL_ENTRY_SIZE * HH_PPU_PALETTE_COLOR_COUNT + color_index * HH_PPU_VRAM_PAL_ENTRY_SIZE;
hh_ppu_vram_write(c);
free(c.data);
}
diff --git a/src/ppu/stm.c b/src/ppu/stm.c
new file mode 100644
index 0000000..fd4a18c
--- /dev/null
+++ b/src/ppu/stm.c
@@ -0,0 +1,4 @@
+#include "ppu/ppu.h"
+
+void hh_ppu_init() {}
+void hh_ppu_deinit() {}
diff --git a/src/ppusim/input.c b/src/ppusim/input.c
new file mode 100644
index 0000000..5323fb1
--- /dev/null
+++ b/src/ppusim/input.c
@@ -0,0 +1,16 @@
+#include <SDL2/SDL.h>
+
+#include "input.h"
+
+hh_s_gamepad g_hh_controller_p1 = {0};
+hh_s_gamepad g_hh_controller_p2 = {0};
+
+void hh_input_read() {
+ // SDL_PumpEvents();
+ const Uint8 *kb = SDL_GetKeyboardState(NULL);
+ g_hh_controller_p1.dpad_up = kb[SDL_SCANCODE_W];
+ g_hh_controller_p1.dpad_down = kb[SDL_SCANCODE_S];
+ g_hh_controller_p1.dpad_left = kb[SDL_SCANCODE_A];
+ g_hh_controller_p1.dpad_right = kb[SDL_SCANCODE_D];
+ g_hh_controller_p1.button_primary = kb[SDL_SCANCODE_SPACE];
+}
diff --git a/src/ppusim/mem.c b/src/ppusim/mem.c
index e3f41f5..bd8606e 100644
--- a/src/ppusim/mem.c
+++ b/src/ppusim/mem.c
@@ -1,8 +1,8 @@
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
-#include "ppusim/mem.h"
#include "ppu/internals.h"
+#include "ppusim/mem.h"
hh_ppu_data_t *g_hh_ppusim_vram = NULL;
diff --git a/src/ppusim/pixel.c b/src/ppusim/pixel.c
index 6e915e6..0457d55 100644
--- a/src/ppusim/pixel.c
+++ b/src/ppusim/pixel.c
@@ -1,10 +1,10 @@
#include <SDL2/SDL.h>
#include <stdbool.h>
-#include "ppusim/work.h"
+#include "ppu/consts.h"
#include "ppu/internals.h"
#include "ppusim/mem.h"
-#include "ppu/consts.h"
+#include "ppusim/work.h"
/* transform xy if tile is flipped */
static uint16_t hh_ppusim_apply_transform(unsigned x, unsigned y, bool fliph, bool flipv) {
@@ -15,25 +15,25 @@ static uint16_t hh_ppusim_apply_transform(unsigned x, unsigned y, bool fliph, bo
/* @brief get current bg pixel cidx */
static uint8_t hh_ppusim_bg_pixel(unsigned x, unsigned y) {
- hh_ppu_data_t* aux = &g_hh_ppusim_vram[HH_PPU_VRAM_AUX_OFFSET];
- unsigned bg_shift_y = HH_RESIZE(aux[0], 7, 0);
- unsigned bg_shift_x = HH_RESIZE(aux[0], 15, 8) | HH_RESIZE(aux[1], 0, 0) << 8;
- unsigned abs_x = bg_shift_x + x;
- unsigned abs_y = bg_shift_y + y;
- unsigned grid_x = abs_x / HH_PPU_SPRITE_WIDTH;
- unsigned grid_y = abs_y / HH_PPU_SPRITE_HEIGHT;
- unsigned loc_x = abs_x - grid_x * HH_PPU_SPRITE_WIDTH;
- unsigned loc_y = abs_y - grid_y * HH_PPU_SPRITE_HEIGHT;
- unsigned bam_offset = grid_y * HH_PPU_BG_CANVAS_TILES_H + grid_x;
- hh_ppu_data_t bam = g_hh_ppusim_vram[HH_PPU_VRAM_BAM_OFFSET + bam_offset];
- uint8_t cidx = 0;
+ hh_ppu_data_t *aux = &g_hh_ppusim_vram[HH_PPU_VRAM_AUX_OFFSET];
+ unsigned bg_shift_y = HH_RESIZE(aux[0], 7, 0);
+ unsigned bg_shift_x = HH_RESIZE(aux[0], 15, 8) | HH_RESIZE(aux[1], 0, 0) << 8;
+ unsigned abs_x = bg_shift_x + x;
+ unsigned abs_y = bg_shift_y + y;
+ unsigned grid_x = abs_x / HH_PPU_SPRITE_WIDTH;
+ unsigned grid_y = abs_y / HH_PPU_SPRITE_HEIGHT;
+ unsigned loc_x = abs_x - grid_x * HH_PPU_SPRITE_WIDTH;
+ unsigned loc_y = abs_y - grid_y * HH_PPU_SPRITE_HEIGHT;
+ unsigned bam_offset = grid_y * HH_PPU_BG_CANVAS_TILES_H + grid_x;
+ hh_ppu_data_t bam = g_hh_ppusim_vram[HH_PPU_VRAM_BAM_OFFSET + bam_offset];
+ uint8_t cidx = 0;
uint16_t tile_pixel_idx = hh_ppusim_apply_transform(loc_x, loc_y, HH_RESIZE(bam, 14, 14), HH_RESIZE(bam, 13, 13));
- uint16_t tile_idx = HH_RESIZE(bam, 9, 0);
- hh_ppu_addr_t ttm_addr = tile_idx * HH_PPU_VRAM_TMM_SPRITE_SIZE + tile_pixel_idx / 5;
- uint8_t word_bit_addr = (tile_pixel_idx % 5) * 3;
- hh_ppu_data_t tmm = g_hh_ppusim_vram[HH_PPU_VRAM_TMM_OFFSET + ttm_addr];
+ uint16_t tile_idx = HH_RESIZE(bam, 9, 0);
+ hh_ppu_addr_t ttm_addr = tile_idx * HH_PPU_VRAM_TMM_SPRITE_SIZE + tile_pixel_idx / 5;
+ uint8_t word_bit_addr = (tile_pixel_idx % 5) * 3;
+ hh_ppu_data_t tmm = g_hh_ppusim_vram[HH_PPU_VRAM_TMM_OFFSET + ttm_addr];
cidx |= HH_RESIZE(bam, 12, 10) << 3;
- cidx |= HH_RESIZE(tmm, word_bit_addr+2, word_bit_addr) << 0;
+ cidx |= HH_RESIZE(tmm, word_bit_addr + 2, word_bit_addr) << 0;
return cidx;
}
@@ -44,42 +44,37 @@ static uint8_t hh_ppusim_fg_pixel(unsigned x, unsigned y) {
uint8_t cidx = 0;
for (unsigned i = 0; i < HH_PPU_FG_SPRITE_COUNT; i++) {
unsigned fam_offset = i * HH_PPU_VRAM_FAM_ENTRY_SIZE;
- hh_ppu_data_t* fam = &g_hh_ppusim_vram[HH_PPU_VRAM_FAM_OFFSET + fam_offset];
- unsigned sprite_y = HH_RESIZE(fam[0], 15, 13) | HH_RESIZE(fam[1], 4, 0) << 3;
- unsigned sprite_x = HH_RESIZE(fam[1], 13, 5);
+ hh_ppu_data_t *fam = &g_hh_ppusim_vram[HH_PPU_VRAM_FAM_OFFSET + fam_offset];
+ unsigned sprite_y = HH_RESIZE(fam[0], 15, 13) | HH_RESIZE(fam[1], 4, 0) << 3;
+ unsigned sprite_x = HH_RESIZE(fam[1], 13, 5);
if (x < sprite_x) continue;
if (x >= sprite_x + HH_PPU_SPRITE_WIDTH) continue;
if (y < sprite_y) continue;
if (y >= sprite_y + HH_PPU_SPRITE_HEIGHT) continue;
- unsigned loc_x = x - sprite_x;
- unsigned loc_y = y - sprite_y;
+ unsigned loc_x = x - sprite_x;
+ unsigned loc_y = y - sprite_y;
uint16_t tile_pixel_idx = hh_ppusim_apply_transform(loc_x, loc_y, HH_RESIZE(fam[1], 15, 15), HH_RESIZE(fam[1], 14, 14));
- uint16_t tile_idx = HH_RESIZE(fam[0], 9, 0);
- hh_ppu_addr_t ttm_addr = tile_idx * HH_PPU_VRAM_TMM_SPRITE_SIZE + tile_pixel_idx / 5;
- uint8_t word_bit_addr = (tile_pixel_idx % 5) * 3;
- hh_ppu_data_t tmm = g_hh_ppusim_vram[HH_PPU_VRAM_TMM_OFFSET + ttm_addr];
- unsigned cidx_col = HH_RESIZE(tmm, word_bit_addr+2, word_bit_addr);
+ uint16_t tile_idx = HH_RESIZE(fam[0], 9, 0);
+ hh_ppu_addr_t ttm_addr = tile_idx * HH_PPU_VRAM_TMM_SPRITE_SIZE + tile_pixel_idx / 5;
+ uint8_t word_bit_addr = (tile_pixel_idx % 5) * 3;
+ hh_ppu_data_t tmm = g_hh_ppusim_vram[HH_PPU_VRAM_TMM_OFFSET + ttm_addr];
+ unsigned cidx_col = HH_RESIZE(tmm, word_bit_addr + 2, word_bit_addr);
if (cidx_col == 0) continue;
unsigned cidx_pal = HH_RESIZE(fam[0], 12, 10);
- cidx = (cidx_col << 0) | (cidx_pal << 3);
+ cidx = (cidx_col << 0) | (cidx_pal << 3);
break;
}
return cidx;
}
-void hh_ppusim_pixel(uint8_t* s, unsigned x, unsigned y) {
- uint8_t bg_cidx = hh_ppusim_bg_pixel(x, y);
- uint8_t fg_cidx = hh_ppusim_fg_pixel(x, y);
- uint8_t cidx = (fg_cidx & HH_MASK(3)) == 0 ? bg_cidx : fg_cidx;
- hh_ppu_data_t pal_rgb = g_hh_ppusim_vram[HH_PPU_VRAM_PAL_OFFSET + cidx];
- hh_ppu_rgb_color_t rgb = {
- HH_RESIZE(pal_rgb, 11, 8),
- HH_RESIZE(pal_rgb, 7, 4),
- HH_RESIZE(pal_rgb, 3, 0)
- };
+void hh_ppusim_pixel(uint8_t *s, unsigned x, unsigned y) {
+ uint8_t bg_cidx = hh_ppusim_bg_pixel(x, y);
+ uint8_t fg_cidx = hh_ppusim_fg_pixel(x, y);
+ uint8_t cidx = (fg_cidx & HH_MASK(3)) == 0 ? bg_cidx : fg_cidx;
+ hh_ppu_data_t pal_rgb = g_hh_ppusim_vram[HH_PPU_VRAM_PAL_OFFSET + cidx];
+ hh_ppu_rgb_color_t rgb = {HH_RESIZE(pal_rgb, 11, 8), HH_RESIZE(pal_rgb, 7, 4), HH_RESIZE(pal_rgb, 3, 0)};
s[0] = rgb[0] << 4;
s[1] = rgb[1] << 4;
s[2] = rgb[2] << 4;
}
-
diff --git a/src/ppusim/sim.c b/src/ppusim/sim.c
index 2816b31..a5fec45 100644
--- a/src/ppusim/sim.c
+++ b/src/ppusim/sim.c
@@ -1,26 +1,56 @@
-#include <stdlib.h>
-#include <stdbool.h>
#include <SDL2/SDL.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
#include "main.h"
#include "ppu/ppu.h"
+#include "ppu/consts.h"
+#include "ppu/internals.h"
#include "ppusim/mem.h"
#include "ppusim/sim.h"
#include "ppusim/work.h"
-SDL_Window *g_hh_window = NULL;
+SDL_Window *g_hh_window = NULL;
SDL_Renderer *g_hh_renderer = NULL;
void hh_ppu_init() {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
- g_hh_window = SDL_CreateWindow("ppusim", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, HH_PPU_SCREEN_WIDTH * HH_PPUSIM_UPSCALE_FACTOR, HH_PPU_SCREEN_HEIGHT * HH_PPUSIM_UPSCALE_FACTOR, SDL_WINDOW_SHOWN);
+ g_hh_window = SDL_CreateWindow("ppusim", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, HH_PPU_SCREEN_WIDTH * HH_PPUSIM_UPSCALE_FACTOR,
+ HH_PPU_SCREEN_HEIGHT * HH_PPUSIM_UPSCALE_FACTOR, SDL_WINDOW_SHOWN);
g_hh_renderer = SDL_CreateRenderer(g_hh_window, -1, SDL_RENDERER_ACCELERATED);
g_hh_ppusim_core_count = SDL_GetCPUCount();
- g_hh_ppusim_threads = malloc(sizeof(pthread_t) * g_hh_ppusim_core_count);
+ g_hh_ppusim_threads = malloc(sizeof(pthread_t) * g_hh_ppusim_core_count);
g_hh_ppusim_vram = malloc(sizeof(hh_ppu_data_t) * 0xffff);
memset(g_hh_ppusim_vram, 0x0000, 0xffff);
+ hh_ppu_load_tilemap();
+}
+
+void hh_ppu_load_tilemap() {
+ char* filename = "../test/bin/tiles.bin";
+ FILE* fp = fopen(filename,"rb");
+ if (!fp){
+ fprintf(stderr,"Error: Failed to load tiles.");
+ return;//error
+ }
+ int sprite_size = (HH_PPU_SPRITE_WIDTH * HH_PPU_SPRITE_HEIGHT);
+ fseek(fp, 0, SEEK_END);//goto EOF
+ int _size = ftell(fp)/sprite_size;
+ fseek(fp, 0, 0);//goto start of file
+
+ for (int i = 0; i < _size; i++) {
+ uint8_t data[sprite_size];
+
+ fread(data,sizeof(uint8_t),sprite_size,fp);
+
+ hh_s_ppu_vram_data sprite = hh_ppu_2nat_sprite(data);
+ sprite.offset = i*HH_PPU_VRAM_TMM_SPRITE_SIZE;
+ hh_ppu_vram_write(sprite);
+ free(sprite.data);
+ }
+ fclose(fp);
}
void hh_ppu_deinit() {
@@ -36,8 +66,9 @@ void hh_loop() {
SDL_Event e;
while (g_hh_run) {
uint32_t start = SDL_GetTicks();
- while (SDL_PollEvent(&e)) if (e.type == SDL_QUIT) exit(0);
-
+ while (SDL_PollEvent(&e))
+ if (e.type == SDL_QUIT) exit(0);
+
hh_ppu_vblank_interrupt();
SDL_RenderClear(g_hh_renderer);
diff --git a/src/ppusim/sim.h b/src/ppusim/sim.h
index 73f4b23..4d1d718 100644
--- a/src/ppusim/sim.h
+++ b/src/ppusim/sim.h
@@ -4,3 +4,6 @@
#define HH_PPUSIM_UPSCALE_FACTOR 3
/** @brief max framerate for PPUSIM */
#define HH_PPUSIM_FRAMERATE 60
+
+/** @brief pump tilemap from rom to ppu ram */
+void hh_ppu_load_tilemap(); //ppu sim?
diff --git a/src/ppusim/work.c b/src/ppusim/work.c
index fcb80ca..96d15aa 100644
--- a/src/ppusim/work.c
+++ b/src/ppusim/work.c
@@ -2,39 +2,41 @@
#include <pthread.h>
#include <stdio.h>
-#include "ppusim/work.h"
-#include "ppusim/sim.h"
#include "ppu/consts.h"
#include "ppusim/pixel.h"
+#include "ppusim/sim.h"
+#include "ppusim/work.h"
-pthread_t* g_hh_ppusim_threads;
+pthread_t *g_hh_ppusim_threads;
unsigned g_hh_ppusim_core_count;
hh_s_ppusim_screen g_hh_ppusim_screen;
-void* hh_ppusim_draw_thread(void* arg) {
- unsigned core = (unsigned long) arg;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
+#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
+
+void *hh_ppusim_draw_thread(void *arg) {
+ unsigned core = (unsigned long)arg;
for (unsigned y = core; y < HH_PPU_SCREEN_HEIGHT; y += g_hh_ppusim_core_count)
- for (unsigned x = 0; x < HH_PPU_SCREEN_WIDTH; x++)
- hh_ppusim_pixel(g_hh_ppusim_screen[y][x], x, y);
+ for (unsigned x = 0; x < HH_PPU_SCREEN_WIDTH; x++) hh_ppusim_pixel(g_hh_ppusim_screen[y][x], x, y);
return NULL;
}
-void hh_ppusim_draw_frame(SDL_Renderer* renderer) {
- for (unsigned core = 0; core < g_hh_ppusim_core_count; core++)
- pthread_create(&g_hh_ppusim_threads[core], NULL, hh_ppusim_draw_thread, (void*)(unsigned long)core);
- for (unsigned core = 0; core < g_hh_ppusim_core_count; core++)
- pthread_join(g_hh_ppusim_threads[core], NULL);
-
+void hh_ppusim_draw_frame(SDL_Renderer *renderer) {
+ for (unsigned core = 0; core < g_hh_ppusim_core_count; core++) pthread_create(&g_hh_ppusim_threads[core], NULL, hh_ppusim_draw_thread, (void *)(unsigned long)core);
+ for (unsigned core = 0; core < g_hh_ppusim_core_count; core++) pthread_join(g_hh_ppusim_threads[core], NULL);
+
for (unsigned x = 0; x < HH_PPU_SCREEN_WIDTH; x++) {
for (unsigned y = 0; y < HH_PPU_SCREEN_HEIGHT; y++) {
SDL_SetRenderDrawColor(renderer, g_hh_ppusim_screen[y][x][0], g_hh_ppusim_screen[y][x][1], g_hh_ppusim_screen[y][x][2], 255);
- SDL_RenderFillRect(renderer, &(SDL_Rect) {
- .x = x * HH_PPUSIM_UPSCALE_FACTOR,
- .y = y * HH_PPUSIM_UPSCALE_FACTOR,
- .w = HH_PPUSIM_UPSCALE_FACTOR,
- .h = HH_PPUSIM_UPSCALE_FACTOR,
- });
+ SDL_RenderFillRect(renderer, &(SDL_Rect){
+ .x = x * HH_PPUSIM_UPSCALE_FACTOR,
+ .y = y * HH_PPUSIM_UPSCALE_FACTOR,
+ .w = HH_PPUSIM_UPSCALE_FACTOR,
+ .h = HH_PPUSIM_UPSCALE_FACTOR,
+ });
}
}
}
+#pragma GCC diagnostic pop
diff --git a/src/ppusim/work.h b/src/ppusim/work.h
index 6f72357..3a165ff 100644
--- a/src/ppusim/work.h
+++ b/src/ppusim/work.h
@@ -1,6 +1,7 @@
#pragma once
#include <SDL2/SDL.h>
+#include <pthread.h>
#include "ppu/consts.h"
diff --git a/src/stm32.mk b/src/stm32.mk
index e41bcf9..3b5ccb9 100644
--- a/src/stm32.mk
+++ b/src/stm32.mk
@@ -17,6 +17,9 @@ SHARED_FLAGS += -I./stm32
ifeq ($(HOST),GNU/Linux)
SHARED_FLAGS += -I/usr/arm-none-eabi/include/
endif
+ifeq ($(HOST),Msys)
+SHARED_FLAGS += -I/mingw64/arm-none-eabi/include/
+endif
SHARED_FLAGS += -ffunction-sections
SHARED_FLAGS += -fdata-sections
SHARED_FLAGS += -Wl,--gc-sections
@@ -40,22 +43,25 @@ STM_SRCS += lib/FreeRTOS-Kernel/croutine.c \
lib/FreeRTOS-Kernel/timers.c \
lib/FreeRTOS-Kernel/portable/GCC/ARM_CM0/port.c \
lib/FreeRTOS-Kernel/portable/MemMang/heap_4.c
-STM_SRCS += lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_rcc.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_rcc_ex.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_i2c.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_i2c_ex.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_gpio.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_dma.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_cortex.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_pwr.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_pwr_ex.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_flash.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_flash_ex.c \
+STM_SRCS += lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal.c \
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_spi.c \
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_spi_ex.c \
lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_tim.c \
lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_tim_ex.c \
lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_uart.c \
- lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_uart_ex.c
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_uart_ex.c \
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_cortex.c \
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_dma.c \
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_flash.c \
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_flash_ex.c \
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_gpio.c \
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_pwr.c \
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_pwr_ex.c \
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_rcc.c \
+ lib/STM32-base-STM32Cube/HAL/STM32F0xx/src/stm32f0xx_hal_rcc_ex.c
STM_SRCS += stm32/idle_task_static_memory.c \
- stm32/main.c
+ stm32/main.c \
+ stm32/setup.c \
+ ppu/stm.c \
+ stm32/input.c
diff --git a/src/stm32/input.c b/src/stm32/input.c
new file mode 100644
index 0000000..e2d07cb
--- /dev/null
+++ b/src/stm32/input.c
@@ -0,0 +1,13 @@
+#include <stm32f0xx_hal_gpio.h>
+
+#include "input.h"
+
+hh_s_gamepad g_hh_controller_p1 = { 0 };
+hh_s_gamepad g_hh_controller_p2 = { 0 };
+
+void hh_input_read() {
+ g_hh_controller_p1.dpad_left = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4);
+ g_hh_controller_p1.dpad_right = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5);
+ g_hh_controller_p1.dpad_down = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6);
+ g_hh_controller_p1.dpad_up = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8);
+}
diff --git a/src/stm32/main.c b/src/stm32/main.c
index 735b378..d381d35 100644
--- a/src/stm32/main.c
+++ b/src/stm32/main.c
@@ -1,4 +1,7 @@
#include "main.h"
+#include "ppu/ppu.h"
+
+void hh_ppu_load_tilemap() {}
void hh_loop() {
while(g_hh_run);
diff --git a/src/stm32/setup.c b/src/stm32/setup.c
new file mode 100644
index 0000000..2c3552b
--- /dev/null
+++ b/src/stm32/setup.c
@@ -0,0 +1,197 @@
+#include <stm32f0xx_hal.h>
+#include <stm32f0xx_hal_spi.h>
+#include <stm32f0xx_hal_uart.h>
+#include <stm32f0xx_hal_gpio.h>
+#include <FreeRTOS.h>
+#include <task.h>
+
+#include "main.h"
+#include "setup.h"
+#include "ppu/ppu.h"
+
+UART_HandleTypeDef huart2 = {
+ .Instance = USART2,
+ .Init.BaudRate = 115200,
+ .Init.WordLength = UART_WORDLENGTH_8B,
+ .Init.StopBits = UART_STOPBITS_1,
+ .Init.Parity = UART_PARITY_NONE,
+ .Init.Mode = UART_MODE_TX_RX,
+ .Init.HwFlowCtl = UART_HWCONTROL_NONE,
+ .Init.OverSampling = UART_OVERSAMPLING_16,
+ .Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE,
+ .AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT,
+};
+
+GPIO_InitTypeDef spi_gpio = {
+ .Pin = HH_IO_SPI_PINS,
+ .Mode = GPIO_MODE_AF_PP,
+ .Pull = GPIO_NOPULL,
+ .Speed = GPIO_SPEED_FREQ_HIGH,
+ .Alternate = GPIO_AF0_SPI1,
+};
+
+SPI_HandleTypeDef hspi1 = {
+ .Instance = SPI1,
+ .Init.Mode = SPI_MODE_MASTER,
+ .Init.Direction = SPI_DIRECTION_1LINE,
+ .Init.DataSize = SPI_DATASIZE_8BIT,
+ .Init.CLKPolarity = SPI_POLARITY_LOW,
+ .Init.CLKPhase = SPI_PHASE_1EDGE,
+ .Init.NSS = SPI_NSS_SOFT,
+ .Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16,
+ .Init.FirstBit = SPI_FIRSTBIT_MSB,
+ .Init.TIMode = SPI_TIMODE_DISABLE,
+ .Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE,
+ .Init.CRCPolynomial = 7,
+ .Init.CRCLength = SPI_CRC_LENGTH_DATASIZE,
+ .Init.NSSPMode = SPI_NSS_PULSE_DISABLE,
+};
+
+TIM_HandleTypeDef htim3 = {
+ .Instance = TIM3,
+ .Init.Prescaler = 7999,
+ .Init.CounterMode = TIM_COUNTERMODE_UP,
+ .Init.Period = 65535,
+ .Init.ClockDivision = TIM_CLOCKDIVISION_DIV1,
+ .Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE,
+};
+
+static void hh_io_spi_setup();
+static void hh_io_tim_setup();
+static void hh_io_usart2_setup();
+static void hh_io_gpio_setup();
+static void hh_io_clock_setup();
+static void hh_io_setup_error_handler();
+
+void hh_setup() {
+ HAL_Init();
+
+ hh_io_clock_setup();
+ hh_io_usart2_setup();
+ hh_io_gpio_setup();
+ hh_io_spi_setup();
+ hh_io_tim_setup();
+
+ hh_ppu_init();
+}
+
+void hh_exit() {
+ hh_ppu_deinit();
+
+ HAL_DeInit();
+}
+
+void hh_io_clock_setup() {
+ if (HAL_OK != HAL_RCC_OscConfig(&(RCC_OscInitTypeDef){
+ .OscillatorType = RCC_OSCILLATORTYPE_HSI,
+ .HSIState = RCC_HSI_ON,
+ .HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT,
+ .PLL.PLLState = RCC_PLL_ON,
+ })) return hh_io_setup_error_handler();
+
+ // cpu, ahb & apb clocks
+ if (HAL_OK != HAL_RCC_ClockConfig(&(RCC_ClkInitTypeDef){
+ .ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1,
+ .SYSCLKSource = RCC_SYSCLKSOURCE_HSI,
+ .AHBCLKDivider = RCC_SYSCLK_DIV1,
+ .APB1CLKDivider = RCC_HCLK_DIV1,
+ }, FLASH_LATENCY_1)) return hh_io_setup_error_handler();
+
+ // usart2 clock (usb serial)
+ if (HAL_RCCEx_PeriphCLKConfig(&(RCC_PeriphCLKInitTypeDef){
+ .PeriphClockSelection = RCC_PERIPHCLK_USART2,
+ .Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1,
+ .I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI,
+ }) != HAL_OK) return hh_io_setup_error_handler();
+}
+
+void hh_io_spi_setup() {
+ if (HAL_SPI_Init(&hspi1) != HAL_OK)
+ return hh_io_setup_error_handler();
+}
+
+void hh_io_usart2_setup() {
+ if (HAL_UART_Init(&huart2) != HAL_OK)
+ return hh_io_setup_error_handler();
+}
+
+void hh_io_tim_setup() {
+ if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
+ return hh_io_setup_error_handler();
+
+ if (HAL_TIM_ConfigClockSource(&htim3, &(TIM_ClockConfigTypeDef) {
+ .ClockSource = TIM_CLOCKSOURCE_INTERNAL
+ }) != HAL_OK) return hh_io_setup_error_handler();
+
+ if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &(TIM_MasterConfigTypeDef) {
+ .MasterOutputTrigger = TIM_TRGO_RESET,
+ .MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE,
+ }) != HAL_OK) return hh_io_setup_error_handler();
+}
+
+void hh_io_gpio_setup() {
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);
+ HAL_GPIO_Init(GPIOA, &(GPIO_InitTypeDef) {
+ .Pin = GPIO_PIN_9,
+ .Mode = GPIO_MODE_OUTPUT_PP,
+ .Pull = GPIO_NOPULL,
+ .Speed = GPIO_SPEED_FREQ_LOW,
+ });
+ HAL_GPIO_Init(GPIOA, &(GPIO_InitTypeDef) {
+ .Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_8,
+ .Mode = GPIO_MODE_INPUT,
+ .Pull = GPIO_PULLDOWN,
+ });
+}
+
+void HAL_MspInit() {
+ __HAL_RCC_SYSCFG_CLK_ENABLE();
+ __HAL_RCC_PWR_CLK_ENABLE();
+}
+
+void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) {
+ if(hspi->Instance != SPI1) return;
+
+ __HAL_RCC_SPI1_CLK_ENABLE();
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+
+ HAL_GPIO_Init(HH_IO_SPI_PORT, &spi_gpio);
+}
+
+void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) {
+ if(hspi->Instance != SPI1) return;
+
+ __HAL_RCC_SPI1_CLK_DISABLE();
+
+ HAL_GPIO_DeInit(HH_IO_SPI_PORT, HH_IO_SPI_PINS);
+}
+
+void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) {
+ if(htim_base->Instance != TIM3) return;
+
+ __HAL_RCC_TIM3_CLK_ENABLE();
+}
+
+void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) {
+ if(htim_base->Instance != TIM3) return;
+
+ __HAL_RCC_TIM3_CLK_DISABLE();
+}
+
+void SysTick_Handler() {
+ HAL_IncTick();
+ if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
+ xPortSysTickHandler();
+}
+
+void HardFault_Handler() {
+ for(;;);
+}
+
+void hh_io_setup_error_handler() {
+ __disable_irq();
+ while (1);
+}
diff --git a/src/stm32/setup.h b/src/stm32/setup.h
new file mode 100644
index 0000000..66d5ff3
--- /dev/null
+++ b/src/stm32/setup.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <stm32f0xx_hal_spi.h>
+#include <stm32f0xx_hal_uart.h>
+#include <stm32f0xx_hal_tim.h>
+#include <stm32f0xx_hal_gpio.h>
+
+#define HH_IO_SPI_PINS (GPIO_PIN_5 | GPIO_PIN_7)
+#define HH_IO_SPI_PORT GPIOA
+
+extern UART_HandleTypeDef huart2; // NOLINT
+extern GPIO_InitTypeDef spi_gpio; // NOLINT
+extern SPI_HandleTypeDef hspi1; // NOLINT
+extern TIM_HandleTypeDef htim3; // NOLINT
+
+// required HAL setup functions
+void HAL_MspInit(); // NOLINT
+void HAL_UART_MspInit(UART_HandleTypeDef *huart); // NOLINT
+void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi); // NOLINT
+void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi); // NOLINT
+void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base); // NOLINT
+void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base); // NOLINT
+void HardFault_Handler(); // NOLINT
+void SysTick_Handler(); // NOLINT
diff --git a/src/stm32/stm32f0xx_hal_conf.h b/src/stm32/stm32f0xx_hal_conf.h
index fc27221..84a3b74 100644
--- a/src/stm32/stm32f0xx_hal_conf.h
+++ b/src/stm32/stm32f0xx_hal_conf.h
@@ -19,16 +19,18 @@
#define DATA_CACHE_ENABLE 0U
#define USE_SPI_CRC 0U
-#define HAL_RCC_MODULE_ENABLED
#define HAL_MODULE_ENABLED
-#define HAL_I2C_MODULE_ENABLED
-#define HAL_GPIO_MODULE_ENABLED
-#define HAL_DMA_MODULE_ENABLED
-#define HAL_CORTEX_MODULE_ENABLED
-#define HAL_PWR_MODULE_ENABLED
-#define HAL_FLASH_MODULE_ENABLED
+#define HAL_SPI_MODULE_ENABLED
#define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+// #define HAL_I2C_MODULE_ENABLED
#ifdef HAL_RCC_MODULE_ENABLED
#include <stm32f0xx_hal_rcc.h>