Open a PVM in PVMEditSharp, go to Export Texture Pack, navigate to your mod's folder, create a Textures folder inside it, then select the Textures folder and hit OK.
Hi! I could use some help. I have two issues. (Sonic the Hedgehog 1) I'm following the guides on how to set up disassembly and whatnot, and I get to the editing art part. The problem is, I can't find artnem_u in the disassembly (git). I can in the Hivebrain one, but then when going to the next part (editing levels) It tells me to attempt to edit mz1, but when I build, the level has no background and the entire layout is glitched. What disassembly should I use, and how do I fix these issues?
In the GitHub disassembly, you have to decompress and recompress the files yourself, with a tool such as KENSSharp or FW-KENSC, whose Windows shell extensions I've linked. As for the level issue, I can't say, as I don't know which disassembly you're using, or what tool you're using, or what steps you're taking to edit, save, and build.
I apologize for being so vague! I used the Hivebrain disassembly, alongside SonED2, and I've been following the guides posted on the INFO section of SonicRetro. They've been giving me step by step, which was working perfectly until the issue I mentioned. But now taht I know that I need to compress/decompress myself, I should be able to fix.
I think I might need some help, as I'm cruddy when it comes to Sonic ASM's. I'm trying to add Special Stage Monitors, like Sonic Triple Trouble. I've used the instructions from Tamkis on how to do it , but in my s2.log, I have 2 errors: Code (Text): > > >s2.asm(23883): error: short addressing not allowed > > > move.b #1,(unk_F7CD).w > > >s2.asm(23883): error: addressing mode not allowed here > > > move.b #1,(unk_F7CD).w and this is where the error occured: Code (Text): loc_12AA6: teleport_monitor: ;** SS monitor cmpi.b #7,(Emerald_count).w ;Does main character have all 7 emeralds? bne.s warp_toSS ;If not, branch to goto Special Stage jsr super_ring ;give 10 rings jsr super_ring jsr super_ring jsr super_ring jsr super_ring ;=total of 10 ring warp_toSS: move.b #1,(unk_F7CD).w move.b #GameModeID_SpecialStage,(Game_Mode).w ; => SpecialStage rts; What does it mean by "short addressing not allowed" and "addressing mode not allowed here"? Did I misplace the "warp_toSS" function? Thanks in advance.
Does the label "unk_F7CD" even exist? In the GitHub disassembly, it's now called "SpecialStage_flag_2P". Though if that is the case, it should be showing "error: symbol undefined", not "error: short addressing not allowed".
I'm pretty confused too. I'll substitute "unk_F7CD" with the "SpecialStage_flag_2P" and see if i get anything. EDIT: I swapped the "unk_F7CD" with the "SpecialStage_flag_2P" and got 3 more errors: Code (Text): > > >s2.asm(41137): error: symbol undefined > > > return_1F220 > > > bhs.w return_1F220 > > >s2.asm(41142): error: symbol undefined > > > return_1F220 > > > bhs.w return_1F220 > > >s2.asm(41146): error: symbol undefined > > > loc_1F206 > > > bne.s loc_1F206 > > >s2.asm(51995): error: addressing mode not allowed on 68000 > > > lea Obj70_Positions(pc,d1.w),a1 > > >s2.asm(51995): error: addressing mode not allowed here > > > lea Obj70_Positions(pc,d1.w),a1 now it shows that addressing mode isn't allowed in a totally different spot, and the "symbol undefined" error is showing up now. Is there a different function I can use to get the same effect, or do I need to replace some more terms?
The last two errors are just the assembler getting confused, they'll go away if you fix the other errors. The "symbol undefined" errors there, are all labels that definitely exist in my copy of the disassembly, perhaps you deleted or renamed them? They should be under Obj79_CheckActivation as part of the checkpoint object.
The "symbol undefined" terms, "return_1F220" and "loc_1F206", are definitely there under Obj79_CheckActivation: Code (Text): loc_1F154: Obj79_CheckActivation: move.b subtype(a0),d2 andi.b #$7F,d2 cmp.b d2,d1 bhs.w loc_1F222 move.w x_pos(a3),d0 sub.w x_pos(a0),d0 addi.w #8,d0 cmpi.w #$10,d0 bhs.w return_1F220 move.w y_pos(a3),d0 sub.w y_pos(a0),d0 addi.w #$40,d0 cmpi.w #$68,d0 bhs.w return_1F220 move.w #SndID_Checkpoint,d0 ; checkpoint ding-dong sound jsr (PlaySound).l jsr (SingleObjLoad).l bne.s loc_1F206 _move.b #ObjID_Starpost,id(a1) ; load obj79 move.b #6,routine(a1) ; => Obj79_Dongle move.w x_pos(a0),objoff_30(a1) move.w y_pos(a0),objoff_32(a1) subi.w #$14,objoff_32(a1) move.l mappings(a0),mappings(a1) move.w art_tile(a0),art_tile(a1) move.b #4,render_flags(a1) move.b #8,width_pixels(a1) move.b #4,priority(a1) move.b #2,mapping_frame(a1) move.w #$20,objoff_36(a1) move.w a0,parent(a1) ;tst.w (Two_player_mode).w ;bne.s loc_1F206 ;cmpi.b #7,(Emerald_count).w ;beq.s loc_1F206 ;cmpi.w #50,(Ring_count).w ;blo.s loc_1F206 ;** bsr.w Obj79_MakeSpecialStars rts; ... Very strange.
oops I'll label them with some numbers Code (Text): loc_1F154: Obj79_CheckActivation: move.b subtype(a0),d2 andi.b #$7F,d2 cmp.b d2,d1 bhs.w loc_1F222 move.w x_pos(a3),d0 sub.w x_pos(a0),d0 addi.w #8,d0 cmpi.w #$10,d0 1 bhs.w return_1F220 move.w y_pos(a3),d0 sub.w y_pos(a0),d0 addi.w #$40,d0 cmpi.w #$68,d0 2 bhs.w return_1F220 move.w #SndID_Checkpoint,d0 ; checkpoint ding-dong sound jsr (PlaySound).l jsr (SingleObjLoad).l bne.s loc_1F206 _move.b #ObjID_Starpost,id(a1) ; load obj79 move.b #6,routine(a1) ; => Obj79_Dongle move.w x_pos(a0),objoff_30(a1) move.w y_pos(a0),objoff_32(a1) subi.w #$14,objoff_32(a1) move.l mappings(a0),mappings(a1) move.w art_tile(a0),art_tile(a1) move.b #4,render_flags(a1) move.b #8,width_pixels(a1) move.b #4,priority(a1) move.b #2,mapping_frame(a1) move.w #$20,objoff_36(a1) move.w a0,parent(a1) ;tst.w (Two_player_mode).w 3 ;bne.s loc_1F206 ;cmpi.b #7,(Emerald_count).w ;beq.s loc_1F206 ;cmpi.w #50,(Ring_count).w 4 ;blo.s loc_1F206 ;** bsr.w Obj79_MakeSpecialStars rts; Obviously the numbers aren't part of the ASM, they're just there to label. Those are the undefined symbols MainMemory said were definitely part of his disassembly.
Those are branches. Labels look like this: Code (Text): return_1F220: Those two lines at the top are labels. You have a branch, but you're not telling the code where to branch to.
Oh, I'm stupid! Thanks, man! You're a lifesaver! EDIT: Should I branch to teleport_monitor function or warp_toSS function? EDIT: I'm pretty sure I got it to assemble. Thanks!
I found another weird bug in my Sonic 1 hack. I recently added some art for the end sequence for my alternate character. While testing it I discovered that on the good ending, the Chaos emeralds are not appearing for either character. I compared my code for the sonic end object, emerald end object, and ending sequence game mode to a working Sonic 1 disassembly to check I didn't change something important by accident, and apart from a couple of character flag checks, the code is identical. I used the debug features of Exodus and found that the instruction to load the emerald object is being executed, but nothing happens. Does anyone have any clue what might be happening here? I normally have some idea of where to start, but I'm totally baffled this time. EDIT: Solved it. Turns out that in adding a new object for the alternate character in the ending, I'd misplaced a pointer. Stupid, but apparently easy to miss.
So I'm building an object handler for my engine, which will roughly be the equivalent of the SST in the classic engines, and I have a few high level questions about how loading objects into memory works. Firstly, where are object definitions per stage stored? Are they stored with chunk definitions, or is there a separate table? I.E. say I place a badnik on the second chunk at the beginning of a stage, where is the placement for that badnik stored? Sonic 2 loads all objects within a Y-range into memory, correct? While Sonic 3 takes into account a Y-range and X-range as well? My idea is to load objects depending on which chunks are around the player, but I'm not sure if that's how it's done in the classic engines. Speaking of loading objects into the SST, are they added into the first open slot? Or is there a more specific way they are loaded into object ram?
They're completely separate mechanisms. Chunks are on a grid, so all you have to do is add/subtract either 1 to move horizontally, or the overall row size to move vertically. Objects can be placed freely so you have to iterate through the object layout until you find one which is out of range. (Objects are ordered by X position so once you find one that's too far away, you know all the others past that are also too far away.) Sonic 3 also considers the Y position of the object before electing to spawn it. Although, I think there's an object flag to suppress it; after all, you still need to go and check the X coord of the next object. Admittedly I don't know enough offhand to answer this and the next question properly.
Right, as Neo said, the object's placement is not stored in with the chunks, instead they are all stored in a single separate list, it's what's called an "object position list". This list will hold a few basic values including: the object ID (object to load), X position in the level, Y position in the level, subtype (for different variences of the same object. e.g. springs can be yellow/red upwards/sideways), whether it's flipped and/or mirrored, and finally, whether or not it should store its status to a "destoryed/collected" list (for example, a badnik destroyed needs to not-respawn). As for loading objects depending on which chunks are around the screen, that is technically already done in Sonic games, for example, in Sonic 1-3, objects are loaded outside of the screen by $80 pixels minimum from the screen (basically, a 128x128 chunks worth), with Sonic 3 including the Y position to save on CPU time. While objects themselves have no relations to the chunks (they are a completely separate system), they load at a nice round 80. They didn't decide on 80 because of the chunk size, as 80 was decided as far back as Sonic 1 when the chunk sizes were 256x256, it was likely chosen as it's a reasonable balance between loading them off screen enough, and not loading too many far away for the CPU to not be able to handle. As for loading objects, they generally are loaded to the first available slot in the dynamic object ram list, the first free slot it can find.
Some more musings on the Sonic 3 object manager, since I couldn't figure out a better place to post them. Since the Y coord culling was added on top of the existing S1/S2 system, you have to move horizontally in order to (re)load new objects. This is fair, since we're used to walking off and then coming back to get blocks back where they were, etc. You would think that since the game delays spawning objects until you're close enough to them vertically, it would discard them if you moved away from them vertically as well. See the hole in that logic, though? Since objects are loaded by moving horizontally, and merely delayed from spawning until you move vertically, if objects deleted themselves when you moved away from them vertically, then they would mysteriously stay gone until you also moved away horizontally and then came back. In fact, that's exactly what Special Stage rings do. This is what accounts for that weird second ring in AIZ1, where if you go right through the cork block rather than bumping into the ceiling, the ring just vanishes. It was probably done so the game can load back the explosion art sooner; there are places where you can fall from a ring room straight to some monitors at least.