Implement trading animation

This commit is contained in:
Lorenzooone 2023-02-16 02:08:49 +01:00
parent f0802eabc7
commit cbc1b9d92c
16 changed files with 288 additions and 48 deletions

2
.gitignore vendored
View File

@ -1,7 +1,9 @@
build/
*.elf
*.gba
*.GBA
*.sav
*.SAV
*.py
settings.sh
__pycache__/

View File

@ -0,0 +1,8 @@
#ifndef ANIMATIONS_HANDLER__
#define ANIMATIONS_HANDLER__
void setup_trade_animation(struct gen3_mon_data_unenc*, struct gen3_mon_data_unenc*, u8, u8);
void advance_trade_animation(void);
u8 get_trade_animation_state(void);
#endif

View File

@ -3,6 +3,13 @@
#include <stddef.h>
#define NUM_POKEMON_SPRITES 2
#define POKEMON_SPRITE_X_TILES 4
#define POKEMON_SPRITE_Y_TILES 4
#define ITEM_SPRITE_X_TILES 1
#define ITEM_SPRITE_Y_TILES 1
void load_pokemon_sprite_gfx(const u32*, u32*, u8, u8, u8, u8*);
void convert_xbpp(u8*, u32*, size_t, u8*, u8, u8);

View File

@ -8,6 +8,8 @@
void print_game_info(struct game_data_t*, int);
void print_trade_menu(struct game_data_t*, u8, u8, u8, u8);
void print_trade_menu_cancel(u8);
void print_trade_animation_send(struct gen3_mon_data_unenc*);
void print_trade_animation_recv(struct gen3_mon_data_unenc*);
void print_set_nature(u8, struct gen3_mon_data_unenc*);
void print_iv_fix(struct gen3_mon_data_unenc*);
void print_pokemon_pages(u8, u8, struct gen3_mon_data_unenc*, u8);

View File

@ -353,7 +353,7 @@ const u8* get_pokeball_base_name_gen3_raw(struct gen3_mon_data_unenc*);
u8 get_trainer_gender_char_raw(struct gen3_mon_data_unenc*);
u8 is_egg_gen3_raw(struct gen3_mon_data_unenc*);
u8 has_pokerus_gen3_raw(struct gen3_mon_data_unenc*);
void load_pokemon_sprite_raw(struct gen3_mon_data_unenc*, u16, u16);
void load_pokemon_sprite_raw(struct gen3_mon_data_unenc*, u8, u16, u16);
u8 get_pokemon_gender_raw(struct gen3_mon_data_unenc*);
char get_pokemon_gender_char_raw(struct gen3_mon_data_unenc*);
u8 is_shiny_gen3_raw(struct gen3_mon_data_unenc*, u32);

View File

@ -9,6 +9,8 @@
#define X_SIZE (SCREEN_REAL_WIDTH>>3)
#define Y_SIZE (SCREEN_REAL_HEIGHT>>3)
#define SCREEN_HALF_X (X_LIMIT>>1)
#define PALETTE 0xF
#define HSWAP_TILE 0x400
@ -35,6 +37,7 @@ void default_reset_screen(void);
void reset_screen(u8);
void set_text_x(u8);
void set_text_y(u8);
void swap_screen_enabled_state(u8);
void enable_screen(u8);
void disable_screen(u8);
void disable_all_screens_but_current(void);

View File

@ -1,26 +1,38 @@
#ifndef SPRITE_HANDLER__
#define SPRITE_HANDLER__
#include "print_system.h"
#include "graphics_handler.h"
#define TOP_SCREEN_SPRITE_POS SCREEN_REAL_HEIGHT
#define LEFT_SCREEN_SPRITE_POS SCREEN_REAL_WIDTH
#define BASE_Y_SPRITE_INFO_PAGE 0
#define BASE_X_SPRITE_INFO_PAGE 0
#define BASE_Y_SPRITE_NATURE_PAGE 248
#define BASE_Y_SPRITE_TRADE_ANIMATION_SEND ((SCREEN_HEIGHT>>1)-((POKEMON_SPRITE_Y_TILES<<3)>>1))
#define BASE_X_SPRITE_TRADE_ANIMATION ((SCREEN_WIDTH>>1)-((POKEMON_SPRITE_X_TILES<<3)>>1))
#define BASE_Y_SPRITE_TRADE_ANIMATION_RECV (TOP_SCREEN_SPRITE_POS-(POKEMON_SPRITE_Y_TILES<<3))
#define BASE_Y_SPRITE_TRADE_ANIMATION_END_RUN_INC (TOP_SCREEN_SPRITE_POS-BASE_Y_SPRITE_TRADE_ANIMATION_RECV)
#define BASE_Y_SPRITE_NATURE_PAGE (TOP_SCREEN_SPRITE_POS-8)
#define BASE_X_SPRITE_NATURE_PAGE 0
#define BASE_Y_SPRITE_IV_FIX_PAGE 248
#define BASE_Y_SPRITE_IV_FIX_PAGE (TOP_SCREEN_SPRITE_POS-8)
#define BASE_X_SPRITE_IV_FIX_PAGE 0
#define X_OFFSET_TRADE_MENU 0
#define Y_OFFSET_TRADE_MENU -3
#define Y_OFFSET_TRADE_MENU_SPRITES (Y_OFFSET_TRADE_MENU + 2)
#define BASE_Y_CURSOR_TRADING_MENU (16 - Y_OFFSET_TRADE_MENU_SPRITES + 1)
#define BASE_X_CURSOR_TRADING_MENU (1 - X_OFFSET_TRADE_MENU)
#define BASE_Y_CURSOR_INCREMENT_TRADING_MENU 24
#define BASE_X_CURSOR_INCREMENT_TRADING_MENU 120
#define BASE_Y_SPRITE_TRADE_MENU (0 - Y_OFFSET_TRADE_MENU_SPRITES)
#define BASE_Y_SPRITE_INCREMENT_TRADE_MENU 24
#define BASE_Y_SPRITE_INCREMENT_TRADE_MENU (3*8)
#define BASE_X_SPRITE_TRADE_MENU (8 - X_OFFSET_TRADE_MENU)
#define CURSOR_Y_POS_CANCEL 152
#define BASE_X_SPRITE_INCREMENT_TRADE_MENU (SCREEN_HALF_X << 3)
#define BASE_Y_CURSOR_TRADING_MENU (16 + BASE_Y_SPRITE_TRADE_MENU + 1)
#define BASE_X_CURSOR_TRADING_MENU (1 - X_OFFSET_TRADE_MENU)
#define BASE_Y_CURSOR_INCREMENT_TRADING_MENU BASE_Y_SPRITE_INCREMENT_TRADE_MENU
#define BASE_X_CURSOR_INCREMENT_TRADING_MENU BASE_X_SPRITE_INCREMENT_TRADE_MENU
#define CURSOR_Y_POS_CANCEL (SCREEN_HEIGHT-8)
#define CURSOR_X_POS_CANCEL 2
#define BASE_X_CURSOR_MAIN_MENU 2
@ -28,15 +40,15 @@
#define BASE_Y_CURSOR_INCREMENT_MAIN_MENU 16
#define BASE_X_CURSOR_TRADE_OPTIONS 2
#define BASE_X_CURSOR_INCREMENT_TRADE_OPTIONS 120
#define BASE_Y_CURSOR_TRADE_OPTIONS 152
#define BASE_X_CURSOR_INCREMENT_TRADE_OPTIONS (SCREEN_HALF_X << 3)
#define BASE_Y_CURSOR_TRADE_OPTIONS (SCREEN_HEIGHT-8)
#define BASE_Y_SPRITE_OFFER_MENU 0
#define BASE_X_SPRITE_OFFER_MENU 0
#define BASE_X_CURSOR_OFFER_OPTIONS 10
#define BASE_Y_CURSOR_OFFER_OPTIONS 128
#define BASE_X_CURSOR_INCREMENT_OFFER_OPTIONS 64
#define BASE_Y_CURSOR_INCREMENT_OFFER_OPTIONS 16
#define BASE_X_CURSOR_OFFER_OPTIONS 10
#define BASE_Y_CURSOR_OFFER_OPTIONS (SCREEN_HEIGHT-16-(BASE_Y_CURSOR_INCREMENT_OFFER_OPTIONS*(2-1)))
void init_sprites(void);
void init_sprite_counter(void);
@ -47,10 +59,12 @@ void set_party_sprite_counter(void);
void init_cursor(void);
void update_cursor_y(u16);
void update_cursor_base_x(u16);
void raw_update_sprite_y(u8, u8);
void move_sprites(u8 counter);
void move_cursor_x(u8 counter);
void disable_cursor(void);
void disable_all_cursors(void);
u8 get_next_sprite_index(void);
void reset_sprites(u8);
void disable_all_sprites(void);
void enable_all_sprites(void);

View File

@ -10,6 +10,18 @@
#define TRADE_OPTIONS_WINDOW_X_SIZE TOTAL_X_SIZE
#define TRADE_OPTIONS_WINDOW_Y_SIZE 1
#define TRADE_ANIMATION_SEND_WINDOW_SCREEN 1
#define TRADE_ANIMATION_SEND_WINDOW_X 1
#define TRADE_ANIMATION_SEND_WINDOW_Y_SIZE 3
#define TRADE_ANIMATION_SEND_WINDOW_Y (TOTAL_Y_SIZE-1-TRADE_ANIMATION_SEND_WINDOW_Y_SIZE)
#define TRADE_ANIMATION_SEND_WINDOW_X_SIZE (TOTAL_X_SIZE-TRADE_ANIMATION_SEND_WINDOW_X-1)
#define TRADE_ANIMATION_RECV_WINDOW_SCREEN 2
#define TRADE_ANIMATION_RECV_WINDOW_X 1
#define TRADE_ANIMATION_RECV_WINDOW_Y_SIZE 3
#define TRADE_ANIMATION_RECV_WINDOW_Y (TOTAL_Y_SIZE-1-TRADE_ANIMATION_RECV_WINDOW_Y_SIZE)
#define TRADE_ANIMATION_RECV_WINDOW_X_SIZE (TOTAL_X_SIZE-TRADE_ANIMATION_RECV_WINDOW_X-1)
#define WAITING_WINDOW_SCREEN 3
#define WAITING_WINDOW_X_SIZE 10
#define WAITING_WINDOW_Y_SIZE 1
@ -55,6 +67,12 @@ void clear_offer_options_window(void);
void init_waiting_window(void);
void clear_waiting_window(void);
void init_trade_animation_send_window(void);
void clear_trade_animation_send_window(void);
void init_trade_animation_recv_window(void);
void clear_trade_animation_recv_window(void);
void init_saving_window(void);
void clear_saving_window(void);

View File

@ -0,0 +1,83 @@
#include <gba.h>
#include "party_handler.h"
#include "sprite_handler.h"
#include "animations_handler.h"
#include "graphics_handler.h"
#include <stddef.h>
#define OWN_SPRITE_INDEX 0
#define OTHER_SPRITE_INDEX 1
#define EVOLUTION_SPRITE_INDEX 0
#define TOTAL_SPRITES 2
#define FIRST_SPEEDUP_THRESHOLD (BASE_Y_SPRITE_TRADE_ANIMATION_SEND+BASE_Y_SPRITE_TRADE_ANIMATION_END_RUN_INC-8)
#define SECOND_SPEEDUP_THRESHOLD (FIRST_SPEEDUP_THRESHOLD-16)
#define THIRD_SPEEDUP_THRESHOLD (SECOND_SPEEDUP_THRESHOLD-32)
u8 sprite_indexes[TOTAL_SPRITES];
u8 sprite_ys[TOTAL_SPRITES];
u8 screen_nums[TOTAL_SPRITES];
u8 trade_animation_counter;
u8 trade_animation_completed;
void setup_trade_animation(struct gen3_mon_data_unenc* own_mon, struct gen3_mon_data_unenc* other_mon, u8 own_screen, u8 other_screen) {
sprite_indexes[OWN_SPRITE_INDEX] = get_next_sprite_index();
sprite_ys[OWN_SPRITE_INDEX] = BASE_Y_SPRITE_TRADE_ANIMATION_SEND;
screen_nums[OWN_SPRITE_INDEX] = own_screen;
load_pokemon_sprite_raw(own_mon, 0, BASE_Y_SPRITE_TRADE_ANIMATION_SEND, BASE_X_SPRITE_TRADE_ANIMATION);
sprite_indexes[OTHER_SPRITE_INDEX] = get_next_sprite_index();
sprite_ys[OTHER_SPRITE_INDEX] = BASE_Y_SPRITE_TRADE_ANIMATION_RECV;
screen_nums[OTHER_SPRITE_INDEX] = other_screen;
load_pokemon_sprite_raw(other_mon, 0, BASE_Y_SPRITE_TRADE_ANIMATION_RECV, BASE_X_SPRITE_TRADE_ANIMATION);
trade_animation_counter = 0;
trade_animation_completed = 0;
}
u8 get_trade_animation_state() {
return trade_animation_completed;
}
void advance_trade_animation() {
u8 index = OWN_SPRITE_INDEX;
s32 inc_type = -1;
if(sprite_ys[OWN_SPRITE_INDEX] == BASE_Y_SPRITE_TRADE_ANIMATION_RECV) {
index = OTHER_SPRITE_INDEX;
inc_type = +1;
}
if(trade_animation_completed)
return;
u8 curr_y = sprite_ys[index] + BASE_Y_SPRITE_TRADE_ANIMATION_END_RUN_INC;
u8 scheduled_change = 0;
trade_animation_counter++;
if(curr_y < THIRD_SPEEDUP_THRESHOLD)
scheduled_change = 1;
else if(curr_y < SECOND_SPEEDUP_THRESHOLD) {
if(trade_animation_counter == 2)
scheduled_change = 1;
}
else if(curr_y < FIRST_SPEEDUP_THRESHOLD) {
if(trade_animation_counter == 4)
scheduled_change = 1;
}
else {
if(trade_animation_counter == 8)
scheduled_change = 1;
}
if((scheduled_change) && (curr_y == THIRD_SPEEDUP_THRESHOLD)) {
swap_screen_enabled_state(screen_nums[index]);
prepare_flush();
}
if(scheduled_change) {
sprite_ys[index] += inc_type;
trade_animation_counter = 0;
raw_update_sprite_y(sprite_indexes[index], sprite_ys[index]);
}
if(sprite_ys[OTHER_SPRITE_INDEX] == BASE_Y_SPRITE_TRADE_ANIMATION_SEND)
trade_animation_completed = 1;
}

View File

@ -4,10 +4,6 @@
#include "print_system.h"
#include <stddef.h>
#define NUM_POKEMON_SPRITES 2
#define POKEMON_SPRITE_X_TILES 4
#define POKEMON_SPRITE_Y_TILES 4
#define POKEMON_SPRITE_ROW_SIZE (TILE_SIZE*POKEMON_SPRITE_X_TILES)
#define SINGLE_POKEMON_SPRITE_SIZE (POKEMON_SPRITE_ROW_SIZE*POKEMON_SPRITE_Y_TILES)
#define TOTAL_POKEMON_SPRITE_SIZE (SINGLE_POKEMON_SPRITE_SIZE*NUM_POKEMON_SPRITES)

View File

@ -18,6 +18,7 @@
#include "gen_converter.h"
#include "sio.h"
#include "vcount_basic.h"
#include "animations_handler.h"
#include <stddef.h>
//#include "save.h"
@ -47,6 +48,7 @@ void change_nature(struct game_data_t*, u8, u8, u8*, u8);
void check_bad_trade_received(struct game_data_t*, u8, u8, u8, u8, u8, u8*);
void trade_cancel_print_screen(u8);
void saving_print_screen(void);
void trading_animation_init(struct game_data_t*, u8, u8);
void offer_init(struct game_data_t*, u8, u8, u8*, u8*, u8);
void waiting_init(void);
void invalid_init(u8);
@ -77,6 +79,10 @@ IWRAM_CODE void vblank_update_function() {
move_cursor_x(counter);
advance_rng();
counter++;
// Handle trading animation
if(curr_state == TRADING_ANIMATION)
advance_trade_animation();
// Handle slave communications
if((REG_SIOCNT & SIO_IRQ) && (!(REG_SIOCNT & SIO_START)))
slave_routine();
@ -210,6 +216,25 @@ void saving_print_screen() {
prepare_flush();
}
void trading_animation_init(struct game_data_t* game_data, u8 own_mon, u8 other_mon) {
set_screen(BASE_SCREEN);
reset_sprites_to_party();
disable_all_screens_but_current();
disable_all_cursors();
disable_all_sprites();
default_reset_screen();
set_screen(TRADE_ANIMATION_SEND_WINDOW_SCREEN);
print_trade_animation_send(&game_data[0].party_3_undec[own_mon]);
set_screen(TRADE_ANIMATION_RECV_WINDOW_SCREEN);
print_trade_animation_recv(&game_data[1].party_3_undec[other_mon]);
set_screen(BASE_SCREEN);
enable_screen(BASE_SCREEN);
enable_screen(TRADE_ANIMATION_SEND_WINDOW_SCREEN);
setup_trade_animation(&game_data[0].party_3_undec[own_mon], &game_data[1].party_3_undec[other_mon], TRADE_ANIMATION_SEND_WINDOW_SCREEN, TRADE_ANIMATION_RECV_WINDOW_SCREEN);
prepare_flush();
curr_state = TRADING_ANIMATION;
}
void offer_init(struct game_data_t* game_data, u8 own_mon, u8 other_mon, u8* cursor_y_pos, u8* cursor_x_pos, u8 reset) {
curr_state = OFFER_MENU;
set_screen(BASE_SCREEN);
@ -421,13 +446,14 @@ int main(void)
u8 submenu_cursor_x_pos = 0;
u8 prev_val = 0;
u8 curr_mon = 0;
u8 success = 0;
u8 other_mon = 0;
u8 curr_page = 0;
const u8* party_selected_mons[2] = {&curr_mon, &other_mon};
main_menu_init(&game_data[0], target, region, master, &cursor_y_pos);
//load_pokemon_sprite_raw(&game_data[1].party_3_undec[0], 0, 0);
//load_pokemon_sprite_raw(&game_data[1].party_3_undec[0], 1, 0, 0);
//worst_case_conversion_tester(&counter);
//PRINT_FUNCTION("\n\n0x\x0D: 0x\x0D\n", REG_MEMORY_CONTROLLER_ADDR, 8, REG_MEMORY_CONTROLLER, 8);
scanKeys();
@ -475,9 +501,10 @@ int main(void)
else if(get_trading_state() == RECEIVED_ACCEPT) {
keys = 0;
if(has_accepted_offer()) {
trading_animation_init(game_data, curr_mon, other_mon);
evolved = trade_mons(game_data, curr_mon, other_mon, learnset_ptr, curr_gen);
success = pre_write_gen_3_data(&game_data[0]);
process_party_data(&game_data[0]);
curr_state = TRADING_ANIMATION;
}
else
return_to_trade_menu(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos);
@ -610,7 +637,7 @@ int main(void)
set_default_gift_ribbons(&game_data[cursor_x_pos]);
if(!cursor_x_pos) {
saving_print_screen();
u8 success = pre_write_gen_3_data(&game_data[0]);
success = pre_write_gen_3_data(&game_data[0]);
if(success)
success = complete_write_gen_3_data();
if(!success) {
@ -636,6 +663,8 @@ int main(void)
else
cursor_update_offer_options(submenu_cursor_y_pos, submenu_cursor_x_pos);
break;
case TRADING_ANIMATION:
break;
default:
main_menu_init(&game_data[0], target, region, master, &cursor_y_pos);
break;

View File

@ -89,7 +89,7 @@ void print_trade_menu(struct game_data_t* game_data, u8 update, u8 curr_gen, u8
PRINT_FUNCTION("\x05 - Gen \x03\n", game_data[0].trainer_name, OT_NAME_GEN3_SIZE+1, game_data[0].game_identifier.game_is_jp, curr_gen);
else {
for(int i = 0; i < num_parties; i++) {
set_text_x((X_LIMIT>>1) * i);
set_text_x(SCREEN_HALF_X * i);
PRINT_FUNCTION("\x05 - \x01", game_data[i].trainer_name, OT_NAME_GEN3_SIZE+1, game_data[i].game_identifier.game_is_jp, person_strings[i]);
}
}
@ -104,7 +104,7 @@ void print_trade_menu(struct game_data_t* game_data, u8 update, u8 curr_gen, u8
set_text_y(2+(3 * i));
for(int j = 0; j < num_parties; j++) {
// These two values are for debug only - They should be j and i
set_text_x(5 + ((X_LIMIT>>1) * j));
set_text_x(5 + (SCREEN_HALF_X * j));
u8 party_index = j;
u8 party_option_index = i;
if(options[party_index][party_option_index] != 0xFF) {
@ -112,7 +112,7 @@ void print_trade_menu(struct game_data_t* game_data, u8 update, u8 curr_gen, u8
// I tried just using printf here with left padding, but it's EXTREMELY slow
PRINT_FUNCTION("\x01", get_pokemon_name_raw(mon));
if(load_sprites)
load_pokemon_sprite_raw(mon, BASE_Y_SPRITE_TRADE_MENU + (i*BASE_Y_SPRITE_INCREMENT_TRADE_MENU), (((X_LIMIT >> 1) << 3)*j) + BASE_X_SPRITE_TRADE_MENU);
load_pokemon_sprite_raw(mon, 1, BASE_Y_SPRITE_TRADE_MENU + (i*BASE_Y_SPRITE_INCREMENT_TRADE_MENU), (BASE_X_SPRITE_INCREMENT_TRADE_MENU*j) + BASE_X_SPRITE_TRADE_MENU);
}
}
}
@ -146,7 +146,7 @@ void print_offer_screen(struct game_data_t* game_data, u8 own_mon, u8 other_mon)
set_text_y(curr_text_y++);
set_text_x(3+(OFFER_WINDOW_X*i));
PRINT_FUNCTION("\x01", offer_strings[i]);
load_pokemon_sprite_raw(mon, BASE_Y_SPRITE_OFFER_MENU, (OFFER_WINDOW_X*8*i) + BASE_X_SPRITE_OFFER_MENU);
load_pokemon_sprite_raw(mon, 1, BASE_Y_SPRITE_OFFER_MENU, (OFFER_WINDOW_X*8*i) + BASE_X_SPRITE_OFFER_MENU);
if(!is_egg) {
set_text_y(curr_text_y++);
@ -254,6 +254,48 @@ void print_waiting(){
PRINT_FUNCTION("Waiting...");
}
void print_trade_animation_send(struct gen3_mon_data_unenc* mon){
u8 is_jp = mon->src->language == JAPANESE_LANGUAGE;
u8 is_egg = mon->is_egg;
reset_screen(BLANK_FILL);
init_trade_animation_send_window();
clear_trade_animation_send_window();
set_text_y(TRADE_ANIMATION_SEND_WINDOW_Y);
set_text_x(TRADE_ANIMATION_SEND_WINDOW_X);
if(!is_egg) {
PRINT_FUNCTION("Sending \x01 away...\n\n", get_pokemon_name_raw(mon));
set_text_x(TRADE_ANIMATION_SEND_WINDOW_X);
PRINT_FUNCTION("Goodbye, \x05!", mon->src->nickname, NICKNAME_GEN3_SIZE, is_jp);
}
else {
PRINT_FUNCTION("Sending an Egg away...\n\n");
set_text_x(TRADE_ANIMATION_SEND_WINDOW_X);
PRINT_FUNCTION("Who knows what's inside...");
}
}
void print_trade_animation_recv(struct gen3_mon_data_unenc* mon){
u8 is_jp = mon->src->language == JAPANESE_LANGUAGE;
u8 is_egg = mon->is_egg;
reset_screen(BLANK_FILL);
init_trade_animation_recv_window();
clear_trade_animation_recv_window();
set_text_y(TRADE_ANIMATION_RECV_WINDOW_Y);
set_text_x(TRADE_ANIMATION_RECV_WINDOW_X);
if(!is_egg) {
PRINT_FUNCTION("Received \x01.\n\n", get_pokemon_name_raw(mon));
set_text_x(TRADE_ANIMATION_RECV_WINDOW_X);
PRINT_FUNCTION("Welcome, \x05!", mon->src->nickname, NICKNAME_GEN3_SIZE, is_jp);
}
else {
PRINT_FUNCTION("Received an Egg.\n\n");
set_text_x(TRADE_ANIMATION_SEND_WINDOW_X);
PRINT_FUNCTION("Who knows what's inside!");
}
}
void print_saving(){
reset_screen(BLANK_FILL);
init_saving_window();
@ -360,7 +402,7 @@ void print_pokemon_base_data(u8 load_sprites, struct gen3_mon_data_unenc* mon, u
if(load_sprites) {
reset_sprites_to_party();
load_pokemon_sprite_raw(mon, y, x);
load_pokemon_sprite_raw(mon, 1, y, x);
}
set_text_y((y>>3) + 2);
@ -490,7 +532,7 @@ void print_pokemon_page5(struct gen3_mon_data_unenc* mon) {
set_text_y(6+i);
PRINT_FUNCTION(" \x01\x01", get_ribbon_name(&mon->misc, ribbon_print_pos[(i*2)]), get_ribbon_rank_name(&mon->misc, ribbon_print_pos[(i*2)]));
if(ribbon_print_pos[(i*2)+1] != 0xFF) {
set_text_x(X_LIMIT>>1);
set_text_x(SCREEN_HALF_X);
PRINT_FUNCTION(" \x01\x01", get_ribbon_name(&mon->misc, ribbon_print_pos[(i*2)+1]), get_ribbon_rank_name(&mon->misc, ribbon_print_pos[(i*2)+1]));
}
}

View File

@ -302,11 +302,11 @@ void load_pokemon_sprite(int index, u32 pid, u8 is_egg, u8 deoxys_form, u8 has_i
set_pokemon_sprite(get_pokemon_sprite_pointer(index, pid, is_egg, deoxys_form), get_palette_references(index, pid, is_egg, deoxys_form), get_pokemon_sprite_info(index, pid, is_egg, deoxys_form), has_item, has_mail, y, x);
}
void load_pokemon_sprite_raw(struct gen3_mon_data_unenc* data_src, u16 y, u16 x){
void load_pokemon_sprite_raw(struct gen3_mon_data_unenc* data_src, u8 show_item, u16 y, u16 x){
if(!data_src->is_valid_gen3)
load_pokemon_sprite(0, 0, 0, 0, has_item_raw(data_src), has_mail_raw(data_src), y, x);
load_pokemon_sprite(0, 0, 0, 0, has_item_raw(data_src) & show_item, has_mail_raw(data_src) & show_item, y, x);
load_pokemon_sprite(data_src->growth.species, data_src->src->pid, data_src->is_egg, data_src->deoxys_form, has_item_raw(data_src), has_mail_raw(data_src), y, x);
load_pokemon_sprite(data_src->growth.species, data_src->src->pid, data_src->is_egg, data_src->deoxys_form, has_item_raw(data_src) & show_item, has_mail_raw(data_src) & show_item, y, x);
}
const u8* get_move_name_gen3(struct gen3_mon_attacks* attacks, u8 slot){

View File

@ -186,6 +186,13 @@ void wait_for_vblank_if_needed() {
VBlankIntrWait();
}
void swap_screen_enabled_state(u8 bg_num){
wait_for_vblank_if_needed();
if(bg_num >= TOTAL_BG)
bg_num = TOTAL_BG-1;
enabled_screen[bg_num] ^= 1;
}
void enable_screen(u8 bg_num){
wait_for_vblank_if_needed();
if(bg_num >= TOTAL_BG)

View File

@ -11,13 +11,15 @@
#define CPUFASTSET_FILL (0x1000000)
#define ITEM_ICON_INC_Y 24
#define ITEM_ICON_INC_X 24
#define ITEM_ICON_INC_X ((POKEMON_SPRITE_X_TILES-ITEM_SPRITE_X_TILES)<<3)
#define ITEM_ICON_INC_Y ((POKEMON_SPRITE_Y_TILES-ITEM_SPRITE_Y_TILES)<<3)
#define SPRITE_BASE_TILE_SIZE 0x10
#define SPRITE_BASE_SIZE_MULTIPLIER NUM_POKEMON_SPRITES
#define SPRITE_BASE_TILE_SIZE (POKEMON_SPRITE_Y_TILES*POKEMON_SPRITE_X_TILES)
#define SPRITE_TILE_SIZE (SPRITE_BASE_SIZE_MULTIPLIER*SPRITE_BASE_TILE_SIZE)
#define SPRITE_ALT_DISTANCE (SPRITE_BASE_TILE_SIZE*TILE_SIZE)
#define SPRITE_SIZE (2*SPRITE_ALT_DISTANCE)
#define SPRITE_SIZE (SPRITE_BASE_SIZE_MULTIPLIER*SPRITE_ALT_DISTANCE)
#define OVRAM_START ((uintptr_t)OBJ_BASE_ADR)
#define OVRAM_SIZE 0x8000
#define OVRAM_END (OVRAM_START+OVRAM_SIZE)
@ -110,6 +112,10 @@ void inc_inner_sprite_counter(){
__inner_sprite_counter++;
}
u8 get_next_sprite_index(){
return __inner_sprite_counter;
}
u8 get_first_variable_palette(){
return ((sprite_palettes_bin_size + item_icon_palette_bin_size)>>5);
}
@ -140,14 +146,13 @@ void set_palette_3bpp(u8* colors, int index, int palette) {
void init_cursor(){
sprite_pointers[__sprite_counter] = (const u8*)sprite_cursor_gfx;
u16* vram_pos = (u16*)get_vram_pos();
for(size_t i = 0; i < (sprite_cursor_bin_size>>1); i++)
vram_pos[i] = sprite_cursor_gfx[i];
vram_pos = (u16*)(get_vram_pos() + SPRITE_ALT_DISTANCE);
for(size_t i = 0; i < (sprite_cursor_bin_size>>1); i++)
vram_pos[i] = sprite_cursor_gfx[i];
for(int i = 0; i < SPRITE_BASE_SIZE_MULTIPLIER; i++) {
u16* vram_pos = (u16*)(get_vram_pos() + (SPRITE_ALT_DISTANCE*i));
for(size_t j = 0; j < (sprite_cursor_bin_size>>1); j++)
vram_pos[j] = sprite_cursor_gfx[j];
}
for(int i = 0; i < TOTAL_BG; i++) {
set_attributes(OFF_SCREEN_SPRITE, 0, (32*__sprite_counter) | ((3-i)<<10));
set_attributes(OFF_SCREEN_SPRITE, 0, (SPRITE_TILE_SIZE*__sprite_counter) | ((3-i)<<10));
if(i < TOTAL_BG-1)
inc_inner_sprite_counter();
}
@ -165,16 +170,15 @@ void init_oam_palette(){
}
void init_item_icon(){
u16* vram_pos = (u16*)(get_vram_pos() + sprite_cursor_bin_size);
for(size_t i = 0; i < (item_icon_bin_size>>1); i++)
vram_pos[i] = item_icon_gfx[i];
vram_pos = (u16*)(get_vram_pos() + SPRITE_ALT_DISTANCE + sprite_cursor_bin_size);
for(size_t i = 0; i < (item_icon_bin_size>>1); i++)
vram_pos[i] = item_icon_gfx[i];
for(int i = 0; i < SPRITE_BASE_SIZE_MULTIPLIER; i++) {
u16* vram_pos = (u16*)(get_vram_pos() + sprite_cursor_bin_size + (SPRITE_ALT_DISTANCE*i));
for(size_t j = 0; j < (item_icon_bin_size>>1); j++)
vram_pos[j] = item_icon_gfx[j];
}
}
u16 get_item_icon_tile(){
return (32*cursor_sprite) + (sprite_cursor_bin_size>>5);
return (SPRITE_TILE_SIZE*cursor_sprite) + (sprite_cursor_bin_size>>5);
}
u16 get_mail_icon_tile(){
@ -222,7 +226,7 @@ void set_pokemon_sprite(const u8* address, u8 palette, u8 info, u8 display_item,
palette = get_3bpp_palette(position-(cursor_sprite+1));
if(position < POSSIBLE_SPRITES)
sprite_pointers[position] = address;
set_attributes(y, x|ATTR1_SIZE_32, (32*position)|(get_curr_priority()<<10)|(palette<<12));
set_attributes(y, x|ATTR1_SIZE_32, (SPRITE_TILE_SIZE*position)|(get_curr_priority()<<10)|(palette<<12));
inc_inner_sprite_counter();
}
@ -236,6 +240,15 @@ void raw_update_cursor_x(u16 cursor_x){
shadow_oam[inner_cursor_sprite-get_loaded_priority()].attr1 = cursor_x;
}
void raw_update_sprite_y(u8 index, u8 new_y){
if(index >= OAM_ENTITIES)
index = OAM_ENTITIES-1;
OAM[index].attr0 &= ~0xFF;
OAM[index].attr0 |= new_y;
shadow_oam[index].attr0 &= ~0xFF;
shadow_oam[index].attr0 |= new_y;
}
void update_cursor_base_x(u16 cursor_x){
wait_for_vblank_if_needed();
cursor_base_x = cursor_x;

View File

@ -33,6 +33,22 @@ void clear_waiting_window() {
reset_window(WAITING_WINDOW_X, WAITING_WINDOW_Y, WAITING_WINDOW_X_SIZE, WAITING_WINDOW_Y_SIZE, WAITING_WINDOW_SCREEN);
}
void init_trade_animation_send_window() {
create_window(TRADE_ANIMATION_SEND_WINDOW_X, TRADE_ANIMATION_SEND_WINDOW_Y, TRADE_ANIMATION_SEND_WINDOW_X_SIZE, TRADE_ANIMATION_SEND_WINDOW_Y_SIZE, TRADE_ANIMATION_SEND_WINDOW_SCREEN);
}
void clear_trade_animation_send_window() {
reset_window(TRADE_ANIMATION_SEND_WINDOW_X, TRADE_ANIMATION_SEND_WINDOW_Y, TRADE_ANIMATION_SEND_WINDOW_X_SIZE, TRADE_ANIMATION_SEND_WINDOW_Y_SIZE, TRADE_ANIMATION_SEND_WINDOW_SCREEN);
}
void init_trade_animation_recv_window() {
create_window(TRADE_ANIMATION_RECV_WINDOW_X, TRADE_ANIMATION_RECV_WINDOW_Y, TRADE_ANIMATION_RECV_WINDOW_X_SIZE, TRADE_ANIMATION_RECV_WINDOW_Y_SIZE, TRADE_ANIMATION_RECV_WINDOW_SCREEN);
}
void clear_trade_animation_recv_window() {
reset_window(TRADE_ANIMATION_RECV_WINDOW_X, TRADE_ANIMATION_RECV_WINDOW_Y, TRADE_ANIMATION_RECV_WINDOW_X_SIZE, TRADE_ANIMATION_RECV_WINDOW_Y_SIZE, TRADE_ANIMATION_RECV_WINDOW_SCREEN);
}
void init_saving_window() {
create_window(SAVING_WINDOW_X, SAVING_WINDOW_Y, SAVING_WINDOW_X_SIZE, SAVING_WINDOW_Y_SIZE, SAVING_WINDOW_SCREEN);
}