System(s) |
Playstation, PSP, PSN (POPS) |
Bug Type | Gameplay |
Region Introduced | |
Patch Version | 2.01.065b |
The main executable contains two functions that are used for getting item data. The first is at 0x80070348. It takes an address to an array of item data, the item type, and the actual item number as arguments. The reason for needing that first pointer is an open question. Most of the shop modules contain copies of the item data, and all of them have code that calls this function, passing a pointer to their own copy of the item data. This function does not take into account the possibility of unidentified items. It expects to receive a type from 1-7, with no quantity or unidentified flag included.
What is strange is that passing a zero, instead of a pointer to a "local" array of item data causes a more global set of data to be used. Why two copies of this data is desirable is not known for certain. It appears that the "global" data could have been a late addition, and Konami initially placed the array only in modules that needed it. This may have been a space-saving measure that turned into more trouble than it was worth.
The second function is at 0x80088D74. This function takes a type/quantity (including the unidentified flag) and an item ID. If the item is unidentified, it returns a dummy entry for the appropriate type of antique. When the item is identified, it actually calls the function previously described with a zero pointer. So it uses the global array by default.
Most of the shops contain two sets of routines. One that calls only the 0x80070348 function, and refers to the local item data. These routines appear to be dead code for the most part. Routines in the second set all call the 0x80088D74 function. For some reason, the Scroll Shop only includes the first set of routines, and no references at all exist for the more appropriate function.
RAM:80111480 li $s7, 0x8008DB48 RAM:80111488 li $s6, 0x80070348 RAM:80111490 li $s5, 0x8008D390 RAM:80111498 li $fp, 1 RAM:8011149C li $s4, 0x8008E024 RAM:801114A4 RAM:801114A4 loc_801114A4: # CODE XREF: sub_801113AC+1B8j RAM:801114A4 lbu $v1, 0x17($s2) RAM:801114A8 nop RAM:801114AC addiu $v1, 1 RAM:801114B0 sll $v0, $v1, 3 RAM:801114B4 subu $v0, $v1 RAM:801114B8 slt $v0, $s0, $v0 RAM:801114BC beqz $v0, loc_8011156C RAM:801114C0 move $a1, $0 RAM:801114C4 lw $a0, 0x1C4($s2) RAM:801114C8 move $a2, $s1 RAM:801114CC jalr $s7 RAM:801114D0 sw $s7, -0x8AC($s3) RAM:801114D4 li $v1, 0x80061000 RAM:801114DC la $a0, unk_80114A44 RAM:801114E4 sll $v0, $s0, 1 RAM:801114E8 addu $v0, $v1 RAM:801114EC li $v1, 0x8000 RAM:801114F0 addu $v0, $v1 RAM:801114F4 sw $s6, -0x8AC($s3) RAM:801114F8 lbu $a1, 0x14AF($v0) RAM:801114FC lbu $a2, 0x14AE($v0) RAM:80111500 andi $a1, 0x70 RAM:80111504 jalr $s6 RAM:80111508 srl $a1, 4
The above is a snippet of code from the Scroll Shop. When it needs to retrieve the item name and description for display, it calls 0x80070348, which cannot return things like "? vase".
.psx .align 4 .openfile FUDAZUK.BIN, 0x8010DC50 .headersize 0 .org 0x80111480 .area 0x80111510-. li $s7, 0x8008DB48 li $s6, 0x80088D74 ; replace sub 0x80070348 li $s5, 0x8008D390 li $fp, 1 li $s4, 0x8008E024 lbu $v1, 0x17($s2) nop addiu $v1, 1 sll $v0, $v1, 3 subu $v0, $v1 slt $v0, $s0, $v0 beqz $v0, 0x8011156C move $a1, $0 lw $a0, 0x1C4($s2) move $a2, $s1 jalr $s7 sw $s7, -0x8AC($s3) li $v1, 0x80061000 li $a0, 0x80114A44 sll $v0, $s0, 1 addu $v0, $v1 li $v1, 0x8000 addu $v0, $v1 sw $s6, -0x8AC($s3) lbu $a0, 0x14AF($v0) ; $a0 is type/quantity lbu $a1, 0x14AE($v0) ; $a1 is item nop ; no longer need or want the andi jalr $s6 nop ; or the srl that isolated the type bits move $a1, $v0 .endarea .org 0x80111E60 .area 0x80111EE0-. li $t0, 0x8008DB48 sw $t0, 0x20($sp) li $fp, 0x80088D74 ; replace sub 0x80070348 li $s7, 0x8008D390 li $s6, 0x8008E024 lbu $v0, 0x16($s2) nop beq $s0, $v0, 0x80111F4C move $a1, $0 andi $s1, $s5, 0xFF lw $a0, 0x1C4($s2) lw $t0, 0x20($sp) move $a2, $s1 jalr $t0 sw $t0, -0x8AC($s4) li $v1, 0x80069000 li $a0, 0x80114A44 sll $v0, $s0, 1 or $v0, $v1 sw $fp, -0x8AC($s4) lbu $a0, 0x14AF($v0) ; $a0 is type/quantity lbu $a1, 0x14AE($v0) ; $a1 is item nop ; no longer need or want the andi jalr $fp nop ; or the srl that isolated the type bits move $a1, $v0 .endarea .close