diff --git a/.gitignore b/.gitignore index e774f06..79f7528 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ log/ assets/whale/*.png assets/enemy/*.png +assets/background/*.png +assets/text/*.png +assets/weapons/*.png assets/out.png __debug_bin diff --git a/.vscode/launch.json b/.vscode/launch.json index ed251c6..1dedbb6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "program": "mGBA.exe", "args": [ - "${workspaceFolder}\\bin\\ecs.gba" + "${workspaceFolder}\\bin\\walk-good-maybe.gba" ] }, { diff --git a/.vscode/settings.json b/.vscode/settings.json index c65e95f..bb2dfaf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,7 @@ }, "C_Cpp.errorSquiggles": "Disabled", "cSpell.words": [ + "allc", "ents" ] } \ No newline at end of file diff --git a/Makefile b/Makefile index cb77c41..32fe37c 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ LIBTONC := $(DEVKITPRO)/tonclib $(DEVKITPRO)/libtonc # DATA is a list of directories containing data files # INCLUDES is a list of directories containing header files #--------------------------------------------------------------------------------- -TARGET := bin/ecs +TARGET := bin/walk-good-maybe MUSIC_TARGET := bin/music BUILD := build ASSETS := assets assets/title_screen assets/whale @@ -136,6 +136,7 @@ assets: $(shell find assets/ -type f -name '.psd') clean: @echo clean ... @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba $(MUSIC_OUPUT).gba + @rm -rf "source/assets" #--------------------------------------------------------------------------------- else diff --git a/assets/background/background.png b/assets/background/background.png deleted file mode 100644 index efac743..0000000 Binary files a/assets/background/background.png and /dev/null differ diff --git a/assets/background/backgroundBuildingA.png b/assets/background/backgroundBuildingA.png deleted file mode 100644 index 4b39e04..0000000 Binary files a/assets/background/backgroundBuildingA.png and /dev/null differ diff --git a/assets/background/backgroundCity.png b/assets/background/backgroundCity.png deleted file mode 100644 index 130c45f..0000000 Binary files a/assets/background/backgroundCity.png and /dev/null differ diff --git a/assets/background/backgroundSky.png b/assets/background/backgroundSky.png deleted file mode 100644 index e0116f6..0000000 Binary files a/assets/background/backgroundSky.png and /dev/null differ diff --git a/assets/background/background_night.png b/assets/background/background_night.png deleted file mode 100644 index fc89954..0000000 Binary files a/assets/background/background_night.png and /dev/null differ diff --git a/assets/background/background_size_test.png b/assets/background/background_size_test.png deleted file mode 100644 index 742e6f6..0000000 Binary files a/assets/background/background_size_test.png and /dev/null differ diff --git a/assets/background/build_tile_set.png b/assets/background/build_tile_set.png deleted file mode 100644 index d02c063..0000000 Binary files a/assets/background/build_tile_set.png and /dev/null differ diff --git a/assets/background/buildingtileset.png b/assets/background/buildingtileset.png deleted file mode 100644 index f866f24..0000000 Binary files a/assets/background/buildingtileset.png and /dev/null differ diff --git a/assets/background/cloud.png b/assets/background/cloud.png deleted file mode 100644 index 920aa3c..0000000 Binary files a/assets/background/cloud.png and /dev/null differ diff --git a/assets/background/fog.png b/assets/background/fog.png deleted file mode 100644 index 87df184..0000000 Binary files a/assets/background/fog.png and /dev/null differ diff --git a/assets/text/numbersfont.png b/assets/text/numbersfont.png deleted file mode 100644 index 2a9f835..0000000 Binary files a/assets/text/numbersfont.png and /dev/null differ diff --git a/assets/weapons/gun_0_bullet.png b/assets/weapons/gun_0_bullet.png deleted file mode 100644 index 93ebb6b..0000000 Binary files a/assets/weapons/gun_0_bullet.png and /dev/null differ diff --git a/make_assets.sh b/make_assets.sh index cfea5cb..3ee6c9c 100644 --- a/make_assets.sh +++ b/make_assets.sh @@ -91,7 +91,6 @@ BG_OPTIONS="$BG_OPTIONS -m" # Export map BG_OPTIONS="$BG_OPTIONS -mR8" # Create Map BG_OPTIONS="$BG_OPTIONS -mLs" # Map 16 Bit BG_OPTIONS="$BG_OPTIONS -pS" # Share pallet -BG_OPTIONS="$BG_OPTIONS -gS" # Share tiles BG_OPTIONS="$BG_OPTIONS -O mainGameShared" # Shared pallet name echo "Creating background tiles for main game / pal / map" @@ -99,7 +98,7 @@ grit \ $ASSETS/backgrounds_out.png \ $ASSETS/background/fog.png \ $ASSETS/background/backgroundCity.png \ - $ASSETS/background/build_tile_set.png $BG_OPTIONS + $ASSETS/background/buildingtileset.png $BG_OPTIONS BG_OPTIONS="" diff --git a/music/pd_beach_song.xm b/music/pd_beach_song.xm new file mode 100644 index 0000000..cb1a728 Binary files /dev/null and b/music/pd_beach_song.xm differ diff --git a/source/enemy.c b/source/enemy.c index b568854..18b86bb 100644 --- a/source/enemy.c +++ b/source/enemy.c @@ -14,67 +14,76 @@ #include "assets/toast_enemy_idle_05.h" const uint *enemy_toast_idle_cycle[] = { - toast_enemy_idle_01Tiles, toast_enemy_idle_01Tiles, toast_enemy_idle_02Tiles, - toast_enemy_idle_03Tiles, toast_enemy_idle_04Tiles, toast_enemy_idle_05Tiles -}; + toast_enemy_idle_01Tiles, toast_enemy_idle_01Tiles, toast_enemy_idle_02Tiles, + toast_enemy_idle_03Tiles, toast_enemy_idle_04Tiles, toast_enemy_idle_05Tiles}; -static int _enemy_top_idx = 0; static int _enemy_tile_idx; +static int _enemy_anime_cycle = 0; -void load_enemy_toast() { - _enemy_tile_idx = allocate_tile_idx(2); +void load_enemy_toast() +{ + _enemy_tile_idx = allocate_obj_tile_idx(2); dma3_cpy(&tile_mem[4][_enemy_tile_idx], toast_enemy_idle_01Tiles, toast_enemy_idle_01TilesLen); } - -void create_toast_enemy(ent_t *ent, FIXED x, FIXED y) { +void create_toast_enemy(ent_t *ent, int att_idx, FIXED x, FIXED y) +{ ent->ent_type = TYPE_ENEMY; ent->x = x; + ent->w = 8; ent->y = y; + ent->h = 16; ent->vx = 0; ent->vy = 0; - ent->w = 8; - ent->h = 16; - ent->att_idx = allocate_att(1); + ent->att_idx = att_idx; - obj_set_attr(&_obj_buffer[ent->att_idx], - ATTR0_TALL | ATTR0_8BPP, ATTR1_SIZE_8x16, - ATTR2_PALBANK(0) | ATTR2_PRIO(1) | ATTR2_ID(_enemy_tile_idx) - ); + obj_set_attr( + get_ent_att(ent), + ATTR0_TALL | ATTR0_8BPP, ATTR1_SIZE_16x8, + ATTR2_PRIO(1) | ATTR2_ID(_enemy_tile_idx)); - obj_set_pos(&_obj_buffer[ent->att_idx], fx2int(ent->x), fx2int(ent->y)); + obj_set_pos(get_ent_att(ent), fx2int(ent->x), fx2int(ent->y)); } -void destroy_toast_enemy(ent_t *ent) { - ent->att_idx = 0; +void step_enemy_global() +{ + if (frame_count() % 2) + { + step_anime( + enemy_toast_idle_cycle, toast_enemy_idle_01TilesLen, ENEMY_TOAST_IDLE_CYCLE, + &_enemy_anime_cycle, _enemy_tile_idx); + } } -void update_enemy(ent_t *ent) { - if(ent->x + ent->w < 0) { +void update_enemy(ent_t *ent) +{ + if (ent->x + ent->w < 0 || ent->ent_cols & (TYPE_BULLET)) + { free_att(1, ent->att_idx); - destroy_toast_enemy(ent); + ent->ent_type = TYPE_NONE; return; } - step_anime( - enemy_toast_idle_cycle, toast_enemy_idle_01TilesLen, ENEMY_TOAST_IDLE_CYCLE, - &ent->anime_cycle, _enemy_tile_idx - ); - bool hit_y = ent_move_y(ent, ent->vy); // Applies gravity - if(!hit_y) { - if(ent->vy < TERMINAL_VY) { + if (!hit_y) + { + if (ent->vy < TERMINAL_VY) + { ent->vy += GRAVITY; } ent->vx = 0; - } else { - if(ent->vx == 0) { + } + else + { + if (ent->vx == 0) + { ent->vx = float2fx(0.75); } int hit_x = ent_level_collision_at(ent, ent->vx, ent->vy); - if(!hit_x) { + if (!hit_x) + { ent->vx = -ent->vx; } } diff --git a/source/enemy.h b/source/enemy.h index 00a82ca..c332fa5 100644 --- a/source/enemy.h +++ b/source/enemy.h @@ -8,8 +8,10 @@ extern const unsigned int *enemy_toast_idle_cycle[]; void load_enemy_toast(); -void create_toast_enemy(ent_t *ent, FIXED x, FIXED y); +void create_toast_enemy(ent_t *ent, int att_idx, FIXED x, FIXED y); void update_enemy(ent_t *ent); +void step_enemy_global(); + #endif \ No newline at end of file diff --git a/source/ent.c b/source/ent.c index 7736701..bc71126 100644 --- a/source/ent.c +++ b/source/ent.c @@ -17,30 +17,40 @@ static int _free_obj; static int _allocated_objs[128]; -void init_obj_atts() { +void init_obj_atts() +{ oam_init(_obj_buffer, 128); - for(int i = 0; i < 128; i++) { + for (int i = 0; i < 128; i++) + { _allocated_objs[i] = 0; } + _allocated_objs[0] = 1; } -int allocate_att(int count) { - for(int i = 0; i < 128;) { +int allocate_att(int count) +{ + for (int i = 0; i < 128;) + { bool found = true; - - for(int j = i; j - i < count && j < 128; j++) { - if(_allocated_objs[j]) { + + for (int j = i; j - i < count && j < 128; j++) + { + if (_allocated_objs[j]) + { found = false; break; } } - if(found) { - for(int j = i; j - i < count; j++) { + if (found) + { + for (int j = i; j - i < count; j++) + { _allocated_objs[j] = 1; } - if(i > _att_count) { + if (i > _att_count) + { _att_count = i + count; } return i; @@ -48,17 +58,20 @@ int allocate_att(int count) { i += count; } - return 0; + return -1; } -void free_att(int count, int idx) { +void free_att(int count, int idx) +{ obj_set_attr(&_obj_buffer[idx], ATTR0_HIDE, 0, 0); - if(idx >= _att_count) { + if (idx >= _att_count) + { _att_count -= count; } - for(int i = idx; i < idx + count; i++) { + for (int i = idx; i < idx + count; i++) + { _allocated_objs[i] = 0; } @@ -66,59 +79,72 @@ void free_att(int count, int idx) { } //THIS SHOULD ONLY BE CALLED ONCE A LOOP -int att_count() { +int att_count() +{ int result = _free_obj + (_att_count + 1); _free_obj = 0; return result; } - -FIXED translate_x(ent_t *e) { +FIXED translate_x(ent_t *e) +{ return e->x + _bg_pos_x; } -FIXED translate_y(ent_t *e) { +FIXED translate_y(ent_t *e) +{ return e->y; } -static inline FIXED level_to_screen(int l) { +static inline FIXED level_to_screen(int l) +{ return int2fx(l * TILE_WIDTH + l % TILE_WIDTH); } // STOLEN from https://github.com/exelotl/goodboy-advance -bool did_hit_x(ent_t *e, FIXED dx) { +bool did_hit_x(ent_t *e, FIXED dx) +{ int flags = ent_level_collision_at(e, dx, 0); return flags & (LEVEL_COL_GROUND); } // STOLEN from https://github.com/exelotl/goodboy-advance -bool ent_move_x(ent_t *e, FIXED dx) { - if(did_hit_x(e, dx)) { +bool ent_move_x(ent_t *e, FIXED dx) +{ + if (did_hit_x(e, dx)) + { int sign = dx >= 0 ? 1 : -1; - while(fx2int(dx) != 0 && !did_hit_x(e, sign)) { + while (fx2int(dx) != 0 && !did_hit_x(e, sign)) + { e->x += sign; dx -= sign; } - + //NOT STOLEN MY OWN SHIT CODE //Failed to push out - if(did_hit_x(e, 0)) { + if (did_hit_x(e, 0)) + { int start = (translate_x(e) / FIX_SCALE) / TILE_WIDTH; int y = (translate_y(e) / FIX_SCALE) / TILE_WIDTH; - //Failed to push out but will only check all tiles - for(int i = 0; i < 32; i++) { + //Failed to push out but will only check all tiles + for (int i = 0; i < 32; i++) + { //Left - if(!tile_to_collision(at_level(level_wrap_x(start - i), y))) { - while(did_hit_x(e, 0)) { + if (!tile_to_collision(at_level(level_wrap_x(start - i), y))) + { + while (did_hit_x(e, 0)) + { e->x--; } break; } //Right - if(!tile_to_collision(at_level(level_wrap_x(start + i), y))) { - while(did_hit_x(e, 0)) { + if (!tile_to_collision(at_level(level_wrap_x(start + i), y))) + { + while (did_hit_x(e, 0)) + { e->x++; } break; @@ -133,16 +159,20 @@ bool ent_move_x(ent_t *e, FIXED dx) { } // STOLEN from https://github.com/exelotl/goodboy-advance -bool did_hit_y(ent_t *e, FIXED dy) { +bool did_hit_y(ent_t *e, FIXED dy) +{ int flags = ent_level_collision_at(e, 0, dy); return flags & (LEVEL_COL_GROUND); } // STOLEN from https://github.com/exelotl/goodboy-advance -bool ent_move_y(ent_t *e, FIXED dy) { - if(did_hit_y(e, dy)) { +bool ent_move_y(ent_t *e, FIXED dy) +{ + if (did_hit_y(e, dy)) + { int sign = dy >= 0 ? 1 : -1; - while(fx2int(dy) != 0 && !did_hit_y(e, sign)) { + while (fx2int(dy) != 0 && !did_hit_y(e, sign)) + { e->y += sign; dy -= sign; } @@ -153,10 +183,12 @@ bool ent_move_y(ent_t *e, FIXED dy) { return false; } -bool apply_gravity(ent_t *e) { +bool apply_gravity(ent_t *e) +{ int flags = ent_level_collision_at(e, 0, GRAVITY); - - if(flags & (LEVEL_COL_GROUND)) { + + if (flags & (LEVEL_COL_GROUND)) + { _player.vy = 0; return true; } @@ -165,8 +197,34 @@ bool apply_gravity(ent_t *e) { return false; } -void update_ents() { - for(int i = 0; i < ENT_COUNT; i++) { +void update_ents() +{ + for (int i = 0; i < ENT_COUNT; i++) + { + if (_ents[i].ent_type == TYPE_NONE) + { + continue; + } + + _ents[i].ent_cols = TYPE_NONE; + + for (int j = 0; j < ENT_COUNT; j++) + { + if ( + i != j && + _ents[j].ent_type != TYPE_NONE && + fx2int(_ents[i].x) < fx2int(_ents[j].x) + _ents[j].w && + fx2int(_ents[i].x) + _ents[i].w > fx2int(_ents[j].x) && + fx2int(_ents[i].y) < fx2int(_ents[j].y) + _ents[j].h && + fx2int(_ents[i].y) + _ents[i].h > fx2int(_ents[j].y)) + { + _ents[i].ent_cols |= _ents[j].ent_type; + } + } + } + + for (int i = 0; i < ENT_COUNT; i++) + { switch (_ents[i].ent_type) { case TYPE_BULLET: @@ -177,6 +235,10 @@ void update_ents() { break; case TYPE_PLAYER: break; + case TYPE_NONE: + break; } } + + step_enemy_global(); } \ No newline at end of file diff --git a/source/ent.h b/source/ent.h index fe951e5..2bb1069 100644 --- a/source/ent.h +++ b/source/ent.h @@ -6,90 +6,107 @@ #include #ifdef ISMAIN - #define def +#define def #else - #define def extern +#define def extern #endif -#define ENT_COUNT 10 -#define ENEMY_MAX_COUNT 10 +//Making this above 90 causes linking errors (maybe running out of ram? that's not how ram works?) +#define ENT_COUNT 25 -typedef enum ent_types_t { - TYPE_PLAYER, TYPE_BULLET, TYPE_ENEMY +typedef enum ent_types_t +{ + TYPE_NONE, + TYPE_PLAYER, + TYPE_BULLET, + TYPE_ENEMY } ent_types_t; -typedef enum movement_state_t { - MOVEMENT_GROUNDED, MOVEMENT_JUMPING, MOVEMENT_AIR, MOVEMENT_LANDED +typedef enum movement_state_t +{ + MOVEMENT_GROUNDED, + MOVEMENT_JUMPING, + MOVEMENT_AIR, + MOVEMENT_LANDED } movement_state_t; -typedef enum facing_t { - FACING_LEFT, FACING_RIGHT +typedef enum facing_t +{ + FACING_LEFT, + FACING_RIGHT } facing_t; -typedef enum { +typedef enum +{ BULLET_TYPE_GUN_0 } bullet_type_t; -typedef struct ent_t { +typedef struct ent_t +{ FIXED x, y; FIXED vx, vy; int tid; int w, h; int att_idx; + int ent_cols; ent_types_t ent_type; //Ent speifc vars - union { + union + { //Player - struct { + struct + { movement_state_t move_state; facing_t facing; FIXED jump_power; }; //Bullet - struct { + struct + { bullet_type_t bullet_type; bool active; }; //Enemy - struct { + struct + { int anime_cycle; }; }; - + } ent_t; def OBJ_ATTR _obj_buffer[128]; def ent_t _player; def ent_t _ents[ENT_COUNT]; -def ent_t _enemy[ENEMY_MAX_COUNT]; void init_obj_atts(); int allocate_att(int count); void free_att(int count, int idx); -inline OBJ_ATTR* get_ent_att(ent_t *e) { +inline OBJ_ATTR *get_ent_att(ent_t *e) +{ return &_obj_buffer[e->att_idx]; } FIXED translate_x(ent_t *e); FIXED translate_y(ent_t *e); -inline int ent_level_collision(ent_t *e) { +inline int ent_level_collision(ent_t *e) +{ return level_collision_rect( translate_x(e) / FIX_SCALE, translate_y(e) / FIX_SCALE, e->w, - e->h - ); + e->h); } -inline int ent_level_collision_at(ent_t *e, FIXED vx, FIXED vy) { +inline int ent_level_collision_at(ent_t *e, FIXED vx, FIXED vy) +{ return level_collision_rect( - (translate_x(e) + vx) / FIX_SCALE, + (translate_x(e) + vx) / FIX_SCALE, (translate_y(e) + vy) / FIX_SCALE, - e->w, - e->h - ); + e->w, + e->h); } int att_count(); diff --git a/source/graphics.c b/source/graphics.c index 8579085..de7a014 100644 --- a/source/graphics.c +++ b/source/graphics.c @@ -1,100 +1,159 @@ -#include "graphics.h" - -#include -#include - -#include "common.h" -#include "debug.h" - -static int _sprite_tile_allc[SPRITE_TILE_ALLC_SIZE]; - -void init_graphics() { - for(int i = 0; i < SPRITE_TILE_ALLC_SIZE; i++) { - _sprite_tile_allc[i] = 0; - } -} - -int allocate_tile_idx(int size) { - size = size * 2; - for(int i = 0; i < SPRITE_TILE_ALLC_SIZE;) { - bool found = true; - for(int j = i; j - i < size && j < SPRITE_TILE_ALLC_SIZE; j++) { - if(_sprite_tile_allc[j] > 0) { - found = false; - break; - } - } - if(found) { - for(int j = 0; j < size; j++) { - _sprite_tile_allc[i + j] = 1; - } - return i; - } - i += size; - } - - return 0; -} - -void free_tile_idx(int idx, int size) { - size = size * 2; - for(int i = idx; i < idx + size; i++) { - _sprite_tile_allc[i] = 0; - } -} - -static inline int calc_address(int width, int x, int y) { - return width * y + x; -} - -bool valid_cloud_address(int tile_offset, int sb, int width, int x, int y) { - int address = calc_address(width, x, y); - - for(int i = 0; i < 4; i++) { - if(se_mem[sb][address+i] != tile_offset){ - return false; - } - } - - for(int i = 0; i < 4; i++) { - if(se_mem[sb][address+32+i] != tile_offset){ - return false; - } - } - - return true; -} - - -void create_cloud(int tile_offset, int sb, int width, int x, int y) { - int address = calc_address(width, x, y); - - se_mem[sb][address+0] = tile_offset + 0x1; - se_mem[sb][address+1] = tile_offset + 0x2; - se_mem[sb][address+2] = tile_offset + 0x3; - se_mem[sb][address+3] = tile_offset + 0x4; - se_mem[sb][address+32] = tile_offset + 0x5; - se_mem[sb][address+33] = tile_offset + 0x6; - se_mem[sb][address+34] = tile_offset + 0x7; - se_mem[sb][address+35] = tile_offset + 0x8; -} - -void place_n_clouds(int tile_offset, int sb, int width, int n) { - for(int i = 0; i < n; i++) { - int j = 0; - while (1) - { - int y = gba_rand_range(0, 10); - int x = gba_rand_range(0, 28); - j++; - if(valid_cloud_address(tile_offset, sb, width, x, y)) { - create_cloud(tile_offset, sb, width, x, y); - j = 6; - } - - if(j > 5) { - break; - } - } - } +#include "graphics.h" + +#include +#include + +#include "common.h" +#include "debug.h" + +static int _obj_tile_allc[OBJ_TILE_ALLC_SIZE]; +static int _bg_tile_allc[BG_TILE_ALLC_SIZE]; + +static int _building_offset; + +void init_graphics() +{ + for (int i = 0; i < OBJ_TILE_ALLC_SIZE; i++) + { + _obj_tile_allc[i] = 0; + } + + for (int i = 0; i < BG_TILE_ALLC_SIZE; i++) + { + _bg_tile_allc[i] = 0; + } +} + +static int allocate_tile_idx(int *allc, int len, int size) +{ + size = size * 2; + for (int i = 0; i < len;) + { + bool found = true; + for (int j = i; j - i < size && j < len; j++) + { + if (allc[j] > 0) + { + found = false; + break; + } + } + if (found) + { + for (int j = 0; j < size; j++) + { + allc[i + j] = 1; + write_to_log(LOG_LEVEL_INFO, "END"); + } + return i; + } + i += size; + } + + return -1; +} + +void free_tile_idx(int *allc, int len, int idx, int size) +{ + size = size * 2; + for (int i = idx; i < idx + size; i++) + { + allc[i] = 0; + } +} + +int allocate_obj_tile_idx(int size) +{ + return allocate_tile_idx(_obj_tile_allc, OBJ_TILE_ALLC_SIZE, size); +} + +void free_obj_tile_idx(int idx, int size) +{ + free_tile_idx(_obj_tile_allc, OBJ_TILE_ALLC_SIZE, idx, size); +} + +int allocate_bg_tile_idx(int size) +{ + return allocate_tile_idx(_bg_tile_allc, BG_TILE_ALLC_SIZE, size); +} + +void free_bg_tile_idx(int idx, int size) +{ + free_tile_idx(_bg_tile_allc, BG_TILE_ALLC_SIZE, idx, size); +} + +int get_buildings_tile_offset() +{ + return _building_offset; +} + +void set_buildings_tiles_offset(int idx) +{ + _building_offset = idx; +} + +static inline int calc_address(int width, int x, int y) +{ + return width * y + x; +} + +bool valid_cloud_address(int tile_offset, int sb, int width, int x, int y) +{ + int address = calc_address(width, x, y); + + for (int i = 0; i < 4; i++) + { + if (se_mem[sb][address + i] != tile_offset) + { + return false; + } + } + + for (int i = 0; i < 4; i++) + { + if (se_mem[sb][address + 32 + i] != tile_offset) + { + return false; + } + } + + return true; +} + +void create_cloud(int tile_offset, int sb, int width, int x, int y) +{ + int address = calc_address(width, x, y); + + se_mem[sb][address + 0] = tile_offset + 0x1; + se_mem[sb][address + 1] = tile_offset + 0x2; + se_mem[sb][address + 2] = tile_offset + 0x3; + se_mem[sb][address + 3] = tile_offset + 0x4; + se_mem[sb][address + 32] = tile_offset + 0x5; + se_mem[sb][address + 33] = tile_offset + 0x6; + se_mem[sb][address + 34] = tile_offset + 0x7; + se_mem[sb][address + 35] = tile_offset + 0x8; +} + +void place_n_clouds(int tile_offset, int sb, int width, int n) +{ + for (int i = 0; i < n; i++) + { + int j = 0; + while (1) + { + int y = gba_rand_range(0, 10); + int x = gba_rand_range(0, 28); + j++; + if (valid_cloud_address(tile_offset, sb, width, x, y)) + { + create_cloud(tile_offset, sb, width, x, y); + j = 6; + } + + if (j > 5) + { + break; + } + } + } } \ No newline at end of file diff --git a/source/graphics.h b/source/graphics.h index 0afff0f..6edfe80 100644 --- a/source/graphics.h +++ b/source/graphics.h @@ -5,7 +5,7 @@ #define SKY_OFFSET 76 -#define BUILDINGS_OFFSET 424 +#define BUILDINGS_OFFSET 0 // BUILDING 0 #define BUILDING_0_LEFT_ROOF BUILDING_0_RIGHT_ROOF @@ -29,12 +29,19 @@ #define BUILDING_1_MIDDLE_ROOF BUILDING_1_OFFSET + 1 #define BUILDING_1_MIDDLE_BOT BUILDING_1_OFFSET + 3 -#define SPRITE_TILE_ALLC_SIZE 64 +#define OBJ_TILE_ALLC_SIZE 64 +#define BG_TILE_ALLC_SIZE 1024 * 2 void init_graphics(); -int allocate_tile_idx(int size); -void free_tile_idx(int idx, int size); +int allocate_obj_tile_idx(int size); +void free_obj_tile_idx(int idx, int size); + +int allocate_bg_tile_idx(int size); +void free_bg_tile_idx(int idx, int size); + +int get_buildings_tile_offset(); +void set_buildings_tiles_offset(int idx); bool valid_cloud_address(int tile_offset, int sb, int width, int x, int y); diff --git a/source/gun.c b/source/gun.c index 854eb1f..b85d3a8 100644 --- a/source/gun.c +++ b/source/gun.c @@ -5,96 +5,66 @@ #include "assets/gun_0_bullet.h" #include "debug.h" -static int _bullet_top = 0; static int _gun_0_tile = -1; -void load_gun_0_tiles() { - _gun_0_tile = allocate_tile_idx(1); +void load_gun_0_tiles() +{ + _gun_0_tile = allocate_obj_tile_idx(1); dma3_cpy(&tile_mem[4][_gun_0_tile], gun_0_bulletTiles, gun_0_bulletTilesLen); } -void unload_gun_0_tiles() { - free_tile_idx(_gun_0_tile, 1); +void unload_gun_0_tiles() +{ + free_obj_tile_idx(_gun_0_tile, 1); } -void create_bullet(bullet_type_t type, FIXED x, FIXED y, FIXED vx, FIXED vy) { - write_to_log(LOG_LEVEL_INFO, "CREATING BULLET"); +int gun_0_tiles() +{ + return _gun_0_tile; +} - ent_t *bul = &_ents[_bullet_top++]; +void create_bullet( + ent_t *bul, int att_idx, bullet_type_t type, + FIXED x, FIXED y, FIXED vx, FIXED vy) +{ + bul->att_idx = att_idx; bul->bullet_type = type; bul->x = x; + bul->w = 5; bul->y = y; + bul->h = 5; bul->vx = vx; bul->vy = vy; bul->active = true; bul->ent_type = TYPE_BULLET; - switch (type) { + switch (type) + { case BULLET_TYPE_GUN_0: break; } - if(_bullet_top >= ENT_COUNT) { - _bullet_top = 0; - } - - bul->att_idx = allocate_att(1); - char str[50]; - sprintf(str, "NB att:%d", bul->att_idx); - write_to_log(LOG_LEVEL_INFO, str); - - obj_set_attr(&_obj_buffer[bul->att_idx], + obj_set_attr( + get_ent_att(bul), ATTR0_SQUARE | ATTR0_8BPP, ATTR1_SIZE_8x8, - ATTR2_PALBANK(0) | ATTR2_PRIO(0) | ATTR2_ID(_gun_0_tile) - ); + ATTR2_ID(_gun_0_tile)); - obj_set_pos(&_obj_buffer[bul->att_idx], fx2int(bul->x), fx2int(bul->y)); + obj_set_pos(get_ent_att(bul), fx2int(bul->x), fx2int(bul->y)); } -void update_bullet(ent_t *bul) { - if(!bul->active) { - return; - } - +void update_bullet(ent_t *bul) +{ bool hit_x = ent_move_x(bul, bul->vx - _scroll_x); ent_move_y(bul, bul->vy); int col = ent_level_collision_at(bul, 0, 0); - if(col & (LEVEL_COL_PLAYER)) { - - } - - if(fx2int(bul->x) > SCREEN_WIDTH || hit_x) { - write_to_log(LOG_LEVEL_INFO, "destroying BULLET"); + if (fx2int(bul->x) > SCREEN_WIDTH || hit_x || bul->ent_cols & (TYPE_ENEMY)) + { free_att(1, bul->att_idx); - bul->active = false; + bul->ent_type = TYPE_NONE; return; } - obj_set_pos(&_obj_buffer[bul->att_idx], fx2int(bul->x), fx2int(bul->y)); -} - -// void update_bullets() { -// for(int i = 0; i < ENTS_LENGTH; i++) { -// if(!_ents[i].active) { -// continue; -// } - -// bool hit_x = ent_move_x(&_ents[i], _ents[i].vx - _scroll_x); -// ent_move_y(&_ents[i], _ents[i].vy); - -// int col = ent_level_collision_at(&_ents[i], 0, 0); -// if(col & (LEVEL_COL_PLAYER)) { - -// } - -// if(fx2int(_ents[i].x) > SCREEN_WIDTH || hit_x) { -// free_att(1, _ents[i].att_idx); -// _ents[i].active = false; -// continue; -// } - -// obj_set_pos(&_obj_buffer[_ents[i].att_idx], fx2int(_ents[i].x), fx2int(_ents[i].y)); -// } -// } \ No newline at end of file + obj_set_pos(get_ent_att(bul), fx2int(bul->x), fx2int(bul->y)); +} \ No newline at end of file diff --git a/source/gun.h b/source/gun.h index 13a0f67..eff3709 100644 --- a/source/gun.h +++ b/source/gun.h @@ -6,7 +6,9 @@ void load_gun_0_tiles(); void unload_gun_0_tiles(); -void create_bullet(bullet_type_t type, FIXED x, FIXED y, FIXED vx, FIXED vy); +int gun_0_tiles(); + +void create_bullet(ent_t *bul, int att_idx, bullet_type_t type, FIXED x, FIXED y, FIXED vx, FIXED vy); void update_bullet(ent_t *bul); #endif \ No newline at end of file diff --git a/source/level.c b/source/level.c index e369c6d..af76e2a 100644 --- a/source/level.c +++ b/source/level.c @@ -4,17 +4,24 @@ #include "common.h" #include "debug.h" +#include "gun.h" + u16 _level[LEVEL_SIZE] = {}; -void set_level_col(int x, int y, u16 tile) { - for(; y < LEVEL_HEIGHT; y++) { +void set_level_col(int x, int y, u16 tile) +{ + for (; y < LEVEL_HEIGHT; y++) + { set_level_at(x, y, tile); } } -bool col_cleared(int x) { - for(int y = 0; y < LEVEL_HEIGHT; y++) { - if(at_level(x, y)) { +bool col_cleared(int x) +{ + for (int y = 0; y < LEVEL_HEIGHT; y++) + { + if (at_level(x, y)) + { return false; } } @@ -22,15 +29,18 @@ bool col_cleared(int x) { return true; } -int tile_to_collision(u16 tile) { - if(tile < BUILDINGS_OFFSET) { +int tile_to_collision(u16 tile) +{ + if (tile < get_buildings_tile_offset()) + { return LEVEL_COL_EMPTY; } return LEVEL_COL_GROUND; } -int level_collision_rect(int x, int y, int w, int h) { +int level_collision_rect(int x, int y, int w, int h) +{ int tile_left = x / TILE_WIDTH; int tile_right = tile_left + w / TILE_WIDTH; int tile_top = y / TILE_WIDTH; @@ -38,8 +48,10 @@ int level_collision_rect(int x, int y, int w, int h) { int res = 0; - for(int i = tile_left; i <= tile_right; i++) { - for(int j = tile_top; j <= tile_bot; j++) { + for (int i = tile_left; i <= tile_right; i++) + { + for (int j = tile_top; j <= tile_bot; j++) + { res |= tile_to_collision(at_level(level_wrap_x(i), j)); } } diff --git a/source/level.h b/source/level.h index b8c45ea..608291d 100644 --- a/source/level.h +++ b/source/level.h @@ -3,31 +3,35 @@ #include -#define LEVEL_SIZE LEVEL_WIDTH * LEVEL_HEIGHT +#define LEVEL_SIZE LEVEL_WIDTH *LEVEL_HEIGHT #define LEVEL_HEIGHT 32 #define LEVEL_WIDTH 64 -#define LEVEL_COL_EMPTY 0 -#define LEVEL_COL_GROUND 1 -#define LEVEL_COL_PLAYER 2 +#define LEVEL_COL_EMPTY 0 +#define LEVEL_COL_GROUND 1 extern u16 _level[LEVEL_SIZE]; extern FIXED _bg_pos_x; -inline u16 at_level(int x, int y) { +inline u16 at_level(int x, int y) +{ return _level[LEVEL_HEIGHT * x + y]; } -inline void set_level_at(int x, int y, u16 val) { +inline void set_level_at(int x, int y, u16 val) +{ _level[LEVEL_HEIGHT * x + y] = val; } -inline int level_wrap_x(int x) { - if(x >= LEVEL_WIDTH) { +inline int level_wrap_x(int x) +{ + if (x >= LEVEL_WIDTH) + { return x - LEVEL_WIDTH; } - if(x < 0) { + if (x < 0) + { return x + LEVEL_WIDTH; } diff --git a/source/numbers.c b/source/numbers.c index 060c24a..02d823b 100644 --- a/source/numbers.c +++ b/source/numbers.c @@ -11,18 +11,21 @@ static int _tile_start_idx; static int _number; -void load_number_tiles() { - _tile_start_idx = allocate_tile_idx(10); +void load_number_tiles() +{ + _tile_start_idx = allocate_obj_tile_idx(10); dma3_cpy(&tile_mem[4][_tile_start_idx], numbersfontTiles, numbersfontTilesLen); dma3_cpy(pal_obj_mem, spriteSharedPal, spriteSharedPalLen); _number = 0; } -void unload_numbers() { - free_tile_idx(_tile_start_idx, 10); +void unload_numbers() +{ + free_obj_tile_idx(_tile_start_idx, 10); } -int get_number_tile_start() { +int get_number_tile_start() +{ return _tile_start_idx; } \ No newline at end of file diff --git a/source/player.c b/source/player.c index bb8433c..d516f21 100644 --- a/source/player.c +++ b/source/player.c @@ -1,200 +1,241 @@ -#include "player.h" - -#include -#include -#include "common.h" -#include "ent.h" -#include "debug.h" -#include "graphics.h" -#include "anime.h" - -#include "assets/whale_small.h" -#include "assets/whale_small_jump_0.h" -#include "assets/whale_small_jump_1.h" -#include "assets/spriteShared.h" -#include "assets/whale_walk_0.h" -#include "assets/whale_walk_1.h" -#include "assets/whale_walk_2.h" -#include "assets/whale_walk_3.h" -#include "assets/whale_walk_4.h" -#include "assets/whale_land_0.h" -#include "assets/whale_land_1.h" -#include "assets/whale_air_0.h" -#include "assets/whale_air_1.h" -#include "assets/whale_air_2.h" - -static const FIXED SPEED = (int)(2.0f * (FIX_SCALE)); - -static int _player_anime_cycle; -static int _tile_start_idx; - -ent_t _player = {}; - -const uint *air_anime_cycle[] = {whale_air_0Tiles, whale_air_0Tiles, whale_air_1Tiles, whale_air_2Tiles}; - -void load_player_tile() { - _tile_start_idx = allocate_tile_idx(4); - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_smallTiles, whale_smallTilesLen); - dma3_cpy(pal_obj_mem, spriteSharedPal, spriteSharedPalLen); -} - -void init_player() { - load_player_tile(); - - _player.att_idx = allocate_att(1); - _player_anime_cycle = 0; - - _player.tid = _tile_start_idx; - _player.facing = FACING_RIGHT; - _player.jump_power = (int)(2.0f * (FIX_SCALE)); - _player.w = 16; - _player.h = 16; - - _player.x = 20 << FIX_SHIFT; - _player.y = PLAYER_SPAWN_Y; - - _player.ent_type = TYPE_PLAYER; - - obj_set_attr(&_obj_buffer[_player.att_idx], - ATTR0_SQUARE | ATTR0_8BPP, ATTR1_SIZE_16x16, - ATTR2_PALBANK(0) | _player.tid - ); -} - -void unload_player() { - free_att(1, _player.att_idx); - free_tile_idx(_tile_start_idx, 4); -} - -void update_player() { - //Handles fliping the sprite if facing the other direction - if(_player.facing == FACING_RIGHT && key_hit(KEY_LEFT)) { - _player.facing = FACING_LEFT; - get_ent_att(&_player)->attr1 ^= ATTR1_HFLIP; - } else if(_player.facing == FACING_LEFT && key_hit(KEY_RIGHT)) { - _player.facing = FACING_RIGHT; - get_ent_att(&_player)->attr1 ^= ATTR1_HFLIP; - } - - // Player movement - if(key_held(KEY_LEFT)) { - _player.vx = -SPEED; - } else if(key_held(KEY_RIGHT)) { - _player.vx = SPEED; - } - - // Stops player from going offscreen to the right - if(fx2int(_player.x) > GBA_WIDTH - 20) { - _player.vx += -SPEED; - } - - switch (_player.move_state) - { - case MOVEMENT_AIR: - _player.vx /= 2; - break; - case MOVEMENT_JUMPING: - case MOVEMENT_LANDED: - _player.vx = 0; - break; - default: - break; - } - - _player.vx += -_scroll_x; - ent_move_x(&_player, _player.vx); - bool hit_y = ent_move_y(&_player, _player.vy); - - // Applies gravity - if(!hit_y) { - if(_player.vy < TERMINAL_VY) { - _player.vy += GRAVITY; - } - } - - switch (_player.move_state) - { - case MOVEMENT_GROUNDED: - if(abs(_player.vx) > _scroll_x) { - const int walk_cycle_count = 25; - if(_player_anime_cycle <= 0) { - _player_anime_cycle = walk_cycle_count; - } - - if(_player_anime_cycle == walk_cycle_count) { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_walk_0Tiles, whale_walk_0TilesLen); - } else if(_player_anime_cycle == 20) { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_walk_1Tiles, whale_walk_1TilesLen); - } else if(_player_anime_cycle == 15) { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_walk_2Tiles, whale_walk_2TilesLen); - } else if(_player_anime_cycle == 10) { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_walk_3Tiles, whale_walk_3TilesLen); - } else if(_player_anime_cycle == 5) { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_walk_4Tiles, whale_walk_4TilesLen); - } else if(_player_anime_cycle <= 0) { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_smallTiles, whale_smallTilesLen); - _player_anime_cycle = walk_cycle_count; - } - - _player_anime_cycle--; - } else { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_smallTiles, whale_smallTilesLen); - } - if(key_hit(KEY_A)) { - _player_anime_cycle = PLAYER_JUMP_TIME; - _player.move_state = MOVEMENT_JUMPING; - } - break; - - case MOVEMENT_JUMPING: - if(_player_anime_cycle == PLAYER_JUMP_TIME) { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_small_jump_0Tiles, whale_small_jump_0TilesLen); - } else if(_player_anime_cycle == PLAYER_JUMP_TIME / 2) { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_small_jump_1Tiles, whale_small_jump_1TilesLen); - } else if(_player_anime_cycle <= 0) { - _player.vy = -_player.jump_power; - _player_anime_cycle = PLAYER_AIR_CYCLE_COUNT; - _player.move_state = MOVEMENT_AIR; - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_smallTiles, whale_smallTilesLen); - } - _player_anime_cycle-- ; - break; - - case MOVEMENT_AIR: - if(hit_y) { - _player.move_state = MOVEMENT_LANDED; - _player_anime_cycle = PLAYER_LAND_TIME; - } - - step_anime( - air_anime_cycle, whale_air_0TilesLen, PLAYER_AIR_CYCLE_COUNT, - &_player_anime_cycle, _tile_start_idx - ); - - break; - - case MOVEMENT_LANDED: - _player.vx = 0; - if(_player_anime_cycle == PLAYER_LAND_TIME) { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_land_0Tiles, whale_land_0TilesLen); - } else if (_player_anime_cycle == PLAYER_LAND_TIME / 2) { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_land_1Tiles, whale_land_1TilesLen); - } else if (_player_anime_cycle <= 0 ) { - dma3_cpy(&tile_mem[4][_tile_start_idx], whale_smallTiles, whale_smallTilesLen); - _player.move_state = MOVEMENT_GROUNDED; - } - _player_anime_cycle--; - break; - } - - _player.vx = 0; - //if the player y wraps everything just fucks up - if(_player.y > 160 * FIX_SCALE) { - _player.y = PLAYER_SPAWN_Y; - } - - // increment/decrement starting tile with R/L - _player.tid += bit_tribool(key_hit(KEY_START), KI_R, KI_L); - - obj_set_pos(get_ent_att(&_player), fx2int(_player.x), fx2int(_player.y)); -} +#include "player.h" + +#include +#include +#include "common.h" +#include "ent.h" +#include "debug.h" +#include "graphics.h" +#include "anime.h" + +#include "assets/whale_small.h" +#include "assets/whale_small_jump_0.h" +#include "assets/whale_small_jump_1.h" +#include "assets/spriteShared.h" +#include "assets/whale_walk_0.h" +#include "assets/whale_walk_1.h" +#include "assets/whale_walk_2.h" +#include "assets/whale_walk_3.h" +#include "assets/whale_walk_4.h" +#include "assets/whale_land_0.h" +#include "assets/whale_land_1.h" +#include "assets/whale_air_0.h" +#include "assets/whale_air_1.h" +#include "assets/whale_air_2.h" + +static const FIXED SPEED = (int)(2.0f * (FIX_SCALE)); + +static int _player_anime_cycle; +static int _tile_start_idx; + +ent_t _player = {}; + +const uint *air_anime_cycle[] = {whale_air_0Tiles, whale_air_0Tiles, whale_air_1Tiles, whale_air_2Tiles}; + +void load_player_tile() +{ + _tile_start_idx = allocate_obj_tile_idx(whale_smallTilesLen / 64); + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_smallTiles, whale_smallTilesLen); + dma3_cpy(pal_obj_mem, spriteSharedPal, spriteSharedPalLen); +} + +void init_player() +{ + load_player_tile(); + + //Reserved for player + _player.att_idx = 0; + _player_anime_cycle = 0; + + _player.tid = _tile_start_idx; + _player.facing = FACING_RIGHT; + _player.jump_power = (int)(2.0f * (FIX_SCALE)); + _player.w = 16; + _player.h = 16; + + _player.x = int2fx(20); + _player.y = PLAYER_SPAWN_Y; + + _player.ent_type = TYPE_PLAYER; + + obj_set_attr( + get_ent_att(&_player), + ATTR0_SQUARE | ATTR0_8BPP, ATTR1_SIZE_16x16, + ATTR2_PALBANK(0) | _player.tid); +} + +void unload_player() +{ + free_att(1, _player.att_idx); + free_obj_tile_idx(_tile_start_idx, 4); +} + +void update_player() +{ + //Handles fliping the sprite if facing the other direction + if (_player.facing == FACING_RIGHT && key_hit(KEY_LEFT)) + { + _player.facing = FACING_LEFT; + get_ent_att(&_player)->attr1 ^= ATTR1_HFLIP; + } + else if (_player.facing == FACING_LEFT && key_hit(KEY_RIGHT)) + { + _player.facing = FACING_RIGHT; + get_ent_att(&_player)->attr1 ^= ATTR1_HFLIP; + } + + // Player movement + if (key_held(KEY_LEFT)) + { + _player.vx = -SPEED; + } + else if (key_held(KEY_RIGHT)) + { + _player.vx = SPEED; + } + + // Stops player from going offscreen to the right + if (fx2int(_player.x) > GBA_WIDTH - 20) + { + _player.vx += -SPEED; + } + + switch (_player.move_state) + { + case MOVEMENT_AIR: + _player.vx /= 2; + break; + case MOVEMENT_JUMPING: + case MOVEMENT_LANDED: + _player.vx = 0; + break; + default: + break; + } + + _player.vx += -_scroll_x; + ent_move_x(&_player, _player.vx); + bool hit_y = ent_move_y(&_player, _player.vy); + + // Applies gravity + if (!hit_y) + { + if (_player.vy < TERMINAL_VY) + { + _player.vy += GRAVITY; + } + } + + switch (_player.move_state) + { + case MOVEMENT_GROUNDED: + if (abs(_player.vx) > _scroll_x) + { + const int walk_cycle_count = 25; + if (_player_anime_cycle <= 0) + { + _player_anime_cycle = walk_cycle_count; + } + + if (_player_anime_cycle == walk_cycle_count) + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_walk_0Tiles, whale_walk_0TilesLen); + } + else if (_player_anime_cycle == 20) + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_walk_1Tiles, whale_walk_1TilesLen); + } + else if (_player_anime_cycle == 15) + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_walk_2Tiles, whale_walk_2TilesLen); + } + else if (_player_anime_cycle == 10) + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_walk_3Tiles, whale_walk_3TilesLen); + } + else if (_player_anime_cycle == 5) + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_walk_4Tiles, whale_walk_4TilesLen); + } + else if (_player_anime_cycle <= 0) + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_smallTiles, whale_smallTilesLen); + _player_anime_cycle = walk_cycle_count; + } + + _player_anime_cycle--; + } + else + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_smallTiles, whale_smallTilesLen); + } + if (key_hit(KEY_A)) + { + _player_anime_cycle = PLAYER_JUMP_TIME; + _player.move_state = MOVEMENT_JUMPING; + } + break; + + case MOVEMENT_JUMPING: + if (_player_anime_cycle == PLAYER_JUMP_TIME) + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_small_jump_0Tiles, whale_small_jump_0TilesLen); + } + else if (_player_anime_cycle == PLAYER_JUMP_TIME / 2) + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_small_jump_1Tiles, whale_small_jump_1TilesLen); + } + else if (_player_anime_cycle <= 0) + { + _player.vy = -_player.jump_power; + _player_anime_cycle = PLAYER_AIR_CYCLE_COUNT; + _player.move_state = MOVEMENT_AIR; + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_smallTiles, whale_smallTilesLen); + } + _player_anime_cycle--; + break; + + case MOVEMENT_AIR: + if (hit_y) + { + _player.move_state = MOVEMENT_LANDED; + _player_anime_cycle = PLAYER_LAND_TIME; + } + + step_anime( + air_anime_cycle, whale_air_0TilesLen, PLAYER_AIR_CYCLE_COUNT, + &_player_anime_cycle, _tile_start_idx); + + break; + + case MOVEMENT_LANDED: + _player.vx = 0; + if (_player_anime_cycle == PLAYER_LAND_TIME) + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_land_0Tiles, whale_land_0TilesLen); + } + else if (_player_anime_cycle == PLAYER_LAND_TIME / 2) + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_land_1Tiles, whale_land_1TilesLen); + } + else if (_player_anime_cycle <= 0) + { + dma3_cpy(&tile_mem[4][_tile_start_idx], whale_smallTiles, whale_smallTilesLen); + _player.move_state = MOVEMENT_GROUNDED; + } + _player_anime_cycle--; + break; + } + + _player.vx = 0; + //if the player y wraps everything just fucks up + if (_player.y > 160 * FIX_SCALE) + { + _player.y = PLAYER_SPAWN_Y; + } + + // increment/decrement starting tile with R/L + _player.tid += bit_tribool(key_hit(KEY_START), KI_R, KI_L); + + obj_set_pos(get_ent_att(&_player), fx2int(_player.x), fx2int(_player.y)); +} diff --git a/source/scenes/main_game.c b/source/scenes/main_game.c index bf8c9f9..9f86be4 100644 --- a/source/scenes/main_game.c +++ b/source/scenes/main_game.c @@ -1,370 +1,446 @@ -#include "main_game.h" - -#include - -#include -#include "soundbank.h" -#include "soundbank_bin.h" - -#include "../common.h" -#include "../ent.h" -#include "../player.h" -#include "../graphics.h" -#include "../level.h" -#include "../debug.h" -#include "../numbers.h" -#include "../gun.h" -#include "../enemy.h" - -#include "../assets/title_text.h" -#include "../assets/backgroundCity.h" -#include "../assets/fog.h" -#include "../assets/mainGameShared.h" - -static FIXED _next_cloud_spawn; -static FIXED _next_building_spawn; -static int _building_spawn_x; -static int _tmp; -static int _bg_0_scroll; -static int _bg_2_scroll; - -static mg_states_t _state; -static mg_states_t _old_state; - -static FIXED wrap_x(FIXED x) { - if(x > MG_BG_X_PIX) { - return x - MG_BG_X_PIX; - } else if(x < 0) { - return x - -x; - } - - return x; -} - -static inline int offset_x_bg(int n) { - int nfx = (n * 8) * FIX_SCALE; - return fx2int(wrap_x(_bg_pos_x + nfx)) / 8; -} - -static void wrap_bkg() { - _bg_pos_x = wrap_x(_bg_pos_x); -} - -static void wrap_x_sb(int *x, int *sb) { - if(*x >= 32) { - *sb = *sb + 1; - *x -= 32; - } else { - *sb = *sb; - } -} - -static int spawn_building_0(int start_x) { - int x_base = start_x; - int x; - int y = gba_rand_range(BUILDING_Y_TILE_SPAWN - 3, BUILDING_Y_TILE_SPAWN); - - //LEFT SECTION - set_level_at(x_base, y, BUILDING_0_LEFT_ROOF); - set_level_col(x_base, y + 1, BUILDING_0_LEFT_ROOF); - - int width = gba_rand_range(5, 10); - //MIDDLE SECTION - for(int i = 1; i < width; i++) { - x = level_wrap_x(x_base + i); - set_level_at(x, y, BUILDING_0_MIDDLE_ROOF); - set_level_col(x, y + 1, BUILDING_0_MIDDLE_BOT); - } - - //RIGHT SECTION - x = level_wrap_x(x_base + width); - set_level_at(x, y, BUILDING_0_MIDDLE_ROOF); - set_level_col(x, y, BUILDING_0_RIGHT_ROOF); - - return width; -} - -static int spawn_building_1(int start_x) { - int x_base = start_x; - int x; - int y = BUILDING_Y_TILE_SPAWN; - - //LEFT SECTION - set_level_at(x_base, y, BUILDING_1_LEFT_ROOF); - set_level_col(x_base, y + 1, BUILDING_1_LEFT_BOT); - - int width = gba_rand_range(3, 7); - //MIDDLE SECTION - for(int i = 1; i < width; i++) { - x = level_wrap_x(x_base + i); - set_level_at(x, y, BUILDING_1_MIDDLE_ROOF); - set_level_col(x, y + 1, BUILDING_1_MIDDLE_BOT); - } - - //RIGHT SECTION - x = level_wrap_x(x_base + width); - set_level_at(x, y, BUILDING_1_RIGHT_ROOF); - set_level_col(x, y + 1, BUILDING_1_RIGHT_BOT); - - return width; -} - -static void spawn_buildings() { - int start_x = _building_spawn_x; - - int width; - if(gba_rand() % 2 == 0){ - width = spawn_building_1(start_x); - } else { - width = spawn_building_0(start_x); - } - - width += gba_rand_range(MIN_JUMP_WIDTH_TILES, MAX_JUMP_WIDTH_TILES); - - _building_spawn_x = level_wrap_x(start_x + width); - - _next_building_spawn = (int)((width * 8) * (FIX_SCALE)); - - int count = gba_rand_range(0, 3); - for(int i = 0; i < count; i++) { - // create_toast_enemy(&_ents, int2fx(120), int2fx(30)); - } -} - -static void spawn_cloud() { - int x = offset_x_bg(32); - int y = gba_rand_range(0, 10); - int sb = MG_CLOUD_SB; - wrap_x_sb(&x, &sb); - - se_plot(se_mem[sb], x + 0, y, SKY_OFFSET + 1); - se_plot(se_mem[sb], x + 1, y, SKY_OFFSET + 2); - se_plot(se_mem[sb], x + 2, y, SKY_OFFSET + 3); - se_plot(se_mem[sb], x + 3, y, SKY_OFFSET + 4); - - se_plot(se_mem[sb], x + 0, y + 1, SKY_OFFSET + 5); - se_plot(se_mem[sb], x + 1, y + 1, SKY_OFFSET + 6); - se_plot(se_mem[sb], x + 2, y + 1, SKY_OFFSET + 7); - se_plot(se_mem[sb], x + 3, y + 1, SKY_OFFSET + 8); -} - -static void clear_offscreen(int sb) { - int x = offset_x_bg(-1); - wrap_x_sb(&x, &sb); - - for(int y = 0; y < 32; y++) { - se_plot(se_mem[sb], x, y, 0); - } -} - -static void clear_offscreen_level() { - int x = level_wrap_x((fx2int(_bg_pos_x) / TILE_WIDTH) - 3); - set_level_col(x, 0, 0); -} - -static void show(void) { - // Load palette - dma3_cpy(pal_bg_mem, mainGameSharedPal, mainGameSharedPalLen); - // Load tiles into MG_SHARED_CB - dma3_cpy(&tile_mem[MG_SHARED_CB], mainGameSharedTiles, mainGameSharedTilesLen); - - dma3_cpy(se_mem[MG_BACKGROUND_SB], backgroundCityMap, backgroundCityMapLen); - - //Fill cloud layer - dma3_cpy(se_mem[MG_CLOUD_SB], fogMap, fogMapLen); - - _bg_0_scroll = int2fx(gba_rand()); - _bg_2_scroll = int2fx(gba_rand()); - - //Set bg postions - REG_BG0HOFS = fx2int(_bg_0_scroll / 6); - REG_BG0VOFS = 0; - - REG_BG1HOFS = 0; - REG_BG1VOFS = 0; - - REG_BG2HOFS = fx2int(_bg_2_scroll / 12); - REG_BG2VOFS = 0; - - char str[50]; - sprintf(str, "0:%d\t1:%d", _bg_0_scroll, _bg_2_scroll); - write_to_log(LOG_LEVEL_INFO, str); - - // Set bkg reg - REG_BG0CNT = BG_PRIO(3) | BG_8BPP | BG_SBB(MG_BACKGROUND_SB) | BG_CBB(MG_SHARED_CB) | BG_REG_32x32; - REG_BG1CNT = BG_PRIO(1) | BG_8BPP | BG_SBB(MG_BUILDING_SB) | BG_CBB(MG_SHARED_CB) | BG_REG_64x32; - REG_BG2CNT = BG_PRIO(2) | BG_8BPP | BG_SBB(MG_CLOUD_SB) | BG_CBB(MG_SHARED_CB) | BG_REG_32x32; - - REG_DISPCNT = DCNT_OBJ | DCNT_OBJ_1D | DCNT_BG0 | DCNT_BG1 | DCNT_BG2; - - //Blend reg - REG_BLDCNT = BLD_BUILD( - BLD_BG2, // Top layers - BLD_BG0, // Bottom layers - 1 // Mode - ); - - // Update blend weights - //Left EVA: Top weight max of 15 (4 bits) - //Right EVB: Bottom wieght max of 15 (4 bits) - // REG_BLDALPHA = BLDA_BUILD(3, 5); - REG_BLDALPHA = BLDA_BUILD(8, 6); - REG_BLDY = BLDY_BUILD(0); - - - _next_cloud_spawn = 0; - _next_building_spawn = 0; - _scroll_x = 0; - _building_spawn_x = 0; - _state = MG_S_STARTING; - - while(_building_spawn_x < LEVEL_WIDTH / 2 + LEVEL_WIDTH / 5) { - spawn_buildings(); - } - - init_player(); - _player.move_state = MOVEMENT_AIR; - load_gun_0_tiles(); - - load_number_tiles(); - init_score(); - // load_enemy_toast(); - - mmSetModuleVolume(600); - mmStart(MOD_INTRO, MM_PLAY_ONCE); -} - -static bool check_game_over() { -#ifdef DEBUG - return false; -#elif - return fx2int(_player.x) < 0; -#endif -} - -static void update(void) { - if(!mmActive()) { - mmStart(MOD_PD_BACKGROUND_0, MM_PLAY_LOOP); - } - - // Pausing! - if(_state == MG_S_PAUSED) { - if(key_hit(KEY_START)) { - write_to_log(LOG_LEVEL_INFO, "UNPAUSE"); - _state = _old_state; - } - return; - } - - if(key_hit(KEY_START)) { - write_to_log(LOG_LEVEL_INFO, "PAUSING"); - _old_state = _state; - _state = MG_S_PAUSED; - return; - } - - if(check_game_over()) { - for(int i = 0; i < SB_SIZE; i++) { - se_mem[MG_BACKGROUND_SB][i] = 0x0; - } - scene_set(title_screen); - return; - } - - _bg_pos_x += _scroll_x; - _bg_0_scroll += _scroll_x; - _bg_2_scroll += _scroll_x; - - wrap_bkg(); - - REG_BG0HOFS = fx2int(_bg_0_scroll / 6); - REG_BG1HOFS = fx2int(_bg_pos_x); - REG_BG2HOFS = fx2int(_bg_2_scroll / 4); - - - _next_cloud_spawn -= _scroll_x; - _next_building_spawn -= _scroll_x; - - if(frame_count() % 60 == 0) { - add_score(fx2int(_scroll_x * 10)); - } - - if(_next_cloud_spawn < 0 && false) { - spawn_cloud(); - _next_cloud_spawn = gba_rand_range( - fx2int(CLOUD_WIDTH), - fx2int(CLOUD_WIDTH + (int)(100 * FIX_SCALE)) - ) * FIX_SCALE; - } - - if(_next_building_spawn < 0) { - spawn_buildings(); - } - - - if(key_hit(KEY_B)) { - create_bullet( - BULLET_TYPE_GUN_0, _player.x + int2fx(16), _player.y + int2fx(4), - float2fx(2.5f), 0 - ); - } - - //Copy buldings into VRAM - for(int x = 0; x < LEVEL_WIDTH; x++) { - for(int y = 0; y < LEVEL_HEIGHT; y++) { - if(x < 32) { - se_plot(se_mem[MG_BUILDING_SB], x, y, at_level(x, y)); - } else { - se_plot(se_mem[MG_BUILDING_SB+1], x-32, y, at_level(x, y)); - } - } - } - - // clear_offscreen(MG_CLOUD_SB); - clear_offscreen_level(); - - update_player(); - update_ents(); - - oam_copy(oam_mem, _obj_buffer, att_count()); - - switch(_state) - { - case MG_S_STARTING: - if(key_hit(KEY_RIGHT)) { - _scroll_x = (int)(0.25f * FIX_SCALE); - _state = MG_S_SCROLLING; - } - break; - case MG_S_SCROLLING: - if(frame_count() % X_SCROLL_RATE == 0) { - _scroll_x += X_SCROLL_GAIN; - //This is better than checking if it's greater prior to adding - //Because it handles the edge case where the gain will put it much - //over the limit - if(_scroll_x > X_SCROLL_MAX) { - _scroll_x = X_SCROLL_MAX; - } - } - break; - case MG_S_PAUSED: - //This should never be hit fuck - break; - } -} - -static void hide(void) { - REG_DISPCNT = 0; - dma3_fill(se_mem[MG_CLOUD_SB], 0x0, SB_SIZE); - dma3_fill(se_mem[MG_CLOUD_SB+1], 0x0, SB_SIZE); - - clear_score(); - unload_gun_0_tiles(); - unload_player(); -} - -const scene_t main_game = { - .show = show, - .update = update, - .hide = hide -}; +#include "main_game.h" + +#include + +#include +#include "soundbank.h" +#include "soundbank_bin.h" + +#include "../common.h" +#include "../ent.h" +#include "../player.h" +#include "../graphics.h" +#include "../level.h" +#include "../debug.h" +#include "../numbers.h" +#include "../gun.h" +#include "../enemy.h" + +#include "../assets/title_text.h" +#include "../assets/backgroundCity.h" +#include "../assets/fog.h" +#include "../assets/mainGameShared.h" +#include "../assets/buildingtileset.h" + +static FIXED _next_cloud_spawn; +static FIXED _next_building_spawn; +static int _building_spawn_x; +static int _tmp; +static int _bg_0_scroll; +static int _bg_2_scroll; + +static int _far_building_tiles_idx; +static int _foreground_build_tile_idx; +static int _fog_tiles_idx; + +static mg_states_t _state; +static mg_states_t _old_state; + +static FIXED wrap_x(FIXED x) +{ + if (x > MG_BG_X_PIX) + { + return x - MG_BG_X_PIX; + } + else if (x < 0) + { + return x - -x; + } + + return x; +} + +static inline int offset_x_bg(int n) +{ + int nfx = (n * 8) * FIX_SCALE; + return fx2int(wrap_x(_bg_pos_x + nfx)) / 8; +} + +static void wrap_bkg() +{ + _bg_pos_x = wrap_x(_bg_pos_x); +} + +static void wrap_x_sb(int *x, int *sb) +{ + if (*x >= 32) + { + *sb = *sb + 1; + *x -= 32; + } + else + { + *sb = *sb; + } +} + +static int spawn_building_0(int start_x) +{ + int x_base = start_x; + int x; + int y = gba_rand_range(BUILDING_Y_TILE_SPAWN - 3, BUILDING_Y_TILE_SPAWN); + + //LEFT SECTION + set_level_at(x_base, y, BUILDING_0_LEFT_ROOF + get_buildings_tile_offset()); + set_level_col(x_base, y + 1, BUILDING_0_LEFT_ROOF + get_buildings_tile_offset()); + + int width = gba_rand_range(5, 10); + //MIDDLE SECTION + for (int i = 1; i < width; i++) + { + x = level_wrap_x(x_base + i); + set_level_at(x, y, BUILDING_0_MIDDLE_ROOF + get_buildings_tile_offset()); + set_level_col(x, y + 1, BUILDING_0_MIDDLE_BOT + get_buildings_tile_offset()); + } + + //RIGHT SECTION + x = level_wrap_x(x_base + width); + set_level_at(x, y, BUILDING_0_MIDDLE_ROOF + get_buildings_tile_offset()); + set_level_col(x, y, BUILDING_0_RIGHT_ROOF + get_buildings_tile_offset()); + + int att_idx = allocate_att(1); + if (att_idx != -1) + { + int enemy_x = gba_rand_range(x_base, x_base + width); + char str[75]; + sprintf( + str, "ex:%d,ey:%d,xs:%d,xe:%d,y:%d", + level_wrap_x(enemy_x) * + 8, + y * 8 + 16, + level_wrap_x(x_base) * 8, + level_wrap_x(x_base + width) * 8, + y * 8); + write_to_log(LOG_LEVEL_INFO, str); + + create_toast_enemy( + &_ents[att_idx], att_idx, + int2fx(level_wrap_x(enemy_x) * 8), int2fx(y * 8 - 32)); + } + + return width; +} + +static int spawn_building_1(int start_x) +{ + int x_base = start_x; + int x; + int y = BUILDING_Y_TILE_SPAWN; + + //LEFT SECTION + set_level_at(x_base, y, BUILDING_1_LEFT_ROOF + get_buildings_tile_offset()); + set_level_col(x_base, y + 1, BUILDING_1_LEFT_BOT + get_buildings_tile_offset()); + + int width = gba_rand_range(3, 7); + //MIDDLE SECTION + for (int i = 1; i < width; i++) + { + x = level_wrap_x(x_base + i); + set_level_at(x, y, BUILDING_1_MIDDLE_ROOF + get_buildings_tile_offset()); + set_level_col(x, y + 1, BUILDING_1_MIDDLE_BOT + get_buildings_tile_offset()); + } + + //RIGHT SECTION + x = level_wrap_x(x_base + width); + set_level_at(x, y, BUILDING_1_RIGHT_ROOF + get_buildings_tile_offset()); + set_level_col(x, y + 1, BUILDING_1_RIGHT_BOT + get_buildings_tile_offset()); + + return width; +} + +static void spawn_buildings() +{ + int start_x = _building_spawn_x; + + int width; + if (gba_rand() % 2 == 0) + { + width = spawn_building_1(start_x); + } + else + { + width = spawn_building_0(start_x); + } + + width += gba_rand_range(MIN_JUMP_WIDTH_TILES, MAX_JUMP_WIDTH_TILES); + + _building_spawn_x = level_wrap_x(start_x + width); + + _next_building_spawn = (int)((width * 8) * (FIX_SCALE)); +} + +static void spawn_cloud() +{ + int x = offset_x_bg(32); + int y = gba_rand_range(0, 10); + int sb = MG_CLOUD_SB; + wrap_x_sb(&x, &sb); + + se_plot(se_mem[sb], x + 0, y, SKY_OFFSET + 1); + se_plot(se_mem[sb], x + 1, y, SKY_OFFSET + 2); + se_plot(se_mem[sb], x + 2, y, SKY_OFFSET + 3); + se_plot(se_mem[sb], x + 3, y, SKY_OFFSET + 4); + + se_plot(se_mem[sb], x + 0, y + 1, SKY_OFFSET + 5); + se_plot(se_mem[sb], x + 1, y + 1, SKY_OFFSET + 6); + se_plot(se_mem[sb], x + 2, y + 1, SKY_OFFSET + 7); + se_plot(se_mem[sb], x + 3, y + 1, SKY_OFFSET + 8); +} + +static void clear_offscreen(int sb) +{ + int x = offset_x_bg(-1); + wrap_x_sb(&x, &sb); + + for (int y = 0; y < 32; y++) + { + se_plot(se_mem[sb], x, y, 0); + } +} + +static void clear_offscreen_level() +{ + int x = level_wrap_x((fx2int(_bg_pos_x) / TILE_WIDTH) - 3); + set_level_col(x, 0, 0); +} + +static void show(void) +{ + // Load palette + dma3_cpy(pal_bg_mem, mainGameSharedPal, mainGameSharedPalLen); + + _bg_0_scroll = int2fx(gba_rand()); + _bg_2_scroll = int2fx(gba_rand()); + char str[50]; + + _far_building_tiles_idx = 0; + dma3_cpy(&tile_mem[MG_SHARED_CB][_far_building_tiles_idx], backgroundCityTiles, backgroundCityTilesLen); + + _fog_tiles_idx = backgroundCityTilesLen / 32; + dma3_cpy(&tile_mem[MG_SHARED_CB][_fog_tiles_idx], fogTiles, fogTilesLen); + + _foreground_build_tile_idx = _fog_tiles_idx + fogTilesLen / 32; + sprintf(str, "fg:%d", _foreground_build_tile_idx / 2); + write_to_log(LOG_LEVEL_INFO, str); + dma3_cpy(&tile_mem[MG_SHARED_CB][_foreground_build_tile_idx], buildingtilesetTiles, buildingtilesetTilesLen); + + set_buildings_tiles_offset(_foreground_build_tile_idx / 2 + 1); + + //City BG + dma3_cpy(se_mem[MG_CITY_SB], backgroundCityMap, backgroundCityMapLen); + + //Fill Cloud + dma3_cpy(se_mem[MG_CLOUD_SB], fogMap, fogMapLen); + //TODO: stop this double iteration bullshit + for (int i = 0; i < fogMapLen; i++) + { + se_mem[MG_CLOUD_SB][i] += _fog_tiles_idx / 2; + } + + //Set bg postions + REG_BG0HOFS = fx2int(_bg_0_scroll / 6); + REG_BG0VOFS = 0; + + REG_BG1HOFS = 0; + REG_BG1VOFS = 0; + + REG_BG2HOFS = fx2int(_bg_2_scroll / 12); + REG_BG2VOFS = 0; + + // Set bkg reg + REG_BG0CNT = BG_PRIO(3) | BG_8BPP | BG_SBB(MG_CITY_SB) | BG_CBB(MG_SHARED_CB) | BG_REG_32x32; + REG_BG1CNT = BG_PRIO(1) | BG_8BPP | BG_SBB(MG_BUILDING_SB) | BG_CBB(MG_SHARED_CB) | BG_REG_64x32; + REG_BG2CNT = BG_PRIO(2) | BG_8BPP | BG_SBB(MG_CLOUD_SB) | BG_CBB(MG_SHARED_CB) | BG_REG_32x32; + + REG_DISPCNT = DCNT_OBJ | DCNT_OBJ_1D | DCNT_BG0 | DCNT_BG1 | DCNT_BG2; + + //Blend reg + REG_BLDCNT = BLD_BUILD( + BLD_BG2, // Top layers + BLD_BG0, // Bottom layers + 1 // Mode + ); + + // Update blend weights + //Left EVA: Top weight max of 15 (4 bits) + //Right EVB: Bottom wieght max of 15 (4 bits) + // REG_BLDALPHA = BLDA_BUILD(3, 5); + REG_BLDALPHA = BLDA_BUILD(8, 6); + REG_BLDY = BLDY_BUILD(0); + + _next_cloud_spawn = 0; + _next_building_spawn = 0; + _scroll_x = 0; + _building_spawn_x = 0; + _state = MG_S_STARTING; + + init_player(); + _player.move_state = MOVEMENT_AIR; + load_gun_0_tiles(); + + load_enemy_toast(); + load_number_tiles(); + init_score(); + + mmSetModuleVolume(300); + mmStart(MOD_INTRO, MM_PLAY_ONCE); + + while (_building_spawn_x < LEVEL_WIDTH / 2 + LEVEL_WIDTH / 5) + { + spawn_buildings(); + } +} + +static bool check_game_over() +{ +#ifdef DEBUG + return false; +#elif + return fx2int(_player.x) < 0; +#endif +} + +static void update(void) +{ + if (!mmActive()) + { + mmStart(MOD_PD_BACKGROUND_0, MM_PLAY_LOOP); + } + + // Pausing! + if (_state == MG_S_PAUSED) + { + if (key_hit(KEY_START)) + { + write_to_log(LOG_LEVEL_INFO, "UNPAUSE"); + _state = _old_state; + } + return; + } + + if (key_hit(KEY_START)) + { + write_to_log(LOG_LEVEL_INFO, "PAUSING"); + _old_state = _state; + _state = MG_S_PAUSED; + return; + } + + if (check_game_over()) + { + for (int i = 0; i < SB_SIZE; i++) + { + se_mem[MG_CITY_SB][i] = 0x0; + } + scene_set(title_screen); + return; + } + + _bg_pos_x += _scroll_x; + _bg_0_scroll += _scroll_x; + _bg_2_scroll += _scroll_x; + + wrap_bkg(); + + REG_BG0HOFS = fx2int(_bg_0_scroll / 6); + REG_BG1HOFS = fx2int(_bg_pos_x); + REG_BG2HOFS = fx2int(_bg_2_scroll / 4); + + _next_cloud_spawn -= _scroll_x; + _next_building_spawn -= _scroll_x; + + if (frame_count() % 60 == 0) + { + add_score(fx2int(_scroll_x * 10)); + } + + if (_next_cloud_spawn < 0 && false) + { + spawn_cloud(); + _next_cloud_spawn = gba_rand_range( + fx2int(CLOUD_WIDTH), + fx2int(CLOUD_WIDTH + (int)(100 * FIX_SCALE))) * + FIX_SCALE; + } + + if (_next_building_spawn < 0) + { + spawn_buildings(); + } + + if (key_hit(KEY_B)) + { + int att_idx = allocate_att(1); + create_bullet( + &_ents[att_idx], att_idx, + BULLET_TYPE_GUN_0, _player.x + int2fx(16), _player.y + int2fx(4), + float2fx(2.5f), 0); + } + + //Copy buldings into VRAM + for (int x = 0; x < LEVEL_WIDTH; x++) + { + for (int y = 0; y < LEVEL_HEIGHT; y++) + { + if (x < 32) + { + se_plot(se_mem[MG_BUILDING_SB], x, y, at_level(x, y)); + } + else + { + se_plot(se_mem[MG_BUILDING_SB + 1], x - 32, y, at_level(x, y)); + } + } + } + + // clear_offscreen(MG_CLOUD_SB); + clear_offscreen_level(); + + update_player(); + update_ents(); + + oam_copy(oam_mem, _obj_buffer, att_count()); + + switch (_state) + { + case MG_S_STARTING: + if (key_hit(KEY_RIGHT)) + { + _scroll_x = (int)(0.25f * FIX_SCALE); + _state = MG_S_SCROLLING; + } + break; + case MG_S_SCROLLING: + if (frame_count() % X_SCROLL_RATE == 0) + { + _scroll_x += X_SCROLL_GAIN; + //This is better than checking if it's greater prior to adding + //Because it handles the edge case where the gain will put it much + //over the limit + if (_scroll_x > X_SCROLL_MAX) + { + _scroll_x = X_SCROLL_MAX; + } + } + break; + case MG_S_PAUSED: + //This should never be hit fuck + break; + } +} + +static void hide(void) +{ + REG_DISPCNT = 0; + dma3_fill(se_mem[MG_CLOUD_SB], 0x0, SB_SIZE); + dma3_fill(se_mem[MG_CLOUD_SB + 1], 0x0, SB_SIZE); + + clear_score(); + unload_gun_0_tiles(); + unload_player(); +} + +const scene_t main_game = { + .show = show, + .update = update, + .hide = hide}; diff --git a/source/scenes/main_game.h b/source/scenes/main_game.h index b2f6abe..98c4418 100644 --- a/source/scenes/main_game.h +++ b/source/scenes/main_game.h @@ -2,7 +2,7 @@ #define MAIN_GAME_H #define MG_SHARED_CB 0 -#define MG_BACKGROUND_SB 30 +#define MG_CITY_SB 30 #define MG_CLOUD_SB 24 #define MG_BUILDING_SB 26 @@ -11,8 +11,11 @@ #define MG_BG_X 64 #define MG_BG_X_PIX (int)(MG_BG_X * 8 * (FIX_SCALE)) -typedef enum mg_states_t { - MG_S_STARTING, MG_S_SCROLLING, MG_S_PAUSED +typedef enum mg_states_t +{ + MG_S_STARTING, + MG_S_SCROLLING, + MG_S_PAUSED } mg_states_t; #endif \ No newline at end of file