mirror of
https://github.com/GearsProgress/Poke_Transporter_GB.git
synced 2026-03-21 17:34:42 -05:00
Adding PCCS
This commit is contained in:
parent
ccaf1e28ae
commit
ba1a075701
4
Makefile
4
Makefile
|
|
@ -30,8 +30,8 @@ LIBTONC := $(DEVKITPRO)/libtonc
|
|||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))_mb
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
INCLUDES := include
|
||||
SOURCES := source source/pccs
|
||||
INCLUDES := include include/pccs
|
||||
DATA := data
|
||||
MUSIC := audio
|
||||
GRAPHICS := graphics
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef BACKGROUND_ENGINE_H
|
||||
#define BACKGROUND_ENGINE_H
|
||||
|
||||
#include "sprite_data.h"
|
||||
#include "text_engine.h"
|
||||
#include "global_frame_controller.h"
|
||||
|
||||
void background_frame(int global_frame_count);
|
||||
void create_textbox(int startTileX, int startTileY, int text_space_width, int text_space_height, bool eraseMainBox);
|
||||
void reset_textbox();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include <tonc.h>
|
||||
#include "string.h"
|
||||
#include "button_handler.h"
|
||||
#include "pokemon.h"
|
||||
#include "string_view"
|
||||
#include "pokemon_party.h"
|
||||
#include "button_handler.h"
|
||||
|
|
@ -27,7 +26,7 @@ class Box_Menu
|
|||
{
|
||||
public:
|
||||
Box_Menu();
|
||||
int box_main(Pokemon_Party party_data);
|
||||
int box_main(PokeBox* box);
|
||||
private:
|
||||
int curr_button;
|
||||
int x;
|
||||
|
|
|
|||
|
|
@ -2,19 +2,19 @@
|
|||
#define DEBUG_MODE_H
|
||||
|
||||
#define VERSION "v1.2.0b"
|
||||
#define PTGB_BUILD_LANGUAGE ENG_ID
|
||||
#define PTGB_BUILD_LANGUAGE 2
|
||||
|
||||
#define DEBUG_MODE true
|
||||
|
||||
#define PRINT_LINK_DATA (false && DEBUG_MODE) // This is currently broken... not sure why
|
||||
#define PRINT_LINK_DATA (true && DEBUG_MODE)
|
||||
#define INSTANT_TEXT_SPEED (false && DEBUG_MODE)
|
||||
#define IGNORE_GAME_PAK (false && DEBUG_MODE)
|
||||
#define IGNORE_GAME_PAK_SPRITES (false && DEBUG_MODE)
|
||||
#define IGNORE_GAME_PAK (true && DEBUG_MODE)
|
||||
#define IGNORE_GAME_PAK_SPRITES (true && DEBUG_MODE)
|
||||
#define IGNORE_LINK_CABLE (true && DEBUG_MODE)
|
||||
#define IGNORE_MG_E4_FLAGS (true && DEBUG_MODE)
|
||||
#define IGNORE_UNRECEIVED_PKMN (true && DEBUG_MODE)
|
||||
#define FORCE_TUTORIAL (false && DEBUG_MODE)
|
||||
#define DONT_REMOVE_PKMN (true && DEBUG_MODE)
|
||||
#define DONT_REMOVE_PKMN (false && DEBUG_MODE)
|
||||
#define DONT_HIDE_INVALID_PKMN (false && DEBUG_MODE)
|
||||
#define IGNORE_DEX_COMPLETION (false && DEBUG_MODE)
|
||||
#define FORCE_ALL_CAUGHT (false && DEBUG_MODE)
|
||||
|
|
@ -28,7 +28,6 @@
|
|||
#define DEBUG_LANG LANG_ENG
|
||||
|
||||
#define ENABLE_MATCH_PID true
|
||||
#define ENABLE_OLD_EVENT false
|
||||
#define ENABLE_DEBUG_SCREEN true
|
||||
|
||||
#define USE_CUSTOM_MALLOC 1
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef MIRROR_H
|
||||
#define MIRROR_H
|
||||
#include <tonc.h>
|
||||
#include "pokemon.h"
|
||||
#include "rom_data.h"
|
||||
|
||||
#define SAVE_A_OFFSET 0x00000000 // Offset of Game Save A
|
||||
|
|
@ -14,7 +13,7 @@ extern vu32 newest_save_offset;
|
|||
extern vu32 memory_section_array[];
|
||||
extern char mem_name;
|
||||
extern u8 global_memory_buffer[0x1000];
|
||||
extern rom_data curr_rom;
|
||||
extern rom_data curr_GBA_rom;
|
||||
|
||||
void initalize_memory_locations();
|
||||
void print_mem_section();
|
||||
|
|
|
|||
|
|
@ -31,10 +31,10 @@
|
|||
#define SLOW_SPEED 1000
|
||||
|
||||
void setup(const u16 *debug_charset);
|
||||
byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, Simplified_Pokemon *curr_simple_array, const u16 *debug_charset, bool cancel_connection);
|
||||
int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_rom, Simplified_Pokemon *curr_simple_array, const u16 *debug_charset, bool cancel_connection);
|
||||
byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBox* box, const u16 *debug_charset, bool cancel_connection);
|
||||
int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_rom, PokeBox* box, const u16 *debug_charset, bool cancel_connection);
|
||||
byte exchange_parties(byte curr_in, byte *curr_payload);
|
||||
byte exchange_boxes(byte curr_in, byte *party_data, GB_ROM *curr_gb_rom);
|
||||
byte exchange_remove_array(byte curr_in, Simplified_Pokemon *curr_simple_array, bool cancel_connection);
|
||||
byte exchange_remove_array(byte curr_in, PokeBox* box, bool cancel_connection);
|
||||
|
||||
#endif /* GAMEBOY_COLOUR_H_ */
|
||||
|
|
|
|||
|
|
@ -1,10 +1,24 @@
|
|||
#ifndef GLOBAL_FRAME_CONTROLLER_H
|
||||
#define GLOBAL_FRAME_CONTROLLER_H
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#define STATE_CONNECTION 1
|
||||
#define STATE_TRANSFER 2
|
||||
#define STATE_NO_ANIM 3
|
||||
|
||||
// TODO: This is kinda a silly spot for this
|
||||
// make sure outBuffer is large enough! Should be at least hex_len + 1
|
||||
template <typename I>
|
||||
void n2hexstr(char *outBuffer, I w, size_t hex_len = sizeof(I) << 1)
|
||||
{
|
||||
static const char *digits = "0123456789ABCDEF";
|
||||
memset(outBuffer, '0', hex_len);
|
||||
outBuffer[hex_len] = '\0'; // we must make sure to terminate the string
|
||||
|
||||
for (size_t i = 0, j = (hex_len - 1) * 4; i < hex_len; ++i, j -= 4)
|
||||
outBuffer[i] = digits[(w >> j) & 0x0f];
|
||||
}
|
||||
void global_next_frame();
|
||||
int get_frame_count();
|
||||
void set_menu_sprite_pal(int frame);
|
||||
|
|
@ -15,7 +29,7 @@ void set_missingno(bool val);
|
|||
bool get_missingno_enabled();
|
||||
void set_treecko(bool val);
|
||||
bool get_treecko_enabled();
|
||||
u32 fnv1a_hash(unsigned char* data, size_t length);
|
||||
u32 fnv1a_hash(unsigned char *data, size_t length);
|
||||
int get_string_length(const byte *str);
|
||||
void convert_int_to_ptgb_str(int val, byte str[]);
|
||||
void convert_int_to_ptgb_str(int val, byte str[], int min_length);
|
||||
|
|
|
|||
|
|
@ -55,199 +55,199 @@
|
|||
#define rlist_r7 0b010000001
|
||||
#define rlist_lr 0b100000000
|
||||
|
||||
#define MOVEMENT_ACTION_FACE_DOWN curr_rom.is_hoenn() ? 0x0 : 0x0
|
||||
#define MOVEMENT_ACTION_FACE_UP curr_rom.is_hoenn() ? 0x1 : 0x1
|
||||
#define MOVEMENT_ACTION_FACE_LEFT curr_rom.is_hoenn() ? 0x2 : 0x2
|
||||
#define MOVEMENT_ACTION_FACE_RIGHT curr_rom.is_hoenn() ? 0x3 : 0x3
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_DOWN curr_rom.is_hoenn() ? 0x4 : 0xC
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_UP curr_rom.is_hoenn() ? 0x5 : 0xD
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_LEFT curr_rom.is_hoenn() ? 0x6 : 0xE
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_RIGHT curr_rom.is_hoenn() ? 0x7 : 0xF
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_DOWN curr_rom.is_hoenn() ? 0x8 : 0x10
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_UP curr_rom.is_hoenn() ? 0x9 : 0x11
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_LEFT curr_rom.is_hoenn() ? 0xA : 0x12
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_RIGHT curr_rom.is_hoenn() ? 0xB : 0x13
|
||||
#define MOVEMENT_ACTION_JUMP_2_DOWN curr_rom.is_hoenn() ? 0xC : 0x14
|
||||
#define MOVEMENT_ACTION_JUMP_2_UP curr_rom.is_hoenn() ? 0xD : 0x15
|
||||
#define MOVEMENT_ACTION_JUMP_2_LEFT curr_rom.is_hoenn() ? 0xE : 0x16
|
||||
#define MOVEMENT_ACTION_JUMP_2_RIGHT curr_rom.is_hoenn() ? 0xF : 0x17
|
||||
#define MOVEMENT_ACTION_DELAY_1 curr_rom.is_hoenn() ? 0x10 : 0x18
|
||||
#define MOVEMENT_ACTION_DELAY_2 curr_rom.is_hoenn() ? 0x11 : 0x19
|
||||
#define MOVEMENT_ACTION_DELAY_4 curr_rom.is_hoenn() ? 0x12 : 0x1A
|
||||
#define MOVEMENT_ACTION_DELAY_8 curr_rom.is_hoenn() ? 0x13 : 0x1B
|
||||
#define MOVEMENT_ACTION_DELAY_16 curr_rom.is_hoenn() ? 0x14 : 0x1C
|
||||
#define MOVEMENT_ACTION_WALK_FAST_DOWN curr_rom.is_hoenn() ? 0x15 : 0x1D
|
||||
#define MOVEMENT_ACTION_WALK_FAST_UP curr_rom.is_hoenn() ? 0x16 : 0x1E
|
||||
#define MOVEMENT_ACTION_WALK_FAST_LEFT curr_rom.is_hoenn() ? 0x17 : 0x1F
|
||||
#define MOVEMENT_ACTION_WALK_FAST_RIGHT curr_rom.is_hoenn() ? 0x18 : 0x20
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_DOWN curr_rom.is_hoenn() ? 0x19 : 0x21
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_UP curr_rom.is_hoenn() ? 0x1A : 0x22
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_LEFT curr_rom.is_hoenn() ? 0x1B : 0x23
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_RIGHT curr_rom.is_hoenn() ? 0x1C : 0x24
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_DOWN curr_rom.is_hoenn() ? 0x1D : 0x25
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_UP curr_rom.is_hoenn() ? 0x1E : 0x26
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_LEFT curr_rom.is_hoenn() ? 0x1F : 0x27
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_RIGHT curr_rom.is_hoenn() ? 0x20 : 0x28
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_DOWN curr_rom.is_hoenn() ? 0x21 : 0x29
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_UP curr_rom.is_hoenn() ? 0x22 : 0x2A
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_LEFT curr_rom.is_hoenn() ? 0x23 : 0x2B
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_RIGHT curr_rom.is_hoenn() ? 0x24 : 0x2C
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_DOWN curr_rom.is_hoenn() ? 0x25 : 0x2D
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_UP curr_rom.is_hoenn() ? 0x26 : 0x2E
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_LEFT curr_rom.is_hoenn() ? 0x27 : 0x2F
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_RIGHT curr_rom.is_hoenn() ? 0x28 : 0x30
|
||||
#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN curr_rom.is_hoenn() ? 0x29 : 0x31
|
||||
#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP curr_rom.is_hoenn() ? 0x2A : 0x32
|
||||
#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_LEFT curr_rom.is_hoenn() ? 0x2B : 0x33
|
||||
#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_RIGHT curr_rom.is_hoenn() ? 0x2C : 0x34
|
||||
#define MOVEMENT_ACTION_WALK_FASTER_DOWN curr_rom.is_hoenn() ? 0x2D : 0x35
|
||||
#define MOVEMENT_ACTION_WALK_FASTER_UP curr_rom.is_hoenn() ? 0x2E : 0x36
|
||||
#define MOVEMENT_ACTION_WALK_FASTER_LEFT curr_rom.is_hoenn() ? 0x2F : 0x37
|
||||
#define MOVEMENT_ACTION_WALK_FASTER_RIGHT curr_rom.is_hoenn() ? 0x30 : 0x38
|
||||
#define MOVEMENT_ACTION_SLIDE_DOWN curr_rom.is_hoenn() ? 0x31 : 0x39
|
||||
#define MOVEMENT_ACTION_SLIDE_UP curr_rom.is_hoenn() ? 0x32 : 0x3A
|
||||
#define MOVEMENT_ACTION_SLIDE_LEFT curr_rom.is_hoenn() ? 0x33 : 0x3B
|
||||
#define MOVEMENT_ACTION_SLIDE_RIGHT curr_rom.is_hoenn() ? 0x34 : 0x3C
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_DOWN curr_rom.is_hoenn() ? 0x35 : 0x3D
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_UP curr_rom.is_hoenn() ? 0x36 : 0x3E
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_LEFT curr_rom.is_hoenn() ? 0x37 : 0x3F
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_RIGHT curr_rom.is_hoenn() ? 0x38 : 0x40
|
||||
#define MOVEMENT_ACTION_START_ANIM_IN_DIRECTION curr_rom.is_hoenn() ? 0x39 : 0x45
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_DOWN curr_rom.is_hoenn() ? 0x3A : 0x46
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_UP curr_rom.is_hoenn() ? 0x3B : 0x47
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_LEFT curr_rom.is_hoenn() ? 0x3C : 0x48
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_RIGHT curr_rom.is_hoenn() ? 0x3D : 0x49
|
||||
#define MOVEMENT_ACTION_FACE_PLAYER curr_rom.is_hoenn() ? 0x3E : 0x4A
|
||||
#define MOVEMENT_ACTION_FACE_AWAY_PLAYER curr_rom.is_hoenn() ? 0x3F : 0x4B
|
||||
#define MOVEMENT_ACTION_LOCK_FACING_DIRECTION curr_rom.is_hoenn() ? 0x40 : 0x4C
|
||||
#define MOVEMENT_ACTION_UNLOCK_FACING_DIRECTION curr_rom.is_hoenn() ? 0x41 : 0x4D
|
||||
#define MOVEMENT_ACTION_JUMP_DOWN curr_rom.is_hoenn() ? 0x42 : 0x4E
|
||||
#define MOVEMENT_ACTION_JUMP_UP curr_rom.is_hoenn() ? 0x43 : 0x4F
|
||||
#define MOVEMENT_ACTION_JUMP_LEFT curr_rom.is_hoenn() ? 0x44 : 0x50
|
||||
#define MOVEMENT_ACTION_JUMP_RIGHT curr_rom.is_hoenn() ? 0x45 : 0x51
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_DOWN curr_rom.is_hoenn() ? 0x46 : 0x52
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_UP curr_rom.is_hoenn() ? 0x47 : 0x53
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_LEFT curr_rom.is_hoenn() ? 0x48 : 0x54
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_RIGHT curr_rom.is_hoenn() ? 0x49 : 0x55
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_DOWN_UP curr_rom.is_hoenn() ? 0x4A : 0x56
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_UP_DOWN curr_rom.is_hoenn() ? 0x4B : 0x57
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_LEFT_RIGHT curr_rom.is_hoenn() ? 0x4C : 0x58
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_RIGHT_LEFT curr_rom.is_hoenn() ? 0x4D : 0x59
|
||||
#define MOVEMENT_ACTION_FACE_ORIGINAL_DIRECTION curr_rom.is_hoenn() ? 0x4E : 0x5A
|
||||
#define MOVEMENT_ACTION_NURSE_JOY_BOW_DOWN curr_rom.is_hoenn() ? 0x4F : 0x5B
|
||||
#define MOVEMENT_ACTION_ENABLE_JUMP_LANDING_GROUND_EFFECT curr_rom.is_hoenn() ? 0x50 : 0x5C
|
||||
#define MOVEMENT_ACTION_DISABLE_JUMP_LANDING_GROUND_EFFECT curr_rom.is_hoenn() ? 0x51 : 0x5D
|
||||
#define MOVEMENT_ACTION_DISABLE_ANIMATION curr_rom.is_hoenn() ? 0x52 : 0x5E
|
||||
#define MOVEMENT_ACTION_RESTORE_ANIMATION curr_rom.is_hoenn() ? 0x53 : 0x5F
|
||||
#define MOVEMENT_ACTION_SET_INVISIBLE curr_rom.is_hoenn() ? 0x54 : 0x60
|
||||
#define MOVEMENT_ACTION_SET_VISIBLE curr_rom.is_hoenn() ? 0x55 : 0x61
|
||||
#define MOVEMENT_ACTION_EMOTE_EXCLAMATION_MARK curr_rom.is_hoenn() ? 0x56 : 0x62
|
||||
#define MOVEMENT_ACTION_EMOTE_QUESTION_MARK curr_rom.is_hoenn() ? 0x57 : 0x63
|
||||
#define MOVEMENT_ACTION_EMOTE_HEART curr_rom.is_hoenn() ? 0x58 : 0xFF
|
||||
#define MOVEMENT_ACTION_REVEAL_TRAINER curr_rom.is_hoenn() ? 0x59 : 0x67
|
||||
#define MOVEMENT_ACTION_ROCK_SMASH_BREAK curr_rom.is_hoenn() ? 0x5A : 0x68
|
||||
#define MOVEMENT_ACTION_CUT_TREE curr_rom.is_hoenn() ? 0x5B : 0x69
|
||||
#define MOVEMENT_ACTION_SET_FIXED_PRIORITY curr_rom.is_hoenn() ? 0x5C : 0x6A
|
||||
#define MOVEMENT_ACTION_CLEAR_FIXED_PRIORITY curr_rom.is_hoenn() ? 0x5D : 0x6B
|
||||
#define MOVEMENT_ACTION_INIT_AFFINE_ANIM curr_rom.is_hoenn() ? 0x5E : 0x6C
|
||||
#define MOVEMENT_ACTION_CLEAR_AFFINE_ANIM curr_rom.is_hoenn() ? 0x5F : 0x6D
|
||||
#define MOVEMENT_ACTION_HIDE_REFLECTION curr_rom.is_hoenn() ? 0x60 : 0xFF
|
||||
#define MOVEMENT_ACTION_SHOW_REFLECTION curr_rom.is_hoenn() ? 0x61 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_DOWN_START_AFFINE curr_rom.is_hoenn() ? 0x62 : 0x6E
|
||||
#define MOVEMENT_ACTION_WALK_DOWN_AFFINE curr_rom.is_hoenn() ? 0x63 : 0x6F
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_DOWN curr_rom.is_hoenn() ? 0x64 : 0x70
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_UP curr_rom.is_hoenn() ? 0x65 : 0x71
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_LEFT curr_rom.is_hoenn() ? 0x66 : 0x72
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_RIGHT curr_rom.is_hoenn() ? 0x67 : 0x73
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_DOWN curr_rom.is_hoenn() ? 0x68 : 0x74
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_UP curr_rom.is_hoenn() ? 0x69 : 0x75
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_LEFT curr_rom.is_hoenn() ? 0x6A : 0x76
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_RIGHT curr_rom.is_hoenn() ? 0x6B : 0x77
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_DOWN curr_rom.is_hoenn() ? 0x6C : 0x78
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_UP curr_rom.is_hoenn() ? 0x6D : 0x79
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_LEFT curr_rom.is_hoenn() ? 0x6E : 0x7A
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_RIGHT curr_rom.is_hoenn() ? 0x6F : 0x7B
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_DOWN curr_rom.is_hoenn() ? 0x70 : 0x7C
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_UP curr_rom.is_hoenn() ? 0x71 : 0x7D
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_LEFT curr_rom.is_hoenn() ? 0x72 : 0x7E
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_RIGHT curr_rom.is_hoenn() ? 0x73 : 0x7F
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_DOWN curr_rom.is_hoenn() ? 0x74 : 0x80
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_UP curr_rom.is_hoenn() ? 0x75 : 0x81
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_LEFT curr_rom.is_hoenn() ? 0x76 : 0x82
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_RIGHT curr_rom.is_hoenn() ? 0x77 : 0x83
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_DOWN curr_rom.is_hoenn() ? 0x78 : 0x84
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_UP curr_rom.is_hoenn() ? 0x79 : 0x85
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_LEFT curr_rom.is_hoenn() ? 0x7A : 0x86
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_RIGHT curr_rom.is_hoenn() ? 0x7B : 0x87
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_DOWN curr_rom.is_hoenn() ? 0x7C : 0x88
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_UP curr_rom.is_hoenn() ? 0x7D : 0x89
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_LEFT curr_rom.is_hoenn() ? 0x7E : 0x8A
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_RIGHT curr_rom.is_hoenn() ? 0x7F : 0x8B
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_DOWN curr_rom.is_hoenn() ? 0x80 : 0x8C
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_UP curr_rom.is_hoenn() ? 0x81 : 0x8D
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_LEFT curr_rom.is_hoenn() ? 0x82 : 0x8E
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_RIGHT curr_rom.is_hoenn() ? 0x83 : 0x8F
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_DOWN curr_rom.is_hoenn() ? 0x84 : 0x90
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_UP curr_rom.is_hoenn() ? 0x85 : 0x91
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_LEFT curr_rom.is_hoenn() ? 0x86 : 0x92
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_RIGHT curr_rom.is_hoenn() ? 0x87 : 0x93
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_DOWN curr_rom.is_hoenn() ? 0x88 : 0xFF
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_UP curr_rom.is_hoenn() ? 0x89 : 0xFF
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_LEFT curr_rom.is_hoenn() ? 0x8A : 0xFF
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_RIGHT curr_rom.is_hoenn() ? 0x8B : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_UP_LEFT curr_rom.is_hoenn() ? 0x8C : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_UP_RIGHT curr_rom.is_hoenn() ? 0x8D : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_DOWN_LEFT curr_rom.is_hoenn() ? 0x8E : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_DOWN_RIGHT curr_rom.is_hoenn() ? 0x8F : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_UP_LEFT curr_rom.is_hoenn() ? 0x90 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_UP_RIGHT curr_rom.is_hoenn() ? 0x91 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_DOWN_LEFT curr_rom.is_hoenn() ? 0x92 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_DOWN_RIGHT curr_rom.is_hoenn() ? 0x93 : 0xFF
|
||||
#define MOVEMENT_ACTION_LOCK_ANIM curr_rom.is_hoenn() ? 0x94 : 0xFF
|
||||
#define MOVEMENT_ACTION_UNLOCK_ANIM curr_rom.is_hoenn() ? 0x95 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_LEFT_AFFINE curr_rom.is_hoenn() ? 0x96 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_RIGHT_AFFINE curr_rom.is_hoenn() ? 0x97 : 0xFF
|
||||
#define MOVEMENT_ACTION_LEVITATE curr_rom.is_hoenn() ? 0x98 : 0xFF
|
||||
#define MOVEMENT_ACTION_STOP_LEVITATE curr_rom.is_hoenn() ? 0x99 : 0xFF
|
||||
#define MOVEMENT_ACTION_STOP_LEVITATE_AT_TOP curr_rom.is_hoenn() ? 0x9A : 0xFF
|
||||
#define MOVEMENT_ACTION_FIGURE_8 curr_rom.is_hoenn() ? 0x9B : 0xFF
|
||||
#define MOVEMENT_ACTION_FLY_UP curr_rom.is_hoenn() ? 0x9C : 0xA4
|
||||
#define MOVEMENT_ACTION_FLY_DOWN curr_rom.is_hoenn() ? 0x9D : 0xA5
|
||||
#define MOVEMENT_ACTION_FACE_DOWN_FAST curr_rom.is_hoenn() ? 0xFF : 0x4
|
||||
#define MOVEMENT_ACTION_FACE_UP_FAST curr_rom.is_hoenn() ? 0xFF : 0x5
|
||||
#define MOVEMENT_ACTION_FACE_LEFT_FAST curr_rom.is_hoenn() ? 0xFF : 0x6
|
||||
#define MOVEMENT_ACTION_FACE_RIGHT_FAST curr_rom.is_hoenn() ? 0xFF : 0x7
|
||||
#define MOVEMENT_ACTION_WALK_SLOWER_DOWN curr_rom.is_hoenn() ? 0xFF : 0x8
|
||||
#define MOVEMENT_ACTION_WALK_SLOWER_UP curr_rom.is_hoenn() ? 0xFF : 0x9
|
||||
#define MOVEMENT_ACTION_WALK_SLOWER_LEFT curr_rom.is_hoenn() ? 0xFF : 0xA
|
||||
#define MOVEMENT_ACTION_WALK_SLOWER_RIGHT curr_rom.is_hoenn() ? 0xFF : 0xB
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_DOWN_SLOW curr_rom.is_hoenn() ? 0xFF : 0x41
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_UP_SLOW curr_rom.is_hoenn() ? 0xFF : 0x42
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_LEFT_SLOW curr_rom.is_hoenn() ? 0xFF : 0x43
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_RIGHT_SLOW curr_rom.is_hoenn() ? 0xFF : 0x44
|
||||
#define MOVEMENT_ACTION_EMOTE_X curr_rom.is_hoenn() ? 0xFF : 0x64
|
||||
#define MOVEMENT_ACTION_EMOTE_DOUBLE_EXCL_MARK curr_rom.is_hoenn() ? 0xFF : 0x65
|
||||
#define MOVEMENT_ACTION_EMOTE_SMILE curr_rom.is_hoenn() ? 0xFF : 0x66
|
||||
#define MOVEMENT_ACTION_SPIN_DOWN curr_rom.is_hoenn() ? 0xFF : 0x94
|
||||
#define MOVEMENT_ACTION_SPIN_UP curr_rom.is_hoenn() ? 0xFF : 0x95
|
||||
#define MOVEMENT_ACTION_SPIN_LEFT curr_rom.is_hoenn() ? 0xFF : 0x96
|
||||
#define MOVEMENT_ACTION_SPIN_RIGHT curr_rom.is_hoenn() ? 0xFF : 0x97
|
||||
#define MOVEMENT_ACTION_RAISE_HAND_AND_STOP curr_rom.is_hoenn() ? 0xFF : 0x98
|
||||
#define MOVEMENT_ACTION_RAISE_HAND_AND_JUMP curr_rom.is_hoenn() ? 0xFF : 0x99
|
||||
#define MOVEMENT_ACTION_RAISE_HAND_AND_SWIM curr_rom.is_hoenn() ? 0xFF : 0x9A
|
||||
#define MOVEMENT_ACTION_WALK_SLOWEST_DOWN curr_rom.is_hoenn() ? 0xFF : 0x9B
|
||||
#define MOVEMENT_ACTION_WALK_SLOWEST_UP curr_rom.is_hoenn() ? 0xFF : 0x9C
|
||||
#define MOVEMENT_ACTION_WALK_SLOWEST_LEFT curr_rom.is_hoenn() ? 0xFF : 0x9D
|
||||
#define MOVEMENT_ACTION_WALK_SLOWEST_RIGHT curr_rom.is_hoenn() ? 0xFF : 0x9E
|
||||
#define MOVEMENT_ACTION_SHAKE_HEAD_OR_WALK_IN_PLACE curr_rom.is_hoenn() ? 0xFF : 0x9F
|
||||
#define MOVEMENT_ACTION_GLIDE_DOWN curr_rom.is_hoenn() ? 0xFF : 0xA0
|
||||
#define MOVEMENT_ACTION_GLIDE_UP curr_rom.is_hoenn() ? 0xFF : 0xA1
|
||||
#define MOVEMENT_ACTION_GLIDE_LEFT curr_rom.is_hoenn() ? 0xFF : 0xA2
|
||||
#define MOVEMENT_ACTION_GLIDE_RIGHT curr_rom.is_hoenn() ? 0xFF : 0xA3
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_DOWN curr_rom.is_hoenn() ? 0xFF : 0xA6
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_UP curr_rom.is_hoenn() ? 0xFF : 0xA7
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_LEFT curr_rom.is_hoenn() ? 0xFF : 0xA8
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_RIGHT curr_rom.is_hoenn() ? 0xFF : 0xA9
|
||||
#define MOVEMENT_ACTION_FACE_DOWN curr_GBA_rom.is_hoenn() ? 0x0 : 0x0
|
||||
#define MOVEMENT_ACTION_FACE_UP curr_GBA_rom.is_hoenn() ? 0x1 : 0x1
|
||||
#define MOVEMENT_ACTION_FACE_LEFT curr_GBA_rom.is_hoenn() ? 0x2 : 0x2
|
||||
#define MOVEMENT_ACTION_FACE_RIGHT curr_GBA_rom.is_hoenn() ? 0x3 : 0x3
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_DOWN curr_GBA_rom.is_hoenn() ? 0x4 : 0xC
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_UP curr_GBA_rom.is_hoenn() ? 0x5 : 0xD
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_LEFT curr_GBA_rom.is_hoenn() ? 0x6 : 0xE
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_RIGHT curr_GBA_rom.is_hoenn() ? 0x7 : 0xF
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_DOWN curr_GBA_rom.is_hoenn() ? 0x8 : 0x10
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_UP curr_GBA_rom.is_hoenn() ? 0x9 : 0x11
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_LEFT curr_GBA_rom.is_hoenn() ? 0xA : 0x12
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_RIGHT curr_GBA_rom.is_hoenn() ? 0xB : 0x13
|
||||
#define MOVEMENT_ACTION_JUMP_2_DOWN curr_GBA_rom.is_hoenn() ? 0xC : 0x14
|
||||
#define MOVEMENT_ACTION_JUMP_2_UP curr_GBA_rom.is_hoenn() ? 0xD : 0x15
|
||||
#define MOVEMENT_ACTION_JUMP_2_LEFT curr_GBA_rom.is_hoenn() ? 0xE : 0x16
|
||||
#define MOVEMENT_ACTION_JUMP_2_RIGHT curr_GBA_rom.is_hoenn() ? 0xF : 0x17
|
||||
#define MOVEMENT_ACTION_DELAY_1 curr_GBA_rom.is_hoenn() ? 0x10 : 0x18
|
||||
#define MOVEMENT_ACTION_DELAY_2 curr_GBA_rom.is_hoenn() ? 0x11 : 0x19
|
||||
#define MOVEMENT_ACTION_DELAY_4 curr_GBA_rom.is_hoenn() ? 0x12 : 0x1A
|
||||
#define MOVEMENT_ACTION_DELAY_8 curr_GBA_rom.is_hoenn() ? 0x13 : 0x1B
|
||||
#define MOVEMENT_ACTION_DELAY_16 curr_GBA_rom.is_hoenn() ? 0x14 : 0x1C
|
||||
#define MOVEMENT_ACTION_WALK_FAST_DOWN curr_GBA_rom.is_hoenn() ? 0x15 : 0x1D
|
||||
#define MOVEMENT_ACTION_WALK_FAST_UP curr_GBA_rom.is_hoenn() ? 0x16 : 0x1E
|
||||
#define MOVEMENT_ACTION_WALK_FAST_LEFT curr_GBA_rom.is_hoenn() ? 0x17 : 0x1F
|
||||
#define MOVEMENT_ACTION_WALK_FAST_RIGHT curr_GBA_rom.is_hoenn() ? 0x18 : 0x20
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_DOWN curr_GBA_rom.is_hoenn() ? 0x19 : 0x21
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_UP curr_GBA_rom.is_hoenn() ? 0x1A : 0x22
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_LEFT curr_GBA_rom.is_hoenn() ? 0x1B : 0x23
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_RIGHT curr_GBA_rom.is_hoenn() ? 0x1C : 0x24
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_DOWN curr_GBA_rom.is_hoenn() ? 0x1D : 0x25
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_UP curr_GBA_rom.is_hoenn() ? 0x1E : 0x26
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_LEFT curr_GBA_rom.is_hoenn() ? 0x1F : 0x27
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_RIGHT curr_GBA_rom.is_hoenn() ? 0x20 : 0x28
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_DOWN curr_GBA_rom.is_hoenn() ? 0x21 : 0x29
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_UP curr_GBA_rom.is_hoenn() ? 0x22 : 0x2A
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_LEFT curr_GBA_rom.is_hoenn() ? 0x23 : 0x2B
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_RIGHT curr_GBA_rom.is_hoenn() ? 0x24 : 0x2C
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_DOWN curr_GBA_rom.is_hoenn() ? 0x25 : 0x2D
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_UP curr_GBA_rom.is_hoenn() ? 0x26 : 0x2E
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_LEFT curr_GBA_rom.is_hoenn() ? 0x27 : 0x2F
|
||||
#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_RIGHT curr_GBA_rom.is_hoenn() ? 0x28 : 0x30
|
||||
#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN curr_GBA_rom.is_hoenn() ? 0x29 : 0x31
|
||||
#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP curr_GBA_rom.is_hoenn() ? 0x2A : 0x32
|
||||
#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_LEFT curr_GBA_rom.is_hoenn() ? 0x2B : 0x33
|
||||
#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_RIGHT curr_GBA_rom.is_hoenn() ? 0x2C : 0x34
|
||||
#define MOVEMENT_ACTION_WALK_FASTER_DOWN curr_GBA_rom.is_hoenn() ? 0x2D : 0x35
|
||||
#define MOVEMENT_ACTION_WALK_FASTER_UP curr_GBA_rom.is_hoenn() ? 0x2E : 0x36
|
||||
#define MOVEMENT_ACTION_WALK_FASTER_LEFT curr_GBA_rom.is_hoenn() ? 0x2F : 0x37
|
||||
#define MOVEMENT_ACTION_WALK_FASTER_RIGHT curr_GBA_rom.is_hoenn() ? 0x30 : 0x38
|
||||
#define MOVEMENT_ACTION_SLIDE_DOWN curr_GBA_rom.is_hoenn() ? 0x31 : 0x39
|
||||
#define MOVEMENT_ACTION_SLIDE_UP curr_GBA_rom.is_hoenn() ? 0x32 : 0x3A
|
||||
#define MOVEMENT_ACTION_SLIDE_LEFT curr_GBA_rom.is_hoenn() ? 0x33 : 0x3B
|
||||
#define MOVEMENT_ACTION_SLIDE_RIGHT curr_GBA_rom.is_hoenn() ? 0x34 : 0x3C
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_DOWN curr_GBA_rom.is_hoenn() ? 0x35 : 0x3D
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_UP curr_GBA_rom.is_hoenn() ? 0x36 : 0x3E
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_LEFT curr_GBA_rom.is_hoenn() ? 0x37 : 0x3F
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_RIGHT curr_GBA_rom.is_hoenn() ? 0x38 : 0x40
|
||||
#define MOVEMENT_ACTION_START_ANIM_IN_DIRECTION curr_GBA_rom.is_hoenn() ? 0x39 : 0x45
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_DOWN curr_GBA_rom.is_hoenn() ? 0x3A : 0x46
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_UP curr_GBA_rom.is_hoenn() ? 0x3B : 0x47
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_LEFT curr_GBA_rom.is_hoenn() ? 0x3C : 0x48
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_RIGHT curr_GBA_rom.is_hoenn() ? 0x3D : 0x49
|
||||
#define MOVEMENT_ACTION_FACE_PLAYER curr_GBA_rom.is_hoenn() ? 0x3E : 0x4A
|
||||
#define MOVEMENT_ACTION_FACE_AWAY_PLAYER curr_GBA_rom.is_hoenn() ? 0x3F : 0x4B
|
||||
#define MOVEMENT_ACTION_LOCK_FACING_DIRECTION curr_GBA_rom.is_hoenn() ? 0x40 : 0x4C
|
||||
#define MOVEMENT_ACTION_UNLOCK_FACING_DIRECTION curr_GBA_rom.is_hoenn() ? 0x41 : 0x4D
|
||||
#define MOVEMENT_ACTION_JUMP_DOWN curr_GBA_rom.is_hoenn() ? 0x42 : 0x4E
|
||||
#define MOVEMENT_ACTION_JUMP_UP curr_GBA_rom.is_hoenn() ? 0x43 : 0x4F
|
||||
#define MOVEMENT_ACTION_JUMP_LEFT curr_GBA_rom.is_hoenn() ? 0x44 : 0x50
|
||||
#define MOVEMENT_ACTION_JUMP_RIGHT curr_GBA_rom.is_hoenn() ? 0x45 : 0x51
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_DOWN curr_GBA_rom.is_hoenn() ? 0x46 : 0x52
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_UP curr_GBA_rom.is_hoenn() ? 0x47 : 0x53
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_LEFT curr_GBA_rom.is_hoenn() ? 0x48 : 0x54
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_RIGHT curr_GBA_rom.is_hoenn() ? 0x49 : 0x55
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_DOWN_UP curr_GBA_rom.is_hoenn() ? 0x4A : 0x56
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_UP_DOWN curr_GBA_rom.is_hoenn() ? 0x4B : 0x57
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_LEFT_RIGHT curr_GBA_rom.is_hoenn() ? 0x4C : 0x58
|
||||
#define MOVEMENT_ACTION_JUMP_IN_PLACE_RIGHT_LEFT curr_GBA_rom.is_hoenn() ? 0x4D : 0x59
|
||||
#define MOVEMENT_ACTION_FACE_ORIGINAL_DIRECTION curr_GBA_rom.is_hoenn() ? 0x4E : 0x5A
|
||||
#define MOVEMENT_ACTION_NURSE_JOY_BOW_DOWN curr_GBA_rom.is_hoenn() ? 0x4F : 0x5B
|
||||
#define MOVEMENT_ACTION_ENABLE_JUMP_LANDING_GROUND_EFFECT curr_GBA_rom.is_hoenn() ? 0x50 : 0x5C
|
||||
#define MOVEMENT_ACTION_DISABLE_JUMP_LANDING_GROUND_EFFECT curr_GBA_rom.is_hoenn() ? 0x51 : 0x5D
|
||||
#define MOVEMENT_ACTION_DISABLE_ANIMATION curr_GBA_rom.is_hoenn() ? 0x52 : 0x5E
|
||||
#define MOVEMENT_ACTION_RESTORE_ANIMATION curr_GBA_rom.is_hoenn() ? 0x53 : 0x5F
|
||||
#define MOVEMENT_ACTION_SET_INVISIBLE curr_GBA_rom.is_hoenn() ? 0x54 : 0x60
|
||||
#define MOVEMENT_ACTION_SET_VISIBLE curr_GBA_rom.is_hoenn() ? 0x55 : 0x61
|
||||
#define MOVEMENT_ACTION_EMOTE_EXCLAMATION_MARK curr_GBA_rom.is_hoenn() ? 0x56 : 0x62
|
||||
#define MOVEMENT_ACTION_EMOTE_QUESTION_MARK curr_GBA_rom.is_hoenn() ? 0x57 : 0x63
|
||||
#define MOVEMENT_ACTION_EMOTE_HEART curr_GBA_rom.is_hoenn() ? 0x58 : 0xFF
|
||||
#define MOVEMENT_ACTION_REVEAL_TRAINER curr_GBA_rom.is_hoenn() ? 0x59 : 0x67
|
||||
#define MOVEMENT_ACTION_ROCK_SMASH_BREAK curr_GBA_rom.is_hoenn() ? 0x5A : 0x68
|
||||
#define MOVEMENT_ACTION_CUT_TREE curr_GBA_rom.is_hoenn() ? 0x5B : 0x69
|
||||
#define MOVEMENT_ACTION_SET_FIXED_PRIORITY curr_GBA_rom.is_hoenn() ? 0x5C : 0x6A
|
||||
#define MOVEMENT_ACTION_CLEAR_FIXED_PRIORITY curr_GBA_rom.is_hoenn() ? 0x5D : 0x6B
|
||||
#define MOVEMENT_ACTION_INIT_AFFINE_ANIM curr_GBA_rom.is_hoenn() ? 0x5E : 0x6C
|
||||
#define MOVEMENT_ACTION_CLEAR_AFFINE_ANIM curr_GBA_rom.is_hoenn() ? 0x5F : 0x6D
|
||||
#define MOVEMENT_ACTION_HIDE_REFLECTION curr_GBA_rom.is_hoenn() ? 0x60 : 0xFF
|
||||
#define MOVEMENT_ACTION_SHOW_REFLECTION curr_GBA_rom.is_hoenn() ? 0x61 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_DOWN_START_AFFINE curr_GBA_rom.is_hoenn() ? 0x62 : 0x6E
|
||||
#define MOVEMENT_ACTION_WALK_DOWN_AFFINE curr_GBA_rom.is_hoenn() ? 0x63 : 0x6F
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_DOWN curr_GBA_rom.is_hoenn() ? 0x64 : 0x70
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_UP curr_GBA_rom.is_hoenn() ? 0x65 : 0x71
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_LEFT curr_GBA_rom.is_hoenn() ? 0x66 : 0x72
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_RIGHT curr_GBA_rom.is_hoenn() ? 0x67 : 0x73
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_DOWN curr_GBA_rom.is_hoenn() ? 0x68 : 0x74
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_UP curr_GBA_rom.is_hoenn() ? 0x69 : 0x75
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_LEFT curr_GBA_rom.is_hoenn() ? 0x6A : 0x76
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_RIGHT curr_GBA_rom.is_hoenn() ? 0x6B : 0x77
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_DOWN curr_GBA_rom.is_hoenn() ? 0x6C : 0x78
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_UP curr_GBA_rom.is_hoenn() ? 0x6D : 0x79
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_LEFT curr_GBA_rom.is_hoenn() ? 0x6E : 0x7A
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_RIGHT curr_GBA_rom.is_hoenn() ? 0x6F : 0x7B
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_DOWN curr_GBA_rom.is_hoenn() ? 0x70 : 0x7C
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_UP curr_GBA_rom.is_hoenn() ? 0x71 : 0x7D
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_LEFT curr_GBA_rom.is_hoenn() ? 0x72 : 0x7E
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_RIGHT curr_GBA_rom.is_hoenn() ? 0x73 : 0x7F
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_DOWN curr_GBA_rom.is_hoenn() ? 0x74 : 0x80
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_UP curr_GBA_rom.is_hoenn() ? 0x75 : 0x81
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_LEFT curr_GBA_rom.is_hoenn() ? 0x76 : 0x82
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_RIGHT curr_GBA_rom.is_hoenn() ? 0x77 : 0x83
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_DOWN curr_GBA_rom.is_hoenn() ? 0x78 : 0x84
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_UP curr_GBA_rom.is_hoenn() ? 0x79 : 0x85
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_LEFT curr_GBA_rom.is_hoenn() ? 0x7A : 0x86
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_RIGHT curr_GBA_rom.is_hoenn() ? 0x7B : 0x87
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_DOWN curr_GBA_rom.is_hoenn() ? 0x7C : 0x88
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_UP curr_GBA_rom.is_hoenn() ? 0x7D : 0x89
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_LEFT curr_GBA_rom.is_hoenn() ? 0x7E : 0x8A
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_RIGHT curr_GBA_rom.is_hoenn() ? 0x7F : 0x8B
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_DOWN curr_GBA_rom.is_hoenn() ? 0x80 : 0x8C
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_UP curr_GBA_rom.is_hoenn() ? 0x81 : 0x8D
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_LEFT curr_GBA_rom.is_hoenn() ? 0x82 : 0x8E
|
||||
#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_RIGHT curr_GBA_rom.is_hoenn() ? 0x83 : 0x8F
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_DOWN curr_GBA_rom.is_hoenn() ? 0x84 : 0x90
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_UP curr_GBA_rom.is_hoenn() ? 0x85 : 0x91
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_LEFT curr_GBA_rom.is_hoenn() ? 0x86 : 0x92
|
||||
#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_RIGHT curr_GBA_rom.is_hoenn() ? 0x87 : 0x93
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_DOWN curr_GBA_rom.is_hoenn() ? 0x88 : 0xFF
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_UP curr_GBA_rom.is_hoenn() ? 0x89 : 0xFF
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_LEFT curr_GBA_rom.is_hoenn() ? 0x8A : 0xFF
|
||||
#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_RIGHT curr_GBA_rom.is_hoenn() ? 0x8B : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_UP_LEFT curr_GBA_rom.is_hoenn() ? 0x8C : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_UP_RIGHT curr_GBA_rom.is_hoenn() ? 0x8D : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_DOWN_LEFT curr_GBA_rom.is_hoenn() ? 0x8E : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_DOWN_RIGHT curr_GBA_rom.is_hoenn() ? 0x8F : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_UP_LEFT curr_GBA_rom.is_hoenn() ? 0x90 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_UP_RIGHT curr_GBA_rom.is_hoenn() ? 0x91 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_DOWN_LEFT curr_GBA_rom.is_hoenn() ? 0x92 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_DOWN_RIGHT curr_GBA_rom.is_hoenn() ? 0x93 : 0xFF
|
||||
#define MOVEMENT_ACTION_LOCK_ANIM curr_GBA_rom.is_hoenn() ? 0x94 : 0xFF
|
||||
#define MOVEMENT_ACTION_UNLOCK_ANIM curr_GBA_rom.is_hoenn() ? 0x95 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_LEFT_AFFINE curr_GBA_rom.is_hoenn() ? 0x96 : 0xFF
|
||||
#define MOVEMENT_ACTION_WALK_RIGHT_AFFINE curr_GBA_rom.is_hoenn() ? 0x97 : 0xFF
|
||||
#define MOVEMENT_ACTION_LEVITATE curr_GBA_rom.is_hoenn() ? 0x98 : 0xFF
|
||||
#define MOVEMENT_ACTION_STOP_LEVITATE curr_GBA_rom.is_hoenn() ? 0x99 : 0xFF
|
||||
#define MOVEMENT_ACTION_STOP_LEVITATE_AT_TOP curr_GBA_rom.is_hoenn() ? 0x9A : 0xFF
|
||||
#define MOVEMENT_ACTION_FIGURE_8 curr_GBA_rom.is_hoenn() ? 0x9B : 0xFF
|
||||
#define MOVEMENT_ACTION_FLY_UP curr_GBA_rom.is_hoenn() ? 0x9C : 0xA4
|
||||
#define MOVEMENT_ACTION_FLY_DOWN curr_GBA_rom.is_hoenn() ? 0x9D : 0xA5
|
||||
#define MOVEMENT_ACTION_FACE_DOWN_FAST curr_GBA_rom.is_hoenn() ? 0xFF : 0x4
|
||||
#define MOVEMENT_ACTION_FACE_UP_FAST curr_GBA_rom.is_hoenn() ? 0xFF : 0x5
|
||||
#define MOVEMENT_ACTION_FACE_LEFT_FAST curr_GBA_rom.is_hoenn() ? 0xFF : 0x6
|
||||
#define MOVEMENT_ACTION_FACE_RIGHT_FAST curr_GBA_rom.is_hoenn() ? 0xFF : 0x7
|
||||
#define MOVEMENT_ACTION_WALK_SLOWER_DOWN curr_GBA_rom.is_hoenn() ? 0xFF : 0x8
|
||||
#define MOVEMENT_ACTION_WALK_SLOWER_UP curr_GBA_rom.is_hoenn() ? 0xFF : 0x9
|
||||
#define MOVEMENT_ACTION_WALK_SLOWER_LEFT curr_GBA_rom.is_hoenn() ? 0xFF : 0xA
|
||||
#define MOVEMENT_ACTION_WALK_SLOWER_RIGHT curr_GBA_rom.is_hoenn() ? 0xFF : 0xB
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_DOWN_SLOW curr_GBA_rom.is_hoenn() ? 0xFF : 0x41
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_UP_SLOW curr_GBA_rom.is_hoenn() ? 0xFF : 0x42
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_LEFT_SLOW curr_GBA_rom.is_hoenn() ? 0xFF : 0x43
|
||||
#define MOVEMENT_ACTION_PLAYER_RUN_RIGHT_SLOW curr_GBA_rom.is_hoenn() ? 0xFF : 0x44
|
||||
#define MOVEMENT_ACTION_EMOTE_X curr_GBA_rom.is_hoenn() ? 0xFF : 0x64
|
||||
#define MOVEMENT_ACTION_EMOTE_DOUBLE_EXCL_MARK curr_GBA_rom.is_hoenn() ? 0xFF : 0x65
|
||||
#define MOVEMENT_ACTION_EMOTE_SMILE curr_GBA_rom.is_hoenn() ? 0xFF : 0x66
|
||||
#define MOVEMENT_ACTION_SPIN_DOWN curr_GBA_rom.is_hoenn() ? 0xFF : 0x94
|
||||
#define MOVEMENT_ACTION_SPIN_UP curr_GBA_rom.is_hoenn() ? 0xFF : 0x95
|
||||
#define MOVEMENT_ACTION_SPIN_LEFT curr_GBA_rom.is_hoenn() ? 0xFF : 0x96
|
||||
#define MOVEMENT_ACTION_SPIN_RIGHT curr_GBA_rom.is_hoenn() ? 0xFF : 0x97
|
||||
#define MOVEMENT_ACTION_RAISE_HAND_AND_STOP curr_GBA_rom.is_hoenn() ? 0xFF : 0x98
|
||||
#define MOVEMENT_ACTION_RAISE_HAND_AND_JUMP curr_GBA_rom.is_hoenn() ? 0xFF : 0x99
|
||||
#define MOVEMENT_ACTION_RAISE_HAND_AND_SWIM curr_GBA_rom.is_hoenn() ? 0xFF : 0x9A
|
||||
#define MOVEMENT_ACTION_WALK_SLOWEST_DOWN curr_GBA_rom.is_hoenn() ? 0xFF : 0x9B
|
||||
#define MOVEMENT_ACTION_WALK_SLOWEST_UP curr_GBA_rom.is_hoenn() ? 0xFF : 0x9C
|
||||
#define MOVEMENT_ACTION_WALK_SLOWEST_LEFT curr_GBA_rom.is_hoenn() ? 0xFF : 0x9D
|
||||
#define MOVEMENT_ACTION_WALK_SLOWEST_RIGHT curr_GBA_rom.is_hoenn() ? 0xFF : 0x9E
|
||||
#define MOVEMENT_ACTION_SHAKE_HEAD_OR_WALK_IN_PLACE curr_GBA_rom.is_hoenn() ? 0xFF : 0x9F
|
||||
#define MOVEMENT_ACTION_GLIDE_DOWN curr_GBA_rom.is_hoenn() ? 0xFF : 0xA0
|
||||
#define MOVEMENT_ACTION_GLIDE_UP curr_GBA_rom.is_hoenn() ? 0xFF : 0xA1
|
||||
#define MOVEMENT_ACTION_GLIDE_LEFT curr_GBA_rom.is_hoenn() ? 0xFF : 0xA2
|
||||
#define MOVEMENT_ACTION_GLIDE_RIGHT curr_GBA_rom.is_hoenn() ? 0xFF : 0xA3
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_DOWN curr_GBA_rom.is_hoenn() ? 0xFF : 0xA6
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_UP curr_GBA_rom.is_hoenn() ? 0xFF : 0xA7
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_LEFT curr_GBA_rom.is_hoenn() ? 0xFF : 0xA8
|
||||
#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_RIGHT curr_GBA_rom.is_hoenn() ? 0xFF : 0xA9
|
||||
|
||||
#define CPU_SET_16BIT 0x00000000
|
||||
#define CPU_SET_32BIT 0x04000000
|
||||
|
|
@ -272,7 +272,7 @@ public:
|
|||
* You're in control!
|
||||
*/
|
||||
mystery_gift_script(u8 *save_section_30_buffer);
|
||||
void build_script(Pokemon_Party &incoming_box_data);
|
||||
void build_script(PokeBox *box);
|
||||
//void build_script_old(Pokemon_Party &incoming_box_data);
|
||||
const u8 *get_script() const;
|
||||
const u8 * get_section30() const;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@
|
|||
#include "pokemon_party.h"
|
||||
#include "pokemon_data.h"
|
||||
|
||||
bool inject_mystery(Pokemon_Party &incoming_box_data);
|
||||
bool inject_mystery(PokeBox* box);
|
||||
|
||||
#endif
|
||||
152
include/pccs/GBPokemon.h
Normal file
152
include/pccs/GBPokemon.h
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
#ifndef GBPOKEMON_H
|
||||
#define GBPOKEMON_H
|
||||
|
||||
#include "Pokemon.h"
|
||||
#include "Gen3Pokemon.h"
|
||||
|
||||
class GBPokemon : public Pokemon // The class for gen 1 and 2 Pokemon, since they share some conversion functions
|
||||
{
|
||||
protected:
|
||||
GBPokemon();
|
||||
void updateValidity();
|
||||
// These store the data bytes
|
||||
byte nicknameArray[11];
|
||||
byte OTArray[11];
|
||||
byte externalIndexNumber;
|
||||
Language lang = (Language)0;
|
||||
|
||||
static const DataVarInfo
|
||||
// All of the data info variables
|
||||
speciesIndexNumber[2],
|
||||
level[2],
|
||||
moveOne[2], moveTwo[2], moveThree[2], moveFour[2],
|
||||
trainerID[2],
|
||||
expPoints[2],
|
||||
hpStatExp[2], atkStatExp[2], defStatExp[2], speStatExp[2], spcStatExp[2],
|
||||
atkDV[2], defDV[2], speDV[2], spcDV[2],
|
||||
ppUpNumMoveOne[2], ppUpNumMoveTwo[2], ppUpNumMoveThree[2], ppUpNumMoveFour[2],
|
||||
ppNumTotalMoveOne[2], ppNumTotalMoveTwo[2], ppNumTotalMoveThree[2], ppNumTotalMoveFour[2];
|
||||
|
||||
static const DataVarInfo
|
||||
// and the convenient arrays of some of the variable groups:
|
||||
*moves[4],
|
||||
*statExps[5],
|
||||
*DVs[5],
|
||||
*PPUpNums[4],
|
||||
*PPUpTotals[4];
|
||||
|
||||
// This is used to easily print out a Pokemon, when using a standard C++ terminal
|
||||
#if ON_GBA
|
||||
#else
|
||||
std::string parentPrint();
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual void loadData(Language nLang, byte nDataArray[], byte nNicknameArray[], byte nOTArray[], byte nExternalIndexNum);
|
||||
|
||||
// All of the simple getters and setters are defined here
|
||||
u32 getLevel() { return getVar(level[generation - 1]); }
|
||||
u32 getTrainerID() { return getVar(trainerID[generation - 1]); }
|
||||
u32 getExpPoints() { return getVar(expPoints[generation - 1]); }
|
||||
|
||||
bool setLevel(byte newVal) { return setVar(level[generation - 1], newVal); }
|
||||
bool setOriginalTrainerID(byte newVal) { return setVar(trainerID[generation - 1], newVal); }
|
||||
bool setExpPoints(u32 newVal) { return setVar(expPoints[generation - 1], newVal); }
|
||||
|
||||
// The ones that access arrays are defined here:
|
||||
u32 getMove(int moveIndex) { return getVar(moves[moveIndex][generation - 1]); }
|
||||
u32 getStatExp(Stat currStat) { return getVar(statExps[currStat][generation - 1]); }
|
||||
u32 getPPUpNum(int moveIndex) { return getVar(PPUpNums[moveIndex][generation - 1]); }
|
||||
u32 getPPTotal(int moveIndex) { return getVar(PPUpTotals[moveIndex][generation - 1]); }
|
||||
|
||||
bool setMove(int moveIndex, byte newVal) { return setVar(moves[moveIndex][generation - 1], newVal); }
|
||||
bool setStatExp(Stat currStat, byte newVal) { return setVar(statExps[currStat][generation - 1], newVal); }
|
||||
bool setPPUpNum(int moveIndex, byte newVal) { return setVar(PPUpNums[moveIndex][generation - 1], newVal); }
|
||||
bool setPPTotal(int moveIndex, byte newVal) { return setVar(PPUpTotals[moveIndex][generation - 1], newVal); }
|
||||
|
||||
// These are all replaced in the child classes, but give a default value or do nothing here
|
||||
|
||||
// ---- Gen 1
|
||||
virtual u32 getSpeciesIndexNumber() { return getVar(*speciesIndexNumber); }
|
||||
virtual u32 getCurrentHP() { return 0; }
|
||||
virtual u32 getStatusCondition() { return 0; }
|
||||
virtual u32 getCatchRate() { return 0; }
|
||||
virtual u32 getType(int typeIndex) { return NORMAL; }
|
||||
|
||||
virtual bool setSpeciesIndexNumber(byte newVal) { return setVar(*speciesIndexNumber, newVal); }
|
||||
virtual bool setCurrentHP(byte newVal) { return false; }
|
||||
virtual bool setStatusCondition(byte newVal) { return false; }
|
||||
virtual bool setCatchRate(byte newVal) { return false; }
|
||||
virtual bool setType(int typeIndex, Gen1Types newVal) { return false; }
|
||||
|
||||
// ---- Gen 2
|
||||
virtual u32 getHeldItem() { return 0; } // no item
|
||||
virtual u32 getFriendship() { return 70; } // default friendship - make this different for Pikachu in Yellow???
|
||||
virtual u32 getPokerusStrain() { return 0; }
|
||||
virtual u32 getPokerusDaysRemaining() { return 0; }
|
||||
virtual u32 getCaughtDataTime() { return 0; }
|
||||
virtual u32 getCaughtDataLevel() { return 0; }
|
||||
virtual u32 getCaughtDataGender() { return 0; }
|
||||
virtual u32 getCaughtDataLocation() { return 0; }
|
||||
|
||||
virtual bool setHeldItem(byte newVal) { return false; } // This could *technically* be seen as setting the catch rate but...
|
||||
virtual bool setFriendship(byte newVal) { return false; }
|
||||
virtual bool setPokerusStrain(byte newVal) { return false; }
|
||||
virtual bool setPokerusDaysRemaining(byte newVal) { return false; }
|
||||
virtual bool setCaughtDataTime(byte newVal) { return false; }
|
||||
virtual bool setCaughtDataLevel(byte newVal) { return false; }
|
||||
virtual bool setCaughtDataGender(byte newVal) { return false; }
|
||||
virtual bool setCaughtDataLocation(byte newVal) { return false; }
|
||||
|
||||
// These all have special implementations
|
||||
u32 getDV(Stat currStat);
|
||||
bool setDV(Stat currStat, byte newVal);
|
||||
|
||||
// These is virtual so it can be overwitten in Gen 1
|
||||
|
||||
// These aren't direct variables, but they're useful to have
|
||||
Language getLanguage() { return lang; };
|
||||
byte getUnownLetter();
|
||||
Gender getGender();
|
||||
Nature getVirtualConsoleNature();
|
||||
bool getIsShiny();
|
||||
bool externalConvertNickname(byte outputArray[]);
|
||||
|
||||
// And this is for all the conversion stuff
|
||||
bool convertToGen3(Gen3Pokemon *newPkmn, bool sanitizeMythicals);
|
||||
bool loadEvent(Gen3Pokemon *newPkmn);
|
||||
|
||||
bool generatePersonalityValue(Gen3Pokemon *newPkmn, RNGMethod rng);
|
||||
bool convertTrainerID(Gen3Pokemon *newPkmn);
|
||||
bool convertNickname(Gen3Pokemon *newPkmn);
|
||||
bool convertLanguage(Gen3Pokemon *newPkmn);
|
||||
bool convertMiscFlags(Gen3Pokemon *newPkmn);
|
||||
bool convertTrainerNickname(Gen3Pokemon *newPkmn);
|
||||
bool convertMarkings(Gen3Pokemon *newPkmn);
|
||||
// Data
|
||||
bool convertSpeciesIndexNumber(Gen3Pokemon *newPkmn);
|
||||
bool convertItem(Gen3Pokemon *newPkmn);
|
||||
bool convertEXP(Gen3Pokemon *newPkmn);
|
||||
bool convertFriendship(Gen3Pokemon *newPkmn);
|
||||
bool convertMoves(Gen3Pokemon *newPkmn);
|
||||
bool convertEVs(Gen3Pokemon *newPkmn);
|
||||
bool convertContestConditions(Gen3Pokemon *newPkmn);
|
||||
bool convertPokerus(Gen3Pokemon *newPkmn);
|
||||
bool convertMetLocation(Gen3Pokemon *newPkmn);
|
||||
bool convertMetLevel(Gen3Pokemon *newPkmn);
|
||||
bool convertGameOfOrigin(Gen3Pokemon *newPkmn);
|
||||
bool convertPokeball(Gen3Pokemon *newPkmn);
|
||||
bool convertTrainerGender(Gen3Pokemon *newPkmn);
|
||||
bool convertIVs(Gen3Pokemon *newPkmn);
|
||||
bool convertAbilityFlag(Gen3Pokemon *newPkmn);
|
||||
bool convertRibbonsAndObedience(Gen3Pokemon *newPkmn);
|
||||
bool convertShininess(Gen3Pokemon *newPkmn);
|
||||
// Extra
|
||||
bool setRequestedLetter(Gen3Pokemon *newPkmn);
|
||||
bool setRequestedNature(Gen3Pokemon *newPkmn);
|
||||
bool setRequestedGender(Gen3Pokemon *newPkmn);
|
||||
bool setRequestedAbility(Gen3Pokemon *newPkmn);
|
||||
bool setRequestedSize(Gen3Pokemon *newPkmn);
|
||||
};
|
||||
|
||||
#endif
|
||||
39
include/pccs/Gen1Pokemon.h
Normal file
39
include/pccs/Gen1Pokemon.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef GEN1POKEMON_H
|
||||
#define GEN1POKEMON_H
|
||||
|
||||
#include "GBPokemon.h"
|
||||
|
||||
class Gen1Pokemon : public GBPokemon // The class for gen 1 Pokemon
|
||||
{
|
||||
public:
|
||||
Gen1Pokemon(PokemonTables *table);
|
||||
byte dataArray[33];
|
||||
|
||||
u32 getSpeciesIndexNumber();
|
||||
u32 getCurrentHP() { return getVar(g1_currentHP); }
|
||||
u32 getStatusCondition() { return getVar(g1_statusCondition); }
|
||||
u32 getCatchRate() { return getVar(g1_catchRate); }
|
||||
u32 getType(int typeIndex) { return getVar(*g1_types[typeIndex]); }
|
||||
|
||||
bool setSpeciesIndexNumber(byte newVal);
|
||||
bool setCurrentHP(byte newVal) { return setVar(g1_currentHP, newVal); }
|
||||
bool setStatusCondition(byte newVal) { return setVar(g1_statusCondition, newVal); }
|
||||
bool setCatchRate(byte newVal) { return setVar(g1_catchRate, newVal); }
|
||||
bool setType(int typeIndex, Gen1Types newVal) { return setVar(*g1_types[typeIndex], newVal); }
|
||||
|
||||
protected:
|
||||
static const DataVarInfo
|
||||
// Gen 1 specific data
|
||||
g1_currentHP,
|
||||
g1_statusCondition,
|
||||
g1_typeOne, g1_typeTwo,
|
||||
g1_catchRate,
|
||||
*g1_types[2];
|
||||
|
||||
#if ON_GBA
|
||||
#else
|
||||
void print(std::ostream &os);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
47
include/pccs/Gen2Pokemon.h
Normal file
47
include/pccs/Gen2Pokemon.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef GEN2POKEMON_H
|
||||
#define GEN2POKEMON_H
|
||||
|
||||
#include "GBPokemon.h"
|
||||
|
||||
class Gen2Pokemon : public GBPokemon // The class for gen 2 Pokemon
|
||||
{
|
||||
public:
|
||||
Gen2Pokemon(PokemonTables *table);
|
||||
byte dataArray[32];
|
||||
|
||||
u32 getHeldItem() { return getVar(g2_heldItem); }
|
||||
u32 getFriendship() { return getVar(g2_friendship); }
|
||||
u32 getPokerusStrain() { return getVar(g2_pokerusStrain); }
|
||||
u32 getPokerusDaysRemaining() { return getVar(g2_pokerusDaysRemaining); }
|
||||
u32 getCaughtDataTime() { return getVar(g2_caughtDataTime); }
|
||||
u32 getCaughtDataLevel() { return getVar(g2_caughtDataLevel); }
|
||||
u32 getCaughtDataGender() { return getVar(g2_caughtDataGender); }
|
||||
u32 getCaughtDataLocation() { return getVar(g2_caughtDataLocation); }
|
||||
|
||||
bool setHeldItem(byte newVal) { return setVar(g2_heldItem, newVal); }
|
||||
bool setFriendship(byte newVal) { return setVar(g2_friendship, newVal); }
|
||||
bool setPokerusStrain(byte newVal) { return setVar(g2_pokerusStrain, newVal); }
|
||||
bool setPokerusDaysRemaining(byte newVal) { return setVar(g2_pokerusDaysRemaining, newVal); }
|
||||
bool setCaughtDataTime(byte newVal) { return setVar(g2_caughtDataTime, newVal); }
|
||||
bool setCaughtDataLevel(byte newVal) { return setVar(g2_caughtDataLevel, newVal); }
|
||||
bool setCaughtDataGender(byte newVal) { return setVar(g2_caughtDataGender, newVal); }
|
||||
bool setCaughtDataLocation(byte newVal) { return setVar(g2_caughtDataLocation, newVal); }
|
||||
|
||||
protected:
|
||||
static const DataVarInfo
|
||||
g2_heldItem,
|
||||
g2_friendship,
|
||||
g2_pokerusStrain,
|
||||
g2_pokerusDaysRemaining,
|
||||
g2_caughtDataTime,
|
||||
g2_caughtDataLevel,
|
||||
g2_caughtDataGender,
|
||||
g2_caughtDataLocation;
|
||||
|
||||
#if ON_GBA
|
||||
#else
|
||||
void print(std::ostream &os);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
295
include/pccs/Gen3Pokemon.h
Normal file
295
include/pccs/Gen3Pokemon.h
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
#ifndef GEN3POKEMON_H
|
||||
#define GEN3POKEMON_H
|
||||
|
||||
#include "Pokemon.h"
|
||||
|
||||
class Gen3Pokemon : public Pokemon // The class for gen 3 Pokemon
|
||||
|
||||
{
|
||||
public:
|
||||
Gen3Pokemon(PokemonTables *table);
|
||||
|
||||
bool convertToGen3(Gen3Pokemon *g3p);
|
||||
|
||||
u32 currRand;
|
||||
u32 getNextRand_u32();
|
||||
u32 getPrevRand_u32();
|
||||
u16 getNextRand_u16();
|
||||
u16 getPrevRand_u16();
|
||||
|
||||
// These are stored internally so that they can be set by different functions
|
||||
byte internalUnownLetter;
|
||||
Nature internalNature;
|
||||
Gender internalGender;
|
||||
int internalSize;
|
||||
u32 internalAbility;
|
||||
|
||||
protected:
|
||||
// These store the data bytes
|
||||
byte dataArray[80] = {0};
|
||||
|
||||
// This stores if the data is current encrypted or not
|
||||
bool isEncrypted;
|
||||
|
||||
// These store the offsets of the various data substructures:
|
||||
int substructOffsets[4] = {0, 12, 24, 36};
|
||||
int currSubstructureShift = 0;
|
||||
|
||||
void swapSubstructures(int indexOne, int indexTwo);
|
||||
|
||||
#pragma region
|
||||
// Since there is only the Pokemon parent class, we can directly define these directly
|
||||
static const DataVarInfo
|
||||
// All of the data info variables
|
||||
personalityValue,
|
||||
trainerID,
|
||||
secretID,
|
||||
nicknameLetterOne, // This is silly. Change this.
|
||||
nicknameLetterTwo,
|
||||
nicknameLetterThree,
|
||||
nicknameLetterFour,
|
||||
nicknameLetterFive,
|
||||
nicknameLetterSix,
|
||||
nicknameLetterSeven,
|
||||
nicknameLetterEight,
|
||||
nicknameLetterNine,
|
||||
nicknameLetterTen,
|
||||
language,
|
||||
isBadEgg,
|
||||
hasSpecies,
|
||||
useEggName,
|
||||
blockBoxRS,
|
||||
// unusedFlags,
|
||||
originalTrainerNameLetterOne, // This is also silly. Change this.
|
||||
originalTrainerNameLetterTwo,
|
||||
originalTrainerNameLetterThree,
|
||||
originalTrainerNameLetterFour,
|
||||
originalTrainerNameLetterFive,
|
||||
originalTrainerNameLetterSix,
|
||||
originalTrainerNameLetterSeven,
|
||||
markings,
|
||||
checksum;
|
||||
// unknown;
|
||||
|
||||
static const DataVarInfo
|
||||
*nickname[10],
|
||||
*originalTrainerName[7];
|
||||
|
||||
// data section G
|
||||
static const DataVarInfo
|
||||
speciesIndexNumber,
|
||||
heldItem,
|
||||
expPoints,
|
||||
ppUpNumMoveOne,
|
||||
ppUpNumMoveTwo,
|
||||
ppUpNumMoveThree,
|
||||
ppUpNumMoveFour,
|
||||
friendship;
|
||||
// unused;
|
||||
|
||||
static const DataVarInfo
|
||||
*ppUpNums[4];
|
||||
|
||||
// data section A
|
||||
static const DataVarInfo
|
||||
moveOne,
|
||||
moveTwo,
|
||||
moveThree,
|
||||
moveFour,
|
||||
moveOnePP,
|
||||
moveTwoPP,
|
||||
moveThreePP,
|
||||
moveFourPP;
|
||||
static const DataVarInfo
|
||||
*moves[4],
|
||||
*ppUpTotals[4];
|
||||
|
||||
// data section E
|
||||
static const DataVarInfo
|
||||
hpEVs,
|
||||
attackEVs,
|
||||
defenseEVs,
|
||||
speedEVs,
|
||||
specialAttackEVs,
|
||||
specialDefenseEVs,
|
||||
coolnessCondition,
|
||||
beautyCondition,
|
||||
cutenessCondition,
|
||||
smartnessCondition,
|
||||
toughnessCondition,
|
||||
sheen;
|
||||
|
||||
static const DataVarInfo
|
||||
*EVs[6],
|
||||
*contestConditions[5];
|
||||
|
||||
static const DataVarInfo
|
||||
|
||||
// data section M
|
||||
pokerusStrain,
|
||||
pokerusDaysRemaining,
|
||||
metLocation,
|
||||
levelMet,
|
||||
gameOfOrigin,
|
||||
pokeballCaughtIn,
|
||||
originalTrainerGender,
|
||||
hpIVs,
|
||||
attackIVs,
|
||||
defenseIVs,
|
||||
speedIVs,
|
||||
specialAttackIVs,
|
||||
specialDefenseIVs,
|
||||
isEgg,
|
||||
ability,
|
||||
coolNormalContestRibbon, // This is also very silly. Change it.
|
||||
coolSuperContestRibbon,
|
||||
coolHyperContestRibbon,
|
||||
coolMasterContestRibbon,
|
||||
beautyNormalContestRibbon,
|
||||
beautySuperContestRibbon,
|
||||
beautyHyperContestRibbon,
|
||||
beautyMasterContestRibbon,
|
||||
cuteNormalContestRibbon,
|
||||
cuteSuperContestRibbon,
|
||||
cuteHyperContestRibbon,
|
||||
cuteMasterContestRibbon,
|
||||
smartNormalContestRibbon,
|
||||
smartSuperContestRibbon,
|
||||
smartHyperContestRibbon,
|
||||
smartMasterContestRibbon,
|
||||
toughNormalContestRibbon,
|
||||
toughSuperContestRibbon,
|
||||
toughHyperContestRibbon,
|
||||
toughMasterContestRibbon,
|
||||
championRibbon,
|
||||
winningRibbon,
|
||||
victoryRibbon,
|
||||
artistRibbon,
|
||||
effortRibbon,
|
||||
battleChampionRibbon,
|
||||
regionalChampionRibbon,
|
||||
nationalChampionRibbon,
|
||||
countryRibbon,
|
||||
nationalRibbon,
|
||||
earthRibbon,
|
||||
unusedRibbons,
|
||||
fatefulEncounterObedience;
|
||||
|
||||
static const DataVarInfo
|
||||
*IVs[6],
|
||||
*ribbons[31];
|
||||
#pragma endregion
|
||||
|
||||
// This is used to easily print out a Pokemon, when using a standard C++ terminal
|
||||
#if ON_GBA
|
||||
#else
|
||||
public:
|
||||
void print(std::ostream &os);
|
||||
std::string printDataArray(bool encrypedData);
|
||||
#endif
|
||||
|
||||
public:
|
||||
// All of the simple getters and setters are defined here
|
||||
u32 getPersonalityValue() { return getVar(personalityValue); }
|
||||
u32 getTrainerID() { return getVar(trainerID); }
|
||||
u32 getSecretID() { return getVar(secretID); }
|
||||
u32 getLanguage() { return getVar(language); }
|
||||
u32 getIsBadEgg() { return getVar(isBadEgg); }
|
||||
u32 getHasSpecies() { return getVar(hasSpecies); }
|
||||
u32 getUseEggName() { return getVar(useEggName); }
|
||||
u32 getBlockBoxRS() { return getVar(blockBoxRS); }
|
||||
u32 getMarkings() { return getVar(markings); }
|
||||
u32 getChecksum() { return getVar(checksum); }
|
||||
u32 getSpeciesIndexNumber() { return getVar(speciesIndexNumber, substructOffsets[SUB_G]); }
|
||||
u32 getHeldItem() { return getVar(heldItem, substructOffsets[SUB_G]); }
|
||||
u32 getExpPoints() { return getVar(expPoints, substructOffsets[SUB_G]); }
|
||||
u32 getFriendship() { return getVar(friendship, substructOffsets[SUB_G]); }
|
||||
u32 getSheen() { return getVar(sheen, substructOffsets[SUB_E]); }
|
||||
u32 getPokerusStrain() { return getVar(pokerusStrain, substructOffsets[SUB_M]); }
|
||||
u32 getPokerusDaysRemaining() { return getVar(pokerusDaysRemaining, substructOffsets[SUB_M]); }
|
||||
u32 getMetLocation() { return getVar(metLocation, substructOffsets[SUB_M]); }
|
||||
u32 getLevelMet() { return getVar(levelMet, substructOffsets[SUB_M]); }
|
||||
u32 getGameOfOrigin() { return getVar(gameOfOrigin, substructOffsets[SUB_M]); }
|
||||
u32 getPokeballCaughtIn() { return getVar(pokeballCaughtIn, substructOffsets[SUB_M]); }
|
||||
u32 getOriginalTrainerGender() { return getVar(originalTrainerGender, substructOffsets[SUB_M]); }
|
||||
u32 getIsEgg() { return getVar(isEgg, substructOffsets[SUB_M]); }
|
||||
u32 getAbility() { return getVar(ability, substructOffsets[SUB_M]); }
|
||||
u32 getFatefulEncounterObedience() { return getVar(fatefulEncounterObedience, substructOffsets[SUB_M]); }
|
||||
|
||||
bool setTrainerID(u32 newVal) { return setVar(trainerID, newVal); }
|
||||
bool setSecretID(u32 newVal) { return setVar(secretID, newVal); }
|
||||
bool setLanguage(u32 newVal) { return setVar(language, newVal); }
|
||||
bool setIsBadEgg(u32 newVal) { return setVar(isBadEgg, newVal); }
|
||||
bool setHasSpecies(u32 newVal) { return setVar(hasSpecies, newVal); }
|
||||
bool setUseEggName(u32 newVal) { return setVar(useEggName, newVal); }
|
||||
bool setBlockBoxRS(u32 newVal) { return setVar(blockBoxRS, newVal); }
|
||||
bool setMarkings(u32 newVal) { return setVar(markings, newVal); }
|
||||
bool setChecksum(u32 newVal) { return setVar(checksum, newVal); }
|
||||
bool setSpeciesIndexNumber(u32 newVal) { return setVar(speciesIndexNumber, substructOffsets[SUB_G], newVal); }
|
||||
bool setHeldItem(Item newVal) { return setVar(heldItem, substructOffsets[SUB_G], newVal); }
|
||||
bool setExpPoints(u32 newVal) { return setVar(expPoints, substructOffsets[SUB_G], newVal); }
|
||||
bool setFriendship(u32 newVal) { return setVar(friendship, substructOffsets[SUB_G], newVal); }
|
||||
bool setSheen(u32 newVal) { return setVar(sheen, substructOffsets[SUB_E], newVal); }
|
||||
bool setPokerusStrain(u32 newVal) { return setVar(pokerusStrain, substructOffsets[SUB_M], newVal); }
|
||||
bool setPokerusDaysRemaining(u32 newVal) { return setVar(pokerusDaysRemaining, substructOffsets[SUB_M], newVal); }
|
||||
bool setMetLocation(u32 newVal) { return setVar(metLocation, substructOffsets[SUB_M], newVal); }
|
||||
bool setLevelMet(u32 newVal) { return setVar(levelMet, substructOffsets[SUB_M], newVal); }
|
||||
bool setGameOfOrigin(Game newVal) { return setVar(gameOfOrigin, substructOffsets[SUB_M], newVal); }
|
||||
bool setPokeballCaughtIn(u32 newVal) { return setVar(pokeballCaughtIn, substructOffsets[SUB_M], newVal); }
|
||||
bool setOriginalTrainerGender(u32 newVal) { return setVar(originalTrainerGender, substructOffsets[SUB_M], newVal); }
|
||||
bool setIsEgg(u32 newVal) { return setVar(isEgg, substructOffsets[SUB_M], newVal); }
|
||||
bool setFatefulEncounterObedience(u32 newVal) { return setVar(fatefulEncounterObedience, substructOffsets[SUB_M], newVal); }
|
||||
|
||||
// The ones that access arrays are defined here:
|
||||
u32 getPPUpNum(int moveIndex) { return getVar(*ppUpNums[moveIndex], substructOffsets[SUB_G]); }
|
||||
u32 getMove(int moveIndex) { return getVar(*moves[moveIndex], substructOffsets[SUB_A]); }
|
||||
u32 getPPTotal(int moveIndex) { return getVar(*ppUpTotals[moveIndex], substructOffsets[SUB_A]); }
|
||||
u32 getEV(Stat currStat) { return getVar(*EVs[currStat], substructOffsets[SUB_E]); }
|
||||
u32 getContestCondition(Condition currCondition) { return getVar(*contestConditions[currCondition], substructOffsets[SUB_E]); }
|
||||
u32 getIV(Stat currStat) { return getVar(*IVs[currStat], substructOffsets[SUB_M]); }
|
||||
u32 getRibbons(Ribbon currRibbon) { return getVar(*ribbons[currRibbon], substructOffsets[SUB_M]); }
|
||||
u32 getNicknameLetter(int index) { return getVar(*nickname[index]); };
|
||||
u32 getOTLetter(int index) { return getVar(*originalTrainerName[index]); };
|
||||
|
||||
bool setPPUpNum(int moveIndex, u32 newVal) { return setVar(*ppUpNums[moveIndex], substructOffsets[SUB_G], newVal); }
|
||||
bool setMove(int moveIndex, u32 newVal) { return setVar(*moves[moveIndex], substructOffsets[SUB_A], newVal); }
|
||||
bool setPPTotal(int moveIndex, u32 newVal) { return setVar(*ppUpTotals[moveIndex], substructOffsets[SUB_A], newVal); }
|
||||
bool setEV(Stat currStat, u32 newVal) { return setVar(*EVs[currStat], substructOffsets[SUB_E], newVal); }
|
||||
bool setContestCondition(Condition currCondition, u32 newVal) { return setVar(*contestConditions[currCondition], substructOffsets[SUB_E], newVal); }
|
||||
bool setIV(Stat currStat, u32 newVal) { return setVar(*IVs[currStat], substructOffsets[SUB_M], newVal); }
|
||||
bool setRibbons(Ribbon currRibbon, u32 newVal) { return setVar(*ribbons[currRibbon], substructOffsets[SUB_M], newVal); }
|
||||
bool setNicknameLetter(int index, u32 newVal) { return setVar(*nickname[index], newVal); };
|
||||
bool setOTLetter(int index, u32 newVal) { return setVar(*originalTrainerName[index], newVal); };
|
||||
|
||||
bool setPersonalityValue(u32 newVal);
|
||||
bool setAbility(u32 newVal);
|
||||
|
||||
// This is used to load our data in from an array and decrypt it
|
||||
void loadData(byte incomingArray[]);
|
||||
|
||||
// And then some general functions
|
||||
void decryptSubstructures();
|
||||
|
||||
void encryptSubstructures();
|
||||
|
||||
void updateChecksum();
|
||||
|
||||
void updateSubstructureShift();
|
||||
|
||||
void resetSubstructureShift();
|
||||
|
||||
void updateSecurityData();
|
||||
|
||||
byte getUnownLetter();
|
||||
Nature getNature();
|
||||
Gender getGender();
|
||||
int getAbilityFromPersonalityValue();
|
||||
int getSize();
|
||||
|
||||
bool getIsShiny();
|
||||
|
||||
bool setNicknameArray(byte nameArr[], int nameArrSize);
|
||||
bool setOTArray(byte nameArr[], int nameArrSize);
|
||||
};
|
||||
|
||||
#endif
|
||||
49
include/pccs/PokeBox.h
Normal file
49
include/pccs/PokeBox.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef POKEBOX_H
|
||||
#define POKEBOX_H
|
||||
|
||||
#include "Gen1Pokemon.h"
|
||||
#include "Gen2Pokemon.h"
|
||||
#include "Gen3Pokemon.h"
|
||||
|
||||
class PokeBox // Stores up to 30 Pokemon in a box
|
||||
{
|
||||
private:
|
||||
void convertPkmn(int index);
|
||||
PokemonTables *table;
|
||||
Pokemon *boxStorage[30];
|
||||
Pokemon *nullMon;
|
||||
int currIndex = 0;
|
||||
|
||||
public:
|
||||
PokeBox();
|
||||
PokeBox(PokemonTables *nTable);
|
||||
void setTable(PokemonTables *nTable);
|
||||
bool addPokemon(Pokemon *currPkmn);
|
||||
Pokemon *getPokemon(int index);
|
||||
GBPokemon *getGBPokemon(int index);
|
||||
Gen3Pokemon *getGen3Pokemon(int index);
|
||||
bool removePokemon(int index);
|
||||
void loadData(int generation, Language nLang, byte nDataArray[]);
|
||||
void convertAll();
|
||||
int getNumInBox();
|
||||
int getNumValid();
|
||||
bool stabilize_mythical = false;
|
||||
|
||||
#if ON_GBA
|
||||
#else
|
||||
friend std::ostream &operator<<(std::ostream &os, PokeBox &pc)
|
||||
{
|
||||
for (int i = 0; i < pc.currIndex; i++)
|
||||
{
|
||||
os << "\n"
|
||||
<< "---------------- " << "POKEMON #" << i << " ----------------" << "\n"
|
||||
<< *pc.boxStorage[i] << "\n";
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
std::string printDataArray();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
105
include/pccs/Pokemon.h
Normal file
105
include/pccs/Pokemon.h
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#ifndef POKEMON_H
|
||||
#define POKEMON_H
|
||||
|
||||
#include "pokemon_data.h"
|
||||
|
||||
#if ON_GBA
|
||||
#else
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#endif
|
||||
|
||||
#if !USE_EXTERNALDATA
|
||||
// #include "pokemonData.h"
|
||||
#endif
|
||||
|
||||
#if USE_CPP_RAND
|
||||
#else
|
||||
#include "random.h"
|
||||
#endif
|
||||
|
||||
// Avoid having to import math
|
||||
inline u32 sizeToMask(int len)
|
||||
{
|
||||
u32 out = 1;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
out *= 2;
|
||||
}
|
||||
return (out - 1);
|
||||
}
|
||||
|
||||
inline u32 getPureRand() // Gets a random number from the device itself
|
||||
{
|
||||
#if USE_CPP_RAND
|
||||
srand(time(0));
|
||||
return rand() << 16 | rand();
|
||||
#else
|
||||
return get_rand_u32();
|
||||
#endif
|
||||
}
|
||||
|
||||
// FNV-1a 32-bit hash function for byte arrays
|
||||
inline u32 fnv1a_hash(unsigned char *data, size_t length)
|
||||
{
|
||||
const uint32_t fnv_prime = 0x01000193;
|
||||
const uint32_t fnv_offset_basis = 0x811C9DC5;
|
||||
uint32_t hash = fnv_offset_basis;
|
||||
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
hash ^= data[i];
|
||||
hash *= fnv_prime;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
class Pokemon // The base Pokemon class
|
||||
{
|
||||
public:
|
||||
Pokemon();
|
||||
virtual ~Pokemon() {};
|
||||
virtual u32 getSpeciesIndexNumber();
|
||||
|
||||
#if ON_GBA
|
||||
#else
|
||||
virtual void print(std::ostream &os)
|
||||
{
|
||||
os << "This is a base Pokemon, it has no info!";
|
||||
};
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, Pokemon &p)
|
||||
{
|
||||
p.print(os);
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
int dataArraySize;
|
||||
int nicknameArraySize;
|
||||
int OTArraySize;
|
||||
|
||||
// Will be set by child classes
|
||||
byte *dataArrayPtr;
|
||||
byte *nicknameArrayPtr;
|
||||
byte *OTArrayPtr;
|
||||
byte *externalIndexNumberPtr;
|
||||
|
||||
// This is extra information that's nice to hold on to
|
||||
int generation = 0;
|
||||
bool isValid;
|
||||
|
||||
protected:
|
||||
PokemonTables *pokeTable;
|
||||
|
||||
bool isBigEndian;
|
||||
|
||||
u32 getVar(DataVarInfo dataVar);
|
||||
u32 getVar(DataVarInfo dataVar, int extraByteOffset);
|
||||
|
||||
bool setVar(DataVarInfo dataVar, u32 newValue);
|
||||
bool setVar(DataVarInfo dataVar, int extraByteOffset, u32 newValue);
|
||||
};
|
||||
|
||||
#endif
|
||||
9
include/pccs/pccs_settings.h
Normal file
9
include/pccs/pccs_settings.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef PCCS_SETTINGS_H
|
||||
#define PCCS_SETTINGS_H
|
||||
|
||||
#define ON_GBA true
|
||||
#define USE_COMPRESSED_DATA true
|
||||
#define USE_CPP_RAND false
|
||||
#define ACCESS_POKEDEX true
|
||||
|
||||
#endif
|
||||
1703
include/pccs/pokemon_data.h
Normal file
1703
include/pccs/pokemon_data.h
Normal file
File diff suppressed because it is too large
Load Diff
671
include/pccs/typeDefs.h
Normal file
671
include/pccs/typeDefs.h
Normal file
|
|
@ -0,0 +1,671 @@
|
|||
#ifndef TYPEDEFS_H
|
||||
#define TYPEDEFS_H
|
||||
|
||||
#include "pccs_settings.h"
|
||||
|
||||
#if ON_GBA
|
||||
#include <tonc.h>
|
||||
#else
|
||||
typedef unsigned char u8, byte, uchar, echar;
|
||||
typedef unsigned short u16, hword, ushort, eshort;
|
||||
typedef unsigned int u32, word, uint, eint;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
typedef signed char s8;
|
||||
typedef signed short s16;
|
||||
typedef signed int s32;
|
||||
typedef signed long long s64;
|
||||
#endif
|
||||
|
||||
// byte offset, data length (in bits), and bit offset
|
||||
struct DataVarInfo
|
||||
{
|
||||
int byteOffset; // The offset of the value
|
||||
int dataLength; // The length of the data in bits
|
||||
int bitOffset; // The offset of where the bits are in the array
|
||||
};
|
||||
|
||||
enum Stat
|
||||
{
|
||||
HP,
|
||||
ATTACK,
|
||||
DEFENSE,
|
||||
SPEED,
|
||||
SPECIAL_ATTACK,
|
||||
SPECIAL_DEFENSE,
|
||||
SPECIAL = SPECIAL_ATTACK,
|
||||
};
|
||||
|
||||
enum Condition
|
||||
{
|
||||
COOLNESS,
|
||||
BEAUTY,
|
||||
CUTENESS,
|
||||
SMARTNESS,
|
||||
TOUGHNESS,
|
||||
};
|
||||
|
||||
enum Gen1Types
|
||||
{
|
||||
NORMAL,
|
||||
FIGHTING,
|
||||
FLYING,
|
||||
POISON,
|
||||
GROUND,
|
||||
ROCK,
|
||||
BIRD,
|
||||
BUG,
|
||||
GHOST,
|
||||
NINE,
|
||||
TEN,
|
||||
ELEVEN,
|
||||
TWELVE,
|
||||
THIRTEEN,
|
||||
FOURTEEN,
|
||||
FIFTEEN,
|
||||
SIXTEEN,
|
||||
SEVENTEEN,
|
||||
EIGHTEEN,
|
||||
NINETEEN,
|
||||
FIRE,
|
||||
WATER,
|
||||
GRASS,
|
||||
ELECTRIC,
|
||||
PSYCHIC,
|
||||
ICE,
|
||||
DRAGON,
|
||||
};
|
||||
|
||||
enum Ribbon
|
||||
{
|
||||
COOL_NORMAL_CONTEST,
|
||||
COOL_SUPER_CONTEST,
|
||||
COOL_HYPER_CONTEST,
|
||||
COOL_MASTER_CONTEST,
|
||||
BEAUTY_NORMAL_CONTEST,
|
||||
BEAUTY_SUPER_CONTEST,
|
||||
BEAUTY_HYPER_CONTEST,
|
||||
BEAUTY_MASTER_CONTEST,
|
||||
CUTE_NORMAL_CONTEST,
|
||||
CUTE_SUPER_CONTEST,
|
||||
CUTE_HYPER_CONTEST,
|
||||
CUTE_MASTER_CONTEST,
|
||||
SMART_NORMAL_CONTEST,
|
||||
SMART_SUPER_CONTEST,
|
||||
SMART_HYPER_CONTEST,
|
||||
SMART_MASTER_CONTEST,
|
||||
TOUGH_NORMAL_CONTEST,
|
||||
TOUGH_SUPER_CONTEST,
|
||||
TOUGH_HYPER_CONTEST,
|
||||
TOUGH_MASTER_CONTEST,
|
||||
CHAMPION,
|
||||
WINNING,
|
||||
VICTORY,
|
||||
ARTIST,
|
||||
EFFORT,
|
||||
BATTLECHAMPION,
|
||||
REGIONALCHAMPION,
|
||||
NATIONALCHAMPION,
|
||||
COUNTRY,
|
||||
NATIONAL,
|
||||
EARTH,
|
||||
};
|
||||
|
||||
enum Gender
|
||||
{
|
||||
MALE,
|
||||
FEMALE,
|
||||
GENDERLESS,
|
||||
};
|
||||
|
||||
enum Nature
|
||||
{
|
||||
HARDY,
|
||||
LONELY,
|
||||
BRAVE,
|
||||
ADAMANT,
|
||||
NAUGHTY,
|
||||
BOLD,
|
||||
DOCILE,
|
||||
RELAXED,
|
||||
IMPISH,
|
||||
LAX,
|
||||
TIMID,
|
||||
HASTY,
|
||||
SERIOUS,
|
||||
JOLLY,
|
||||
NAIVE,
|
||||
MODEST,
|
||||
MILD,
|
||||
QUIET,
|
||||
BASHFUL,
|
||||
RASH,
|
||||
CALM,
|
||||
GENTLE,
|
||||
SASSY,
|
||||
CAREFUL,
|
||||
QUIRKY,
|
||||
};
|
||||
|
||||
enum Species
|
||||
{
|
||||
BULBASAUR = 1,
|
||||
IVYSAUR,
|
||||
VENUSAUR,
|
||||
CHARMANDER,
|
||||
CHARMELEON,
|
||||
CHARIZARD,
|
||||
SQUIRTLE,
|
||||
WARTORTLE,
|
||||
BLASTOISE,
|
||||
CATERPIE,
|
||||
METAPOD,
|
||||
BUTTERFREE,
|
||||
WEEDLE,
|
||||
KAKUNA,
|
||||
BEEDRILL,
|
||||
PIDGEY,
|
||||
PIDGEOTTO,
|
||||
PIDGEOT,
|
||||
RATTATA,
|
||||
RATICATE,
|
||||
SPEAROW,
|
||||
FEAROW,
|
||||
EKANS,
|
||||
ARBOK,
|
||||
PIKACHU,
|
||||
RAICHU,
|
||||
SANDSHREW,
|
||||
SANDSLASH,
|
||||
NIDORAN_F,
|
||||
NIDORINA,
|
||||
NIDOQUEEN,
|
||||
NIDORAN_M,
|
||||
NIDORINO,
|
||||
NIDOKING,
|
||||
CLEFAIRY,
|
||||
CLEFABLE,
|
||||
VULPIX,
|
||||
NINETALES,
|
||||
JIGGLYPUFF,
|
||||
WIGGLYTUFF,
|
||||
ZUBAT,
|
||||
GOLBAT,
|
||||
ODDISH,
|
||||
GLOOM,
|
||||
VILEPLUME,
|
||||
PARAS,
|
||||
PARASECT,
|
||||
VENONAT,
|
||||
VENOMOTH,
|
||||
DIGLETT,
|
||||
DUGTRIO,
|
||||
MEOWTH,
|
||||
PERSIAN,
|
||||
PSYDUCK,
|
||||
GOLDUCK,
|
||||
MANKEY,
|
||||
PRIMEAPE,
|
||||
GROWLITHE,
|
||||
ARCANINE,
|
||||
POLIWAG,
|
||||
POLIWHIRL,
|
||||
POLIWRATH,
|
||||
ABRA,
|
||||
KADABRA,
|
||||
ALAKAZAM,
|
||||
MACHOP,
|
||||
MACHOKE,
|
||||
MACHAMP,
|
||||
BELLSPROUT,
|
||||
WEEPINBELL,
|
||||
VICTREEBEL,
|
||||
TENTACOOL,
|
||||
TENTACRUEL,
|
||||
GEODUDE,
|
||||
GRAVELER,
|
||||
GOLEM,
|
||||
PONYTA,
|
||||
RAPIDASH,
|
||||
SLOWPOKE,
|
||||
SLOWBRO,
|
||||
MAGNEMITE,
|
||||
MAGNETON,
|
||||
FARFETCHD,
|
||||
DODUO,
|
||||
DODRIO,
|
||||
SEEL,
|
||||
DEWGONG,
|
||||
GRIMER,
|
||||
MUK,
|
||||
SHELLDER,
|
||||
CLOYSTER,
|
||||
GASTLY,
|
||||
HAUNTER,
|
||||
GENGAR,
|
||||
ONIX,
|
||||
DROWZEE,
|
||||
HYPNO,
|
||||
KRABBY,
|
||||
KINGLER,
|
||||
VOLTORB,
|
||||
ELECTRODE,
|
||||
EXEGGCUTE,
|
||||
EXEGGUTOR,
|
||||
CUBONE,
|
||||
MAROWAK,
|
||||
HITMONLEE,
|
||||
HITMONCHAN,
|
||||
LICKITUNG,
|
||||
KOFFING,
|
||||
WEEZING,
|
||||
RHYHORN,
|
||||
RHYDON,
|
||||
CHANSEY,
|
||||
TANGELA,
|
||||
KANGASKHAN,
|
||||
HORSEA,
|
||||
SEADRA,
|
||||
GOLDEEN,
|
||||
SEAKING,
|
||||
STARYU,
|
||||
STARMIE,
|
||||
MR_MIME,
|
||||
SCYTHER,
|
||||
JYNX,
|
||||
ELECTABUZZ,
|
||||
MAGMAR,
|
||||
PINSIR,
|
||||
TAUROS,
|
||||
MAGIKARP,
|
||||
GYARADOS,
|
||||
LAPRAS,
|
||||
DITTO,
|
||||
EEVEE,
|
||||
VAPOREON,
|
||||
JOLTEON,
|
||||
FLAREON,
|
||||
PORYGON,
|
||||
OMANYTE,
|
||||
OMASTAR,
|
||||
KABUTO,
|
||||
KABUTOPS,
|
||||
AERODACTYL,
|
||||
SNORLAX,
|
||||
ARTICUNO,
|
||||
ZAPDOS,
|
||||
MOLTRES,
|
||||
DRATINI,
|
||||
DRAGONAIR,
|
||||
DRAGONITE,
|
||||
MEWTWO,
|
||||
MEW,
|
||||
CHIKORITA,
|
||||
BAYLEEF,
|
||||
MEGANIUM,
|
||||
CYNDAQUIL,
|
||||
QUILAVA,
|
||||
TYPHLOSION,
|
||||
TOTODILE,
|
||||
CROCONAW,
|
||||
FERALIGATR,
|
||||
SENTRET,
|
||||
FURRET,
|
||||
HOOTHOOT,
|
||||
NOCTOWL,
|
||||
LEDYBA,
|
||||
LEDIAN,
|
||||
SPINARAK,
|
||||
ARIADOS,
|
||||
CROBAT,
|
||||
CHINCHOU,
|
||||
LANTURN,
|
||||
PICHU,
|
||||
CLEFFA,
|
||||
IGGLYBUFF,
|
||||
TOGEPI,
|
||||
TOGETIC,
|
||||
NATU,
|
||||
XATU,
|
||||
MAREEP,
|
||||
FLAAFFY,
|
||||
AMPHAROS,
|
||||
BELLOSSOM,
|
||||
MARILL,
|
||||
AZUMARILL,
|
||||
SUDOWOODO,
|
||||
POLITOED,
|
||||
HOPPIP,
|
||||
SKIPLOOM,
|
||||
JUMPLUFF,
|
||||
AIPOM,
|
||||
SUNKERN,
|
||||
SUNFLORA,
|
||||
YANMA,
|
||||
WOOPER,
|
||||
QUAGSIRE,
|
||||
ESPEON,
|
||||
UMBREON,
|
||||
MURKROW,
|
||||
SLOWKING,
|
||||
MISDREAVUS,
|
||||
UNOWN,
|
||||
WOBBUFFET,
|
||||
GIRAFARIG,
|
||||
PINECO,
|
||||
FORRETRESS,
|
||||
DUNSPARCE,
|
||||
GLIGAR,
|
||||
STEELIX,
|
||||
SNUBBULL,
|
||||
GRANBULL,
|
||||
QWILFISH,
|
||||
SCIZOR,
|
||||
SHUCKLE,
|
||||
HERACROSS,
|
||||
SNEASEL,
|
||||
TEDDIURSA,
|
||||
URSARING,
|
||||
SLUGMA,
|
||||
MAGCARGO,
|
||||
SWINUB,
|
||||
PILOSWINE,
|
||||
CORSOLA,
|
||||
REMORAID,
|
||||
OCTILLERY,
|
||||
DELIBIRD,
|
||||
MANTINE,
|
||||
SKARMORY,
|
||||
HOUNDOUR,
|
||||
HOUNDOOM,
|
||||
KINGDRA,
|
||||
PHANPY,
|
||||
DONPHAN,
|
||||
PORYGON2,
|
||||
STANTLER,
|
||||
SMEARGLE,
|
||||
TYROGUE,
|
||||
HITMONTOP,
|
||||
SMOOCHUM,
|
||||
ELEKID,
|
||||
MAGBY,
|
||||
MILTANK,
|
||||
BLISSEY,
|
||||
RAIKOU,
|
||||
ENTEI,
|
||||
SUICUNE,
|
||||
LARVITAR,
|
||||
PUPITAR,
|
||||
TYRANITAR,
|
||||
LUGIA,
|
||||
HO_OH,
|
||||
CELEBI,
|
||||
TREECKO,
|
||||
MISSINGNO = 0xFF,
|
||||
};
|
||||
|
||||
enum PokeBall
|
||||
{
|
||||
MASTER = 1,
|
||||
ULTRA,
|
||||
GREAT,
|
||||
POKE,
|
||||
SAFARI,
|
||||
NET,
|
||||
DIVE,
|
||||
NEST,
|
||||
REPEAT,
|
||||
TIMER,
|
||||
LUXURY,
|
||||
PREMIER,
|
||||
};
|
||||
|
||||
enum Game
|
||||
{
|
||||
SAPPHIRE = 1,
|
||||
RUBY,
|
||||
EMERALD,
|
||||
FIRERED,
|
||||
LEAFGREEN,
|
||||
HEARTGOLD = 7,
|
||||
SOULSILVER,
|
||||
DIAMOND = 10,
|
||||
PEARL,
|
||||
PLATINUM,
|
||||
COlOSSEUM_XD = 15,
|
||||
};
|
||||
|
||||
enum Item
|
||||
{
|
||||
NONE,
|
||||
MASTER_BALL,
|
||||
ULTRA_BALL,
|
||||
GREAT_BALL,
|
||||
POKE_BALL,
|
||||
SAFARI_BALL,
|
||||
NET_BALL,
|
||||
DIVE_BALL,
|
||||
NEST_BALL,
|
||||
REPEAT_BALL,
|
||||
TIMER_BALL,
|
||||
LUXURY_BALL,
|
||||
PREMIER_BALL,
|
||||
POTION,
|
||||
ANTIDOTE,
|
||||
BURN_HEAL,
|
||||
ICE_HEAL,
|
||||
AWAKENING,
|
||||
PARLYZ_HEAL,
|
||||
FULL_RESTORE,
|
||||
MAX_POTION,
|
||||
HYPER_POTION,
|
||||
SUPER_POTION,
|
||||
FULL_HEAL,
|
||||
REVIVE,
|
||||
MAX_REVIVE,
|
||||
FRESH_WATER,
|
||||
SODA_POP,
|
||||
LEMONADE,
|
||||
MOOMOO_MILK,
|
||||
ENERGYPOWDER,
|
||||
ENERGY_ROOT,
|
||||
HEAL_POWDER,
|
||||
REVIVAL_HERB,
|
||||
ETHER,
|
||||
MAX_ETHER,
|
||||
ELIXIR,
|
||||
MAX_ELIXIR,
|
||||
LAVA_COOKIE,
|
||||
BLUE_FLUTE,
|
||||
YELLOW_FLUTE,
|
||||
RED_FLUTE,
|
||||
BLACK_FLUTE,
|
||||
WHITE_FLUTE,
|
||||
BERRY_JUICE,
|
||||
SACRED_ASH,
|
||||
SHOAL_SALT,
|
||||
SHOAL_SHELL,
|
||||
RED_SHARD,
|
||||
BLUE_SHARD,
|
||||
YELLOW_SHARD,
|
||||
GREEN_SHARD,
|
||||
|
||||
HP_UP = 0x3F,
|
||||
PROTEIN,
|
||||
IRON,
|
||||
CARBOS,
|
||||
CALCIUM,
|
||||
RARE_CANDY,
|
||||
PP_UP,
|
||||
ZINC,
|
||||
PP_MAX,
|
||||
|
||||
GUARD_SPEC = 0x49,
|
||||
DIRE_HIT,
|
||||
X_ATTACK,
|
||||
X_DEFEND,
|
||||
X_SPEED,
|
||||
X_ACCURACY,
|
||||
X_SPECIAL,
|
||||
POKE_DOLL,
|
||||
FLUFFY_TAIL,
|
||||
|
||||
SUPER_REPEL = 0x53,
|
||||
MAX_REPEL,
|
||||
ESCAPE_ROPE,
|
||||
REPEL,
|
||||
|
||||
SUN_STONE = 0x5D,
|
||||
MOON_STONE,
|
||||
FIRE_STONE,
|
||||
THUNDERSTONE,
|
||||
WATER_STONE,
|
||||
LEAF_STONE,
|
||||
|
||||
TINYMUSHROOM = 0x67,
|
||||
BIG_MUSHROOM,
|
||||
|
||||
NORMAL_PEARL = 0x6A,
|
||||
BIG_PEARL,
|
||||
STARDUST,
|
||||
STAR_PIECE,
|
||||
NUGGET,
|
||||
HEART_SCALE,
|
||||
|
||||
ORANGE_MAIL = 0x79,
|
||||
HARBOR_MAIL,
|
||||
GLITTER_MAIL,
|
||||
MECH_MAIL,
|
||||
WOOD_MAIL,
|
||||
WAVE_MAIL,
|
||||
BEAD_MAIL,
|
||||
SHADOW_MAIL,
|
||||
TROPIC_MAIL,
|
||||
DREAM_MAIL,
|
||||
FAB_MAIL,
|
||||
RETRO_MAIL,
|
||||
CHERI_BERRY,
|
||||
CHESTO_BERRY,
|
||||
PECHA_BERRY,
|
||||
RAWST_BERRY,
|
||||
ASPEAR_BERRY,
|
||||
LEPPA_BERRY,
|
||||
ORAN_BERRY,
|
||||
PERSIM_BERRY,
|
||||
LUM_BERRY,
|
||||
SITRUS_BERRY,
|
||||
FIGY_BERRY,
|
||||
WIKI_BERRY,
|
||||
MAGO_BERRY,
|
||||
AGUAV_BERRY,
|
||||
IAPAPA_BERRY,
|
||||
RAZZ_BERRY,
|
||||
BLUK_BERRY,
|
||||
NANAB_BERRY,
|
||||
WEPEAR_BERRY,
|
||||
PINAP_BERRY,
|
||||
POMEG_BERRY,
|
||||
KELPSY_BERRY,
|
||||
QUALOT_BERRY,
|
||||
HONDEW_BERRY,
|
||||
GREPA_BERRY,
|
||||
TAMATO_BERRY,
|
||||
CORNN_BERRY,
|
||||
MAGOST_BERRY,
|
||||
RABUTA_BERRY,
|
||||
NOMEL_BERRY,
|
||||
SPELON_BERRY,
|
||||
PAMTRE_BERRY,
|
||||
WATMEL_BERRY,
|
||||
DURIN_BERRY,
|
||||
BELUE_BERRY,
|
||||
LIECHI_BERRY,
|
||||
GANLON_BERRY,
|
||||
SALAC_BERRY,
|
||||
PETAYA_BERRY,
|
||||
APICOT_BERRY,
|
||||
LANSAT_BERRY,
|
||||
STARF_BERRY,
|
||||
ENIGMA_BERRY,
|
||||
|
||||
BRIGHTPOWDER = 0xB3,
|
||||
WHITE_HERB,
|
||||
MACHO_BRACE,
|
||||
EXP_SHARE,
|
||||
QUICK_CLAW,
|
||||
SOOTHE_BELL,
|
||||
MENTAL_HERB,
|
||||
CHOICE_BAND,
|
||||
KINGS_ROCK,
|
||||
SILVERPOWDER,
|
||||
AMULET_COIN,
|
||||
CLEANSE_TAG,
|
||||
SOUL_DEW,
|
||||
DEEPSEATOOTH,
|
||||
DEEPSEASCALE,
|
||||
SMOKE_BALL,
|
||||
EVERSTONE,
|
||||
FOCUS_BAND,
|
||||
LUCKY_EGG,
|
||||
SCOPE_LENS,
|
||||
METAL_COAT,
|
||||
LEFTOVERS,
|
||||
DRAGON_SCALE,
|
||||
LIGHT_BALL,
|
||||
SOFT_SAND,
|
||||
HARD_STONE,
|
||||
MIRACLE_SEED,
|
||||
BLACKGLASSES,
|
||||
BLACK_BELT,
|
||||
MAGNET,
|
||||
MYSTIC_WATER,
|
||||
SHARP_BEAK,
|
||||
POISON_BARB,
|
||||
NEVERMELTICE,
|
||||
SPELL_TAG,
|
||||
TWISTEDSPOON,
|
||||
CHARCOAL,
|
||||
DRAGON_FANG,
|
||||
SILK_SCARF,
|
||||
UPGRADE,
|
||||
SHELL_BELL,
|
||||
SEA_INCENSE,
|
||||
LAX_INCENSE,
|
||||
LUCKY_PUNCH,
|
||||
METAL_POWDER,
|
||||
THICK_CLUB,
|
||||
STICK,
|
||||
|
||||
RED_SCARF = 0xFE,
|
||||
BLUE_SCARF,
|
||||
PINK_SCARF,
|
||||
GREEN_SCARF,
|
||||
YELLOW_SCARF
|
||||
};
|
||||
|
||||
enum Substructure
|
||||
{
|
||||
SUB_G,
|
||||
SUB_A,
|
||||
SUB_E,
|
||||
SUB_M,
|
||||
};
|
||||
|
||||
enum Language
|
||||
{
|
||||
JAPANESE = 1,
|
||||
ENGLISH,
|
||||
FRENCH,
|
||||
ITALIAN,
|
||||
GERMAN,
|
||||
SPANISH,
|
||||
KOREAN,
|
||||
};
|
||||
|
||||
enum RNGMethod
|
||||
{
|
||||
ABCD_U, // Normal method
|
||||
BACD_R, // Used for calculating events
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
#ifndef POKEMON_H
|
||||
#define POKEMON_H
|
||||
|
||||
#include <tonc.h>
|
||||
#include "random.h"
|
||||
#include "global_frame_controller.h"
|
||||
|
||||
#define POKEMON_SIZE 80
|
||||
|
||||
// How much trade data is sent for each langauge and generation,
|
||||
// sarts at OT name and ends after the 3 buffer bytes
|
||||
#define GEN1_JPN_SIZE 353
|
||||
#define GEN1_INT_SIZE 418
|
||||
#define GEN2_JPN_SIZE 383
|
||||
#define GEN2_INT_SIZE 444
|
||||
|
||||
class PokemonTables;
|
||||
|
||||
struct Simplified_Pokemon
|
||||
{
|
||||
byte dex_number;
|
||||
byte met_level;
|
||||
byte nickname[10];
|
||||
bool is_valid;
|
||||
bool is_transferred;
|
||||
bool is_shiny;
|
||||
int unown_letter;
|
||||
bool is_missingno;
|
||||
};
|
||||
|
||||
enum Conversion_Types
|
||||
{
|
||||
Faithful,
|
||||
Legal,
|
||||
Virtual,
|
||||
};
|
||||
|
||||
class Pokemon
|
||||
{
|
||||
public:
|
||||
int pkmn_size = 0;
|
||||
int ot_and_party = 0;
|
||||
int ot_size = 0;
|
||||
int nickname_size = 0;
|
||||
int nature_mod = 0;
|
||||
int unown_letter = -1;
|
||||
Pokemon();
|
||||
void load_data(int index, const byte *party_data, int game, int lang);
|
||||
void convert_to_gen_three(PokemonTables& data_tables, Conversion_Types conv_type, bool simplified, bool stabilize_mythical);
|
||||
void copy_from_to(const byte *source, byte *destination, int size, bool reverse_endian);
|
||||
void alocate_data_chunks(byte *G, byte *A, byte *E, byte *M);
|
||||
void insert_data(byte *first, byte *second, byte *third, byte *fourth);
|
||||
byte get_gen_3_data(int index);
|
||||
byte *get_full_gen_3_array();
|
||||
byte get_unencrypted_data(int index);
|
||||
byte *convert_text(PokemonTables& data_tables, byte *text_array, int size);
|
||||
u32 generate_pid_save_iv(PokemonTables& data_tables, byte pid_species_index, byte nature, byte *pid_dvs);
|
||||
u32 generate_pid_iv_match(PokemonTables& data_tables, byte pid_species_index, byte nature, byte *pid_dvs);
|
||||
u32 generate_pid_iv_legendary(byte pid_species_index, byte *pid_dvs, byte *out_ivs);
|
||||
byte rand_reverse_mod(byte modulo_divisor, byte target_mod);
|
||||
byte get_rand_gender_byte(PokemonTables &data_tables, byte index_num, byte attack_DVs);
|
||||
byte get_dex_number();
|
||||
bool get_validity();
|
||||
bool get_is_new();
|
||||
bool get_is_shiny();
|
||||
Simplified_Pokemon get_simple_pkmn();
|
||||
u8 get_letter_from_pid(u32 pid);
|
||||
u8 get_nature_from_pid(u32 pid);
|
||||
u8 get_gender_from_pid(u32 pid);
|
||||
void set_to_event(PokemonTables &data_tables, byte nature);
|
||||
int num_in_box;
|
||||
int index_in_box;
|
||||
bool is_missingno = false;
|
||||
|
||||
private:
|
||||
byte gen = 2;
|
||||
byte language;
|
||||
byte species_index_party; // The species ID stored in the party. Really only used for egg detection
|
||||
byte species_index_struct; // The species ID stored in the pkmn strucutre. The main one to use.
|
||||
byte moves[4];
|
||||
byte trainer_id[2];
|
||||
byte secret_id[2];
|
||||
u32 exp;
|
||||
byte nickname[10];
|
||||
byte trainer_name[7];
|
||||
byte pokerus;
|
||||
byte caught_data[2];
|
||||
byte met_level;
|
||||
byte item;
|
||||
byte gen_3_pkmn[80];
|
||||
byte unencrypted_data[49]; // Contains the 48 GAEM bytes, along with the modulo int
|
||||
byte pid[4] = {0, 0, 0, 0}; // Little Endian, reverse of Bulbapedia
|
||||
byte blank_word[4] = {0};
|
||||
byte data_section_G[12];
|
||||
byte data_section_A[12];
|
||||
byte data_section_E[12];
|
||||
byte data_section_M[12];
|
||||
hword checksum;
|
||||
byte encryption_key[4];
|
||||
hword origin_info = 0;
|
||||
bool is_shiny = false;
|
||||
byte pp_values[4];
|
||||
byte pp_bonus[4];
|
||||
byte pure_pp_values[4];
|
||||
byte dvs[2];
|
||||
byte ivs[6];
|
||||
byte ribbons[4] = {0, 0, 0, 0};
|
||||
u32 iv_egg_ability;
|
||||
bool is_valid;
|
||||
bool is_new = false;
|
||||
int box_size;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,143 +0,0 @@
|
|||
#ifndef POKEMON_DATA_H
|
||||
#define POKEMON_DATA_H
|
||||
|
||||
#include <tonc.h>
|
||||
|
||||
#define med_fast_max (u32)1000000
|
||||
// Slightly Fast goes unused
|
||||
// Slightly Slow goes unused
|
||||
#define med_slow_max (u32)1059860
|
||||
#define fast_max (u32)800000
|
||||
#define slow_max (u32)1250000
|
||||
// Erractic is Gen 3+
|
||||
// Fluctuating is Gen 3+
|
||||
|
||||
#define EXP_FAST 0
|
||||
// Slightly Fast goes unused
|
||||
// Slightly Slow goes unused
|
||||
#define EXP_MED_SLOW 3
|
||||
#define EXP_MED_FAST 4
|
||||
#define EXP_SLOW 5
|
||||
// Erractic is Gen 3+
|
||||
// Fluctuating is Gen 3+
|
||||
|
||||
#define JPN_ID 1
|
||||
#define ENG_ID 2
|
||||
#define FRE_ID 3
|
||||
#define ITA_ID 4
|
||||
#define GER_ID 5
|
||||
#define SPA_ID 7
|
||||
#define KOR_ID 8
|
||||
|
||||
#define GREEN_ID 0
|
||||
#define RED_ID 1
|
||||
#define BLUE_ID 2
|
||||
#define YELLOW_ID 3
|
||||
#define GOLD_ID 4
|
||||
#define SILVER_ID 5
|
||||
#define CRYSTAL_ID 6
|
||||
|
||||
#define EVENT_MEW_JPN 0
|
||||
#define EVENT_MEW_ENG 1
|
||||
#define EVENT_MEW_FRE 2
|
||||
#define EVENT_MEW_ITA 3
|
||||
#define EVENT_MEW_GER 4
|
||||
#define EVENT_MEW_SPA 5
|
||||
#define EVENT_CELEBI 6
|
||||
|
||||
|
||||
#define MAX_PKMN_IN_BOX 30
|
||||
#define NUM_POKEMON 252
|
||||
#define POKEMON_ARRAY_SIZE NUM_POKEMON + 1
|
||||
|
||||
// these arrays are too small to compress
|
||||
extern const u32 EXP_MAXIMUMS[6];
|
||||
extern const int GENDER_THRESHOLDS[2][8];
|
||||
// the next arrays don't compress well at all. Not worth the decompression overhead.
|
||||
extern const byte gen_1_index_array[191];
|
||||
extern const u8 EVOLUTIONS[POKEMON_ARRAY_SIZE];
|
||||
|
||||
// Unfortunately we can't compress this 8 KB MOVESETS array.
|
||||
// I mean, we physically can, but decompressing it means storing it in IWRAM,
|
||||
// at a moment (during convert_to_gen_three()) at which we are using a LOT of IWRAM already.
|
||||
// By keeping it uncompressed, it gets stored in EWRAM, where it won't hinder us.
|
||||
// But it does mean that it still takes up 8 KB in the rom.
|
||||
// Just for reference: when compressing it with ZX0 AND only storing the "changed" bits for PKMN
|
||||
// evolutions in relation to their base forms, we could bring the size down to 4641 bytes.
|
||||
// But alas, the IWRAM consumption at a critical point in time made this approach unviable.
|
||||
// TODO: we might be able to load similar data from the game cartridges.
|
||||
// However, it turns out the data is different between the R/S/E and FR/LG games.
|
||||
// So we would have to store "patches"/differences if we go this route.
|
||||
// It also means we'd have to figure out rom offsets for every single gen III game variant/localization.
|
||||
extern const byte MOVESETS[POKEMON_ARRAY_SIZE][32];
|
||||
|
||||
/**
|
||||
* Okay, here's the thing: to reduce the rom size, we compressed a bunch of data with ZX0
|
||||
* Among this data are various data tables that were previously just stored as const arrays.
|
||||
*
|
||||
* But, during the mystery_gift_builder/mystery_gift_injector execution,
|
||||
* these data tables are used intensely, because you're not using them for single pokémon, but rather for boxes of pokémon.
|
||||
*
|
||||
* Decompression is not cheap, so we can't afford to decompress the tables again and again for every pokémon we deal with
|
||||
* during this flow.
|
||||
*
|
||||
* This is where this class comes in. It is basically a holder of these tables. The idea is to pass it along with the mystery_gift_builder
|
||||
* and have it lazy decompress the tables AND charsets it needs. This way when we are dealing with multiple pokémon, we are not decompressing
|
||||
* the same data every time and thereby make performance suffer.
|
||||
*
|
||||
* It DOES have a significant IWRAM cost though. The intention is to just allocate this struct on the stack.
|
||||
* As far as I can tell, our stack is not really restricted at all. It just fills up the IWRAM as needed. So we need to be careful not to
|
||||
* overwrite/corrupt any code or data we specifically tagged to be stored in IWRAM.
|
||||
*/
|
||||
class PokemonTables
|
||||
{
|
||||
public:
|
||||
bool exp_groups_loaded;
|
||||
bool gender_ratios_loaded;
|
||||
bool num_abilities_loaded;
|
||||
bool first_moves_loaded;
|
||||
bool power_points_loaded;
|
||||
bool event_pkmn_loaded;
|
||||
bool types_loaded;
|
||||
// a number representing the unique combination of gen 1/2 and the specific language
|
||||
// 0 means not loaded
|
||||
u8 input_charset_type;
|
||||
// 0 means not loaded, 1=JPN, 2=Intern
|
||||
u8 gen3_charset_type;
|
||||
|
||||
u8 EXP_GROUPS[POKEMON_ARRAY_SIZE];
|
||||
u8 GENDER_RATIO[POKEMON_ARRAY_SIZE];
|
||||
bool NUM_ABILITIES[POKEMON_ARRAY_SIZE];
|
||||
byte FIRST_MOVES[POKEMON_ARRAY_SIZE];
|
||||
u8 POWER_POINTS[252];
|
||||
byte EVENT_PKMN[8][80];
|
||||
u8 TYPES[POKEMON_ARRAY_SIZE][2];
|
||||
u16 input_charset[256];
|
||||
u16 gen3_charset[256];
|
||||
|
||||
PokemonTables();
|
||||
|
||||
void load_exp_groups();
|
||||
void load_gender_ratios();
|
||||
void load_num_abilities();
|
||||
void load_first_moves();
|
||||
void load_power_points();
|
||||
void load_event_pkmn();
|
||||
void load_types();
|
||||
void load_input_charset(byte gen, byte lang);
|
||||
void load_gen3_charset(byte lang);
|
||||
|
||||
u32 get_max_exp(int index_num);
|
||||
u8 get_gender_threshold(int index_num, bool is_gen_3);
|
||||
bool get_num_abilities(int index_num);
|
||||
bool can_learn_move(int pkmn_index, int move_index);
|
||||
byte get_earliest_move(int index_num);
|
||||
byte get_gen_3_char(u16 input_char);
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads the charset for <gen> and <lang> into <output_char_array>
|
||||
*/
|
||||
void load_localized_charset(u16 *output_char_array, byte gen, byte lang);
|
||||
byte get_char_from_charset(const u16 *charset, u16 input_char);
|
||||
#endif
|
||||
|
|
@ -2,16 +2,17 @@
|
|||
#define POKEMON_PARTY_H
|
||||
|
||||
#include <tonc.h>
|
||||
#include "pokemon.h"
|
||||
#include "pccs/PokeBox.h"
|
||||
#include "gb_rom_values/base_gb_rom_struct.h"
|
||||
class Pokemon_Party
|
||||
{
|
||||
public:
|
||||
Pokemon_Party();
|
||||
PokemonTables table;
|
||||
void start_link();
|
||||
void continue_link(bool cancel_connection);
|
||||
int get_last_error();
|
||||
Pokemon get_converted_pkmn(PokemonTables &data_tables, int index);
|
||||
bool load_gb_rom(Language lang, Game game);
|
||||
bool get_has_new_pkmn();
|
||||
void set_game(int nGame);
|
||||
void set_lang(int nLang);
|
||||
|
|
@ -19,17 +20,13 @@ public:
|
|||
bool load_gb_rom();
|
||||
GB_ROM curr_gb_rom;
|
||||
void show_sprites();
|
||||
Simplified_Pokemon simple_pkmn_array[30];
|
||||
Simplified_Pokemon get_simple_pkmn(int index);
|
||||
bool fill_simple_pkmn_array(PokemonTables &data_tables);
|
||||
bool get_contains_mythical();
|
||||
void set_mythic_stabilization(bool stabilize);
|
||||
bool contains_valid = false;
|
||||
bool contains_invalid = false;
|
||||
int get_game_gen();
|
||||
int get_num_pkmn();
|
||||
bool get_contains_invalid();
|
||||
bool get_contains_missingno();
|
||||
PokeBox box;
|
||||
byte box_data_array[0x462];
|
||||
|
||||
private:
|
||||
|
|
@ -37,10 +34,7 @@ private:
|
|||
|
||||
u8 current_payload[PAYLOAD_SIZE];
|
||||
int last_error;
|
||||
bool has_new_pkmn = false;
|
||||
bool contains_mythical = false;
|
||||
bool stabilize_mythic = false;
|
||||
bool contains_missingno = false;
|
||||
int game;
|
||||
char lang;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#define DEFAULT_LANGUAGE 0x21 // | 0x22 | 1 | Default international language
|
||||
#define SAVE_DATA_SIZE 0x22
|
||||
|
||||
extern rom_data curr_rom;
|
||||
extern rom_data curr_GBA_rom;
|
||||
|
||||
void load_custom_save_data();
|
||||
void write_custom_save_data();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#define CMD_CONTINUE_LINK DIA_END + 13
|
||||
#define CMD_BOX_MENU DIA_END + 14
|
||||
#define CMD_MYTHIC_MENU DIA_END + 15
|
||||
#define CMD_LOAD_SIMP DIA_END + 16
|
||||
#define CMD_IS_A_VALID_PKMN DIA_END + 16
|
||||
#define CMD_CANCEL_LINK DIA_END + 17
|
||||
#define CMD_END_MISSINGNO DIA_END + 18
|
||||
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
extern const script_obj_params transfer_script_params[];
|
||||
extern const script_obj_params event_script_params[];
|
||||
extern rom_data curr_rom;
|
||||
extern rom_data curr_GBA_rom;
|
||||
|
||||
void populate_lang_menu();
|
||||
void populate_game_menu(int lang);
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
#define SPRITE_DATA_H
|
||||
|
||||
#include <tonc.h>
|
||||
#include "pokemon.h"
|
||||
#include "pokemon_data.h"
|
||||
#include "pokemon_party.h"
|
||||
#include "rom_data.h"
|
||||
#include "box_menu.h"
|
||||
|
|
@ -112,7 +110,7 @@ extern OBJ_ATTR *grabbed_front_sprite;
|
|||
#define BG_MAIN_MENU 3
|
||||
#define BG_BOX 4
|
||||
|
||||
extern rom_data curr_rom;
|
||||
extern rom_data curr_GBA_rom;
|
||||
|
||||
void load_sprite(OBJ_ATTR *sprite, const unsigned int objTiles[], int objTilesLen,
|
||||
u32 &tile_id, u32 pal_bank, int attr0, int attr1, u32 priority);
|
||||
|
|
@ -124,7 +122,7 @@ void set_background_pal(int curr_rom_id, bool dark, bool fade);
|
|||
void load_textbox_background();
|
||||
void load_flex_background(int background_id, int layer);
|
||||
void load_eternal_sprites();
|
||||
void load_temp_box_sprites(Pokemon_Party *party_data);
|
||||
void load_temp_box_sprites(PokeBox* box);
|
||||
void load_type_sprites(const u8* pkmn_type_table, int pkmn_index, int dex_offset, bool is_caught);
|
||||
void add_menu_box(int options, int startTileX, int startTileY);
|
||||
void add_menu_box(int startTileX, int startTileY, int width, int height);
|
||||
|
|
@ -135,6 +133,6 @@ void fennel_speak(int frame);
|
|||
int get_curr_flex_background();
|
||||
void update_y_offset();
|
||||
void erase_textbox_tiles();
|
||||
void update_front_box_sprite(Simplified_Pokemon *curr_pkmn);
|
||||
void update_menu_sprite(Pokemon_Party *party_data, int index, int frame);
|
||||
void update_front_box_sprite(GBPokemon *curr_pkmn);
|
||||
void update_menu_sprite(PokeBox* box, int index, int frame);
|
||||
#endif
|
||||
996
payload_builder copy.cpp
Normal file
996
payload_builder copy.cpp
Normal file
|
|
@ -0,0 +1,996 @@
|
|||
#include "payloads/payload_builder.h"
|
||||
#include "gb_rom_values/base_gb_rom_struct.h"
|
||||
#include "payloads/z80_asm.h"
|
||||
#include "../../../include/debug_mode.h"
|
||||
#include <cstring>
|
||||
|
||||
#define DATA_LOC (SHOW_DATA_PACKETS ? curr_rom.transferStringLocation : curr_rom.wEnemyMonSpecies)
|
||||
#define DEBUG_PAYLOADS (false && DEBUG_MODE)
|
||||
|
||||
void init_payload(byte *payload_buffer, const GB_ROM &curr_rom, int type, bool debug)
|
||||
{
|
||||
if (DEBUG_PAYLOADS)
|
||||
{
|
||||
debug = true;
|
||||
}
|
||||
|
||||
(void)type;
|
||||
/* 10 RNG bytes
|
||||
8 Preamble bytes
|
||||
418 / 441 Party bytes
|
||||
7 Preamble bytes
|
||||
194 Patch list bytes (last 2 are unused)
|
||||
|
||||
637 / 660 total bytes
|
||||
*/
|
||||
if ((curr_rom.generation == 1 && curr_rom.version != YELLOW_ID))
|
||||
{
|
||||
std::vector<z80_jump *> jump_vector;
|
||||
std::vector<z80_variable *> var_vector;
|
||||
|
||||
z80_asm_handler z80_rng_seed(0x0A, curr_rom.wSerialOtherGameboyRandomNumberListBlock + 8);
|
||||
z80_asm_handler z80_payload(0x1AA, curr_rom.wSerialEnemyDataBlock);
|
||||
z80_asm_handler z80_patchlist(0xC9, curr_rom.wSerialEnemyMonsPatchList);
|
||||
|
||||
z80_jump asm_start(&jump_vector);
|
||||
z80_jump save_box(&jump_vector);
|
||||
z80_jump remove_array_loop(&jump_vector);
|
||||
z80_jump packet_loop(&jump_vector);
|
||||
z80_jump fe_bypass(&jump_vector);
|
||||
z80_jump send_packet_loop(&jump_vector);
|
||||
|
||||
z80_variable array_counter(&var_vector, 1, 0x00); // 1 byte to store the current array counter
|
||||
z80_variable removal_array(&var_vector); // 40 byte storage for list of Pokemon to remove, plus a permanent array terminator
|
||||
|
||||
byte removal_array_data[41];
|
||||
for (int i = 0; i < 41; i++)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
removal_array_data[i] = (i < 30 ? (29 - i) : 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
removal_array_data[i] = (i < 30 ? 0xFD : 0xFF);
|
||||
}
|
||||
}
|
||||
removal_array.load_data(41, removal_array_data);
|
||||
z80_variable transfer_wait_string(&var_vector, 13, // SENDING DATA
|
||||
0x92, 0x84, 0x8D, 0x83, 0x88, 0x8D, 0x86, 0x7F, 0x83, 0x80, 0x93, 0x80, 0x50);
|
||||
z80_variable custom_name(&var_vector, 11, // FENNEL
|
||||
0x85, 0x84, 0x8D, 0x8D, 0x84, 0x8B, 0x50, 0x50, 0x50, 0x50, 0x50);
|
||||
|
||||
// RNG Seed
|
||||
// Location of the entrance vector
|
||||
z80_rng_seed.index = 5; // Set the entrance vector
|
||||
z80_rng_seed.JP(asm_start.place_direct_jump(&z80_rng_seed) | T_U16);
|
||||
|
||||
// Preamble
|
||||
// At 0x00, 0x07 in length
|
||||
// Must be filled with 0xFD
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
z80_payload.add_byte(0xFD);
|
||||
}
|
||||
|
||||
// Rival name
|
||||
// At 0x07, 0x0B in length
|
||||
// Set to stored name
|
||||
z80_payload.index = 0x07;
|
||||
custom_name.insert_variable(&z80_payload);
|
||||
|
||||
// Number of Pokemon
|
||||
// At 0x12, 0x01 in length
|
||||
// Does not need to be set
|
||||
z80_payload.index = 0x12;
|
||||
z80_payload.add_byte(0x06);
|
||||
|
||||
// Pokemon list
|
||||
// At 0x13, can be up to 0x1A2 / 0x1B9 bytes in length.
|
||||
// Calculate the number of Pokemon names that need to be printed,
|
||||
// and add them to the list. Then terminate the list.
|
||||
z80_payload.index = 0x13;
|
||||
int distance = curr_rom.stack_overwrite_location - curr_rom.print_string_start;
|
||||
distance /= 20; // Automatically truncated, so it won't overshoot
|
||||
|
||||
for (int i = 0; i < distance; i++)
|
||||
{
|
||||
z80_payload.add_byte(curr_rom.short_pkmn_name);
|
||||
}
|
||||
z80_payload.add_byte(curr_rom.pointer_pkmn_name);
|
||||
z80_payload.add_byte(0xFF);
|
||||
|
||||
// Patchlist preamble
|
||||
// At 0x1B4 / 0x1D7, 0x07 in length
|
||||
// Set as five 0xFD and two 0xFF
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
z80_patchlist.add_byte(i < 5 ? 0xFD : 0xFF);
|
||||
}
|
||||
|
||||
// Patchlist
|
||||
// At 0x1BB / 0x1DE, 0xC2 in length (0xC4, but the last 2 are unused)
|
||||
// Fill with custom code
|
||||
asm_start.set_start(&z80_patchlist);
|
||||
|
||||
/* Write transferring message to screen: */
|
||||
// call ClearScreen
|
||||
z80_patchlist.CALL(curr_rom.clearScreen | T_U16);
|
||||
z80_patchlist.LD(HL, curr_rom.textBorderUppLeft | T_U16);
|
||||
z80_patchlist.LD(C, curr_rom.textBorderWidth | T_U8);
|
||||
z80_patchlist.LD(B, curr_rom.textBorderHeight | T_U8);
|
||||
z80_patchlist.CALL(curr_rom.CableClub_TextBoxBorder | T_U16);
|
||||
z80_patchlist.LD(HL, curr_rom.transferStringLocation | T_U16);
|
||||
z80_patchlist.LD(DE, transfer_wait_string.place_ptr(&z80_patchlist) | T_U16);
|
||||
z80_patchlist.CALL(curr_rom.placeString | T_U16);
|
||||
|
||||
/* Build the packet */
|
||||
// HL is the current data pointer
|
||||
// DE is the destination pointer
|
||||
// A is the checksum
|
||||
// B is the 0xFE flag byte
|
||||
// C is the counter
|
||||
send_packet_loop.set_start(&z80_patchlist);
|
||||
|
||||
z80_patchlist.LD(HL, (DATA_LOC + PACKET_SIZE + 3) | T_U16); // Load the next data location into HL
|
||||
z80_patchlist.LD(A, HLI_PTR);
|
||||
z80_patchlist.LD(H, HL_PTR);
|
||||
z80_patchlist.LD(L, A);
|
||||
z80_patchlist.LD(DE, (DATA_LOC + 2) | T_U16); // Enemy Pokemon data, should be unused
|
||||
z80_patchlist.XOR(A, A); // Clear the register
|
||||
z80_patchlist.LD(B, A); // Clear B as well
|
||||
z80_patchlist.LD(C, A); // Clear C as well
|
||||
z80_patchlist.PUSH(AF);
|
||||
packet_loop.set_start(&z80_patchlist);
|
||||
z80_patchlist.LD(B, 0x00 | T_U8); // Reset the flag byte
|
||||
z80_patchlist.POP(AF);
|
||||
z80_patchlist.ADD(A, HL_PTR); // Add the current data to the checksum
|
||||
z80_patchlist.PUSH(AF);
|
||||
z80_patchlist.LD(A, 0xFE);
|
||||
z80_patchlist.CP(A, HL_PTR); // Compare the current data to 0xFE
|
||||
z80_patchlist.LD(A, HLI_PTR); // Load HL's data into A for modification (if need be)
|
||||
|
||||
// If HL's data is 0xFE
|
||||
z80_patchlist.JR(NZ_F, fe_bypass.place_relative_jump(&z80_patchlist) | T_I8);
|
||||
z80_patchlist.DEC(A);
|
||||
z80_patchlist.INC(B); // Set flag
|
||||
|
||||
fe_bypass.set_start(&z80_patchlist);
|
||||
z80_patchlist.LD(DE_PTR, A); // Place the data in
|
||||
z80_patchlist.INC(DE);
|
||||
z80_patchlist.PUSH(AF);
|
||||
z80_patchlist.LD(A, B);
|
||||
z80_patchlist.LD(DE_PTR, A); // Place the flag in as well
|
||||
z80_patchlist.POP(AF);
|
||||
z80_patchlist.INC(DE);
|
||||
z80_patchlist.INC(C);
|
||||
z80_patchlist.LD(A, DATA_PER_PACKET - 1);
|
||||
z80_patchlist.CP(A, C);
|
||||
z80_patchlist.JR(NC_F, packet_loop.place_relative_jump(&z80_patchlist) | T_I8); // If all the data has been set, send the rest of the data
|
||||
z80_patchlist.POP(AF);
|
||||
z80_patchlist.RES(7 | T_BIT, A); // Reset bit 7 of the checksum, guaranteeing that it will never be 0xFE
|
||||
z80_patchlist.LD(DE_PTR, A);
|
||||
z80_patchlist.INC(DE);
|
||||
z80_patchlist.LD(A, H);
|
||||
z80_patchlist.LD(DE_PTR, A);
|
||||
z80_patchlist.INC(DE);
|
||||
z80_patchlist.LD(A, L);
|
||||
z80_patchlist.LD(DE_PTR, A);
|
||||
|
||||
// z80_patchlist.LD(HL, curr_rom.garbageDataLocation | T_U16);
|
||||
|
||||
/* Transfer box data packet: */
|
||||
z80_patchlist.LD(A, (debug ? 0x02 : 0x01) | T_U8); // Make sure GB is the slave, master if debug
|
||||
z80_patchlist.LDH((curr_rom.hSerialConnectionStatus & 0xFF) | T_U8, A); // Since hSerialConnectionStatus is at 0xFFxx we can use this method instead
|
||||
z80_patchlist.LD(HL, DATA_LOC | T_U16);
|
||||
z80_patchlist.LD(HL_PTR, 0xFD | T_U8); // set the start of the data to 0xFD so Serial_ExchangeBytes is happy
|
||||
z80_patchlist.INC(HL);
|
||||
z80_patchlist.LD(HL_PTR, 0x00 | T_U8); // add a 0x00 after the 0xFD to prevent further 0xFDs from being interpreted as part of the preamble
|
||||
z80_patchlist.DEC(HL); // Reset HL back so it points to 0xFD
|
||||
z80_patchlist.LD(DE, (DATA_LOC + PACKET_SIZE) | T_U16); // location to put stored data
|
||||
z80_patchlist.LD(BC, PACKET_SIZE | T_U16);
|
||||
if (debug) // Don't call serialExchangeBytes if debug is enabled
|
||||
{
|
||||
z80_patchlist.index += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_patchlist.CALL(curr_rom.Serial_ExchangeBytes | T_U16);
|
||||
}
|
||||
|
||||
z80_patchlist.LD(A, (DATA_LOC + PACKET_SIZE + 3 + 1) | T_U16);
|
||||
z80_patchlist.CP(A, 0xFF);
|
||||
z80_patchlist.JR(NZ_F, send_packet_loop.place_relative_jump(&z80_patchlist) | T_I8);
|
||||
|
||||
/* Recieve the Pokemon to remove */
|
||||
z80_patchlist.LD(HL, curr_rom.hSerialConnectionStatus | T_U16); // This can also be shortened
|
||||
z80_patchlist.LD(HL_PTR, (debug ? 0x02 : 0x01) | T_U8); // Make sure GB is the slave, master if debug
|
||||
z80_patchlist.LD(HL, curr_rom.garbageDataLocation | T_U16);
|
||||
z80_patchlist.LD(DE, removal_array.place_ptr(&z80_patchlist) | T_U16);
|
||||
z80_patchlist.LD(BC, 0x001E | T_U16); // Preamble does *not* count
|
||||
if (debug) // Don't add in the Serial_ExchangeBytes call if in debug
|
||||
{
|
||||
z80_patchlist.index += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_patchlist.CALL(curr_rom.Serial_ExchangeBytes | T_U16);
|
||||
}
|
||||
|
||||
/* Remove the transfered Pokemon */
|
||||
z80_patchlist.LD(HL, curr_rom.wRemoveMonFromBox | T_U16);
|
||||
z80_patchlist.LD(HL_PTR, 0x01 | T_U8); // != 0x00 specifies the current box
|
||||
remove_array_loop.set_start(&z80_patchlist);
|
||||
z80_patchlist.LD(A, array_counter.place_ptr(&z80_patchlist) | T_U16);
|
||||
z80_patchlist.LD(E, A);
|
||||
z80_patchlist.LD(D, 0x00 | T_U8);
|
||||
z80_patchlist.LD(HL, removal_array.place_ptr(&z80_patchlist) | T_U16);
|
||||
z80_patchlist.ADD(HL, DE);
|
||||
z80_patchlist.INC(A);
|
||||
z80_patchlist.LD(array_counter.place_ptr(&z80_patchlist) | T_U16, A);
|
||||
z80_patchlist.LD(A, curr_rom.wBoxCount | T_U16);
|
||||
z80_patchlist.LD(B, A);
|
||||
z80_patchlist.LD(A, HL_PTR);
|
||||
z80_patchlist.CP(A, 0xFF | T_U8);
|
||||
z80_patchlist.JR(Z_F, save_box.place_relative_jump(&z80_patchlist) | T_I8);
|
||||
z80_patchlist.CP(A, B);
|
||||
z80_patchlist.JR(NC_F, remove_array_loop.place_relative_jump(&z80_patchlist) | T_I8);
|
||||
z80_patchlist.LD(HL, curr_rom.wWhichPokemon | T_U16);
|
||||
z80_patchlist.LD(HL_PTR, A);
|
||||
if (DONT_REMOVE_PKMN)
|
||||
{
|
||||
z80_patchlist.index += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_patchlist.CALL(curr_rom._RemovePokemon | T_U16);
|
||||
}
|
||||
z80_patchlist.JR((remove_array_loop.place_relative_jump(&z80_patchlist) & 0xFF) | T_I8);
|
||||
|
||||
/* Save the current box */
|
||||
save_box.set_start(&z80_patchlist);
|
||||
z80_patchlist.LD(B, (curr_rom.SaveSAVtoSRAM1 >> 16) | T_U8); // Load ROM Bank
|
||||
z80_patchlist.LD(HL, curr_rom.SaveSAVtoSRAM1 | T_U16);
|
||||
z80_patchlist.CALL(curr_rom.Bankswitch | T_U16);
|
||||
z80_patchlist.LD(B, (curr_rom.SaveSAVtoSRAM1 >> 16) | T_U8); // Load ROM Bank
|
||||
z80_patchlist.LD(HL, curr_rom.SaveSAVtoSRAM2 | T_U16); // TODO: We probably don't have to load the ROM bank twice
|
||||
z80_patchlist.CALL(curr_rom.Bankswitch | T_U16);
|
||||
z80_patchlist.JP(curr_rom.SoftReset | T_U16);
|
||||
|
||||
// z80_patchlist.index += 5;
|
||||
|
||||
array_counter.insert_variable(&z80_patchlist);
|
||||
removal_array.insert_variable(&z80_payload);
|
||||
transfer_wait_string.insert_variable(&z80_patchlist);
|
||||
|
||||
// This payload works by placing Pokemon ID 0xFC's name in the stack, and causing a return to CD8E,
|
||||
// which is part of the RNG seed. From there we can jump anywhere- and we choose to jump to D887,
|
||||
// which is the rival's name. This code fixes the stack and jumps to the patchlist, which is where
|
||||
// our final code is.
|
||||
|
||||
// Update all the pointers
|
||||
for (unsigned int i = 0; i < var_vector.size(); i++)
|
||||
{
|
||||
var_vector.at(i)->update_ptrs();
|
||||
}
|
||||
for (unsigned int i = 0; i < jump_vector.size(); i++)
|
||||
{
|
||||
jump_vector.at(i)->update_jumps();
|
||||
}
|
||||
|
||||
// Combine the vectors into the full payload
|
||||
u8 *cur_out = payload_buffer;
|
||||
memcpy(cur_out, z80_rng_seed.data_vector.data(), z80_rng_seed.data_vector.size());
|
||||
cur_out += z80_rng_seed.data_vector.size();
|
||||
memcpy(cur_out, z80_payload.data_vector.data(), z80_payload.data_vector.size());
|
||||
cur_out += z80_payload.data_vector.size();
|
||||
memcpy(cur_out, z80_patchlist.data_vector.data(), z80_patchlist.data_vector.size());
|
||||
cur_out += z80_patchlist.data_vector.size();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
else if ((curr_rom.generation == 1 && curr_rom.version == YELLOW_ID))
|
||||
{
|
||||
std::vector<z80_jump *> jump_vector;
|
||||
std::vector<z80_variable *> var_vector;
|
||||
|
||||
z80_asm_handler z80_rng_seed(0x0A, curr_rom.wSerialOtherGameboyRandomNumberListBlock + 8);
|
||||
z80_asm_handler z80_payload(0x1AA, curr_rom.wSerialEnemyDataBlock - 8); // Subtracting 8 is because the data is shifted after patching, removing part of the enemy name. May change depending on language
|
||||
z80_asm_handler z80_patchlist(0xC9, curr_rom.wSerialEnemyMonsPatchList);
|
||||
|
||||
z80_jump asm_start(&jump_vector);
|
||||
z80_jump save_box(&jump_vector);
|
||||
z80_jump remove_array_loop(&jump_vector);
|
||||
z80_jump packet_loop(&jump_vector);
|
||||
z80_jump fe_bypass(&jump_vector);
|
||||
z80_jump send_packet_loop(&jump_vector);
|
||||
z80_jump skip_enemy_write(&jump_vector);
|
||||
|
||||
z80_jump test_loop(&jump_vector);
|
||||
|
||||
z80_variable array_counter(&var_vector, 1, 0x00); // 1 byte to store the current array counter
|
||||
z80_variable removal_array(&var_vector); // 40 byte storage for list of Pokemon to remove, plus a permanent array terminator
|
||||
|
||||
byte removal_array_data[41];
|
||||
for (int i = 0; i < 41; i++)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
removal_array_data[i] = (i < 30 ? (29 - i) : 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
removal_array_data[i] = (i < 30 ? 0xFD : 0xFF);
|
||||
}
|
||||
}
|
||||
removal_array.load_data(41, removal_array_data);
|
||||
z80_variable transfer_wait_string(&var_vector, 13, // SENDING DATA
|
||||
0x92, 0x84, 0x8D, 0x83, 0x88, 0x8D, 0x86, 0x7F, 0x83, 0x80, 0x93, 0x80, 0x50);
|
||||
z80_variable custom_name(&var_vector, 11, // FENNEL
|
||||
0x85, 0x84, 0x8D, 0x8D, 0x84, 0x8B, 0x50, 0x50, 0x50, 0x50, 0x50);
|
||||
|
||||
// RNG Seed:
|
||||
// at 0x00, 0x0A in length
|
||||
// Can be empty
|
||||
|
||||
// Preamble
|
||||
// At 0x00, 0x07 in length
|
||||
// Must be filled with 0xFD
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
z80_payload.add_byte(0xFD);
|
||||
}
|
||||
|
||||
// Rival name
|
||||
// At 0x07, 0x0B in length
|
||||
// Set to stored name
|
||||
z80_payload.index = 0x07;
|
||||
custom_name.insert_variable(&z80_payload);
|
||||
|
||||
// Number of Pokemon
|
||||
// At 0x12, 0x01 in length
|
||||
// 2 or higher, 0xE8 for JPN
|
||||
z80_payload.index = 0x12;
|
||||
z80_payload.add_byte(0x02);
|
||||
|
||||
// Pokemon list
|
||||
// At 0x13, is usually 6 bytes and 1 terminator
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
z80_payload.add_byte(i < 6 ? i + 1 : 0xFF);
|
||||
}
|
||||
|
||||
// Pokemon data
|
||||
// Specific for each language
|
||||
|
||||
// Mon #1 HP
|
||||
z80_payload.add_bytes(2,
|
||||
0x00, 0x00);
|
||||
|
||||
// Mon #2 data
|
||||
z80_payload.index = 0x46;
|
||||
z80_payload.add_bytes(9,
|
||||
0x4E, 0x4E, 0x4E, 0x00, 0x01, 0x80, 0x80, 0xD4, 0xCF);
|
||||
|
||||
z80_payload.add_bytes(2, asm_start.place_pointer(&z80_payload), 0x00); // These values must not have any control characters in them.
|
||||
|
||||
z80_payload.add_bytes(33,
|
||||
0x4E, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4E, 0x50, 0x00, 0x00,
|
||||
0x00, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x59);
|
||||
|
||||
// Mon #2 name
|
||||
z80_payload.index = 0x16F;
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
z80_payload.add_byte(0x4E);
|
||||
}
|
||||
|
||||
// Now that the ACE has been set up, we can use the space between Mon #2's data and Mon #2's name to put our code.
|
||||
// Since this space is larger than the patchlist, we will be able to fit everything in it
|
||||
|
||||
// Patchlist preamble
|
||||
// At 0x1B4 0x07 in length
|
||||
// Set as five 0xFD, the 0xFF will be added as part of the patch list.
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
z80_patchlist.add_byte(0xFD);
|
||||
}
|
||||
|
||||
z80_payload.index = 0x72;
|
||||
|
||||
array_counter.insert_variable(&z80_payload);
|
||||
removal_array.insert_variable(&z80_payload);
|
||||
transfer_wait_string.insert_variable(&z80_payload);
|
||||
|
||||
asm_start.set_start(&z80_payload);
|
||||
|
||||
z80_payload.CALL(0x2233 | T_U16); // Stop the battle music
|
||||
|
||||
/* Write transferring message to screen: */
|
||||
// call ClearScreen
|
||||
z80_payload.CALL(curr_rom.clearScreen | T_U16);
|
||||
z80_payload.LD(HL, curr_rom.textBorderUppLeft | T_U16);
|
||||
z80_payload.LD(C, curr_rom.textBorderWidth | T_U8);
|
||||
z80_payload.LD(B, curr_rom.textBorderHeight | T_U8);
|
||||
z80_payload.CALL(curr_rom.CableClub_TextBoxBorder | T_U16);
|
||||
z80_payload.LD(HL, curr_rom.transferStringLocation | T_U16);
|
||||
z80_payload.LD(DE, transfer_wait_string.place_ptr(&z80_payload) | T_U16);
|
||||
z80_payload.CALL(curr_rom.placeString | T_U16);
|
||||
z80_payload.JR(skip_enemy_write.place_relative_jump(&z80_payload) | T_I8); // This is a simple way to avoid the enemy name placement. Might have to modify for other languages
|
||||
|
||||
z80_payload.index = 0xCA;
|
||||
|
||||
skip_enemy_write.set_start(&z80_payload);
|
||||
|
||||
// Reload the save data to remove any data that was overwritten during exploit entry
|
||||
z80_payload.LD(B, (curr_rom.LoadCurrentBoxData >> 16) | T_U8);
|
||||
z80_payload.LD(HL, curr_rom.LoadCurrentBoxData | T_U16);
|
||||
z80_payload.CALL(curr_rom.Bankswitch | T_U16);
|
||||
if (!debug)
|
||||
{
|
||||
/* Build the packet */
|
||||
// HL is the current data pointer
|
||||
// DE is the destination pointer
|
||||
// A is the checksum
|
||||
// B is the 0xFE flag byte
|
||||
// C is the counter
|
||||
send_packet_loop.set_start(&z80_payload);
|
||||
|
||||
z80_payload.LD(HL, (DATA_LOC + PACKET_SIZE + 3) | T_U16); // Load the next data location into HL
|
||||
z80_payload.LD(A, HLI_PTR);
|
||||
z80_payload.LD(H, HL_PTR);
|
||||
z80_payload.LD(L, A);
|
||||
z80_payload.LD(DE, (DATA_LOC + 2) | T_U16); // Enemy Pokemon data, should be unused
|
||||
z80_payload.XOR(A, A); // Clear the register
|
||||
z80_payload.LD(B, A); // Clear B as well
|
||||
z80_payload.LD(C, A); // Clear C as well
|
||||
z80_payload.PUSH(AF);
|
||||
packet_loop.set_start(&z80_payload);
|
||||
z80_payload.LD(B, 0x00 | T_U8); // Reset the flag byte
|
||||
z80_payload.POP(AF);
|
||||
z80_payload.ADD(A, HL_PTR); // Add the current data to the checksum
|
||||
z80_payload.PUSH(AF);
|
||||
z80_payload.LD(A, 0xFE);
|
||||
z80_payload.CP(A, HL_PTR); // Compare the current data to 0xFE
|
||||
z80_payload.LD(A, HLI_PTR); // Load HL's data into A for modification (if need be)
|
||||
|
||||
// If HL's data is 0xFE
|
||||
z80_payload.JR(NZ_F, fe_bypass.place_relative_jump(&z80_payload) | T_I8);
|
||||
z80_payload.DEC(A);
|
||||
z80_payload.INC(B); // Set flag
|
||||
|
||||
fe_bypass.set_start(&z80_payload);
|
||||
z80_payload.LD(DE_PTR, A); // Place the data in
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.PUSH(AF);
|
||||
z80_payload.LD(A, B);
|
||||
z80_payload.LD(DE_PTR, A); // Place the flag in as well
|
||||
z80_payload.POP(AF);
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.INC(C);
|
||||
z80_payload.LD(A, DATA_PER_PACKET - 1);
|
||||
z80_payload.CP(A, C);
|
||||
z80_payload.JR(NC_F, packet_loop.place_relative_jump(&z80_payload) | T_I8); // If all the data has been set, send the rest of the data
|
||||
z80_payload.POP(AF);
|
||||
z80_payload.RES(7 | T_BIT, A); // Reset bit 7 of the checksum, guaranteeing that it will never be 0xFE
|
||||
z80_payload.LD(DE_PTR, A);
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.LD(A, H);
|
||||
|
||||
z80_payload.LD(DE_PTR, A);
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.LD(A, L);
|
||||
z80_payload.LD(DE_PTR, A);
|
||||
|
||||
/* Transfer box data packet: */
|
||||
z80_payload.LD(A, (debug ? 0x02 : 0x01) | T_U8); // Make sure GB is the slave, master if debug
|
||||
z80_payload.LDH((curr_rom.hSerialConnectionStatus & 0xFF) | T_U8, A); // Since hSerialConnectionStatus is at 0xFFxx we can use this method instead
|
||||
z80_payload.LD(HL, DATA_LOC | T_U16);
|
||||
z80_payload.LD(HL_PTR, 0xFD | T_U8); // set the start of the data to 0xFD so Serial_ExchangeBytes is happy
|
||||
z80_payload.INC(HL);
|
||||
z80_payload.LD(HL_PTR, 0x00 | T_U8); // add a 0x00 after the 0xFD to prevent further 0xFDs from being interpreted as part of the preamble
|
||||
z80_payload.DEC(HL); // Reset HL back so it points to 0xFD
|
||||
z80_payload.LD(DE, (DATA_LOC + PACKET_SIZE) | T_U16); // location to put stored data
|
||||
z80_payload.LD(BC, PACKET_SIZE | T_U16);
|
||||
if (debug) // Don't call serialExchangeBytes if debug is enabled
|
||||
{
|
||||
z80_payload.index += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_payload.CALL(curr_rom.Serial_ExchangeBytes | T_U16);
|
||||
}
|
||||
|
||||
z80_payload.LD(A, (DATA_LOC + PACKET_SIZE + 3 + 1) | T_U16);
|
||||
z80_payload.CP(A, 0xFF);
|
||||
if (debug && false) // Don't compare the "recieved" data if in debug
|
||||
{
|
||||
z80_payload.index += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_payload.JR(NZ_F, send_packet_loop.place_relative_jump(&z80_payload) | T_I8);
|
||||
}
|
||||
}
|
||||
/* Recieve the Pokemon to remove */
|
||||
z80_payload.LD(HL, curr_rom.hSerialConnectionStatus | T_U16); // This can also be shortened
|
||||
z80_payload.LD(HL_PTR, (debug ? 0x02 : 0x01) | T_U8); // Make sure GB is the slave, master if debug
|
||||
z80_payload.LD(HL, curr_rom.garbageDataLocation | T_U16);
|
||||
z80_payload.LD(DE, removal_array.place_ptr(&z80_payload) | T_U16);
|
||||
z80_payload.LD(BC, 0x001E | T_U16); // Preamble does *not* count
|
||||
if (debug) // Don't add in the Serial_ExchangeBytes call if in debug
|
||||
{
|
||||
z80_payload.index += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_payload.CALL(curr_rom.Serial_ExchangeBytes | T_U16);
|
||||
}
|
||||
|
||||
/* Remove the transfered Pokemon */
|
||||
z80_payload.LD(HL, curr_rom.wRemoveMonFromBox | T_U16);
|
||||
z80_payload.LD(HL_PTR, 0x01 | T_U8); // != 0x00 specifies the current box
|
||||
remove_array_loop.set_start(&z80_payload);
|
||||
z80_payload.LD(A, array_counter.place_ptr(&z80_payload) | T_U16);
|
||||
z80_payload.LD(E, A);
|
||||
z80_payload.LD(D, 0x00 | T_U8);
|
||||
z80_payload.LD(HL, removal_array.place_ptr(&z80_payload) | T_U16);
|
||||
z80_payload.ADD(HL, DE);
|
||||
z80_payload.INC(A);
|
||||
z80_payload.LD(array_counter.place_ptr(&z80_payload) | T_U16, A);
|
||||
z80_payload.LD(A, curr_rom.wBoxCount | T_U16);
|
||||
z80_payload.LD(B, A);
|
||||
z80_payload.LD(A, HL_PTR);
|
||||
z80_payload.CP(A, 0xFF | T_U8);
|
||||
z80_payload.JR(Z_F, save_box.place_relative_jump(&z80_payload) | T_I8);
|
||||
z80_payload.CP(A, B);
|
||||
z80_payload.JR(NC_F, remove_array_loop.place_relative_jump(&z80_payload) | T_I8);
|
||||
z80_payload.LD(HL, curr_rom.wWhichPokemon | T_U16);
|
||||
z80_payload.LD(HL_PTR, A);
|
||||
if (DONT_REMOVE_PKMN)
|
||||
{
|
||||
z80_payload.index += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_payload.LD(B, (curr_rom._RemovePokemon >> 16) | T_U8); // Load ROM Bank
|
||||
z80_payload.LD(HL, curr_rom._RemovePokemon | T_U16);
|
||||
z80_payload.CALL(curr_rom.Bankswitch | T_U16);
|
||||
}
|
||||
z80_payload.JR((remove_array_loop.place_relative_jump(&z80_payload) & 0xFF) | T_I8);
|
||||
|
||||
// We need to move this in order to not corrupt the 4E's
|
||||
z80_payload.JR((save_box.place_relative_jump(&z80_payload) & 0xFF) | T_I8);
|
||||
z80_payload.index = 0x17A;
|
||||
|
||||
/* Save the current box */
|
||||
save_box.set_start(&z80_payload);
|
||||
z80_payload.LD(B, (curr_rom.SaveSAVtoSRAM1 >> 16) | T_U8); // Load ROM Bank
|
||||
z80_payload.LD(HL, curr_rom.SaveSAVtoSRAM1 | T_U16);
|
||||
z80_payload.CALL(curr_rom.Bankswitch | T_U16);
|
||||
z80_payload.CALL(curr_rom.SaveSAVtoSRAM2 | T_U16); // The bank is already loaded, we don't have to load it again
|
||||
z80_payload.JP(curr_rom.SoftReset | T_U16);
|
||||
|
||||
// z80_payload.index += 5;
|
||||
|
||||
// Patchlist
|
||||
// At 0x1BB / 0x1DE, 0xC2 in length (0xC4, but the last 2 are unused)
|
||||
z80_patchlist.generate_patchlist(&z80_payload);
|
||||
|
||||
// This payload works by placing Pokemon ID 0xFC's name in the stack, and causing a return to CD8E,
|
||||
// which is part of the RNG seed. From there we can jump anywhere- and we choose to jump to D887,
|
||||
// which is the rival's name. This code fixes the stack and jumps to the patchlist, which is where
|
||||
// our final code is.
|
||||
|
||||
// Update all the pointers
|
||||
for (unsigned int i = 0; i < var_vector.size(); i++)
|
||||
{
|
||||
var_vector.at(i)->update_ptrs();
|
||||
}
|
||||
for (unsigned int i = 0; i < jump_vector.size(); i++)
|
||||
{
|
||||
jump_vector.at(i)->update_jumps();
|
||||
}
|
||||
|
||||
// Combine the vectors into the full payload
|
||||
u8 *cur_out = payload_buffer;
|
||||
memcpy(cur_out, z80_rng_seed.data_vector.data(), z80_rng_seed.data_vector.size());
|
||||
cur_out += z80_rng_seed.data_vector.size();
|
||||
memcpy(cur_out, z80_payload.data_vector.data(), z80_payload.data_vector.size());
|
||||
cur_out += z80_payload.data_vector.size();
|
||||
memcpy(cur_out, z80_patchlist.data_vector.data(), z80_patchlist.data_vector.size());
|
||||
cur_out += z80_patchlist.data_vector.size();
|
||||
|
||||
return;
|
||||
|
||||
/*
|
||||
else if (type == EVENT)
|
||||
{
|
||||
// ld a, $03
|
||||
payload_storage[offset++] = 0x3A;
|
||||
payload_storage[offset++] = 0x03;
|
||||
|
||||
// call OpenSRAM
|
||||
payload_storage[offset++] = 0xC3;
|
||||
payload_storage[offset++] = (curr_rom.OpenSRAM >> 0) & 0xFF;
|
||||
payload_storage[offset++] = (curr_rom.OpenSRAM >> 8) & 0xFF;
|
||||
|
||||
// ld de, $BEB0
|
||||
payload_storage[offset++] = 0x11;
|
||||
payload_storage[offset++] = 0xB0;
|
||||
payload_storage[offset++] = 0xBE;
|
||||
|
||||
// ld bc, $150
|
||||
payload_storage[offset++] = 0x01;
|
||||
payload_storage[offset++] = 0x50;
|
||||
payload_storage[offset++] = 0x01;
|
||||
|
||||
// ld hl, ???
|
||||
payload_storage[offset++] = 0x21;
|
||||
payload_storage[offset++] = 0x00;
|
||||
payload_storage[offset++] = 0x00;
|
||||
|
||||
// CUSTOM EVENT SCRIPT:
|
||||
// Start with the table data
|
||||
int init_offset = offset;
|
||||
insert_ext_copy_cmd(&offset, 0x11410E, 0xD930, 18); // Copy text pointers
|
||||
insert_ext_copy_cmd(&offset, 0x00C120, 0xC140, 10); //
|
||||
insert_ext_copy_cmd(&offset, 0x00C220, 0xC240, 16); //
|
||||
byte temp[] = {0xD0, 0x0A};
|
||||
insert_int_copy_cmd(&offset, 0xD4E9, 2, temp); //
|
||||
byte temp1[] = {0x15, 0x05};
|
||||
insert_int_copy_cmd(&offset, 0xD517, 2, temp1); //
|
||||
byte temp2[] = {0x30, 0xD9};
|
||||
insert_int_copy_cmd(&offset, 0xD36B, 2, temp2); //
|
||||
byte temp3[] = {0x0B, 0xF0, 0xFF};
|
||||
insert_int_copy_cmd(&offset, 0xD5D3, 3, temp3); //
|
||||
byte temp4[] = {0x05};
|
||||
insert_int_copy_cmd(&offset, 0xD4E0, 1, temp4); //
|
||||
byte temp5[] = {0x44, 0xD9, 0x08, 0x21, 0x54, 0xD9, 0xCD, 0x68, 0x31, 0x21, 0xB0, 0xC1, 0x00, 0x00, 0xC3, 0xD2, 0x23, 0x01, 0x00, 0x5E, 0xD8, 0xD8, 0xC9, 0xD8, 0xC9, 0xD8, 0xC9, 0xD8, 0xC9, 0x00, 0x8C, 0xB8, 0xB4, 0xB4, 0xE7, 0x50, 0x08, 0x3E, 0x83, 0xCD, 0x8B, 0x11, 0xCD, 0x3E, 0x37, 0xC3, 0xD2, 0x23};
|
||||
insert_int_copy_cmd(&offset, 0xD942, 48, temp5); //
|
||||
payload_storage[offset++] = 0xFF;
|
||||
|
||||
|
||||
// call CloseSRAM
|
||||
payload_storage[offset++] = 0xC3;
|
||||
payload_storage[offset++] = (curr_rom.CloseSRAM >> 0) & 0xFF;
|
||||
payload_storage[offset++] = (curr_rom.CloseSRAM >> 8) & 0xFF;
|
||||
|
||||
// call SoftReset
|
||||
payload_storage[offset++] = 0xC3;
|
||||
payload_storage[offset++] = (curr_rom.SoftReset >> 0) & 0xFF;
|
||||
payload_storage[offset++] = (curr_rom.SoftReset >> 8) & 0xFF;
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
else if (curr_rom.generation == 2)
|
||||
{
|
||||
std::vector<z80_jump *> jump_vector;
|
||||
std::vector<z80_variable *> var_vector;
|
||||
|
||||
z80_asm_handler z80_rng_seed(0x0A, curr_rom.wSerialOtherGameboyRandomNumberListBlock);
|
||||
z80_asm_handler z80_payload(0x1CD, curr_rom.wSerialEnemyDataBlock); // wOTPartyData
|
||||
z80_asm_handler z80_patchlist(0xC9, curr_rom.wSerialEnemyMonsPatchList); // wOTPatchLists
|
||||
|
||||
/*
|
||||
Initally the entire wLinkData is copied into the data section at D26B.
|
||||
then, CopyBytes is called four times within link.skip_mail:
|
||||
1. It copies 0xB bytes from wLinkData to wOTPlayerName (D26B)
|
||||
2. It copies 0x8 bytes from where the previous one ended (D280) to wOTPartyCount
|
||||
3. It copies 0x2 bytes from where the previous one ended (D276) to wOTPlayerID
|
||||
4. It copies 0x1A4 bytes from where the previous one ended (D288) to wOTPartyMons
|
||||
|
||||
8 bytes aren't overwritten when copied over (D278-D28F), which is where the weird offset comes from. These bytes are index 0xE through 0x15 in the original data
|
||||
By having 9 bytes of 0xFD, the offset ends up working out correctly.
|
||||
*/
|
||||
|
||||
z80_jump asm_start(&jump_vector);
|
||||
z80_jump save_box(&jump_vector);
|
||||
z80_jump remove_array_loop(&jump_vector);
|
||||
z80_jump jump_to_party(&jump_vector);
|
||||
z80_jump jump_to_payload(&jump_vector);
|
||||
z80_jump packet_loop(&jump_vector);
|
||||
z80_jump fe_bypass(&jump_vector);
|
||||
z80_jump send_packet_loop(&jump_vector);
|
||||
|
||||
z80_variable array_counter(&var_vector, 1, 0x00); // 1 byte to store the current array counter
|
||||
z80_variable removal_array(&var_vector); // 40 byte storage for list of Pokemon to remove, plus a permanent array terminator
|
||||
byte removal_array_data[41];
|
||||
for (int i = 0; i < 41; i++)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
removal_array_data[i] = (i < 30 ? (29 - i) : 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
removal_array_data[i] = (i < 30 ? 0xFD : 0xFF);
|
||||
}
|
||||
}
|
||||
removal_array.load_data(41, removal_array_data);
|
||||
z80_variable transfer_wait_string(&var_vector, 13, // SENDING DATA
|
||||
0x92, 0x84, 0x8D, 0x83, 0x88, 0x8D, 0x86, 0x7F, 0x83, 0x80, 0x93, 0x80, 0x50);
|
||||
z80_variable custom_name(&var_vector, 11, // FENNEL
|
||||
0x85, 0x84, 0x8D, 0x8D, 0x84, 0x8B, 0x50, 0x50, 0x50, 0x50, 0x50);
|
||||
|
||||
// RNG Seed:
|
||||
// at 0x00, 0x0A in length
|
||||
// Does not need to be set
|
||||
|
||||
// Preamble
|
||||
// At 0x00, 0x09 in length
|
||||
// Must be filled with 0xFD
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
z80_payload.add_byte(0xFD);
|
||||
}
|
||||
|
||||
// Preamble/Rival name
|
||||
// At 0x00, 0x1C5 in length
|
||||
// Set to stored name
|
||||
int distance = curr_rom.stack_overwrite_location - curr_rom.print_string_start;
|
||||
int remainder = distance % 40;
|
||||
distance /= 40; // Automatically truncated, so it won't overshoot
|
||||
distance -= 8; // There will be 8 extra bytes due to how the copy functions work.
|
||||
|
||||
for (int i = 0; i < distance; i++)
|
||||
{
|
||||
z80_payload.add_byte(curr_rom.short_pkmn_name);
|
||||
}
|
||||
for (int i = 0; i < remainder; i++)
|
||||
{
|
||||
z80_payload.add_byte(0x80);
|
||||
}
|
||||
|
||||
z80_payload.index -= 1; // Prep for the direct jump, since it usually has to jump forward one for the ASM call
|
||||
jump_to_payload.place_direct_jump(&z80_payload);
|
||||
z80_payload.index += 3;
|
||||
z80_payload.add_byte(0x50); // String terminator
|
||||
|
||||
// Saving the box overwrites our code, so we need to move it here.
|
||||
jump_to_party.set_start(&z80_payload);
|
||||
z80_payload.LD(A, curr_rom.SaveBox >> 16 | T_U8);
|
||||
z80_payload.RST(0x10); // Bank switch
|
||||
z80_payload.CALL(curr_rom.SaveBox | T_U16);
|
||||
|
||||
z80_payload.JP(curr_rom.SoftReset | T_U16);
|
||||
|
||||
// Patchlist preamble
|
||||
// At 0x1B4 / 0x1D7, 0x07 in length
|
||||
// Set as five 0xFD and two 0xFF
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
z80_patchlist.add_byte(i < 5 ? 0xFD : 0xFF);
|
||||
}
|
||||
|
||||
// Patchlist
|
||||
// At 0x1DE, 194 in length
|
||||
// Fill with custom code
|
||||
|
||||
// Write transferring message to screen:
|
||||
// call ClearScreen
|
||||
jump_to_payload.set_start(&z80_patchlist);
|
||||
z80_patchlist.CALL(curr_rom.clearScreen | T_U16);
|
||||
|
||||
z80_patchlist.LD(HL, curr_rom.textBorderUppLeft | T_U16);
|
||||
z80_patchlist.LD(C, curr_rom.textBorderWidth | T_U8);
|
||||
z80_patchlist.LD(B, curr_rom.textBorderHeight | T_U8);
|
||||
z80_patchlist.LD(A, curr_rom.CableClub_TextBoxBorder >> 16 | T_U8);
|
||||
z80_patchlist.RST(0x10); // Bank switch
|
||||
z80_patchlist.CALL(curr_rom.CableClub_TextBoxBorder | T_U16);
|
||||
z80_patchlist.LD(HL, curr_rom.transferStringLocation | T_U16);
|
||||
z80_patchlist.LD(DE, transfer_wait_string.place_ptr(&z80_patchlist) | T_U16);
|
||||
|
||||
// call PlaceString
|
||||
z80_patchlist.CALL(curr_rom.placeString | T_U16);
|
||||
|
||||
// call OpenSRAM
|
||||
z80_patchlist.LD(A, 0x01 | T_U8);
|
||||
z80_patchlist.CALL(curr_rom.OpenSRAM | T_U16);
|
||||
|
||||
/* Build the packet */
|
||||
// HL is the current data pointer
|
||||
// DE is the destination pointer
|
||||
// A is the checksum
|
||||
// B is the 0xFE flag byte
|
||||
// C is the counter
|
||||
send_packet_loop.set_start(&z80_patchlist);
|
||||
|
||||
z80_patchlist.LD(HL, (DATA_LOC + PACKET_SIZE + 3) | T_U16); // Load the next data location into HL
|
||||
z80_patchlist.LD(A, HLI_PTR);
|
||||
z80_patchlist.LD(H, HL_PTR);
|
||||
z80_patchlist.LD(L, A);
|
||||
|
||||
z80_patchlist.LD(DE, (DATA_LOC + 2) | T_U16); // Enemy Pokemon data, should be unused
|
||||
z80_patchlist.XOR(A, A); // Clear the register
|
||||
z80_patchlist.LD(B, A); // Clear B as well
|
||||
z80_patchlist.LD(C, A); // Clear C as well
|
||||
z80_patchlist.PUSH(AF);
|
||||
packet_loop.set_start(&z80_patchlist);
|
||||
z80_patchlist.LD(B, 0x00 | T_U8); // Reset the flag byte
|
||||
z80_patchlist.POP(AF);
|
||||
z80_patchlist.ADD(A, HL_PTR); // Add the current data to the checksum
|
||||
z80_patchlist.PUSH(AF);
|
||||
z80_patchlist.LD(A, 0xFE);
|
||||
z80_patchlist.CP(A, HL_PTR); // Compare the current data to 0xFE
|
||||
z80_patchlist.LD(A, HLI_PTR); // Load HL's data into A for modification (if need be)
|
||||
|
||||
// If HL's data is 0xFE
|
||||
z80_patchlist.JR(NZ_F, fe_bypass.place_relative_jump(&z80_patchlist) | T_I8);
|
||||
z80_patchlist.DEC(A);
|
||||
z80_patchlist.INC(B); // Set flag
|
||||
|
||||
fe_bypass.set_start(&z80_patchlist);
|
||||
z80_patchlist.LD(DE_PTR, A); // Place the data in
|
||||
z80_patchlist.INC(DE);
|
||||
z80_patchlist.PUSH(AF);
|
||||
z80_patchlist.LD(A, B);
|
||||
z80_patchlist.LD(DE_PTR, A); // Place the flag in as well
|
||||
z80_patchlist.POP(AF);
|
||||
z80_patchlist.INC(DE);
|
||||
z80_patchlist.INC(C);
|
||||
z80_patchlist.LD(A, DATA_PER_PACKET - 1);
|
||||
z80_patchlist.CP(A, C);
|
||||
z80_patchlist.JR(NC_F, packet_loop.place_relative_jump(&z80_patchlist) | T_I8); // If all the data has been set, send the rest of the data
|
||||
z80_patchlist.POP(AF);
|
||||
z80_patchlist.RES(7 | T_BIT, A); // Reset bit 7 of the checksum, guaranteeing that it will never be 0xFE
|
||||
z80_patchlist.LD(DE_PTR, A);
|
||||
z80_patchlist.INC(DE);
|
||||
z80_patchlist.LD(A, H);
|
||||
z80_patchlist.LD(DE_PTR, A);
|
||||
z80_patchlist.INC(DE);
|
||||
z80_patchlist.LD(A, L);
|
||||
z80_patchlist.LD(DE_PTR, A);
|
||||
|
||||
/* Transfer box data packet: */
|
||||
z80_patchlist.LD(A, (debug ? 0x02 : 0x01) | T_U8); // Make sure GB is the slave, master if debug
|
||||
z80_patchlist.LDH((curr_rom.hSerialConnectionStatus & 0xFF) | T_U8, A); // Since hSerialConnectionStatus is at 0xFFxx we can use this method instead
|
||||
z80_patchlist.LD(HL, DATA_LOC | T_U16);
|
||||
z80_patchlist.LD(HL_PTR, 0xFD | T_U8); // set the start of the data to 0xFD so Serial_ExchangeBytes is happy
|
||||
z80_patchlist.INC(HL);
|
||||
z80_patchlist.LD(HL_PTR, 0x00 | T_U8); // add a 0x00 after the 0xFD to prevent further 0xFDs from being interpreted as part of the preamble
|
||||
z80_patchlist.DEC(HL); // Reset HL back so it points to 0xFD
|
||||
z80_patchlist.LD(DE, (DATA_LOC + PACKET_SIZE) | T_U16); // location to put stored data
|
||||
z80_patchlist.LD(BC, PACKET_SIZE | T_U16);
|
||||
if (debug) // Don't call serialExchangeBytes if debug is enabled
|
||||
{
|
||||
z80_patchlist.index += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_patchlist.CALL(curr_rom.Serial_ExchangeBytes | T_U16);
|
||||
}
|
||||
|
||||
z80_patchlist.LD(A, (DATA_LOC + PACKET_SIZE + 3 + 1) | T_U16);
|
||||
z80_patchlist.CP(A, 0xFF);
|
||||
z80_patchlist.JR(NZ_F, send_packet_loop.place_relative_jump(&z80_patchlist) | T_I8);
|
||||
|
||||
// Recieve the Pokemon to remove
|
||||
z80_patchlist.LD(HL, curr_rom.hSerialConnectionStatus | T_U16); // This can also be shortened
|
||||
z80_patchlist.LD(HL_PTR, (debug ? 0x02 : 0x01) | T_U8); // Make sure GB is the slave, master if debug
|
||||
z80_patchlist.LD(HL, curr_rom.garbageDataLocation | T_U16);
|
||||
z80_patchlist.LD(DE, removal_array.place_ptr(&z80_patchlist) | T_U16);
|
||||
z80_patchlist.LD(BC, 0x001E | T_U16); // Preamble does *not* count
|
||||
if (debug) // Don't add in the Serial_ExchangeBytes call if in debug
|
||||
{
|
||||
z80_patchlist.index += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_patchlist.CALL(curr_rom.Serial_ExchangeBytes | T_U16);
|
||||
}
|
||||
|
||||
// Remove the transfered Pokemon
|
||||
z80_patchlist.LD(HL, curr_rom.wRemoveMonFromBox | T_U16);
|
||||
z80_patchlist.LD(HL_PTR, 0x01 | T_U8); // != 0x00 specifies the current box
|
||||
remove_array_loop.set_start(&z80_patchlist);
|
||||
z80_patchlist.LD(A, array_counter.place_ptr(&z80_patchlist) | T_U16);
|
||||
z80_patchlist.LD(E, A);
|
||||
z80_patchlist.LD(D, 0x00 | T_U8);
|
||||
z80_patchlist.LD(HL, removal_array.place_ptr(&z80_patchlist) | T_U16);
|
||||
z80_patchlist.ADD(HL, DE);
|
||||
z80_patchlist.INC(A);
|
||||
z80_patchlist.LD(array_counter.place_ptr(&z80_patchlist) | T_U16, A);
|
||||
z80_patchlist.LD(A, curr_rom.wBoxCount | T_U16);
|
||||
z80_patchlist.LD(B, A);
|
||||
z80_patchlist.LD(A, HL_PTR);
|
||||
z80_patchlist.CP(A, 0xFF | T_U8);
|
||||
z80_patchlist.JR(Z_F, save_box.place_relative_jump(&z80_patchlist) | T_I8);
|
||||
z80_patchlist.CP(A, B);
|
||||
z80_patchlist.JR(NC_F, remove_array_loop.place_relative_jump(&z80_patchlist) | T_I8);
|
||||
z80_patchlist.LD(HL, curr_rom.wWhichPokemon | T_U16);
|
||||
z80_patchlist.LD(HL_PTR, A);
|
||||
if (DONT_REMOVE_PKMN)
|
||||
{
|
||||
z80_patchlist.index += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_patchlist.LD(A, curr_rom._RemovePokemon >> 16 | T_U8);
|
||||
z80_patchlist.RST(0x10); // Bank switch
|
||||
z80_patchlist.CALL(curr_rom._RemovePokemon | T_U16);
|
||||
}
|
||||
z80_patchlist.JR(remove_array_loop.place_relative_jump(&z80_patchlist) | T_I8);
|
||||
|
||||
save_box.set_start(&z80_patchlist);
|
||||
z80_patchlist.JP(jump_to_party.place_direct_jump(&z80_patchlist) | T_U16); // jp pkmn list (because saving the box overwrites the data)
|
||||
|
||||
array_counter.insert_variable(&z80_patchlist);
|
||||
removal_array.insert_variable(&z80_payload);
|
||||
transfer_wait_string.insert_variable(&z80_patchlist);
|
||||
|
||||
// This payload works by placing Pokemon ID 0xFC's name in the stack, and causing a return to CD8E,
|
||||
// which is part of the RNG seed. From there we can jump anywhere- and we choose to jump to D887,
|
||||
// which is the rival's name. This code fixes the stack and jumps to the patchlist, which is where
|
||||
// our final code is.
|
||||
|
||||
// Update all the pointers
|
||||
for (unsigned int i = 0; i < var_vector.size(); i++)
|
||||
{
|
||||
var_vector.at(i)->update_ptrs();
|
||||
}
|
||||
for (unsigned int i = 0; i < jump_vector.size(); i++)
|
||||
{
|
||||
jump_vector.at(i)->update_jumps();
|
||||
}
|
||||
|
||||
// Combine the vectors into the full payload
|
||||
u8 *cur_out = payload_buffer;
|
||||
memcpy(cur_out, z80_rng_seed.data_vector.data(), z80_rng_seed.data_vector.size());
|
||||
cur_out += z80_rng_seed.data_vector.size();
|
||||
memcpy(cur_out, z80_payload.data_vector.data(), z80_payload.data_vector.size());
|
||||
cur_out += z80_payload.data_vector.size();
|
||||
memcpy(cur_out, z80_patchlist.data_vector.data(), z80_patchlist.data_vector.size());
|
||||
cur_out += z80_patchlist.data_vector.size();
|
||||
|
||||
return;
|
||||
|
||||
// This payload works by placing Pokemon ID 0xFC's name in the stack, and causing a return to CD8E,
|
||||
// which is part of the RNG seed. From there we can jump anywhere- and we choose to jump to D887,
|
||||
// which is the rival's name. This code fixes the stack and jumps to the patchlist, which is where
|
||||
// our final code is.
|
||||
}
|
||||
memset(payload_buffer, 0x00, PAYLOAD_SIZE);
|
||||
};
|
||||
|
||||
#if PAYLOAD_EXPORT_TEST
|
||||
#include <cstdio>
|
||||
#include "gb_rom_values/gb_rom_values.h"
|
||||
int main() // Rename to "main" to send the payload to test_payload.txt
|
||||
{
|
||||
byte buffer[672] = {0};
|
||||
freopen("test_payload.txt", "w", stdout);
|
||||
printf("\n");
|
||||
init_payload(buffer, gb_rom_values_eng[RED_ID], TRANSFER, true);
|
||||
|
||||
if (true)
|
||||
{
|
||||
for (int i = 0; i < 0x2A0; i++)
|
||||
{
|
||||
printf("0x%02X, ", (unsigned int)buffer[i]);
|
||||
if (i % 0x10 == 0xF)
|
||||
{
|
||||
printf("\n# 0x%X\n", i + 1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 0x150; i++)
|
||||
{
|
||||
printf("%02X ", (unsigned int)buffer[i + ((0x10 * 28) + 9)]);
|
||||
if (i % 0x10 == 0xF)
|
||||
{
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
#include <tonc.h>
|
||||
|
||||
#include "sprite_data.h"
|
||||
#include "text_engine.h"
|
||||
#include "pokemon_data.h"
|
||||
#include "background_engine.h"
|
||||
|
||||
#define CBB 0
|
||||
#define SBB 24
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <tonc.h>
|
||||
#include "pccs/typeDefs.h"
|
||||
#include "button_menu.h"
|
||||
#include "button_handler.h"
|
||||
#include "save_data_manager.h"
|
||||
|
|
@ -6,14 +7,13 @@
|
|||
#include "string"
|
||||
#include "sprite_data.h"
|
||||
#include "box_menu.h"
|
||||
#include "pokemon_data.h"
|
||||
#include "text_engine.h"
|
||||
#include "translated_text.h"
|
||||
#include "text_data_table.h"
|
||||
|
||||
Box_Menu::Box_Menu() {};
|
||||
|
||||
int Box_Menu::box_main(Pokemon_Party party_data)
|
||||
int Box_Menu::box_main(PokeBox* box)
|
||||
{
|
||||
u8 names_decompression_buffer[3072];
|
||||
text_data_table PKMN_NAMES(names_decompression_buffer);
|
||||
|
|
@ -22,7 +22,7 @@ int Box_Menu::box_main(Pokemon_Party party_data)
|
|||
load_flex_background(BG_BOX, 2);
|
||||
REG_BG1VOFS = 0;
|
||||
REG_BG1HOFS = 0;
|
||||
load_temp_box_sprites(&party_data);
|
||||
load_temp_box_sprites(box);
|
||||
Button cancel_button(button_cancel_left, button_cancel_right, 64);
|
||||
Button confirm_button(button_confirm_left, button_confirm_right, 64);
|
||||
cancel_button.set_location(88, 124);
|
||||
|
|
@ -42,9 +42,9 @@ int Box_Menu::box_main(Pokemon_Party party_data)
|
|||
{
|
||||
if (get_frame_count() % 20 == 0)
|
||||
{
|
||||
for (int i = 0; i < 30; i++)
|
||||
for (int i = 0; i < box->getNumInBox(); i++)
|
||||
{
|
||||
update_menu_sprite(&party_data, i, get_frame_count() % 40);
|
||||
update_menu_sprite(box, i, get_frame_count() % 40);
|
||||
}
|
||||
}
|
||||
if (curr_button == 0)
|
||||
|
|
@ -128,15 +128,15 @@ int Box_Menu::box_main(Pokemon_Party party_data)
|
|||
index = x + (y * BOXMENU_HNUM);
|
||||
obj_set_pos(box_select, BOXMENU_LEFT + (x * (BOXMENU_SPRITE_WIDTH + BOXMENU_HSPACE)), BOXMENU_TOP + (y * (BOXMENU_SPRITE_HEIGHT + BOXMENU_VSPACE)));
|
||||
tte_erase_rect(6, 16, 80, 152);
|
||||
Simplified_Pokemon curr_pkmn = party_data.get_simple_pkmn(index);
|
||||
GBPokemon* curr_pkmn = box->getGBPokemon(index);
|
||||
obj_hide(grabbed_front_sprite);
|
||||
if (curr_pkmn.is_valid)
|
||||
if (index < box->getNumInBox() && curr_pkmn->isValid)
|
||||
{
|
||||
byte val[11];
|
||||
tte_set_pos(6, 88);
|
||||
ptgb_write(curr_pkmn.nickname, true);
|
||||
|
||||
if (curr_pkmn.is_shiny)
|
||||
curr_pkmn->externalConvertNickname(val);
|
||||
ptgb_write(val, true);
|
||||
if (curr_pkmn->getIsShiny())
|
||||
{
|
||||
tte_set_pos(64, 16);
|
||||
val[0] = 0xF9;
|
||||
|
|
@ -144,14 +144,14 @@ int Box_Menu::box_main(Pokemon_Party party_data)
|
|||
ptgb_write(val, true);
|
||||
}
|
||||
tte_set_pos(14, 98);
|
||||
if (curr_pkmn.is_missingno)
|
||||
if (curr_pkmn->getSpeciesIndexNumber() == MISSINGNO)
|
||||
{
|
||||
ptgb_write(PKMN_NAMES.get_text_entry(0), true);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
ptgb_write(PKMN_NAMES.get_text_entry(curr_pkmn.dex_number), true);
|
||||
ptgb_write(PKMN_NAMES.get_text_entry(curr_pkmn->getSpeciesIndexNumber()), true);
|
||||
}
|
||||
tte_set_pos(6, 108);
|
||||
val[0] = 0xC6; // L
|
||||
|
|
@ -160,10 +160,10 @@ int Box_Menu::box_main(Pokemon_Party party_data)
|
|||
val[3] = 0x00; // " "
|
||||
val[4] = 0xFF; // endline
|
||||
ptgb_write(val, true);
|
||||
convert_int_to_ptgb_str(curr_pkmn.met_level, val); // Val should never go out of bounds
|
||||
convert_int_to_ptgb_str(curr_pkmn->getLevel(), val); // Val should never go out of bounds
|
||||
ptgb_write(val, true);
|
||||
|
||||
update_front_box_sprite(&curr_pkmn);
|
||||
update_front_box_sprite(curr_pkmn);
|
||||
obj_unhide(grabbed_front_sprite, 0);
|
||||
update_pos = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#include <tonc.h>
|
||||
#include "libstd_replacements.h"
|
||||
#include "flash_mem.h"
|
||||
#include "pokemon.h"
|
||||
#include "pokemon_data.h"
|
||||
#include "rom_data.h"
|
||||
#include "libraries/Pokemon-Gen3-to-Gen-X/include/save.h"
|
||||
|
|
@ -97,16 +96,18 @@ void initalize_memory_locations()
|
|||
void print_mem_section()
|
||||
{
|
||||
return; // This function isn't really needed now
|
||||
/*
|
||||
uint16_t charset[256];
|
||||
byte out[4] = {0, 0, 0, 0xFF};
|
||||
|
||||
load_localized_charset(charset, 3, ENG_ID);
|
||||
load_localized_charset(charset, 3, ENGLISH);
|
||||
|
||||
out[0] = get_char_from_charset(charset, mem_name);
|
||||
out[1] = get_char_from_charset(charset, '-');
|
||||
out[2] = get_char_from_charset(charset, mem_id + 0xA1); // Kinda a dumb way to
|
||||
tte_set_pos(0, 0);
|
||||
ptgb_write(out, true);
|
||||
*/
|
||||
}
|
||||
|
||||
// Reverses the endian of the given array
|
||||
|
|
@ -158,29 +159,29 @@ bool read_flag(u16 flag_id)
|
|||
{
|
||||
tte_set_pos(0, 0);
|
||||
tte_write("#{cx:0xD000}Attempting to read byte ");
|
||||
tte_write(ptgb::to_string((curr_rom.offset_flags + (flag_id / 8)) % 0xF80));
|
||||
tte_write(ptgb::to_string((curr_GBA_rom.offset_flags + (flag_id / 8)) % 0xF80));
|
||||
tte_write(" of memory section ");
|
||||
tte_write(ptgb::to_string(1 + ((curr_rom.offset_flags + (flag_id / 8)) / 0xF80)));
|
||||
tte_write(ptgb::to_string(1 + ((curr_GBA_rom.offset_flags + (flag_id / 8)) / 0xF80)));
|
||||
tte_write(" for flag ");
|
||||
tte_write(ptgb::to_string(flag_id));
|
||||
tte_write(". Flag is ");
|
||||
copy_save_to_ram(memory_section_array[1 + ((curr_rom.offset_flags + (flag_id / 8)) / 0xF80)], &global_memory_buffer[0], 0x1000);
|
||||
u8 flags = global_memory_buffer[(curr_rom.offset_flags + (flag_id / 8)) % 0xF80];
|
||||
copy_save_to_ram(memory_section_array[1 + ((curr_GBA_rom.offset_flags + (flag_id / 8)) / 0xF80)], &global_memory_buffer[0], 0x1000);
|
||||
u8 flags = global_memory_buffer[(curr_GBA_rom.offset_flags + (flag_id / 8)) % 0xF80];
|
||||
tte_write(ptgb::to_string((flags >> (flag_id % 8)) & 0b1));
|
||||
while (true)
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
copy_save_to_ram(memory_section_array[1 + ((curr_rom.offset_flags + (flag_id / 8)) / 0xF80)], &global_memory_buffer[0], 0x1000);
|
||||
u8 flags = global_memory_buffer[(curr_rom.offset_flags + (flag_id / 8)) % 0xF80];
|
||||
copy_save_to_ram(memory_section_array[1 + ((curr_GBA_rom.offset_flags + (flag_id / 8)) / 0xF80)], &global_memory_buffer[0], 0x1000);
|
||||
u8 flags = global_memory_buffer[(curr_GBA_rom.offset_flags + (flag_id / 8)) % 0xF80];
|
||||
return (flags >> (flag_id % 8)) & 0b1;
|
||||
}
|
||||
|
||||
bool compare_map_and_npc_data(int map_bank, int map_id, int npc_id)
|
||||
{
|
||||
copy_save_to_ram(memory_section_array[4], &global_memory_buffer[0], 0x1000);
|
||||
return (global_memory_buffer[curr_rom.offset_script + 5] == map_bank &&
|
||||
global_memory_buffer[curr_rom.offset_script + 6] == map_id &&
|
||||
global_memory_buffer[curr_rom.offset_script + 7] == npc_id);
|
||||
return (global_memory_buffer[curr_GBA_rom.offset_script + 5] == map_bank &&
|
||||
global_memory_buffer[curr_GBA_rom.offset_script + 6] == map_id &&
|
||||
global_memory_buffer[curr_GBA_rom.offset_script + 7] == npc_id);
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ byte data_packet[PACKET_SIZE];
|
|||
|
||||
// Here's a compilation check to ensure that the size of these structs match our expectations.
|
||||
// Just update it if you changed the struct members. The data-generator process prints their actual sizes.
|
||||
static_assert(sizeof(struct GB_ROM) == 132);
|
||||
static_assert(sizeof(struct GB_ROM) == 136);
|
||||
static_assert(sizeof(struct ROM_DATA) == 160);
|
||||
|
||||
void print(const char *format, ...)
|
||||
|
|
@ -169,7 +169,7 @@ void setup(const u16 *debug_charset)
|
|||
}
|
||||
}
|
||||
|
||||
byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, Simplified_Pokemon *curr_simple_array, const u16 *debug_charset, bool cancel_connection)
|
||||
byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBox *box, const u16 *debug_charset, bool cancel_connection)
|
||||
{
|
||||
// TODO: Change to a switch statement
|
||||
if (state == hs)
|
||||
|
|
@ -224,7 +224,7 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_
|
|||
text_data_table general_text(general_text_table_buffer);
|
||||
|
||||
general_text.decompress(get_compressed_general_table());
|
||||
ptgb_write(general_text.get_text_entry(curr_gb_rom->version != YELLOW_ID ? GENERAL_link_success_yellow : GENERAL_link_success), true);
|
||||
ptgb_write(general_text.get_text_entry(curr_gb_rom->version != YELLOW_ID ? GENERAL_link_success : GENERAL_link_success_yellow), true);
|
||||
}
|
||||
|
||||
link_animation_state(STATE_NO_ANIM);
|
||||
|
|
@ -340,7 +340,7 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_
|
|||
if (in != 0xFD)
|
||||
{
|
||||
state = send_remove_array;
|
||||
return exchange_remove_array(in, curr_simple_array, cancel_connection);
|
||||
return exchange_remove_array(in, box, cancel_connection);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
|
@ -352,27 +352,61 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_
|
|||
state = end2;
|
||||
}
|
||||
data_counter++;
|
||||
return exchange_remove_array(in, curr_simple_array, cancel_connection);
|
||||
return exchange_remove_array(in, box, cancel_connection);
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, Simplified_Pokemon *curr_simple_array, const u16 *debug_charset, bool cancel_connection)
|
||||
int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBox *box, const u16 *debug_charset, bool cancel_connection)
|
||||
{
|
||||
#define LINE_WIDTH 21
|
||||
#define NUM_LINES 8
|
||||
int counter = 0;
|
||||
char stuff[NUM_LINES][LINE_WIDTH];
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (PRINT_LINK_DATA && key_held(KEY_L))
|
||||
{
|
||||
while (!key_hit(KEY_R))
|
||||
{
|
||||
global_next_frame();
|
||||
}
|
||||
global_next_frame();
|
||||
}
|
||||
// TODO: Restore Errors
|
||||
in_data = linkSPI->transfer(out_data);
|
||||
|
||||
if (PRINT_LINK_DATA && false)
|
||||
if (PRINT_LINK_DATA && !key_held(KEY_DOWN))
|
||||
{
|
||||
tte_set_margins(0, 0, H_MAX, V_MAX);
|
||||
print("%d: [%d][%d][%" PRIu8 "][%" PRIu8 "]\n\n", counter, data_counter, state, in_data, out_data);
|
||||
// tte_set_margins(0, 0, H_MAX, V_MAX);
|
||||
// print("%d: [%d][%d][%" PRIu8 "][%" PRIu8 "]\n\n", counter, data_counter, state, in_data, out_data);
|
||||
for (int i = 0; i < NUM_LINES; i++)
|
||||
{
|
||||
// ptgb_write_debug(debug_charset, "\n", true);
|
||||
for (int j = 0; j < LINE_WIDTH; j++)
|
||||
{
|
||||
stuff[i][j] = stuff[i + 1][j];
|
||||
}
|
||||
stuff[i][20] = '\n';
|
||||
}
|
||||
n2hexstr(&stuff[NUM_LINES - 1][0], counter & 0xFFFFFF, 6);
|
||||
stuff[NUM_LINES - 1][6] = ':';
|
||||
n2hexstr(&stuff[NUM_LINES - 1][7], data_counter & 0xFFFF, 4);
|
||||
stuff[NUM_LINES - 1][11] = '|';
|
||||
n2hexstr(&stuff[NUM_LINES - 1][12], state & 0xFF, 2);
|
||||
stuff[NUM_LINES - 1][14] = '|';
|
||||
n2hexstr(&stuff[NUM_LINES - 1][15], in_data & 0xFF, 2);
|
||||
stuff[NUM_LINES - 1][17] = '|';
|
||||
n2hexstr(&stuff[NUM_LINES - 1][18], out_data & 0xFF, 2);
|
||||
stuff[NUM_LINES - 1][20] = '\0';
|
||||
|
||||
create_textbox(0, 0, 125, 80, false);
|
||||
ptgb_write_debug(debug_charset, *stuff, true);
|
||||
}
|
||||
out_data = handleIncomingByte(in_data, box_data_storage, curr_payload, curr_gb_rom, curr_simple_array, debug_charset, cancel_connection);
|
||||
|
||||
out_data = handleIncomingByte(in_data, box_data_storage, curr_payload, curr_gb_rom, box, debug_charset, cancel_connection);
|
||||
|
||||
if (FF_count > (15 * 60))
|
||||
{
|
||||
|
|
@ -557,13 +591,13 @@ byte exchange_boxes(byte curr_in, byte *box_data_storage, GB_ROM *curr_gb_rom)
|
|||
}
|
||||
};
|
||||
|
||||
byte exchange_remove_array(byte curr_in, Simplified_Pokemon *curr_simple_array, bool cancel_connection)
|
||||
byte exchange_remove_array(byte curr_in, PokeBox *box, bool cancel_connection)
|
||||
{
|
||||
for (int i = 29; i >= 0; i--)
|
||||
{
|
||||
if (curr_simple_array[i].is_valid && !curr_simple_array[i].is_transferred && !cancel_connection)
|
||||
if (box->getGen3Pokemon(i)->isValid && !cancel_connection)
|
||||
{
|
||||
curr_simple_array[i].is_transferred = true;
|
||||
box->removePokemon(i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ void global_next_frame()
|
|||
if (global_frame_count % 60 == 0)
|
||||
{
|
||||
set_menu_sprite_pal(0);
|
||||
if (!curr_rom.verify_rom())
|
||||
if (!curr_GBA_rom.verify_rom())
|
||||
{
|
||||
REG_BG0CNT = (REG_BG0CNT & ~BG_PRIO_MASK) | BG_PRIO(2);
|
||||
REG_BG2CNT = (REG_BG2CNT & ~BG_PRIO_MASK) | BG_PRIO(1);
|
||||
|
|
@ -247,7 +247,7 @@ void set_missingno(bool val)
|
|||
missingno_enabled = val;
|
||||
if (val == false)
|
||||
{
|
||||
set_background_pal(curr_rom.gamecode, false, false);
|
||||
set_background_pal(curr_GBA_rom.gamecode, false, false);
|
||||
fennel_blink_timer = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -267,21 +267,6 @@ bool get_treecko_enabled()
|
|||
return treecko_enabled;
|
||||
}
|
||||
|
||||
// FNV-1a 32-bit hash function for byte arrays
|
||||
u32 fnv1a_hash(unsigned char *data, size_t length)
|
||||
{
|
||||
const uint32_t fnv_prime = 0x01000193;
|
||||
const uint32_t fnv_offset_basis = 0x811C9DC5;
|
||||
uint32_t hash = fnv_offset_basis;
|
||||
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
hash ^= data[i];
|
||||
hash *= fnv_prime;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
int get_string_length(const byte *str)
|
||||
{
|
||||
int size = 0;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include "interrupt.h"
|
||||
#include "gb_link.h"
|
||||
#include "gameboy_colour.h"
|
||||
#include "pokemon.h"
|
||||
#include "random.h"
|
||||
#include "text_engine.h"
|
||||
#include "background_engine.h"
|
||||
|
|
@ -51,7 +50,7 @@ TODO:
|
|||
int delay_counter = 0;
|
||||
int curr_selection = 0;
|
||||
bool skip = true;
|
||||
rom_data curr_rom;
|
||||
rom_data curr_GBA_rom;
|
||||
Button_Menu yes_no_menu(1, 2, 40, 24, false);
|
||||
|
||||
/*
|
||||
|
|
@ -87,18 +86,6 @@ int test_main(void) Music
|
|||
// (R + G*32 + B*1024)
|
||||
#define RGB(r, g, b) (r + (g * 32) + (b * 1024))
|
||||
|
||||
// make sure outBuffer is large enough! Should be at least hex_len + 1
|
||||
template <typename I>
|
||||
void n2hexstr(char* outBuffer, I w, size_t hex_len = sizeof(I) << 1)
|
||||
{
|
||||
static const char *digits = "0123456789ABCDEF";
|
||||
memset(outBuffer, '0', hex_len);
|
||||
outBuffer[hex_len] = '\0'; // we must make sure to terminate the string
|
||||
|
||||
for (size_t i = 0, j = (hex_len - 1) * 4; i < hex_len; ++i, j -= 4)
|
||||
outBuffer[i] = digits[(w >> j) & 0x0f];
|
||||
}
|
||||
|
||||
void load_graphics()
|
||||
{
|
||||
|
||||
|
|
@ -253,18 +240,18 @@ int credits()
|
|||
{
|
||||
char hexBuffer[16];
|
||||
uint16_t charset[256];
|
||||
load_localized_charset(charset, 3, ENG_ID);
|
||||
load_localized_charset(charset, 3, ENGLISH);
|
||||
if (key_held(KEY_UP) && key_held(KEY_L) && key_held(KEY_R))
|
||||
{
|
||||
set_treecko(true);
|
||||
}
|
||||
u32 pkmn_flags = 0;
|
||||
bool e4_flag = read_flag(curr_rom.e4_flag);
|
||||
bool mg_flag = read_flag(curr_rom.mg_flag);
|
||||
bool all_collected_flag = read_flag(curr_rom.all_collected_flag);
|
||||
bool e4_flag = read_flag(curr_GBA_rom.e4_flag);
|
||||
bool mg_flag = read_flag(curr_GBA_rom.mg_flag);
|
||||
bool all_collected_flag = read_flag(curr_GBA_rom.all_collected_flag);
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
pkmn_flags |= (read_flag(curr_rom.pkmn_collected_flag_start + i) << i);
|
||||
pkmn_flags |= (read_flag(curr_GBA_rom.pkmn_collected_flag_start + i) << i);
|
||||
}
|
||||
|
||||
bool tutorial = get_tutorial_flag();
|
||||
|
|
@ -272,8 +259,8 @@ int credits()
|
|||
|
||||
create_textbox(4, 1, 160, 80, true);
|
||||
ptgb_write_debug(charset, "Debug info:\n\nG: ", true);
|
||||
ptgb_write_debug(charset, ptgb::to_string(curr_rom.language), true);
|
||||
switch (curr_rom.gamecode)
|
||||
ptgb_write_debug(charset, ptgb::to_string(curr_GBA_rom.language), true);
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
ptgb_write_debug(charset, "-R-", true);
|
||||
|
|
@ -292,7 +279,7 @@ int credits()
|
|||
break;
|
||||
}
|
||||
|
||||
ptgb_write_debug(charset, ptgb::to_string(curr_rom.version), true);
|
||||
ptgb_write_debug(charset, ptgb::to_string(curr_GBA_rom.version), true);
|
||||
|
||||
ptgb_write_debug(charset, "\nF: ", true);
|
||||
ptgb_write_debug(charset, ptgb::to_string(e4_flag), true);
|
||||
|
|
@ -455,7 +442,7 @@ static void __attribute__((noinline)) show_intro()
|
|||
REG_BG1CNT = REG_BG1CNT | BG_PRIO(3);
|
||||
|
||||
key_poll(); // Reset the keys
|
||||
curr_rom.load_rom();
|
||||
curr_GBA_rom.load_rom();
|
||||
|
||||
obj_set_pos(ptgb_logo_l, 56, 12);
|
||||
obj_set_pos(ptgb_logo_r, 56 + 64, 12);
|
||||
|
|
@ -501,7 +488,7 @@ int main(void)
|
|||
REG_BLDALPHA = BLDA_BUILD(0b10000, 0); // Reset fade
|
||||
|
||||
// Check if the game has been loaded correctly.
|
||||
while (!curr_rom.load_rom())
|
||||
while (!curr_GBA_rom.load_rom())
|
||||
{
|
||||
obj_hide_multi(ptgb_logo_l, 2);
|
||||
global_next_frame();
|
||||
|
|
@ -516,13 +503,14 @@ int main(void)
|
|||
initalize_memory_locations();
|
||||
load_custom_save_data();
|
||||
|
||||
set_background_pal(curr_rom.gamecode, false, true);
|
||||
set_background_pal(curr_GBA_rom.gamecode, false, true);
|
||||
|
||||
if (!IGNORE_MG_E4_FLAGS && (!get_tutorial_flag() || FORCE_TUTORIAL))
|
||||
{
|
||||
obj_hide_multi(ptgb_logo_l, 2);
|
||||
text_loop(BTN_TRANSFER);
|
||||
initalize_save_data();
|
||||
// TODO: We should be able to test for a Bootleg rom in here- if the save data isn't written, then it is bootleg.
|
||||
}
|
||||
|
||||
obj_unhide_multi(ptgb_logo_l, 1, 2);
|
||||
|
|
@ -533,7 +521,7 @@ int main(void)
|
|||
if (DEBUG_MODE && false) // This isn't really needed anymore
|
||||
{
|
||||
print_mem_section();
|
||||
curr_rom.print_rom_info();
|
||||
curr_GBA_rom.print_rom_info();
|
||||
}
|
||||
load_flex_background(BG_MAIN_MENU, 2);
|
||||
|
||||
|
|
@ -555,10 +543,10 @@ int main(void)
|
|||
obj_hide_multi(ptgb_logo_l, 2);
|
||||
global_next_frame();
|
||||
load_flex_background(BG_DEX, 2);
|
||||
set_background_pal(curr_rom.gamecode, true, false);
|
||||
set_background_pal(curr_GBA_rom.gamecode, true, false);
|
||||
pokedex_loop();
|
||||
load_flex_background(BG_DEX, 3);
|
||||
set_background_pal(curr_rom.gamecode, false, false);
|
||||
set_background_pal(curr_GBA_rom.gamecode, false, false);
|
||||
}
|
||||
break;
|
||||
case (BTN_CREDITS):
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#define MG_SCRIPT false
|
||||
#define S30_SCRIPT true
|
||||
|
||||
extern rom_data curr_rom;
|
||||
extern rom_data curr_GBA_rom;
|
||||
bool asm_payload_location;
|
||||
|
||||
// These are static variables
|
||||
|
|
@ -75,60 +75,55 @@ union decompressed_data_storage_union
|
|||
|
||||
// constructor and destructor are needed to make the compiler stop complaining
|
||||
// about the decompressed_data_tables struct not being trivial
|
||||
decompressed_data_storage_union(){}
|
||||
~decompressed_data_storage_union(){}
|
||||
decompressed_data_storage_union() {}
|
||||
~decompressed_data_storage_union() {}
|
||||
};
|
||||
|
||||
mystery_gift_script::mystery_gift_script(u8 *save_section_30_buffer)
|
||||
: curr_mg_index(NPC_LOCATION_OFFSET)
|
||||
, curr_section30_index(0)
|
||||
, save_section_30(save_section_30_buffer)
|
||||
, mg_script()
|
||||
, value_buffer()
|
||||
, four_align_value(0)
|
||||
: curr_mg_index(NPC_LOCATION_OFFSET), curr_section30_index(0), save_section_30(save_section_30_buffer), mg_script(), value_buffer(), four_align_value(0)
|
||||
{
|
||||
ptr_call_check_flag = (curr_rom.loc_gSpecialVar_0x8000 + 0x08);
|
||||
ptr_call_return_2 = (curr_rom.loc_gSpecialVar_0x8000 + 0x0A);
|
||||
ptr_box_return = (curr_rom.loc_gSpecialVar_0x8000 + 0x0C);
|
||||
ptr_dex_seen_caught = (curr_rom.loc_gSpecialVar_0x8000 + 0x0E);
|
||||
ptr_index = (curr_rom.loc_gSpecialVar_0x8000 + 0x12);
|
||||
ptr_pkmn_offset = (curr_rom.loc_gSpecialVar_0x8000 + 0x14);
|
||||
ptr_call_check_flag = (curr_GBA_rom.loc_gSpecialVar_0x8000 + 0x08);
|
||||
ptr_call_return_2 = (curr_GBA_rom.loc_gSpecialVar_0x8000 + 0x0A);
|
||||
ptr_box_return = (curr_GBA_rom.loc_gSpecialVar_0x8000 + 0x0C);
|
||||
ptr_dex_seen_caught = (curr_GBA_rom.loc_gSpecialVar_0x8000 + 0x0E);
|
||||
ptr_index = (curr_GBA_rom.loc_gSpecialVar_0x8000 + 0x12);
|
||||
ptr_pkmn_offset = (curr_GBA_rom.loc_gSpecialVar_0x8000 + 0x14);
|
||||
|
||||
// TODO: For old script, can be removed later
|
||||
ptr_callASM = (curr_rom.loc_gSpecialVar_0x8000 + 0x00);
|
||||
ptr_script_ptr_low = (curr_rom.loc_gSpecialVar_0x8000 + 0x02);
|
||||
ptr_script_ptr_high = (curr_rom.loc_gSpecialVar_0x8000 + 0x04);
|
||||
ptr_call_return_1 = (curr_rom.loc_gSpecialVar_0x8000 + 0x06);
|
||||
ptr_block_ptr_low = (curr_rom.loc_gSaveBlock1PTR + 0x00);
|
||||
ptr_block_ptr_high = (curr_rom.loc_gSaveBlock1PTR + 0x02);
|
||||
ptr_callASM = (curr_GBA_rom.loc_gSpecialVar_0x8000 + 0x00);
|
||||
ptr_script_ptr_low = (curr_GBA_rom.loc_gSpecialVar_0x8000 + 0x02);
|
||||
ptr_script_ptr_high = (curr_GBA_rom.loc_gSpecialVar_0x8000 + 0x04);
|
||||
ptr_call_return_1 = (curr_GBA_rom.loc_gSpecialVar_0x8000 + 0x06);
|
||||
ptr_block_ptr_low = (curr_GBA_rom.loc_gSaveBlock1PTR + 0x00);
|
||||
ptr_block_ptr_high = (curr_GBA_rom.loc_gSaveBlock1PTR + 0x02);
|
||||
}
|
||||
|
||||
void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
||||
void mystery_gift_script::build_script(PokeBox *box)
|
||||
{
|
||||
decompressed_data_storage_union decompressed_store;
|
||||
text_data_table decompressed_text_table(decompressed_store.text.buffer);
|
||||
ptgb::vector<script_var *> mg_variable_list;
|
||||
ptgb::vector<script_var *> sec30_variable_list;
|
||||
|
||||
asm_var sendMonToPC_ptr(curr_rom.loc_sendMonToPC + READ_AS_THUMB, sec30_variable_list, &curr_section30_index);
|
||||
asm_var sendMonToPC_ptr(curr_GBA_rom.loc_sendMonToPC + READ_AS_THUMB, sec30_variable_list, &curr_section30_index);
|
||||
asm_var returned_box_success_ptr(ptr_box_return, sec30_variable_list, &curr_section30_index);
|
||||
asm_var curr_pkmn_index_ptr(ptr_pkmn_offset, sec30_variable_list, &curr_section30_index);
|
||||
asm_var setPokedexFlag_ptr(curr_rom.loc_setPokedexFlag + READ_AS_THUMB, sec30_variable_list, &curr_section30_index);
|
||||
asm_var setPokedexFlag_ptr(curr_GBA_rom.loc_setPokedexFlag + READ_AS_THUMB, sec30_variable_list, &curr_section30_index);
|
||||
asm_var dexSeenCaught_ptr(ptr_dex_seen_caught, sec30_variable_list, &curr_section30_index);
|
||||
asm_var currPkmnIndex_ptr(ptr_index, sec30_variable_list, &curr_section30_index);
|
||||
asm_var pkmnStruct(curr_rom.loc_gSaveDataBuffer, sec30_variable_list, &curr_section30_index);
|
||||
asm_var dexStruct(curr_rom.loc_gSaveDataBuffer + (MAX_PKMN_IN_BOX * POKEMON_SIZE), sec30_variable_list, &curr_section30_index);
|
||||
asm_var m4aMPlayStop_ptr(curr_rom.loc_m4aMPlayStop + READ_AS_THUMB, sec30_variable_list, &curr_section30_index);
|
||||
asm_var gMPlayInfo_BGM_ptr(curr_rom.loc_gMPlayInfo_BGM, sec30_variable_list, &curr_section30_index);
|
||||
asm_var gMPlayInfo_SE2_ptr(curr_rom.loc_gMPlayInfo_SE2, sec30_variable_list, &curr_section30_index);
|
||||
asm_var MPlayStart_ptr(curr_rom.loc_MPlayStart + READ_AS_THUMB, sec30_variable_list, &curr_section30_index);
|
||||
asm_var CreateFanfareTask_ptr(curr_rom.loc_CreateFanfareTask + READ_AS_THUMB, sec30_variable_list, &curr_section30_index);
|
||||
asm_var sFanfareCounter_ptr(curr_rom.loc_sFanfareCounter, sec30_variable_list, &curr_section30_index);
|
||||
asm_var gPlttBufferFaded_ptr(curr_rom.loc_gPlttBufferFaded + (32 * 0x1A), sec30_variable_list, &curr_section30_index); // 0x1A is the pallet number
|
||||
asm_var copySizeControl(CPU_SET_32BIT | ((32) / (32 / 8) & 0x1FFFFF), sec30_variable_list, &curr_section30_index); // CPU_SET_32BIT | ((size)/(32/8) & 0x1FFFFF)
|
||||
asm_var pkmnStruct(curr_GBA_rom.loc_gSaveDataBuffer, sec30_variable_list, &curr_section30_index);
|
||||
asm_var dexStruct(curr_GBA_rom.loc_gSaveDataBuffer + (MAX_PKMN_IN_BOX * POKEMON_SIZE), sec30_variable_list, &curr_section30_index);
|
||||
asm_var m4aMPlayStop_ptr(curr_GBA_rom.loc_m4aMPlayStop + READ_AS_THUMB, sec30_variable_list, &curr_section30_index);
|
||||
asm_var gMPlayInfo_BGM_ptr(curr_GBA_rom.loc_gMPlayInfo_BGM, sec30_variable_list, &curr_section30_index);
|
||||
asm_var gMPlayInfo_SE2_ptr(curr_GBA_rom.loc_gMPlayInfo_SE2, sec30_variable_list, &curr_section30_index);
|
||||
asm_var MPlayStart_ptr(curr_GBA_rom.loc_MPlayStart + READ_AS_THUMB, sec30_variable_list, &curr_section30_index);
|
||||
asm_var CreateFanfareTask_ptr(curr_GBA_rom.loc_CreateFanfareTask + READ_AS_THUMB, sec30_variable_list, &curr_section30_index);
|
||||
asm_var sFanfareCounter_ptr(curr_GBA_rom.loc_sFanfareCounter, sec30_variable_list, &curr_section30_index);
|
||||
asm_var gPlttBufferFaded_ptr(curr_GBA_rom.loc_gPlttBufferFaded + (32 * 0x1A), sec30_variable_list, &curr_section30_index); // 0x1A is the pallet number
|
||||
asm_var copySizeControl(CPU_SET_32BIT | ((32) / (32 / 8) & 0x1FFFFF), sec30_variable_list, &curr_section30_index); // CPU_SET_32BIT | ((size)/(32/8) & 0x1FFFFF)
|
||||
|
||||
asm_var flashBuffer_ptr(curr_rom.loc_gSaveDataBuffer, mg_variable_list, &curr_mg_index);
|
||||
asm_var readFlashSector_ptr(curr_rom.loc_readFlashSector + READ_AS_THUMB, mg_variable_list, &curr_mg_index);
|
||||
asm_var flashBuffer_ptr(curr_GBA_rom.loc_gSaveDataBuffer, mg_variable_list, &curr_mg_index);
|
||||
asm_var readFlashSector_ptr(curr_GBA_rom.loc_readFlashSector + READ_AS_THUMB, mg_variable_list, &curr_mg_index);
|
||||
|
||||
asm_var mainAsmStart(sec30_variable_list, &curr_section30_index);
|
||||
asm_var dexAsmStart(sec30_variable_list, &curr_section30_index);
|
||||
|
|
@ -249,7 +244,7 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
const int movementWalkBackArrayFRLG[2] = {MOVEMENT_ACTION_WALK_FAST_DOWN, MOVEMENT_ACTION_WALK_FAST_DOWN};
|
||||
const int movementWalkBackArrayE[4] = {MOVEMENT_ACTION_WALK_FAST_RIGHT, MOVEMENT_ACTION_WALK_FAST_RIGHT, MOVEMENT_ACTION_WALK_FAST_RIGHT, MOVEMENT_ACTION_WALK_FAST_DOWN};
|
||||
|
||||
switch (curr_rom.gamecode)
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
case SAPPHIRE_ID:
|
||||
|
|
@ -304,7 +299,7 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
// songLooker.add_track(track_7, sizeof(track_7));
|
||||
|
||||
unsigned char instrument;
|
||||
switch (curr_rom.gamecode)
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
case SAPPHIRE_ID:
|
||||
|
|
@ -331,14 +326,23 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
// placement new is required to run the constructor of PokemonTables for the decompressed_store's instance
|
||||
// it won't get called automatically because it's part of the union (and neither will the destructor)
|
||||
new (&decompressed_store.tables.data) PokemonTables();
|
||||
|
||||
// TODO make it so that the table is added here(?)
|
||||
box->setTable(&decompressed_store.tables.data);
|
||||
box->convertAll();
|
||||
for (int i = 0; i < MAX_PKMN_IN_BOX; i++) // Add in the Pokemon data
|
||||
{
|
||||
Pokemon curr_pkmn = incoming_box_data.get_converted_pkmn(decompressed_store.tables.data, i);
|
||||
if (curr_pkmn.get_validity())
|
||||
Gen3Pokemon *curr_pkmn = box->getGen3Pokemon(i);
|
||||
if (curr_pkmn->isValid)
|
||||
{
|
||||
memcpy(save_section_30 + curr_section30_index, curr_pkmn.get_full_gen_3_array(), POKEMON_SIZE);
|
||||
for (int j = 0; j < POKEMON_SIZE; j++)
|
||||
{
|
||||
*(save_section_30 + curr_section30_index + j) = curr_pkmn->dataArrayPtr[j];
|
||||
}
|
||||
// memcpy(save_section_30 + curr_section30_index, curr_pkmn->dataArrayPtr, POKEMON_SIZE);
|
||||
|
||||
curr_section30_index += POKEMON_SIZE;
|
||||
dex_nums[i] = curr_pkmn.get_dex_number();
|
||||
dex_nums[i] = curr_pkmn->getSpeciesIndexNumber();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -347,7 +351,7 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
}
|
||||
// the PokemonTables instance is no longer needed, but we do need to keep the english gen3 charset around
|
||||
// for our insert_text() calls
|
||||
decompressed_store.tables.data.load_gen3_charset(ENG_ID);
|
||||
decompressed_store.tables.data.load_gen3_charset(ENGLISH);
|
||||
// we specifically defined the decompressed_text_data struct to ensure the memcpy shouldn't overlap
|
||||
memcpy(decompressed_store.text.gen3_charset, decompressed_store.tables.data.gen3_charset, sizeof(decompressed_store.text.gen3_charset));
|
||||
// calling the destructor is nothing more than a formality for our PokemonTables class,
|
||||
|
|
@ -375,7 +379,7 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
// this decompresses the ZX0 compressed text table into the buffer inside of the decompressed_store union
|
||||
// thereby reusing the stack (=IWRAM) memory used earlier for the PokemonTables instance we used above
|
||||
decompressed_text_table.decompress(get_compressed_rsefrlg_table());
|
||||
switch (curr_rom.gamecode)
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
textGreet.set_text(decompressed_text_table.get_text_entry(RSEFRLG_dia_textGreet_rse));
|
||||
|
|
@ -433,7 +437,7 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
curr_section30_index++; // Align the code so that it is byte aligned
|
||||
}
|
||||
|
||||
songLooker.insert_music_data(save_section_30, 0, 0, 0, curr_rom.loc_voicegroup);
|
||||
songLooker.insert_music_data(save_section_30, 0, 0, 0, curr_GBA_rom.loc_voicegroup);
|
||||
|
||||
asm_var customSong(songLooker.get_loc_in_sec30(), sec30_variable_list, &curr_section30_index);
|
||||
asm_var customSongDuration(119, sec30_variable_list, &curr_section30_index);
|
||||
|
|
@ -445,7 +449,7 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
|
||||
#include "lookerFRLG.h"
|
||||
#include "lookerRSE.h"
|
||||
if (curr_rom.is_hoenn())
|
||||
if (curr_GBA_rom.is_hoenn())
|
||||
{
|
||||
spriteLooker.insert_sprite_data(save_section_30, lookerRSETiles, 256, lookerRSEPal);
|
||||
}
|
||||
|
|
@ -453,7 +457,7 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
{
|
||||
spriteLooker.insert_sprite_data(save_section_30, lookerFRLGTiles, 256, lookerFRLGPal);
|
||||
}
|
||||
asm_var paletteData(curr_rom.loc_gSaveDataBuffer + (curr_section30_index - 32), sec30_variable_list, &curr_section30_index);
|
||||
asm_var paletteData(curr_GBA_rom.loc_gSaveDataBuffer + (curr_section30_index - 32), sec30_variable_list, &curr_section30_index);
|
||||
|
||||
asm_payload_location = S30_SCRIPT;
|
||||
|
||||
|
|
@ -574,47 +578,47 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
|
||||
asm_payload_location = MG_SCRIPT;
|
||||
// Located at 0x?8A8 in the .sav
|
||||
init_npc_location(curr_rom.map_bank, curr_rom.map_id, curr_rom.npc_id); // Set the location of the NPC
|
||||
setvirtualaddress(VIRTUAL_ADDRESS); // Set virtual address
|
||||
if (curr_rom.gamecode == RUBY_ID || curr_rom.gamecode == SAPPHIRE_ID)
|
||||
init_npc_location(curr_GBA_rom.map_bank, curr_GBA_rom.map_id, curr_GBA_rom.npc_id); // Set the location of the NPC
|
||||
setvirtualaddress(VIRTUAL_ADDRESS); // Set virtual address
|
||||
if (curr_GBA_rom.gamecode == RUBY_ID || curr_GBA_rom.gamecode == SAPPHIRE_ID)
|
||||
{
|
||||
callASM(loadSec30.add_reference(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
callASM(curr_rom.loc_loadSaveSection30 + READ_AS_THUMB); // Load save section 30 into saveDataBuffer
|
||||
callASM(curr_GBA_rom.loc_loadSaveSection30 + READ_AS_THUMB); // Load save section 30 into saveDataBuffer
|
||||
}
|
||||
lock(); // Lock the player
|
||||
faceplayer(); // Have the NPC face the player
|
||||
virtualmsgbox(textGreet.add_reference(1)); // Start the dialouge
|
||||
waitmsg();
|
||||
waitkeypress();
|
||||
applymovement(curr_rom.npc_id, movementExclaim.get_loc_in_sec30());
|
||||
applymovement(curr_GBA_rom.npc_id, movementExclaim.get_loc_in_sec30());
|
||||
playse(0x15);
|
||||
waitse();
|
||||
waitmovement(curr_rom.npc_id);
|
||||
waitmovement(curr_GBA_rom.npc_id);
|
||||
virtualmsgbox(textYouMustBe.add_reference(1));
|
||||
waitmsg();
|
||||
waitkeypress();
|
||||
applymovement(curr_rom.npc_id, movementSlowSpin.get_loc_in_sec30());
|
||||
waitmovement(curr_rom.npc_id);
|
||||
applymovement(curr_rom.npc_id, movementFastSpin.get_loc_in_sec30());
|
||||
waitmovement(curr_rom.npc_id);
|
||||
applymovement(curr_GBA_rom.npc_id, movementSlowSpin.get_loc_in_sec30());
|
||||
waitmovement(curr_GBA_rom.npc_id);
|
||||
applymovement(curr_GBA_rom.npc_id, movementFastSpin.get_loc_in_sec30());
|
||||
waitmovement(curr_GBA_rom.npc_id);
|
||||
changeSpriteMacro(1, spriteLooker.get_loc_in_sec30());
|
||||
callASM(loadPalette.get_loc_in_sec30());
|
||||
changePaletteMacro(curr_rom.npc_id, 0xA);
|
||||
applymovement(curr_rom.npc_id, movementLookDown.get_loc_in_sec30());
|
||||
changePaletteMacro(curr_GBA_rom.npc_id, 0xA);
|
||||
applymovement(curr_GBA_rom.npc_id, movementLookDown.get_loc_in_sec30());
|
||||
callASM(customSoundASM.get_loc_in_sec30());
|
||||
waitfanfare();
|
||||
virtualmsgbox(textIAm.add_reference(1));
|
||||
waitmsg();
|
||||
waitkeypress();
|
||||
changeSpriteMacro(1, curr_rom.loc_sPicTable_NPC);
|
||||
changePaletteMacro(curr_rom.npc_id, curr_rom.npc_palette);
|
||||
applymovement(curr_rom.npc_id, movementFastSpin.get_loc_in_sec30());
|
||||
waitmovement(curr_rom.npc_id);
|
||||
applymovement(curr_rom.npc_id, movementSlowSpin.get_loc_in_sec30());
|
||||
waitmovement(curr_rom.npc_id);
|
||||
changeSpriteMacro(1, curr_GBA_rom.loc_sPicTable_NPC);
|
||||
changePaletteMacro(curr_GBA_rom.npc_id, curr_GBA_rom.npc_palette);
|
||||
applymovement(curr_GBA_rom.npc_id, movementFastSpin.get_loc_in_sec30());
|
||||
waitmovement(curr_GBA_rom.npc_id);
|
||||
applymovement(curr_GBA_rom.npc_id, movementSlowSpin.get_loc_in_sec30());
|
||||
waitmovement(curr_GBA_rom.npc_id);
|
||||
faceplayer();
|
||||
msgboxMacro(textWeHere.get_loc_in_sec30());
|
||||
compare(0x800C, 1); // 0x800C == SpecialVar_Facing
|
||||
|
|
@ -622,13 +626,13 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
applymovement(0xFF, movementOutOfWay.get_loc_in_sec30());
|
||||
waitmovement(0xFF);
|
||||
jumpNotInWay.set_start();
|
||||
applymovement(curr_rom.npc_id, movementToBoxes.get_loc_in_sec30());
|
||||
waitmovement(curr_rom.npc_id);
|
||||
applymovement(curr_GBA_rom.npc_id, movementToBoxes.get_loc_in_sec30());
|
||||
waitmovement(curr_GBA_rom.npc_id);
|
||||
playse(0x15);
|
||||
waitse();
|
||||
msgboxMacro(textMoveBox.get_loc_in_sec30());
|
||||
fadeScreen(1);
|
||||
switch (curr_rom.gamecode)
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
case SAPPHIRE_ID:
|
||||
|
|
@ -646,11 +650,11 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
setMetaTile(3, 2, 566, 1);
|
||||
setMetaTile(1, 1, 531, 1);
|
||||
setMetaTile(1, 2, 539, 0);
|
||||
applymovement(curr_rom.npc_id, movementGoUp.get_loc_in_sec30());
|
||||
applymovement(curr_GBA_rom.npc_id, movementGoUp.get_loc_in_sec30());
|
||||
break;
|
||||
}
|
||||
special(curr_rom.special_DrawWholeMapView);
|
||||
switch (curr_rom.gamecode)
|
||||
special(curr_GBA_rom.special_DrawWholeMapView);
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
case SAPPHIRE_ID:
|
||||
|
|
@ -664,7 +668,7 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
}
|
||||
waitse();
|
||||
fadeScreen(0);
|
||||
switch (curr_rom.gamecode)
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
case SAPPHIRE_ID:
|
||||
|
|
@ -678,41 +682,41 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
setMetaTile(3, 1, 5, 1);
|
||||
break;
|
||||
}
|
||||
special(curr_rom.special_DrawWholeMapView);
|
||||
special(curr_GBA_rom.special_DrawWholeMapView);
|
||||
playse(0x2);
|
||||
waitse();
|
||||
msgboxMacro(textPCConvo.get_loc_in_sec30());
|
||||
// -- POKEMON INJECTION START--
|
||||
setvar(var_index, 0); // set the index to 0
|
||||
setvar(var_pkmn_offset, 0); // Set the Pokemon struct offset to 0
|
||||
setvar(var_call_check_flag, rev_endian(0x2B00)); // Set the variable to 0x2B. 0x2B = CHECK FLAG
|
||||
addvar(var_call_check_flag, rev_endian(curr_rom.pkmn_collected_flag_start)); // Add the starting flag ID (plus one to ignore the is collected flag) to the check flag ASM variable
|
||||
setvar(var_call_return_2, rev_endian(0x0003)); // Set the variable to 0x03. 0x03 = RETURN
|
||||
jumpLoop.set_start(); // Set the jump destination for the JUMP_LOOP
|
||||
call(ptr_call_check_flag); // Call the check flag ASM
|
||||
virtualgotoif(COND_FLAGFALSE, jumpPkmnCollected.add_reference(2)); // If the "pokemon collected" flag is false, jump to the end of the loop
|
||||
callASM(mainAsmStart.get_loc_in_sec30()); // Call SendMonToPC ASM
|
||||
compare(var_box_return, 2); // Compare the resulting return to #2
|
||||
virtualgotoif(COND_EQUALS, jumpBoxFull.add_reference(2)); // If the return value was #2, jump to the box full message
|
||||
setvar(var_dex_seen_caught, 2); // set the seen caught variable to 2, so that the Pokemon is set to "seen"
|
||||
callASM(dexAsmStart.get_loc_in_sec30()); // call "PTR_DEX_START"
|
||||
addvar(var_dex_seen_caught, 1); // add 1 to the seen caught variable so that the Pokemon will be "Caught"
|
||||
callASM(dexAsmStart.get_loc_in_sec30()); // Call "PTR_DEX_START" again
|
||||
jumpPkmnCollected.set_start(); // Set the jump destination for if the Pokemon has already been collected
|
||||
addvar(var_pkmn_offset, POKEMON_SIZE); // Add the size of one Pokmeon to the Pokemon offset
|
||||
addvar(var_index, 1); // Add one to the index
|
||||
addvar(var_call_check_flag, rev_endian(1)); // Add one to the flag index
|
||||
compare(var_index, MAX_PKMN_IN_BOX); // Compare the index to 30
|
||||
virtualgotoif(COND_LESSTHAN, jumpLoop.add_reference(2)); // if index is less than six, jump to the start of the loop
|
||||
setflag(curr_rom.all_collected_flag); // Set the "all collected" flag
|
||||
fanfare(257); // Play the received fanfare
|
||||
msgboxMacro(textReceived.get_loc_in_sec30()); // Display the recieved text
|
||||
waitfanfare(); // Wait for the fanfare
|
||||
setvar(var_index, 0); // set the index to 0
|
||||
setvar(var_pkmn_offset, 0); // Set the Pokemon struct offset to 0
|
||||
setvar(var_call_check_flag, rev_endian(0x2B00)); // Set the variable to 0x2B. 0x2B = CHECK FLAG
|
||||
addvar(var_call_check_flag, rev_endian(curr_GBA_rom.pkmn_collected_flag_start)); // Add the starting flag ID (plus one to ignore the is collected flag) to the check flag ASM variable
|
||||
setvar(var_call_return_2, rev_endian(0x0003)); // Set the variable to 0x03. 0x03 = RETURN
|
||||
jumpLoop.set_start(); // Set the jump destination for the JUMP_LOOP
|
||||
call(ptr_call_check_flag); // Call the check flag ASM
|
||||
virtualgotoif(COND_FLAGFALSE, jumpPkmnCollected.add_reference(2)); // If the "pokemon collected" flag is false, jump to the end of the loop
|
||||
callASM(mainAsmStart.get_loc_in_sec30()); // Call SendMonToPC ASM
|
||||
compare(var_box_return, 2); // Compare the resulting return to #2
|
||||
virtualgotoif(COND_EQUALS, jumpBoxFull.add_reference(2)); // If the return value was #2, jump to the box full message
|
||||
setvar(var_dex_seen_caught, 2); // set the seen caught variable to 2, so that the Pokemon is set to "seen"
|
||||
callASM(dexAsmStart.get_loc_in_sec30()); // call "PTR_DEX_START"
|
||||
addvar(var_dex_seen_caught, 1); // add 1 to the seen caught variable so that the Pokemon will be "Caught"
|
||||
callASM(dexAsmStart.get_loc_in_sec30()); // Call "PTR_DEX_START" again
|
||||
jumpPkmnCollected.set_start(); // Set the jump destination for if the Pokemon has already been collected
|
||||
addvar(var_pkmn_offset, POKEMON_SIZE); // Add the size of one Pokmeon to the Pokemon offset
|
||||
addvar(var_index, 1); // Add one to the index
|
||||
addvar(var_call_check_flag, rev_endian(1)); // Add one to the flag index
|
||||
compare(var_index, MAX_PKMN_IN_BOX); // Compare the index to 30
|
||||
virtualgotoif(COND_LESSTHAN, jumpLoop.add_reference(2)); // if index is less than six, jump to the start of the loop
|
||||
setflag(curr_GBA_rom.all_collected_flag); // Set the "all collected" flag
|
||||
fanfare(257); // Play the received fanfare
|
||||
msgboxMacro(textReceived.get_loc_in_sec30()); // Display the recieved text
|
||||
waitfanfare(); // Wait for the fanfare
|
||||
|
||||
// -- POKEMON INJECTION END --
|
||||
jumpAllCollected.set_start(); // Set the destination for if all the Pokemon have already been collected
|
||||
msgboxMacro(textPCThanks.get_loc_in_sec30()); // Display the thank text
|
||||
switch (curr_rom.gamecode)
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
case SAPPHIRE_ID:
|
||||
|
|
@ -726,12 +730,12 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
setMetaTile(3, 1, 4, 0);
|
||||
break;
|
||||
}
|
||||
special(curr_rom.special_DrawWholeMapView);
|
||||
special(curr_GBA_rom.special_DrawWholeMapView);
|
||||
playse(0x3);
|
||||
waitse();
|
||||
fadeScreen(1);
|
||||
// Place the PC and boxes
|
||||
switch (curr_rom.gamecode)
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
case SAPPHIRE_ID:
|
||||
|
|
@ -749,11 +753,11 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
setMetaTile(3, 2, 539, 1);
|
||||
setMetaTile(1, 1, 525, 1);
|
||||
setMetaTile(1, 2, 566, 0);
|
||||
applymovement(curr_rom.npc_id, movementGoDown.get_loc_in_sec30());
|
||||
applymovement(curr_GBA_rom.npc_id, movementGoDown.get_loc_in_sec30());
|
||||
break;
|
||||
}
|
||||
special(curr_rom.special_DrawWholeMapView);
|
||||
switch (curr_rom.gamecode)
|
||||
special(curr_GBA_rom.special_DrawWholeMapView);
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
case SAPPHIRE_ID:
|
||||
|
|
@ -767,8 +771,8 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
}
|
||||
waitse();
|
||||
fadeScreen(0);
|
||||
applymovement(curr_rom.npc_id, movementWalkBack.get_loc_in_sec30());
|
||||
waitmovement(curr_rom.npc_id);
|
||||
applymovement(curr_GBA_rom.npc_id, movementWalkBack.get_loc_in_sec30());
|
||||
waitmovement(curr_GBA_rom.npc_id);
|
||||
compare(0x800C, 1); // 0x800C == SpecialVar_Facing
|
||||
virtualgotoif(COND_NOTEQUAL, jumpNotToSide.add_reference(2));
|
||||
applymovement(0xFF, movementInWay.get_loc_in_sec30());
|
||||
|
|
@ -783,7 +787,7 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
jumpBoxFull.set_start(); // Set the destination for if the box is full
|
||||
msgboxMacro(textPCFull.get_loc_in_sec30()); // Display the thank text
|
||||
setMetaTile(4, 1, 98, 0);
|
||||
special(curr_rom.special_DrawWholeMapView);
|
||||
special(curr_GBA_rom.special_DrawWholeMapView);
|
||||
playse(0x3);
|
||||
waitse();
|
||||
fadeScreen(1);
|
||||
|
|
@ -792,8 +796,8 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
// Place the boxes
|
||||
setMetaTile(2, 1, 272, 1);
|
||||
setMetaTile(2, 2, 273, 0);
|
||||
special(curr_rom.special_DrawWholeMapView);
|
||||
switch (curr_rom.gamecode)
|
||||
special(curr_GBA_rom.special_DrawWholeMapView);
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
case SAPPHIRE_ID:
|
||||
|
|
@ -807,8 +811,8 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data)
|
|||
}
|
||||
waitse();
|
||||
fadeScreen(0);
|
||||
applymovement(curr_rom.npc_id, movementWalkBack.get_loc_in_sec30());
|
||||
waitmovement(curr_rom.npc_id);
|
||||
applymovement(curr_GBA_rom.npc_id, movementWalkBack.get_loc_in_sec30());
|
||||
waitmovement(curr_GBA_rom.npc_id);
|
||||
compare(0x800C, 1); // 0x800C == SpecialVar_Facing
|
||||
virtualgotoif(COND_NOTEQUAL, jumpNotToSideFull.add_reference(2));
|
||||
applymovement(0xFF, movementInWay.get_loc_in_sec30());
|
||||
|
|
@ -1094,12 +1098,12 @@ void mystery_gift_script::build_script_old(Pokemon_Party &incoming_box_data)
|
|||
};
|
||||
*/
|
||||
|
||||
const u8* mystery_gift_script::get_script() const
|
||||
const u8 *mystery_gift_script::get_script() const
|
||||
{
|
||||
return mg_script;
|
||||
}
|
||||
|
||||
const u8* mystery_gift_script::get_section30() const
|
||||
const u8 *mystery_gift_script::get_section30() const
|
||||
{
|
||||
return save_section_30;
|
||||
}
|
||||
|
|
@ -1487,15 +1491,15 @@ void mystery_gift_script::msgboxMacro(u32 location)
|
|||
|
||||
void mystery_gift_script::changeSpriteMacro(u8 npcId, u32 spriteTablePtr)
|
||||
{
|
||||
writebytetooffset(spriteTablePtr >> 0, curr_rom.loc_gSprites + (0x44 * npcId) + 0xC + 0);
|
||||
writebytetooffset(spriteTablePtr >> 8, curr_rom.loc_gSprites + (0x44 * npcId) + 0xC + 1);
|
||||
writebytetooffset(spriteTablePtr >> 16, curr_rom.loc_gSprites + (0x44 * npcId) + 0xC + 2);
|
||||
writebytetooffset(spriteTablePtr >> 24, curr_rom.loc_gSprites + (0x44 * npcId) + 0xC + 3);
|
||||
writebytetooffset(spriteTablePtr >> 0, curr_GBA_rom.loc_gSprites + (0x44 * npcId) + 0xC + 0);
|
||||
writebytetooffset(spriteTablePtr >> 8, curr_GBA_rom.loc_gSprites + (0x44 * npcId) + 0xC + 1);
|
||||
writebytetooffset(spriteTablePtr >> 16, curr_GBA_rom.loc_gSprites + (0x44 * npcId) + 0xC + 2);
|
||||
writebytetooffset(spriteTablePtr >> 24, curr_GBA_rom.loc_gSprites + (0x44 * npcId) + 0xC + 3);
|
||||
}
|
||||
|
||||
void mystery_gift_script::changePaletteMacro(u8 npcId, u8 palNum)
|
||||
{
|
||||
writebytetooffset((palNum << 4) | 0x08, curr_rom.loc_gSprites + (0x44 * npcId) + 0x5);
|
||||
writebytetooffset((palNum << 4) | 0x08, curr_GBA_rom.loc_gSprites + (0x44 * npcId) + 0x5);
|
||||
}
|
||||
|
||||
// ASM Commands
|
||||
|
|
|
|||
|
|
@ -14,36 +14,7 @@ static const u8 em_wonder_card[0x14E] = {
|
|||
static const u8 frlg_wonder_card[0x14E] = {
|
||||
0x67, 0x18, 0x00, 0x00, 0xBA, 0xB4, 0xBE, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xCA, 0xCC, 0xC9, 0xC0, 0xBF, 0xCD, 0xCD, 0xC9, 0xCC, 0x00, 0xC0, 0xBF, 0xC8, 0xC8, 0xBF, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xE6, 0xD5, 0xE2, 0xE7, 0xDA, 0xD9, 0xE6, 0x00, 0xBD, 0xD9, 0xE6, 0xE8, 0xDD, 0xDA, 0xDD, 0xD7, 0xD5, 0xE8, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xDD, 0xE7, 0xDD, 0xE8, 0x00, 0xE8, 0xDC, 0xD9, 0x00, 0xDC, 0xE3, 0xE9, 0xE7, 0xD9, 0x00, 0xE7, 0xE3, 0xE9, 0xE8, 0xDC, 0x00, 0xE3, 0xDA, 0x00, 0xE8, 0xDC, 0xD9, 0x00, 0xCA, 0xC9, 0xC5, 0x1B, 0xC7, 0xC9, 0xC8, 0x00, 0x00, 0x00, 0x00, 0xBD, 0xBF, 0xC8, 0xCE, 0xBF, 0xCC, 0x00, 0xE3, 0xE2, 0x00, 0xCD, 0xD9, 0xEA, 0xD9, 0xE2, 0x00, 0xC3, 0xE7, 0xE0, 0xD5, 0xE2, 0xD8, 0x00, 0xE8, 0xE3, 0x00, 0xE6, 0xD9, 0xD7, 0xDD, 0xD9, 0xEA, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xED, 0xE3, 0xE9, 0xE6, 0x00, 0xE8, 0xE6, 0xD5, 0xE2, 0xE7, 0xDA, 0xD9, 0xE6, 0xD9, 0xD8, 0x00, 0xCA, 0xC9, 0xC5, 0x1B, 0xC7, 0xC9, 0xC8, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xE3, 0x00, 0xE2, 0xE3, 0xE8, 0x00, 0xE8, 0xE3, 0xE7, 0xE7, 0x00, 0xE8, 0xDC, 0xDD, 0xE7, 0x00, 0xBF, 0xEC, 0xD7, 0xDC, 0xD5, 0xE2, 0xDB, 0xD9, 0x00, 0xBD, 0xD5, 0xE6, 0xD8, 0x00, 0xD6, 0xD9, 0xDA, 0xE3, 0xE6, 0xD9, 0x00, 0x00, 0x00, 0xE6, 0xD9, 0xD7, 0xD9, 0xDD, 0xEA, 0xDD, 0xE2, 0xDB, 0x00, 0xED, 0xE3, 0xE9, 0xE6, 0x00, 0xE8, 0xE6, 0xD5, 0xE2, 0xE7, 0xDA, 0xD9, 0xE6, 0xD9, 0xD8, 0x00, 0xCA, 0xC9, 0xC5, 0x1B, 0xC7, 0xC9, 0xC8, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // checksum
|
||||
|
||||
// noinline to ensure the scope of data_tables remains limited to this function
|
||||
static void __attribute__((noinline)) handle_old_event(Pokemon_Party &incoming_box_data, int &curr_index, int *dex_nums)
|
||||
{
|
||||
PokemonTables data_tables;
|
||||
for (int i = 0; i < MAX_PKMN_IN_BOX; i++) // Add in the Pokemon data
|
||||
{
|
||||
Pokemon curr_pkmn = incoming_box_data.get_converted_pkmn(data_tables, i);
|
||||
if (curr_pkmn.get_validity())
|
||||
{
|
||||
|
||||
for (int curr_byte = 0; curr_byte < POKEMON_SIZE; curr_byte++)
|
||||
{
|
||||
global_memory_buffer[curr_index] = curr_pkmn.get_gen_3_data(curr_byte);
|
||||
curr_index++;
|
||||
}
|
||||
dex_nums[i] = curr_pkmn.get_dex_number();
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_index += POKEMON_SIZE;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < MAX_PKMN_IN_BOX; i++) // Add in the dex numbers
|
||||
{
|
||||
global_memory_buffer[curr_index] = dex_nums[i];
|
||||
curr_index++;
|
||||
}
|
||||
}
|
||||
|
||||
bool inject_mystery(Pokemon_Party &incoming_box_data)
|
||||
bool inject_mystery(PokeBox* box)
|
||||
{
|
||||
// WARNING: Look right here: we're passing global_memory_buffer to mystery_gift_script to be used as its save_section_30 buffer.
|
||||
// Since we're going to be reusing global_memory_buffer later, we need to be careful about the timing/sequence of operations.
|
||||
|
|
@ -51,16 +22,9 @@ bool inject_mystery(Pokemon_Party &incoming_box_data)
|
|||
mystery_gift_script script(global_memory_buffer);
|
||||
u32 checksum = 0;
|
||||
|
||||
if (ENABLE_OLD_EVENT)
|
||||
{
|
||||
// script.build_script_old(incoming_box_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
script.build_script(incoming_box_data);
|
||||
}
|
||||
script.build_script(box);
|
||||
|
||||
if (curr_rom.is_ruby_sapphire())
|
||||
if (curr_GBA_rom.is_ruby_sapphire())
|
||||
{
|
||||
checksum = script.calc_checksum32();
|
||||
}
|
||||
|
|
@ -73,17 +37,8 @@ bool inject_mystery(Pokemon_Party &incoming_box_data)
|
|||
// We need to do this NOW, because mystery_gift_script::build_script() actually fills the global_memory_buffer.
|
||||
// In the steps after this, we will be recycling the global_memory_buffer to read and write data to other sections of the save.
|
||||
// So we really MUST write the generated data now, before we lose it.
|
||||
if (ENABLE_OLD_EVENT)
|
||||
{
|
||||
int dex_nums[MAX_PKMN_IN_BOX] = {};
|
||||
int curr_index = 0;
|
||||
copy_save_to_ram(0x1E000, &global_memory_buffer[0], 0x1000);
|
||||
handle_old_event(incoming_box_data, curr_index, dex_nums);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(global_memory_buffer, script.get_section30(), 0x1000);
|
||||
}
|
||||
|
||||
memcpy(global_memory_buffer, script.get_section30(), 0x1000);
|
||||
|
||||
update_memory_buffer_checksum(false);
|
||||
erase_sector(0x1E000);
|
||||
|
|
@ -91,10 +46,10 @@ bool inject_mystery(Pokemon_Party &incoming_box_data)
|
|||
|
||||
// section_30 data has been stored, so now we can safely re-use the global_memory_buffer for other sections.
|
||||
// Let's move on to the next step.
|
||||
|
||||
|
||||
// Add in Wonder Card
|
||||
copy_save_to_ram(memory_section_array[4], &global_memory_buffer[0], 0x1000);
|
||||
switch (curr_rom.gamecode)
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
case RUBY_ID:
|
||||
case SAPPHIRE_ID:
|
||||
|
|
@ -102,22 +57,22 @@ bool inject_mystery(Pokemon_Party &incoming_box_data)
|
|||
break;
|
||||
case FIRERED_ID:
|
||||
case LEAFGREEN_ID:
|
||||
memcpy(global_memory_buffer + curr_rom.offset_wondercard, frlg_wonder_card, 0x14E);
|
||||
memcpy(global_memory_buffer + curr_GBA_rom.offset_wondercard, frlg_wonder_card, 0x14E);
|
||||
break;
|
||||
case EMERALD_ID:
|
||||
default:
|
||||
memcpy(global_memory_buffer + curr_rom.offset_wondercard, em_wonder_card, 0x14E);
|
||||
memcpy(global_memory_buffer + curr_GBA_rom.offset_wondercard, em_wonder_card, 0x14E);
|
||||
break;
|
||||
}
|
||||
|
||||
// Set checksum and padding
|
||||
global_memory_buffer[curr_rom.offset_script] = checksum >> 0;
|
||||
global_memory_buffer[curr_rom.offset_script + 1] = checksum >> 8;
|
||||
global_memory_buffer[curr_rom.offset_script + 2] = checksum >> 16;
|
||||
global_memory_buffer[curr_rom.offset_script + 3] = checksum >> 24;
|
||||
global_memory_buffer[curr_GBA_rom.offset_script] = checksum >> 0;
|
||||
global_memory_buffer[curr_GBA_rom.offset_script + 1] = checksum >> 8;
|
||||
global_memory_buffer[curr_GBA_rom.offset_script + 2] = checksum >> 16;
|
||||
global_memory_buffer[curr_GBA_rom.offset_script + 3] = checksum >> 24;
|
||||
|
||||
// Add in Mystery Script data
|
||||
memcpy(global_memory_buffer + curr_rom.offset_script + 4, script.get_script(), MG_SCRIPT_SIZE);
|
||||
memcpy(global_memory_buffer + curr_GBA_rom.offset_script + 4, script.get_script(), MG_SCRIPT_SIZE);
|
||||
|
||||
update_memory_buffer_checksum(false);
|
||||
erase_sector(memory_section_array[4]);
|
||||
|
|
@ -127,7 +82,9 @@ bool inject_mystery(Pokemon_Party &incoming_box_data)
|
|||
{
|
||||
for (int i = 0; i < 1122; i++)
|
||||
{
|
||||
global_memory_buffer[i] = incoming_box_data.box_data_array[i];
|
||||
// global_memory_buffer[i] = incoming_box_data.box_data_array[i];
|
||||
while(true){}
|
||||
// This is currently not possible(?)
|
||||
}
|
||||
for (int i = 0; i < 0x1000 - 1122; i++)
|
||||
{
|
||||
|
|
@ -137,18 +94,18 @@ bool inject_mystery(Pokemon_Party &incoming_box_data)
|
|||
}
|
||||
|
||||
// Set flags
|
||||
int memory_section = 1 + ((curr_rom.offset_flags + (curr_rom.unused_flag_start / 8)) / 0xF80); // This sets the correct memory section, since flags stretch between section 1 and 2.
|
||||
int memory_section = 1 + ((curr_GBA_rom.offset_flags + (curr_GBA_rom.unused_flag_start / 8)) / 0xF80); // This sets the correct memory section, since flags stretch between section 1 and 2.
|
||||
copy_save_to_ram(memory_section_array[memory_section], &global_memory_buffer[0], 0x1000);
|
||||
global_memory_buffer[(curr_rom.offset_flags + (curr_rom.all_collected_flag / 8)) % 0xF80] &= ~(1 << (curr_rom.all_collected_flag % 8)); // Set "collected all" flag to 0
|
||||
global_memory_buffer[(curr_GBA_rom.offset_flags + (curr_GBA_rom.all_collected_flag / 8)) % 0xF80] &= ~(1 << (curr_GBA_rom.all_collected_flag % 8)); // Set "collected all" flag to 0
|
||||
|
||||
for (int i = 0; i < MAX_PKMN_IN_BOX; i++)
|
||||
{
|
||||
int curr_flag;
|
||||
curr_flag = curr_rom.pkmn_collected_flag_start + i;
|
||||
global_memory_buffer[(curr_rom.offset_flags + (curr_flag / 8)) % 0xF80] &= ~(1 << (curr_flag % 8)); // Reset the flag
|
||||
if (incoming_box_data.get_simple_pkmn(i).is_valid)
|
||||
curr_flag = curr_GBA_rom.pkmn_collected_flag_start + i;
|
||||
global_memory_buffer[(curr_GBA_rom.offset_flags + (curr_flag / 8)) % 0xF80] &= ~(1 << (curr_flag % 8)); // Reset the flag
|
||||
if (box->getGen3Pokemon(i)->isValid)
|
||||
{
|
||||
global_memory_buffer[(curr_rom.offset_flags + (curr_flag / 8)) % 0xF80] |= (1 << (curr_flag % 8)); // Set flag accordingly
|
||||
global_memory_buffer[(curr_GBA_rom.offset_flags + (curr_flag / 8)) % 0xF80] |= (1 << (curr_flag % 8)); // Set flag accordingly
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
818
source/pccs/GBPokemon.cpp
Normal file
818
source/pccs/GBPokemon.cpp
Normal file
|
|
@ -0,0 +1,818 @@
|
|||
#include "GBPokemon.h"
|
||||
|
||||
// This constructor fills all our convenience arrays
|
||||
GBPokemon::GBPokemon()
|
||||
{
|
||||
nicknameArrayPtr = nicknameArray;
|
||||
nicknameArraySize = 11;
|
||||
OTArrayPtr = OTArray;
|
||||
OTArraySize = 11;
|
||||
externalIndexNumberPtr = &externalIndexNumber;
|
||||
isBigEndian = true;
|
||||
generation = 0;
|
||||
}
|
||||
|
||||
// This is used to load our data in from an array
|
||||
void GBPokemon::loadData(Language nLang, byte nDataArray[], byte nNicknameArray[], byte nOTArray[], byte nExternalIndexNum)
|
||||
{
|
||||
for (int i = 0; i < dataArraySize; i++)
|
||||
{
|
||||
dataArrayPtr[i] = nDataArray[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < nicknameArraySize; i++)
|
||||
{
|
||||
nicknameArray[i] = nNicknameArray[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < OTArraySize; i++)
|
||||
{
|
||||
OTArray[i] = nOTArray[i];
|
||||
}
|
||||
|
||||
if (generation == 1)
|
||||
{
|
||||
externalIndexNumber = gen_1_index_array[nExternalIndexNum];
|
||||
}
|
||||
else
|
||||
{
|
||||
externalIndexNumber = nExternalIndexNum;
|
||||
}
|
||||
|
||||
lang = nLang;
|
||||
updateValidity();
|
||||
}
|
||||
|
||||
// This is used to easily print out a Pokemon, when using a standard C++ terminal
|
||||
#if ON_GBA
|
||||
#else
|
||||
std::string GBPokemon::parentPrint()
|
||||
{
|
||||
pokeTable->load_input_charset(generation, ENGLISH);
|
||||
std::stringstream os;
|
||||
os << "Species Index Number: " << getSpeciesIndexNumber() << "\n"
|
||||
<< "Nickname: [";
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
os << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex << (int)nicknameArray[i] << (i < 9 ? ", " : "");
|
||||
}
|
||||
|
||||
os << "] (";
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
os << (char)(pokeTable->input_charset[(int)nicknameArray[i]]);
|
||||
}
|
||||
|
||||
os << ")" << "\n"
|
||||
<< "Original Trainer: [";
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
os << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex << (int)OTArray[i] << (i < 6 ? ", " : "");
|
||||
}
|
||||
|
||||
os << "] (";
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
os << (char)(pokeTable->input_charset[(int)OTArray[i]]);
|
||||
}
|
||||
|
||||
os << ")" << "\n"
|
||||
<< std::dec
|
||||
<< "Trainer ID: " << getTrainerID() << "\n"
|
||||
<< "Level: " << getLevel() << "\n"
|
||||
<< "Exp: " << getExpPoints() << "\n"
|
||||
<< "Moves: "
|
||||
<< "\n\t" << getMove(0) << " (" << getPPTotal(0) << " PP, " << getPPUpNum(0) << " PP Ups" << ")"
|
||||
<< "\n\t" << getMove(1) << " (" << getPPTotal(1) << " PP, " << getPPUpNum(1) << " PP Ups" << ")"
|
||||
<< "\n\t" << getMove(2) << " (" << getPPTotal(2) << " PP, " << getPPUpNum(2) << " PP Ups" << ")"
|
||||
<< "\n\t" << getMove(3) << " (" << getPPTotal(3) << " PP, " << getPPUpNum(3) << " PP Ups" << ")" << "\n"
|
||||
<< "Is Shiny: " << getIsShiny() << "\n";
|
||||
return os.str();
|
||||
}
|
||||
#endif
|
||||
|
||||
u32 GBPokemon::getDV(Stat currStat)
|
||||
{
|
||||
if (currStat == HP)
|
||||
{
|
||||
|
||||
return ((getVar(DVs[ATTACK][generation - 1]) & 0x1) << 3) |
|
||||
((getVar(DVs[DEFENSE][generation - 1]) & 0x1) << 2) |
|
||||
((getVar(DVs[SPEED][generation - 1]) & 0x1) << 1) |
|
||||
((getVar(DVs[SPECIAL][generation - 1]) & 0x1) << 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return getVar(DVs[currStat][generation - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
bool GBPokemon::setDV(Stat currStat, byte newVal)
|
||||
{
|
||||
if (currStat == HP)
|
||||
{
|
||||
return setVar(DVs[ATTACK][generation - 1], (getVar(DVs[ATTACK][generation - 1]) & 0b1110) | ((newVal >> 3) & 0x1)) &&
|
||||
setVar(DVs[DEFENSE][generation - 1], (getVar(DVs[DEFENSE][generation - 1]) & 0b1110) | ((newVal >> 2) & 0x1)) &&
|
||||
setVar(DVs[SPEED][generation - 1], (getVar(DVs[SPEED][generation - 1]) & 0b1110) | ((newVal >> 1) & 0x1)) &&
|
||||
setVar(DVs[SPECIAL][generation - 1], (getVar(DVs[SPECIAL][generation - 1]) & 0b1110) | ((newVal >> 0) & 0x1));
|
||||
}
|
||||
else
|
||||
{
|
||||
return setVar(DVs[currStat][generation - 1], newVal);
|
||||
}
|
||||
}
|
||||
|
||||
byte GBPokemon::getUnownLetter()
|
||||
{
|
||||
if (getSpeciesIndexNumber() == 201)
|
||||
{
|
||||
byte letter = 0;
|
||||
letter |= ((getDV(ATTACK) & 0b0110) >> 1) << 6;
|
||||
letter |= ((getDV(DEFENSE) & 0b0110) >> 1) << 4;
|
||||
letter |= ((getDV(SPEED) & 0b0110) >> 1) << 2;
|
||||
letter |= ((getDV(SPECIAL) & 0b0110) >> 1) << 0;
|
||||
letter = letter / 10;
|
||||
return letter;
|
||||
}
|
||||
return 255;
|
||||
}
|
||||
|
||||
Gender GBPokemon::getGender()
|
||||
{
|
||||
byte index = getSpeciesIndexNumber();
|
||||
u32 threshold = pokeTable->get_gender_threshold(index, false);
|
||||
|
||||
if (threshold == 255)
|
||||
{
|
||||
return GENDERLESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getDV(ATTACK) <= threshold)
|
||||
{
|
||||
return FEMALE;
|
||||
}
|
||||
return MALE;
|
||||
}
|
||||
}
|
||||
|
||||
Nature GBPokemon::getVirtualConsoleNature()
|
||||
{
|
||||
return (Nature)(getExpPoints() % 25);
|
||||
}
|
||||
|
||||
bool GBPokemon::getIsShiny()
|
||||
{
|
||||
return ((getDV(ATTACK) & 0b0010) == 0b0010) &&
|
||||
getDV(DEFENSE) == 10 &&
|
||||
getDV(SPEED) == 10 &&
|
||||
getDV(SPECIAL) == 10;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertToGen3(Gen3Pokemon *newPkmn, bool sanitizeMythicals)
|
||||
{
|
||||
if (!isValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool valid =
|
||||
// Start with things that effect the PID
|
||||
convertSpeciesIndexNumber(newPkmn) &&
|
||||
setRequestedLetter(newPkmn) &&
|
||||
setRequestedNature(newPkmn) &&
|
||||
setRequestedGender(newPkmn) &&
|
||||
setRequestedAbility(newPkmn) &&
|
||||
setRequestedSize(newPkmn) &&
|
||||
|
||||
// Then set the PID
|
||||
generatePersonalityValue(newPkmn, ABCD_U) &&
|
||||
|
||||
// Then set everything else
|
||||
convertTrainerID(newPkmn) &&
|
||||
convertNickname(newPkmn) &&
|
||||
convertLanguage(newPkmn) &&
|
||||
convertMiscFlags(newPkmn) &&
|
||||
convertTrainerNickname(newPkmn) &&
|
||||
convertMarkings(newPkmn) &&
|
||||
convertItem(newPkmn) &&
|
||||
convertEXP(newPkmn) &&
|
||||
convertFriendship(newPkmn) &&
|
||||
convertMoves(newPkmn) &&
|
||||
convertEVs(newPkmn) &&
|
||||
convertContestConditions(newPkmn) &&
|
||||
convertPokerus(newPkmn) &&
|
||||
convertMetLocation(newPkmn) &&
|
||||
convertMetLevel(newPkmn) &&
|
||||
convertGameOfOrigin(newPkmn) &&
|
||||
convertPokeball(newPkmn) &&
|
||||
convertTrainerGender(newPkmn) &&
|
||||
convertIVs(newPkmn) &&
|
||||
convertRibbonsAndObedience(newPkmn) &&
|
||||
convertShininess(newPkmn);
|
||||
|
||||
if (sanitizeMythicals && (getSpeciesIndexNumber() == MEW || getSpeciesIndexNumber() == CELEBI))
|
||||
{
|
||||
// Modify the required data for the event
|
||||
valid &= loadEvent(newPkmn);
|
||||
}
|
||||
|
||||
newPkmn->isValid = valid;
|
||||
return valid;
|
||||
};
|
||||
|
||||
bool GBPokemon::loadEvent(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
bool valid =
|
||||
generatePersonalityValue(newPkmn, BACD_R) &&
|
||||
convertEVs(newPkmn) &&
|
||||
convertIVs(newPkmn);
|
||||
if (!valid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (getSpeciesIndexNumber() == MEW)
|
||||
{
|
||||
newPkmn->setGameOfOrigin(RUBY);
|
||||
newPkmn->setFatefulEncounterObedience(true);
|
||||
newPkmn->setMetLocation(0xFF); // Fateful Encounter
|
||||
newPkmn->setLevelMet(10);
|
||||
newPkmn->setSecretID(00000);
|
||||
if (newPkmn->getExpPoints() < 560) // 560 is level 10 for Mew
|
||||
{
|
||||
newPkmn->setExpPoints(560);
|
||||
}
|
||||
|
||||
byte jpnOT[] = {0x6A, 0x95, 0x53, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
byte engOT[] = {0xBB, 0xE9, 0xE6, 0xD5, 0xFF, 0x00, 0x00};
|
||||
|
||||
switch (getLanguage())
|
||||
{
|
||||
case JAPANESE:
|
||||
case KOREAN:
|
||||
newPkmn->setTrainerID(50716);
|
||||
newPkmn->setOTArray(jpnOT, 7);
|
||||
break;
|
||||
case ENGLISH:
|
||||
case FRENCH:
|
||||
case ITALIAN:
|
||||
case GERMAN:
|
||||
case SPANISH:
|
||||
default:
|
||||
newPkmn->setTrainerID(20078);
|
||||
newPkmn->setOTArray(engOT, 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (getSpeciesIndexNumber() == CELEBI)
|
||||
{
|
||||
newPkmn->setGameOfOrigin(RUBY);
|
||||
newPkmn->setFatefulEncounterObedience(false);
|
||||
newPkmn->setMetLocation(0xFF); // Fateful Encounter
|
||||
newPkmn->setSecretID(0);
|
||||
|
||||
byte jpnOT[] = {0x70, 0x62, 0x78, 0x7E, 0xFF, 0x00, 0x00};
|
||||
byte engOT[] = {0xA2, 0xA1, 0x00, 0xBB, 0xC8, 0xC3, 0xD0};
|
||||
|
||||
switch (getLanguage())
|
||||
{
|
||||
case JAPANESE:
|
||||
case KOREAN:
|
||||
newPkmn->setLevelMet(10);
|
||||
if (newPkmn->getExpPoints() < 560) // 560 is level 10 for Celebi
|
||||
{
|
||||
newPkmn->setExpPoints(560);
|
||||
}
|
||||
newPkmn->setTrainerID(60720);
|
||||
newPkmn->setOTArray(jpnOT, 7);
|
||||
break;
|
||||
case ENGLISH:
|
||||
case FRENCH:
|
||||
case ITALIAN:
|
||||
case GERMAN:
|
||||
case SPANISH:
|
||||
default:
|
||||
newPkmn->setLanguage(ENGLISH);
|
||||
newPkmn->setLevelMet(70);
|
||||
if (newPkmn->getExpPoints() < 344960) // 344960 is level 70 for Celebi
|
||||
{
|
||||
newPkmn->setExpPoints(344960);
|
||||
}
|
||||
newPkmn->setTrainerID(10);
|
||||
newPkmn->setOTArray(engOT, 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int val = getExpPoints();
|
||||
if (val < 560) // Mew and Celebi are both Medium Slow, 560 is level 10
|
||||
{
|
||||
setExpPoints(560);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GBPokemon::updateValidity()
|
||||
{
|
||||
byte currSpeciesIndexNumber = getSpeciesIndexNumber();
|
||||
isValid = ((currSpeciesIndexNumber <= CELEBI || // Checks if the Pokemon is beyond the spported Pokemon, excluding Treecko for now
|
||||
(currSpeciesIndexNumber == MISSINGNO && generation == 1)) && // But keep MissingNo
|
||||
currSpeciesIndexNumber != 0 && // Makes sure the Pokemon isn't a blank party space
|
||||
currSpeciesIndexNumber == externalIndexNumber && // Checks that the Pokemon isn't a hybrid or an egg
|
||||
getHeldItem() == 0 // Makes sure the current Pokemon doesn't have a held item
|
||||
);
|
||||
};
|
||||
|
||||
bool GBPokemon::externalConvertNickname(byte outputArray[])
|
||||
{
|
||||
pokeTable->load_input_charset(generation, ENGLISH);
|
||||
pokeTable->load_gen3_charset(ENGLISH);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
outputArray[i] = pokeTable->get_gen_3_char(pokeTable->input_charset[nicknameArray[i]]);
|
||||
}
|
||||
outputArray[10] = 0xFF;
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::generatePersonalityValue(Gen3Pokemon *newPkmn, RNGMethod rng)
|
||||
{
|
||||
newPkmn->currRand = getPureRand();
|
||||
u32 pid = 0;
|
||||
u16 seedA = 0;
|
||||
u16 seedB = 0;
|
||||
do
|
||||
{
|
||||
if (rng == ABCD_U)
|
||||
{
|
||||
seedA = newPkmn->getNextRand_u16();
|
||||
seedB = newPkmn->getNextRand_u16();
|
||||
pid = seedA | (seedB << 16);
|
||||
}
|
||||
else if (rng == BACD_R)
|
||||
{
|
||||
newPkmn->currRand &= 0xFFFF; // Restrict the seed to 16 bits
|
||||
seedA = newPkmn->getNextRand_u16();
|
||||
seedB = newPkmn->getNextRand_u16();
|
||||
pid = seedB | (seedA << 16);
|
||||
}
|
||||
newPkmn->setPersonalityValue(pid);
|
||||
// std::cout << "Testing PID: " << std::hex << pid << "\n";
|
||||
/*
|
||||
std::cout << "PV: " << newPkmn->getPersonalityValue() << "\n"
|
||||
<< "Letter: " << newPkmn->getUnownLetter() << " | " << getUnownLetter() << "\n"
|
||||
<< "Nature: " << newPkmn->getNature() << " | " << getVirtualConsoleNature() << "\n"
|
||||
<< "Gender: " << newPkmn->getGender() << " | " << getGender() << "\n";
|
||||
*/
|
||||
} while (!(
|
||||
newPkmn->getAbilityFromPersonalityValue() == newPkmn->internalAbility &&
|
||||
newPkmn->getUnownLetter() == newPkmn->internalUnownLetter &&
|
||||
newPkmn->getNature() == newPkmn->internalNature &&
|
||||
newPkmn->getGender() == newPkmn->internalGender &&
|
||||
newPkmn->getSize() == newPkmn->internalSize));
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::convertTrainerID(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->setTrainerID(getTrainerID());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertNickname(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
pokeTable->load_input_charset(generation, ENGLISH);
|
||||
pokeTable->load_gen3_charset(ENGLISH);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
newPkmn->setNicknameLetter(i, pokeTable->get_gen_3_char(pokeTable->input_charset[nicknameArray[i]]));
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::convertLanguage(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->setLanguage(getLanguage());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertMiscFlags(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->setIsBadEgg(false);
|
||||
newPkmn->setHasSpecies(true);
|
||||
newPkmn->setUseEggName(false);
|
||||
newPkmn->setIsEgg(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertTrainerNickname(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
pokeTable->load_input_charset(1, ENGLISH);
|
||||
pokeTable->load_gen3_charset(ENGLISH);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
newPkmn->setOTLetter(i, pokeTable->get_gen_3_char(pokeTable->input_charset[OTArray[i]]));
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::convertMarkings(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->setMarkings(0b0000);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertSpeciesIndexNumber(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
switch (getSpeciesIndexNumber())
|
||||
{
|
||||
case TREECKO:
|
||||
newPkmn->setSpeciesIndexNumber(0x115);
|
||||
break;
|
||||
case MISSINGNO:
|
||||
newPkmn->setSpeciesIndexNumber(PORYGON);
|
||||
break;
|
||||
default:
|
||||
newPkmn->setSpeciesIndexNumber(getSpeciesIndexNumber());
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertItem(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
#if ACCESS_POKEDEX
|
||||
#include "save_data_manager.h"
|
||||
if (!is_caught(newPkmn->getSpeciesIndexNumber()))
|
||||
{
|
||||
newPkmn->setHeldItem(RARE_CANDY);
|
||||
set_caught(newPkmn->getSpeciesIndexNumber());
|
||||
}
|
||||
else
|
||||
{
|
||||
newPkmn->setHeldItem(NONE);
|
||||
}
|
||||
#else
|
||||
newPkmn->setHeldItem(NONE);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertEXP(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
// As per Poke Transporter, the level will be based on the level value, not the EXP
|
||||
// Make sure Level is not over 100
|
||||
|
||||
int speciesIndex = getSpeciesIndexNumber();
|
||||
int currLevel = getLevel();
|
||||
if (currLevel > 100)
|
||||
{
|
||||
currLevel = 100;
|
||||
}
|
||||
|
||||
// Truncate the EXP down to the current level
|
||||
pokeTable->load_exp_groups();
|
||||
switch (pokeTable->EXP_GROUPS[speciesIndex])
|
||||
{
|
||||
case EXP_FAST:
|
||||
newPkmn->setExpPoints((4 * (currLevel * currLevel * currLevel)) / 5);
|
||||
break;
|
||||
|
||||
default: // MissingNo is the only one that should hit default, so match it to Porygon
|
||||
case EXP_MED_FAST:
|
||||
newPkmn->setExpPoints(currLevel * currLevel * currLevel);
|
||||
break;
|
||||
|
||||
case EXP_MED_SLOW:
|
||||
newPkmn->setExpPoints(((6 * currLevel * currLevel * currLevel) / 5) - (15 * currLevel * currLevel) + (100 * currLevel) - 140);
|
||||
break;
|
||||
|
||||
case EXP_SLOW:
|
||||
newPkmn->setExpPoints((5 * (currLevel * currLevel * currLevel)) / 4);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::convertFriendship(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->setFriendship(70);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertMoves(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
Species speciesIndexNum = (Species)getSpeciesIndexNumber();
|
||||
// Check that the moves are valid
|
||||
if ((speciesIndexNum != SMEARGLE) &&
|
||||
(speciesIndexNum != MISSINGNO) &&
|
||||
(speciesIndexNum != TREECKO)) // Ignore Smeargle, MissingNo, and Treecko
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (pokeTable->can_learn_move(speciesIndexNum, getMove(i)))
|
||||
{
|
||||
newPkmn->setMove(i, getMove(i)); // Add the move
|
||||
newPkmn->setPPUpNum(i, getPPUpNum(i)); // Add the PP Bonuses
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure it has at least one move
|
||||
int count = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
count += (newPkmn->getMove(i) != 0);
|
||||
}
|
||||
if (count == 0)
|
||||
{
|
||||
newPkmn->setMove(0, pokeTable->get_earliest_move(speciesIndexNum));
|
||||
}
|
||||
|
||||
// Bubble valid moves to the top
|
||||
int i, j;
|
||||
bool swapped;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
swapped = false;
|
||||
for (j = 0; j < 3 - i; j++)
|
||||
{
|
||||
if (newPkmn->getMove(j) == 0 && newPkmn->getMove(j + 1) != 0)
|
||||
{
|
||||
// Move the move *and* PP bonus up if there is a blank space
|
||||
newPkmn->setMove(j, newPkmn->getMove(j + 1));
|
||||
newPkmn->setPPUpNum(j, newPkmn->getPPUpNum(j + 1));
|
||||
newPkmn->setMove(j + 1, 0);
|
||||
newPkmn->setPPUpNum(j + 1, 0);
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If no two elements were swapped
|
||||
// by inner loop, then break
|
||||
if (swapped == false)
|
||||
break;
|
||||
}
|
||||
|
||||
// Restore the PP values
|
||||
pokeTable->load_power_points();
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int move = newPkmn->getMove(i);
|
||||
newPkmn->setPPTotal(i, pokeTable->POWER_POINTS[move] + ((pokeTable->POWER_POINTS[move] / 5) * newPkmn->getPPUpNum(i)));
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::convertEVs(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
newPkmn->setEV((Stat)i, 0);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::convertContestConditions(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
newPkmn->setContestCondition((Condition)i, 0);
|
||||
}
|
||||
newPkmn->setSheen(0);
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::convertPokerus(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->setPokerusStrain(getPokerusStrain());
|
||||
newPkmn->setPokerusDaysRemaining(getPokerusDaysRemaining());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertMetLocation(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->setMetLocation(0xFF); // A fateful encounter
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertMetLevel(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->setLevelMet(getLevel());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertGameOfOrigin(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
switch (generation)
|
||||
{
|
||||
case 1:
|
||||
newPkmn->setGameOfOrigin(FIRERED);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
newPkmn->setGameOfOrigin(HEARTGOLD);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertPokeball(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
if (getSpeciesIndexNumber() == MISSINGNO)
|
||||
{
|
||||
newPkmn->setPokeballCaughtIn(MASTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
newPkmn->setPokeballCaughtIn(POKE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertTrainerGender(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->setOriginalTrainerGender(getCaughtDataGender());
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::convertIVs(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
u16 currRand;
|
||||
|
||||
currRand = newPkmn->getNextRand_u16();
|
||||
newPkmn->setIV(HP, (currRand >> 0) & 0b11111);
|
||||
newPkmn->setIV(ATTACK, (currRand >> 5) & 0b11111);
|
||||
newPkmn->setIV(DEFENSE, (currRand >> 10) & 0b11111);
|
||||
currRand = newPkmn->getNextRand_u16();
|
||||
newPkmn->setIV(SPEED, (currRand >> 0) & 0b11111);
|
||||
newPkmn->setIV(SPECIAL_ATTACK, (currRand >> 5) & 0b11111);
|
||||
newPkmn->setIV(SPECIAL_DEFENSE, (currRand >> 10) & 0b11111);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::convertAbilityFlag(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->setAbility(newPkmn->getPersonalityValue() & 0b1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GBPokemon::convertRibbonsAndObedience(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
Species speciesIndexNumber = (Species)getSpeciesIndexNumber();
|
||||
if (speciesIndexNumber == MEW || speciesIndexNumber == CELEBI)
|
||||
{
|
||||
newPkmn->setFatefulEncounterObedience(true);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::setRequestedLetter(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->internalUnownLetter = getUnownLetter();
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::setRequestedNature(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->internalNature = getVirtualConsoleNature();
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::setRequestedGender(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->internalGender = getGender();
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::setRequestedAbility(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->internalAbility = 255;
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::setRequestedSize(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
newPkmn->internalSize = 255;
|
||||
return true;
|
||||
};
|
||||
|
||||
bool GBPokemon::convertShininess(Gen3Pokemon *newPkmn)
|
||||
{
|
||||
byte nickname[10] = {};
|
||||
byte trainerName[7] = {};
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
nickname[i] = newPkmn->getNicknameLetter(i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
trainerName[i] = newPkmn->getOTLetter(i);
|
||||
}
|
||||
|
||||
if ((getSpeciesIndexNumber() == 52) &&
|
||||
fnv1a_hash(trainerName, 7) == 1342961308 &&
|
||||
(fnv1a_hash(nickname, 7) == 1515822901 || fnv1a_hash(nickname, 8) == 2671449886))
|
||||
{
|
||||
for (int i = 1; i <= 4; i++)
|
||||
{
|
||||
setDV((Stat)i, 15);
|
||||
}
|
||||
}
|
||||
|
||||
u16 shinyTest = newPkmn->getTrainerID() ^
|
||||
(newPkmn->getPersonalityValue() >> 0 & 0xFFFF) ^
|
||||
(newPkmn->getPersonalityValue() >> 16 & 0xFFFF);
|
||||
|
||||
if (getIsShiny())
|
||||
{ // Make shiny
|
||||
newPkmn->setSecretID(shinyTest);
|
||||
}
|
||||
else
|
||||
{ // Make sure it isn't shiny
|
||||
if (shinyTest < 8)
|
||||
{ // It became shiny, fix that
|
||||
newPkmn->setSecretID(51691);
|
||||
}
|
||||
else
|
||||
{
|
||||
newPkmn->setSecretID(0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const DataVarInfo
|
||||
GBPokemon::speciesIndexNumber[2] = {{0x00, 8, 0}, {0x00, 8, 0}},
|
||||
GBPokemon::level[2] = {{0x03, 8, 0}, {0x1F, 8, 0}},
|
||||
GBPokemon::moveOne[2] = {{0x08, 8, 0}, {0x02, 8, 0}},
|
||||
GBPokemon::moveTwo[2] = {{0x09, 8, 0}, {0x03, 8, 0}},
|
||||
GBPokemon::moveThree[2] = {{0x0A, 8, 0}, {0x04, 8, 0}},
|
||||
GBPokemon::moveFour[2] = {{0x0B, 8, 0}, {0x05, 8, 0}},
|
||||
GBPokemon::trainerID[2] = {{0x0C, 16, 0}, {0x06, 16, 0}},
|
||||
GBPokemon::expPoints[2] = {{0x0E, 24, 0}, {0x08, 24, 0}},
|
||||
GBPokemon::hpStatExp[2] = {{0x11, 16, 0}, {0x0B, 16, 0}},
|
||||
GBPokemon::atkStatExp[2] = {{0x13, 16, 0}, {0x0D, 16, 0}},
|
||||
GBPokemon::defStatExp[2] = {{0x15, 16, 0}, {0x0F, 16, 0}},
|
||||
GBPokemon::speStatExp[2] = {{0x17, 16, 0}, {0x11, 16, 0}},
|
||||
GBPokemon::spcStatExp[2] = {{0x19, 16, 0}, {0x13, 16, 0}},
|
||||
GBPokemon::atkDV[2] = {{0x1B, 4, 4}, {0x15, 4, 4}},
|
||||
GBPokemon::defDV[2] = {{0x1B, 4, 0}, {0x15, 4, 0}},
|
||||
GBPokemon::speDV[2] = {{0x1C, 4, 4}, {0x16, 4, 4}},
|
||||
GBPokemon::spcDV[2] = {{0x1C, 4, 0}, {0x16, 4, 0}},
|
||||
GBPokemon::ppUpNumMoveOne[2] = {{0x1D, 2, 6}, {0x17, 2, 6}},
|
||||
GBPokemon::ppNumTotalMoveOne[2] = {{0x1D, 6, 0}, {0x17, 6, 0}},
|
||||
GBPokemon::ppUpNumMoveTwo[2] = {{0x1E, 2, 6}, {0x18, 2, 6}},
|
||||
GBPokemon::ppNumTotalMoveTwo[2] = {{0x1E, 6, 0}, {0x18, 6, 0}},
|
||||
GBPokemon::ppUpNumMoveThree[2] = {{0x1F, 2, 6}, {0x19, 2, 6}},
|
||||
GBPokemon::ppNumTotalMoveThree[2] = {{0x1F, 6, 0}, {0x19, 6, 0}},
|
||||
GBPokemon::ppUpNumMoveFour[2] = {{0x20, 2, 6}, {0x1A, 2, 6}},
|
||||
GBPokemon::ppNumTotalMoveFour[2] = {{0x20, 6, 0}, {0x1A, 6, 0}};
|
||||
|
||||
const DataVarInfo
|
||||
*GBPokemon::moves[4] = {
|
||||
GBPokemon::moveOne,
|
||||
GBPokemon::moveTwo,
|
||||
GBPokemon::moveThree,
|
||||
GBPokemon::moveFour,
|
||||
},
|
||||
*GBPokemon::statExps[5] = {
|
||||
GBPokemon::hpStatExp,
|
||||
GBPokemon::atkStatExp,
|
||||
GBPokemon::defStatExp,
|
||||
GBPokemon::speStatExp,
|
||||
GBPokemon::spcStatExp,
|
||||
},
|
||||
*GBPokemon::DVs[5] = {
|
||||
GBPokemon::atkDV, // This is wrong, but it will never be accessed anyway.
|
||||
GBPokemon::atkDV,
|
||||
GBPokemon::defDV,
|
||||
GBPokemon::speDV,
|
||||
GBPokemon::spcDV,
|
||||
},
|
||||
*GBPokemon::PPUpNums[4] = {
|
||||
GBPokemon::ppUpNumMoveOne,
|
||||
GBPokemon::ppUpNumMoveTwo,
|
||||
GBPokemon::ppUpNumMoveThree,
|
||||
GBPokemon::ppUpNumMoveFour,
|
||||
},
|
||||
*GBPokemon::PPUpTotals[4] = {
|
||||
GBPokemon::ppNumTotalMoveOne,
|
||||
GBPokemon::ppNumTotalMoveTwo,
|
||||
GBPokemon::ppNumTotalMoveThree,
|
||||
GBPokemon::ppNumTotalMoveFour,
|
||||
};
|
||||
60
source/pccs/Gen1Pokemon.cpp
Normal file
60
source/pccs/Gen1Pokemon.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#include "Gen1Pokemon.h"
|
||||
|
||||
Gen1Pokemon::Gen1Pokemon(PokemonTables *table)
|
||||
{
|
||||
pokeTable = table;
|
||||
dataArrayPtr = dataArray;
|
||||
dataArraySize = 33;
|
||||
generation = 1;
|
||||
}
|
||||
|
||||
#if ON_GBA
|
||||
#else
|
||||
void Gen1Pokemon::print(std::ostream &os)
|
||||
{
|
||||
os << parentPrint()
|
||||
<< "Stats: "
|
||||
<< "\n\tHP: " << getStatExp(HP) << " Stat EXP, " << getDV(HP) << " DVs"
|
||||
<< "\n\tAttack: " << getStatExp(ATTACK) << " Stat EXP, " << getDV(ATTACK) << " DVs"
|
||||
<< "\n\tDefense: " << getStatExp(DEFENSE) << " Stat EXP, " << getDV(DEFENSE) << " DVs"
|
||||
<< "\n\tSpeed: " << getStatExp(SPEED) << " Stat EXP, " << getDV(SPEED) << " DVs"
|
||||
<< "\n\tSpecial: " << getStatExp(SPECIAL) << " Stat EXP, " << getDV(SPECIAL) << " DVs" << "\n"
|
||||
<< "Types: "
|
||||
<< "\n\t" << getType(0)
|
||||
<< "\n\t" << getType(1) << "\n"
|
||||
<< "Current HP: " << getCurrentHP() << "\n"
|
||||
<< "Status Condition: " << getStatusCondition() << "\n"
|
||||
<< "Catch Rate: " << getCatchRate() << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
u32 Gen1Pokemon::getSpeciesIndexNumber()
|
||||
{
|
||||
return gen_1_index_array[getVar(speciesIndexNumber[1])];
|
||||
}
|
||||
|
||||
bool Gen1Pokemon::setSpeciesIndexNumber(byte newVal)
|
||||
{
|
||||
for (int i = 0; i < 191; i++)
|
||||
{
|
||||
if (gen_1_index_array[i] == newVal)
|
||||
{
|
||||
return setVar(speciesIndexNumber[1], newVal);
|
||||
}
|
||||
}
|
||||
return setVar(speciesIndexNumber[1], newVal);
|
||||
}
|
||||
|
||||
const DataVarInfo
|
||||
Gen1Pokemon::g1_currentHP = {0x01, 16, 0},
|
||||
Gen1Pokemon::g1_statusCondition = {0x04, 8, 0},
|
||||
Gen1Pokemon::g1_typeOne = {0x05, 8, 0},
|
||||
Gen1Pokemon::g1_typeTwo = {0x06, 8, 0},
|
||||
Gen1Pokemon::g1_catchRate = {0x07, 8, 0};
|
||||
|
||||
const DataVarInfo
|
||||
*Gen1Pokemon::g1_types[2] =
|
||||
{
|
||||
&Gen1Pokemon::g1_typeOne,
|
||||
&Gen1Pokemon::g1_typeTwo,
|
||||
};
|
||||
44
source/pccs/Gen2Pokemon.cpp
Normal file
44
source/pccs/Gen2Pokemon.cpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include "Gen2Pokemon.h"
|
||||
|
||||
Gen2Pokemon::Gen2Pokemon(PokemonTables *table)
|
||||
{
|
||||
pokeTable = table;
|
||||
dataArrayPtr = dataArray;
|
||||
dataArraySize = 32;
|
||||
generation = 2;
|
||||
}
|
||||
|
||||
#if ON_GBA
|
||||
#else
|
||||
void Gen2Pokemon::print(std::ostream &os)
|
||||
{
|
||||
os << parentPrint()
|
||||
<< "Stats: "
|
||||
<< "\n\tHP: " << getStatExp(HP) << " Stat EXP, " << getDV(HP) << " DVs"
|
||||
<< "\n\tAttack: " << getStatExp(ATTACK) << " Stat EXP, " << getDV(ATTACK) << " DVs"
|
||||
<< "\n\tDefense: " << getStatExp(DEFENSE) << " Stat EXP, " << getDV(DEFENSE) << " DVs"
|
||||
<< "\n\tSpeed: " << getStatExp(SPEED) << " Stat EXP, " << getDV(SPEED) << " DVs"
|
||||
<< "\n\tSpecial Attack: " << getStatExp(SPECIAL) << " Stat EXP, " << getDV(SPECIAL) << " DVs"
|
||||
<< "\n\tSpecial Defense: " << getStatExp(SPECIAL) << " Stat EXP, " << getDV(SPECIAL) << " DVs" << "\n" // Special Attack and Special Defense are the same
|
||||
<< "Held Item: " << getHeldItem() << "\n"
|
||||
<< "Friendship: " << getFriendship() << "\n"
|
||||
<< "Pokerus: "
|
||||
<< "\n\tStrain: " << getPokerusStrain()
|
||||
<< "\n\tDays Remaining: " << getPokerusDaysRemaining() << "\n"
|
||||
<< "Caught Data: "
|
||||
<< "\n\tTime: " << getCaughtDataTime()
|
||||
<< "\n\tLevel: " << getCaughtDataLevel()
|
||||
<< "\n\tTrainer Gender: " << getCaughtDataGender()
|
||||
<< "\n\tLocation: " << getCaughtDataLocation() << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
const DataVarInfo
|
||||
Gen2Pokemon::g2_heldItem = {0x01, 8, 0},
|
||||
Gen2Pokemon::g2_friendship = {0x1B, 8, 0},
|
||||
Gen2Pokemon::g2_pokerusStrain = {0x1C, 4, 4},
|
||||
Gen2Pokemon::g2_pokerusDaysRemaining = {0x1C, 4, 0},
|
||||
Gen2Pokemon::g2_caughtDataTime = {0x1D, 2, 6},
|
||||
Gen2Pokemon::g2_caughtDataLevel = {0x1D, 6, 0},
|
||||
Gen2Pokemon::g2_caughtDataGender = {0x1E, 1, 7},
|
||||
Gen2Pokemon::g2_caughtDataLocation = {0x1E, 7, 0};
|
||||
743
source/pccs/Gen3Pokemon.cpp
Normal file
743
source/pccs/Gen3Pokemon.cpp
Normal file
|
|
@ -0,0 +1,743 @@
|
|||
#include "Gen3Pokemon.h"
|
||||
|
||||
Gen3Pokemon::Gen3Pokemon(PokemonTables *table)
|
||||
{
|
||||
pokeTable = table;
|
||||
dataArrayPtr = dataArray;
|
||||
dataArraySize = 80;
|
||||
nicknameArrayPtr = &dataArray[0x8];
|
||||
OTArrayPtr = &dataArray[0x14];
|
||||
isBigEndian = false;
|
||||
isEncrypted = false;
|
||||
generation = 3;
|
||||
};
|
||||
|
||||
bool Gen3Pokemon::convertToGen3(Gen3Pokemon *g3p)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is used to easily print out a Pokemon, when using a standard C++ terminal
|
||||
#if ON_GBA
|
||||
#else
|
||||
void Gen3Pokemon::print(std::ostream &os)
|
||||
{
|
||||
updateChecksum();
|
||||
updateSubstructureShift();
|
||||
|
||||
pokeTable->load_gen3_charset(ENGLISH);
|
||||
if (!isValid)
|
||||
{
|
||||
os << "ERROR: POKEMON IS INVALID\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
os
|
||||
<< "Personality Value: " << std::hex << getPersonalityValue() << std::dec
|
||||
<< "\n\tLetter: " << (int)getUnownLetter()
|
||||
<< "\n\tNature: " << getNature()
|
||||
<< "\n\tGender: " << getGender() << '\n'
|
||||
<< "Trainer ID: " << getTrainerID() << "\n"
|
||||
<< "Secret ID: " << getSecretID() << "\n"
|
||||
<< "Nickname: [";
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
os << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex << (int)getNicknameLetter(i) << (i < 9 ? ", " : "");
|
||||
}
|
||||
|
||||
os << "] (";
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
os << (char)(pokeTable->gen3_charset[(int)getNicknameLetter(i)]);
|
||||
}
|
||||
|
||||
os << ")" << "\n"
|
||||
<< "Original Trainer: [";
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
os << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex << (int)getOTLetter(i) << (i < 6 ? ", " : "");
|
||||
}
|
||||
|
||||
os << "] (";
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
os << (char)(pokeTable->gen3_charset[(int)getOTLetter(i)]);
|
||||
}
|
||||
|
||||
os << ")" << "\n"
|
||||
<< std::dec
|
||||
<< "Language: " << getLanguage() << "\n"
|
||||
<< "Is Bad Egg: " << getIsBadEgg() << "\n"
|
||||
<< "Has Species: " << getHasSpecies() << "\n"
|
||||
<< "Use Egg Name: " << getUseEggName() << "\n"
|
||||
<< "Block Box RS: " << getBlockBoxRS() << "\n"
|
||||
<< "Markings: " << getMarkings() << "\n"
|
||||
<< "Checksum: " << getChecksum() << "\n"
|
||||
<< "Species Index Number: " << getSpeciesIndexNumber() << "\n"
|
||||
<< "Held Item: " << getHeldItem() << "\n"
|
||||
<< "Experience: " << getExpPoints() << "\n"
|
||||
<< "Friendship: " << getFriendship() << "\n"
|
||||
<< "Stats: "
|
||||
<< "\n\tHP: " << getEV(HP) << " EVs, " << getIV(HP) << " IVs"
|
||||
<< "\n\tAttack: " << getEV(ATTACK) << " EVs, " << getIV(ATTACK) << " IVs"
|
||||
<< "\n\tDefense: " << getEV(DEFENSE) << " EVs, " << getIV(DEFENSE) << " IVs"
|
||||
<< "\n\tSpecial Attack: " << getEV(SPECIAL_ATTACK) << " EVs, " << getIV(SPECIAL_ATTACK) << " IVs"
|
||||
<< "\n\tSpecial Defense: " << getEV(SPECIAL_DEFENSE) << " EVs, " << getIV(SPECIAL_DEFENSE) << " IVs"
|
||||
<< "\n\tSpeed: " << getEV(SPEED) << " EVs, " << getIV(SPEED) << " IVs" << "\n"
|
||||
<< "Contest Stats: "
|
||||
<< "\n\tCoolness: " << getContestCondition(COOLNESS)
|
||||
<< "\n\tBeauty: " << getContestCondition(BEAUTY)
|
||||
<< "\n\tCuteness: " << getContestCondition(CUTENESS)
|
||||
<< "\n\tSmartness: " << getContestCondition(SMARTNESS)
|
||||
<< "\n\tToughness: " << getContestCondition(TOUGHNESS)
|
||||
<< "\n\tSheen: " << getSheen() << "\n"
|
||||
<< "Moves: "
|
||||
<< "\n\t" << getMove(0) << " (" << getPPTotal(0) << " PP, " << getPPUpNum(0) << " PP Ups" << ")"
|
||||
<< "\n\t" << getMove(1) << " (" << getPPTotal(1) << " PP, " << getPPUpNum(1) << " PP Ups" << ")"
|
||||
<< "\n\t" << getMove(2) << " (" << getPPTotal(2) << " PP, " << getPPUpNum(2) << " PP Ups" << ")"
|
||||
<< "\n\t" << getMove(3) << " (" << getPPTotal(3) << " PP, " << getPPUpNum(3) << " PP Ups" << ")" << "\n"
|
||||
<< "Pokerus: "
|
||||
<< "\n\tStrain: " << getPokerusStrain()
|
||||
<< "\n\tDays Remaining: " << getPokerusDaysRemaining() << "\n"
|
||||
<< "Met Location: " << getMetLocation() << "\n"
|
||||
<< "Level Met: " << getLevelMet() << "\n"
|
||||
<< "Game of Origin: " << getGameOfOrigin() << "\n"
|
||||
<< "Pokeball Caught In: " << getPokeballCaughtIn() << "\n"
|
||||
<< "Original Trainer Gender: " << getOriginalTrainerGender() << "\n"
|
||||
<< "Is Egg: " << getIsEgg() << "\n"
|
||||
<< "Ability: " << getAbility() << "\n"
|
||||
<< "Fateful Encounter/Obedience: " << getFatefulEncounterObedience() << "\n"
|
||||
<< "Is Shiny: " << getIsShiny() << "\n"
|
||||
<< "\n"
|
||||
<< "Substructure Perm: " << currSubstructureShift << "\n"
|
||||
<< "Encryption Key: " << std::hex << ((getTrainerID() | getSecretID() << 16) ^ getPersonalityValue()) << std::dec << "\n"
|
||||
<< "Substructure offsets:"
|
||||
<< "\n\tG: " << substructOffsets[SUB_G]
|
||||
<< "\n\tA: " << substructOffsets[SUB_A]
|
||||
<< "\n\tE: " << substructOffsets[SUB_E]
|
||||
<< "\n\tM: " << substructOffsets[SUB_M]
|
||||
<< "\n";
|
||||
}
|
||||
};
|
||||
std::string Gen3Pokemon::printDataArray(bool encrypedData)
|
||||
{
|
||||
updateSubstructureShift();
|
||||
updateChecksum();
|
||||
encryptSubstructures();
|
||||
std::stringstream ss;
|
||||
for (int i = 0; i < 80; i++)
|
||||
{
|
||||
ss << std::hex << std::setw(2) << std::setfill('0') << (int)dataArray[i] << (i < 79 ? " " : "");
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get Nickname is different
|
||||
// u32 getNickname() {};
|
||||
// u32 getOriginalTrainerName() {}
|
||||
|
||||
u32 Gen3Pokemon::getNextRand_u32()
|
||||
{
|
||||
currRand = (0x41C64E6D * currRand) + 0x6073;
|
||||
// std::cout << "Rolled: " << std::hex << currRand << "\n";
|
||||
return currRand;
|
||||
}
|
||||
|
||||
u32 Gen3Pokemon::getPrevRand_u32()
|
||||
{
|
||||
currRand = (currRand - 24691) * 4005161829;
|
||||
return currRand;
|
||||
}
|
||||
|
||||
u16 Gen3Pokemon::getNextRand_u16()
|
||||
{
|
||||
return getNextRand_u32() >> 16;
|
||||
}
|
||||
|
||||
u16 Gen3Pokemon::getPrevRand_u16()
|
||||
{
|
||||
return getPrevRand_u32() >> 16;
|
||||
}
|
||||
|
||||
bool Gen3Pokemon::setPersonalityValue(u32 newVal) // Setting the Personality Value should modify some other values as well
|
||||
{
|
||||
bool successful = setVar(personalityValue, newVal);
|
||||
if (successful)
|
||||
{
|
||||
//successful &= setAbility(getPersonalityValue() & 0b1);
|
||||
}
|
||||
return successful;
|
||||
}
|
||||
|
||||
bool Gen3Pokemon::setAbility(u32 newVal) // We need to check if they have two abilities
|
||||
{
|
||||
if (pokeTable->get_num_abilities(getSpeciesIndexNumber()) == 0)
|
||||
{
|
||||
newVal = 0;
|
||||
}
|
||||
internalAbility = newVal;
|
||||
return setVar(ability, substructOffsets[SUB_M], newVal);
|
||||
}
|
||||
|
||||
// This is used to load our data in from an array and mark it as encrypted
|
||||
void Gen3Pokemon::loadData(byte incomingArray[])
|
||||
{
|
||||
for (int i = 0; i < dataArraySize; i++)
|
||||
{
|
||||
dataArrayPtr[i] = incomingArray[i];
|
||||
}
|
||||
isEncrypted = true;
|
||||
}
|
||||
|
||||
// And then some general functions
|
||||
void Gen3Pokemon::decryptSubstructures()
|
||||
{
|
||||
if (isEncrypted)
|
||||
{
|
||||
u32 key = (getTrainerID() | getSecretID() << 16) ^ getPersonalityValue();
|
||||
for (int i = 0; i < 48; i++)
|
||||
{
|
||||
dataArrayPtr[0x20 + i] ^= ((key >> (8 * (i % 4))) & 0xFF);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void Gen3Pokemon::encryptSubstructures()
|
||||
{
|
||||
if (!isEncrypted)
|
||||
{
|
||||
u32 key = (getTrainerID() | getSecretID() << 16) ^ getPersonalityValue();
|
||||
for (int i = 0; i < 48; i++)
|
||||
{
|
||||
dataArrayPtr[0x20 + i] ^= ((key >> (8 * (i % 4))) & 0xFF);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void Gen3Pokemon::updateChecksum()
|
||||
{
|
||||
bool encryptionState = isEncrypted;
|
||||
decryptSubstructures();
|
||||
int checksum = 0x0000;
|
||||
for (int i = 0; i < 48; i = i + 2)
|
||||
{
|
||||
checksum = checksum + ((dataArrayPtr[0x20 + i + 1] << 8) | dataArrayPtr[0x20 + i]);
|
||||
}
|
||||
setChecksum(checksum);
|
||||
if (encryptionState)
|
||||
{
|
||||
encryptSubstructures();
|
||||
}
|
||||
}
|
||||
|
||||
void Gen3Pokemon::updateSubstructureShift()
|
||||
{
|
||||
int structureVal = getPersonalityValue() % 24;
|
||||
if (structureVal == currSubstructureShift)
|
||||
{
|
||||
return;
|
||||
}
|
||||
currSubstructureShift = structureVal;
|
||||
|
||||
resetSubstructureShift();
|
||||
|
||||
#define MAX_LEN 4
|
||||
int index = 0;
|
||||
while (index < MAX_LEN)
|
||||
{
|
||||
int len = MAX_LEN - index;
|
||||
int factorial = 1;
|
||||
for (int i = 1; i < len; i++)
|
||||
{
|
||||
factorial *= i;
|
||||
}
|
||||
int swapLoc = (structureVal / factorial) + index;
|
||||
for (int i = index; i < swapLoc; i++)
|
||||
{
|
||||
swapSubstructures(index, (i + 1));
|
||||
}
|
||||
index += 1;
|
||||
structureVal %= factorial;
|
||||
}
|
||||
}
|
||||
|
||||
void Gen3Pokemon::resetSubstructureShift()
|
||||
{
|
||||
for (int currDest = 0; currDest < 4; currDest++)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if ((substructOffsets[i] / 12) == currDest)
|
||||
{
|
||||
swapSubstructures(currDest, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gen3Pokemon::swapSubstructures(int indexOne, int indexTwo)
|
||||
{
|
||||
if (indexOne == indexTwo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
byte tempByte;
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
tempByte = dataArrayPtr[0x20 + (indexOne * 12) + i];
|
||||
dataArrayPtr[0x20 + (indexOne * 12) + i] = dataArrayPtr[0x20 + (indexTwo * 12) + i];
|
||||
dataArrayPtr[0x20 + (indexTwo * 12) + i] = tempByte;
|
||||
}
|
||||
|
||||
int valOne = 0;
|
||||
int valTwo = 0;
|
||||
int tempInt;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (substructOffsets[i] == indexOne * 12)
|
||||
{
|
||||
valOne = i;
|
||||
}
|
||||
if (substructOffsets[i] == indexTwo * 12)
|
||||
{
|
||||
valTwo = i;
|
||||
}
|
||||
}
|
||||
tempInt = substructOffsets[valOne];
|
||||
substructOffsets[valOne] = substructOffsets[valTwo];
|
||||
substructOffsets[valTwo] = tempInt;
|
||||
}
|
||||
|
||||
void Gen3Pokemon::updateSecurityData()
|
||||
{
|
||||
updateSubstructureShift();
|
||||
updateChecksum();
|
||||
encryptSubstructures();
|
||||
}
|
||||
|
||||
byte Gen3Pokemon::getUnownLetter()
|
||||
{
|
||||
if (getSpeciesIndexNumber() == 201)
|
||||
{
|
||||
|
||||
u32 personalityValue = getPersonalityValue();
|
||||
return (
|
||||
((personalityValue & 0x03000000) >> 18) +
|
||||
((personalityValue & 0x00030000) >> 12) +
|
||||
((personalityValue & 0x00000300) >> 6) +
|
||||
((personalityValue & 0x00000003) >> 0)) %
|
||||
28;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
};
|
||||
|
||||
Nature Gen3Pokemon::getNature()
|
||||
{
|
||||
return (Nature)(getPersonalityValue() % 25);
|
||||
};
|
||||
|
||||
Gender Gen3Pokemon::getGender()
|
||||
{
|
||||
byte index = getSpeciesIndexNumber();
|
||||
u32 threshold = pokeTable->get_gender_threshold(index, true);
|
||||
|
||||
switch (threshold)
|
||||
{
|
||||
case 0:
|
||||
return MALE;
|
||||
case 254:
|
||||
return FEMALE;
|
||||
case 255:
|
||||
return GENDERLESS;
|
||||
default:
|
||||
if ((getPersonalityValue() & 0xFF) >= threshold)
|
||||
{
|
||||
return MALE;
|
||||
}
|
||||
return FEMALE;
|
||||
}
|
||||
}
|
||||
|
||||
int Gen3Pokemon::getAbilityFromPersonalityValue()
|
||||
{
|
||||
if (internalAbility == 255)
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
return getPersonalityValue() & 0b1;
|
||||
}
|
||||
|
||||
int Gen3Pokemon::getSize()
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
|
||||
bool Gen3Pokemon::getIsShiny()
|
||||
{
|
||||
return (getTrainerID() ^
|
||||
getSecretID() ^
|
||||
(getPersonalityValue() >> 0 & 0xFFFF) ^
|
||||
(getPersonalityValue() >> 16 & 0xFFFF)) < 8;
|
||||
}
|
||||
|
||||
bool Gen3Pokemon::setNicknameArray(byte nameArr[], int nameArrSize)
|
||||
{
|
||||
for (int i = 0; i < nameArrSize; i++)
|
||||
{
|
||||
setNicknameLetter(i, nameArr[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Gen3Pokemon::setOTArray(byte otArr[], int otArrSize)
|
||||
{
|
||||
for (int i = 0; i < otArrSize; i++)
|
||||
{
|
||||
setOTLetter(i, otArr[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma region
|
||||
// Since there is only the Pokemon parent class, we can directly define these directly
|
||||
const DataVarInfo
|
||||
// All of the data info variables
|
||||
Gen3Pokemon::personalityValue =
|
||||
{0x00, 32, 0},
|
||||
Gen3Pokemon::trainerID =
|
||||
{0x04, 16, 0},
|
||||
Gen3Pokemon::secretID =
|
||||
{0x06, 16, 0},
|
||||
Gen3Pokemon::nicknameLetterOne =
|
||||
{0x08, 8, 0}, // This is silly. Change this.
|
||||
Gen3Pokemon::nicknameLetterTwo =
|
||||
{0x09, 8, 0},
|
||||
Gen3Pokemon::nicknameLetterThree =
|
||||
{0x0A, 8, 0},
|
||||
Gen3Pokemon::nicknameLetterFour =
|
||||
{0x0B, 8, 0},
|
||||
Gen3Pokemon::nicknameLetterFive =
|
||||
{0x0C, 8, 0},
|
||||
Gen3Pokemon::nicknameLetterSix =
|
||||
{0x0D, 8, 0},
|
||||
Gen3Pokemon::nicknameLetterSeven =
|
||||
{0x0E, 8, 0},
|
||||
Gen3Pokemon::nicknameLetterEight =
|
||||
{0x0F, 8, 0},
|
||||
Gen3Pokemon::nicknameLetterNine =
|
||||
{0x10, 8, 0},
|
||||
Gen3Pokemon::nicknameLetterTen =
|
||||
{0x11, 8, 0},
|
||||
Gen3Pokemon::language =
|
||||
{0x12, 8, 0},
|
||||
Gen3Pokemon::isBadEgg =
|
||||
{0x13, 1, 0},
|
||||
Gen3Pokemon::hasSpecies =
|
||||
{0x13, 1, 1},
|
||||
Gen3Pokemon::useEggName =
|
||||
{0x13, 1, 2},
|
||||
Gen3Pokemon::blockBoxRS =
|
||||
{0x13, 1, 3},
|
||||
// Gen3Pokemon::unusedFlags =
|
||||
// {0x13, 4, 4},
|
||||
Gen3Pokemon::originalTrainerNameLetterOne =
|
||||
{0x14, 8, 0}, // This is also silly. Change this.
|
||||
Gen3Pokemon::originalTrainerNameLetterTwo =
|
||||
{0x15, 8, 0},
|
||||
Gen3Pokemon::originalTrainerNameLetterThree =
|
||||
{0x16, 8, 0},
|
||||
Gen3Pokemon::originalTrainerNameLetterFour =
|
||||
{0x17, 8, 0},
|
||||
Gen3Pokemon::originalTrainerNameLetterFive =
|
||||
{0x18, 8, 0},
|
||||
Gen3Pokemon::originalTrainerNameLetterSix =
|
||||
{0x19, 8, 0},
|
||||
Gen3Pokemon::originalTrainerNameLetterSeven =
|
||||
{0x1A, 8, 0},
|
||||
Gen3Pokemon::markings =
|
||||
{0x1B, 4, 0},
|
||||
Gen3Pokemon::checksum =
|
||||
{0x1C, 16, 0};
|
||||
// Gen3Pokemon::unknown =
|
||||
// {0x1E, 16, 0};
|
||||
|
||||
const DataVarInfo
|
||||
*Gen3Pokemon::nickname[10] = {
|
||||
&Gen3Pokemon::nicknameLetterOne,
|
||||
&Gen3Pokemon::nicknameLetterTwo,
|
||||
&Gen3Pokemon::nicknameLetterThree,
|
||||
&Gen3Pokemon::nicknameLetterFour,
|
||||
&Gen3Pokemon::nicknameLetterFive,
|
||||
&Gen3Pokemon::nicknameLetterSix,
|
||||
&Gen3Pokemon::nicknameLetterSeven,
|
||||
&Gen3Pokemon::nicknameLetterEight,
|
||||
&Gen3Pokemon::nicknameLetterNine,
|
||||
&Gen3Pokemon::nicknameLetterTen,
|
||||
},
|
||||
*Gen3Pokemon::originalTrainerName[7] = {
|
||||
&Gen3Pokemon::originalTrainerNameLetterOne,
|
||||
&Gen3Pokemon::originalTrainerNameLetterTwo,
|
||||
&Gen3Pokemon::originalTrainerNameLetterThree,
|
||||
&Gen3Pokemon::originalTrainerNameLetterFour,
|
||||
&Gen3Pokemon::originalTrainerNameLetterFive,
|
||||
&Gen3Pokemon::originalTrainerNameLetterSix,
|
||||
&Gen3Pokemon::originalTrainerNameLetterSeven,
|
||||
};
|
||||
|
||||
// data section G
|
||||
const DataVarInfo
|
||||
Gen3Pokemon::speciesIndexNumber =
|
||||
{0x20 + 0x00, 16, 0},
|
||||
Gen3Pokemon::heldItem =
|
||||
{0x20 + 0x02, 16, 0},
|
||||
Gen3Pokemon::expPoints =
|
||||
{0x20 + 0x04, 32, 0},
|
||||
Gen3Pokemon::ppUpNumMoveOne =
|
||||
{0x20 + 0x08, 2, 0},
|
||||
Gen3Pokemon::ppUpNumMoveTwo =
|
||||
{0x20 + 0x08, 2, 2},
|
||||
Gen3Pokemon::ppUpNumMoveThree =
|
||||
{0x20 + 0x08, 2, 4},
|
||||
Gen3Pokemon::ppUpNumMoveFour =
|
||||
{0x20 + 0x08, 2, 6},
|
||||
Gen3Pokemon::friendship =
|
||||
{0x20 + 0x09, 8, 0};
|
||||
// Gen3Pokemon::unused =
|
||||
// {0x20 + 0x0A, 16, 0};
|
||||
const DataVarInfo
|
||||
*Gen3Pokemon::ppUpNums[4] = {
|
||||
&Gen3Pokemon::ppUpNumMoveOne,
|
||||
&Gen3Pokemon::ppUpNumMoveTwo,
|
||||
&Gen3Pokemon::ppUpNumMoveThree,
|
||||
&Gen3Pokemon::ppUpNumMoveFour,
|
||||
};
|
||||
|
||||
// data section A
|
||||
const DataVarInfo
|
||||
Gen3Pokemon::moveOne =
|
||||
{0x20 + 0x00, 16, 0},
|
||||
Gen3Pokemon::moveTwo =
|
||||
{0x20 + 0x02, 16, 0},
|
||||
Gen3Pokemon::moveThree =
|
||||
{0x20 + 0x04, 16, 0},
|
||||
Gen3Pokemon::moveFour =
|
||||
{0x20 + 0x06, 16, 0},
|
||||
Gen3Pokemon::moveOnePP =
|
||||
{0x20 + 0x08, 8, 0},
|
||||
Gen3Pokemon::moveTwoPP =
|
||||
{0x20 + 0x09, 8, 0},
|
||||
Gen3Pokemon::moveThreePP =
|
||||
{0x20 + 0x0A, 8, 0},
|
||||
Gen3Pokemon::moveFourPP =
|
||||
{0x20 + 0x0B, 8, 0};
|
||||
const DataVarInfo
|
||||
*Gen3Pokemon::moves[4] = {
|
||||
&Gen3Pokemon::moveOne,
|
||||
&Gen3Pokemon::moveTwo,
|
||||
&Gen3Pokemon::moveThree,
|
||||
&Gen3Pokemon::moveFour,
|
||||
},
|
||||
*Gen3Pokemon::ppUpTotals[4] = {
|
||||
&Gen3Pokemon::moveOnePP,
|
||||
&Gen3Pokemon::moveTwoPP,
|
||||
&Gen3Pokemon::moveThreePP,
|
||||
&Gen3Pokemon::moveFourPP,
|
||||
};
|
||||
|
||||
// data section E
|
||||
const DataVarInfo
|
||||
Gen3Pokemon::hpEVs =
|
||||
{0x20 + 0x00, 8, 0},
|
||||
Gen3Pokemon::attackEVs =
|
||||
{0x20 + 0x01, 8, 0},
|
||||
Gen3Pokemon::defenseEVs =
|
||||
{0x20 + 0x02, 8, 0},
|
||||
Gen3Pokemon::speedEVs =
|
||||
{0x20 + 0x03, 8, 0},
|
||||
Gen3Pokemon::specialAttackEVs =
|
||||
{0x20 + 0x04, 8, 0},
|
||||
Gen3Pokemon::specialDefenseEVs =
|
||||
{0x20 + 0x05, 8, 0},
|
||||
Gen3Pokemon::coolnessCondition =
|
||||
{0x20 + 0x06, 8, 0},
|
||||
Gen3Pokemon::beautyCondition =
|
||||
{0x20 + 0x07, 8, 0},
|
||||
Gen3Pokemon::cutenessCondition =
|
||||
{0x20 + 0x08, 8, 0},
|
||||
Gen3Pokemon::smartnessCondition =
|
||||
{0x20 + 0x09, 8, 0},
|
||||
Gen3Pokemon::toughnessCondition =
|
||||
{0x20 + 0x0A, 8, 0},
|
||||
Gen3Pokemon::sheen =
|
||||
{0x20 + 0x0B, 8, 0};
|
||||
|
||||
const DataVarInfo
|
||||
*Gen3Pokemon::EVs[6] = {
|
||||
&Gen3Pokemon::hpEVs,
|
||||
&Gen3Pokemon::attackEVs,
|
||||
&Gen3Pokemon::defenseEVs,
|
||||
&Gen3Pokemon::speedEVs,
|
||||
&Gen3Pokemon::specialAttackEVs,
|
||||
&Gen3Pokemon::specialDefenseEVs,
|
||||
},
|
||||
*Gen3Pokemon::contestConditions[5] = {
|
||||
&Gen3Pokemon::coolnessCondition,
|
||||
&Gen3Pokemon::beautyCondition,
|
||||
&Gen3Pokemon::cutenessCondition,
|
||||
&Gen3Pokemon::smartnessCondition,
|
||||
&Gen3Pokemon::toughnessCondition,
|
||||
};
|
||||
|
||||
const DataVarInfo
|
||||
|
||||
// data section M
|
||||
Gen3Pokemon::pokerusStrain =
|
||||
{0x20 + 0x00, 4, 0},
|
||||
Gen3Pokemon::pokerusDaysRemaining =
|
||||
{0x20 + 0x00, 4, 4},
|
||||
Gen3Pokemon::metLocation =
|
||||
{0x20 + 0x01, 8, 0},
|
||||
Gen3Pokemon::levelMet =
|
||||
{0x20 + 0x02, 7, 0},
|
||||
Gen3Pokemon::gameOfOrigin =
|
||||
{0x20 + 0x02, 4, 7},
|
||||
Gen3Pokemon::pokeballCaughtIn =
|
||||
{0x20 + 0x02, 4, 11},
|
||||
Gen3Pokemon::originalTrainerGender =
|
||||
{0x20 + 0x02, 1, 15},
|
||||
Gen3Pokemon::hpIVs =
|
||||
{0x20 + 0x04, 5, 0},
|
||||
Gen3Pokemon::attackIVs =
|
||||
{0x20 + 0x04, 5, 5},
|
||||
Gen3Pokemon::defenseIVs =
|
||||
{0x20 + 0x04, 5, 10},
|
||||
Gen3Pokemon::speedIVs =
|
||||
{0x20 + 0x04, 5, 15},
|
||||
Gen3Pokemon::specialAttackIVs =
|
||||
{0x20 + 0x04, 5, 20},
|
||||
Gen3Pokemon::specialDefenseIVs =
|
||||
{0x20 + 0x04, 5, 25},
|
||||
Gen3Pokemon::isEgg =
|
||||
{0x20 + 0x04, 1, 30},
|
||||
Gen3Pokemon::ability =
|
||||
{0x20 + 0x04, 1, 31},
|
||||
Gen3Pokemon::coolNormalContestRibbon =
|
||||
{0x20 + 0x08, 1, 0}, // This is also very silly. Change it.
|
||||
Gen3Pokemon::coolSuperContestRibbon =
|
||||
{0x20 + 0x08, 1, 0},
|
||||
Gen3Pokemon::coolHyperContestRibbon =
|
||||
{0x20 + 0x08, 1, 1},
|
||||
Gen3Pokemon::coolMasterContestRibbon =
|
||||
{0x20 + 0x08, 1, 2},
|
||||
Gen3Pokemon::beautyNormalContestRibbon =
|
||||
{0x20 + 0x08, 1, 3},
|
||||
Gen3Pokemon::beautySuperContestRibbon =
|
||||
{0x20 + 0x08, 1, 4},
|
||||
Gen3Pokemon::beautyHyperContestRibbon =
|
||||
{0x20 + 0x08, 1, 5},
|
||||
Gen3Pokemon::beautyMasterContestRibbon =
|
||||
{0x20 + 0x08, 1, 6},
|
||||
Gen3Pokemon::cuteNormalContestRibbon =
|
||||
{0x20 + 0x08, 1, 7},
|
||||
Gen3Pokemon::cuteSuperContestRibbon =
|
||||
{0x20 + 0x08, 1, 8},
|
||||
Gen3Pokemon::cuteHyperContestRibbon =
|
||||
{0x20 + 0x08, 1, 9},
|
||||
Gen3Pokemon::cuteMasterContestRibbon =
|
||||
{0x20 + 0x08, 1, 10},
|
||||
Gen3Pokemon::smartNormalContestRibbon =
|
||||
{0x20 + 0x08, 1, 11},
|
||||
Gen3Pokemon::smartSuperContestRibbon =
|
||||
{0x20 + 0x08, 1, 12},
|
||||
Gen3Pokemon::smartHyperContestRibbon =
|
||||
{0x20 + 0x08, 1, 13},
|
||||
Gen3Pokemon::smartMasterContestRibbon =
|
||||
{0x20 + 0x08, 1, 14},
|
||||
Gen3Pokemon::toughNormalContestRibbon =
|
||||
{0x20 + 0x08, 1, 15},
|
||||
Gen3Pokemon::toughSuperContestRibbon =
|
||||
{0x20 + 0x08, 1, 16},
|
||||
Gen3Pokemon::toughHyperContestRibbon =
|
||||
{0x20 + 0x08, 1, 17},
|
||||
Gen3Pokemon::toughMasterContestRibbon =
|
||||
{0x20 + 0x08, 1, 18},
|
||||
Gen3Pokemon::championRibbon =
|
||||
{0x20 + 0x08, 1, 19},
|
||||
Gen3Pokemon::winningRibbon =
|
||||
{0x20 + 0x08, 1, 20},
|
||||
Gen3Pokemon::victoryRibbon =
|
||||
{0x20 + 0x08, 1, 21},
|
||||
Gen3Pokemon::artistRibbon =
|
||||
{0x20 + 0x08, 1, 22},
|
||||
Gen3Pokemon::effortRibbon =
|
||||
{0x20 + 0x08, 1, 23},
|
||||
Gen3Pokemon::battleChampionRibbon =
|
||||
{0x20 + 0x08, 1, 24},
|
||||
Gen3Pokemon::regionalChampionRibbon =
|
||||
{0x20 + 0x08, 1, 25},
|
||||
Gen3Pokemon::nationalChampionRibbon =
|
||||
{0x20 + 0x08, 1, 26},
|
||||
Gen3Pokemon::countryRibbon =
|
||||
{0x20 + 0x08, 1, 27},
|
||||
Gen3Pokemon::nationalRibbon =
|
||||
{0x20 + 0x08, 1, 28},
|
||||
Gen3Pokemon::earthRibbon =
|
||||
{0x20 + 0x08, 1, 29},
|
||||
Gen3Pokemon::unusedRibbons =
|
||||
{0x20 + 0x08, 1, 30},
|
||||
Gen3Pokemon::fatefulEncounterObedience =
|
||||
{0x20 + 0x08, 1, 31};
|
||||
|
||||
const DataVarInfo
|
||||
*Gen3Pokemon::IVs[6] = {
|
||||
&Gen3Pokemon::hpIVs,
|
||||
&Gen3Pokemon::attackIVs,
|
||||
&Gen3Pokemon::defenseIVs,
|
||||
&Gen3Pokemon::speedIVs,
|
||||
&Gen3Pokemon::specialAttackIVs,
|
||||
&Gen3Pokemon::specialDefenseIVs,
|
||||
},
|
||||
*Gen3Pokemon::ribbons[31] = {
|
||||
&Gen3Pokemon::coolNormalContestRibbon,
|
||||
&Gen3Pokemon::coolSuperContestRibbon,
|
||||
&Gen3Pokemon::coolHyperContestRibbon,
|
||||
&Gen3Pokemon::coolMasterContestRibbon,
|
||||
&Gen3Pokemon::beautyNormalContestRibbon,
|
||||
&Gen3Pokemon::beautySuperContestRibbon,
|
||||
&Gen3Pokemon::beautyHyperContestRibbon,
|
||||
&Gen3Pokemon::beautyMasterContestRibbon,
|
||||
&Gen3Pokemon::cuteNormalContestRibbon,
|
||||
&Gen3Pokemon::cuteSuperContestRibbon,
|
||||
&Gen3Pokemon::cuteHyperContestRibbon,
|
||||
&Gen3Pokemon::cuteMasterContestRibbon,
|
||||
&Gen3Pokemon::smartNormalContestRibbon,
|
||||
&Gen3Pokemon::smartSuperContestRibbon,
|
||||
&Gen3Pokemon::smartHyperContestRibbon,
|
||||
&Gen3Pokemon::smartMasterContestRibbon,
|
||||
&Gen3Pokemon::toughNormalContestRibbon,
|
||||
&Gen3Pokemon::toughSuperContestRibbon,
|
||||
&Gen3Pokemon::toughHyperContestRibbon,
|
||||
&Gen3Pokemon::toughMasterContestRibbon,
|
||||
&Gen3Pokemon::championRibbon,
|
||||
&Gen3Pokemon::winningRibbon,
|
||||
&Gen3Pokemon::victoryRibbon,
|
||||
&Gen3Pokemon::artistRibbon,
|
||||
&Gen3Pokemon::effortRibbon,
|
||||
&Gen3Pokemon::battleChampionRibbon,
|
||||
&Gen3Pokemon::regionalChampionRibbon,
|
||||
&Gen3Pokemon::nationalChampionRibbon,
|
||||
&Gen3Pokemon::countryRibbon,
|
||||
&Gen3Pokemon::nationalRibbon,
|
||||
&Gen3Pokemon::earthRibbon,
|
||||
};
|
||||
#pragma endregion
|
||||
165
source/pccs/PokeBox.cpp
Normal file
165
source/pccs/PokeBox.cpp
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
#include "PokeBox.h"
|
||||
#include <string>
|
||||
|
||||
#if ON_GBA
|
||||
#include "global_frame_controller.h"
|
||||
#include "text_engine.h"
|
||||
#endif
|
||||
|
||||
PokeBox::PokeBox()
|
||||
{
|
||||
nullMon = new Pokemon();
|
||||
}
|
||||
|
||||
PokeBox::PokeBox(PokemonTables *nTable)
|
||||
{
|
||||
table = nTable;
|
||||
}
|
||||
|
||||
void PokeBox::setTable(PokemonTables *nTable)
|
||||
{
|
||||
table = nTable;
|
||||
}
|
||||
|
||||
bool PokeBox::addPokemon(Pokemon *currPkmn)
|
||||
{
|
||||
if (currIndex < 30)
|
||||
{
|
||||
boxStorage[currIndex] = currPkmn;
|
||||
currIndex++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Pokemon *PokeBox::getPokemon(int index)
|
||||
{
|
||||
if (index < currIndex)
|
||||
{
|
||||
return boxStorage[index];
|
||||
}
|
||||
return nullMon;
|
||||
}
|
||||
|
||||
GBPokemon *PokeBox::getGBPokemon(int index)
|
||||
{
|
||||
Pokemon *currPkmn = getPokemon(index);
|
||||
GBPokemon *currGBPkmn = (GBPokemon *)currPkmn;
|
||||
return currGBPkmn;
|
||||
}
|
||||
|
||||
Gen3Pokemon *PokeBox::getGen3Pokemon(int index)
|
||||
{
|
||||
Pokemon *currPkmn = getPokemon(index);
|
||||
Gen3Pokemon *currGen3Pkmn = (Gen3Pokemon *)currPkmn;
|
||||
currGen3Pkmn->updateSecurityData();
|
||||
return currGen3Pkmn;
|
||||
}
|
||||
|
||||
bool PokeBox::removePokemon(int index)
|
||||
{
|
||||
if (index < currIndex)
|
||||
{
|
||||
for (int i = index; i < currIndex; i++)
|
||||
{
|
||||
boxStorage[i] = boxStorage[i + 1];
|
||||
}
|
||||
currIndex -= 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is used to load our data in from an array
|
||||
void PokeBox::loadData(int generation, Language nLang, byte nDataArray[])
|
||||
{
|
||||
if (nLang != ENGLISH)
|
||||
{
|
||||
return; // Other languages are not supported yet
|
||||
}
|
||||
for (int pkmnIndex = 0; pkmnIndex < nDataArray[0]; pkmnIndex++)
|
||||
{
|
||||
GBPokemon *newPkmn = nullptr;
|
||||
if (generation == 1)
|
||||
{
|
||||
newPkmn = new Gen1Pokemon(table);
|
||||
}
|
||||
else if (generation == 2)
|
||||
{
|
||||
newPkmn = new Gen2Pokemon(table);
|
||||
}
|
||||
|
||||
int externalIDOffset = 1;
|
||||
int dataOffset = externalIDOffset + (20 * 1) + 1;
|
||||
int trainerNameOffset = dataOffset + (20 * newPkmn->dataArraySize);
|
||||
int nicknameOffset = trainerNameOffset + (20 * newPkmn->OTArraySize);
|
||||
|
||||
externalIDOffset += pkmnIndex * 1;
|
||||
dataOffset += pkmnIndex * newPkmn->dataArraySize;
|
||||
trainerNameOffset += pkmnIndex * newPkmn->OTArraySize;
|
||||
nicknameOffset += pkmnIndex * newPkmn->nicknameArraySize;
|
||||
|
||||
newPkmn->loadData(
|
||||
nLang,
|
||||
&nDataArray[dataOffset], // Pokemon Data
|
||||
&nDataArray[nicknameOffset], // Nickname
|
||||
&nDataArray[trainerNameOffset], // Trainer Name
|
||||
nDataArray[externalIDOffset] // External ID Number
|
||||
);
|
||||
|
||||
addPokemon(newPkmn);
|
||||
}
|
||||
}
|
||||
|
||||
void PokeBox::convertPkmn(int index)
|
||||
{
|
||||
Gen3Pokemon *convertedPkmn = new Gen3Pokemon(table);
|
||||
Pokemon *basePkmn = getPokemon(index);
|
||||
GBPokemon *oldPkmn = (GBPokemon *)(basePkmn);
|
||||
|
||||
oldPkmn->convertToGen3(convertedPkmn, stabilize_mythical);
|
||||
delete boxStorage[index];
|
||||
boxStorage[index] = convertedPkmn;
|
||||
}
|
||||
|
||||
void PokeBox::convertAll()
|
||||
{
|
||||
for (int i = 0; i < currIndex; i++)
|
||||
{
|
||||
convertPkmn(i);
|
||||
}
|
||||
}
|
||||
|
||||
int PokeBox::getNumInBox()
|
||||
{
|
||||
return currIndex;
|
||||
}
|
||||
|
||||
int PokeBox::getNumValid()
|
||||
{
|
||||
int numValid = 0;
|
||||
for (int i = 0; i < currIndex; i++)
|
||||
{
|
||||
if (getPokemon(i)->isValid)
|
||||
{
|
||||
numValid++;
|
||||
}
|
||||
}
|
||||
return numValid;
|
||||
}
|
||||
|
||||
#if ON_GBA
|
||||
#else
|
||||
std::string PokeBox::printDataArray()
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (int i = 0; i < currIndex; i++)
|
||||
{
|
||||
if (boxStorage[i]->generation == 3)
|
||||
{
|
||||
ss << ((Gen3Pokemon *)boxStorage[i])->printDataArray(true) << "\n";
|
||||
}
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
#endif
|
||||
99
source/pccs/Pokemon.cpp
Normal file
99
source/pccs/Pokemon.cpp
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#include "Pokemon.h"
|
||||
|
||||
Pokemon::Pokemon()
|
||||
{
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
u32 Pokemon::getSpeciesIndexNumber()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 Pokemon::getVar(DataVarInfo dataVar)
|
||||
{
|
||||
return getVar(dataVar, 0);
|
||||
}
|
||||
|
||||
u32 Pokemon::getVar(DataVarInfo dataVar, int extraByteOffset)
|
||||
{
|
||||
u32 out = 0;
|
||||
if (dataVar.dataLength < 8)
|
||||
{ // is less than a byte, do bitwise stuff on a single byte
|
||||
// ... but we can't assume that the data is within a single byte (thanks gen 3)
|
||||
if (dataVar.dataLength + dataVar.bitOffset > 8)
|
||||
{
|
||||
int numBytes = (dataVar.dataLength + dataVar.bitOffset) / 8 + 1;
|
||||
if (numBytes > 4)
|
||||
{
|
||||
numBytes = 4; // This avoids importing math for rounding. Silly though.
|
||||
}
|
||||
int arrayIndex;
|
||||
for (int i = 0; i < numBytes; i++)
|
||||
{
|
||||
arrayIndex = (isBigEndian ? i : numBytes - (i + 1));
|
||||
out = (out << 8) | dataArrayPtr[dataVar.byteOffset + extraByteOffset + arrayIndex];
|
||||
}
|
||||
out = (out >> dataVar.bitOffset) & sizeToMask(dataVar.dataLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
out = (dataArrayPtr[dataVar.byteOffset + extraByteOffset] >> dataVar.bitOffset) & sizeToMask(dataVar.dataLength);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // is larger than a byte, will have to access multiple parts of the array
|
||||
int numBytes = dataVar.dataLength / 8;
|
||||
int arrayIndex;
|
||||
for (int i = 0; i < numBytes; i++)
|
||||
{
|
||||
arrayIndex = (isBigEndian ? i : numBytes - (i + 1));
|
||||
out = (out << 8) | dataArrayPtr[dataVar.byteOffset + extraByteOffset + arrayIndex];
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool Pokemon::setVar(DataVarInfo dataVar, u32 newValue)
|
||||
{
|
||||
return setVar(dataVar, 0, newValue);
|
||||
}
|
||||
|
||||
bool Pokemon::setVar(DataVarInfo dataVar, int extraByteOffset, u32 newValue)
|
||||
{
|
||||
if (dataVar.dataLength < 8)
|
||||
{ // is less than a byte, do bitwise stuff on a single byte
|
||||
// ... but we can't assume that the data is within a single byte (thanks gen 3)
|
||||
if (dataVar.dataLength + dataVar.bitOffset > 8)
|
||||
{
|
||||
int numBytes = (dataVar.dataLength + dataVar.bitOffset) / 8 + 1;
|
||||
if (numBytes > 4)
|
||||
{
|
||||
numBytes = 4; // This avoids importing math for rounding. Silly though.
|
||||
}
|
||||
int arrayIndex;
|
||||
for (int i = 0; i < numBytes; i++)
|
||||
{
|
||||
arrayIndex = (isBigEndian ? i : numBytes - (i + 1));
|
||||
dataArrayPtr[dataVar.byteOffset + arrayIndex + extraByteOffset] &= ~((sizeToMask(dataVar.dataLength) << dataVar.bitOffset) >> (arrayIndex * 8));
|
||||
dataArrayPtr[dataVar.byteOffset + arrayIndex + extraByteOffset] |= ((newValue & sizeToMask(dataVar.dataLength)) << dataVar.bitOffset) >> (arrayIndex * 8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dataArrayPtr[dataVar.byteOffset + extraByteOffset] &= ~(sizeToMask(dataVar.dataLength) << dataVar.bitOffset);
|
||||
dataArrayPtr[dataVar.byteOffset + extraByteOffset] |= (newValue & sizeToMask(dataVar.dataLength)) << dataVar.bitOffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // is larger than a byte, will have to access multiple parts of the array
|
||||
int numBytes = dataVar.dataLength / 8;
|
||||
int arrayIndex;
|
||||
for (int i = 0; i < numBytes; i++)
|
||||
{
|
||||
arrayIndex = (isBigEndian ? i : numBytes - (i + 1));
|
||||
dataArrayPtr[dataVar.byteOffset + arrayIndex + extraByteOffset] = (newValue >> (8 * ((numBytes - 1) - i)));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
1142
source/pokemon.cpp
1142
source/pokemon.cpp
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,5 @@
|
|||
#include "gameboy_colour.h"
|
||||
#include "pokemon_party.h"
|
||||
#include "pokemon.h"
|
||||
#include "flash_mem.h"
|
||||
#include "debug_mode.h"
|
||||
#include "mystery_gift_injector.h"
|
||||
|
|
@ -13,8 +12,9 @@
|
|||
#include "gb_gen1_payloads_RB_lz10_bin.h"
|
||||
#include "gb_gen1_payloads_Y_lz10_bin.h"
|
||||
#include "gb_gen2_payloads_lz10_bin.h"
|
||||
#include "save_data_manager.h"
|
||||
|
||||
static const byte gen1_rb_debug_box_data[0x462] = {
|
||||
static byte gen1_rb_debug_box_data[0x462] = {
|
||||
// Num of Pokemon
|
||||
0x14,
|
||||
// Pokemon 1-20
|
||||
|
|
@ -83,7 +83,7 @@ static const byte gen1_rb_debug_box_data[0x462] = {
|
|||
0x91, 0x80, 0x93, 0x93, 0x80, 0x93, 0x80, 0x50, 0x50, 0x50, 0x50,
|
||||
0x8F, 0x88, 0x83, 0x86, 0x84, 0x98, 0x50, 0x50, 0x50, 0x50, 0x50};
|
||||
|
||||
static const byte gen2_debug_box_data[0x44E] = {
|
||||
static byte gen2_debug_box_data[0x44E] = {
|
||||
// Num of Pokemon
|
||||
0x14,
|
||||
// Pokemon 1-20
|
||||
|
|
@ -152,7 +152,9 @@ static const byte gen2_debug_box_data[0x44E] = {
|
|||
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50,
|
||||
0x92, 0x87, 0x94, 0x82, 0x8A, 0x8B, 0x84, 0x50, 0x50, 0x50, 0x50};
|
||||
|
||||
Pokemon_Party::Pokemon_Party() {};
|
||||
Pokemon_Party::Pokemon_Party() {
|
||||
box.setTable(&table);
|
||||
};
|
||||
|
||||
void Pokemon_Party::start_link()
|
||||
{
|
||||
|
|
@ -160,30 +162,27 @@ void Pokemon_Party::start_link()
|
|||
{
|
||||
if (curr_gb_rom.generation == 1 && curr_gb_rom.version)
|
||||
{
|
||||
for (int i = 0; i < 0x462; i++)
|
||||
{
|
||||
box_data_array[i] = gen1_rb_debug_box_data[i];
|
||||
}
|
||||
box.loadData(1, ENGLISH, gen1_rb_debug_box_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 0x44E; i++)
|
||||
{
|
||||
box_data_array[i] = gen2_debug_box_data[i];
|
||||
}
|
||||
box.loadData(2, ENGLISH, gen2_debug_box_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 debug_charset[256];
|
||||
|
||||
load_localized_charset(debug_charset, 3, ENG_ID);
|
||||
load_localized_charset(debug_charset, 3, ENGLISH);
|
||||
init_payload();
|
||||
|
||||
setup(debug_charset);
|
||||
memset(box_data_array, 0, curr_gb_rom.box_data_size);
|
||||
|
||||
last_error = loop(&box_data_array[0], current_payload, &curr_gb_rom, simple_pkmn_array, debug_charset, false);
|
||||
// This used to clear out the box data, probably isn't needed anymore
|
||||
// memset(box_data_array, 0, curr_gb_rom.box_data_size);
|
||||
|
||||
last_error = loop(&box_data_array[0], current_payload, &curr_gb_rom, &box, debug_charset, false);
|
||||
box.loadData(curr_gb_rom.generation, (Language)curr_gb_rom.language, box_data_array);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -193,9 +192,9 @@ void Pokemon_Party::continue_link(bool cancel_connection)
|
|||
{
|
||||
u16 debug_charset[256];
|
||||
|
||||
load_localized_charset(debug_charset, 3, ENG_ID);
|
||||
load_localized_charset(debug_charset, 3, ENGLISH);
|
||||
|
||||
last_error = loop(&box_data_array[0], current_payload, &curr_gb_rom, simple_pkmn_array, debug_charset, cancel_connection);
|
||||
last_error = loop(&box_data_array[0], current_payload, &curr_gb_rom, &box, debug_charset, cancel_connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -204,29 +203,30 @@ int Pokemon_Party::get_last_error()
|
|||
return last_error;
|
||||
}
|
||||
|
||||
Pokemon Pokemon_Party::get_converted_pkmn(PokemonTables& data_tables, int index)
|
||||
{
|
||||
Pokemon converted_mon;
|
||||
converted_mon.load_data(index, box_data_array, game, lang);
|
||||
converted_mon.convert_to_gen_three(data_tables, Legal, false, stabilize_mythic);
|
||||
has_new_pkmn = has_new_pkmn || converted_mon.get_is_new();
|
||||
simple_pkmn_array[index] = converted_mon.get_simple_pkmn();
|
||||
return converted_mon;
|
||||
}
|
||||
|
||||
bool Pokemon_Party::get_has_new_pkmn() // If Pokemon is not in the dex
|
||||
{
|
||||
return has_new_pkmn;
|
||||
bool out = false;
|
||||
for (int i = 0; i < box.getNumInBox(); i++)
|
||||
{
|
||||
|
||||
out |= !is_caught(box.getPokemon(i)->getSpeciesIndexNumber());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool Pokemon_Party::get_contains_mythical()
|
||||
{
|
||||
return contains_mythical;
|
||||
bool out = false;
|
||||
for (int i = 0; i < box.getNumInBox(); i++)
|
||||
{
|
||||
out |= (box.getPokemon(i)->getSpeciesIndexNumber() == MEW || box.getPokemon(i)->getSpeciesIndexNumber() == CELEBI);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void Pokemon_Party::set_mythic_stabilization(bool stabilize)
|
||||
{
|
||||
stabilize_mythic = stabilize;
|
||||
box.stabilize_mythical = stabilize;
|
||||
}
|
||||
|
||||
void Pokemon_Party::set_game(int nGame)
|
||||
|
|
@ -269,7 +269,7 @@ bool Pokemon_Party::load_gb_rom()
|
|||
u32 rom_table_size;
|
||||
const u8 *cur;
|
||||
|
||||
switch(lang)
|
||||
switch (lang)
|
||||
{
|
||||
case ENG_ID:
|
||||
compressed_rom_table = gb_rom_values_eng_lz10_bin;
|
||||
|
|
@ -287,7 +287,7 @@ bool Pokemon_Party::load_gb_rom()
|
|||
LZ77UnCompWram(compressed_rom_table, gb_rom_table_buffer);
|
||||
|
||||
cur = gb_rom_table_buffer;
|
||||
while(cur < gb_rom_table_buffer + rom_table_size)
|
||||
while (cur < gb_rom_table_buffer + rom_table_size)
|
||||
{
|
||||
const GB_ROM *rom_values = reinterpret_cast<const GB_ROM *>(cur);
|
||||
if (lang == rom_values->language &&
|
||||
|
|
@ -302,44 +302,30 @@ bool Pokemon_Party::load_gb_rom()
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
Simplified_Pokemon Pokemon_Party::get_simple_pkmn(int index)
|
||||
{
|
||||
return simple_pkmn_array[index];
|
||||
}
|
||||
|
||||
bool Pokemon_Party::fill_simple_pkmn_array(PokemonTables &data_tables)
|
||||
{
|
||||
contains_mythical = false;
|
||||
for (int index = 0; index < get_num_pkmn(); index++)
|
||||
{
|
||||
Pokemon converted_mon;
|
||||
converted_mon.load_data(index, box_data_array, game, lang);
|
||||
converted_mon.convert_to_gen_three(data_tables, Legal, true, stabilize_mythic);
|
||||
has_new_pkmn = has_new_pkmn || converted_mon.get_is_new();
|
||||
contains_mythical = contains_mythical ||
|
||||
converted_mon.get_dex_number() == 151 || converted_mon.get_dex_number() == 251;
|
||||
simple_pkmn_array[index] = converted_mon.get_simple_pkmn();
|
||||
contains_valid |= converted_mon.get_validity();
|
||||
contains_invalid |= !converted_mon.get_validity();
|
||||
contains_missingno |= converted_mon.is_missingno;
|
||||
}
|
||||
return contains_valid || DONT_HIDE_INVALID_PKMN;
|
||||
}
|
||||
|
||||
int Pokemon_Party::get_num_pkmn()
|
||||
{
|
||||
return box_data_array[0];
|
||||
return box.getNumInBox();
|
||||
}
|
||||
|
||||
bool Pokemon_Party::get_contains_invalid()
|
||||
{
|
||||
return contains_invalid;
|
||||
}
|
||||
bool out = false;
|
||||
for (int i = 0; i < box.getNumInBox(); i++)
|
||||
{
|
||||
|
||||
out |= !box.getGBPokemon(i)->isValid;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
bool Pokemon_Party::get_contains_missingno()
|
||||
{
|
||||
return contains_missingno;
|
||||
bool out = false;
|
||||
for (int i = 0; i < box.getNumInBox(); i++)
|
||||
{
|
||||
|
||||
out |= box.getPokemon(i)->getSpeciesIndexNumber() == MISSINGNO;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void Pokemon_Party::init_payload()
|
||||
|
|
@ -348,11 +334,11 @@ void Pokemon_Party::init_payload()
|
|||
const u8 *payload_src;
|
||||
u32 payload_file_size;
|
||||
|
||||
//WARNING: Ensure sure decompression_buffer is large enough!
|
||||
// WARNING: Ensure sure decompression_buffer is large enough!
|
||||
|
||||
if(curr_gb_rom.generation == 1)
|
||||
if (curr_gb_rom.generation == 1)
|
||||
{
|
||||
if(curr_gb_rom.version == YELLOW_ID)
|
||||
if (curr_gb_rom.version == YELLOW_ID)
|
||||
{
|
||||
payload_src = gb_gen1_payloads_Y_lz10_bin;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#include "random.h"
|
||||
#include <tonc.h>
|
||||
#include "random.h"
|
||||
|
||||
unsigned int u32_rand;
|
||||
|
||||
void rand_set_seed(unsigned int init_seed)
|
||||
{
|
||||
u32_rand = init_seed;
|
||||
u32_rand = init_seed + 1;
|
||||
}
|
||||
|
||||
unsigned int rand_get_seed()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "gba_rom_values_jpn_lz10_bin.h"
|
||||
#include "gba_rom_values_spa_lz10_bin.h"
|
||||
|
||||
extern rom_data curr_rom;
|
||||
extern rom_data curr_GBA_rom;
|
||||
|
||||
rom_data::rom_data() {}
|
||||
bool rom_data::load_rom()
|
||||
|
|
@ -124,9 +124,9 @@ void rom_data::fill_values(const ROM_DATA *rom_values)
|
|||
all_collected_flag = rom_values->unused_flag_start; // The flag for if everything has been collected
|
||||
pkmn_collected_flag_start = rom_values->unused_flag_start + 1; // The beginning of the flags for each of the Pokemon
|
||||
|
||||
map_bank = (ENABLE_OLD_EVENT ? rom_values->old_map_bank : rom_values->map_bank);
|
||||
map_id = (ENABLE_OLD_EVENT ? rom_values->old_map_id : rom_values->map_id);
|
||||
npc_id = (ENABLE_OLD_EVENT ? rom_values->old_npc_id : rom_values->npc_id);
|
||||
map_bank = rom_values->map_bank;
|
||||
map_id = rom_values->map_id;
|
||||
npc_id = rom_values->npc_id;
|
||||
npc_palette = rom_values->npc_palette;
|
||||
|
||||
def_map_bank = rom_values->def_map_bank;
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ Box_Menu box_viewer;
|
|||
// DIA_ERROR_DISCONNECT
|
||||
//
|
||||
// Pause the transfer and show the user their box data
|
||||
// CMD_LOAD_SIMP
|
||||
// CMD_IS_A_VALID_PKMN
|
||||
// DIA_NO_VALID_PKMN
|
||||
// COND_SOME_INVALID_PKMN
|
||||
// DIA_SOME_INVALID_PKMN
|
||||
|
|
@ -364,9 +364,9 @@ const script_obj_params transfer_script_params[SCRIPT_SIZE] = {
|
|||
.conditional_index = CMD_MYTHIC_MENU,
|
||||
.next_if_true = COND_CHECK_MISSINGNO
|
||||
},
|
||||
// CMD_LOAD_SIMP
|
||||
// CMD_IS_A_VALID_PKMN
|
||||
{
|
||||
.conditional_index = CMD_LOAD_SIMP,
|
||||
.conditional_index = CMD_IS_A_VALID_PKMN,
|
||||
.next_if_true = COND_SOME_INVALID_PKMN,
|
||||
.next_if_false = DIA_NO_VALID_PKMN
|
||||
},
|
||||
|
|
@ -389,7 +389,7 @@ const script_obj_params transfer_script_params[SCRIPT_SIZE] = {
|
|||
// COND_ERROR_DISCONNECT
|
||||
{
|
||||
.conditional_index = COND_ERROR_DISCONNECT,
|
||||
.next_if_true = CMD_LOAD_SIMP,
|
||||
.next_if_true = CMD_IS_A_VALID_PKMN,
|
||||
.next_if_false = DIA_ERROR_DISCONNECT
|
||||
},
|
||||
// COND_ERROR_COM_ENDED
|
||||
|
|
@ -640,7 +640,7 @@ const script_obj_params event_script_params[SCRIPT_SIZE] = {
|
|||
{}, // CMD_CONTINUE_LINK
|
||||
{}, // CMD_BOX_MENU
|
||||
{}, // CMD_MYTHIC_MENU
|
||||
{}, // CMD_LOAD_SIMP
|
||||
{}, // CMD_IS_A_VALID_PKMN
|
||||
{}, // CMD_CANCEL_LINK
|
||||
{}, // CMD_END_MISSINGNO
|
||||
{}, // COND_ERROR_TIMEOUT_ONE
|
||||
|
|
@ -689,7 +689,7 @@ void populate_lang_menu()
|
|||
langs.add_option(GENERAL_option_german, GER_ID);
|
||||
langs.add_option(GENERAL_option_italian, ITA_ID);
|
||||
langs.add_option(GENERAL_option_korean, KOR_ID);
|
||||
// Removing the cancel option for the time being, since canceling the
|
||||
// TODO: Removing the cancel option for the time being, since canceling the
|
||||
// link trade when there is no link connection crashes the game
|
||||
// langs.add_option(GENERAL_option_cancel, UINT8_MAX);
|
||||
}
|
||||
|
|
@ -727,12 +727,6 @@ void populate_game_menu(int lang)
|
|||
}
|
||||
}
|
||||
|
||||
static bool __attribute__((noinline)) load_simple_party_data()
|
||||
{
|
||||
PokemonTables data_tables;
|
||||
return party_data.fill_simple_pkmn_array(data_tables);
|
||||
}
|
||||
|
||||
bool run_conditional(int index)
|
||||
{
|
||||
// Here is most of the logic that drives what lines show up where. It's probably not the best way to code it, but it works
|
||||
|
|
@ -758,10 +752,10 @@ bool run_conditional(int index)
|
|||
return party_data.get_last_error() != COND_ERROR_COLOSSEUM;
|
||||
|
||||
case COND_BEAT_E4:
|
||||
return read_flag(curr_rom.e4_flag) || IGNORE_MG_E4_FLAGS;
|
||||
return read_flag(curr_GBA_rom.e4_flag) || IGNORE_MG_E4_FLAGS;
|
||||
|
||||
case COND_MG_ENABLED:
|
||||
return read_flag(curr_rom.mg_flag) || IGNORE_MG_E4_FLAGS;
|
||||
return read_flag(curr_GBA_rom.mg_flag) || IGNORE_MG_E4_FLAGS;
|
||||
|
||||
case COND_TUTORIAL_COMPLETE:
|
||||
return get_tutorial_flag() && !FORCE_TUTORIAL;
|
||||
|
|
@ -770,16 +764,16 @@ bool run_conditional(int index)
|
|||
return party_data.get_has_new_pkmn();
|
||||
|
||||
case COND_IS_HOENN_RS:
|
||||
return curr_rom.is_ruby_sapphire();
|
||||
return curr_GBA_rom.is_ruby_sapphire();
|
||||
|
||||
case COND_IS_FRLGE:
|
||||
return !curr_rom.is_ruby_sapphire();
|
||||
return !curr_GBA_rom.is_ruby_sapphire();
|
||||
|
||||
case COND_MG_OTHER_EVENT:
|
||||
return compare_map_and_npc_data(curr_rom.def_map_bank, curr_rom.def_map_id, curr_rom.def_npc_id) && !IGNORE_MG_E4_FLAGS;
|
||||
return compare_map_and_npc_data(curr_GBA_rom.def_map_bank, curr_GBA_rom.def_map_id, curr_GBA_rom.def_npc_id) && !IGNORE_MG_E4_FLAGS;
|
||||
|
||||
case COND_PKMN_TO_COLLECT:
|
||||
return compare_map_and_npc_data(curr_rom.map_bank, curr_rom.map_id, curr_rom.npc_id) && !read_flag(curr_rom.all_collected_flag) && !IGNORE_UNRECEIVED_PKMN;
|
||||
return compare_map_and_npc_data(curr_GBA_rom.map_bank, curr_GBA_rom.map_id, curr_GBA_rom.npc_id) && !read_flag(curr_GBA_rom.all_collected_flag) && !IGNORE_UNRECEIVED_PKMN;
|
||||
|
||||
case COND_GB_ROM_EXISTS:
|
||||
return party_data.load_gb_rom();
|
||||
|
|
@ -804,7 +798,7 @@ bool run_conditional(int index)
|
|||
return party_data.get_contains_invalid();
|
||||
|
||||
case COND_IS_HOENN_E:
|
||||
return curr_rom.gamecode == EMERALD_ID;
|
||||
return curr_GBA_rom.gamecode == EMERALD_ID;
|
||||
|
||||
case COND_CHECK_MISSINGNO:
|
||||
if (party_data.get_contains_missingno())
|
||||
|
|
@ -824,7 +818,7 @@ bool run_conditional(int index)
|
|||
return true;
|
||||
|
||||
case CMD_IMPORT_POKEMON:
|
||||
inject_mystery(party_data);
|
||||
inject_mystery(&party_data.box);
|
||||
return true;
|
||||
|
||||
case CMD_BACK_TO_MENU:
|
||||
|
|
@ -901,7 +895,7 @@ bool run_conditional(int index)
|
|||
|
||||
case CMD_BOX_MENU:
|
||||
hide_text_box();
|
||||
ret = (box_viewer.box_main(party_data) == CONFIRM_BUTTON);
|
||||
ret = (box_viewer.box_main(&party_data.box) == CONFIRM_BUTTON);
|
||||
show_text_box();
|
||||
return ret;
|
||||
|
||||
|
|
@ -909,8 +903,8 @@ bool run_conditional(int index)
|
|||
party_data.set_mythic_stabilization(yes_no_menu.button_main());
|
||||
return true;
|
||||
|
||||
case CMD_LOAD_SIMP:
|
||||
return load_simple_party_data();
|
||||
case CMD_IS_A_VALID_PKMN:
|
||||
return party_data.box.getNumValid() > 0;
|
||||
|
||||
case CMD_CANCEL_LINK:
|
||||
party_data.continue_link(true);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "debug_mode.h"
|
||||
#include "global_frame_controller.h"
|
||||
|
||||
extern rom_data curr_rom;
|
||||
extern rom_data curr_GBA_rom;
|
||||
|
||||
script_var::script_var(u32 nValue, ptgb::vector<script_var *> &var_list_ref, int *nCurr_loc_ptr)
|
||||
{
|
||||
|
|
@ -77,7 +77,7 @@ void asm_var::fill_refrences(u8 mg_array[])
|
|||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
mg_array[location_list[i] + j] += (start_location_in_script + curr_rom.loc_gSaveBlock1 + curr_rom.offset_ramscript + 7) >> (j * 8);
|
||||
mg_array[location_list[i] + j] += (start_location_in_script + curr_GBA_rom.loc_gSaveBlock1 + curr_GBA_rom.offset_ramscript + 7) >> (j * 8);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -89,7 +89,7 @@ void asm_var::fill_refrences(u8 mg_array[])
|
|||
|
||||
u32 asm_var::get_loc_in_sec30()
|
||||
{
|
||||
return start_location_in_script + curr_rom.loc_gSaveDataBuffer + 3; // plus 3 to offset the -2 in set_start, and one for reading as thumb
|
||||
return start_location_in_script + curr_GBA_rom.loc_gSaveDataBuffer + 3; // plus 3 to offset the -2 in set_start, and one for reading as thumb
|
||||
}
|
||||
|
||||
// XSE VAR ----------------
|
||||
|
|
@ -132,7 +132,7 @@ void xse_var::fill_refrences(u8 mg_array[])
|
|||
|
||||
u32 xse_var::get_loc_in_sec30()
|
||||
{
|
||||
return start_location_in_script + curr_rom.loc_gSaveDataBuffer;
|
||||
return start_location_in_script + curr_GBA_rom.loc_gSaveDataBuffer;
|
||||
}
|
||||
|
||||
// TEXTBOX VAR
|
||||
|
|
@ -145,7 +145,7 @@ void textbox_var::set_text(const byte nText[])
|
|||
|
||||
void textbox_var::set_start()
|
||||
{
|
||||
start_location_in_script = *curr_loc_ptr - (ENABLE_OLD_EVENT * 4);
|
||||
start_location_in_script = *curr_loc_ptr;
|
||||
}
|
||||
|
||||
void textbox_var::set_virtual_start()
|
||||
|
|
@ -166,7 +166,7 @@ void textbox_var::insert_text(const u16 *charset, u8 mg_array[], bool should_set
|
|||
|
||||
for (int parser = 0; parser < text_length; parser++)
|
||||
{
|
||||
if (curr_rom.is_hoenn() && (text[parser] == 0xFC) && (get_char_from_charset(charset, (char16_t)(text[parser + 1])) == 0x01)) // Removes colored text
|
||||
if (curr_GBA_rom.is_hoenn() && (text[parser] == 0xFC) && (get_char_from_charset(charset, (char16_t)(text[parser + 1])) == 0x01)) // Removes colored text
|
||||
{
|
||||
parser += 2;
|
||||
}
|
||||
|
|
@ -216,7 +216,7 @@ void sprite_var::insert_sprite_data(u8 mg_array[], const unsigned int sprite_arr
|
|||
{
|
||||
|
||||
set_start();
|
||||
u32 pointer = curr_rom.loc_gSaveDataBuffer + *curr_loc_ptr + 8;
|
||||
u32 pointer = curr_GBA_rom.loc_gSaveDataBuffer + *curr_loc_ptr + 8;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
mg_array[*curr_loc_ptr] = pointer >> (8 * i);
|
||||
|
|
@ -255,7 +255,7 @@ void music_var::insert_music_data(u8 mg_array[], u8 blockCount, u8 priority, u8
|
|||
{
|
||||
for (unsigned int i = 0; i < trackArrays.size(); i++)
|
||||
{
|
||||
trackPointers.push_back(*curr_loc_ptr + curr_rom.loc_gSaveDataBuffer);
|
||||
trackPointers.push_back(*curr_loc_ptr + curr_GBA_rom.loc_gSaveDataBuffer);
|
||||
for (unsigned int j = 0; j < trackArrays[i].size(); j++)
|
||||
{
|
||||
mg_array[(*curr_loc_ptr)++] = trackArrays[i][j];
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "sprite_data.h"
|
||||
#include "translated_text.h"
|
||||
#include "text_data_table.h"
|
||||
#include "global_frame_controller.h"
|
||||
|
||||
#define TEXT_HEIGHT 10
|
||||
#define TEXT_WIDTH 8
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "sprite_data.h"
|
||||
#include "debug_mode.h"
|
||||
#include "gba_rom_values/base_gba_rom_struct.h"
|
||||
#include "global_frame_controller.h"
|
||||
|
||||
#define SPRITE_CHAR_BLOCK 4
|
||||
|
||||
|
|
@ -464,7 +465,7 @@ void load_eternal_sprites()
|
|||
obj_set_pos(up_arrow, 14 * 8, 3 * 8);
|
||||
}
|
||||
|
||||
void load_temp_box_sprites(Pokemon_Party *party_data)
|
||||
void load_temp_box_sprites(PokeBox *box)
|
||||
{
|
||||
u32 curr_tile_id = global_tile_id_end;
|
||||
|
||||
|
|
@ -472,21 +473,21 @@ void load_temp_box_sprites(Pokemon_Party *party_data)
|
|||
{
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
if (party_data->get_simple_pkmn(i).is_valid || DONT_HIDE_INVALID_PKMN)
|
||||
GBPokemon *curr_pkmn = box->getGBPokemon(i);
|
||||
if (curr_pkmn->isValid || DONT_HIDE_INVALID_PKMN)
|
||||
{
|
||||
Simplified_Pokemon curr_pkmn = party_data->get_simple_pkmn(i);
|
||||
int dex_num = curr_pkmn.dex_number;
|
||||
int dex_num = curr_pkmn->getSpeciesIndexNumber();
|
||||
if (dex_num == 201)
|
||||
{
|
||||
dex_num = POKEMON_ARRAY_SIZE + curr_pkmn.unown_letter;
|
||||
dex_num = POKEMON_ARRAY_SIZE + curr_pkmn->getUnownLetter();
|
||||
}
|
||||
else if (curr_pkmn.is_missingno)
|
||||
else if (curr_pkmn->getSpeciesIndexNumber() == MISSINGNO)
|
||||
{
|
||||
dex_num = 0;
|
||||
}
|
||||
|
||||
u32 sprite_location = (*(u32 *)(curr_rom.loc_gMonIconTable + (dex_num * 4)));
|
||||
int pal_num = *(byte *)(curr_rom.loc_gMonIconPaletteIndices + dex_num);
|
||||
u32 sprite_location = (*(u32 *)(curr_GBA_rom.loc_gMonIconTable + (dex_num * 4)));
|
||||
int pal_num = *(byte *)(curr_GBA_rom.loc_gMonIconPaletteIndices + dex_num);
|
||||
load_sprite(party_sprites[i], (const unsigned int *)sprite_location, 512, curr_tile_id, MENU_PAL_RED + pal_num, ATTR0_SQUARE, ATTR1_SIZE_32x32, 1);
|
||||
obj_set_pos(party_sprites[i], ((BOXMENU_SPRITE_WIDTH + BOXMENU_HSPACE) * (i % BOXMENU_HNUM)) + (BOXMENU_LEFT + BOXMENU_SPRITE_HOFFSET), ((BOXMENU_SPRITE_HEIGHT + BOXMENU_VSPACE) * (i / BOXMENU_HNUM)) + (BOXMENU_TOP + BOXMENU_SPRITE_VOFFSET));
|
||||
obj_unhide(party_sprites[i], 0);
|
||||
|
|
@ -499,10 +500,10 @@ void load_temp_box_sprites(Pokemon_Party *party_data)
|
|||
// Load the menu sprite palettes. Should this be done somewhere else?
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
tonccpy((pal_obj_mem + ((MENU_PAL_RED + i) * 16)), (const unsigned short *)(curr_rom.loc_gMonIconPalettes + (i * 32)), 32);
|
||||
tonccpy((pal_obj_mem + ((MENU_PAL_RED + i) * 16)), (const unsigned short *)(curr_GBA_rom.loc_gMonIconPalettes + (i * 32)), 32);
|
||||
}
|
||||
|
||||
load_sprite_compressed(grabbed_front_sprite, (const unsigned int *)*(u32 *)(curr_rom.loc_gMonFrontPicTable + (0 * 8)), curr_tile_id, PULLED_SPRITE_PAL, ATTR0_SQUARE, ATTR1_SIZE_64x64, 1);
|
||||
load_sprite_compressed(grabbed_front_sprite, (const unsigned int *)*(u32 *)(curr_GBA_rom.loc_gMonFrontPicTable + (0 * 8)), curr_tile_id, PULLED_SPRITE_PAL, ATTR0_SQUARE, ATTR1_SIZE_64x64, 1);
|
||||
obj_set_pos(grabbed_front_sprite, 8, 16);
|
||||
}
|
||||
|
||||
|
|
@ -721,7 +722,7 @@ void load_select_sprites(u8 game_id, u8 lang)
|
|||
|
||||
const unsigned int *gba_cart_tiles = 0;
|
||||
const unsigned short *gba_cart_palette = 0;
|
||||
switch (curr_rom.gamecode)
|
||||
switch (curr_GBA_rom.gamecode)
|
||||
{
|
||||
|
||||
case RUBY_ID:
|
||||
|
|
@ -852,7 +853,7 @@ void update_y_offset()
|
|||
obj_set_pos(flag, (8 * 11) + 4, (8 * 4) + 19 + y_offset);
|
||||
}
|
||||
|
||||
void update_front_box_sprite(Simplified_Pokemon *curr_pkmn)
|
||||
void update_front_box_sprite(GBPokemon *curr_pkmn)
|
||||
{
|
||||
if (IGNORE_GAME_PAK || IGNORE_GAME_PAK_SPRITES)
|
||||
{
|
||||
|
|
@ -860,23 +861,26 @@ void update_front_box_sprite(Simplified_Pokemon *curr_pkmn)
|
|||
}
|
||||
|
||||
u32 curr_tile_id = global_tile_id_end + (30 * 16);
|
||||
int dex_num = 0;
|
||||
|
||||
if (curr_pkmn->unown_letter > 1)
|
||||
int dex_num = curr_pkmn->getSpeciesIndexNumber();
|
||||
if (dex_num == 201)
|
||||
{
|
||||
dex_num = 412 + curr_pkmn->unown_letter;
|
||||
if (curr_pkmn->getUnownLetter() > 1)
|
||||
{
|
||||
dex_num = 412 + curr_pkmn->getUnownLetter();
|
||||
}
|
||||
}
|
||||
else if (curr_pkmn->is_missingno)
|
||||
else if (curr_pkmn->getSpeciesIndexNumber() == MISSINGNO)
|
||||
{
|
||||
dex_num = 0;
|
||||
}
|
||||
else
|
||||
else if (curr_pkmn->getSpeciesIndexNumber() == TREECKO)
|
||||
{
|
||||
dex_num = curr_pkmn->dex_number;
|
||||
dex_num = 277;
|
||||
}
|
||||
|
||||
u32 sprite_location = *(u32 *)(curr_rom.loc_gMonFrontPicTable + (dex_num * 8));
|
||||
u32 palette_location = *(u32 *)((curr_pkmn->is_shiny ? curr_rom.loc_gMonShinyPaletteTable : curr_rom.loc_gMonPaletteTable) + (curr_pkmn->dex_number * 8));
|
||||
u32 sprite_location = *(u32 *)(curr_GBA_rom.loc_gMonFrontPicTable + (dex_num * 8));
|
||||
u32 palette_location = *(u32 *)((curr_pkmn->getIsShiny() ? curr_GBA_rom.loc_gMonShinyPaletteTable : curr_GBA_rom.loc_gMonPaletteTable) + (curr_pkmn->getSpeciesIndexNumber() * 8));
|
||||
unsigned short buffer[16];
|
||||
|
||||
LZ77UnCompWram((const unsigned short *)palette_location, buffer); // This is a little silly, but it's being weird with bytes vs shorts when we copy it directly
|
||||
|
|
@ -894,7 +898,7 @@ void update_front_box_sprite(Simplified_Pokemon *curr_pkmn)
|
|||
LZ77UnCompVram((const unsigned int *)sprite_location, &tile_mem[SPRITE_CHAR_BLOCK][curr_tile_id]);
|
||||
}
|
||||
|
||||
void update_menu_sprite(Pokemon_Party *party_data, int index, int frame)
|
||||
void update_menu_sprite(PokeBox *box, int index, int frame)
|
||||
{
|
||||
if (IGNORE_GAME_PAK || IGNORE_GAME_PAK_SPRITES)
|
||||
{
|
||||
|
|
@ -903,20 +907,25 @@ void update_menu_sprite(Pokemon_Party *party_data, int index, int frame)
|
|||
|
||||
u32 curr_tile_id = global_tile_id_end + (index * 16);
|
||||
|
||||
Simplified_Pokemon curr_pkmn = party_data->get_simple_pkmn(index);
|
||||
int dex_num = curr_pkmn.dex_number;
|
||||
GBPokemon *curr_pkmn = box->getGBPokemon(index);
|
||||
|
||||
int dex_num = curr_pkmn->getSpeciesIndexNumber();
|
||||
if (dex_num == 201)
|
||||
{
|
||||
if (curr_pkmn.unown_letter != 0)
|
||||
if (curr_pkmn->getUnownLetter() > 1)
|
||||
{
|
||||
dex_num = 0x19C + curr_pkmn.unown_letter;
|
||||
dex_num = 412 + curr_pkmn->getUnownLetter();
|
||||
}
|
||||
}
|
||||
else if (curr_pkmn.is_missingno)
|
||||
else if (curr_pkmn->getSpeciesIndexNumber() == MISSINGNO)
|
||||
{
|
||||
dex_num = 0;
|
||||
}
|
||||
else if (curr_pkmn->getSpeciesIndexNumber() == TREECKO)
|
||||
{
|
||||
dex_num = 277;
|
||||
}
|
||||
|
||||
u32 sprite_location = (*(u32 *)(curr_rom.loc_gMonIconTable + (dex_num * 4))) + (frame == 0 ? 0 : 512);
|
||||
u32 sprite_location = (*(u32 *)(curr_GBA_rom.loc_gMonIconTable + (dex_num * 4))) + (frame == 0 ? 0 : 512);
|
||||
tonccpy(&tile_mem[SPRITE_CHAR_BLOCK][curr_tile_id], (const unsigned int *)sprite_location, 512);
|
||||
}
|
||||
|
|
@ -174,6 +174,7 @@ int ptgb_write(const byte *text, bool instant)
|
|||
// Re-implementing TTE's "tte_write" to use the gen 3 character encoding chart
|
||||
int ptgb_write(const byte *text, bool instant, int length)
|
||||
{
|
||||
instant = instant || INSTANT_TEXT_SPEED;
|
||||
if (text == NULL)
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ if (update == True):
|
|||
new_file_path = 'text_helper/new_text.xlsx'
|
||||
old_file_path = 'text_helper/text.xlsx'
|
||||
json_file_path = 'text_helper/output.json'
|
||||
no_file = False
|
||||
|
||||
try:
|
||||
response = requests.get(url, timeout=5)
|
||||
|
|
@ -31,22 +32,26 @@ if (update == True):
|
|||
except requests.exceptions.ReadTimeout as errrt:
|
||||
if os.path.exists(old_file_path):
|
||||
print("Connection timed out. Continuing with locally downloaded file.")
|
||||
no_file = True
|
||||
else:
|
||||
print("xlsx file is missing and connection timed out. Exiting...")
|
||||
except requests.exceptions.ConnectionError as conerr:
|
||||
if os.path.exists(old_file_path):
|
||||
print("Connection error. Continuing with locally downloaded file.")
|
||||
no_file = True
|
||||
else:
|
||||
print("xlsx file is missing and connection timed out. Exiting...")
|
||||
|
||||
|
||||
if os.path.exists(old_file_path):
|
||||
new_file = pd.read_excel(new_file_path, sheet_name="Translations")
|
||||
old_file = pd.read_excel(old_file_path, sheet_name="Translations")
|
||||
if new_file.equals(old_file):
|
||||
if (not no_file):
|
||||
new_file = pd.read_excel(new_file_path, sheet_name="Translations")
|
||||
old_file = pd.read_excel(old_file_path, sheet_name="Translations")
|
||||
if no_file or new_file.equals(old_file):
|
||||
if os.path.exists(json_file_path):
|
||||
print("Downloaded file is identical. Skipping parse\n")
|
||||
os.remove(new_file_path)
|
||||
if (not no_file):
|
||||
os.remove(new_file_path)
|
||||
exit()
|
||||
print("json file missing - forcing rebuild.")
|
||||
os.remove(old_file_path)
|
||||
|
|
@ -516,7 +521,7 @@ for lang in Languages:
|
|||
|
||||
# now generate the cpp file.
|
||||
with open(os.curdir + '/source/translated_text.cpp', 'w') as cppFile:
|
||||
cppFile.write("#include \"translated_text.h\"\n#include \"debug_mode.h\"\n#include \"pokemon_data.h\"\n")
|
||||
cppFile.write("#include \"translated_text.h\"\n#include \"debug_mode.h\"\n#include \"extern_pokemon_data.h\"\n")
|
||||
# generate includes for each language
|
||||
for lang in Languages:
|
||||
for cat in mainDict[lang.name]:
|
||||
|
|
|
|||
|
|
@ -5,5 +5,6 @@
|
|||
#include <cstddef>
|
||||
|
||||
void writeTable(const char *input_path, const char *output_path, const char *filename, const char *buffer, size_t buffer_size);
|
||||
void generate_pokemon_data(const char *output_path);
|
||||
|
||||
#endif
|
||||
|
|
@ -16,7 +16,7 @@ typedef int32_t i32;
|
|||
#else
|
||||
extern "C"
|
||||
{
|
||||
#include <tonc_types.h>
|
||||
#include <tonc_types.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -79,6 +79,7 @@ public:
|
|||
u32 _RemovePokemon; // location of the _RemovePokemon function in the ROM
|
||||
u32 SaveSAVtoSRAM1; // location of the SaveSAVtoSRAM1 function in the ROM
|
||||
u32 SaveSAVtoSRAM2; // location of the SaveSAVtoSRAM2 function in the ROM
|
||||
u32 LoadCurrentBoxData; // location of the LoadCurrentBoxData function in the ROM
|
||||
u32 OpenSRAM; // location of the OpenSRAM function in the ROM
|
||||
u32 SaveBox; // location of the SaveBox function in the ROM
|
||||
u32 Bankswitch; // location of the BankswitchCommon function in the ROM
|
||||
|
|
@ -86,22 +87,22 @@ public:
|
|||
u32 CloseSRAM; // location of the OpenSRAM function in the ROM
|
||||
u32 garbageDataLocation; // location of random data starting with 0xFD in the ROM
|
||||
|
||||
u32 wRemoveMonFromBox; // location of wRemoveMonFromBox in RAM
|
||||
u32 wBoxCount; // location of wBoxCount in RAM
|
||||
u32 wWhichPokemon; // location of wWhichPokemon in RAM
|
||||
u32 wBoxDataStart; // location of wBoxDataStart in RAM
|
||||
u32 wBoxDataEnd; // location of wBoxDataEnd in RAM
|
||||
u32 wSerialEnemyDataBlock; // location of wSerialEnemyDataBlock in RAM
|
||||
u32 wEnemyMonSpecies; // location of wEnemyMonSpecies in RAM
|
||||
|
||||
u32 wRemoveMonFromBox; // location of wRemoveMonFromBox in RAM
|
||||
u32 wBoxCount; // location of wBoxCount in RAM
|
||||
u32 wWhichPokemon; // location of wWhichPokemon in RAM
|
||||
u32 wBoxDataStart; // location of wBoxDataStart in RAM
|
||||
u32 wBoxDataEnd; // location of wBoxDataEnd in RAM
|
||||
u32 wSerialEnemyDataBlock; // location of wSerialEnemyDataBlock in RAM
|
||||
u32 wEnemyMonSpecies; // location of wEnemyMonSpecies in RAM
|
||||
|
||||
u32 wSerialEnemyMonsPatchList; // location of wSerialEnemyMonsPatchList in RAM
|
||||
u32 wSerialOtherGameboyRandomNumberListBlock; // location of wSerialOtherGameboyRandomNumberListBlock in RAM
|
||||
u32 hSerialConnectionStatus; // location of hSerialConnectionStatus in RAM
|
||||
|
||||
u16 transferStringLocation; // location in VRAM to start writing the transfer string to
|
||||
u16 textBorderUppLeft; // location in VRAM to put the upper left corner of the border
|
||||
u8 textBorderWidth; // the width of the text box border
|
||||
u8 textBorderHeight; // the height of the text box border
|
||||
u16 transferStringLocation; // location in VRAM to start writing the transfer string to
|
||||
u16 textBorderUppLeft; // location in VRAM to put the upper left corner of the border
|
||||
u8 textBorderWidth; // the width of the text box border
|
||||
u8 textBorderHeight; // the height of the text box border
|
||||
u16 padding_2;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "common.h"
|
||||
#include "extern_pokemon_data.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
|
|
|||
Binary file not shown.
80
tools/data-generator/src/debug_scripts/bgb_link.py
Normal file
80
tools/data-generator/src/debug_scripts/bgb_link.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import socket
|
||||
import sys
|
||||
|
||||
|
||||
def format_data(string) -> int:
|
||||
result = 0
|
||||
for c in string:
|
||||
result = (result << 8) | c
|
||||
return result
|
||||
|
||||
|
||||
def send_data(sock, b1: int, b2: int, b3: int, b4: int, time) -> None:
|
||||
data = bytearray()
|
||||
|
||||
data.append(b1)
|
||||
data.append(b2)
|
||||
data.append(b3)
|
||||
data.append(b4)
|
||||
|
||||
data.append((time >> 24) & 0xff)
|
||||
data.append((time >> 16) & 0xff)
|
||||
data.append((time >> 8) & 0xff)
|
||||
data.append(time & 0xff)
|
||||
|
||||
sock.send(data)
|
||||
|
||||
|
||||
def connect(port, callback) -> None:
|
||||
sock = socket.socket()
|
||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY,
|
||||
1) # requires nodelay
|
||||
sock.connect(("localhost", port))
|
||||
|
||||
send_data(sock, 1, 1, 4, 0, 0) # send version
|
||||
|
||||
try:
|
||||
while 1:
|
||||
# data packet will be 8 byte long
|
||||
raw = format_data(sock.recv(8))
|
||||
if raw == 0:
|
||||
continue
|
||||
|
||||
b1 = cmd = raw >> 56
|
||||
b2 = (raw >> 48) & 0xff
|
||||
b3 = (raw >> 40) & 0xff
|
||||
b4 = (raw >> 32) & 0xff
|
||||
time = raw & 0xffffffff
|
||||
|
||||
# print("%.2x %.2x %.2x %.2x %.8x" % (b1, b2, b3, b4, time))
|
||||
|
||||
if cmd == 1:
|
||||
# handshake (version)
|
||||
pass
|
||||
# send_data(sock, 0x01, 0x01, 0x04, 0x00, time)
|
||||
# send_data(sock, b1, b2, b3, b4, time)
|
||||
|
||||
elif cmd == 101:
|
||||
# sync gamepad
|
||||
pass
|
||||
|
||||
elif cmd == 104:
|
||||
# byte received from master
|
||||
result = callback(b2)
|
||||
if not result == None:
|
||||
# send data
|
||||
send_data(sock, 105, result, 0x80, 0, 0)
|
||||
else:
|
||||
# send ack
|
||||
send_data(sock, 106, 1, 00, 0, 0)
|
||||
|
||||
elif cmd == 106:
|
||||
send_data(sock, b1, b2, b3, b4, time)
|
||||
|
||||
elif cmd == 108:
|
||||
send_data(sock, 108, 1, 0, 0, 0)
|
||||
except Exception as e:
|
||||
sock.close()
|
||||
raise e
|
||||
|
||||
print("Connection closed.")
|
||||
99
tools/data-generator/src/debug_scripts/cable_club_y.py
Normal file
99
tools/data-generator/src/debug_scripts/cable_club_y.py
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import bgb_link
|
||||
import numpy as np
|
||||
from io import BufferedReader
|
||||
from typing import List
|
||||
|
||||
hs: int
|
||||
ack: int
|
||||
menu: int
|
||||
trade: int
|
||||
colosseum: int
|
||||
cancel: int
|
||||
preamble: int
|
||||
trade_data: int
|
||||
done: int
|
||||
|
||||
hs, ack, menu, trade, colosseum, cancel, preamble, trade_data, done = list(
|
||||
range(9))
|
||||
state: int = hs
|
||||
counter = 0
|
||||
|
||||
file_path = "to_compress/gb_gen1_payloads_Y.bin"
|
||||
try:
|
||||
data = np.fromfile(file_path, dtype=np.uint8)
|
||||
except FileNotFoundError:
|
||||
print(f"Error: The file '{file_path}' was not found.")
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
|
||||
|
||||
def cable_club(byte):
|
||||
global state, hs, ack, menu, trade, colosseum, cancel, trade_data
|
||||
|
||||
if state == hs:
|
||||
if byte == 0x01:
|
||||
state = ack
|
||||
print("Connection established")
|
||||
return 0x02
|
||||
|
||||
elif state == ack:
|
||||
if byte == 0x00:
|
||||
state = menu
|
||||
print("Menu")
|
||||
return 0x00
|
||||
|
||||
elif state == menu:
|
||||
# 0xd1 battle
|
||||
# 0xd5 battle selected
|
||||
if byte == 0xd0:
|
||||
print("Battle")
|
||||
state = trade
|
||||
return 0xd5
|
||||
else:
|
||||
return byte
|
||||
|
||||
elif state == trade:
|
||||
if byte == 0xfd:
|
||||
state = preamble
|
||||
return byte
|
||||
|
||||
elif state == preamble:
|
||||
if byte != 0xfd:
|
||||
print("Sending data...")
|
||||
state = trade_data
|
||||
return exchange_parties(byte)
|
||||
return byte
|
||||
|
||||
elif state == trade_data:
|
||||
# 0xfd = Preamble byte for array
|
||||
# 0xfe = No data
|
||||
return exchange_parties(byte)
|
||||
|
||||
elif state == done:
|
||||
# Refill the code section
|
||||
return exchange_parties(byte)
|
||||
return byte
|
||||
|
||||
|
||||
def exchange_parties(byte):
|
||||
global counter, data, state, done
|
||||
if counter < len(data):
|
||||
ret = data[counter]
|
||||
counter += 1
|
||||
print(hex(ret))
|
||||
return ret
|
||||
else:
|
||||
while(True):
|
||||
1==1
|
||||
state = done
|
||||
print("Restarting!")
|
||||
counter = 436
|
||||
ret = data[counter]
|
||||
counter += 1
|
||||
print(hex(ret))
|
||||
return ret
|
||||
|
||||
|
||||
bgb_link.connect(8765, cable_club)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "pokemon_data.h"
|
||||
#include "extern_pokemon_data.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
|
@ -4705,16 +4705,16 @@ const u8 TYPES[POKEMON_ARRAY_SIZE][2]{
|
|||
|
||||
void generate_pokemon_data(const char *output_path)
|
||||
{
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "gen_1_charsets.bin", (const char*)gen_1_charsets, sizeof(gen_1_charsets));
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "gen_2_charsets.bin", (const char*)gen_2_charsets, sizeof(gen_2_charsets));
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "gen_3_charsets.bin", (const char*)gen_3_charsets, sizeof(gen_3_charsets));
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "EXP_GROUPS.bin", (const char*)EXP_GROUPS, sizeof(EXP_GROUPS));
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "GENDER_RATIO.bin", (const char*)GENDER_RATIO, sizeof(GENDER_RATIO));
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "NUM_ABILITIES.bin", (const char*)(NUM_ABILITIES), sizeof(NUM_ABILITIES));
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "FIRST_MOVES.bin", (const char*)FIRST_MOVES, sizeof(FIRST_MOVES));
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "JPN_NAMES.bin", (const char*)JPN_NAMES, sizeof(JPN_NAMES));
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "POWER_POINTS.bin", (const char*)POWER_POINTS, sizeof(POWER_POINTS));
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "MENU_SPRITE_PALS.bin", (const char*)MENU_SPRITE_PALS, sizeof(MENU_SPRITE_PALS));
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "EVENT_PKMN.bin", (const char*)EVENT_PKMN, sizeof(EVENT_PKMN));
|
||||
writeTable("tools/data-generator/src/pokemon_data.cpp", output_path, "TYPES.bin", (const char*)TYPES, sizeof(TYPES));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "gen_1_charsets.bin", (const char*)gen_1_charsets, sizeof(gen_1_charsets));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "gen_2_charsets.bin", (const char*)gen_2_charsets, sizeof(gen_2_charsets));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "gen_3_charsets.bin", (const char*)gen_3_charsets, sizeof(gen_3_charsets));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "EXP_GROUPS.bin", (const char*)EXP_GROUPS, sizeof(EXP_GROUPS));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "GENDER_RATIO.bin", (const char*)GENDER_RATIO, sizeof(GENDER_RATIO));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "NUM_ABILITIES.bin", (const char*)(NUM_ABILITIES), sizeof(NUM_ABILITIES));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "FIRST_MOVES.bin", (const char*)FIRST_MOVES, sizeof(FIRST_MOVES));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "JPN_NAMES.bin", (const char*)JPN_NAMES, sizeof(JPN_NAMES));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "POWER_POINTS.bin", (const char*)POWER_POINTS, sizeof(POWER_POINTS));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "MENU_SPRITE_PALS.bin", (const char*)MENU_SPRITE_PALS, sizeof(MENU_SPRITE_PALS));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "EVENT_PKMN.bin", (const char*)EVENT_PKMN, sizeof(EVENT_PKMN));
|
||||
writeTable("tools/data-generator/src/extern_pokemon_data.cpp", output_path, "TYPES.bin", (const char*)TYPES, sizeof(TYPES));
|
||||
}
|
||||
|
|
@ -1,282 +1,281 @@
|
|||
#include "gb_rom_values/gb_rom_values.h"
|
||||
|
||||
const struct GB_ROM gb_rom_values_eng[] = {
|
||||
{ // ENG_RED
|
||||
.language = ENG_ID,
|
||||
.version = RED_ID,
|
||||
.generation = 1,
|
||||
.method = METHOD_NEWLINE,
|
||||
.payload_size = 637,
|
||||
.box_data_size = 0x462,
|
||||
{// ENG_RED
|
||||
.language = ENG_ID,
|
||||
.version = RED_ID,
|
||||
.generation = 1,
|
||||
.method = METHOD_NEWLINE,
|
||||
.payload_size = 637,
|
||||
.box_data_size = 0x462,
|
||||
|
||||
.print_string_start = 0xC456,
|
||||
.stack_overwrite_location = 0xDFDD,
|
||||
.short_pkmn_name = 0xE3,
|
||||
.pointer_pkmn_name = 0xFC,
|
||||
.padding_1 = 0,
|
||||
.print_string_start = 0xC456,
|
||||
.stack_overwrite_location = 0xDFDD,
|
||||
.short_pkmn_name = 0xE3,
|
||||
.pointer_pkmn_name = 0xFC,
|
||||
.padding_1 = 0,
|
||||
|
||||
.clearScreen = 0x190F,
|
||||
.CableClub_TextBoxBorder = 0x5AB3,
|
||||
.placeString = 0x1955,
|
||||
.Serial_ExchangeBytes = 0x216F,
|
||||
._RemovePokemon = 0x7B68,
|
||||
.SaveSAVtoSRAM1 = 0x1C77E2,
|
||||
.SaveSAVtoSRAM2 = 0x1C780F,
|
||||
.OpenSRAM = 0,
|
||||
.SaveBox = 0,
|
||||
.Bankswitch = 0x35D6,
|
||||
.SoftReset = 0x1F49,
|
||||
.CloseSRAM = 0,
|
||||
.garbageDataLocation = 0x0316,
|
||||
.clearScreen = 0x190F,
|
||||
.CableClub_TextBoxBorder = 0x5AB3,
|
||||
.placeString = 0x1955,
|
||||
.Serial_ExchangeBytes = 0x216F,
|
||||
._RemovePokemon = 0x7B68,
|
||||
.SaveSAVtoSRAM1 = 0x1C77E2,
|
||||
.SaveSAVtoSRAM2 = 0x1C780F,
|
||||
.LoadCurrentBoxData = 0,
|
||||
.OpenSRAM = 0,
|
||||
.SaveBox = 0,
|
||||
.Bankswitch = 0x35D6,
|
||||
.SoftReset = 0x1F49,
|
||||
.CloseSRAM = 0,
|
||||
.garbageDataLocation = 0x0316,
|
||||
|
||||
.wRemoveMonFromBox = 0xCF95,
|
||||
.wBoxCount = 0xDA80,
|
||||
.wWhichPokemon = 0xCF92,
|
||||
.wBoxDataStart = 0xDA80,
|
||||
.wBoxDataEnd = 0xDEE2,
|
||||
.wSerialEnemyDataBlock = 0xD893,
|
||||
.wEnemyMonSpecies = 0xCFE5,
|
||||
.wRemoveMonFromBox = 0xCF95,
|
||||
.wBoxCount = 0xDA80,
|
||||
.wWhichPokemon = 0xCF92,
|
||||
.wBoxDataStart = 0xDA80,
|
||||
.wBoxDataEnd = 0xDEE2,
|
||||
.wSerialEnemyDataBlock = 0xD893,
|
||||
.wEnemyMonSpecies = 0xCFE5,
|
||||
|
||||
.wSerialEnemyMonsPatchList = 0xC5D0,
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xCD81,
|
||||
.hSerialConnectionStatus = 0xFFAA,
|
||||
.wSerialEnemyMonsPatchList = 0xC5D0,
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xCD81,
|
||||
.hSerialConnectionStatus = 0xFFAA,
|
||||
|
||||
.transferStringLocation = 0xC444,
|
||||
.textBorderUppLeft = 0xC42F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0
|
||||
},
|
||||
{ // ENG_BLUE
|
||||
.language = ENG_ID,
|
||||
.version = BLUE_ID,
|
||||
.generation = 1,
|
||||
.method = METHOD_NEWLINE,
|
||||
.payload_size = 637,
|
||||
.box_data_size = 0x462,
|
||||
.transferStringLocation = 0xC444,
|
||||
.textBorderUppLeft = 0xC42F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0},
|
||||
{// ENG_BLUE
|
||||
.language = ENG_ID,
|
||||
.version = BLUE_ID,
|
||||
.generation = 1,
|
||||
.method = METHOD_NEWLINE,
|
||||
.payload_size = 637,
|
||||
.box_data_size = 0x462,
|
||||
|
||||
.print_string_start = 0xC456,
|
||||
.stack_overwrite_location = 0xDFDD,
|
||||
.short_pkmn_name = 0xE3,
|
||||
.pointer_pkmn_name = 0xFC,
|
||||
.padding_1 = 0,
|
||||
.print_string_start = 0xC456,
|
||||
.stack_overwrite_location = 0xDFDD,
|
||||
.short_pkmn_name = 0xE3,
|
||||
.pointer_pkmn_name = 0xFC,
|
||||
.padding_1 = 0,
|
||||
|
||||
.clearScreen = 0x190F,
|
||||
.CableClub_TextBoxBorder = 0x5AB3,
|
||||
.placeString = 0x1955,
|
||||
.Serial_ExchangeBytes = 0x216F,
|
||||
._RemovePokemon = 0x7B68,
|
||||
.SaveSAVtoSRAM1 = 0x1C77E2,
|
||||
.SaveSAVtoSRAM2 = 0x1C780F,
|
||||
.OpenSRAM = 0,
|
||||
.SaveBox = 0,
|
||||
.Bankswitch = 0x35D6,
|
||||
.SoftReset = 0x1F49,
|
||||
.CloseSRAM = 0,
|
||||
.garbageDataLocation = 0x0316,
|
||||
.clearScreen = 0x190F,
|
||||
.CableClub_TextBoxBorder = 0x5AB3,
|
||||
.placeString = 0x1955,
|
||||
.Serial_ExchangeBytes = 0x216F,
|
||||
._RemovePokemon = 0x7B68,
|
||||
.SaveSAVtoSRAM1 = 0x1C77E2,
|
||||
.SaveSAVtoSRAM2 = 0x1C780F,
|
||||
.LoadCurrentBoxData = 0,
|
||||
.OpenSRAM = 0,
|
||||
.SaveBox = 0,
|
||||
.Bankswitch = 0x35D6,
|
||||
.SoftReset = 0x1F49,
|
||||
.CloseSRAM = 0,
|
||||
.garbageDataLocation = 0x0316,
|
||||
|
||||
.wRemoveMonFromBox = 0xCF95,
|
||||
.wBoxCount = 0xDA80,
|
||||
.wWhichPokemon = 0xCF92,
|
||||
.wBoxDataStart = 0xDA80,
|
||||
.wBoxDataEnd = 0xDEE2,
|
||||
.wSerialEnemyDataBlock = 0xD893,
|
||||
.wEnemyMonSpecies = 0xCFE5,
|
||||
.wRemoveMonFromBox = 0xCF95,
|
||||
.wBoxCount = 0xDA80,
|
||||
.wWhichPokemon = 0xCF92,
|
||||
.wBoxDataStart = 0xDA80,
|
||||
.wBoxDataEnd = 0xDEE2,
|
||||
.wSerialEnemyDataBlock = 0xD893,
|
||||
.wEnemyMonSpecies = 0xCFE5,
|
||||
|
||||
.wSerialEnemyMonsPatchList = 0xC5D0,
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xCD81,
|
||||
.hSerialConnectionStatus = 0xFFAA,
|
||||
.wSerialEnemyMonsPatchList = 0xC5D0,
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xCD81,
|
||||
.hSerialConnectionStatus = 0xFFAA,
|
||||
|
||||
.transferStringLocation = 0xC444,
|
||||
.textBorderUppLeft = 0xC42F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0
|
||||
},
|
||||
{ // ENG_YELLOW
|
||||
.language = ENG_ID,
|
||||
.version = YELLOW_ID,
|
||||
.generation = 1,
|
||||
.method = METHOD_MEW,
|
||||
.payload_size = 637,
|
||||
.box_data_size = 0x462,
|
||||
.transferStringLocation = 0xC444,
|
||||
.textBorderUppLeft = 0xC42F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0},
|
||||
{// ENG_YELLOW
|
||||
.language = ENG_ID,
|
||||
.version = YELLOW_ID,
|
||||
.generation = 1,
|
||||
.method = METHOD_MEW,
|
||||
.payload_size = 637,
|
||||
.box_data_size = 0x462,
|
||||
|
||||
.print_string_start = 0xC456,
|
||||
.stack_overwrite_location = 0xDFDD,
|
||||
.short_pkmn_name = 0x15,
|
||||
.pointer_pkmn_name = 0xE3,
|
||||
.padding_1 = 0,
|
||||
.print_string_start = 0xC456,
|
||||
.stack_overwrite_location = 0xDFDD,
|
||||
.short_pkmn_name = 0x15,
|
||||
.pointer_pkmn_name = 0xE3,
|
||||
.padding_1 = 0,
|
||||
|
||||
.clearScreen = 0x16DD,
|
||||
.CableClub_TextBoxBorder = 0x16F0, // TextBoxBoarder, since the Cable Club isn't loaded
|
||||
.placeString = 0x1723,
|
||||
.Serial_ExchangeBytes = 0x1FCB,
|
||||
._RemovePokemon = 0x7A0F,
|
||||
.SaveSAVtoSRAM1 = 0x1C7B32,
|
||||
.SaveSAVtoSRAM2 = 0x1C7B56,
|
||||
.OpenSRAM = 0x3E99,
|
||||
.SaveBox = 0,
|
||||
.Bankswitch = 0x3E7E, // BankswitchCommon
|
||||
.SoftReset = 0x1D05,
|
||||
.CloseSRAM = 0x3EA9,
|
||||
.garbageDataLocation = 0x0161,
|
||||
.clearScreen = 0x16DD,
|
||||
.CableClub_TextBoxBorder = 0x16F0, // TextBoxBoarder, since the Cable Club isn't loaded
|
||||
.placeString = 0x1723,
|
||||
.Serial_ExchangeBytes = 0x1FCB,
|
||||
._RemovePokemon = 0x017A0F,
|
||||
.SaveSAVtoSRAM1 = 0x1C7B32,
|
||||
.SaveSAVtoSRAM2 = 0x1C7B56,
|
||||
.LoadCurrentBoxData = 0x1C79FC,
|
||||
.OpenSRAM = 0x3E99,
|
||||
.SaveBox = 0,
|
||||
.Bankswitch = 0x3E84,
|
||||
.SoftReset = 0x1D05,
|
||||
.CloseSRAM = 0x3EA9,
|
||||
.garbageDataLocation = 0x0161,
|
||||
|
||||
.wRemoveMonFromBox = 0xCF94,
|
||||
.wBoxCount = 0xDA7F,
|
||||
.wWhichPokemon = 0xCF91,
|
||||
.wBoxDataStart = 0xDA7F,
|
||||
.wBoxDataEnd = 0xDEE1,
|
||||
.wSerialEnemyDataBlock = 0xD892,
|
||||
.wEnemyMonSpecies = 0xCFE4,
|
||||
.wRemoveMonFromBox = 0xCF94,
|
||||
.wBoxCount = 0xDA7F,
|
||||
.wWhichPokemon = 0xCF91,
|
||||
.wBoxDataStart = 0xDA7F,
|
||||
.wBoxDataEnd = 0xDEE1,
|
||||
.wSerialEnemyDataBlock = 0xD892,
|
||||
.wEnemyMonSpecies = 0xCFE4,
|
||||
|
||||
.wSerialEnemyMonsPatchList = 0xC5D0,
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xCD81,
|
||||
.hSerialConnectionStatus = 0xFFAA,
|
||||
.wSerialEnemyMonsPatchList = 0xC5D0,
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xCD81,
|
||||
.hSerialConnectionStatus = 0xFFAA,
|
||||
|
||||
.transferStringLocation = 0xC444,
|
||||
.textBorderUppLeft = 0xC42F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0
|
||||
},
|
||||
{ // ENG_GOLD
|
||||
.language = ENG_ID,
|
||||
.version = GOLD_ID,
|
||||
.generation = 2,
|
||||
.method = METHOD_GEN2,
|
||||
.payload_size = 672,
|
||||
.box_data_size = 0x44E,
|
||||
.transferStringLocation = 0xC444,
|
||||
.textBorderUppLeft = 0xC42F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0},
|
||||
{// ENG_GOLD
|
||||
.language = ENG_ID,
|
||||
.version = GOLD_ID,
|
||||
.generation = 2,
|
||||
.method = METHOD_GEN2,
|
||||
.payload_size = 672,
|
||||
.box_data_size = 0x44E,
|
||||
|
||||
.print_string_start = 0xC442,
|
||||
.stack_overwrite_location = 0xDFCB, // Found by seeing where 772C is stored in the stack, 772C is the code that calls PlaceString
|
||||
.short_pkmn_name = 0x4E,
|
||||
.pointer_pkmn_name = 0,
|
||||
.padding_1 = 0,
|
||||
.print_string_start = 0xC442,
|
||||
.stack_overwrite_location = 0xDFCB, // Found by seeing where 772C is stored in the stack, 772C is the code that calls PlaceString
|
||||
.short_pkmn_name = 0x4E,
|
||||
.pointer_pkmn_name = 0,
|
||||
.padding_1 = 0,
|
||||
|
||||
.clearScreen = 0x000EE2,
|
||||
.CableClub_TextBoxBorder = 0x0A4D88, // LinkTextboxAtHL
|
||||
.placeString = 0x000F74,
|
||||
.Serial_ExchangeBytes = 0x0710,
|
||||
._RemovePokemon = 0x03603F, // RemoveMonFromPartyOrBox
|
||||
.SaveSAVtoSRAM1 = 0,
|
||||
.SaveSAVtoSRAM2 = 0,
|
||||
.OpenSRAM = 0x0030E1,
|
||||
.SaveBox = 0x054DF6,
|
||||
.Bankswitch = 0,
|
||||
.SoftReset = 0x05B0,
|
||||
.CloseSRAM = 0,
|
||||
.garbageDataLocation = 0x0654,
|
||||
.clearScreen = 0x000EE2,
|
||||
.CableClub_TextBoxBorder = 0x0A4D88, // LinkTextboxAtHL
|
||||
.placeString = 0x000F74,
|
||||
.Serial_ExchangeBytes = 0x0710,
|
||||
._RemovePokemon = 0x03603F, // RemoveMonFromPartyOrBox
|
||||
.SaveSAVtoSRAM1 = 0,
|
||||
.SaveSAVtoSRAM2 = 0,
|
||||
.LoadCurrentBoxData = 0,
|
||||
.OpenSRAM = 0x0030E1,
|
||||
.SaveBox = 0x054DF6,
|
||||
.Bankswitch = 0,
|
||||
.SoftReset = 0x05B0,
|
||||
.CloseSRAM = 0,
|
||||
.garbageDataLocation = 0x0654,
|
||||
|
||||
.wRemoveMonFromBox = 0x01D008, // wPokemonWithdrawDepositParameter
|
||||
.wBoxCount = 0x01AD6C, // sBoxCount
|
||||
.wWhichPokemon = 0x01D005, // wCurPartyMon
|
||||
.wBoxDataStart = 0xAD6C, // sBoxStart
|
||||
.wBoxDataEnd = 0xB1BA, // sBoxEnd
|
||||
.wSerialEnemyDataBlock = 0xDD40, // wOTPartyData
|
||||
.wEnemyMonSpecies = 0x01D0EF,
|
||||
.wRemoveMonFromBox = 0x01D008, // wPokemonWithdrawDepositParameter
|
||||
.wBoxCount = 0x01AD6C, // sBoxCount
|
||||
.wWhichPokemon = 0x01D005, // wCurPartyMon
|
||||
.wBoxDataStart = 0xAD6C, // sBoxStart
|
||||
.wBoxDataEnd = 0xB1BA, // sBoxEnd
|
||||
.wSerialEnemyDataBlock = 0xDD40, // wOTPartyData
|
||||
.wEnemyMonSpecies = 0x01D0EF,
|
||||
|
||||
.wSerialEnemyMonsPatchList = 0xC5D0, // wOTPatchLists
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xD0EF, // wOTLinkBattleRNData
|
||||
.hSerialConnectionStatus = 0xFFCD,
|
||||
.wSerialEnemyMonsPatchList = 0xC5D0, // wOTPatchLists
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xD0EF, // wOTLinkBattleRNData
|
||||
.hSerialConnectionStatus = 0xFFCD,
|
||||
|
||||
.transferStringLocation = 0xC444,
|
||||
.textBorderUppLeft = 0xC42F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0
|
||||
},
|
||||
{ // ENG_SILVER
|
||||
.language = ENG_ID,
|
||||
.version = SILVER_ID,
|
||||
.generation = 2,
|
||||
.method = METHOD_GEN2,
|
||||
.payload_size = 672,
|
||||
.box_data_size = 0x44E,
|
||||
.transferStringLocation = 0xC444,
|
||||
.textBorderUppLeft = 0xC42F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0},
|
||||
{// ENG_SILVER
|
||||
.language = ENG_ID,
|
||||
.version = SILVER_ID,
|
||||
.generation = 2,
|
||||
.method = METHOD_GEN2,
|
||||
.payload_size = 672,
|
||||
.box_data_size = 0x44E,
|
||||
|
||||
.print_string_start = 0xC442,
|
||||
.stack_overwrite_location = 0xDFCB, // Found by seeing where 772C is stored in the stack, 772C is the code that calls PlaceString
|
||||
.short_pkmn_name = 0x4E,
|
||||
.pointer_pkmn_name = 0,
|
||||
.padding_1 = 0,
|
||||
.print_string_start = 0xC442,
|
||||
.stack_overwrite_location = 0xDFCB, // Found by seeing where 772C is stored in the stack, 772C is the code that calls PlaceString
|
||||
.short_pkmn_name = 0x4E,
|
||||
.pointer_pkmn_name = 0,
|
||||
.padding_1 = 0,
|
||||
|
||||
.clearScreen = 0x000EE2,
|
||||
.CableClub_TextBoxBorder = 0x0A4D88, // LinkTextboxAtHL
|
||||
.placeString = 0x000F74,
|
||||
.Serial_ExchangeBytes = 0x0710,
|
||||
._RemovePokemon = 0x03603D, // RemoveMonFromPartyOrBox
|
||||
.SaveSAVtoSRAM1 = 0,
|
||||
.SaveSAVtoSRAM2 = 0,
|
||||
.OpenSRAM = 0x0030E1,
|
||||
.SaveBox = 0x054DF6,
|
||||
.Bankswitch = 0,
|
||||
.SoftReset = 0x05B0,
|
||||
.CloseSRAM = 0,
|
||||
.garbageDataLocation = 0x0654,
|
||||
.clearScreen = 0x000EE2,
|
||||
.CableClub_TextBoxBorder = 0x0A4D88, // LinkTextboxAtHL
|
||||
.placeString = 0x000F74,
|
||||
.Serial_ExchangeBytes = 0x0710,
|
||||
._RemovePokemon = 0x03603D, // RemoveMonFromPartyOrBox
|
||||
.SaveSAVtoSRAM1 = 0,
|
||||
.SaveSAVtoSRAM2 = 0,
|
||||
.LoadCurrentBoxData = 0,
|
||||
.OpenSRAM = 0x0030E1,
|
||||
.SaveBox = 0x054DF6,
|
||||
.Bankswitch = 0,
|
||||
.SoftReset = 0x05B0,
|
||||
.CloseSRAM = 0,
|
||||
.garbageDataLocation = 0x0654,
|
||||
|
||||
.wRemoveMonFromBox = 0x01D008, // wPokemonWithdrawDepositParameter
|
||||
.wBoxCount = 0x01AD6C, // sBoxCount
|
||||
.wWhichPokemon = 0x01D005, // wCurPartyMon
|
||||
.wBoxDataStart = 0xAD6C, // sBoxStart
|
||||
.wBoxDataEnd = 0xB1BA, // sBoxEnd
|
||||
.wSerialEnemyDataBlock = 0xDD40, // wOTPartyData
|
||||
.wEnemyMonSpecies = 0x01D0EF,
|
||||
.wRemoveMonFromBox = 0x01D008, // wPokemonWithdrawDepositParameter
|
||||
.wBoxCount = 0x01AD6C, // sBoxCount
|
||||
.wWhichPokemon = 0x01D005, // wCurPartyMon
|
||||
.wBoxDataStart = 0xAD6C, // sBoxStart
|
||||
.wBoxDataEnd = 0xB1BA, // sBoxEnd
|
||||
.wSerialEnemyDataBlock = 0xDD40, // wOTPartyData
|
||||
.wEnemyMonSpecies = 0x01D0EF,
|
||||
|
||||
.wSerialEnemyMonsPatchList = 0xC5D0, // wOTPatchLists
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xD0EF, // wOTLinkBattleRNData
|
||||
.hSerialConnectionStatus = 0xFFCD,
|
||||
.wSerialEnemyMonsPatchList = 0xC5D0, // wOTPatchLists
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xD0EF, // wOTLinkBattleRNData
|
||||
.hSerialConnectionStatus = 0xFFCD,
|
||||
|
||||
.transferStringLocation = 0xC444,
|
||||
.textBorderUppLeft = 0xC42F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0
|
||||
},
|
||||
{ // ENG_CRYSTAL
|
||||
.language = ENG_ID,
|
||||
.version = CRYSTAL_ID,
|
||||
.generation = 2,
|
||||
.method = METHOD_GEN2,
|
||||
.payload_size = 672,
|
||||
.box_data_size = 0x44E,
|
||||
.transferStringLocation = 0xC444,
|
||||
.textBorderUppLeft = 0xC42F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0},
|
||||
{// ENG_CRYSTAL
|
||||
.language = ENG_ID,
|
||||
.version = CRYSTAL_ID,
|
||||
.generation = 2,
|
||||
.method = METHOD_GEN2,
|
||||
.payload_size = 672,
|
||||
.box_data_size = 0x44E,
|
||||
|
||||
.print_string_start = 0xC544,
|
||||
.stack_overwrite_location = 0xE0BB, // Found by seeing where 7622 is stored in the stack, 7622 is the code that calls PlaceString (PlaceTradePartnerNamesAndParty)
|
||||
.short_pkmn_name = 0x4E,
|
||||
.pointer_pkmn_name = 0,
|
||||
.padding_1 = 0,
|
||||
.print_string_start = 0xC544,
|
||||
.stack_overwrite_location = 0xE0BB, // Found by seeing where 7622 is stored in the stack, 7622 is the code that calls PlaceString (PlaceTradePartnerNamesAndParty)
|
||||
.short_pkmn_name = 0x4E,
|
||||
.pointer_pkmn_name = 0,
|
||||
.padding_1 = 0,
|
||||
|
||||
.clearScreen = 0x000FDB,
|
||||
.CableClub_TextBoxBorder = 0x0A4EEF, // LinkTextboxAtHL
|
||||
.placeString = 0x001078,
|
||||
.Serial_ExchangeBytes = 0x075F,
|
||||
._RemovePokemon = 0x036039, // RemoveMonFromPartyOrBox
|
||||
.SaveSAVtoSRAM1 = 0,
|
||||
.SaveSAVtoSRAM2 = 0,
|
||||
.OpenSRAM = 0x002FCB,
|
||||
.SaveBox = 0x054E0C,
|
||||
.Bankswitch = 0,
|
||||
.SoftReset = 0x0150, // Reset
|
||||
.CloseSRAM = 0,
|
||||
.garbageDataLocation = 0x0770,
|
||||
.clearScreen = 0x000FDB,
|
||||
.CableClub_TextBoxBorder = 0x0A4EEF, // LinkTextboxAtHL
|
||||
.placeString = 0x001078,
|
||||
.Serial_ExchangeBytes = 0x075F,
|
||||
._RemovePokemon = 0x036039, // RemoveMonFromPartyOrBox
|
||||
.SaveSAVtoSRAM1 = 0,
|
||||
.SaveSAVtoSRAM2 = 0,
|
||||
.LoadCurrentBoxData = 0,
|
||||
.OpenSRAM = 0x002FCB,
|
||||
.SaveBox = 0x054E0C,
|
||||
.Bankswitch = 0,
|
||||
.SoftReset = 0x0150, // Reset
|
||||
.CloseSRAM = 0,
|
||||
.garbageDataLocation = 0x0770,
|
||||
|
||||
.wRemoveMonFromBox = 0x01D10B, // wPokemonWithdrawDepositParameter
|
||||
.wBoxCount = 0x01AD10, // sBoxCount
|
||||
.wWhichPokemon = 0x01D109, // wCurPartyMon
|
||||
.wBoxDataStart = 0x01AD10, // sBox
|
||||
.wBoxDataEnd = 0x01B15E, // sBoxEnd
|
||||
.wSerialEnemyDataBlock = 0xD26B, // wOTPartyData
|
||||
.wEnemyMonSpecies = 0x01D206,
|
||||
.wRemoveMonFromBox = 0x01D10B, // wPokemonWithdrawDepositParameter
|
||||
.wBoxCount = 0x01AD10, // sBoxCount
|
||||
.wWhichPokemon = 0x01D109, // wCurPartyMon
|
||||
.wBoxDataStart = 0x01AD10, // sBox
|
||||
.wBoxDataEnd = 0x01B15E, // sBoxEnd
|
||||
.wSerialEnemyDataBlock = 0xD26B, // wOTPartyData
|
||||
.wEnemyMonSpecies = 0x01D206,
|
||||
|
||||
.wSerialEnemyMonsPatchList = 0xC6D0, // wOTPatchLists
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xD206, // wOTLinkBattleRNData
|
||||
.hSerialConnectionStatus = 0xFFCB,
|
||||
.wSerialEnemyMonsPatchList = 0xC6D0, // wOTPatchLists
|
||||
.wSerialOtherGameboyRandomNumberListBlock = 0xD206, // wOTLinkBattleRNData
|
||||
.hSerialConnectionStatus = 0xFFCB,
|
||||
|
||||
.transferStringLocation = 0xC544,
|
||||
.textBorderUppLeft = 0xC52F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0
|
||||
}
|
||||
};
|
||||
.transferStringLocation = 0xC544,
|
||||
.textBorderUppLeft = 0xC52F,
|
||||
.textBorderWidth = 12,
|
||||
.textBorderHeight = 1,
|
||||
.padding_2 = 0}};
|
||||
|
||||
const u16 gb_rom_values_eng_size = static_cast<u16>(sizeof(gb_rom_values_eng) / sizeof(struct GB_ROM));
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "pokemon_data.h"
|
||||
//#include "pokemon_data.h"
|
||||
#include "common.h"
|
||||
#include "gba_rom_values/gba_rom_values.h"
|
||||
#include "gb_rom_values/gb_rom_values.h"
|
||||
|
|
|
|||
|
|
@ -5,9 +5,15 @@
|
|||
#include <cstring>
|
||||
|
||||
#define DATA_LOC (SHOW_DATA_PACKETS ? curr_rom.transferStringLocation : curr_rom.wEnemyMonSpecies)
|
||||
#define DEBUG_PAYLOADS (false && DEBUG_MODE)
|
||||
|
||||
void init_payload(byte *payload_buffer, const GB_ROM& curr_rom, int type, bool debug)
|
||||
void init_payload(byte *payload_buffer, const GB_ROM &curr_rom, int type, bool debug)
|
||||
{
|
||||
if (DEBUG_PAYLOADS)
|
||||
{
|
||||
debug = true;
|
||||
}
|
||||
|
||||
(void)type;
|
||||
/* 10 RNG bytes
|
||||
8 Preamble bytes
|
||||
|
|
@ -420,94 +426,95 @@ void init_payload(byte *payload_buffer, const GB_ROM& curr_rom, int type, bool d
|
|||
skip_enemy_write.set_start(&z80_payload);
|
||||
|
||||
// Reload the save data to remove any data that was overwritten during exploit entry
|
||||
z80_payload.LD(A, (curr_rom.SaveSAVtoSRAM1 >> 16) | T_U8);
|
||||
z80_payload.LD(B, (curr_rom.LoadCurrentBoxData >> 16) | T_U8);
|
||||
z80_payload.LD(HL, curr_rom.LoadCurrentBoxData | T_U16);
|
||||
z80_payload.CALL(curr_rom.Bankswitch | T_U16);
|
||||
z80_payload.CALL(0x79FC | T_U16); // Call LoadSAV1 TODO FIX THIS BAD BAD NO BAD
|
||||
|
||||
/* Build the packet */
|
||||
// HL is the current data pointer
|
||||
// DE is the destination pointer
|
||||
// A is the checksum
|
||||
// B is the 0xFE flag byte
|
||||
// C is the counter
|
||||
send_packet_loop.set_start(&z80_payload);
|
||||
|
||||
z80_payload.LD(HL, (DATA_LOC + PACKET_SIZE + 3) | T_U16); // Load the next data location into HL
|
||||
z80_payload.LD(A, HLI_PTR);
|
||||
z80_payload.LD(H, HL_PTR);
|
||||
z80_payload.LD(L, A);
|
||||
z80_payload.LD(DE, (DATA_LOC + 2) | T_U16); // Enemy Pokemon data, should be unused
|
||||
z80_payload.XOR(A, A); // Clear the register
|
||||
z80_payload.LD(B, A); // Clear B as well
|
||||
z80_payload.LD(C, A); // Clear C as well
|
||||
z80_payload.PUSH(AF);
|
||||
packet_loop.set_start(&z80_payload);
|
||||
z80_payload.LD(B, 0x00 | T_U8); // Reset the flag byte
|
||||
z80_payload.POP(AF);
|
||||
z80_payload.ADD(A, HL_PTR); // Add the current data to the checksum
|
||||
z80_payload.PUSH(AF);
|
||||
z80_payload.LD(A, 0xFE);
|
||||
z80_payload.CP(A, HL_PTR); // Compare the current data to 0xFE
|
||||
z80_payload.LD(A, HLI_PTR); // Load HL's data into A for modification (if need be)
|
||||
|
||||
// If HL's data is 0xFE
|
||||
z80_payload.JR(NZ_F, fe_bypass.place_relative_jump(&z80_payload) | T_I8);
|
||||
z80_payload.DEC(A);
|
||||
z80_payload.INC(B); // Set flag
|
||||
|
||||
fe_bypass.set_start(&z80_payload);
|
||||
z80_payload.LD(DE_PTR, A); // Place the data in
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.PUSH(AF);
|
||||
z80_payload.LD(A, B);
|
||||
z80_payload.LD(DE_PTR, A); // Place the flag in as well
|
||||
z80_payload.POP(AF);
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.INC(C);
|
||||
z80_payload.LD(A, DATA_PER_PACKET - 1);
|
||||
z80_payload.CP(A, C);
|
||||
z80_payload.JR(NC_F, packet_loop.place_relative_jump(&z80_payload) | T_I8); // If all the data has been set, send the rest of the data
|
||||
z80_payload.POP(AF);
|
||||
z80_payload.RES(7 | T_BIT, A); // Reset bit 7 of the checksum, guaranteeing that it will never be 0xFE
|
||||
z80_payload.LD(DE_PTR, A);
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.LD(A, H);
|
||||
|
||||
z80_payload.LD(DE_PTR, A);
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.LD(A, L);
|
||||
z80_payload.LD(DE_PTR, A);
|
||||
|
||||
/* Transfer box data packet: */
|
||||
z80_payload.LD(A, (debug ? 0x02 : 0x01) | T_U8); // Make sure GB is the slave, master if debug
|
||||
z80_payload.LDH((curr_rom.hSerialConnectionStatus & 0xFF) | T_U8, A); // Since hSerialConnectionStatus is at 0xFFxx we can use this method instead
|
||||
z80_payload.LD(HL, DATA_LOC | T_U16);
|
||||
z80_payload.LD(HL_PTR, 0xFD | T_U8); // set the start of the data to 0xFD so Serial_ExchangeBytes is happy
|
||||
z80_payload.INC(HL);
|
||||
z80_payload.LD(HL_PTR, 0x00 | T_U8); // add a 0x00 after the 0xFD to prevent further 0xFDs from being interpreted as part of the preamble
|
||||
z80_payload.DEC(HL); // Reset HL back so it points to 0xFD
|
||||
z80_payload.LD(DE, (DATA_LOC + PACKET_SIZE) | T_U16); // location to put stored data
|
||||
z80_payload.LD(BC, PACKET_SIZE | T_U16);
|
||||
if (debug) // Don't call serialExchangeBytes if debug is enabled
|
||||
if (!debug)
|
||||
{
|
||||
z80_payload.index += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_payload.CALL(curr_rom.Serial_ExchangeBytes | T_U16);
|
||||
}
|
||||
/* Build the packet */
|
||||
// HL is the current data pointer
|
||||
// DE is the destination pointer
|
||||
// A is the checksum
|
||||
// B is the 0xFE flag byte
|
||||
// C is the counter
|
||||
send_packet_loop.set_start(&z80_payload);
|
||||
|
||||
z80_payload.LD(A, (DATA_LOC + PACKET_SIZE + 3 + 1) | T_U16);
|
||||
z80_payload.CP(A, 0xFF);
|
||||
if (debug && false) // Don't compare the "recieved" data if in debug
|
||||
{
|
||||
z80_payload.index += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_payload.JR(NZ_F, send_packet_loop.place_relative_jump(&z80_payload) | T_I8);
|
||||
}
|
||||
z80_payload.LD(HL, (DATA_LOC + PACKET_SIZE + 3) | T_U16); // Load the next data location into HL
|
||||
z80_payload.LD(A, HLI_PTR);
|
||||
z80_payload.LD(H, HL_PTR);
|
||||
z80_payload.LD(L, A);
|
||||
z80_payload.LD(DE, (DATA_LOC + 2) | T_U16); // Enemy Pokemon data, should be unused
|
||||
z80_payload.XOR(A, A); // Clear the register
|
||||
z80_payload.LD(B, A); // Clear B as well
|
||||
z80_payload.LD(C, A); // Clear C as well
|
||||
z80_payload.PUSH(AF);
|
||||
packet_loop.set_start(&z80_payload);
|
||||
z80_payload.LD(B, 0x00 | T_U8); // Reset the flag byte
|
||||
z80_payload.POP(AF);
|
||||
z80_payload.ADD(A, HL_PTR); // Add the current data to the checksum
|
||||
z80_payload.PUSH(AF);
|
||||
z80_payload.LD(A, 0xFE);
|
||||
z80_payload.CP(A, HL_PTR); // Compare the current data to 0xFE
|
||||
z80_payload.LD(A, HLI_PTR); // Load HL's data into A for modification (if need be)
|
||||
|
||||
// If HL's data is 0xFE
|
||||
z80_payload.JR(NZ_F, fe_bypass.place_relative_jump(&z80_payload) | T_I8);
|
||||
z80_payload.DEC(A);
|
||||
z80_payload.INC(B); // Set flag
|
||||
|
||||
fe_bypass.set_start(&z80_payload);
|
||||
z80_payload.LD(DE_PTR, A); // Place the data in
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.PUSH(AF);
|
||||
z80_payload.LD(A, B);
|
||||
z80_payload.LD(DE_PTR, A); // Place the flag in as well
|
||||
z80_payload.POP(AF);
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.INC(C);
|
||||
z80_payload.LD(A, DATA_PER_PACKET - 1);
|
||||
z80_payload.CP(A, C);
|
||||
z80_payload.JR(NC_F, packet_loop.place_relative_jump(&z80_payload) | T_I8); // If all the data has been set, send the rest of the data
|
||||
z80_payload.POP(AF);
|
||||
z80_payload.RES(7 | T_BIT, A); // Reset bit 7 of the checksum, guaranteeing that it will never be 0xFE
|
||||
z80_payload.LD(DE_PTR, A);
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.LD(A, H);
|
||||
|
||||
z80_payload.LD(DE_PTR, A);
|
||||
z80_payload.INC(DE);
|
||||
z80_payload.LD(A, L);
|
||||
z80_payload.LD(DE_PTR, A);
|
||||
|
||||
/* Transfer box data packet: */
|
||||
z80_payload.LD(A, (debug ? 0x02 : 0x01) | T_U8); // Make sure GB is the slave, master if debug
|
||||
z80_payload.LDH((curr_rom.hSerialConnectionStatus & 0xFF) | T_U8, A); // Since hSerialConnectionStatus is at 0xFFxx we can use this method instead
|
||||
z80_payload.LD(HL, DATA_LOC | T_U16);
|
||||
z80_payload.LD(HL_PTR, 0xFD | T_U8); // set the start of the data to 0xFD so Serial_ExchangeBytes is happy
|
||||
z80_payload.INC(HL);
|
||||
z80_payload.LD(HL_PTR, 0x00 | T_U8); // add a 0x00 after the 0xFD to prevent further 0xFDs from being interpreted as part of the preamble
|
||||
z80_payload.DEC(HL); // Reset HL back so it points to 0xFD
|
||||
z80_payload.LD(DE, (DATA_LOC + PACKET_SIZE) | T_U16); // location to put stored data
|
||||
z80_payload.LD(BC, PACKET_SIZE | T_U16);
|
||||
if (debug) // Don't call serialExchangeBytes if debug is enabled
|
||||
{
|
||||
z80_payload.index += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_payload.CALL(curr_rom.Serial_ExchangeBytes | T_U16);
|
||||
}
|
||||
|
||||
z80_payload.LD(A, (DATA_LOC + PACKET_SIZE + 3 + 1) | T_U16);
|
||||
z80_payload.CP(A, 0xFF);
|
||||
if (debug && false) // Don't compare the "recieved" data if in debug
|
||||
{
|
||||
z80_payload.index += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
z80_payload.JR(NZ_F, send_packet_loop.place_relative_jump(&z80_payload) | T_I8);
|
||||
}
|
||||
}
|
||||
/* Recieve the Pokemon to remove */
|
||||
z80_payload.LD(HL, curr_rom.hSerialConnectionStatus | T_U16); // This can also be shortened
|
||||
z80_payload.LD(HL_PTR, (debug ? 0x02 : 0x01) | T_U8); // Make sure GB is the slave, master if debug
|
||||
|
|
@ -549,16 +556,22 @@ void init_payload(byte *payload_buffer, const GB_ROM& curr_rom, int type, bool d
|
|||
}
|
||||
else
|
||||
{
|
||||
z80_payload.CALL(curr_rom._RemovePokemon | T_U16);
|
||||
z80_payload.LD(B, (curr_rom._RemovePokemon >> 16) | T_U8); // Load ROM Bank
|
||||
z80_payload.LD(HL, curr_rom._RemovePokemon | T_U16);
|
||||
z80_payload.CALL(curr_rom.Bankswitch | T_U16);
|
||||
}
|
||||
z80_payload.JR((remove_array_loop.place_relative_jump(&z80_payload) & 0xFF) | T_I8);
|
||||
|
||||
// We need to move this in order to not corrupt the 4E's
|
||||
z80_payload.JR((save_box.place_relative_jump(&z80_payload) & 0xFF) | T_I8);
|
||||
z80_payload.index = 0x17A;
|
||||
|
||||
/* Save the current box */
|
||||
save_box.set_start(&z80_payload);
|
||||
z80_payload.LD(A, (curr_rom.SaveSAVtoSRAM1 >> 16) | T_U8); // Load ROM Bank
|
||||
z80_payload.LD(B, (curr_rom.SaveSAVtoSRAM1 >> 16) | T_U8); // Load ROM Bank
|
||||
z80_payload.LD(HL, curr_rom.SaveSAVtoSRAM1 | T_U16);
|
||||
z80_payload.CALL(curr_rom.Bankswitch | T_U16);
|
||||
z80_payload.LD(A, (curr_rom.SaveSAVtoSRAM1 >> 16) | T_U8); // Load ROM Bank
|
||||
z80_payload.LD(B, (curr_rom.SaveSAVtoSRAM2 >> 16) | T_U8); // Load ROM Bank
|
||||
z80_payload.LD(HL, curr_rom.SaveSAVtoSRAM2 | T_U16);
|
||||
z80_payload.CALL(curr_rom.Bankswitch | T_U16);
|
||||
z80_payload.JP(curr_rom.SoftReset | T_U16);
|
||||
|
|
@ -949,17 +962,19 @@ void init_payload(byte *payload_buffer, const GB_ROM& curr_rom, int type, bool d
|
|||
|
||||
#if PAYLOAD_EXPORT_TEST
|
||||
#include <cstdio>
|
||||
#include "gb_rom_values/gb_rom_values.h"
|
||||
int main() // Rename to "main" to send the payload to test_payload.txt
|
||||
{
|
||||
byte buffer[672] = {0};
|
||||
freopen("test_payload.txt", "w", stdout);
|
||||
printf("\n");
|
||||
init_payload(ENG_GOLD, TRANSFER, true);
|
||||
byte *payload = get_payload();
|
||||
init_payload(buffer, gb_rom_values_eng[RED_ID], TRANSFER, true);
|
||||
|
||||
if (true)
|
||||
{
|
||||
for (int i = 0; i < 0x2A0; i++)
|
||||
{
|
||||
printf("0x%02X, ", (unsigned int)payload[i]);
|
||||
printf("0x%02X, ", (unsigned int)buffer[i]);
|
||||
if (i % 0x10 == 0xF)
|
||||
{
|
||||
printf("\n# 0x%X\n", i + 1);
|
||||
|
|
@ -971,7 +986,7 @@ int main() // Rename to "main" to send the payload to test_payload.txt
|
|||
{
|
||||
for (int i = 0; i < 0x150; i++)
|
||||
{
|
||||
printf("%02X ", (unsigned int)payload[i + ((0x10 * 28) + 9)]);
|
||||
printf("%02X ", (unsigned int)buffer[i + ((0x10 * 28) + 9)]);
|
||||
if (i % 0x10 == 0xF)
|
||||
{
|
||||
printf("\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user