And it's me with my Hill Top 2P queries again. I've got Act 1 working semi-competently now, Act 2 however has a key roadblock, about halfway in it stops loading the objects for the level. Well more accurately, it loads the objects only after a player has went past their location. When you turn back to meet it onscreen from the left, there it is. Anyone know what might be the source of such behaviour? I get HTZ 2 has a load more objects than VS can perhaps handle but it seems here like the issue isn't loading them altogether just WHEN it does it.
What are you using to add sprites, SonMapEd or Flex 2? Also, have you expanded Sonic's art limit, or converted it to a DMA queue yet? Edit: I just realised your problem has been solved, sorry.
Okay, now I've got Act 2 of Hill Top running in VS. One issue though. The signpost I added in doesn't work. It just causes a Game Over. Anyone know how to install a signpost into a 2P version of a level? EDIT: Okay looking further turns out that was a half truth. It works fine if Tails crosses first, but Sonic crossing first glitches up Tails' screen and causes a Game Over. That specify the problem any better? Also I've made a 'sorta kinda' step into fixing HTZ's background in split screen: Here the art is back and the far mountains are still like I was aiming for, but the far clouds are still dynamic on Sonic's screen, and I think that may be what is causing the SLIGHT corruption here. :P I kinda did a blind shot in the dark here, having no idea how the code actually works. Anyone got a better idea how to go about this? Code (Text): Dynamic_HTZ: tst.w (Two_player_mode).w bne.w Dynamic_HTZ_2P lea ($FFFFF7F0).w,a3 moveq #0,d0 move.w (Camera_X_pos).w,d1 neg.w d1 asr.w #3,d1 move.w (Camera_X_pos).w,d0 move.w d0,d2 andi.w #$F,d2 seq.b d2 ext.w d2 lsr.w #4,d0 add.w d1,d0 add.w d2,d0 subi.w #$10,d0 divu.w #$30,d0 swap d0 cmp.b 1(a3),d0 beq.s BranchTo_loc_3FE5C Dynamic_HTZ_2P: move.b d0,1(a3) move.w d0,d2 andi.w #7,d0 add.w d0,d0 add.w d0,d0 add.w d0,d0 move.w d0,d1 add.w d0,d0 add.w d1,d0 andi.w #$38,d2 lsr.w #2,d2 add.w d2,d0 lea word_3FD9C(pc,d0.w),a4 moveq #5,d5 move.w #-$6000,d4 loc_3FD7C: moveq #-1,d1 move.w (a4)+,d1 andi.l #$FFFFFF,d1 move.w d4,d2 moveq #$40,d3 jsr (QueueDMATransfer).l addi.w #$80,d4 dbf d5,loc_3FD7C BranchTo_loc_3FE5C: bra.w loc_3FE5C
Hi, I am looking for guidance on how I can create mods for Sonic Generations in reference to importing models and music into the game to be loaded up using the mod loader, I have looked online through modding tutorials, however I am new to modding so some of it isn't very clear to me, so if anyone would be able to help me in modding the game it would be greatly appreciated.
Okay progression. I've managed to figure out the issue with the background, apparently the VRAM is interfering with some of the split screen data in the location. I know how to move the background tiles' VRAM location, but not what location the game projects, anyone else know from that bit of code above and this one below? Code (Text): loc_3FE5C: lea ($FFFFA800).w,a1 ;A800 tst.w (Two_player_mode).w bne.w Dynamic_HTZ_2P_2 move.w (Camera_X_pos).w,d2 neg.w d2 asr.w #3,d2 Dynamic_HTZ_2P_2: move.l a2,-(sp) lea (ArtUnc_HTZClouds).l,a0 lea ($FFFF7C00).l,a2 ;7C00 moveq #$F,d1 jsr Adjust2PArtPointer loc_3FE78: move.w (a1)+,d0 neg.w d0 add.w d2,d0 andi.w #$1F,d0 lsr.w #1,d0 bcc.s loc_3FE8A addi.w #$200,d0 loc_3FE8A: lea (a0,d0.w),a4 lsr.w #1,d0 bcs.s loc_3FEB4 move.l (a4)+,(a2)+ adda.w #$3C,a2 move.l (a4)+,(a2)+ adda.w #$3C,a2 move.l (a4)+,(a2)+ adda.w #$3C,a2 move.l (a4)+,(a2)+ suba.w #$C0,a2 adda.w #$20,a0 dbf d1,loc_3FE78 bra.s loc_3FEEC ; =========================================================================== loc_3FEB4: move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ adda.w #$3C,a2 move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ adda.w #$3C,a2 move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ adda.w #$3C,a2 move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ move.b (a4)+,(a2)+ suba.w #$C0,a2 adda.w #$20,a0 dbf d1,loc_3FE78 loc_3FEEC: move.l #$FF7C00,d1 ;7C00 move.w #-$7B00,d2 ;-$5D00 move.w #$80,d3 jsr (QueueDMATransfer).l movea.l (sp)+,a2 addq.w #2,a3 bra.w loc_3FF30
I've tried several times over the last 2 weeks to get this working properly (https://info.sonicretro.org/SCHG_How-to:Port_Sonic_2's_Level_Art_Loader_to_Sonic_1), I had similar problems when trying to implement the Fast Loading stuff Aurora Fields had (https://forums.sonicretro.org/index.php?threads/s1-considerably-speeding-up-level-loading.33616/), at this point i'm starting to wonder if the re-compressed tiles are at fault, i used KENSSharp to decompress every nemesis file and re-compress in several formats, only the nemesis code seems to work, I've tried searching the forum to see if anyone else has had similar problems to no avail, the graphics always end up garbled. I'm about 90% sure the problems are with the ProcessDMAQueue part, though i may be wrong (i'm also certain i had it working fine at one point then after changing other code and going back it stopped working, though i have commented out all the other code and disabled all other things I've implemented so it may just be that I've missed something.), I'd actually like to implement https://github.com/flamewing/ultra-dma-queue however the code seems completely incompatible I've uploaded my code to github if anyone wants to take a look https://github.com/TrueCyberAxe/Sonic-1-Enhanced I've been using http://geoo.digibase.ca/Genesis/s1_labellist.txt to figure out how to map the older subroutines from the guide to the github code Any advice or insight would be appreciated, thanks.
Whoops, now I remember what happened. The 2P glitch was caused by me trying to improvise a levevents to branch over the HTZ boss like the other 3 levels do in 2 player. Code (Text): ; --------------------------------------------------------------------------- loc_HTZ_2P2: move.w #$2D80,(Camera_Max_X_pos).w move.w #$2D80,(Tails_Max_X_pos).w rts Problem is this just puts Tails straight to Sonic's location when he hits the screen end area. Putting the branch later in the routine prevents a Game Over but the same problem still occurs. Is there some info I'm missing from the three proper levels' approach to this?
All that code is doing is setting where the end of the level is. Somewhere, the min X position is also being set, and when that happens Tails gets pushed to the end of the level to stay inside the boundaries of the screen. If the max Y position is also set, then that will likely also place Tails below the bottom of the level, causing him to die, and then probably respawn back underneath the bottom of the level in a cycle, leading to a game over. Look for places where those camera values are manipulated (did you remove the boss object from the layout?) and do whatever makes sense, like only locking Sonic's camera or not bothering with the vertical lock at all.
Well the way they seem to do it for the main three levels is if it's two player then branch over the whole routine. I tried doing that and got the same problems. EDIT: No wait, fixed it. Didn't notice a sneaky branch all the way at the very top before the index.
Sorry to bug again, but I'm so damn close to getting this thing looking perfect and this roadblock is driving me crazy. I'm trying to move the VRAM location of the dynamic background in Hill Top Zone. I get that it's connected to Dynamic_HTZ and I know how to move the tiles around, but not where the plane detects them, they're ALWAYS on $A000 no matter what I edit. Does anyone know what I'm supposed to do to move this around, anything to do with this? Code (Text): lea word_3FD9C(pc,d0.w),a4 moveq #5,d5 ;5 move.w #-$6000,d4 ;-6000 loc_3FD7C: moveq #-1,d1 move.w (a4)+,d1 andi.l #$FFFFFF,d1 ;$FFFFFF move.w d4,d2 moveq #$40,d3 ;$40 jsr (QueueDMATransfer).l addi.w #$80,d4 ;$80 dbf d5,loc_3FD7C BranchTo_loc_3FE5C: bra.w loc_3FE5C ; =========================================================================== ; HTZ mountain art main RAM addresses? word_3FD9C: dc.w $80, $180, $280, $580, $600, $700 ; 6 dc.w $80, $180, $280, $580, $600, $700 ; 12 dc.w $980, $A80, $B80, $C80, $D00, $D80 ; 18 dc.w $980, $A80, $B80, $C80, $D00, $D80 ; 24 dc.w $E80,$1180,$1200,$1280,$1300,$1380 ; 30 dc.w $E80,$1180,$1200,$1280,$1300,$1380 ; 36 dc.w $1400,$1480,$1500,$1580,$1600,$1900 ; 42 dc.w $1400,$1480,$1500,$1580,$1600,$1900 ; 48 dc.w $1D00,$1D80,$1E00,$1F80,$2400,$2580 ; 54 dc.w $1D00,$1D80,$1E00,$1F80,$2400,$2580 ; 60 dc.w $2600,$2680,$2780,$2B00,$2F00,$3280 ; 66 dc.w $2600,$2680,$2780,$2B00,$2F00,$3280 ; 72 dc.w $3600,$3680,$3780,$3C80,$3D00,$3F00 ; 78 dc.w $3600,$3680,$3780,$3C80,$3D00,$3F00 ; 84 dc.w $3F80,$4080,$4480,$4580,$4880,$4900 ; 90 dc.w $3F80,$4080,$4480,$4580,$4880,$4900 ; 96 ; =========================================================================== Also I've figured out some bugs caused with objects duplicating in two player mode. Is there any sort of branch to make the object recognise if there's a duplicate of itself in the exact same location? That way I can tell it not to spawn so long as there's another one already there.
The "move.w #-$6000,d4 ;-6000" is what you want, -$6000 is actually $A000 in signed negative. -$6000 is just another way of representing it. Remove the minus symbol, and make this word whatever VRAM address you want.
I tried that but like I said, it only moves the actual tiles, not where the plane directs it. eg. If I put -$7000, it moves the tiles up to $9000 but the scrolling plane still shows the tiles at $A000.
I don't understand the question. Are we talking about the blue mountains in the far BG? Those are part of the background blocks/chunks, aren't they? Did you edit the block definitions to point at the new tile ID/VRAM addresses? Also, I should point out that if you want to get the parallax effect working for both players, you're going to have to DMA the mountain tiles to two different places in VRAM, one for each camera, and then have each screen draw a different set of background chunks, one pointing at one VRAM address and the other one at the other. This is not an easy job; the only level that does this in Sonic 3 is Desert Palace, open that up in SonLVL to see what I mean.
Yeah the blue mountains plus the far back clouds, I've actually managed to edit the routine so it stays still, meaning no conflict between either player screens. However is that they're in the same location as some split screen data ($A000) so activating them corrupts 2 player's screen. The roadblock is that I don't know how to edit the block definitions. Even SonicLVL doesn't seem to be able to locate above $2FF while I've relocated to them to $E800 (which I'm even in short terming is above $400). Plus I want the definitions to alter between both one player and two player modes really. Is there anything in the asm that can edit the block definitions so they look for $E800 onward instead of $A000?
Did you edit the actual BG's block mappings in a level editor of some kind (say SonLVL)? If not, that'll be why...
The thing is last time I tried to edit that section it just completely screwed up the entire tile set and I had to start all over. And again, I need to somehow make this work for two different sections due to 1 player and 2 player using different VRAM areas (unless this is solely an edit to the actual 128 mappings, in which case I could maybe redirect to an edited duplicate for two player?). EDIT: I've tried this again with somewhat less disastrous results, however I'm having trouble processing how the Block format works with the imported tiles (ie. the orange cross blocks). It doesn't seem to format which tiles in the VRAM to load for it and when I try it just ruins the previous selected block instead. EDIT 2: Never mind. Managed to work around it. Just one bug left! :D If this one is out of range, I'll pass one fix for another. Some of the objects in HTZ are loading multiple times in splitscreen, seemingly for each time either player comes within range of them (though that seems to include other cases that didn't count in 1p mode before like crossing them from far above or below). If I'm not mistaken some objects in normal multiplayer levels suffer this issue as well. I believe I saw the Crawlton badnik in MCZ in duplicates when in 2P. This of course can consume the object number in HTZ, especially since it does it for a ton of awkwardly placed objects (the player lagging behind can come before a three or four headed Rexon for example, or FIVE airlifts overlapped with each other), so I need to figure out what the issue is here.
Okay I've finally got the VRAM moved where I want....only of course that means now that one player's location is screwed. Since the changes are allocated the mappings files, I supposedly could make both versions of the level use separate ones. Does anyone know how to edit the levelartpointers to notice a different branch for a two player version of the same level?
EDIT: See this instead. This post is missing some details. What you can do is in LevelArtPointers, after every zone entry, make a copy of it i.e.: Code (Text): LevelArtPointers: levartptrs PLCID_Ehz1, PLCID_Ehz2, PalID_EHZ, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 0 ; EHZ ; EMERALD HILL ZONE levartptrs PLCID_Ehz1, PLCID_Ehz2, PalID_EHZ, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 0 ; EHZ ; EMERALD HILL ZONE (2 PLAYER) levartptrs PLCID_Miles1up, PLCID_MilesLife, PalID_EHZ2, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 1 ; LEV1 ; LEVEL 1 (UNUSED) levartptrs PLCID_Miles1up, PLCID_MilesLife, PalID_EHZ2, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 1 ; LEV1 ; LEVEL 1 (UNUSED, 2 PLAYER) levartptrs PLCID_Tails1up, PLCID_TailsLife, PalID_WZ, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 2 ; LEV2 ; LEVEL 2 (UNUSED) levartptrs PLCID_Tails1up, PLCID_TailsLife, PalID_WZ, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 2 ; LEV2 ; LEVEL 2 (UNUSED, 2 PLAYER) Then, replace the levartptrs macro above it with this: Code (Text): ; declare some global variables to be used by the levartptrs macro cur_zone_id := 0 cur_zone_str := "0" cur_zone_2p := 0 ; macro for declaring a "main level load block" (MLLB) levartptrs macro plc1,plc2,palette,art,map16x16,map128x128 !org LevelArtPointers+zone_id_{cur_zone_str}*24+cur_zone_2p dc.l (plc1<<24)|art dc.l (plc2<<24)|map16x16 dc.l (palette<<24)|map128x128 cur_zone_2p := cur_zone_2p+12 if cur_zone_2p>=24 cur_zone_2p := 0 cur_zone_id := cur_zone_id+1 cur_zone_str := "\{cur_zone_id}" endif endm And have this added after the LevelArtPointers table: Code (Text): if (cur_zone_2p<>0)&&(MOMPASS=1) message "Warning: Table LevelArtPointers's last entry does not have a 2P entry" endif Then, go to Level and go to the comment that says "; multiply d0 by 12, the size of a level art load block". Insert this before "lea (LevelArtPointers).l,a2": Code (Text): add.w d0,d0 tst.w (Two_player_mode).w beq.s .not_2p_mode addi.w #12,d0 .not_2p_mode: Then go to both LoadZoneTiles and loadZoneBlockMaps and add the same code before both instances of "lea (LevelArtPointers).l,a2". With that, you should now be able to set up level data pointers for 2P mode for any zone. As an added bonus for applying the same thing to collision and level/object layouts... With that, you go to LoadCollisionIndexes and change "lsl.w #2,d0" into: Code (Text): lsl.w #3,d0 tst.w (Two_player_mode).w beq.s .not_2p_mode addq.w #4,d0 .not_2p_mode: And then apply that copying logic thing that was done LevelArtPointers in Off_ColP and Off_ColS, and also for both tables, change "zoneOrderedTable 4,1" into "zoneOrderedTable 4,2". You may get an error regading "movea.l Off_ColS(pc,d0.w),a0" because Off_ColS is too far away for that instruction to work. Just change that to: Code (Text): lea Off_ColS(pc),a0 movea.l (a0,d0.w),a0 And it'll be good. Then, g to Off_Level, change "zoneOrderedOffsetTable 2,2" into "zoneOrderedOffsetTable 2,4", and do the same copying logic as before. Then go to loadLevelLayout, and change "lsr.w #6,d0" into: Code (Text): lsr.w #5,d0 tst.w (Two_player_mode).w beq.s .not_2p_mode addq.w #2,d0 .not_2p_mode: Then, go to Off_Objects, change "zoneOrderedOffsetTable 2,2" into "zoneOrderedOffsetTable 2,4", and do the same copying logic as before. Also, do not forget to change the CNZ 2P object layout pointers here into Objects_CNZ1_2P and Objects_CNZ2_2P. Then, go to ObjectsManager_Init and change: Code (Text): lsr.w #6,d0 ; and this yields $003E. lea (Off_Objects).l,a0 ; Next, we load the first pointer in the object layout list pointer index, movea.l a0,a1 ; then copy it for quicker use later. adda.w (a0,d0.w),a0 ; (Point1 * 2) + $003E tst.w (Two_player_mode).w ; skip if not in 2-player vs mode beq.s + cmpi.b #casino_night_zone,(Current_Zone).w ; skip if not Casino Night Zone bne.s + lea (Objects_CNZ1_2P).l,a0 ; CNZ 1 2-player object layout tst.b (Current_Act).w ; skip if not past act 1 beq.s + lea (Objects_CNZ2_2P).l,a0 ; CNZ 2 2-player object layout + Into: Code (Text): lsr.w #5,d0 ; and this yields $003E. tst.w (Two_player_mode).w ; skip if not in 2-player vs modew beq.s + addq.w #2,d0 + lea (Off_Objects).l,a0 ; Next, we load the first pointer in the object layout list pointer index, movea.l a0,a1 ; then copy it for quicker use later. adda.w (a0,d0.w),a0 ; (Point1 * 2) + $003E And finally, move the CNZ 2P object layout data closer to the Off_Objects table.
Thanx for the quick reply. :D Just checking first. Is this for the GitHub or Xenowhirl version? I'm working on Xenowhirl. EDIT: Never mind. Just had to take out one line GitHub exclusive and it works. Thanx very much. :D