mirror of
https://github.com/pret/pokediamond.git
synced 2024-10-07 11:13:24 +00:00
Merge pull request #521 from red031000/master
sync bag.c with heartgold
This commit is contained in:
commit
2f964cb953
5
Makefile
5
Makefile
@ -168,7 +168,7 @@ clean: mostlyclean clean-fs clean-tools
|
||||
clean-fs:
|
||||
$(RM) $(filter %.narc %.arc,$(HOSTFS_FILES))
|
||||
$(RM) $(patsubst %.narc,%.naix,$(patsubst %.arc,%.naix,$(filter %.narc %.arc,$(HOSTFS_FILES))))
|
||||
$(RM) $(NCGR_CLEAN_LIST) $(NCLR_CLEAN_LIST) $(NCER_CLEAN_LIST) $(FS_CLEAN_LIST)
|
||||
$(RM) $(NCGR_CLEAN_LIST) $(NCLR_CLEAN_LIST) $(NCER_CLEAN_LIST) $(NANR_CLEAN_LIST) $(FS_CLEAN_LIST)
|
||||
find . \( -iname '*.1bpp' -o -iname '*.4bpp' -o -iname '*.8bpp' -o -iname '*.gbapal' -o -iname '*.lz' \) -exec $(RM) {} +
|
||||
$(RM) files/msgdata/msg/narc_*.bin
|
||||
|
||||
@ -283,6 +283,9 @@ $(NCPR_NCLR_FILES): GFX_FLAGS = -ncpr
|
||||
%.NCER: %.json
|
||||
$(GFX) $< $@
|
||||
|
||||
%.NANR: %.json
|
||||
$(GFX) $< $@
|
||||
|
||||
%.NSCR: %_map.json
|
||||
$(GFX) $< $@ $(GFX_FLAGS)
|
||||
|
||||
|
@ -2096,7 +2096,7 @@ _020360EA:
|
||||
ldr r1, _0203627C ; =UNK_020F2A90
|
||||
add r0, r7, #0x0
|
||||
mov r2, #0xb
|
||||
bl CreateBagView
|
||||
bl Bag_CreateView
|
||||
mov r1, #0x7e
|
||||
lsl r1, r1, #0x2
|
||||
add r3, r5, #0x0
|
||||
@ -3141,7 +3141,7 @@ _020369C6:
|
||||
mov r1, #0x4
|
||||
add r2, sp, #0x8
|
||||
add r3, #0x1
|
||||
bl sub_0206F17C
|
||||
bl BagCursor_Field_PocketGetPosition
|
||||
mov r0, #0x7e
|
||||
add r2, sp, #0x8
|
||||
lsl r0, r0, #0x2
|
||||
@ -3188,7 +3188,7 @@ sub_02036A14: ; 0x02036A14
|
||||
ldrb r3, [r3, #0x1]
|
||||
ldr r0, [r0, #0x0]
|
||||
mov r1, #0x4
|
||||
bl sub_0206F190
|
||||
bl BagCursor_Field_PocketSetPosition
|
||||
mov r1, #0x7e
|
||||
lsl r1, r1, #0x2
|
||||
ldr r1, [r4, r1]
|
||||
|
@ -233,7 +233,7 @@ sub_02037400: ; 0x02037400
|
||||
mov r1, #0xb
|
||||
bl sub_02034A28
|
||||
mov r0, #0xb
|
||||
bl sub_0206F164
|
||||
bl BagCursor_New
|
||||
add r1, r4, #0x0
|
||||
add r1, #0x94
|
||||
str r0, [r1, #0x0]
|
||||
|
@ -267,7 +267,7 @@ sub_02037844: ; 0x02037844
|
||||
bl Save_Bag_Get
|
||||
ldr r1, _02037898 ; =UNK_020F2BDC
|
||||
mov r2, #0xb
|
||||
bl CreateBagView
|
||||
bl Bag_CreateView
|
||||
add r3, r5, #0x0
|
||||
add r3, #0x94
|
||||
ldr r1, [r5, #0xc]
|
||||
@ -328,7 +328,7 @@ _020378C8:
|
||||
add r0, r6, #0x0
|
||||
ldr r1, [r1, #0x0]
|
||||
mov r2, #0x20
|
||||
bl CreateBagView
|
||||
bl Bag_CreateView
|
||||
add r3, r5, #0x0
|
||||
add r3, #0x94
|
||||
ldr r1, [r5, #0xc]
|
||||
|
@ -46,7 +46,7 @@ sub_020889B0: ; 0x020889B0
|
||||
str r0, [r4, #0x0]
|
||||
str r5, [r4, #0x10]
|
||||
ldr r0, [r4, #0x0]
|
||||
bl sub_0206F164
|
||||
bl BagCursor_New
|
||||
str r0, [r4, #0xc]
|
||||
ldr r0, [r5, #0x4]
|
||||
cmp r0, #0x1
|
||||
|
@ -5024,22 +5024,22 @@
|
||||
.extern Bag_PocketNotEmpty
|
||||
.extern Bag_GetQuantity
|
||||
.extern Pocket_GetQuantity
|
||||
.extern CreateBagView
|
||||
.extern Bag_CreateView
|
||||
.extern Bag_GetPocketSlotN
|
||||
.extern Save_Bag_Get
|
||||
.extern sub_0206F164
|
||||
.extern sub_0206F17C
|
||||
.extern sub_0206F18C
|
||||
.extern sub_0206F190
|
||||
.extern sub_0206F19C
|
||||
.extern sub_0206F1A0
|
||||
.extern sub_0206F1AC
|
||||
.extern sub_0206F1B0
|
||||
.extern sub_0206F1B4
|
||||
.extern sub_0206F1B8
|
||||
.extern sub_0206F1C0
|
||||
.extern sub_0206F1E4
|
||||
.extern sub_0206F1EC
|
||||
.extern BagCursor_New
|
||||
.extern BagCursor_Field_PocketGetPosition
|
||||
.extern BagCursor_Field_GetPocket
|
||||
.extern BagCursor_Field_PocketSetPosition
|
||||
.extern BagCursor_Field_SetPocket
|
||||
.extern BagCursor_Battle_PocketGetPosition
|
||||
.extern BagCursor_Battle_GetLastUsedItem
|
||||
.extern BagCursor_Battle_GetLastUsedPocket
|
||||
.extern BagCursor_Battle_GetPocket
|
||||
.extern BagCursor_Battle_PocketSetPosition
|
||||
.extern BagCursor_Battle_Init
|
||||
.extern BagCursor_Battle_SetLastUsedItem
|
||||
.extern BagCursor_Battle_SetPocket
|
||||
.extern sub_0206F3B8
|
||||
.extern sub_0206F3D8
|
||||
.extern sub_0207008C
|
||||
|
@ -11163,7 +11163,7 @@ ov06_0223ECF0: ; 0x0223ECF0
|
||||
bl Save_Bag_Get
|
||||
ldr r1, _0223ED48 ; =0x0224F47C
|
||||
mov r2, #0xb
|
||||
bl CreateBagView
|
||||
bl Bag_CreateView
|
||||
add r3, r5, #0
|
||||
str r0, [r4, #4]
|
||||
add r3, #0x94
|
||||
|
@ -3808,7 +3808,7 @@ _02213CA8:
|
||||
bl ov11_02230218
|
||||
add r1, r4, #0
|
||||
add r2, r6, #0
|
||||
bl sub_0206F1E4
|
||||
bl BagCursor_Battle_SetLastUsedItem
|
||||
pop {r3, r4, r5, r6, r7, pc}
|
||||
|
||||
thumb_func_start ov09_02213CB8
|
||||
@ -12685,18 +12685,18 @@ _02218730:
|
||||
add r1, r5, #0
|
||||
add r2, r2, r5
|
||||
add r3, r3, r5
|
||||
bl sub_0206F1A0
|
||||
bl BagCursor_Battle_PocketGetPosition
|
||||
add r0, r5, #1
|
||||
lsl r0, r0, #0x18
|
||||
lsr r5, r0, #0x18
|
||||
cmp r5, #5
|
||||
blo _02218730
|
||||
add r0, r6, #0
|
||||
bl sub_0206F1AC
|
||||
bl BagCursor_Battle_GetLastUsedItem
|
||||
ldr r1, [r4]
|
||||
strh r0, [r1, #0x20]
|
||||
add r0, r6, #0
|
||||
bl sub_0206F1B0
|
||||
bl BagCursor_Battle_GetLastUsedPocket
|
||||
ldr r1, [r4]
|
||||
strb r0, [r1, #0x1f]
|
||||
add r0, r4, #0
|
||||
@ -12873,7 +12873,7 @@ ov09_02218888: ; 0x02218888
|
||||
ldr r0, [r4]
|
||||
ldr r0, [r0]
|
||||
bl ov11_02230218
|
||||
bl sub_0206F1B4
|
||||
bl BagCursor_Battle_GetPocket
|
||||
ldr r1, _02218950 ; =0x0000114D
|
||||
strb r0, [r4, r1]
|
||||
add r0, r4, #0
|
||||
@ -13687,7 +13687,7 @@ _02218F4E:
|
||||
ldrb r2, [r2]
|
||||
ldrb r3, [r3]
|
||||
add r1, r4, #0
|
||||
bl sub_0206F1B8
|
||||
bl BagCursor_Battle_PocketSetPosition
|
||||
add r0, r4, #1
|
||||
lsl r0, r0, #0x18
|
||||
lsr r4, r0, #0x18
|
||||
@ -13696,7 +13696,7 @@ _02218F4E:
|
||||
ldr r1, _02218F8C ; =0x0000114D
|
||||
add r0, r6, #0
|
||||
ldrb r1, [r5, r1]
|
||||
bl sub_0206F1EC
|
||||
bl BagCursor_Battle_SetPocket
|
||||
_02218F78:
|
||||
ldr r0, [r5]
|
||||
mov r1, #1
|
||||
@ -14300,7 +14300,7 @@ ov09_0221944C: ; 0x0221944C
|
||||
bl ov11_02230218
|
||||
add r1, r4, #0
|
||||
add r2, r6, #0
|
||||
bl sub_0206F1E4
|
||||
bl BagCursor_Battle_SetLastUsedItem
|
||||
pop {r3, r4, r5, r6, r7, pc}
|
||||
|
||||
thumb_func_start ov09_02219474
|
||||
|
@ -1039,7 +1039,7 @@ _0222DC42:
|
||||
bl ov11_0222FE94
|
||||
add r0, r4, #0
|
||||
bl ov11_02230218
|
||||
bl sub_0206F1C0
|
||||
bl BagCursor_Battle_Init
|
||||
mov r0, #5
|
||||
mov r1, #4
|
||||
mov r2, #0
|
||||
|
@ -4708,7 +4708,7 @@ _0223F598:
|
||||
bl ov11_02230218
|
||||
ldrh r1, [r6]
|
||||
ldrb r2, [r6, #2]
|
||||
bl sub_0206F1E4
|
||||
bl BagCursor_Battle_SetLastUsedItem
|
||||
_0223F5D2:
|
||||
ldrh r1, [r6]
|
||||
mov r0, #0x4a
|
||||
|
@ -5810,7 +5810,7 @@ _021DA41E:
|
||||
bl Save_Bag_Get
|
||||
ldr r1, _021DA5D8 ; =ov14_021E6264
|
||||
mov r2, #9
|
||||
bl CreateBagView
|
||||
bl Bag_CreateView
|
||||
mov r1, #0x85
|
||||
lsl r1, r1, #2
|
||||
str r0, [r4, r1]
|
||||
|
@ -1114,7 +1114,7 @@ _021E74AE:
|
||||
ldr r0, [r0, #0x6c]
|
||||
add r2, #1
|
||||
add r3, sp, #0
|
||||
bl sub_0206F17C
|
||||
bl BagCursor_Field_PocketGetPosition
|
||||
add r0, sp, #0
|
||||
ldrb r0, [r0, #1]
|
||||
cmp r0, #0
|
||||
@ -1139,7 +1139,7 @@ _021E74F2:
|
||||
add r0, #0xc4
|
||||
ldr r0, [r0]
|
||||
ldr r0, [r0, #0x6c]
|
||||
bl sub_0206F18C
|
||||
bl BagCursor_Field_GetPocket
|
||||
mov r1, #0
|
||||
mov r3, #0xc
|
||||
_021E7502:
|
||||
@ -1195,7 +1195,7 @@ _021E7540:
|
||||
ldr r0, [r0, #0x6c]
|
||||
lsr r2, r2, #0x18
|
||||
lsr r3, r3, #0x18
|
||||
bl sub_0206F190
|
||||
bl BagCursor_Field_PocketSetPosition
|
||||
add r4, r4, #1
|
||||
add r5, #0xc
|
||||
cmp r4, #8
|
||||
@ -1210,7 +1210,7 @@ _021E7568:
|
||||
mul r1, r2
|
||||
add r1, r7, r1
|
||||
ldrb r1, [r1, #8]
|
||||
bl sub_0206F19C
|
||||
bl BagCursor_Field_SetPocket
|
||||
_021E757E:
|
||||
pop {r3, r4, r5, r6, r7, pc}
|
||||
thumb_func_end ov75_021E752C
|
||||
|
682
arm9/src/bag.c
682
arm9/src/bag.c
@ -1,458 +1,420 @@
|
||||
#include "global.h"
|
||||
#include "constants/items.h"
|
||||
#include "MI_memory.h"
|
||||
#include "bag.h"
|
||||
#include "itemtool.h"
|
||||
#include "heap.h"
|
||||
|
||||
u32 Save_Bag_sizeof(void)
|
||||
{
|
||||
return sizeof(struct Bag);
|
||||
static u32 Bag_GetItemPocket(Bag *bag, u16 itemId, ItemSlot **itemSlots, u32 *countPtr, HeapID heapId);
|
||||
static ItemSlot *Pocket_GetItemSlotForAdd(ItemSlot *slots, u32 count, u16 itemId, u16 quantity, u16 maxQuantity);
|
||||
static ItemSlot *Bag_GetItemSlotForAdd(Bag *bag, u16 itemId, u16 quantity, HeapID heapId);
|
||||
static ItemSlot *Pocket_GetItemSlotForRemove(ItemSlot *slots, u32 count, u16 itemId, u16 quantity);
|
||||
static ItemSlot *Bag_GetItemSlotForRemove(Bag *bag, u16 itemId, u16 quantity, HeapID heapId);
|
||||
static void SwapItemSlots(ItemSlot *a, ItemSlot *b);
|
||||
static void PocketCompaction(ItemSlot *slots, u32 count);
|
||||
static void SortPocket(ItemSlot *slots, u32 count);
|
||||
|
||||
u32 Save_Bag_sizeof(void) {
|
||||
return sizeof(Bag);
|
||||
}
|
||||
|
||||
struct Bag * Save_Bag_New(HeapID heapId)
|
||||
{
|
||||
struct Bag * ret = (struct Bag *)AllocFromHeap(heapId, sizeof(struct Bag));
|
||||
Save_Bag_Init(ret);
|
||||
return ret;
|
||||
Bag *Save_Bag_New(HeapID heapId) {
|
||||
Bag *bag = (Bag *) AllocFromHeap(heapId, sizeof(Bag));
|
||||
Save_Bag_Init(bag);
|
||||
return bag;
|
||||
}
|
||||
|
||||
void Save_Bag_Init(struct Bag * bag)
|
||||
{
|
||||
MI_CpuClear16(bag, sizeof(struct Bag));
|
||||
void Save_Bag_Init(Bag *bag) {
|
||||
MI_CpuClear16(bag, sizeof(Bag));
|
||||
}
|
||||
|
||||
void Save_Bag_Copy(const struct Bag * src, struct Bag * dest)
|
||||
{
|
||||
MI_CpuCopy8(src, dest, sizeof(struct Bag));
|
||||
void Save_Bag_Copy(const Bag *src, Bag *dest) {
|
||||
MI_CpuCopy8(src, dest, sizeof(Bag));
|
||||
}
|
||||
|
||||
u32 Bag_GetRegisteredItem(struct Bag * bag)
|
||||
{
|
||||
u32 Bag_GetRegisteredItem(Bag *bag) {
|
||||
return bag->registeredItem;
|
||||
}
|
||||
|
||||
void Bag_SetRegisteredItem(struct Bag * bag, u32 item)
|
||||
{
|
||||
void Bag_SetRegisteredItem(Bag *bag, u32 item) {
|
||||
bag->registeredItem = item;
|
||||
}
|
||||
|
||||
u32 Bag_GetItemPocket(struct Bag * bag, u16 item_id, struct ItemSlot ** slot_p, u32 * count_p, HeapID heapId)
|
||||
{
|
||||
u32 pocket = GetItemAttr(item_id, 5, heapId);
|
||||
switch (pocket)
|
||||
{
|
||||
case POCKET_KEY_ITEMS:
|
||||
*slot_p = bag->keyItems;
|
||||
*count_p = NUM_BAG_KEY_ITEMS;
|
||||
break;
|
||||
case POCKET_ITEMS:
|
||||
*slot_p = bag->items;
|
||||
*count_p = NUM_BAG_ITEMS;
|
||||
break;
|
||||
case POCKET_BERRIES:
|
||||
*slot_p = bag->berries;
|
||||
*count_p = NUM_BAG_BERRIES;
|
||||
break;
|
||||
case POCKET_MEDICINE:
|
||||
*slot_p = bag->medicine;
|
||||
*count_p = NUM_BAG_MEDICINE;
|
||||
break;
|
||||
case POCKET_BALLS:
|
||||
*slot_p = bag->balls;
|
||||
*count_p = NUM_BAG_BALLS;
|
||||
break;
|
||||
case POCKET_BATTLE_ITEMS:
|
||||
*slot_p = bag->battleItems;
|
||||
*count_p = NUM_BAG_BATTLE_ITEMS;
|
||||
break;
|
||||
case POCKET_MAIL:
|
||||
*slot_p = bag->mail;
|
||||
*count_p = NUM_BAG_MAIL;
|
||||
break;
|
||||
case POCKET_TMHMS:
|
||||
*slot_p = bag->TMsHMs;
|
||||
*count_p = NUM_BAG_TMS_HMS;
|
||||
break;
|
||||
static u32 Bag_GetItemPocket(Bag *bag, u16 itemId, ItemSlot **itemSlots, u32 *countPtr, HeapID heapId) {
|
||||
u32 pocket = GetItemAttr(itemId, ITEMATTR_POCKET, heapId);
|
||||
switch (pocket) {
|
||||
case POCKET_KEY_ITEMS:
|
||||
*itemSlots = bag->keyItems;
|
||||
*countPtr = NUM_BAG_KEY_ITEMS;
|
||||
break;
|
||||
case POCKET_ITEMS:
|
||||
*itemSlots = bag->items;
|
||||
*countPtr = NUM_BAG_ITEMS;
|
||||
break;
|
||||
case POCKET_BERRIES:
|
||||
*itemSlots = bag->berries;
|
||||
*countPtr = NUM_BAG_BERRIES;
|
||||
break;
|
||||
case POCKET_MEDICINE:
|
||||
*itemSlots = bag->medicine;
|
||||
*countPtr = NUM_BAG_MEDICINE;
|
||||
break;
|
||||
case POCKET_BALLS:
|
||||
*itemSlots = bag->balls;
|
||||
*countPtr = NUM_BAG_BALLS;
|
||||
break;
|
||||
case POCKET_BATTLE_ITEMS:
|
||||
*itemSlots = bag->battleItems;
|
||||
*countPtr = NUM_BAG_BATTLE_ITEMS;
|
||||
break;
|
||||
case POCKET_MAIL:
|
||||
*itemSlots = bag->mail;
|
||||
*countPtr = NUM_BAG_MAIL;
|
||||
break;
|
||||
case POCKET_TMHMS:
|
||||
*itemSlots = bag->TMsHMs;
|
||||
*countPtr = NUM_BAG_TMS_HMS;
|
||||
break;
|
||||
}
|
||||
return pocket;
|
||||
}
|
||||
|
||||
struct ItemSlot * Pocket_GetItemSlotForAdd(struct ItemSlot * slots, u32 count, u16 item_id, u16 quantity, u16 maxquantity)
|
||||
{
|
||||
int i;
|
||||
int found = -1;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (slots[i].id == item_id)
|
||||
{
|
||||
if (quantity + slots[i].quantity > maxquantity)
|
||||
static ItemSlot *Pocket_GetItemSlotForAdd(ItemSlot *slots, u32 count, u16 itemId, u16 quantity, u16 maxQuantity) {
|
||||
s32 i;
|
||||
s32 found = -1;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (slots[i].id == itemId) {
|
||||
// Only one stack allowed per item.
|
||||
// If the resulting stack would be too large,
|
||||
// pretend there's no room for it.
|
||||
if (quantity + slots[i].quantity > maxQuantity) {
|
||||
return NULL;
|
||||
}
|
||||
return &slots[i];
|
||||
}
|
||||
if (found == -1 && slots[i].id == ITEM_NONE && slots[i].quantity == 0)
|
||||
{
|
||||
if (found == -1 && slots[i].id == ITEM_NONE && slots[i].quantity == 0) {
|
||||
found = i;
|
||||
}
|
||||
}
|
||||
if (found == -1)
|
||||
if (found == -1) {
|
||||
return NULL;
|
||||
}
|
||||
return &slots[found];
|
||||
}
|
||||
|
||||
struct ItemSlot * Bag_GetItemSlotForAdd(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId)
|
||||
{
|
||||
struct ItemSlot * slots;
|
||||
static ItemSlot *Bag_GetItemSlotForAdd(Bag *bag, u16 itemId, u16 quantity, HeapID heapId) {
|
||||
ItemSlot *slots;
|
||||
u32 count;
|
||||
u32 pocket = Bag_GetItemPocket(bag, item_id, &slots, &count, heapId);
|
||||
if (pocket == POCKET_TMHMS)
|
||||
{
|
||||
return Pocket_GetItemSlotForAdd(slots, count, item_id, quantity, 99);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Pocket_GetItemSlotForAdd(slots, count, item_id, quantity, 999);
|
||||
u32 pocket = Bag_GetItemPocket(bag, itemId, &slots, &count, heapId);
|
||||
if (pocket == POCKET_TMHMS) {
|
||||
return Pocket_GetItemSlotForAdd(slots, count, itemId, quantity, BAG_TMHM_QUANTITY_MAX);
|
||||
} else {
|
||||
return Pocket_GetItemSlotForAdd(slots, count, itemId, quantity, BAG_SLOT_QUANTITY_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL Bag_HasSpaceForItem(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId)
|
||||
{
|
||||
return Bag_GetItemSlotForAdd(bag, item_id, quantity, heapId) != NULL;
|
||||
BOOL Bag_HasSpaceForItem(Bag *bag, u16 itemId, u16 quantity, HeapID heapId) {
|
||||
return Bag_GetItemSlotForAdd(bag, itemId, quantity, heapId) != NULL;
|
||||
}
|
||||
|
||||
BOOL Bag_AddItem(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId)
|
||||
{
|
||||
struct ItemSlot * slots = Bag_GetItemSlotForAdd(bag, item_id, quantity, heapId);
|
||||
if (slots == NULL)
|
||||
BOOL Bag_AddItem(Bag *bag, u16 itemId, u16 quantity, HeapID heapId) {
|
||||
ItemSlot *slot = Bag_GetItemSlotForAdd(bag, itemId, quantity, heapId);
|
||||
if (slot == NULL) {
|
||||
return FALSE;
|
||||
slots->id = item_id;
|
||||
slots->quantity += quantity;
|
||||
}
|
||||
slot->id = itemId;
|
||||
slot->quantity += quantity;
|
||||
u32 count;
|
||||
u32 pocket = Bag_GetItemPocket(bag, item_id, &slots, &count, heapId);
|
||||
if (pocket == POCKET_TMHMS || pocket == POCKET_BERRIES)
|
||||
{
|
||||
SortPocket(slots, count);
|
||||
u32 pocket = Bag_GetItemPocket(bag, itemId, &slot, &count, heapId);
|
||||
if (pocket == POCKET_TMHMS || pocket == POCKET_BERRIES) {
|
||||
SortPocket(slot, count);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct ItemSlot * Pocket_GetItemSlotForRemove(struct ItemSlot * slots, u32 count, u16 item_id, u16 quantity)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (slots[i].id == item_id)
|
||||
{
|
||||
if (slots[i].quantity >= quantity)
|
||||
return &slots[i];
|
||||
return NULL;
|
||||
static ItemSlot *Pocket_GetItemSlotForRemove(ItemSlot *slots, u32 count, u16 itemId, u16 quantity) {
|
||||
for (s32 i = 0; i < count; i++) {
|
||||
if (slots[i].id == itemId) {
|
||||
if (slots[i].quantity < quantity) {
|
||||
return NULL;
|
||||
}
|
||||
return &slots[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ItemSlot * Bag_GetItemSlotForRemove(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId)
|
||||
{
|
||||
struct ItemSlot * slots;
|
||||
static ItemSlot *Bag_GetItemSlotForRemove(Bag *bag, u16 itemId, u16 quantity, HeapID heapId) {
|
||||
ItemSlot *slots;
|
||||
u32 count;
|
||||
(void)Bag_GetItemPocket(bag, item_id, &slots, &count, heapId);
|
||||
return Pocket_GetItemSlotForRemove(slots, count, item_id, quantity);
|
||||
Bag_GetItemPocket(bag, itemId, &slots, &count, heapId);
|
||||
return Pocket_GetItemSlotForRemove(slots, count, itemId, quantity);
|
||||
}
|
||||
|
||||
BOOL Bag_TakeItem(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId)
|
||||
{
|
||||
struct ItemSlot * slots = Bag_GetItemSlotForRemove(bag, item_id, quantity, heapId);
|
||||
if (slots == NULL)
|
||||
return FALSE;
|
||||
slots->quantity -= quantity;
|
||||
if (slots->quantity == 0)
|
||||
slots->id = ITEM_NONE;
|
||||
u32 count;
|
||||
(void)Bag_GetItemPocket(bag, item_id, &slots, &count, heapId);
|
||||
PocketCompaction(slots, count);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Pocket_TakeItem(struct ItemSlot * slots, u32 count, u16 item_id, u16 quantity)
|
||||
{
|
||||
struct ItemSlot * slot = Pocket_GetItemSlotForRemove(slots, count, item_id, quantity);
|
||||
if (slot == NULL)
|
||||
return FALSE;
|
||||
slot->quantity -= quantity;
|
||||
if (slot->quantity == 0)
|
||||
slot->id = ITEM_NONE;
|
||||
PocketCompaction(slots, count);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Bag_HasItem(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId)
|
||||
{
|
||||
return Bag_GetItemSlotForRemove(bag, item_id, quantity, heapId) != NULL;
|
||||
}
|
||||
|
||||
BOOL Bag_PocketNotEmpty(struct Bag * bag, u32 pocket)
|
||||
{
|
||||
struct ItemSlot * slots;
|
||||
u32 count;
|
||||
switch (pocket)
|
||||
{
|
||||
case POCKET_KEY_ITEMS:
|
||||
slots = bag->keyItems;
|
||||
count = NUM_BAG_KEY_ITEMS;
|
||||
break;
|
||||
case POCKET_ITEMS:
|
||||
slots = bag->items;
|
||||
count = NUM_BAG_ITEMS;
|
||||
break;
|
||||
case POCKET_BERRIES:
|
||||
slots = bag->berries;
|
||||
count = NUM_BAG_BERRIES;
|
||||
break;
|
||||
case POCKET_MEDICINE:
|
||||
slots = bag->medicine;
|
||||
count = NUM_BAG_MEDICINE;
|
||||
break;
|
||||
case POCKET_BALLS:
|
||||
slots = bag->balls;
|
||||
count = NUM_BAG_BALLS;
|
||||
break;
|
||||
case POCKET_BATTLE_ITEMS:
|
||||
slots = bag->battleItems;
|
||||
count = NUM_BAG_BATTLE_ITEMS;
|
||||
break;
|
||||
case POCKET_MAIL:
|
||||
slots = bag->mail;
|
||||
count = NUM_BAG_MAIL;
|
||||
break;
|
||||
case POCKET_TMHMS:
|
||||
slots = bag->TMsHMs;
|
||||
count = NUM_BAG_TMS_HMS;
|
||||
break;
|
||||
default:
|
||||
BOOL Bag_TakeItem(Bag *bag, u16 itemId, u16 quantity, HeapID heapId) {
|
||||
ItemSlot *slot = Bag_GetItemSlotForRemove(bag, itemId, quantity, heapId);
|
||||
if (slot == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (slots[i].id != ITEM_NONE)
|
||||
slot->quantity -= quantity;
|
||||
if (slot->quantity == 0) {
|
||||
slot->id = ITEM_NONE;
|
||||
}
|
||||
u32 count;
|
||||
Bag_GetItemPocket(bag, itemId, &slot, &count, heapId);
|
||||
PocketCompaction(slot, count);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Pocket_TakeItem(ItemSlot *slots, u32 count, u16 itemId, u16 quantity) {
|
||||
ItemSlot *slot = Pocket_GetItemSlotForRemove(slots, count, itemId, quantity);
|
||||
if (slot == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
slot->quantity -= quantity;
|
||||
if (slot->quantity == 0) {
|
||||
slot->id = ITEM_NONE;
|
||||
}
|
||||
PocketCompaction(slots, count);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Bag_HasItem(Bag *bag, u16 itemId, u16 quantity, HeapID heapId) {
|
||||
return Bag_GetItemSlotForRemove(bag, itemId, quantity, heapId) != NULL;
|
||||
}
|
||||
|
||||
BOOL Bag_PocketNotEmpty(Bag *bag, u32 pocket) {
|
||||
ItemSlot * slots;
|
||||
u32 count;
|
||||
switch (pocket) {
|
||||
case POCKET_KEY_ITEMS:
|
||||
slots = bag->keyItems;
|
||||
count = NUM_BAG_KEY_ITEMS;
|
||||
break;
|
||||
case POCKET_ITEMS:
|
||||
slots = bag->items;
|
||||
count = NUM_BAG_ITEMS;
|
||||
break;
|
||||
case POCKET_BERRIES:
|
||||
slots = bag->berries;
|
||||
count = NUM_BAG_BERRIES;
|
||||
break;
|
||||
case POCKET_MEDICINE:
|
||||
slots = bag->medicine;
|
||||
count = NUM_BAG_MEDICINE;
|
||||
break;
|
||||
case POCKET_BALLS:
|
||||
slots = bag->balls;
|
||||
count = NUM_BAG_BALLS;
|
||||
break;
|
||||
case POCKET_BATTLE_ITEMS:
|
||||
slots = bag->battleItems;
|
||||
count = NUM_BAG_BATTLE_ITEMS;
|
||||
break;
|
||||
case POCKET_MAIL:
|
||||
slots = bag->mail;
|
||||
count = NUM_BAG_MAIL;
|
||||
break;
|
||||
case POCKET_TMHMS:
|
||||
slots = bag->TMsHMs;
|
||||
count = NUM_BAG_TMS_HMS;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (s32 i = 0; i < count; i++) {
|
||||
if (slots[i].id != ITEM_NONE) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u16 Bag_GetQuantity(struct Bag * bag, u16 item_id, HeapID heapId)
|
||||
{
|
||||
struct ItemSlot * slot = Bag_GetItemSlotForRemove(bag, item_id, 1, heapId);
|
||||
if (slot == NULL)
|
||||
u16 Bag_GetQuantity(Bag *bag, u16 itemId, HeapID heapId) {
|
||||
ItemSlot *slot = Bag_GetItemSlotForRemove(bag, itemId, 1, heapId);
|
||||
if (slot == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return slot->quantity;
|
||||
}
|
||||
|
||||
u16 Pocket_GetQuantity(struct ItemSlot * slots, u32 count, u16 item_id)
|
||||
{
|
||||
struct ItemSlot * slot = Pocket_GetItemSlotForRemove(slots, count, item_id, 1);
|
||||
if (slot == NULL)
|
||||
u16 Pocket_GetQuantity(ItemSlot *slots, u32 count, u16 itemId) {
|
||||
ItemSlot *slot = Pocket_GetItemSlotForRemove(slots, count, itemId, 1);
|
||||
if (slot == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return slot->quantity;
|
||||
}
|
||||
|
||||
void SwapItemSlots(struct ItemSlot * a, struct ItemSlot * b)
|
||||
{
|
||||
struct ItemSlot tmp;
|
||||
|
||||
tmp = *a;
|
||||
static void SwapItemSlots(ItemSlot *a, ItemSlot *b) {
|
||||
ItemSlot c = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
*b = c;
|
||||
}
|
||||
|
||||
void PocketCompaction(struct ItemSlot * slots, u32 count)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < count - 1; i++)
|
||||
{
|
||||
for (j = i + 1; j < count; j++)
|
||||
{
|
||||
if (slots[i].quantity == 0)
|
||||
{
|
||||
static void PocketCompaction(ItemSlot *slots, u32 count) {
|
||||
for (s32 i = 0; i < count - 1; i++) {
|
||||
for (s32 j = i + 1; j < count; j++) {
|
||||
if (slots[i].quantity == 0) {
|
||||
SwapItemSlots(&slots[i], &slots[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SortPocket(struct ItemSlot * slots, u32 count)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < count - 1; i++)
|
||||
{
|
||||
for (j = i + 1; j < count; j++)
|
||||
{
|
||||
if (slots[i].quantity == 0 || (slots[j].quantity != 0 && slots[i].id > slots[j].id))
|
||||
{
|
||||
static void SortPocket(ItemSlot *slots, u32 count) {
|
||||
for (s32 i = 0; i < count - 1; i++) {
|
||||
for (s32 j = i + 1; j < count; j++) {
|
||||
if (slots[i].quantity == 0 || (slots[j].quantity != 0 && slots[i].id > slots[j].id)) {
|
||||
SwapItemSlots(&slots[i], &slots[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct BagView * CreateBagView(struct Bag * bag, const u8 * pockets, HeapID heapId)
|
||||
BagView *Bag_CreateView(Bag *bag, const u8 *pockets, HeapID heapId)
|
||||
{
|
||||
struct BagView * view = BagView_New((u8)heapId);
|
||||
BagView *ret = BagView_New(heapId);
|
||||
|
||||
for (u32 i = 0; pockets[i] != 0xFF; i++)
|
||||
{
|
||||
switch (pockets[i])
|
||||
{
|
||||
case POCKET_KEY_ITEMS:
|
||||
BagView_SetItem(view, bag->keyItems, POCKET_KEY_ITEMS, (u8)i);
|
||||
break;
|
||||
case POCKET_ITEMS:
|
||||
BagView_SetItem(view, bag->items, POCKET_ITEMS, (u8)i);
|
||||
break;
|
||||
case POCKET_BERRIES:
|
||||
BagView_SetItem(view, bag->berries, POCKET_BERRIES, (u8)i);
|
||||
break;
|
||||
case POCKET_MEDICINE:
|
||||
BagView_SetItem(view, bag->medicine, POCKET_MEDICINE, (u8)i);
|
||||
break;
|
||||
case POCKET_BALLS:
|
||||
BagView_SetItem(view, bag->balls, POCKET_BALLS, (u8)i);
|
||||
break;
|
||||
case POCKET_BATTLE_ITEMS:
|
||||
BagView_SetItem(view, bag->battleItems, POCKET_BATTLE_ITEMS, (u8)i);
|
||||
break;
|
||||
case POCKET_MAIL:
|
||||
BagView_SetItem(view, bag->mail, POCKET_MAIL, (u8)i);
|
||||
break;
|
||||
case POCKET_TMHMS:
|
||||
BagView_SetItem(view, bag->TMsHMs, POCKET_TMHMS, (u8)i);
|
||||
break;
|
||||
for (u32 i = 0; pockets[i] != POCKET_BAG_VIEW_END; i++) {
|
||||
switch (pockets[i]) {
|
||||
case POCKET_KEY_ITEMS:
|
||||
BagView_SetItem(ret, bag->keyItems, POCKET_KEY_ITEMS, i);
|
||||
break;
|
||||
case POCKET_ITEMS:
|
||||
BagView_SetItem(ret, bag->items, POCKET_ITEMS, i);
|
||||
break;
|
||||
case POCKET_BERRIES:
|
||||
BagView_SetItem(ret, bag->berries, POCKET_BERRIES, i);
|
||||
break;
|
||||
case POCKET_MEDICINE:
|
||||
BagView_SetItem(ret, bag->medicine, POCKET_MEDICINE, i);
|
||||
break;
|
||||
case POCKET_BALLS:
|
||||
BagView_SetItem(ret, bag->balls, POCKET_BALLS, i);
|
||||
break;
|
||||
case POCKET_BATTLE_ITEMS:
|
||||
BagView_SetItem(ret, bag->battleItems, POCKET_BATTLE_ITEMS, i);
|
||||
break;
|
||||
case POCKET_MAIL:
|
||||
BagView_SetItem(ret, bag->mail, POCKET_MAIL, i);
|
||||
break;
|
||||
case POCKET_TMHMS:
|
||||
BagView_SetItem(ret, bag->TMsHMs, POCKET_TMHMS, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
struct ItemSlot * Bag_GetPocketSlotN(struct Bag * bag, u32 pocket, u32 slot)
|
||||
{
|
||||
struct ItemSlot * slots;
|
||||
u32 count;
|
||||
switch (pocket)
|
||||
{
|
||||
case POCKET_KEY_ITEMS:
|
||||
slots = bag->keyItems;
|
||||
count = NUM_BAG_KEY_ITEMS;
|
||||
break;
|
||||
case POCKET_ITEMS:
|
||||
slots = bag->items;
|
||||
count = NUM_BAG_ITEMS;
|
||||
break;
|
||||
case POCKET_BERRIES:
|
||||
slots = bag->berries;
|
||||
count = NUM_BAG_BERRIES;
|
||||
break;
|
||||
case POCKET_MEDICINE:
|
||||
slots = bag->medicine;
|
||||
count = NUM_BAG_MEDICINE;
|
||||
break;
|
||||
case POCKET_BALLS:
|
||||
slots = bag->balls;
|
||||
count = NUM_BAG_BALLS;
|
||||
break;
|
||||
case POCKET_BATTLE_ITEMS:
|
||||
slots = bag->battleItems;
|
||||
count = NUM_BAG_BATTLE_ITEMS;
|
||||
break;
|
||||
case POCKET_MAIL:
|
||||
slots = bag->mail;
|
||||
count = NUM_BAG_MAIL;
|
||||
break;
|
||||
case POCKET_TMHMS:
|
||||
slots = bag->TMsHMs;
|
||||
count = NUM_BAG_TMS_HMS;
|
||||
break;
|
||||
}
|
||||
if (slot >= count)
|
||||
return NULL;
|
||||
return &slots[slot];
|
||||
}
|
||||
|
||||
struct Bag * Save_Bag_Get(struct SaveData * save)
|
||||
{
|
||||
return (struct Bag *)SaveArray_Get(save, 3);
|
||||
}
|
||||
|
||||
struct BagCursor * sub_0206F164(HeapID heapId)
|
||||
{
|
||||
struct BagCursor * ret = (struct BagCursor *)AllocFromHeap(heapId, sizeof(struct BagCursor));
|
||||
MI_CpuClear16(ret, sizeof(struct BagCursor));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sub_0206F17C(struct BagCursor * a0, u32 a1, u8 * a2, u8 * a3)
|
||||
{
|
||||
*a2 = a0->field.position[a1];
|
||||
*a3 = a0->field.scroll[a1];
|
||||
}
|
||||
ItemSlot *Bag_GetPocketSlotN(Bag *bag, u8 pocket, u32 slot) {
|
||||
ItemSlot *slots;
|
||||
u32 count;
|
||||
|
||||
u16 sub_0206F18C(struct BagCursor * a0)
|
||||
{
|
||||
return a0->field.pocket;
|
||||
}
|
||||
|
||||
void sub_0206F190(struct BagCursor * a0, u32 a1, u8 a2, u8 a3)
|
||||
{
|
||||
a0->field.position[a1] = a2;
|
||||
a0->field.scroll[a1] = a3;
|
||||
}
|
||||
|
||||
void sub_0206F19C(struct BagCursor * a0, u16 a1)
|
||||
{
|
||||
a0->field.pocket = a1;
|
||||
}
|
||||
|
||||
void sub_0206F1A0(struct BagCursor * a0, u32 a1, u8 * a2, u8 * a3)
|
||||
{
|
||||
*a2 = a0->battle.position[a1];
|
||||
*a3 = a0->battle.scroll[a1];
|
||||
}
|
||||
|
||||
u16 sub_0206F1AC(struct BagCursor * a0)
|
||||
{
|
||||
return a0->battle.lastUsedItem;
|
||||
}
|
||||
|
||||
u16 sub_0206F1B0(struct BagCursor * a0)
|
||||
{
|
||||
return a0->battle.lastUsedPocket;
|
||||
}
|
||||
|
||||
u16 sub_0206F1B4(struct BagCursor * a0)
|
||||
{
|
||||
return a0->battle.pocket;
|
||||
}
|
||||
|
||||
void sub_0206F1B8(struct BagCursor * a0, u32 a1, u8 a2, u8 a3)
|
||||
{
|
||||
a0->battle.position[a1] = a2;
|
||||
a0->battle.scroll[a1] = a3;
|
||||
}
|
||||
|
||||
void sub_0206F1C0(struct BagCursor * a0)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
sub_0206F1B8(a0, i, 0, 0);
|
||||
switch (pocket) {
|
||||
case POCKET_KEY_ITEMS:
|
||||
slots = bag->keyItems;
|
||||
count = NUM_BAG_KEY_ITEMS;
|
||||
break;
|
||||
case POCKET_ITEMS:
|
||||
slots = bag->items;
|
||||
count = NUM_BAG_ITEMS;
|
||||
break;
|
||||
case POCKET_BERRIES:
|
||||
slots = bag->berries;
|
||||
count = NUM_BAG_BERRIES;
|
||||
break;
|
||||
case POCKET_MEDICINE:
|
||||
slots = bag->medicine;
|
||||
count = NUM_BAG_MEDICINE;
|
||||
break;
|
||||
case POCKET_BALLS:
|
||||
slots = bag->balls;
|
||||
count = NUM_BAG_BALLS;
|
||||
break;
|
||||
case POCKET_BATTLE_ITEMS:
|
||||
slots = bag->battleItems;
|
||||
count = NUM_BAG_BATTLE_ITEMS;
|
||||
break;
|
||||
case POCKET_MAIL:
|
||||
slots = bag->mail;
|
||||
count = NUM_BAG_MAIL;
|
||||
break;
|
||||
case POCKET_TMHMS:
|
||||
slots = bag->TMsHMs;
|
||||
count = NUM_BAG_TMS_HMS;
|
||||
break;
|
||||
}
|
||||
sub_0206F1EC(a0, 0);
|
||||
// UB: If pocket invalid, count and slot are uninitialized
|
||||
if (slot >= count) {
|
||||
return NULL;
|
||||
}
|
||||
return &slots[slot];
|
||||
}
|
||||
|
||||
void sub_0206F1E4(struct BagCursor * a0, u16 a1, u16 a2)
|
||||
{
|
||||
a0->battle.lastUsedItem = a1;
|
||||
a0->battle.lastUsedPocket = a2;
|
||||
Bag *Save_Bag_Get(SaveData *saveData) {
|
||||
return SaveArray_Get(saveData, SAVE_BAG);
|
||||
}
|
||||
|
||||
void sub_0206F1EC(struct BagCursor * a0, u16 a1)
|
||||
{
|
||||
a0->battle.pocket = a1;
|
||||
BagCursor *BagCursor_New(HeapID heapId) {
|
||||
BagCursor *ret = AllocFromHeap(heapId, sizeof(BagCursor));
|
||||
MI_CpuClear16(ret, sizeof(BagCursor));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void BagCursor_Field_PocketGetPosition(BagCursor *cursor, u32 pocket, u8 *position, u8 *scroll) {
|
||||
*position = cursor->field.position[pocket];
|
||||
*scroll = cursor->field.scroll[pocket];
|
||||
}
|
||||
|
||||
u16 BagCursor_Field_GetPocket(BagCursor *cursor) {
|
||||
return cursor->field.pocket;
|
||||
}
|
||||
|
||||
void BagCursor_Field_PocketSetPosition(BagCursor *cursor, u32 pocket, u8 position, u8 scroll) {
|
||||
cursor->field.position[pocket] = position;
|
||||
cursor->field.scroll[pocket] = scroll;
|
||||
}
|
||||
|
||||
void BagCursor_Field_SetPocket(BagCursor *cursor, u16 pocket) {
|
||||
cursor->field.pocket = pocket;
|
||||
}
|
||||
|
||||
void BagCursor_Battle_PocketGetPosition(BagCursor *cursor, u32 pocket, u8 *position, u8 *scroll) {
|
||||
*position = cursor->battle.position[pocket];
|
||||
*scroll = cursor->battle.scroll[pocket];
|
||||
}
|
||||
|
||||
u16 BagCursor_Battle_GetLastUsedItem(BagCursor *cursor) {
|
||||
return cursor->battle.lastUsedItem;
|
||||
}
|
||||
|
||||
u16 BagCursor_Battle_GetLastUsedPocket(BagCursor *cursor) {
|
||||
return cursor->battle.lastUsedPocket;
|
||||
}
|
||||
|
||||
u16 BagCursor_Battle_GetPocket(BagCursor *cursor) {
|
||||
return cursor->battle.pocket;
|
||||
}
|
||||
|
||||
void BagCursor_Battle_PocketSetPosition(BagCursor *cursor, u32 pocket, u8 position, u8 scroll) {
|
||||
cursor->battle.position[pocket] = position;
|
||||
cursor->battle.scroll[pocket] = scroll;
|
||||
}
|
||||
|
||||
void BagCursor_Battle_Init(BagCursor *cursor) {
|
||||
for (u32 i = 0; i < 5; i++) {
|
||||
BagCursor_Battle_PocketSetPosition(cursor, i, 0, 0);
|
||||
}
|
||||
BagCursor_Battle_SetPocket(cursor, 0);
|
||||
}
|
||||
|
||||
void BagCursor_Battle_SetLastUsedItem(BagCursor *cursor, u16 itemId, u16 pocket) {
|
||||
cursor->battle.lastUsedItem = itemId;
|
||||
cursor->battle.lastUsedPocket = pocket;
|
||||
}
|
||||
|
||||
void BagCursor_Battle_SetPocket(BagCursor *cursor, u16 pocket) {
|
||||
cursor->battle.pocket = pocket;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "gx.h"
|
||||
#include "heap.h"
|
||||
|
||||
const u8 sTilemapWidthByBufferSize[] = {
|
||||
static const u8 sTilemapWidthByBufferSize[] = {
|
||||
[GF_BG_SCR_SIZE_128x128] = 0x10,
|
||||
[GF_BG_SCR_SIZE_256x256] = 0x20,
|
||||
[GF_BG_SCR_SIZE_256x512] = 0x20,
|
||||
|
@ -89,7 +89,7 @@ u32 sub_02088B4C(struct UnkStruct_02088AAC *r0)
|
||||
.exitFunc = ov75_021E6F00,
|
||||
.ovly = FS_OVERLAY_ID(OVERLAY_75)
|
||||
};
|
||||
struct BagView *bag_view = CreateBagView(r0->poffinCaseAppData->bag, UNK_020FD6F4, r0->heapId);
|
||||
struct BagView *bag_view = Bag_CreateView(r0->poffinCaseAppData->bag, UNK_020FD6F4, r0->heapId);
|
||||
|
||||
sub_0206E314(bag_view, r0->poffinCaseAppData->save, (u8)((u8)r0->unk06 == 1 ? 5 : 4), r0->unk0C);
|
||||
|
||||
@ -166,7 +166,7 @@ u32 sub_02088C3C(struct UnkStruct_02088AAC *r0)
|
||||
u8 sp5;
|
||||
u8 sp6;
|
||||
|
||||
sub_0206F17C(r0->unk0C, 4, &sp6, &sp5);
|
||||
BagCursor_Field_PocketGetPosition(r0->unk0C, 4, &sp6, &sp5);
|
||||
sub_020851F8(r0->ovly_param, sp5, sp6, (u8)(berry_count + 2));
|
||||
|
||||
r0->ovly_data = OverlayManager_New(&OVERLAY_68_MANAGER, (s32 *)r0->ovly_param, r0->heapId);
|
||||
@ -185,7 +185,7 @@ u32 sub_02088CDC(struct UnkStruct_02088AAC *r0)
|
||||
u8 sp1;
|
||||
|
||||
sub_0208524C(r0->ovly_param, &sp0, &sp1);
|
||||
sub_0206F190(r0->unk0C, 4, sp1, sp0);
|
||||
BagCursor_Field_PocketSetPosition(r0->unk0C, 4, sp1, sp0);
|
||||
FreeToHeap(r0->ovly_param);
|
||||
|
||||
r0->ovly_param = NULL;
|
||||
|
2
files/poketool/icongra/poke_icon/.gitignore
vendored
2
files/poketool/icongra/poke_icon/.gitignore
vendored
@ -1,4 +1,6 @@
|
||||
narc_0000.NCLR
|
||||
narc_0001.NANR
|
||||
narc_0003.NANR
|
||||
*.NCER
|
||||
narc_0007.NCGR
|
||||
narc_0008.NCGR
|
||||
|
Binary file not shown.
46
files/poketool/icongra/poke_icon/narc_0001.json
Normal file
46
files/poketool/icongra/poke_icon/narc_0001.json
Normal file
@ -0,0 +1,46 @@
|
||||
{
|
||||
"labelEnabled": true,
|
||||
"sequenceCount": 2,
|
||||
"frameCount": 2,
|
||||
"sequences": [
|
||||
{
|
||||
"frameCount": 1,
|
||||
"loopStartFrame": 0,
|
||||
"animationElement": 0,
|
||||
"animationType": 1,
|
||||
"playbackMode": 1,
|
||||
"frameData": [
|
||||
{
|
||||
"frameDelay": 1,
|
||||
"resultId": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"frameCount": 1,
|
||||
"loopStartFrame": 0,
|
||||
"animationElement": 0,
|
||||
"animationType": 1,
|
||||
"playbackMode": 1,
|
||||
"frameData": [
|
||||
{
|
||||
"frameDelay": 1,
|
||||
"resultId": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"animationResults": [
|
||||
{
|
||||
"resultType": 0,
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"resultType": 0,
|
||||
"index": 1
|
||||
}
|
||||
],
|
||||
"resultCount": 2,
|
||||
"labels": ["CellAnime0", "CellAnime1"],
|
||||
"labelCount": 2
|
||||
}
|
Binary file not shown.
140
files/poketool/icongra/poke_icon/narc_0003.json
Normal file
140
files/poketool/icongra/poke_icon/narc_0003.json
Normal file
@ -0,0 +1,140 @@
|
||||
{
|
||||
"labelEnabled": true,
|
||||
"sequenceCount": 6,
|
||||
"frameCount": 12,
|
||||
"sequences": [
|
||||
{
|
||||
"frameCount": 1,
|
||||
"loopStartFrame": 0,
|
||||
"animationElement": 0,
|
||||
"animationType": 1,
|
||||
"playbackMode": 1,
|
||||
"frameData": [
|
||||
{
|
||||
"frameDelay": 1,
|
||||
"resultId": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"frameCount": 2,
|
||||
"loopStartFrame": 0,
|
||||
"animationElement": 0,
|
||||
"animationType": 1,
|
||||
"playbackMode": 2,
|
||||
"frameData": [
|
||||
{
|
||||
"frameDelay": 4,
|
||||
"resultId": 0
|
||||
},
|
||||
{
|
||||
"frameDelay": 4,
|
||||
"resultId": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"frameCount": 2,
|
||||
"loopStartFrame": 0,
|
||||
"animationElement": 0,
|
||||
"animationType": 1,
|
||||
"playbackMode": 2,
|
||||
"frameData": [
|
||||
{
|
||||
"frameDelay": 6,
|
||||
"resultId": 0
|
||||
},
|
||||
{
|
||||
"frameDelay": 6,
|
||||
"resultId": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"frameCount": 2,
|
||||
"loopStartFrame": 0,
|
||||
"animationElement": 0,
|
||||
"animationType": 1,
|
||||
"playbackMode": 2,
|
||||
"frameData": [
|
||||
{
|
||||
"frameDelay": 12,
|
||||
"resultId": 0
|
||||
},
|
||||
{
|
||||
"frameDelay": 12,
|
||||
"resultId": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"frameCount": 2,
|
||||
"loopStartFrame": 0,
|
||||
"animationElement": 0,
|
||||
"animationType": 1,
|
||||
"playbackMode": 2,
|
||||
"frameData": [
|
||||
{
|
||||
"frameDelay": 20,
|
||||
"resultId": 0
|
||||
},
|
||||
{
|
||||
"frameDelay": 20,
|
||||
"resultId": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"frameCount": 3,
|
||||
"loopStartFrame": 0,
|
||||
"animationElement": 2,
|
||||
"animationType": 1,
|
||||
"playbackMode": 2,
|
||||
"frameData": [
|
||||
{
|
||||
"frameDelay": 32,
|
||||
"resultId": 2
|
||||
},
|
||||
{
|
||||
"frameDelay": 2,
|
||||
"resultId": 3
|
||||
},
|
||||
{
|
||||
"frameDelay": 2,
|
||||
"resultId": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"animationResults": [
|
||||
{
|
||||
"resultType": 0,
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"resultType": 0,
|
||||
"index": 1
|
||||
},
|
||||
{
|
||||
"resultType": 2,
|
||||
"index": 0,
|
||||
"positionX": 0,
|
||||
"positionY": 0
|
||||
},
|
||||
{
|
||||
"resultType": 2,
|
||||
"index": 0,
|
||||
"positionX": 1,
|
||||
"positionY": 0
|
||||
},
|
||||
{
|
||||
"resultType": 2,
|
||||
"index": 0,
|
||||
"positionX": -1,
|
||||
"positionY": 0
|
||||
}
|
||||
],
|
||||
"resultCount": 5,
|
||||
"labels": ["CellAnime0", "CellAnime1", "CellAnime2", "CellAnime3", "CellAnime4", "CellAnime5"],
|
||||
"labelCount": 6
|
||||
}
|
@ -2671,7 +2671,9 @@ files/poketool/pokegra/pokegra.narc: \
|
||||
|
||||
files/poketool/icongra/poke_icon.narc: \
|
||||
files/poketool/icongra/poke_icon/narc_0000.NCLR \
|
||||
files/poketool/icongra/poke_icon/narc_0001.NANR \
|
||||
files/poketool/icongra/poke_icon/narc_0002.NCER \
|
||||
files/poketool/icongra/poke_icon/narc_0003.NANR \
|
||||
files/poketool/icongra/poke_icon/narc_0004.NCER \
|
||||
files/poketool/icongra/poke_icon/narc_0006.NCER \
|
||||
files/poketool/icongra/poke_icon/narc_0007.NCGR \
|
||||
|
@ -1211,3 +1211,6 @@ NCLR_CLEAN_LIST := files/application/wifi_earth/wifi_earth/narc_0006.NCLR \
|
||||
NCER_CLEAN_LIST := files/poketool/icongra/poke_icon/narc_0002.NCER \
|
||||
files/poketool/icongra/poke_icon/narc_0004.NCER \
|
||||
files/poketool/icongra/poke_icon/narc_0006.NCER
|
||||
|
||||
NANR_CLEAN_LIST := files/poketool/icongra/poke_icon/narc_0001.NANR \
|
||||
files/poketool/icongra/poke_icon/narc_0003.NANR
|
||||
|
@ -7,54 +7,34 @@
|
||||
#include "save.h"
|
||||
|
||||
typedef struct Bag {
|
||||
struct ItemSlot items[NUM_BAG_ITEMS];
|
||||
struct ItemSlot keyItems[NUM_BAG_KEY_ITEMS];
|
||||
struct ItemSlot TMsHMs[NUM_BAG_TMS_HMS];
|
||||
struct ItemSlot mail[NUM_BAG_MAIL];
|
||||
struct ItemSlot medicine[NUM_BAG_MEDICINE];
|
||||
struct ItemSlot berries[NUM_BAG_BERRIES];
|
||||
struct ItemSlot balls[NUM_BAG_BALLS];
|
||||
struct ItemSlot battleItems[NUM_BAG_BATTLE_ITEMS];
|
||||
ItemSlot items[NUM_BAG_ITEMS];
|
||||
ItemSlot keyItems[NUM_BAG_KEY_ITEMS];
|
||||
ItemSlot TMsHMs[NUM_BAG_TMS_HMS];
|
||||
ItemSlot mail[NUM_BAG_MAIL];
|
||||
ItemSlot medicine[NUM_BAG_MEDICINE];
|
||||
ItemSlot berries[NUM_BAG_BERRIES];
|
||||
ItemSlot balls[NUM_BAG_BALLS];
|
||||
ItemSlot battleItems[NUM_BAG_BATTLE_ITEMS];
|
||||
u32 registeredItem;
|
||||
} Bag;
|
||||
|
||||
u32 Save_Bag_sizeof(void);
|
||||
struct Bag * Save_Bag_New(HeapID heapId);
|
||||
void Save_Bag_Init(struct Bag * bag);
|
||||
void Save_Bag_Copy(const struct Bag * src, struct Bag * dest);
|
||||
u32 Bag_GetRegisteredItem(struct Bag * bag);
|
||||
void Bag_SetRegisteredItem(struct Bag * bag, u32 item);
|
||||
u32 Bag_GetItemPocket(struct Bag * bag, u16 item_id, struct ItemSlot ** slot_p, u32 * count_p, HeapID heapId);
|
||||
struct ItemSlot * Pocket_GetItemSlotForAdd(struct ItemSlot * slots, u32 count, u16 item_id, u16 quantity, u16 maxquantity);
|
||||
struct ItemSlot * Bag_GetItemSlotForAdd(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId);
|
||||
BOOL Bag_HasSpaceForItem(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId);
|
||||
BOOL Bag_AddItem(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId);
|
||||
struct ItemSlot * Pocket_GetItemSlotForRemove(struct ItemSlot * slots, u32 count, u16 item_id, u16 quantity);
|
||||
struct ItemSlot * Bag_GetItemSlotForRemove(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId);
|
||||
BOOL Bag_TakeItem(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId);
|
||||
BOOL Pocket_TakeItem(struct ItemSlot * slots, u32 count, u16 item_id, u16 quantity);
|
||||
BOOL Bag_HasItem(struct Bag * bag, u16 item_id, u16 quantity, HeapID heapId);
|
||||
BOOL Bag_PocketNotEmpty(struct Bag * bag, u32 pocket);
|
||||
u16 Bag_GetQuantity(struct Bag * bag, u16 item_id, HeapID heapId);
|
||||
u16 Pocket_GetQuantity(struct ItemSlot * slots, u32 count, u16 item_id);
|
||||
void SwapItemSlots(struct ItemSlot * a, struct ItemSlot * b);
|
||||
void PocketCompaction(struct ItemSlot * slots, u32 count);
|
||||
void SortPocket(struct ItemSlot * slots, u32 count);
|
||||
struct BagView * CreateBagView(struct Bag * bag, const u8 * pockets, HeapID heapId);
|
||||
struct ItemSlot * Bag_GetPocketSlotN(struct Bag * bag, u32 pocket, u32 slot);
|
||||
struct Bag * Save_Bag_Get(struct SaveData * save);
|
||||
struct BagCursor * sub_0206F164(HeapID heapId);
|
||||
void sub_0206F17C(struct BagCursor * a0, u32 a1, u8 * a2, u8 * a3);
|
||||
u16 sub_0206F18C(struct BagCursor * a0);
|
||||
void sub_0206F190(struct BagCursor * a0, u32 a1, u8 a2, u8 a3);
|
||||
void sub_0206F19C(struct BagCursor * a0, u16 a1);
|
||||
void sub_0206F1A0(struct BagCursor * a0, u32 a1, u8 * a2, u8 * a3);
|
||||
u16 sub_0206F1AC(struct BagCursor * a0);
|
||||
u16 sub_0206F1B0(struct BagCursor * a0);
|
||||
u16 sub_0206F1B4(struct BagCursor * a0);
|
||||
void sub_0206F1B8(struct BagCursor * a0, u32 a1, u8 a2, u8 a3);
|
||||
void sub_0206F1C0(struct BagCursor * a0);
|
||||
void sub_0206F1E4(struct BagCursor * a0, u16 a1, u16 a2);
|
||||
void sub_0206F1EC(struct BagCursor * a0, u16 a1);
|
||||
Bag *Save_Bag_New(HeapID heapId);
|
||||
void Save_Bag_Init(Bag *bag);
|
||||
void Save_Bag_Copy(const Bag *src, Bag *dest);
|
||||
u32 Bag_GetRegisteredItem(Bag *bag);
|
||||
void Bag_SetRegisteredItem(Bag *bag, u32 item);
|
||||
BOOL Bag_HasSpaceForItem(Bag *bag, u16 itemId, u16 quantity, HeapID heapId);
|
||||
BOOL Bag_AddItem(Bag *bag, u16 itemId, u16 quantity, HeapID heapId);
|
||||
BOOL Bag_TakeItem(Bag *bag, u16 itemId, u16 quantity, HeapID heapId);
|
||||
BOOL Pocket_TakeItem(ItemSlot *slots, u32 count, u16 itemId, u16 quantity);
|
||||
BOOL Bag_HasItem(Bag *bag, u16 itemId, u16 quantity, HeapID heapId);
|
||||
BOOL Bag_PocketNotEmpty(Bag *bag, u32 pocket);
|
||||
u16 Bag_GetQuantity(Bag *bag, u16 itemId, HeapID heapId);
|
||||
u16 Pocket_GetQuantity(ItemSlot *slots, u32 count, u16 itemId);
|
||||
void SortPocket(ItemSlot *slots, u32 count);
|
||||
BagView * Bag_CreateView(Bag *bag, const u8 *pockets, HeapID heapId);
|
||||
ItemSlot *Bag_GetPocketSlotN(Bag *bag, u8 pocket, u32 slot);
|
||||
Bag *Save_Bag_Get(SaveData *saveData);
|
||||
|
||||
#endif //POKEDIAMOND_BAG_H
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define POKEDIAMOND_BAG_CURSOR_H
|
||||
|
||||
#include "global.h"
|
||||
#include "heap.h"
|
||||
|
||||
typedef struct BagCursorField {
|
||||
u8 scroll[8];
|
||||
@ -23,4 +24,18 @@ typedef struct BagCursor {
|
||||
BagCursorBattle battle;
|
||||
} BagCursor;
|
||||
|
||||
BagCursor *BagCursor_New(HeapID heapId);
|
||||
void BagCursor_Field_PocketGetPosition(BagCursor *cursor, u32 pocket, u8 *position, u8 *scroll);
|
||||
u16 BagCursor_Field_GetPocket(BagCursor *cursor);
|
||||
void BagCursor_Field_PocketSetPosition(BagCursor *cursor, u32 pocket, u8 position, u8 scroll);
|
||||
void BagCursor_Field_SetPocket(BagCursor *cursor, u16 pocket);
|
||||
void BagCursor_Battle_PocketGetPosition(BagCursor *cursor, u32 pocket, u8 *position, u8 *scroll);
|
||||
u16 BagCursor_Battle_GetLastUsedItem(BagCursor *cursor);
|
||||
u16 BagCursor_Battle_GetLastUsedPocket(BagCursor *cursor);
|
||||
u16 BagCursor_Battle_GetPocket(BagCursor *cursor);
|
||||
void BagCursor_Battle_PocketSetPosition(BagCursor *cursor, u32 pocket, u8 position, u8 scroll);
|
||||
void BagCursor_Battle_Init(BagCursor *cursor);
|
||||
void BagCursor_Battle_SetLastUsedItem(BagCursor *cursor, u16 itemId, u16 pocket);
|
||||
void BagCursor_Battle_SetPocket(BagCursor *cursor, u16 pocket);
|
||||
|
||||
#endif // POKEDIAMOND_BAG_CURSOR_H
|
||||
|
@ -10,6 +10,8 @@
|
||||
#define POCKET_BATTLE_ITEMS 6
|
||||
#define POCKET_KEY_ITEMS 7
|
||||
|
||||
#define POCKET_BAG_VIEW_END 0xFF
|
||||
|
||||
#define NUM_BAG_ITEMS 165
|
||||
#define NUM_BAG_KEY_ITEMS 50
|
||||
#define NUM_BAG_TMS_HMS 100
|
||||
@ -19,6 +21,9 @@
|
||||
#define NUM_BAG_BALLS 15
|
||||
#define NUM_BAG_BATTLE_ITEMS 30
|
||||
|
||||
#define BAG_SLOT_QUANTITY_MAX 999
|
||||
#define BAG_TMHM_QUANTITY_MAX 99
|
||||
|
||||
#define ITEMATTR_PRICE 0
|
||||
#define ITEMATTR_HOLD_EFFECT 1
|
||||
#define ITEMATTR_HOLD_EFFECT_PARAM 2
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef POKEDIAMOND_CONSTANTS_SAVE_ARRAYS_H
|
||||
#define POKEDIAMOND_CONSTANTS_SAVE_ARRAYS_H
|
||||
|
||||
#define SAVE_BAG 3
|
||||
#define SAVE_SAFARI_ZONE 27
|
||||
#define SAVE_BLOCK_NUM 36
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2015 YamaArashi
|
||||
Copyright (c) 2015 YamaArashi, 2021-2023 red031000
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -19,7 +19,7 @@ all: nitrogfx
|
||||
@:
|
||||
|
||||
nitrogfx-debug: $(SRCS) convert_png.h gfx.h global.h jasc_pal.h lz.h rl.h util.h font.h json.h cJSON.h
|
||||
$(CC) $(CFLAGS) -DDEBUG $(SRCS) -o $@ $(LDFLAGS) $(LIBS)
|
||||
$(CC) $(CFLAGS) -g -DDEBUG $(SRCS) -o $@ $(LDFLAGS) $(LIBS)
|
||||
|
||||
nitrogfx: $(SRCS) convert_png.h gfx.h global.h jasc_pal.h lz.h rl.h util.h font.h json.h cJSON.h
|
||||
$(CC) $(CFLAGS) $(SRCS) -o $@ $(LDFLAGS) $(LIBS)
|
||||
|
@ -96,9 +96,9 @@ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
|
||||
return (const char*) (global_error.json + global_error.position);
|
||||
}
|
||||
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
|
||||
{
|
||||
if (!cJSON_IsString(item))
|
||||
if (!cJSON_IsString(item))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@ -106,9 +106,9 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
|
||||
return item->valuestring;
|
||||
}
|
||||
|
||||
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
|
||||
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
|
||||
{
|
||||
if (!cJSON_IsNumber(item))
|
||||
if (!cJSON_IsNumber(item))
|
||||
{
|
||||
return (double) NAN;
|
||||
}
|
||||
@ -117,8 +117,8 @@ CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
|
||||
}
|
||||
|
||||
/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
|
||||
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 14)
|
||||
#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
|
||||
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 15)
|
||||
#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
|
||||
#endif
|
||||
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void)
|
||||
@ -347,7 +347,7 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu
|
||||
goto loop_end;
|
||||
}
|
||||
}
|
||||
loop_end:
|
||||
loop_end:
|
||||
number_c_string[i] = '\0';
|
||||
|
||||
number = strtod((const char*)number_c_string, (char**)&after_end);
|
||||
@ -511,7 +511,7 @@ static unsigned char* ensure(printbuffer * const p, size_t needed)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
memcpy(newbuffer, p->buffer, p->offset + 1);
|
||||
p->hooks.deallocate(p->buffer);
|
||||
}
|
||||
@ -761,7 +761,7 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi
|
||||
|
||||
return sequence_length;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -820,7 +820,7 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu
|
||||
{
|
||||
*output_pointer++ = *input_pointer++;
|
||||
}
|
||||
/* escape sequence */
|
||||
/* escape sequence */
|
||||
else
|
||||
{
|
||||
unsigned char sequence_length = 2;
|
||||
@ -852,7 +852,7 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu
|
||||
*output_pointer++ = input_pointer[1];
|
||||
break;
|
||||
|
||||
/* UTF-16 literal */
|
||||
/* UTF-16 literal */
|
||||
case 'u':
|
||||
sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
|
||||
if (sequence_length == 0)
|
||||
@ -880,7 +880,7 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
if (output != NULL)
|
||||
{
|
||||
input_buffer->hooks.deallocate(output);
|
||||
@ -1045,7 +1045,7 @@ static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
|
||||
|
||||
while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
|
||||
{
|
||||
buffer->offset++;
|
||||
buffer->offset++;
|
||||
}
|
||||
|
||||
if (buffer->offset == buffer->length)
|
||||
@ -1103,7 +1103,7 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer
|
||||
}
|
||||
|
||||
buffer.content = (const unsigned char*)value;
|
||||
buffer.length = buffer_length;
|
||||
buffer.length = buffer_length;
|
||||
buffer.offset = 0;
|
||||
buffer.hooks = global_hooks;
|
||||
|
||||
@ -1135,7 +1135,7 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer
|
||||
|
||||
return item;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
if (item != NULL)
|
||||
{
|
||||
cJSON_Delete(item);
|
||||
@ -1230,7 +1230,7 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
|
||||
|
||||
return printed;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
if (buffer->buffer != NULL)
|
||||
{
|
||||
hooks->deallocate(buffer->buffer);
|
||||
@ -1508,7 +1508,7 @@ static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buf
|
||||
goto fail; /* expected end of array */
|
||||
}
|
||||
|
||||
success:
|
||||
success:
|
||||
input_buffer->depth--;
|
||||
|
||||
if (head != NULL) {
|
||||
@ -1522,7 +1522,7 @@ static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buf
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
if (head != NULL)
|
||||
{
|
||||
cJSON_Delete(head);
|
||||
@ -1684,7 +1684,7 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu
|
||||
goto fail; /* expected end of object */
|
||||
}
|
||||
|
||||
success:
|
||||
success:
|
||||
input_buffer->depth--;
|
||||
|
||||
if (head != NULL) {
|
||||
@ -1697,7 +1697,7 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu
|
||||
input_buffer->offset++;
|
||||
return true;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
if (head != NULL)
|
||||
{
|
||||
cJSON_Delete(head);
|
||||
@ -1989,7 +1989,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item)
|
||||
}
|
||||
|
||||
#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
@ -2000,7 +2000,7 @@ static void* cast_away_const(const void* string)
|
||||
return (void*)string;
|
||||
}
|
||||
#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
|
||||
#pragma GCC diagnostic pop
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
@ -2689,7 +2689,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int co
|
||||
if (a && a->child) {
|
||||
a->child->prev = n;
|
||||
}
|
||||
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
@ -2768,7 +2768,7 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
|
||||
|
||||
return newitem;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
if (newitem != NULL)
|
||||
{
|
||||
cJSON_Delete(newitem);
|
||||
@ -2976,7 +2976,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
|
||||
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
|
||||
{
|
||||
if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
|
||||
if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 14
|
||||
#define CJSON_VERSION_PATCH 15
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
@ -124,9 +124,9 @@ typedef struct cJSON
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
@ -255,8 +255,8 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
||||
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||
* but should point to a readable and writable adress area. */
|
||||
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||
* but should point to a readable and writable address area. */
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015 YamaArashi
|
||||
// Copyright (c) 2015 YamaArashi, 2021-2023 red031000
|
||||
|
||||
#ifndef GFX_H
|
||||
#define GFX_H
|
||||
@ -30,10 +30,10 @@ struct Image {
|
||||
};
|
||||
|
||||
void ReadImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors);
|
||||
uint32_t ReadNtrImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors);
|
||||
uint32_t ReadNtrImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors, bool scanFrontToBack);
|
||||
void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors);
|
||||
void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image,
|
||||
bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc, bool scanned,
|
||||
bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc, uint32_t scanMode,
|
||||
uint32_t key, bool wrongSize);
|
||||
void FreeImage(struct Image *image);
|
||||
void ReadGbaPalette(char *path, struct Palette *palette);
|
||||
@ -41,6 +41,7 @@ void ReadNtrPalette(char *path, struct Palette *palette, int bitdepth, int palIn
|
||||
void WriteGbaPalette(char *path, struct Palette *palette);
|
||||
void WriteNtrPalette(char *path, struct Palette *palette, bool ncpr, bool ir, int bitdepth, bool pad, int compNum);
|
||||
void WriteNtrCell(char *path, struct JsonToCellOptions *options);
|
||||
void WriteNtrScreen(char *outputPath, struct JsonToScreenOptions *options);
|
||||
void WriteNtrScreen(char *path, struct JsonToScreenOptions *options);
|
||||
void WriteNtrAnimation(char *path, struct JsonToAnimationOptions *options);
|
||||
|
||||
#endif // GFX_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2021 red031000
|
||||
// Copyright (c) 2021-2023 red031000
|
||||
|
||||
#include "global.h"
|
||||
#include "cJSON.h"
|
||||
@ -230,6 +230,176 @@ struct JsonToScreenOptions *ParseNSCRJson(char *path)
|
||||
return options;
|
||||
}
|
||||
|
||||
struct JsonToAnimationOptions *ParseNANRJson(char *path)
|
||||
{
|
||||
int filelength;
|
||||
unsigned char *jsonString = ReadWholeFile(path, &filelength);
|
||||
|
||||
cJSON *json = cJSON_Parse((const char *)jsonString);
|
||||
|
||||
struct JsonToAnimationOptions *options = malloc(sizeof(struct JsonToAnimationOptions));
|
||||
|
||||
if (json == NULL)
|
||||
{
|
||||
const char *errorPtr = cJSON_GetErrorPtr();
|
||||
FATAL_ERROR("Error in line \"%s\"\n", errorPtr);
|
||||
}
|
||||
|
||||
cJSON *sequenceCount = cJSON_GetObjectItemCaseSensitive(json, "sequenceCount");
|
||||
cJSON *frameCount = cJSON_GetObjectItemCaseSensitive(json, "frameCount");
|
||||
|
||||
options->sequenceCount = GetInt(sequenceCount);
|
||||
options->frameCount = GetInt(frameCount);
|
||||
|
||||
options->sequenceData = malloc(sizeof(struct SequenceData *) * options->sequenceCount);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < options->sequenceCount; i++)
|
||||
{
|
||||
options->sequenceData[i] = malloc(sizeof(struct SequenceData));
|
||||
}
|
||||
|
||||
cJSON *sequence = NULL;
|
||||
cJSON *sequences = cJSON_GetObjectItemCaseSensitive(json, "sequences");
|
||||
|
||||
i = 0;
|
||||
cJSON_ArrayForEach(sequence, sequences)
|
||||
{
|
||||
if (i > options->sequenceCount - 1)
|
||||
FATAL_ERROR("Sequence count is incorrect.\n");
|
||||
|
||||
cJSON *frameCount = cJSON_GetObjectItemCaseSensitive(sequence, "frameCount");
|
||||
cJSON *loopStartFrame = cJSON_GetObjectItemCaseSensitive(sequence, "loopStartFrame");
|
||||
cJSON *animationElement = cJSON_GetObjectItemCaseSensitive(sequence, "animationElement");
|
||||
cJSON *animationType = cJSON_GetObjectItemCaseSensitive(sequence, "animationType");
|
||||
cJSON *playbackMode = cJSON_GetObjectItemCaseSensitive(sequence, "playbackMode");
|
||||
|
||||
options->sequenceData[i]->frameCount = GetInt(frameCount);
|
||||
options->sequenceData[i]->loopStartFrame = GetInt(loopStartFrame);
|
||||
options->sequenceData[i]->animationElement = GetInt(animationElement);
|
||||
options->sequenceData[i]->animationType = GetInt(animationType);
|
||||
options->sequenceData[i]->playbackMode = GetInt(playbackMode);
|
||||
|
||||
options->sequenceData[i]->frameData = malloc(sizeof(struct FrameData *) * options->sequenceData[i]->frameCount);
|
||||
int j;
|
||||
for (j = 0; j < options->sequenceData[i]->frameCount; j++)
|
||||
{
|
||||
options->sequenceData[i]->frameData[j] = malloc(sizeof(struct FrameData));
|
||||
}
|
||||
|
||||
j = 0;
|
||||
cJSON *frame = NULL;
|
||||
cJSON *frameData = cJSON_GetObjectItemCaseSensitive(sequence, "frameData");
|
||||
|
||||
cJSON_ArrayForEach(frame, frameData)
|
||||
{
|
||||
if (j > options->sequenceData[i]->frameCount - 1)
|
||||
FATAL_ERROR("Sequence frame count is incorrect.\n");
|
||||
|
||||
cJSON *frameDelay = cJSON_GetObjectItemCaseSensitive(frame, "frameDelay");
|
||||
cJSON *resultId = cJSON_GetObjectItemCaseSensitive(frame, "resultId");
|
||||
|
||||
options->sequenceData[i]->frameData[j]->frameDelay = GetInt(frameDelay);
|
||||
options->sequenceData[i]->frameData[j]->resultId = GetInt(resultId);
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
//todo implement extended attributes
|
||||
|
||||
cJSON *resultCount = cJSON_GetObjectItemCaseSensitive(json, "resultCount");
|
||||
|
||||
options->resultCount = GetInt(resultCount);
|
||||
|
||||
options->animationResults = malloc(sizeof(struct AnimationResults *) * options->resultCount);
|
||||
|
||||
for (i = 0; i < options->resultCount; i++)
|
||||
{
|
||||
options->animationResults[i] = malloc(sizeof(struct AnimationResults));
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
cJSON *animationResult = NULL;
|
||||
cJSON *animationResults = cJSON_GetObjectItemCaseSensitive(json, "animationResults");
|
||||
cJSON_ArrayForEach(animationResult, animationResults)
|
||||
{
|
||||
if (i > options->resultCount - 1)
|
||||
FATAL_ERROR("Frame count is incorrect.\n");
|
||||
|
||||
cJSON *resultType = cJSON_GetObjectItemCaseSensitive(animationResult, "resultType");
|
||||
options->animationResults[i]->resultType = GetInt(resultType);
|
||||
switch (options->animationResults[i]->resultType) {
|
||||
case 0: { //index
|
||||
cJSON *index = cJSON_GetObjectItemCaseSensitive(animationResult, "index");
|
||||
options->animationResults[i]->index = GetInt(index);
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: { //SRT
|
||||
cJSON *index = cJSON_GetObjectItemCaseSensitive(animationResult, "index");
|
||||
cJSON *rotation = cJSON_GetObjectItemCaseSensitive(animationResult, "rotation");
|
||||
cJSON *scaleX = cJSON_GetObjectItemCaseSensitive(animationResult, "scaleX");
|
||||
cJSON *scaleY = cJSON_GetObjectItemCaseSensitive(animationResult, "scaleY");
|
||||
cJSON *positionX = cJSON_GetObjectItemCaseSensitive(animationResult, "positionX");
|
||||
cJSON *positionY = cJSON_GetObjectItemCaseSensitive(animationResult, "positionY");
|
||||
|
||||
options->animationResults[i]->dataSrt.index = GetInt(index);
|
||||
options->animationResults[i]->dataSrt.rotation = GetInt(rotation);
|
||||
options->animationResults[i]->dataSrt.scaleX = GetInt(scaleX);
|
||||
options->animationResults[i]->dataSrt.scaleY = GetInt(scaleY);
|
||||
options->animationResults[i]->dataSrt.positionX = GetInt(positionX);
|
||||
options->animationResults[i]->dataSrt.positionY = GetInt(positionY);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: { //T
|
||||
cJSON *index = cJSON_GetObjectItemCaseSensitive(animationResult, "index");
|
||||
//cJSON *rotation = cJSON_GetObjectItemCaseSensitive(animationResult, "rotation");
|
||||
cJSON *positionX = cJSON_GetObjectItemCaseSensitive(animationResult, "positionX");
|
||||
cJSON *positionY = cJSON_GetObjectItemCaseSensitive(animationResult, "positionY");
|
||||
|
||||
options->animationResults[i]->dataT.index = GetInt(index);
|
||||
//options->animationResults[i]->dataSrt.rotation = GetInt(rotation);
|
||||
options->animationResults[i]->dataT.positionX = GetInt(positionX);
|
||||
options->animationResults[i]->dataT.positionY = GetInt(positionY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
cJSON *labelBool = cJSON_GetObjectItemCaseSensitive(json, "labelEnabled");
|
||||
options->labelEnabled = GetBool(labelBool);
|
||||
|
||||
if (options->labelEnabled)
|
||||
{
|
||||
cJSON *labelCount = cJSON_GetObjectItemCaseSensitive(json, "labelCount");
|
||||
options->labelCount = GetInt(labelCount);
|
||||
options->labels = malloc(sizeof(char *) * options->labelCount);
|
||||
|
||||
cJSON *labels = cJSON_GetObjectItemCaseSensitive(json, "labels");
|
||||
cJSON *label = NULL;
|
||||
|
||||
int j = 0;
|
||||
cJSON_ArrayForEach(label, labels)
|
||||
{
|
||||
char *labelString = GetString(label);
|
||||
options->labels[j] = malloc(strlen(labelString) + 1);
|
||||
strcpy(options->labels[j], labelString);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
cJSON_Delete(json);
|
||||
free(jsonString);
|
||||
return options;
|
||||
}
|
||||
|
||||
void FreeNCERCell(struct JsonToCellOptions *options)
|
||||
{
|
||||
for (int i = 0; i < options->cellCount; i++)
|
||||
@ -244,6 +414,7 @@ void FreeNCERCell(struct JsonToCellOptions *options)
|
||||
}
|
||||
free(options->labels);
|
||||
}
|
||||
free(options->cells);
|
||||
free(options);
|
||||
}
|
||||
|
||||
@ -253,3 +424,31 @@ void FreeNSCRScreen(struct JsonToScreenOptions *options)
|
||||
free(options);
|
||||
}
|
||||
|
||||
|
||||
void FreeNANRAnimation(struct JsonToAnimationOptions *options)
|
||||
{
|
||||
for (int i = 0; i < options->sequenceCount; i++)
|
||||
{
|
||||
for (int j = 0; j < options->sequenceData[i]->frameCount; j++)
|
||||
{
|
||||
free(options->sequenceData[i]->frameData[j]);
|
||||
}
|
||||
free(options->sequenceData[i]->frameData);
|
||||
free(options->sequenceData[i]);
|
||||
}
|
||||
for (int i = 0; i < options->resultCount; i++)
|
||||
{
|
||||
free(options->animationResults[i]);
|
||||
}
|
||||
if (options->labelEnabled)
|
||||
{
|
||||
for (int j = 0; j < options->labelCount; j++)
|
||||
{
|
||||
free(options->labels[j]);
|
||||
}
|
||||
free(options->labels);
|
||||
}
|
||||
free(options->sequenceData);
|
||||
free(options->animationResults);
|
||||
free(options);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2021 red031000
|
||||
// Copyright (c) 2021-2023 red031000
|
||||
|
||||
#ifndef JSON_H
|
||||
#define JSON_H
|
||||
@ -7,7 +7,9 @@
|
||||
|
||||
struct JsonToCellOptions *ParseNCERJson(char *path);
|
||||
struct JsonToScreenOptions *ParseNSCRJson(char *path);
|
||||
struct JsonToAnimationOptions *ParseNANRJson(char *path);
|
||||
void FreeNCERCell(struct JsonToCellOptions *options);
|
||||
void FreeNSCRScreen(struct JsonToScreenOptions *options);
|
||||
void FreeNANRAnimation(struct JsonToAnimationOptions *options);
|
||||
|
||||
#endif //JSON_H
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2015 YamaArashi
|
||||
// Copyright (c) 2015 YamaArashi, 2021-2023 red031000
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
@ -45,8 +46,30 @@ void ConvertGbaToPng(char *inputPath, char *outputPath, struct GbaToPngOptions *
|
||||
FreeImage(&image);
|
||||
}
|
||||
|
||||
void ConvertNtrToPng(char *inputPath, char *outputPath, struct GbaToPngOptions *options)
|
||||
void ConvertNtrToPng(char *inputPath, char *outputPath, struct NtrToPngOptions *options)
|
||||
{
|
||||
// handle empty files if possible
|
||||
FILE *fp = fopen(inputPath, "rb");
|
||||
|
||||
if (options->handleEmpty)
|
||||
{
|
||||
if (fp != NULL)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
uint32_t size = ftell(fp);
|
||||
rewind(fp);
|
||||
if (size == 0)
|
||||
{
|
||||
FILE *out = fopen(outputPath, "wb+");
|
||||
fclose(out);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
struct Image image;
|
||||
|
||||
if (options->paletteFilePath != NULL)
|
||||
@ -58,8 +81,8 @@ void ConvertNtrToPng(char *inputPath, char *outputPath, struct GbaToPngOptions *
|
||||
{
|
||||
image.hasPalette = false;
|
||||
}
|
||||
|
||||
uint32_t key = ReadNtrImage(inputPath, options->width, 0, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette);
|
||||
|
||||
uint32_t key = ReadNtrImage(inputPath, options->width, 0, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette, options->scanFrontToBack);
|
||||
|
||||
if (key)
|
||||
{
|
||||
@ -95,6 +118,27 @@ void ConvertPngToGba(char *inputPath, char *outputPath, struct PngToGbaOptions *
|
||||
|
||||
void ConvertPngToNtr(char *inputPath, char *outputPath, struct PngToNtrOptions *options)
|
||||
{
|
||||
// handle empty files if possible
|
||||
FILE *fp = fopen(inputPath, "rb");
|
||||
|
||||
if (options->handleEmpty)
|
||||
{
|
||||
if (fp != NULL)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
uint32_t size = ftell(fp);
|
||||
rewind(fp);
|
||||
if (size == 0)
|
||||
{
|
||||
FILE *out = fopen(outputPath, "wb+");
|
||||
fclose(out);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
struct Image image;
|
||||
|
||||
image.bitDepth = options->bitDepth;
|
||||
@ -102,7 +146,7 @@ void ConvertPngToNtr(char *inputPath, char *outputPath, struct PngToNtrOptions *
|
||||
ReadPng(inputPath, &image);
|
||||
|
||||
uint32_t key = 0;
|
||||
if (options->scanned)
|
||||
if (options->scanMode)
|
||||
{
|
||||
char* string = malloc(strlen(inputPath) + 5);
|
||||
sprintf(string, "%s.key", inputPath);
|
||||
@ -118,7 +162,7 @@ void ConvertPngToNtr(char *inputPath, char *outputPath, struct PngToNtrOptions *
|
||||
|
||||
WriteNtrImage(outputPath, options->numTiles, image.bitDepth, options->metatileWidth, options->metatileHeight,
|
||||
&image, !image.hasPalette, options->clobberSize, options->byteOrder, options->version101,
|
||||
options->sopc, options->scanned, key, options->wrongSize);
|
||||
options->sopc, options->scanMode, key, options->wrongSize);
|
||||
|
||||
FreeImage(&image);
|
||||
}
|
||||
@ -128,7 +172,10 @@ void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||
char *inputFileExtension = GetFileExtension(inputPath);
|
||||
struct GbaToPngOptions options;
|
||||
options.paletteFilePath = NULL;
|
||||
options.bitDepth = inputFileExtension[0] - '0';
|
||||
if (isdigit(inputFileExtension[0]))
|
||||
options.bitDepth = inputFileExtension[0] - '0';
|
||||
else
|
||||
options.bitDepth = 4;
|
||||
options.hasTransparency = false;
|
||||
options.width = 1;
|
||||
options.metatileWidth = 1;
|
||||
@ -204,13 +251,15 @@ void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||
|
||||
void HandleNtrToPngCommand(char *inputPath, char *outputPath, int argc, char **argv)
|
||||
{
|
||||
struct GbaToPngOptions options;
|
||||
struct NtrToPngOptions options;
|
||||
options.paletteFilePath = NULL;
|
||||
options.hasTransparency = false;
|
||||
options.width = 1;
|
||||
options.width = 0;
|
||||
options.metatileWidth = 1;
|
||||
options.metatileHeight = 1;
|
||||
options.palIndex = 1;
|
||||
options.scanFrontToBack = false;
|
||||
options.handleEmpty = false;
|
||||
|
||||
for (int i = 3; i < argc; i++)
|
||||
{
|
||||
@ -281,13 +330,21 @@ void HandleNtrToPngCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||
if (options.metatileHeight < 1)
|
||||
FATAL_ERROR("metatile height must be positive.\n");
|
||||
}
|
||||
else if (strcmp(option, "-scanfronttoback") == 0)
|
||||
{
|
||||
options.scanFrontToBack = true;
|
||||
}
|
||||
else if (strcmp(option, "-handleempty") == 0)
|
||||
{
|
||||
options.handleEmpty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.metatileWidth > options.width)
|
||||
if (options.width != 0 && options.metatileWidth > options.width)
|
||||
options.width = options.metatileWidth;
|
||||
|
||||
ConvertNtrToPng(inputPath, outputPath, &options);
|
||||
@ -296,7 +353,11 @@ void HandleNtrToPngCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||
void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **argv)
|
||||
{
|
||||
char *outputFileExtension = GetFileExtension(outputPath);
|
||||
int bitDepth = outputFileExtension[0] - '0';
|
||||
int bitDepth;
|
||||
if (strcmp(outputFileExtension, "nbfc") == 0)
|
||||
bitDepth = 4;
|
||||
else
|
||||
bitDepth = outputFileExtension[0] - '0';
|
||||
struct PngToGbaOptions options;
|
||||
options.numTiles = 0;
|
||||
options.bitDepth = bitDepth;
|
||||
@ -367,7 +428,8 @@ void HandlePngToNtrCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||
options.byteOrder = true;
|
||||
options.version101 = false;
|
||||
options.sopc = false;
|
||||
options.scanned = false;
|
||||
options.scanMode = 0;
|
||||
options.handleEmpty = false;
|
||||
|
||||
for (int i = 3; i < argc; i++)
|
||||
{
|
||||
@ -443,11 +505,23 @@ void HandlePngToNtrCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||
}
|
||||
else if (strcmp(option, "-scanned") == 0)
|
||||
{
|
||||
options.scanned = true;
|
||||
if (options.scanMode != 0)
|
||||
FATAL_ERROR("Scan mode specified more than once.\n-scanned goes back to front as in DP, -scanfronttoback goes front to back as in PtHGSS\n");
|
||||
options.scanMode = 1;
|
||||
}
|
||||
else if (strcmp(option, "-scanfronttoback") == 0)
|
||||
{
|
||||
if (options.scanMode != 0)
|
||||
FATAL_ERROR("Scan mode specified more than once.\n-scanned goes back to front as in DP, -scanfronttoback goes front to back as in PtHGSS\n");
|
||||
options.scanMode = 2;
|
||||
}
|
||||
else if (strcmp(option, "-wrongsize") == 0) {
|
||||
options.wrongSize = true;
|
||||
}
|
||||
else if (strcmp(option, "-handleempty") == 0)
|
||||
{
|
||||
options.handleEmpty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
|
||||
@ -732,6 +806,32 @@ void HandleJsonToNtrScreenCommand(char *inputPath, char *outputPath, int argc UN
|
||||
FreeNSCRScreen(options);
|
||||
}
|
||||
|
||||
void HandleJsonToNtrAnimationCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||
{
|
||||
struct JsonToAnimationOptions *options;
|
||||
|
||||
options = ParseNANRJson(inputPath);
|
||||
|
||||
options->multiCell = false;
|
||||
|
||||
WriteNtrAnimation(outputPath, options);
|
||||
|
||||
FreeNANRAnimation(options);
|
||||
}
|
||||
|
||||
void HandleJsonToNtrMulticellAnimationCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||
{
|
||||
struct JsonToAnimationOptions *options;
|
||||
|
||||
options = ParseNANRJson(inputPath);
|
||||
|
||||
options->multiCell = true;
|
||||
|
||||
WriteNtrAnimation(outputPath, options);
|
||||
|
||||
FreeNANRAnimation(options);
|
||||
}
|
||||
|
||||
void HandleLatinFontToPngCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||
{
|
||||
struct Image image;
|
||||
@ -992,6 +1092,8 @@ int main(int argc, char **argv)
|
||||
{ "png", "fwjpnfont", HandlePngToFullwidthJapaneseFontCommand },
|
||||
{ "json", "NCER", HandleJsonToNtrCellCommand },
|
||||
{ "json", "NSCR", HandleJsonToNtrScreenCommand },
|
||||
{ "json", "NANR", HandleJsonToNtrAnimationCommand },
|
||||
{ "json", "NMAR", HandleJsonToNtrMulticellAnimationCommand },
|
||||
{ NULL, "huff", HandleHuffCompressCommand },
|
||||
{ NULL, "lz", HandleLZCompressCommand },
|
||||
{ "huff", NULL, HandleHuffDecompressCommand },
|
||||
|
@ -1,8 +1,9 @@
|
||||
// Copyright (c) 2018 huderlem
|
||||
// Copyright (c) 2018 huderlem, 2021-2023 red031000
|
||||
|
||||
#ifndef OPTIONS_H
|
||||
#define OPTIONS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct GbaToPngOptions {
|
||||
@ -31,8 +32,21 @@ struct PngToNtrOptions {
|
||||
bool byteOrder;
|
||||
bool version101;
|
||||
bool sopc;
|
||||
bool scanned;
|
||||
uint32_t scanMode;
|
||||
bool wrongSize;
|
||||
bool handleEmpty;
|
||||
};
|
||||
|
||||
struct NtrToPngOptions {
|
||||
char *paletteFilePath;
|
||||
int bitDepth;
|
||||
bool hasTransparency;
|
||||
int width;
|
||||
int metatileWidth;
|
||||
int metatileHeight;
|
||||
int palIndex;
|
||||
bool scanFrontToBack;
|
||||
bool handleEmpty;
|
||||
};
|
||||
|
||||
struct Attr0 {
|
||||
@ -91,4 +105,55 @@ struct JsonToScreenOptions {
|
||||
int bitdepth;
|
||||
};
|
||||
|
||||
struct FrameData {
|
||||
int resultId;
|
||||
short frameDelay;
|
||||
};
|
||||
|
||||
struct SequenceData {
|
||||
short frameCount;
|
||||
short loopStartFrame;
|
||||
short animationElement;
|
||||
short animationType;
|
||||
int playbackMode;
|
||||
struct FrameData **frameData;
|
||||
};
|
||||
|
||||
struct AnimationDataSRT {
|
||||
short index;
|
||||
unsigned short rotation;
|
||||
int scaleX;
|
||||
int scaleY;
|
||||
short positionX;
|
||||
short positionY;
|
||||
};
|
||||
|
||||
struct AnimationDataT {
|
||||
short index;
|
||||
//unsigned short rotation;
|
||||
short positionX;
|
||||
short positionY;
|
||||
};
|
||||
|
||||
struct AnimationResults {
|
||||
short resultType;
|
||||
union {
|
||||
short index;
|
||||
struct AnimationDataSRT dataSrt;
|
||||
struct AnimationDataT dataT;
|
||||
};
|
||||
};
|
||||
|
||||
struct JsonToAnimationOptions {
|
||||
bool multiCell;
|
||||
short sequenceCount;
|
||||
short frameCount;
|
||||
struct SequenceData **sequenceData;
|
||||
struct AnimationResults **animationResults;
|
||||
bool labelEnabled;
|
||||
char **labels;
|
||||
int labelCount;
|
||||
short resultCount;
|
||||
};
|
||||
|
||||
#endif // OPTIONS_H
|
||||
|
@ -101,7 +101,7 @@ unsigned char *RLCompress(unsigned char *src, int srcSize, int *compressedSize)
|
||||
srcPos++;
|
||||
uncompressedLength++;
|
||||
}
|
||||
|
||||
|
||||
if (uncompressedLength > 0)
|
||||
{
|
||||
dest[destPos++] = uncompressedLength - 1;
|
||||
|
@ -13,4 +13,45 @@ unsigned char *ReadWholeFileZeroPadded(char *path, int *size, int padAmount);
|
||||
void WriteWholeFile(char *path, void *buffer, int bufferSize);
|
||||
void WriteGenericNtrHeader(FILE* fp, const char* magicNumber, uint32_t size, bool byteorder, bool version101, uint16_t sectionCount);
|
||||
|
||||
// Unaligned IO
|
||||
static inline uint8_t ReadU8(const unsigned char *ptr, const size_t offset) {
|
||||
return ptr[offset];
|
||||
}
|
||||
|
||||
static inline uint16_t ReadU16(const unsigned char *ptr, const size_t offset) {
|
||||
return ptr[offset] | (ptr[offset + 1] << 8);
|
||||
}
|
||||
|
||||
static inline uint32_t ReadU32(const unsigned char *ptr, const size_t offset) {
|
||||
return ptr[offset] | (ptr[offset + 1] << 8) | (ptr[offset + 2] << 16) | (ptr[offset + 3] << 24);
|
||||
}
|
||||
|
||||
static inline int8_t ReadS8(const unsigned char *ptr, const size_t offset) {
|
||||
return ptr[offset];
|
||||
}
|
||||
|
||||
static inline int16_t ReadS16(const unsigned char *ptr, const size_t offset) {
|
||||
return ptr[offset] | (ptr[offset + 1] << 8);
|
||||
}
|
||||
|
||||
static inline int32_t ReadS32(const unsigned char *ptr, const size_t offset) {
|
||||
return ptr[offset] | (ptr[offset + 1] << 8) | (ptr[offset + 2] << 16) | (ptr[offset + 3] << 24);
|
||||
}
|
||||
|
||||
static inline void WriteU8(unsigned char *ptr, const size_t offset, uint8_t value) {
|
||||
ptr[offset] = value;
|
||||
}
|
||||
|
||||
static inline void WriteU16(unsigned char *ptr, const size_t offset, uint16_t value) {
|
||||
ptr[offset] = value;
|
||||
ptr[offset + 1] = value >> 8;
|
||||
}
|
||||
|
||||
static inline void WriteU32(unsigned char *ptr, const size_t offset, uint32_t value) {
|
||||
ptr[offset] = value;
|
||||
ptr[offset + 1] = value >> 8;
|
||||
ptr[offset + 2] = value >> 16;
|
||||
ptr[offset + 3] = value >> 24;
|
||||
}
|
||||
|
||||
#endif // UTIL_H
|
||||
|
Loading…
Reference in New Issue
Block a user