You are not logged in.
That means you did not include mon_party_sprites2.asm correctly.
I literally just copy/pasted from your main.asm
Added the gfx/party_mon_sprites2
Added engine/mon_party_sprites.asm, engine/mon_party_sprites2.asm, and engine/menu/party_menu.asm.
Added wEvolutionData to wram.asm
PartyMonSprites: INCBIN "gfx/party_mon_sprites.2bpp",$0,$4000
Last edited by Konsty (2015-10-18 04:09:58)
I'm getting a "Section 'bank32' is too big" error when I try this.
I am attempting to do this also, and get the error:
ERROR: red/main.asm(2) -> main.asm(4760) -> engine/menu/party_menu.asm(34) :
Macro 'coord' not defined
I'm not entirely sure why this would happen as the original party_menu.asm also used "coord" and had no problems???? Nothing has really changed that would have affected this so...
Last edited by KeiTaRo (2016-02-16 12:38:56)
Thanks for your response! I'm still really new to this, so I appreciate the help. Trying my best to learn as I go. Curious, what is the reason for using hlCoord instead of coord hl in this case (since the original seemed like it used to work, but no longer does?) Also, when attempting your fix, it gives me a different error now:
rgblink -n pokered.sym -o pokered.gbc red/audio.o red/main.o red/text.o red/wram.o
C:\pokered\cygwin64\usr\local\bin\rgblink.exe: Unknown symbol 'Func_71882'
I've really reached a dead end with this error. It seems Shichirobei had this same issue but I'm not sure if I really understood the fix. Danny-E 33 mentions that he may have been copying old code, but I was using Danny-E 33's code :P so I assume that would not be the case here. The only times I see Func_71882 mentioned even at all is in two seemingly unrelated files (naming_screen.asm and trade.asm)... using the code:
It shows up again in mon_party_sprites.asm in what I assumed was probably the culprit, but only in the comments. Also, this chunk of code does not differ from the vanilla PokeRed in this case, so I'm not sure why it would be an issue. it's listed on the following lines:
WriteMonPartySpriteOAMBySpecies: ; 71882 (1c:5882)
; Write OAM blocks for the party sprite of the species in
ld [hPartyMonIndex], a
ld a, [wMonPartySpriteSpecies]
ld [wOAMBaseTile], a
Again, I'm fairly new to this, so I apologize if I'm missing something obvious, but I'm treating this as a learning experience :P I feel like I'm missing a major step...also, I noticed that Danny-E 33's data/mon_party_sprites.asm is the same as the original....is that going to cause problems? do I need to define the new sprites somewhere? Again, I apologize if I'm asking obvious questions, I'd just like to learn as much as possible so I can hopefully be less reliant on others in the future x_x
also, if it helps to know what I've done so far, I've literally just replaced engine/mon_party_sprites.asm, engine/mon_party_sprites2.asm, and engine/menu/party_menu.asm with the ones Danny-E 33 provided. I added the approriate GFX file, and then added them to the end of main.asm by copying the code exactly as it was in the main.asm he also shared in this thread. To the best of my knowledge, I've been following the example code 1:1 (and yes, my game did compile before doing this...I was using pokered-gen-II if that has any bearing on this!)
I have not changed anything in any other file than what I've mentioned here. Really all I want to be able to do is just use the Pokemon menu icons from G/S/C :( so I guess what it comes down to is that I really just need it so the game displays two full sprite frames instead of two frames of mirrored halves. Surely it would be less complicated than all this?
Last edited by KeiTaRo (2016-02-16 22:25:32)
hlCoord is the old version of coord hl just like Func_71882 is the old version WriteMonPartySpriteOAMBySpecies. The code you're copying is old and some of the labels have been renamed since that code was written. Unknown symbol 'Func_71882' means that Func_71882 is referenced, but it does not exist. It indeed does not exist, because now it's called WriteMonPartySpriteOAMBySpecies. callba Func_71882 attempts to call a function called Func_71882, but since no such function exists, it doesn't know what to call. Replacing callba Func_71882 with callba WriteMonPartySpriteOAMBySpecies will fix this issue.
However, you'll run into one error like this one for every label mismatch. Copy-pasting his code straight away isn't going to work because there are a lot of functions and addresses whose labels have been updated since it was written nearly two years ago. You should stick to porting only the necessary changes of each file to your own repository, rather than the whole file because otherwise you're going to break everything. Then you would update all the labels that don't match their current name by looking at the most recent version of pokered. It's maybe a better idea to look at the related commits rather than the files. I think what you need is this commit and the nicknaming screen fix from this other commit.
Last edited by Crystal_ (2016-02-16 23:47:32)
So after playing around a bit, I decided to try and reuse the existing system and tweak it to do what I need. The way I'm intending to do it, I have each icon as an individual PNG of two animation frames versus the massive sheets I've seen used in other examples so far (laid out top to bottom, like the normal sprite sheets) since I intend to use the G/S/C icons ... works for me so far :) I then went and redid how the game displays the sprites (basically commented out the routine to check if it's the Helix and instead made it go directly to the asymmetrical sprite loading function)
I would like to be able to remap the sprite IDs to my custom icons now...Does anyone know where in the code the Helix gets assigned as Party Icon sprite ID 2? It's not located in the pointers with the others (goes straight from Ball to Clefairy...?) I've been looking around but I can't seem to figure out how it assigns the Helix sprite as a party icon in the first place. It appears that changing the pointer data for the menu Ball sprite directly affects the Helix, but only insofar as to what sprite graphics it loads...I noticed there was a function related to the two of them, but it appeared to only be animation related.
I'm actually not sure I completely understand how the stock party icon sprite are set up to begin with. At a glance, it seems like it simply goes in the order of the sprite ID's as defined in Sprite Constants, starting with the data for the first frame, then immediately followed by the data for the second frame. Weird thing here is that the sprites used by mon_ow_sprites.png seem to have separate pointers for their top and bottom halves......okay, so obviously that is less than ideal now that I have the sprites set up to be asymmetrical. The labels here are pretty good at explaining what all the various functions do, but I can't quite tell if there's any code at work which is setting which sprite ID's are behaving this way...between this and the Helix/Ball oddities, is there seriously just some sort of hardcoding going on for every entry? The ideal solution would be to just make them all behave like the Rhydon, I.E. the very first entry. Kinda feels like they took a really complicated approach to something that should have been pretty simple....
While I'm at it, I'm wondering if it is possible to expand the number of pointers in this table as well...the reason I ask is because after the pointer for the first frame of the last "MonPartySprites" character ("Quadraped"...?) it simply jumps back around to the Rhydon ("slowbro") sprite's second frame pointer...I'm sure it's just a matter of telling the game how many entries there are, but I can't quite figure out where that code is, either.
Last edited by KeiTaRo (2016-04-07 18:38:30)
Okay! Update on this issue: I was able to fix the issue with the pointers corresponding to only 1/4 of the sprite (updated the number for vSprites + [value] to be + $40 instead of + $20 from the previous) but still have no idea idea how to expand the pointer table or remove the weird functionality for the Ball and Helix entries...still, this is progress! yay!
It appears as though the second frame of every sprite is determined in the pointer table not by its physical location in the list but by the "vSprite + [value]" ...would appear whatever entry is + $400 higher than the previous entry's vSprite value become the second frame. I could be totally wrong, but by my experimenting, that is what I came across. It also severely limits how many sprites I could fit in to the list if this is true :( I will keep researching this further, unless anyone has any suggestions.
Figured it out! the answer is in the .animateSprite routine! specifically,
ld c, $40 ; amount to increase the tile id by
Increasing this means I can add on to the pointer table entries, it seems! yay! By how much? Guess I will find out :P The issue with the weird hardcoded Helix and Ball thing still stands
EDIT: Further update! under LoadMonPartySpriteGfxWithLCDDisabled, there is a "ld a, $1c" which hardcodes the entire number of entries in the pointer table. This too must be updated. That answers my question of how much I can increase it by, I guess (I hope?) Also, I was able to disable the routine which forces Ball and Helix in to a single bouncing frame as opposed to an animated sprite sprite, but still have no idea what code is at play to determine where the Helix entry is getting loaded from. If anyone has insight, that would be fantastic.
EDIT EDIT: .....oh....kay. So, it turns out all you need to do is set a pointer entry in the space between Ball and Fairy (and increase the table length to $1e) and make sure that it corresponds to vSprite + $80 and it automatically becomes assigned to the helix slot? wh....I'm not going to pretend I understand <i>how</i> this works, but it does work, so okay, not gonna argue.....heh. I'll probably write up a tutorial here in a bit on how to do all of this using the original icon engine.
Last edited by KeiTaRo (2016-04-08 23:58:22)
Update #30bajillion: Well, that was short-lived. Definitely do -not- do the above method of expanding the pointed table unless you enjoy having the font get overwritten in memory :V
back to the drawing board. I guess I will need to come up with a new method of loading the sprites in to memory than what the normal engine does.
Last edited by KeiTaRo (2016-04-09 08:04:45)
This might be of some help.
Originally, there are only 10 party menu sprite ids. Since there are so few, all 10 can be loaded into vram before exactly which sprites are needed is determined.
When the sprites are being loaded, the actual address of the helix sprite, OmanyteSprite (omanyte.2bpp), is never directly referenced since it is in rom immediately after BallSprite (ball.2bpp) which also must be loaded.
You might notice that MonPartySpritePointers references BallSprite, which is a single 2x2 tile image. Since each tile is $10 bytes, this image must be $40 bytes. But MonPartySpritePointers says to load $80 bytes starting at BallSprite. This guarantees that the helix sprite will be loaded and also that it will immediately follow the ball sprite in vram.
Secondly, GetPartyMonSpriteID gets the sprite id for the currently loaded pokemon from MonPartyData. Remember that valid numbers for this id are from 0 to 9. But before this routine returns the result in a, it actually returns the id << 2.
This guarantees that instead of returning $0, $1, $2, $3, $4, $5, $6, $7, $8, or $9, it returns $0, $4, $8, $c, $10, $14, $18, $1c, $20, or $24.
If you run the game in an emulator like bgb and open the vram viewer while the party menu is open, you will see that these values correspond to the tile ids of each sprite.
For example, SPRITE_HELIX has the value 2. So 2 << 2 is 8. In the vram viewer, tile $8 is the base tile for the helix sprite.
Next, you might notice that the return value (from GetPartyMonSpriteID) that is in register a immediately gets stored in wOAMBaseTile, which gets used by WriteAsymmetricMonPartySpriteOAM and WriteSymmetricMonPartySpriteOAM when constructing the oam data for each pokemon in your party.
I'm not sure how much of this helps clear up some of your confusion, but I hope some of this information is of use to you. It should at least solve the mystery of how the helix sprite gets correctly loaded and used.
That looks like the changes I was expecting to have to make!
Its been about a year and a half since I tinkered with this so I'm getting back in the saddle. Thanks for pointing that out!
I know this is an old post, but I want to add this sprite to the party menu, should I proceed to do aaall these steps?
(Btw, the same sprite is repeated serious times because I only want to add 1, just did it that way because is based on what I found on pokered)
Following up, as it appears I imported all of the changes correctly so its got to be something odd I missed; on switching the Pokemon in the menu, the newly positioned pokemon do not match their icons, they match their old icons. Anyone else run into this?
Take a look at the beginning of DrawPartyMenu_ in engine/menu/party_menu.asm:
DrawPartyMenu_: xor a ld [H_AUTOBGTRANSFERENABLED],a call ClearScreen call UpdateSprites callba LoadMonPartySpriteGfxWithLCDDisabled ; load pokemon icon graphics RedrawPartyMenu_:
RedrawPartyMenu_ is called after two mon switch positions. The party sprites don't have to be reloaded because in the original game, every one of the party sprites is already loaded, and the order of the sprites in memory is the same no matter what, regardless of the mon in your party.
In your hack where you have added a unique sprite for each mon, obviously not every sprite is in memory all at once. Instead, only the ones that are needed are loaded, and they are deliberately in the same order as the mon in your party. So the sprite graphics need to be reloaded.
Change the beginning of the routine to this:
DrawPartyMenu_: xor a ld [H_AUTOBGTRANSFERENABLED],a call ClearScreen call UpdateSprites RedrawPartyMenu_ReloadSprites: callba LoadMonPartySpriteGfxWithLCDDisabled ; load pokemon icon graphics RedrawPartyMenu_:
And in engine/menu/start_sub_menus.asm at the end of SwitchPartyMon, change `jp RedrawPartyMenu_` to `jp RedrawPartyMenu_ReloadSprites`
There we go :D
Its exactly as I expected, but not where I expected it to be :D I knew the routine wasn't reloading the new sprites right and was looking for somewhere the refresh occurred, but I was looking in the actual party_mon files~
Quick Edit: Any way to address the flicker/garbage that appears on the redraw?
Last edited by daMoose52 (2016-10-14 22:58:03)
I don't know what you mean by garbage.
For a split second, when it reloads the sprites, there's some garbage on the screen:
http://projectneo.retrogaminggear.com/i … licker.AVI
Hm, I've never seen something like that. Are you sure you disabled the LCD while writing to VRAM?
EDIT: If you pause the video just right, it's actually not garbage. It's the overworld. But no sprites are drawn and its using the party menu palettes.
Last edited by Danny-E 33 (2016-10-15 05:35:46)
Yup, routines have the LCD Disabled and re-enabled as appropriate.
My core ASM is a little old so the function names don't always line up but its there~ Both on the old routines and the ones I imported as a part of this feature.
Here's my initial portion of the party_mon.asm file:
DrawPartyMenu_: ; 12cd2 (4:6cd2) xor a ld [H_AUTOBGTRANSFERENABLED],a call ClearScreen call UpdateSprites ; move sprites RedrawPartyMenu_ReloadSprites: callba LoadPartyMonSprites ; load pokemon icon graphics ;callba Func_71791 ; load pokemon icon graphics RedrawPartyMenu_: ; 12ce3 (4:6ce3)
I do note the difference in the function name, but that's mostly a difference of age and not function. Here is that routine though, straight from your mon_party_sprite2.asm file in my build:
LoadPartyMonSprites: call DisableLCD ld de, vNPCSprites ld hl, wPartySpecies .loop ld a, [hli] cp $ff jr z, .done push hl call LoadPartyMonSprite pop hl jr .loop .done jp EnableLCD
Last edited by daMoose52 (2016-10-15 17:16:16)