• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Mugshots via ASM

Kyoko1

Banned
63
Posts
10
Years
    • Seen Feb 27, 2014

    Mugshots via ASM


    This time I would like to present you an improved version of my old tutorial..
    Now the ASM reads from a table, which contains image pointer, palette pointer and pal-#.
    I will explain you all the variables you must use and the table later.



    We need:

    thumb compiler
    loading.asm
    removing.asm

    You also need inserted 64x64 sized mugshots and palettes for them.
    If you don't know how to make this, visit my old tutorial here.
    Its explained step-by-step there.



    Building up the table

    Open up your preferred hex-editor and load your ROM in it.
    Now go to a location with much free space. I would recommend you
    to keep space for lets say 0x180 bytes, which allows 32 mugshot-entries.

    The table must be built up like this:
    Code:
    [image-pointer][palette-pointer][pal#][00 00 00]
    First you need to reverse your image-offset and write it there, do the same
    with the palette offset. But what is pal#? Well, we have access to 15 OAM palettes.
    You can decide, which of these OAM palettes you want to use for this mugshot.
    (Don't write a higher value than 0xF for this, or it crashes! [no more than 15 pals])

    And if you don't know how to reverse offsets:

    Let's say I got an image at 0xABCDEF and a palette at 0x123456
    I split the offsets up into 3 parts: [AB] [CD] [EF] // [12] [34] [56]
    Then I change the first and last block: [EF] [CD] [AB] // [56] [34] [12]
    At last we add 08 behind it: EF CD AB 08 // 56 34 12 08

    For example, my table could look like this:
    Code:
    [COLOR=DarkRed]EFCDAB08[/COLOR][COLOR=Navy]56341208[/COLOR][COLOR=Green]0E[COLOR=Purple]000000
    [COLOR=Black][image][palette][pal#][filler][/COLOR][/COLOR][/COLOR]
    Now repeat that for as much mugshots as you want.
    Remember: The first entry of the table is INDEX 0x0.
    The 2nd entry is INDEX 0x1 and so on.

    Currently its only possible to display max. 2 images at the same time.
    I failed at making the OAM-data 100 % dynamically in the RAM.
    I will for sure fix this at the next version, as I nearly finished it.



    Editing the ASM code

    This time it gets easy:
    Code:
    .equ TABLE, 0x08(TABLE)
    Replace (TABLE) with your table-offset in the ROM.

    And the last thing you must do is changing all [OFFSET_OF_THIS_CODE]
    to the offset you are going to insert this ASM code.
    If you want it to insert it to
    0x800000 for example, you
    replace all [OFFSET_OF_THIS_CODE] with800000.

    At the next version you don't need to do this..
    For now you must
    1.%20smile.gif


    If you have done that, download the thumb.zip if you haven't done so before.
    Extract it for example on your desktop.
    Now put in the Loading.asm and Removing.asm into this folder.

    Drag and Drop the Loading.asm to thumb.bat and the Removing.asm too.
    You should get the files "Loading.bin" and "Removing.bin".

    Open these 2 files and your ROM in your preferred hex-editor.
    Firstly, mark all bytes in the Loading.bin. Copy them by pressing CTRL+C and
    swap to the tab where your ROM is.
    Go to the offset, which you inserted at "
    [OFFSET_OF_THIS_CODE]" in the code.
    Mark 0x11C bytes and press CTRL+V to replace our codes with the FF's.

    Now swap over to the Removing.bin. Again, mark all bytes of the Removing.bin.
    After that mark 0x40 bytes in your ROM file (right after the Loading.bin was) and
    replace our Removing.bin with the FF's.

    Note down the offsets where you inserted the 2 codes in the ROM and add +1 to them.
    (F.E: 0x800000 gets to 0x800001; 0x83210C gets to 0x83210D)

    Open AdvanceMap and XSE.
    Write a script in XSE, which contains:


    Code:
    #dynamic 0x750000
    #org @testscript
    setvar 0x4500 0x0
    setvar 0x4501 0x0
    setvar 0x4502 0x0
    callasm 0x(offset_of_your_loading.bin) +1 
    msgbox @text 0x6
    callasm 0x(offset_of_your_removing.bin)
    Code:
    [COLOR=DarkGreen][COLOR=black][COLOR=black]+1
    end
    
    #org @text
    = TEST.[/COLOR][/COLOR][/COLOR]
    For explanation:

    Code:
    @/* VAR 0x4500 = SPRITE INDEX IN TABLE     */@
    @/* VAR 0x4501 = LEFT OR RIGHT SIDE?        */@
    @/* VAR 0x4502 = SPRITE SLOT IN SCRIPT        */@
    At 0x4500, you choose your sprite which you want to load.
    If you set this variable to 0x0, the first table-entry will be loaded.
    If you set it to 0x1, the second will be loaded and so on.

    At 0x4501 you can decide whether the mugshot should be on the
    left or right side of the textbox: left = 0x0; right = 0x1

    At 0x4502 you MUST write the sprite slot in the script.
    If you are loading 1 mugshot in the script, you must set this var to 0x0
    If you are loading another mugshot in the same script, you must set to 0x1!

    Example of loading 2 sprites (like they are speaking with each other:

    Code:
    #dynamic 0x750000
    #org @testscript
    setvar 0x4500 0x0                              'first sprite
    setvar 0x4501 0x0                              'left
    setvar 0x4502 0x0                              'this sprite is the 1st one
    callasm 0x(offset_of_your_loading.bin) +1
    setvar 0x4500 0x1                              'second sprite
    setvar 0x4501 0x1                              'right
    setvar 0x4502 0x1                              'this sprite is the 2nd one
    callasm 0x(offset_of_your_loading.bin) +1
    msgbox @text 0x6
    callasm  0x(offset_of_your_removing.bin) +1
    end
    
    #org @text
    = TEST.
    Let's check out the result:
    Spoiler:


    Ofc the mugshots don't fit but I can't sprite, so..




    Ending words


    Thanks again for reading this tutorial and good luck on your romhack with it!
    If you got any problem, feel free to ask in this thread. DON'T send me PMs!

    I guess one or another person will have a question, because I didn't have any pictures
    while explaining this times (too lazy
    12.%20tongue.gif
    )
    Will check this thread out daily, so don't hesitate to ask here!

    Give credits if you use this hack to:
    -Kyoko1
    -knizz (for research on OAM)

    Original Tutorial:


    Spoiler:
     
    Last edited by a moderator:

    ShyRayq

    Unprofessional Unprofessional
    1,856
    Posts
    16
    Years
    • Seen Apr 2, 2024
    This is pretty good stuff here! Good work.
    I only glanced over just now, but I didn't see anything about a table or anything.
    How would you do multiple mugshots? Using a table that could be read would be easy, but if you had to reinsert the ASM routine every time, that's just troublesome.
    Also, say you want a mugshot on the right side of the screen?
    Just want some clarifications.
     

    Kyoko1

    Banned
    63
    Posts
    10
    Years
    • Seen Feb 27, 2014
    I could make the code use a table by using a variable that the player has to set before
    the callasm (setvar 0xXXXX 0xY or something) but that would be a little more complicated ;)
    I will see what I can do, though I can't fulfill every single wish :P

    Also, say you want a mugshot on the right side of the screen?
    Change this part:

    Code:
    Object_Load:
    ldr r0, DATA
    mov r1, #0x30
    mov r2, #0x53
    mov r3, #0x0
    mov r1, #0x30 is the X-koordinate of the object.
    Change it to #0x88 to make it appear on the right side ^.^

    To display multiple mugshots, you can call the routine 2 times, but with different koordinates.
    The problem with that one is, that both mugshots use the same palette.
    To change this, you must call the OAM Buffer and change some things there..
    I will for sure update this tut for your wishes :)


    ________________________________________________________________________________

    Ok guys, table reading and multiple sprite showing works now!
    You can now have up to 255 mugshot entries and you can show a maximum of 2 mugshots.

    This evening I will post an update on the tutorial!

    f0dzs2.png
     
    Last edited:

    Sniper

    ふゆかい
    1,412
    Posts
    10
    Years
  • Awesome, now I know how they do it in some hack. Well, I suck at ASM so I'll do the best I can in sometime if I think this would be nice in my work :)
     

    Kyoko1

    Banned
    63
    Posts
    10
    Years
    • Seen Feb 27, 2014
    Thanks.

    Btw, there seems to be a problem with the routine for multiple mugshots.
    Somehow the routine of gamefreak doesn't leave me the OAM number in r0..
    It's needed for deleting the object afterwards.. :(
     
    249
    Posts
    11
    Years
    • Seen Apr 22, 2024
    a suggestion?
    in my hack for mughsot use a different method.
    I made a table of the mugshot and a table for the palette and the load two mugshot in BG0.
    Spoiler:

    i'm not expert but you and your tutorial are amazing :D good job.
     

    Kyoko1

    Banned
    63
    Posts
    10
    Years
    • Seen Feb 27, 2014
    The problem is, that the usage of showpokepic seems not to work in FR.
    (you are using ruby, right?)
    Thats why i have to use the object-way ;)

    My idea of a table is this:

    Code:
    .equ TABLE, 0x08[ROMOFFSET]
    .equ VAR, 0x020370B8
    
    Table_Reading:
    push {r0-r7, lr}
    ldr r3, =VAR
    ldrb r0, [r3]
    mov r2, #0x8
    mul r0, r0, r2
    ldr r1, =TABLE
    add r1, r1, r0
    mov r5, r1
    ldr r0, [r1]
    swi 0x12

    In the script, you can set a variable (in my case 0x8000) for the sprite slot you want to use.
    Then it calculates (from the table) where the pointers of the images are.
    Then I load this pointer into R0 (= destination offset of SWI 0x12) and yeah..

    Later in my code, it reads right behind the image pointer the palette pointer.
    So my table looks like:
    [IMAGEPOINTER1][PALETTEPOINTER1][IMAGEPOINTER2][PALETTEPOINTER2]..
     
    16
    Posts
    10
    Years
  • Nice work! This was once thought impossible on FireRed, but I guess with enough ASM knowledge, the boundaries for creativity is far lengthened. I wish I knew how to write ASM routines. Only problem I see is how the head is sort of cut-off, making it look rather weird.
    But anyways, I'll give this tutorial a shot when I can find time :3
     

    Kyoko1

    Banned
    63
    Posts
    10
    Years
    • Seen Feb 27, 2014
    The head is "cut off" because the image, I inserted, exactly looks like this ;)
    Open the picture in paint or something and compare the pixels.. its 64px high ^.^
     

    Kyoko1

    Banned
    63
    Posts
    10
    Years
    • Seen Feb 27, 2014
    Unfortunatly, the GBA supports only up to 64x64 for OBJ. ;)

    And btw, funny idea, dear mods.
    Please look up in the thread guys, there is now the TABLE-ASM-CODE!

    If you need to have sprite and palette insertion step by step, click
    the original thread spoiler below!
     

    GoGoJJTech

    (☞゚ヮ゚)☞ http://GoGoJJTech.com ☜(゚ヮ゚☜)
    2,475
    Posts
    11
    Years
  • Hey. I have another method that takes a LOT less space but only supports one at a time. Maybe I can post it and you look through it?
     

    Kyoko1

    Banned
    63
    Posts
    10
    Years
    • Seen Feb 27, 2014
    If you try to not make it via objects, you can only display one at a
    time and your textbox will be overwritten.. -> where is sense?

    And no, post it in a seperate thread of yours, please.
     
    84
    Posts
    14
    Years
    • Seen Jun 6, 2014
    would it be possible to modify the transparency for one of the images to direct who's speaking? or would it be something to just specify in the dialogue
     

    Kyoko1

    Banned
    63
    Posts
    10
    Years
    • Seen Feb 27, 2014
    There are more possibilities which you can do yourself, without knowing ASM.

    - Make a kind of direct speech and write "Name:" that we know whos speaking
    - Let the one image appear when the one is speaking, let the other appear when
    the other person is speaking.
    Spoiler:
    - Make a darker palette for each sprite and load them how you need it currently

    I will see if I can improve this though..
     
    84
    Posts
    14
    Years
    • Seen Jun 6, 2014
    yeah, that's kinda what i was thinking of
    thanks for following up
     

    Kyoko1

    Banned
    63
    Posts
    10
    Years
    • Seen Feb 27, 2014
    I think it doesn't work with FR. Mugshots dont show, help me, please!

    Well it should work ONLY with FR ;)
    Tell me exactly what happens.
    Open in VBA -> Tools -> OAM viewer
    and
    VBA -> Tools -> Memory viewer (Offset 0x7000000)

    Send me a screen of both and share your modified ASM code.
     

    mrtienduc1999

    Banned
    37
    Posts
    11
    Years
  • I got a pokemon font 64x64 in rom.
    Table:
    Code:
    80337E0890377E0800000000
    Offset loading: 0x29f774
    Offset Remove: 0x294890
    Script XSE:
    Code:
    #Dynamic 0x800000
    
    #Org @Start
    setvar 0x4500 0x0
    setvar 0x4501 0x0
    setvar 0x4502 0x0
    callasm 0x29f775
    msgbox @string 0x6
    callasm 0x294891
    end
    
    #org @string
    = ...
    OAM:
    th_oam_zps925c7d5f.png

    Memory:
    th_mem_zps98a2c39f.png

    -I do all step, but not show!
     
    Back
    Top