diff --git a/asm/pokenav.s b/asm/pokenav.s index fee2fc91c5..68dd355421 100644 --- a/asm/pokenav.s +++ b/asm/pokenav.s @@ -3,606 +3,6 @@ .syntax unified - .text - - thumb_func_start sub_81C8DBC -sub_81C8DBC: @ 81C8DBC - push {r4-r6,lr} - mov r6, r9 - mov r5, r8 - push {r5,r6} - sub sp, 0x1C - adds r6, r0, 0 - mov r8, r1 - add r1, sp, 0xC - ldr r0, =gUnknown_0861FBE8 - ldm r0!, {r2-r4} - stm r1!, {r2-r4} - add r0, sp, 0x18 - mov r9, r0 - ldr r1, =gUnknown_0861FBF4 - movs r2, 0x3 - bl memcpy - ldrh r4, [r6, 0xA] - mov r1, r8 - lsls r0, r1, 1 - adds r0, 0x1 - adds r4, r0 - movs r0, 0xF - ands r4, r0 - ldrb r0, [r6, 0x8] - lsls r5, r4, 4 - adds r3, r5, 0 - ldrb r1, [r6, 0x4] - str r1, [sp] - movs r1, 0x10 - str r1, [sp, 0x4] - movs r1, 0x11 - movs r2, 0 - bl FillWindowPixelRect - ldrb r0, [r6, 0x8] - movs r1, 0x1 - orrs r5, r1 - mov r2, r9 - str r2, [sp] - subs r1, 0x2 - str r1, [sp, 0x4] - mov r3, r8 - lsls r3, 2 - mov r8, r3 - mov r1, sp - add r1, r8 - adds r1, 0xC - ldr r1, [r1] - str r1, [sp, 0x8] - movs r1, 0x7 - movs r2, 0x2 - adds r3, r5, 0 - bl AddTextPrinterParameterized3 - ldrh r0, [r6, 0x8] - lsls r4, 1 - ldrb r1, [r6, 0x4] - str r1, [sp] - movs r1, 0x2 - str r1, [sp, 0x4] - movs r2, 0 - adds r3, r4, 0 - bl CopyWindowRectToVram - add sp, 0x1C - pop {r3,r4} - mov r8, r3 - mov r9, r4 - pop {r4-r6} - pop {r0} - bx r0 - .pool - thumb_func_end sub_81C8DBC - - thumb_func_start sub_81C8E54 -sub_81C8E54: @ 81C8E54 - push {r4-r7,lr} - mov r7, r8 - push {r7} - sub sp, 0xC - adds r7, r1, 0 - adds r1, r2, 0 - ldrh r3, [r7, 0xA] - ldr r2, =gUnknown_0861FBF7 - adds r2, r1, r2 - ldrb r2, [r2] - adds r6, r3, r2 - movs r2, 0xF - ands r6, r2 - ldrh r0, [r0] - bl sub_81CAFD8 - adds r5, r0, 0 - cmp r5, 0 - beq _081C8EC0 - ldrh r0, [r7, 0x8] - lsls r4, r6, 1 - ldrb r3, [r7, 0x4] - subs r3, 0x1 - movs r1, 0x2 - mov r8, r1 - str r1, [sp] - movs r1, 0x1 - adds r2, r4, 0 - bl sub_81DB620 - ldrb r0, [r7, 0x8] - lsls r1, r6, 4 - movs r2, 0x1 - orrs r1, r2 - str r1, [sp] - movs r1, 0xFF - str r1, [sp, 0x4] - movs r1, 0 - str r1, [sp, 0x8] - movs r1, 0x7 - adds r2, r5, 0 - movs r3, 0x2 - bl AddTextPrinterParameterized - ldrh r0, [r7, 0x8] - ldrb r1, [r7, 0x4] - str r1, [sp] - mov r1, r8 - str r1, [sp, 0x4] - movs r1, 0x2 - movs r2, 0 - adds r3, r4, 0 - bl CopyWindowRectToVram -_081C8EC0: - add sp, 0xC - pop {r3} - mov r8, r3 - pop {r4-r7} - pop {r0} - bx r0 - .pool - thumb_func_end sub_81C8E54 - - thumb_func_start sub_81C8ED0 -sub_81C8ED0: @ 81C8ED0 - push {r4,r5,lr} - movs r5, 0 - ldr r4, =gUnknown_0861FBFC -_081C8ED6: - adds r0, r4, 0 - bl LoadCompressedSpriteSheet - adds r4, 0x8 - adds r5, 0x1 - cmp r5, 0 - beq _081C8ED6 - ldr r0, =gUnknown_0861FC04 - bl sub_81C795C - pop {r4,r5} - pop {r0} - bx r0 - .pool - thumb_func_end sub_81C8ED0 - - thumb_func_start sub_81C8EF8 -sub_81C8EF8: @ 81C8EF8 - push {r4-r6,lr} - mov r6, r10 - mov r5, r9 - mov r4, r8 - push {r4-r6} - adds r4, r0, 0 - adds r5, r1, 0 - ldr r0, =gUnknown_0861FC1C - ldrb r1, [r5, 0x2] - lsls r1, 3 - adds r1, 0x3 - ldrb r2, [r5, 0x3] - adds r2, 0x1 - lsls r2, 3 - movs r3, 0x7 - bl CreateSprite - lsls r0, 24 - lsrs r3, r0, 24 - lsls r0, r3, 4 - adds r0, r3 - lsls r0, 2 - ldr r1, =gSprites - mov r8, r1 - add r0, r8 - str r0, [r5, 0x3C] - ldrb r6, [r5, 0x2] - lsls r6, 3 - ldrb r0, [r5, 0x4] - subs r0, 0x1 - lsls r0, 2 - ldr r3, =gUnknown_0861FC3C - mov r10, r3 - adds r6, r0 - ldrb r2, [r5, 0x3] - lsls r2, 3 - ldrh r0, [r4, 0x8] - lsls r0, 4 - adds r2, r0 - lsls r2, 16 - asrs r2, 16 - mov r0, r10 - adds r1, r6, 0 - movs r3, 0x7 - bl CreateSprite - lsls r0, 24 - lsrs r3, r0, 24 - lsls r2, r3, 4 - adds r2, r3 - lsls r2, 2 - add r2, r8 - str r2, [r5, 0x44] - ldrh r3, [r2, 0x4] - lsls r1, r3, 22 - lsrs r1, 22 - adds r1, 0x2 - ldr r0, =0x000003ff - mov r9, r0 - mov r0, r9 - ands r1, r0 - ldr r4, =0xfffffc00 - adds r0, r4, 0 - ands r0, r3 - orrs r0, r1 - strh r0, [r2, 0x4] - ldr r1, [r5, 0x44] - ldr r0, =sub_81C90A0 - str r0, [r1, 0x1C] - ldrb r2, [r5, 0x3] - lsls r2, 3 - mov r0, r10 - adds r1, r6, 0 - movs r3, 0x7 - bl CreateSprite - lsls r0, 24 - lsrs r3, r0, 24 - lsls r1, r3, 4 - adds r1, r3 - lsls r1, 2 - add r1, r8 - str r1, [r5, 0x40] - ldrh r2, [r1, 0x4] - lsls r0, r2, 22 - lsrs r0, 22 - adds r0, 0x4 - mov r3, r9 - ands r0, r3 - ands r4, r2 - orrs r4, r0 - strh r4, [r1, 0x4] - ldr r1, [r5, 0x40] - ldr r0, =sub_81C90F4 - str r0, [r1, 0x1C] - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r6} - pop {r0} - bx r0 - .pool - thumb_func_end sub_81C8EF8 - - thumb_func_start sub_81C8FE0 -sub_81C8FE0: @ 81C8FE0 - push {r4,lr} - adds r4, r0, 0 - ldr r0, [r4, 0x3C] - bl DestroySprite - ldr r0, [r4, 0x40] - bl DestroySprite - ldr r0, [r4, 0x44] - bl DestroySprite - movs r0, 0xA - bl FreeSpriteTilesByTag - movs r0, 0x14 - bl FreeSpritePaletteByTag - pop {r4} - pop {r0} - bx r0 - thumb_func_end sub_81C8FE0 - - thumb_func_start sub_81C9008 -sub_81C9008: @ 81C9008 - push {r4,r5,lr} - adds r5, r0, 0 - adds r4, r1, 0 - cmp r4, 0 - beq _081C9028 - ldr r2, [r5, 0x3C] - ldr r1, =SpriteCallbackDummy - str r1, [r2, 0x1C] - ldr r0, [r5, 0x40] - str r1, [r0, 0x1C] - ldr r0, [r5, 0x44] - str r1, [r0, 0x1C] - b _081C903A - .pool -_081C9028: - ldr r2, [r5, 0x3C] - ldr r0, =sub_81C9080 - str r0, [r2, 0x1C] - ldr r1, [r5, 0x40] - ldr r0, =sub_81C90F4 - str r0, [r1, 0x1C] - ldr r1, [r5, 0x44] - ldr r0, =sub_81C90A0 - str r0, [r1, 0x1C] -_081C903A: - adds r3, r2, 0 - adds r3, 0x3E - movs r0, 0x1 - ands r4, r0 - lsls r4, 2 - ldrb r2, [r3] - movs r1, 0x5 - negs r1, r1 - adds r0, r1, 0 - ands r0, r2 - orrs r0, r4 - strb r0, [r3] - ldr r2, [r5, 0x40] - adds r2, 0x3E - ldrb r3, [r2] - adds r0, r1, 0 - ands r0, r3 - orrs r0, r4 - strb r0, [r2] - ldr r0, [r5, 0x44] - adds r0, 0x3E - ldrb r2, [r0] - ands r1, r2 - orrs r1, r4 - strb r1, [r0] - pop {r4,r5} - pop {r0} - bx r0 - .pool - thumb_func_end sub_81C9008 - - thumb_func_start sub_81C9080 -sub_81C9080: @ 81C9080 - push {r4,lr} - adds r4, r0, 0 - movs r0, 0x11 - bl GetSubstructPtr - ldr r1, =0x0000088e - adds r0, r1 - ldrh r0, [r0] - lsls r0, 4 - strh r0, [r4, 0x26] - pop {r4} - pop {r0} - bx r0 - .pool - thumb_func_end sub_81C9080 - - thumb_func_start sub_81C90A0 -sub_81C90A0: @ 81C90A0 - push {r4,lr} - adds r4, r0, 0 - movs r1, 0x3C - ldrsh r0, [r4, r1] - cmp r0, 0 - bne _081C90C2 - bl sub_81C84C0 - cmp r0, 0 - beq _081C90C2 - adds r2, r4, 0 - adds r2, 0x3E - ldrb r1, [r2] - movs r0, 0x5 - negs r0, r0 - ands r0, r1 - b _081C90CC -_081C90C2: - adds r2, r4, 0 - adds r2, 0x3E - ldrb r0, [r2] - movs r1, 0x4 - orrs r0, r1 -_081C90CC: - strb r0, [r2] - ldrh r0, [r4, 0x2E] - adds r0, 0x1 - strh r0, [r4, 0x2E] - lsls r0, 16 - asrs r0, 16 - cmp r0, 0x3 - ble _081C90EC - movs r0, 0 - strh r0, [r4, 0x2E] - ldrh r0, [r4, 0x30] - adds r0, 0x1 - movs r1, 0x7 - ands r0, r1 - strh r0, [r4, 0x30] - strh r0, [r4, 0x26] -_081C90EC: - pop {r4} - pop {r0} - bx r0 - thumb_func_end sub_81C90A0 - - thumb_func_start sub_81C90F4 -sub_81C90F4: @ 81C90F4 - push {r4,lr} - adds r4, r0, 0 - movs r1, 0x3C - ldrsh r0, [r4, r1] - cmp r0, 0 - bne _081C9116 - bl sub_81C84A4 - cmp r0, 0 - beq _081C9116 - adds r2, r4, 0 - adds r2, 0x3E - ldrb r1, [r2] - movs r0, 0x5 - negs r0, r0 - ands r0, r1 - b _081C9120 -_081C9116: - adds r2, r4, 0 - adds r2, 0x3E - ldrb r0, [r2] - movs r1, 0x4 - orrs r0, r1 -_081C9120: - strb r0, [r2] - ldrh r0, [r4, 0x2E] - adds r0, 0x1 - strh r0, [r4, 0x2E] - lsls r0, 16 - asrs r0, 16 - cmp r0, 0x3 - ble _081C9142 - movs r0, 0 - strh r0, [r4, 0x2E] - ldrh r0, [r4, 0x30] - adds r0, 0x1 - movs r1, 0x7 - ands r0, r1 - strh r0, [r4, 0x30] - negs r0, r0 - strh r0, [r4, 0x26] -_081C9142: - pop {r4} - pop {r0} - bx r0 - thumb_func_end sub_81C90F4 - - thumb_func_start sub_81C9148 -sub_81C9148: @ 81C9148 - push {r4,lr} - adds r4, r0, 0 - movs r0, 0x11 - bl GetSubstructPtr - ldr r1, [r0, 0x40] - strh r4, [r1, 0x3C] - ldr r0, [r0, 0x44] - strh r4, [r0, 0x3C] - pop {r4} - pop {r0} - bx r0 - thumb_func_end sub_81C9148 - - thumb_func_start sub_81C9160 -sub_81C9160: @ 81C9160 - push {r4,r5,lr} - adds r2, r0, 0 - ldr r0, [r1] - str r0, [r2, 0x10] - ldrh r4, [r1, 0x6] - movs r5, 0 - strh r4, [r2] - ldrh r3, [r1, 0x4] - strh r3, [r2, 0x2] - ldrb r0, [r1, 0x8] - str r0, [r2, 0xC] - ldrb r1, [r1, 0xC] - strh r1, [r2, 0x8] - lsls r0, r3, 16 - lsrs r0, 16 - cmp r1, r0 - bcc _081C918A - strh r5, [r2] - strh r5, [r2, 0x4] - strh r4, [r2, 0x6] - b _081C91A6 -_081C918A: - subs r0, r3, r1 - strh r0, [r2, 0x4] - ldrh r1, [r2] - ldrh r0, [r2, 0x8] - adds r1, r0 - ldrh r0, [r2, 0x2] - cmp r1, r0 - ble _081C91A4 - subs r0, r1, r0 - strh r0, [r2, 0x6] - subs r0, r4, r0 - strh r0, [r2] - b _081C91A6 -_081C91A4: - strh r5, [r2, 0x6] -_081C91A6: - pop {r4,r5} - pop {r0} - bx r0 - thumb_func_end sub_81C9160 - - thumb_func_start sub_81C91AC -sub_81C91AC: @ 81C91AC - push {r4-r7,lr} - mov r7, r9 - mov r6, r8 - push {r6,r7} - sub sp, 0x8 - adds r7, r0, 0 - ldr r4, [r1] - lsls r4, 30 - lsrs r0, r4, 30 - movs r1, 0 - mov r9, r1 - strb r0, [r7] - strh r3, [r7, 0x6] - ldr r0, [r2, 0x10] - str r0, [r7, 0x34] - ldr r0, [r2, 0x14] - str r0, [r7, 0x38] - ldrb r6, [r2, 0xD] - strb r6, [r7, 0x1] - ldrb r1, [r2, 0x9] - strb r1, [r7, 0x2] - ldrb r0, [r2, 0xB] - strb r0, [r7, 0x3] - ldrb r5, [r2, 0xA] - strb r5, [r7, 0x4] - ldrb r0, [r2, 0xE] - strb r0, [r7, 0x5] - lsrs r4, 30 - ldr r2, =0xffffff00 - mov r8, r2 - ldr r0, [sp] - ands r0, r2 - orrs r0, r4 - lsls r1, 24 - lsrs r1, 16 - ldr r2, =0xffff00ff - ands r0, r2 - orrs r0, r1 - ldr r1, =0xff00ffff - ands r0, r1 - lsls r5, 24 - ldr r1, =0x00ffffff - ands r0, r1 - orrs r0, r5 - str r0, [sp] - ldr r0, [sp, 0x4] - mov r1, r8 - ands r0, r1 - movs r1, 0x20 - orrs r0, r1 - lsls r6, 24 - lsrs r6, 16 - ands r0, r2 - orrs r0, r6 - adds r3, 0x2 - lsls r3, 16 - ldr r1, =0x0000ffff - ands r0, r1 - orrs r0, r3 - str r0, [sp, 0x4] - mov r0, sp - bl AddWindow - strh r0, [r7, 0x8] - lsls r0, 16 - lsrs r0, 16 - cmp r0, 0xFF - beq _081C9258 - mov r2, r9 - strh r2, [r7, 0xA] - mov r0, r9 - str r0, [r7, 0x3C] - str r0, [r7, 0x40] - str r0, [r7, 0x44] - movs r0, 0x1 - b _081C925A - .pool -_081C9258: - movs r0, 0 -_081C925A: - add sp, 0x8 - pop {r3,r4} - mov r8, r3 - mov r9, r4 - pop {r4-r7} - pop {r1} - bx r1 - thumb_func_end sub_81C91AC - thumb_func_start sub_81C9268 sub_81C9268: @ 81C9268 push {r4,lr} @@ -5440,7 +4840,7 @@ _081CB7BA: b _081CB81A _081CB7C4: movs r0, 0x1 - bl sub_81C9148 + bl ToggleMatchCallVerticalArrows adds r0, r5, 0 bl sub_81CC058 movs r0, 0 @@ -5508,7 +4908,7 @@ _081CB844: adds r0, r5, 0 bl sub_81CC09C movs r0, 0x1 - bl sub_81C9148 + bl ToggleMatchCallVerticalArrows movs r0, 0x1 strb r0, [r5, 0xE] movs r0, 0 @@ -5617,7 +5017,7 @@ _081CB922: bne _081CB8EC _081CB92C: movs r0, 0 - bl sub_81C9148 + bl ToggleMatchCallVerticalArrows movs r6, 0x4 _081CB934: adds r0, r6, 0 diff --git a/asmdiff.ps1 b/asmdiff.ps1 index 17a8cb8e8c..f476d51e85 100644 --- a/asmdiff.ps1 +++ b/asmdiff.ps1 @@ -1,4 +1,119 @@ -$objdump = Join-Path -Path "$($args[0])" -ChildPath "bin\objdump.exe" -&$objdump -D -bbinary -marmv4t -Mforce-thumb --start-address="$($args[1])" --stop-address="$($args[2])" .\baserom.gba > .\baserom.dump -&$objdump -D -bbinary -marmv4t -Mforce-thumb --start-address="$($args[1])" --stop-address="$($args[2])" .\pokeemerald.gba > .\pokeemerald.dump -Compare-Object (Get-Content .\baserom.dump) (Get-Content .\pokeemerald.dump) +Param +( + [Parameter(Position = 0)] + [string]$Start, + + [Parameter(Position = 1)] + [string]$Offset, + + [Parameter()] + [string[]]$DiffTool +) + +$ErrorActionPreference = "Stop" + +$offset_default_value = "0x100" +$diff_tool_default_value = "diff" + +$help = " +$($args[0]) [OPTIONS] Start [Offset] + +Performs a diff on the assembly of a function in a rom. 'Start' is the start +location of the function, and 'Offset' is the number of bytes to disassemble. +The assembly is saved to *.dump files. + +'Offset' is optional, and defaults to $offset_default_value. If this value is +very large (0x10000+), objdump may hang / freeze. + +Requirements: + - A clean copy of the rom named 'baserom.gba'. + - $$ENV:DEVKITARM to point to the installation of devkitpro. By default, it is + installed to 'C:\devkitpro\devkitARM'. + +Options: + -DiffTool The tool to use for diffing. Defaults to '$diff_tool_default_value'. For VSCode, + you can use -DiffTool 'code --diff'. (Quotes are necessary around 'code --diff') +" + +if ((-not (Test-Path variable:Start)) -or [string]::IsNullOrWhiteSpace($Start)) +{ + Write-Host $help + exit +} + +if (-not (Test-Path variable:DiffTool) -or [string]::IsNullOrWhiteSpace($DiffTool)) +{ + $DiffTool = $diff_tool_default_value +} + +if (-not (Test-Path variable:Offset) -or [string]::IsNullOrWhiteSpace($Offset)) +{ + $Offset = $offset_default_value +} + +if (-Not (Test-Path env:DEVKITARM)) +{ + Write-Host "ENV:DEVKITARM variable not set." + Write-Host $help + exit +} + +if (-Not (Test-Path $env:DEVKITARM)) +{ + Write-Host "DEVKITARM path '$env:DEVKITARM' does not exist." + Write-Host $help + exit +} + +if (-Not (Test-Path ".\pokeemerald.gba")) +{ + Write-Host "File 'pokeemerald.gba' not found." + Write-Host $help + exit +} + +if (-Not (Test-Path ".\baserom.gba")) +{ + Write-Host "File 'baserom.gba' not found." +} + +try +{ + $start_num = [System.Convert]::ToUInt64($Start, 16) +} +catch +{ + Write-Host "Error parsing '$start_num' as a hex number." + Write-Host $help + exit +} + +try +{ + $offset_num = [System.Convert]::ToUInt64($Offset, 16) +} +catch +{ + Write-Host "Error parsing '$offset_num' as a hex number." + Write-Host $help + exit +} + +if ($start_num -gt 0x1000000) +{ + Write-Host "Warning: Start address is larger than the ROM file. Hint: ignore the leading number in the address." +} + +$end_str = [System.Convert]::ToString($start_num + $offset_num, 16) +$end_str = "0x$end_str" + +$start_str = "0x$Start" + +Write-Host "$start_str - $end_str" +$objdump = Join-Path -Path $env:DEVKITARM -ChildPath "arm-none-eabi\bin\objdump.exe" +Write-Host "Dumping [0/2]" +&$objdump -D -bbinary -marmv4t -Mforce-thumb --start-address="$start_str" --stop-address="$end_str" .\baserom.gba > .\baserom.dump +Write-Host "Dumping [1/2]" +&$objdump -D -bbinary -marmv4t -Mforce-thumb --start-address="$start_str" --stop-address="$end_str" .\pokeemerald.gba > .\pokeemerald.dump +Write-Host "Dumping [2/2]" +Invoke-Expression "$DiffTool .\baserom.dump .\pokeemerald.dump" diff --git a/data/pokenav.s b/data/pokenav.s index 5847bca0d3..0e2c781664 100644 --- a/data/pokenav.s +++ b/data/pokenav.s @@ -3,60 +3,6 @@ .section .rodata -gUnknown_0861FB5C:: @ 861FB5C - .incbin "graphics/pokenav/arrows_matchcall.gbapal" - -gUnknown_0861FB7C:: @ 861FB7C - .incbin "graphics/pokenav/arrows_matchcall.4bpp.lz" - -gUnknown_0861FBE4:: @ 861FBE4 - .byte 0x0 - .byte 0x2 - .byte 0x5 - .byte 0x0 - -gUnknown_0861FBE8:: @ 861FBE8 - .4byte gUnknown_085EBEA8 - .4byte gUnknown_085EBEB1 - .4byte gUnknown_085EBEC3 - -gUnknown_0861FBF4:: @ 861FBF4 - .byte 0x1 - .byte 0x4 - .byte 0x5 - -gUnknown_0861FBF7:: @ 861FBF7 - .byte 0x2 - .byte 0x4 - .byte 0x6 - .byte 0x7 - .byte 0x0 - -gUnknown_0861FBFC:: @ 861FBFC - .4byte gUnknown_0861FB7C - .2byte 0xC0 - .2byte 0xA - -gUnknown_0861FC04:: @ 861FC04 - .4byte gUnknown_0861FB5C - .4byte 0x14 - .4byte 0x0 - .4byte 0x0 - -gUnknown_0861FC14:: @ 861FC14 - .4byte 0x8000 - .4byte 0x800 - -gUnknown_0861FC1C:: @ 861FC1C - spr_template 10, 20, gUnknown_0861FC14, gDummySpriteAnimTable, NULL, gDummySpriteAffineAnimTable, sub_81C9080 - -gUnknown_0861FC34:: @ 861FC34 - .4byte 0x4000 - .4byte 0x800 - -gUnknown_0861FC3C:: @ 861FC3C - spr_template 10, 20, gUnknown_0861FC34, gDummySpriteAnimTable, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy - gUnknown_0861FC54:: @ 861FC54 .byte 2 .byte 3 @@ -1313,7 +1259,7 @@ gUnknown_0862278C:: @ 862278C .4byte 0x20206A gUnknown_08622794:: @ 8622794 - .4byte 0x3077 + .4byte 0x00003077 gUnknown_08622798:: @ 8622798 .4byte NULL diff --git a/include/strings.h b/include/strings.h index 3899b63aa5..d0c339d4a3 100644 --- a/include/strings.h +++ b/include/strings.h @@ -986,6 +986,9 @@ extern const u8 gText_SomeonesPC[]; extern const u8 gText_PlayersPC[]; extern const u8 gText_WhichPCShouldBeAccessed[]; +extern const u8 gText_NavgearMatchCall_Strategy[]; +extern const u8 gText_NavgearMatchCall_TrainerPokemon[]; +extern const u8 gText_NavgearMatchCall_SelfIntroduction[]; extern const u8 gText_Navgear_ClearButtonList[]; extern const u8 gText_NavgearMap_ZoomedOutButtons[]; extern const u8 gText_NavgearMap_ZoomedInButtons[]; diff --git a/src/pokenav.c b/src/pokenav.c index 3986cb51c0..cde8646bc9 100644 --- a/src/pokenav.c +++ b/src/pokenav.c @@ -34,7 +34,7 @@ struct UnknownSubSubStruct_0203CF40 { u8 unk2; u8 unk3; u8 unk4; - u8 unk5; + u8 fontId; u16 unk6; u16 windowId; u16 unkA; @@ -80,12 +80,12 @@ struct UnknownInnerStruct_81C81D4 u32 unk28; s32 unk2C; u32 unk30; - void (*unk34)(u32, char*); + void (*unk34)(u32, u8*); void (*unk38)(u16, u32, u32); - u32 unk3C; - u32 unk40; - u32 unk44; - char unk48[0x40]; + struct Sprite *rightArrow; + struct Sprite *upArrow; + struct Sprite *downArrow; + u8 unkTextBuffer[0x40]; }; // Generally at index 0x11 (17) @@ -117,12 +117,27 @@ struct CompressedSpritePalette_ u32 tag; }; +struct UnknownStruct_81C9160 +{ + u32 unk0; + u16 unk4; + u16 unk6; + u8 unk8; + u8 unk9; + u8 unkA; + u8 unkB; + u8 unkC; + u8 unkD; + u8 unkE; + void (*unk10)(u32, u8 *a1); + void (*unk14)(u16 a0, u32 a1, u32 a2); +}; + extern u32 sub_81C9430(void); extern void sub_81CAADC(void); extern u32 sub_81C99D4(void); extern void sub_8199D98(void); extern void sub_81C7D28(void); -extern void sub_81C8FE0(void); extern u32 sub_81C9298(void); extern u32 sub_81C941C(void); extern u32 sub_81C9924(void); @@ -180,16 +195,22 @@ extern u32 sub_81D04B8(void); extern u32 sub_81D09F4(void); extern u32 sub_81CFA04(void); extern u32 sub_81CFE08(void); -extern u32 sub_81C91AC(struct UnknownSubStruct_81C81D4 *a0, const void *a1, void *a2, s32 a3); -extern u32 sub_81C9160(struct UnknownSubSubStruct_81C81D4 *a0, void *a1); -extern void sub_81C8ED0(void); extern void sub_81C7CB4(struct Sprite* sprite); extern void sub_81CBD48(u16 windowId, u32 a1); -extern void sub_81C8EF8(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownInnerStruct_81C81D4 *a1); -extern void sub_81C9008(struct UnknownInnerStruct_81C81D4 *a0, u32 a1); -extern void sub_81C8DBC(struct UnknownInnerStruct_81C81D4 *a0, u32 a1); -extern void sub_81C8E54(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownInnerStruct_81C81D4 *a1, u32 a2); +extern u8 *sub_81CAFD8(u16 a0, u32 a1); +extern void sub_81DB620(u32 windowId, u32 a1, u32 a2, u32 a3, u32 a4); +u32 sub_81C91AC(struct UnknownInnerStruct_81C81D4 *a0, const struct BgTemplate *a1, struct UnknownStruct_81C9160 *a2, s32 a3); +void sub_81C9160(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownStruct_81C9160 *a1); +void SpriteCB_MatchCallUpArrow(struct Sprite *sprite); +void SpriteCB_MatchCallDownArrow(struct Sprite *sprite); +void SpriteCB_MatchCallRightArrow(struct Sprite *sprite); +void ToggleMatchCallArrows(struct UnknownInnerStruct_81C81D4 *a0, u32 a1); +void sub_81C8FE0(struct UnknownInnerStruct_81C81D4 *a0); +void sub_81C8EF8(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownInnerStruct_81C81D4 *a1); +void sub_81C8ED0(void); +void sub_81C8E54(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownInnerStruct_81C81D4 *a1, u32 a2); +void PrintMatchCallFieldNames(struct UnknownInnerStruct_81C81D4 *a0, u32 a1); void sub_81C8D4C(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownInnerStruct_81C81D4 *a1); void sub_81C8CB4(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownInnerStruct_81C81D4 *a1); void sub_81C8B70(struct UnknownSubSubStruct_0203CF40 *a0, u32 a1, u32 a2); @@ -636,12 +657,103 @@ static const struct SpriteTemplate sUnknown_0861FB44 = .callback = SpriteCallbackDummy }; +static const u16 sMatchcallArrowPaletteData[] = INCBIN_U16("graphics/pokenav/arrows_matchcall.gbapal"); +static const u32 sMatchcallArrowSpriteSheetData[] = INCBIN_U32("graphics/pokenav/arrows_matchcall.4bpp.lz"); + +static const u8 sPokenavColors_0861FBE4[] = +{ + 0, 2, 5 +}; + +static const u8 *const sMatchCallFieldNames[] = +{ + gText_NavgearMatchCall_Strategy, + gText_NavgearMatchCall_TrainerPokemon, + gText_NavgearMatchCall_SelfIntroduction +}; + +static const u8 sMatchCallFieldColors[] = +{ + 1, 4, 5 +}; + +static const u8 sUnknown_0861FBF7[] = +{ + 2, 4, 6, 7, 0 +}; + +static const struct CompressedSpriteSheet sMatchcallArrowSpriteSheet[] = +{ + { + .data = sMatchcallArrowSpriteSheetData, + .size = 192, + .tag = 0xA + } +}; + +static const struct SpritePalette sMatchcallArrowPalette[] = +{ + { + .data = sMatchcallArrowPaletteData, + .tag = 0x14 + }, + {} +}; + +static const struct OamData sMatchCallRightArrowSpriteOam = +{ + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .bpp = ST_OAM_4BPP, + .shape = 2, //SPRITE_SHAPE(16x8), + .x = 0, + .size = 0, //SPRITE_SIZE(16x8), + .tileNum = 0, + .priority = 2, + .paletteNum = 0 +}; + +static const struct SpriteTemplate sMatchCallRightArrowSprite = +{ + .tileTag = 0xA, + .paletteTag = 0x14, + .oam = &sMatchCallRightArrowSpriteOam, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_MatchCallRightArrow +}; + +static const struct OamData sMatchCallUpDownArrowSpriteOam = +{ + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .bpp = ST_OAM_4BPP, + .shape = 1, //SPRITE_SHAPE(8x16), + .x = 0, + .size = 0, //SPRITE_SIZE(8x16), + .tileNum = 0, + .priority = 2, + .paletteNum = 0 +}; + +static const struct SpriteTemplate sMatchCallUpDownArrowSprite = +{ + .tileTag = 0xA, + .paletteTag = 0x14, + .oam = &sMatchCallUpDownArrowSpriteOam, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + EWRAM_DATA u8 gUnknown_0203CF3C = 0; EWRAM_DATA struct UnknownStruct_0203CF40 *gUnknown_0203CF40 = NULL; EWRAM_DATA u32 gUnknown_0203CF44 = 0; -extern const u8 gUnknown_0861FBE4[3]; - // code u32 sub_81C7078(u32 (*func)(s32), u32 priority) { @@ -1670,7 +1782,7 @@ void sub_81C817C(struct Sprite *sprite) } } -bool32 sub_81C81D4(const void *arg0, void *arg1, s32 arg2) +bool32 sub_81C81D4(const struct BgTemplate *arg0, struct UnknownStruct_81C9160 *arg1, s32 arg2) { u32 v1; struct UnknownSubStruct_81C81D4 *structPtr; @@ -1682,7 +1794,7 @@ bool32 sub_81C81D4(const void *arg0, void *arg1, s32 arg2) sub_81C9160(&structPtr->unk888, arg1); - v1 = sub_81C91AC(structPtr, arg0, arg1, arg2); + v1 = sub_81C91AC(&structPtr->unk0, arg0, arg1, arg2); if (v1 == 0) return FALSE; @@ -1700,7 +1812,7 @@ void sub_81C8234(void) struct UnknownSubStruct_81C81D4 *structPtr; structPtr = GetSubstructPtr(0x11); - sub_81C8FE0(); + sub_81C8FE0(&structPtr->unk0); RemoveWindow(structPtr->unk0.unk0.windowId); FreeSubstruct(0x11); } @@ -1807,13 +1919,13 @@ u32 sub_81C83F0(s32 a0) { case 0: v1 = (structPtr->unk0.unkA + structPtr->unk0.unkC + structPtr->unk10) & 0xF; - structPtr->unk34(structPtr->unk1C, structPtr->unk48); + structPtr->unk34(structPtr->unk1C, structPtr->unkTextBuffer); if (structPtr->unk38 != NULL) // Accessing unk0.windowId as if it were a u16...? // It's accessed as a u8 again in the very next line... structPtr->unk38(*(u16*)(&structPtr->unk0.windowId), structPtr->unk14, v1); - AddTextPrinterParameterized(structPtr->unk0.windowId, structPtr->unk0.unk5, structPtr->unk48, 8, (v1 << 4) | 1, 255, (void (*)(struct TextPrinterTemplate*, u16))a0); + AddTextPrinterParameterized(structPtr->unk0.windowId, structPtr->unk0.fontId, structPtr->unkTextBuffer, 8, (v1 << 4) + 1, 255, NULL); if (++structPtr->unk0.unkC >= structPtr->unk0.unkE) { @@ -2245,7 +2357,7 @@ u32 sub_81C8870(s32 a0) switch (a0) { case 0: - sub_81C9008(&structPtr->unk0, 1); + ToggleMatchCallArrows(&structPtr->unk0, 1); // fall-through case 1: if (structPtr->unk89C != structPtr->unk888.unk6) @@ -2299,19 +2411,19 @@ u32 sub_81C8958(s32 a0) sub_81C8CB4(&structPtr->unk888, &structPtr->unk0); break; case 1: - sub_81C8DBC(&structPtr->unk0, 0); + PrintMatchCallFieldNames(&structPtr->unk0, 0); break; case 2: sub_81C8E54(&structPtr->unk888, &structPtr->unk0, 0); break; case 3: - sub_81C8DBC(&structPtr->unk0, 1); + PrintMatchCallFieldNames(&structPtr->unk0, 1); break; case 4: sub_81C8E54(&structPtr->unk888, &structPtr->unk0, 1); break; case 5: - sub_81C8DBC(&structPtr->unk0, 2); + PrintMatchCallFieldNames(&structPtr->unk0, 2); break; case 6: sub_81C8E54(&structPtr->unk888, &structPtr->unk0, 2); @@ -2409,7 +2521,7 @@ u32 sub_81C8A28(s32 a0) return 1; return 9; case 6: - sub_81C9008(subPtr0, 0); + ToggleMatchCallArrows(subPtr0, 0); return 4; } } @@ -2483,24 +2595,249 @@ void sub_81C8C64(struct UnknownSubSubStruct_0203CF40 *a0, u32 a1) void sub_81C8CB4(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownInnerStruct_81C81D4 *a1) { - u8 buffer[ARRAY_COUNT(gUnknown_0861FBE4)]; + u8 colors[3]; - memcpy(buffer, gUnknown_0861FBE4, ARRAY_COUNT(gUnknown_0861FBE4)); + memcpy(colors, sPokenavColors_0861FBE4, ARRAY_COUNT(sPokenavColors_0861FBE4)); - a1->unk34(a0->unk10 + a0->unkC * a0->unk0, a1->unk48); + a1->unk34(a0->unk10 + a0->unkC * a0->unk0, a1->unkTextBuffer); a1->unk38(a1->unk0.windowId, a0->unk0, a1->unk0.unkA); FillWindowPixelRect(a1->unk0.windowId, PIXEL_FILL(4), 0, a1->unk0.unkA * 16, a1->unk0.unk4 * 8, 16); - AddTextPrinterParameterized3(a1->unk0.windowId, a1->unk0.unk5, 8, (a1->unk0.unkA * 16) + 1, buffer, TEXT_SPEED_FF, a1->unk48); + AddTextPrinterParameterized3(a1->unk0.windowId, a1->unk0.fontId, 8, (a1->unk0.unkA * 16) + 1, colors, TEXT_SPEED_FF, a1->unkTextBuffer); sub_81C8C64(&a1->unk0, 1); CopyWindowRectToVram(a1->unk0.windowId, 3, 0, a1->unk0.unkA * 2, a1->unk0.unk4, 2); } void sub_81C8D4C(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownInnerStruct_81C81D4 *a1) { - a1->unk34(a0->unk10 + a0->unkC * a0->unk0, a1->unk48); + a1->unk34(a0->unk10 + a0->unkC * a0->unk0, a1->unkTextBuffer); FillWindowPixelRect(a1->unk0.windowId, PIXEL_FILL(1), 0, a1->unk0.unkA * 16, a1->unk0.unk4 * 8, 16); - AddTextPrinterParameterized(a1->unk0.windowId, a1->unk0.unk5, a1->unk48, 8, a1->unk0.unkA * 16 + 1, TEXT_SPEED_FF, NULL); + AddTextPrinterParameterized(a1->unk0.windowId, a1->unk0.fontId, a1->unkTextBuffer, 8, a1->unk0.unkA * 16 + 1, TEXT_SPEED_FF, NULL); sub_81C8C64(&a1->unk0, 0); CopyWindowToVram(a1->unk0.windowId, 3); +} + +void PrintMatchCallFieldNames(struct UnknownInnerStruct_81C81D4 *a0, u32 fieldId) +{ + const u8 *fieldNames[3]; + u8 colors[3]; + u32 r4; + u32 r5; + u32 tmp; + u32 one; + + memcpy(fieldNames, sMatchCallFieldNames, sizeof(sMatchCallFieldNames)); + memcpy(colors, sMatchCallFieldColors, sizeof(sMatchCallFieldColors)); + + r4 = a0->unk0.unkA; + tmp = fieldId * 2 + 1; + r4 += tmp; + r4 &= 0xF; + FillWindowPixelRect(a0->unk0.windowId, PIXEL_FILL(1), 0, r4 << 4, a0->unk0.unk4, 16); + + // This is a fake match. It should be this: + // AddTextPrinterParameterized3(a0->unk0.windowId, 7, 2, r4 << 4 + 1, colors, TEXT_SPEED_FF, fieldNames[fieldId]); + // But the original GCC does some clever reuse of the `1` constant that the current GCC doesn't. + one = 1; + AddTextPrinterParameterized3(a0->unk0.windowId, 7, 2, (r4 << 4) + one, colors, one - 2, fieldNames[fieldId]); + CopyWindowRectToVram(a0->unk0.windowId, 2, 0, r4 << 1, a0->unk0.unk4, 2); +} + +void sub_81C8E54(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownInnerStruct_81C81D4 *a1, u32 a2) +{ + const u8 *str; + u32 r6; + + r6 = (a1->unk0.unkA + sUnknown_0861FBF7[a2]) & 0xF; + + str = sub_81CAFD8(a0->unk0, a2); + if (str != NULL) { + sub_81DB620(a1->unk0.windowId, 1, r6 * 2, a1->unk0.unk4 - 1, 2); + AddTextPrinterParameterized(a1->unk0.windowId, 7, str, 2, (r6 << 4) + 1, TEXT_SPEED_FF, NULL); + CopyWindowRectToVram(a1->unk0.windowId, 2, 0, r6 * 2, a1->unk0.unk4, 2); + } +} + +void sub_81C8ED0(void) +{ + u32 i; + const struct CompressedSpriteSheet *ptr; + + for (i = 0, ptr = sMatchcallArrowSpriteSheet; i < ARRAY_COUNT(sMatchcallArrowSpriteSheet); ptr++, i++) + { + LoadCompressedSpriteSheet(ptr); + } + sub_81C795C(sMatchcallArrowPalette); +} + +void sub_81C8EF8(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownInnerStruct_81C81D4 *a1) +{ + register u32 spriteId asm("r3"); + s16 temp; + + spriteId = (u8)CreateSprite(&sMatchCallRightArrowSprite, a1->unk0.unk2 * 8 + 3, (a1->unk0.unk3 + 1) * 8, 7); + a1->rightArrow = &gSprites[spriteId]; + + temp = a1->unk0.unk2 * 8 + (a1->unk0.unk4 - 1) * 4; + spriteId = (u8)CreateSprite(&sMatchCallUpDownArrowSprite, temp, a1->unk0.unk3 * 8 + a0->unk8 * 16, 7); + a1->downArrow = &gSprites[spriteId]; + a1->downArrow->oam.tileNum += 2; + a1->downArrow->callback = SpriteCB_MatchCallDownArrow; + + spriteId = (u8)CreateSprite(&sMatchCallUpDownArrowSprite, temp, a1->unk0.unk3 * 8, 7); + a1->upArrow = &gSprites[spriteId]; + a1->upArrow->oam.tileNum += 4; + a1->upArrow->callback = SpriteCB_MatchCallUpArrow; +} + +void sub_81C8FE0(struct UnknownInnerStruct_81C81D4 *a0) +{ + DestroySprite(a0->rightArrow); + DestroySprite(a0->upArrow); + DestroySprite(a0->downArrow); + FreeSpriteTilesByTag(0xA); + FreeSpritePaletteByTag(0x14); +} + +void ToggleMatchCallArrows(struct UnknownInnerStruct_81C81D4 *a0, bool32 shouldHide) +{ + if (shouldHide) + { + a0->rightArrow->callback = SpriteCallbackDummy; + a0->upArrow->callback = SpriteCallbackDummy; + a0->downArrow->callback = SpriteCallbackDummy; + } + else + { + a0->rightArrow->callback = SpriteCB_MatchCallRightArrow; + a0->upArrow->callback = SpriteCB_MatchCallUpArrow; + a0->downArrow->callback = SpriteCB_MatchCallDownArrow; + } + a0->rightArrow->invisible = shouldHide; + a0->upArrow->invisible = shouldHide; + a0->downArrow->invisible = shouldHide; +} + +void SpriteCB_MatchCallRightArrow(struct Sprite *sprite) +{ + struct UnknownSubStruct_81C81D4 *structPtr; + structPtr = GetSubstructPtr(0x11); + sprite->pos2.y = structPtr->unk888.unk6 << 4; +} + +void SpriteCB_MatchCallDownArrow(struct Sprite *sprite) +{ + if (sprite->data[7] == 0 && sub_81C84C0()) + sprite->invisible = FALSE; + else + sprite->invisible = TRUE; + + if (++sprite->data[0] > 3) + { + s16 offset; + + sprite->data[0] = 0; + offset = (sprite->data[1] + 1) & 7; + sprite->data[1] = offset; + sprite->pos2.y = offset; + } +} + +void SpriteCB_MatchCallUpArrow(struct Sprite *sprite) +{ + if (sprite->data[7] == 0 && sub_81C84A4()) + sprite->invisible = FALSE; + else + sprite->invisible = TRUE; + + if (++sprite->data[0] > 3) + { + s16 offset; + + sprite->data[0] = 0; + offset = (sprite->data[1] + 1) & 7; + sprite->data[1] = offset; + sprite->pos2.y = -1 * offset; + } +} + +void ToggleMatchCallVerticalArrows(bool32 shouldHide) +{ + struct UnknownSubStruct_81C81D4 *structPtr; + structPtr = GetSubstructPtr(0x11); + structPtr->unk0.upArrow->data[7] = shouldHide; + structPtr->unk0.downArrow->data[7] = shouldHide; +} + +void sub_81C9160(struct UnknownSubSubStruct_81C81D4 *a0, struct UnknownStruct_81C9160 *a1) +{ + u32 unused1 = a0->unk10 = a1->unk0; + u32 v0 = a1->unk6; + u32 zero = 0; + u32 unused2 = a0->unk0 = v0; + u32 v1 = a0->unk2 = a1->unk4; + + a0->unkC = a1->unk8; + a0->unk8 = a1->unkC; + if (a0->unk8 >= (u16)v1) + { + a0->unk0 = 0; + a0->unk4 = 0; + a0->unk6 = v0; + } + else + { + s32 v2; + a0->unk4 = a0->unk2 - a0->unk8; + v2 = a0->unk0 + a0->unk8; + if (v2 > a0->unk2) { + a0->unk6 = v2 - a0->unk2; + a0->unk0 = v0 - a0->unk6; + } + else + { + a0->unk6 = 0; + } + } +} + +u32 sub_81C91AC(struct UnknownInnerStruct_81C81D4 *a0, const struct BgTemplate *a1, struct UnknownStruct_81C9160 *a2, s32 a3) +{ + register u32 raw_bg asm("r4") = ((a1->bg) << 30); + u8 bg = raw_bg >> 30; + u32 unknown = 0; + struct WindowTemplate template; + u8 bg_again; + + a0->unk0.bg = bg; + a0->unk0.unk6 = a3; + a0->unk34 = a2->unk10; + a0->unk38 = a2->unk14; + a0->unk0.unk1 = a2->unkD; + a0->unk0.unk2 = a2->unk9; + a0->unk0.unk3 = a2->unkB; + a0->unk0.unk4 = a2->unkA; + a0->unk0.fontId = a2->unkE; + + template.bg = raw_bg >> 30; + template.tilemapLeft = a2->unk9; + template.tilemapTop = 0; + template.width = a2->unkA; + template.height = 32; + template.paletteNum = a2->unkD; + template.baseBlock = a3 + 2; + + a0->unk0.windowId = AddWindow(&template); + if (a0->unk0.windowId == 0xFF) + { + return 0; + } + else + { + a0->unk0.unkA = unknown; + a0->rightArrow = NULL; + a0->upArrow = NULL; + a0->downArrow = NULL; + return 1; + } } \ No newline at end of file diff --git a/src/strings.c b/src/strings.c index f81a19083c..c4266a1352 100644 --- a/src/strings.c +++ b/src/strings.c @@ -962,9 +962,9 @@ const u8 gUnknown_085EBE7D[] = _("DETAIL"); const u8 gUnknown_085EBE84[] = _("CALL"); const u8 gUnknown_085EBE89[] = _("EXIT"); const u8 gUnknown_085EBE8E[] = _("Can't call opponent here."); -const u8 gUnknown_085EBEA8[] = _("STRATEGY"); -const u8 gUnknown_085EBEB1[] = _("TRAINER'S POKéMON"); -const u8 gUnknown_085EBEC3[] = _("SELF-INTRODUCTION"); +const u8 gText_NavgearMatchCall_Strategy[] = _("STRATEGY"); +const u8 gText_NavgearMatchCall_TrainerPokemon[] = _("TRAINER'S POKéMON"); +const u8 gText_NavgearMatchCall_SelfIntroduction[] = _("SELF-INTRODUCTION"); const u8 gText_Navgear_ClearButtonList[] = _("{CLEAR 0x80}"); const u8 gText_NavgearMap_ZoomedOutButtons[] = _("{A_BUTTON}ZOOM {B_BUTTON}CANCEL"); const u8 gText_NavgearMap_ZoomedInButtons[] = _("{A_BUTTON}FULL {B_BUTTON}CANCEL");