mirror of
https://github.com/GearsProgress/Poke_Transporter_GB.git
synced 2026-07-17 01:00:32 -05:00
336 lines
8.4 KiB
C++
336 lines
8.4 KiB
C++
#include <tonc.h>
|
|
#include "script_builder.h"
|
|
|
|
mystery_gift_script::mystery_gift_script()
|
|
{
|
|
curr_index = NPC_LOCATION_OFFSET;
|
|
}
|
|
|
|
void mystery_gift_script::build_script()
|
|
{
|
|
set_script();
|
|
};
|
|
|
|
void mystery_gift_script::set_script()
|
|
{
|
|
// Located at 0x?8A8 in the .sav
|
|
init_npc_location(0xFF, 0xFF, 0xFF);
|
|
setvirtualaddress(0x08000000);
|
|
lock();
|
|
faceplayer();
|
|
checkflag(FLAG_ALL_COLLECTED);
|
|
virtualgotoif(COND_FLAGTRUE, JUMP_ALL_COLLECTED);
|
|
virtualmsgbox(TEXT_GREET);
|
|
waitmsg();
|
|
waitkeypress();
|
|
setvar(VAR_INDEX, 0x0000);
|
|
setvar(VAR_CALLASM, rev_endian(0x0023));
|
|
setvar(VAR_PKMN_OFFSET, 0x0000);
|
|
copybyte(PTR_SCRIPT_PTR_LOW, PTR_BLOCK_PTR_LOW);
|
|
copybyte(PTR_SCRIPT_PTR_LOW + 1, PTR_BLOCK_PTR_LOW + 1);
|
|
copybyte(PTR_SCRIPT_PTR_HIGH, PTR_BLOCK_PTR_HIGH);
|
|
copybyte(PTR_SCRIPT_PTR_HIGH + 1, PTR_BLOCK_PTR_HIGH + 1);
|
|
addvar(VAR_SCRIPT_PTR_LOW, 0x3731);
|
|
addvar(VAR_SCRIPT_PTR_LOW, 0x164); // Combine to one line to free up space
|
|
setvar(VAR_CALL_RETURN_1, rev_endian(0x0300));
|
|
setvar(VAR_CALL_CHECK_FLAG, rev_endian(0x2B00));
|
|
addvar(VAR_CALL_CHECK_FLAG, 0x2000);
|
|
setvar(VAR_CALL_RETURN_2, rev_endian(0x0003));
|
|
set_jump_destination(JUMP_LOOP);
|
|
call(PTR_CALL_CHECK_FLAG);
|
|
virtualgotoif(COND_FLAGFALSE, JUMP_PKMN_COLLECTED);
|
|
call(PTR_CALLASM);
|
|
compare(VAR_BOX_RETURN, 0x02);
|
|
virtualgotoif(COND_EQUALS, JUMP_BOX_FULL);
|
|
set_jump_destination(JUMP_PKMN_COLLECTED);
|
|
addvar(VAR_PKMN_OFFSET, 0x64);
|
|
addvar(VAR_INDEX, 0x01);
|
|
addvar(VAR_CALL_CHECK_FLAG, 0x0100);
|
|
compare(VAR_INDEX, 0x06);
|
|
virtualgotoif(COND_LESSTHAN, JUMP_LOOP);
|
|
setflag(FLAG_ALL_COLLECTED);
|
|
set_jump_destination(JUMP_ALL_COLLECTED);
|
|
virtualmsgbox(TEXT_THANK);
|
|
waitmsg();
|
|
waitkeypress();
|
|
release();
|
|
end();
|
|
set_jump_destination(JUMP_BOX_FULL);
|
|
virtualmsgbox(TEXT_FULL);
|
|
waitmsg();
|
|
waitkeypress();
|
|
release();
|
|
end();
|
|
|
|
insert_textboxes();
|
|
|
|
fill_jumppoint_pointers();
|
|
fill_textbox_pointers();
|
|
};
|
|
|
|
u8 mystery_gift_script::get_script_value_at(int i)
|
|
{
|
|
return mg_script[i];
|
|
}
|
|
|
|
u16 mystery_gift_script::rev_endian(u16 num)
|
|
{
|
|
return ((num & 0xFF) << 8) | (num >> 8);
|
|
}
|
|
|
|
void mystery_gift_script::add_command(int len)
|
|
{
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
mg_script[curr_index - NPC_LOCATION_OFFSET] = value_buffer[i];
|
|
curr_index++;
|
|
}
|
|
}
|
|
|
|
void mystery_gift_script::fill_jumppoint_pointers()
|
|
{
|
|
for (int i = 0; i < NUM_JUMPS; i++) // Parse through the script and replace any jump points
|
|
// and text boxes to match their locations
|
|
{
|
|
u32 jump_addr = jumppoint_destination[i] + VIR_ADDRESS;
|
|
u32 jump_loc = jumppoint_location[i];
|
|
mg_script[jump_loc] = jump_addr >> 0;
|
|
mg_script[jump_loc + 1] = jump_addr >> 8;
|
|
mg_script[jump_loc + 2] = jump_addr >> 16;
|
|
mg_script[jump_loc + 3] = jump_addr >> 24;
|
|
}
|
|
}
|
|
|
|
void mystery_gift_script::fill_textbox_pointers()
|
|
{
|
|
for (int i = 0; i < NUM_TEXTBOXES; i++)
|
|
{
|
|
u32 textbox_addr = textbox_destination[i] + VIR_ADDRESS;
|
|
u32 textbox_loc = textbox_location[i];
|
|
mg_script[textbox_loc] = textbox_addr >> 0;
|
|
mg_script[textbox_loc + 1] = textbox_addr >> 8;
|
|
mg_script[textbox_loc + 2] = textbox_addr >> 16;
|
|
mg_script[textbox_loc + 3] = textbox_addr >> 24;
|
|
}
|
|
}
|
|
|
|
void mystery_gift_script::insert_textboxes()
|
|
{
|
|
for (int i = 0; i < NUM_TEXTBOXES; i++)
|
|
{
|
|
textbox_destination[i] = curr_index - NPC_LOCATION_OFFSET;
|
|
for (unsigned int parser = 0; parser < textboxes[i].length(); parser++)
|
|
{
|
|
mg_script[curr_index - NPC_LOCATION_OFFSET] = convert_char(textboxes[i].at(parser));
|
|
curr_index++;
|
|
}
|
|
mg_script[curr_index - NPC_LOCATION_OFFSET] = 0xFF; // End string
|
|
curr_index++;
|
|
}
|
|
}
|
|
|
|
u8 mystery_gift_script::convert_char(char convert_char)
|
|
{
|
|
switch (convert_char)
|
|
{
|
|
case '0' ... '9':
|
|
return convert_char + (0xA1 - '0'); // '0' = 0xA1
|
|
case 'A' ... 'Z':
|
|
return convert_char + (0xBB - 'A'); // 'A' = 0xBB
|
|
case 'a' ... 'z':
|
|
return convert_char + (0xD5 - 'a'); // 'a' = 0xD5
|
|
case '!':
|
|
return 0xAB;
|
|
case '?':
|
|
return 0xAC;
|
|
case '.':
|
|
return 0xAD;
|
|
case '#': // Variable escape sequence
|
|
return 0xFD;
|
|
case '*': // Player name
|
|
return 0x01;
|
|
case '^': // Wait for button and scroll text
|
|
return 0xFA;
|
|
case '-': // Wait for button and clear text
|
|
return 0xFB;
|
|
case ' ':
|
|
return 0x00;
|
|
default:
|
|
return 0x00;
|
|
}
|
|
}
|
|
|
|
u16 mystery_gift_script::calc_checksum() // Implementation taken from PokeEmerald Decomp
|
|
{
|
|
u16 i, j;
|
|
u16 crc = 0x1121;
|
|
|
|
for (i = 0; i < MG_SCRIPT_SIZE; i++)
|
|
{
|
|
crc ^= mg_script[i];
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0x8408;
|
|
else
|
|
crc >>= 1;
|
|
}
|
|
}
|
|
return ~crc;
|
|
}
|
|
|
|
// Scripting commands:
|
|
|
|
void mystery_gift_script::setvirtualaddress(u32 location)
|
|
{
|
|
value_buffer[0] = 0xB8;
|
|
value_buffer[1] = location >> 0;
|
|
value_buffer[2] = location >> 8;
|
|
value_buffer[3] = location >> 16;
|
|
value_buffer[4] = location >> 24;
|
|
add_command(5);
|
|
}
|
|
|
|
void mystery_gift_script::lock()
|
|
{
|
|
value_buffer[0] = 0x6A;
|
|
add_command(1);
|
|
}
|
|
|
|
void mystery_gift_script::faceplayer()
|
|
{
|
|
value_buffer[0] = 0x5A;
|
|
add_command(1);
|
|
}
|
|
|
|
void mystery_gift_script::checkflag(u8 flag_id)
|
|
{
|
|
value_buffer[0] = 0x2B;
|
|
value_buffer[1] = flag_id >> 0;
|
|
value_buffer[2] = flag_id >> 8;
|
|
add_command(3);
|
|
}
|
|
|
|
void mystery_gift_script::virtualgotoif(u8 condition, u8 jumppoint_id)
|
|
{
|
|
jumppoint_location[jumppoint_id] = ((curr_index - NPC_LOCATION_OFFSET) + 2);
|
|
|
|
value_buffer[0] = 0xBB;
|
|
value_buffer[1] = condition;
|
|
value_buffer[2] = 0x00;
|
|
value_buffer[3] = 0x00;
|
|
value_buffer[4] = 0x00;
|
|
value_buffer[5] = 0x00;
|
|
add_command(6);
|
|
}
|
|
|
|
void mystery_gift_script::set_jump_destination(u8 jumppoint_id)
|
|
{
|
|
jumppoint_destination[jumppoint_id] = curr_index - NPC_LOCATION_OFFSET;
|
|
}
|
|
|
|
void mystery_gift_script::virtualmsgbox(u8 textbox_id)
|
|
{
|
|
textbox_location[textbox_id] = ((curr_index - NPC_LOCATION_OFFSET) + 1);
|
|
value_buffer[0] = 0xBD;
|
|
value_buffer[1] = 0x00;
|
|
value_buffer[2] = 0x00;
|
|
value_buffer[3] = 0x00;
|
|
value_buffer[4] = 0x00;
|
|
add_command(5);
|
|
}
|
|
|
|
void mystery_gift_script::waitmsg()
|
|
{
|
|
value_buffer[0] = 0x66;
|
|
add_command(1);
|
|
}
|
|
|
|
void mystery_gift_script::waitkeypress()
|
|
{
|
|
value_buffer[0] = 0x6D;
|
|
add_command(1);
|
|
}
|
|
|
|
void mystery_gift_script::setvar(u16 var_id, u16 value)
|
|
{
|
|
value_buffer[0] = 0x16;
|
|
value_buffer[1] = var_id >> 0;
|
|
value_buffer[2] = var_id >> 8;
|
|
value_buffer[3] = value >> 0;
|
|
value_buffer[4] = value >> 8;
|
|
add_command(5);
|
|
}
|
|
|
|
void mystery_gift_script::copybyte(u32 destination, u32 source)
|
|
{
|
|
value_buffer[0] = 0x15;
|
|
value_buffer[1] = destination >> 0;
|
|
value_buffer[2] = destination >> 8;
|
|
value_buffer[3] = destination >> 16;
|
|
value_buffer[4] = destination >> 24;
|
|
value_buffer[5] = source >> 0;
|
|
value_buffer[6] = source >> 8;
|
|
value_buffer[7] = source >> 16;
|
|
value_buffer[8] = source >> 24;
|
|
add_command(9);
|
|
}
|
|
|
|
void mystery_gift_script::addvar(u16 var_id, u16 value)
|
|
{
|
|
value_buffer[0] = 0x17;
|
|
value_buffer[1] = var_id >> 0;
|
|
value_buffer[2] = var_id >> 8;
|
|
value_buffer[3] = value >> 0;
|
|
value_buffer[4] = value >> 8;
|
|
add_command(5);
|
|
}
|
|
|
|
void mystery_gift_script::call(u32 script_ptr)
|
|
{
|
|
value_buffer[0] = 0x04;
|
|
value_buffer[1] = script_ptr >> 0;
|
|
value_buffer[2] = script_ptr >> 8;
|
|
value_buffer[3] = script_ptr >> 16;
|
|
value_buffer[4] = script_ptr >> 24;
|
|
add_command(5);
|
|
}
|
|
|
|
void mystery_gift_script::compare(u16 var_id, u16 value)
|
|
{
|
|
value_buffer[0] = 0x21;
|
|
value_buffer[1] = var_id >> 0;
|
|
value_buffer[2] = var_id >> 8;
|
|
value_buffer[3] = value >> 0;
|
|
value_buffer[4] = value >> 8;
|
|
add_command(5);
|
|
}
|
|
|
|
void mystery_gift_script::setflag(u16 flag_id)
|
|
{
|
|
value_buffer[0] = 0x29;
|
|
value_buffer[1] = flag_id >> 0;
|
|
value_buffer[2] = flag_id >> 8;
|
|
add_command(3);
|
|
}
|
|
|
|
void mystery_gift_script::release()
|
|
{
|
|
value_buffer[0] = 0x6C;
|
|
add_command(1);
|
|
}
|
|
|
|
void mystery_gift_script::end()
|
|
{
|
|
value_buffer[0] = 0x02;
|
|
add_command(1);
|
|
}
|
|
|
|
void mystery_gift_script::init_npc_location(u8 bank, u8 map, u8 npc){
|
|
mg_script[0] = 0x33; // File ID?
|
|
mg_script[1] = bank;
|
|
mg_script[2] = map;
|
|
mg_script[3] = npc;
|
|
|
|
}
|