Jump to content

wwylele

Member
  • Posts

    3
  • Joined

  • Last visited

Everything posted by wwylele

  1. Sorry for my misunderstanding and thanks. I really learn something new every times. The adrress contained in R3 can be different for each track (it is also stored in the pointer R2+0x54), and can be changed when changing BGM. The memory located at R2 I call it "track controller structure". I don't know if you've found it and how you call it. There is an array of "track controller structures", begin at 0x02291D28, and 0x5C bytes for each, corresponding to each track. The event handler receives R2 as the pointer to an element in the array. Another structure array is located after "track controller structure array"( it is not static), 0xC8 bytes for each element. The parameter R3 is the pointer to an element in this array. I will call these structures "R3 structure". For example, BGM#1(Pokémon Exploration Team Theme), the parameters that each track pass to event handlers (including E0 and E3) are: track0: R2=0x02291D28, R3=0x02292370 track1: R2=0x02291D84, R3=0x02292370 track2: R2=0x02291DE0, R3=0x02292438 track3: R2=0x02291E3C, R3=0x02292500 track4: R2=0x02291E98, R3=0x022925C8 ... My R3+0x18 is not the same as your R5+0x18, for different address and different behavior. I didn't dig deeply into swd files, so I can't help much about volume envelope.
  2. I disassembled the event handler for 0xE0 and 0xE3 and try understanding them. Here is my note for assembly code of 0xE0 handler (0xE3 is quite similar) /* Event Handler Parameter: R0 event sequance pointer R2 "Track Controller Structure" pointer R3 "Audio Output Structure?" pointer R3+0x18 (the final volume?)written by both event E0 and E3 R3+0x2C (the volume?)written by event E0(=parameter<<16), read by event E3 R3+0x34 (the volume?)written by event E0(=parameter<<16) R3+0x38 cleared by event E0 R3+0x50 (the expression?) read by event E0, written by event E3(=parameter) R3+0xB4 (a linked list head pointer?) read by both event E0 and E3 R3+0xC4 (a pointer, to the main audio output controller?) read by both event E0 and E3 */ ============================================================================ 0207227C(Event E0 Handler) 0207227C STMDB SP!,{R3-R5,LR} 02072280 LDRSB R4,[R0,#0]//r4=parameter (as signed byte) 02072284 MOV R5,#0//r5=0 02072288 LDR R2,[02072308]//r2=0x82061029(whats this...) 0207228C MOV R1,R4,LSL #10//r1=r4<<0x10 02072290 STR R1,[R3,#34]//*(u32*)(r3+0x34)=r1(=parameter<<16)(store the track valume) 02072294 STR R1,[R3,#2C]//*(u32*)(r3+0x2C)=r1(=parameter<<16)(also store the track valume?) 02072298 STRH R5,[R3,#38]//*(u16*)(r3+0x38)=r5(=0) 0207229C LDR R12,[R3,#C4]//r12=*(u32*)(r3+0xC4) (= pointer to main audio controller?) 020722A0 LDRB R1,[R3,#50]//r1=*(u8*)(r3+0x50)( =track expression) 020722A4 LDRSB LR,[R12,#8]//LR=*(s8*)(r12+8) ( =main volume? it's often 0x7F in memory and decrease its value when the bgm fades out) 020722A8 LDR R12,[0207230C]//r12=0x04000208(=Register_IME) //The following code looks like mixing the track volume ,expression and main volume together //But by a quite strange method //Note: now r1=track_expression, r4=track_volume, lr=main_volume? 020722AC SMULBB R1,R4,R1//r1*=r4 020722B0 MUL R4,LR,R1//r4=LR*r1 020722B4 SMULL R1,LR,R2,R4//(u64)(r1,LR)=r2*r4? 020722B8 ADD LR,R4,LR//LR+=r4 020722BC MOV R1,R4,LSR #1F//r1=r4>>0x1F 020722C0 ADD LR,R1,LR,ASR #D//LR=r1+(LR>>0xD) 020722C4 STRH LR,[R3,#18]//*(u16*)(r3+0x18)=LR (store final volume?) 020722C8 LDRH R4,[R12,#0]//r4=*(u16*)0x04000208(Get current IRQs state) 020722CC STRH R5,[R12,#0]//*(u16*)0x04000208=r5(=0)(Disable IRQs) 020722D0 LDR R2,[R3,#B4]//r2=*(u32*)(r3+0xB4) //r2 looks like a linked list pointer 020722D4 CMP R2,#0 020722D8 BEQ 020722F4 //while(r2!=0){ //This loop looks like notifying every members in the list 020722DC LDRH R1,[R2,#6]//r1=*(u16*)(r2+6) 020722E0 ORR R1,R1,#20//r1|=0x20 020722E4 STRG R1,[R2,#6]//*(u16*)(r2+6)=r1 020722E8 LDR R2,[R2,#154]//r2=*(u16*)(r2+0x154) 020722EC CMP R2 #0 020722F0 BNE 020722DC //} 020722F4 LDR R2,[0207230C]//r2=0x04000208 020722F8 ADD R0,R0,#1//R0+=1 (r0 is the event sequance pointer) 020722FC LDRH R1,[R2,#0] r1=*(u16*)0x04000208 02072300 STRH R4,[R2,#0] *(u16*)0x04000208=r4(Restore IRQs state) 02072304 LDMIA SP!,{R3-R5,PC}//return As you can see, the volume envelope staff looks strange, computing with a magic number 0x82061029. I think maybe it is just "final_volume=track_volume*expression*main_volume/something;", which is in the most common way. Because ARM doesn't support division directly, it computes like that. But if it is not the correct way to envelop the volume, I have no more idea at present.
  3. Hello, I was working on SMD files of PMD2 these days, and found this forum by chance. You really did a great job! I particularly read this note (not knowing if it is the most-updated one):https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/PMD2_MusicAndSoundFormats.txt It helps me a lot. Also, everything I've been found before match with yours well, except for the following: The bold sentence is difference from what I found. I found that it is (expressed in your way): - 0x0( 0000 ) : The note is played at TWO octaves LOWER the current pitch, and the current pitch is now equal to that I came up with this by checking the code that handles the pitch changing: 020712A0 E5CD3003 strb r3,[r13,3h] 020712A4 E5D01000 ldrb r1,[r0] // r1 now is the first parameter of play event 020712A8 E5D65004 ldrb r5,[r6,4h] //r5 now is the current pitch 020712AC E3A0300C mov r3,0Ch 020712B0 E1A02A01 mov r2,r1,lsl 14h //r2=r1<<0x14; 020712B4 E1A02C42 mov r2,r2,asr 18h //r2>>=0x18 //now r2 is the high nybble of the first parameter 020712B8 E2022003 and r2,r2,3h //now r2 is 2 lowest bits of the nybble (pitch change field) //The following code really confused me, but I believe that it is just "r5+=r2-2;" 020712BC E2422002 sub r2,r2,2h //r2-=2; 020712C0 E1A02C02 mov r2,r2,lsl 18h//r2<<=0x18; 020712C4 E0852C42 add r2,r5,r2,asr 18h//r2=r5+(r2>>0x18); 020712C8 E1A02C02 mov r2,r2,lsl 18h //r2<<=0x18; 020712CC E1A05C42 mov r5,r2,asr 18h //r5=r2>>0x18; 020712D0 E201200F and r2,r1,0Fh 020712D4 E1022385 smlabb r2,r5,r3,r2 020712D8 E5CD2002 strb r2,[r13,2h] 020712DC E1A01341 mov r1,r1,asr 6h 020712E0 E5C65004 strb r5,[r6,4h] // Store the new pitch Hope it can help. If you have found it, just ignoring me is fine. EDIT: Oops, find this has been fixed in the post above...How can I reply without reading posts carefully... Anyway I love your research. Wish you make more great process.
×
×
  • Create New...