Skip to content

Instantly share code, notes, and snippets.

@Slattz
Created October 18, 2017 20:41
Show Gist options
  • Save Slattz/f0af3e317536aafc2fcab4ce737eeaf6 to your computer and use it in GitHub Desktop.
Save Slattz/f0af3e317536aafc2fcab4ce737eeaf6 to your computer and use it in GitHub Desktop.
ACNL Inventory Item Whitelist RE
/*
Reverse Engineering of ACNL's Inventory Whitelist by Slattz
Any hardcoded pointer offsets are based on EUR
Code.bin Offsets of functions below:
0x769864: CheckInventoryItemWhitelist
0x535908: ItemValidity
0x53589C: CheckIfValidItem
0x768DC4: CheckItemValidity
*/
//#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
typedef uint8_t u8; //< 8-bit unsigned integer
typedef uint16_t u16; //< 16-bit unsigned integer
typedef uint32_t u32; //< 32-bit unsigned integer
typedef uint64_t u64; //< 64-bit unsigned integer
int CheckItemValidity(u32 *invslot_addr)
{
/* Checks if the item is valid/obtainable.
It disregards wrapping paper as it has already bypassed this function. */
int result = 0;
u16 maxID = 0x172B; //Real Max ID is 0x372B but game takes 0x2000 from the item ID for these checks
u16 itemID = *(u16 *)invslot_addr; //Read itemID from specified Inventory Slot
itemID = itemID & ~0x8000;
u16 chk = itemID - 0x2000; //To cover items lower than 0x2000 (Enviroment Items)
if (chk < maxID) //If item passes this check, it's 'valid'
result = itemID - 0x2000;
if (chk >= maxID) //If item passes this check, it's 'invalid'
result = -1;
return result;
}
int CheckIfValidItem(u32 *invslot_addr)
{
int valid = CheckItemValidity(invslot_addr);
if (valid < 0) //If item is 'invalid'
return 0;
u32 point = *(u32 *)0xA18390;
if (point != 0)
{
u16 maxID = 0x172B;
if (valid <= maxID)
{
valid = (valid << 4) - valid;
valid = point + (valid << 1);
return valid;
}
}
else return 0;
}
int ItemValidity(u32 *invslot_addr)
{
int valid = CheckIfValidItem(invslot_addr);
if (valid == 0)
return 0;
u8 point = *(u8 *)(valid+0xA);
u32 point2 = *(u32 *)0xA183A0;
if (0x9B >= point)
point = 0;
if (point2 == 0)
return 0;
if (point < 0x9B)
{
point = point + (point << 1);
point = point + point2;
return point;
}
else return 0;
}
bool CheckInventoryItemWhitelist(u32 *invslot_addr)
{
u16 itemID = *(u16 *)invslot_addr;
itemID &= 0x6000;
if (itemID == 0x4000) //If item is wrapping paper / Any item ID between 0x4000 - 0x5FFF
goto ItemIsInventoryWhitelisted;
u32 offset = ItemValidity(invslot_addr);
if (offset == 0)
goto ItemNotInventoryWhitelisted;
u8 point = *(u8 *)(offset+1);
point = (point << 27);
point = (point >> 31);
ItemIsInventoryWhitelisted:
return 1;
ItemNotInventoryWhitelisted:
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment