Sonic and Sega Retro Message Board: Hayate - Viewing Profile - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help

Group:
Tech Member: Tech Members
Active Posts:
2376 (0.57 per day)
Most Active In:
Engineering & Reverse Engineering (1049 posts)
Joined:
01-February 04
Profile Views:
5824
Last Active:
User is offline May 19 2015 01:29 AM
Currently:
Offline

My Information

Age:
25 years old
Birthday:
December 23, 1989
Gender:
Male Male
Location:
Torquay, England

Previous Fields

National Flag:
gb
Wiki edits:
70

Latest Visitors

Posts I've Made

  1. In Topic: Basic Questions & Answers thread

    10 February 2015 - 02:30 AM

    View PostE-122-Psi, on 03 February 2015 - 02:24 PM, said:

    Does anyone know how to program sprite collision in S3+K?

    I've made a new object in the game. I've given it a $40 for the collision flag byte ($28) and made a branch to the collision response data like so:

    [...code removed...]

    It doesn't quite work. It only hits enemies half the time and won't hit other objects like monitors at all. Any idea what I'm doing wrong?

    I should perhaps note I'm not positive it's implemented correctly. The projectile appears behind a lot of objects and foregrounds instead of in front.



    EDIT: Okay scratch that, I (as in Flamewing :P) managed to work out how to program it to collide properly, however I'm still having problems getting it to work on other objects like monitors, would the correct form of branch be this?

    cmpi.l #Obj_Laser,(a*) ; is it laser?
    



    I am guessing you're trying to make an object in the middle of the object table check for collisions with other objects. If so then you're running into the exact same problem I had when I added a cutscene character object that needed to do collision the same way as the player.

    What happens is that each object that is collidable with writes its RAM address to Collision_list when it is processed. The Sonic and Tails objects, at the very start of the object table, read this list. There is another object which lies in the slot directly after Tails (called Reserved_object_3 in the disasm I'm using). This object clears the Collision_list. So: An object in the middle of the object table won't see collidable objects if they are after it, because Reserved_object_3 cleared that entry and the object didn't get around to writing it again yet.

    My solution was to make a Second_collision_list, and have objects write into this new one while reading from the original one. Reserved_object_3 then does nothing, and after processing all objects, Second_collision_list is copied into Collision_list and then cleared. This means every object gets to see the entire collision list for the previous frame just like how Sonic and Tails do. I also have a flag that turns this behavior on and off, and disable it where necessary, mainly because the $80 bytes I chose for my Second_collision_list overlaps the Target_water_palette.

    Of course, if you know you are only going to have one such extra colliding object loaded at once it might be easier to create a new reserved object and move Reserved_object_3 up by one, though I'm not sure if that would involve shuffling any other reserved objects around or changing other things.

    Also, I wouldn't advise using the check you have at the end of your post. It will work if that object doesn't replace its pointer - a lot of objects will do so upon loading or on other occasions instead of (or as well as) using a routine counter.

    Just had a thought, what you might want to look at, instead of making the new object check for collision with all other objects: try making the other objects check for collision with the new object. Again this will only work if you know you are only going to have one such object and you keep it in the same place in memory, but then you can check just like how objects check for Sonic and Tails. That lets you specify the behavior you want for each particular object, so you don't have to check "is it a monitor", you just add the monitor-specific code to the monitor object.
  2. In Topic: Basic Questions & Answers thread

    13 January 2015 - 01:50 AM

    View PostE-122-Psi, on 06 December 2014 - 11:20 PM, said:

    Also a more complex query. Is it possible to change the character's life icon when they turn Super? I know there are routines that recognize patches for a different character's life icons, but have no idea where and how it knows when to load them and if it can be done mid game.


    View PostE-122-Psi, on 12 December 2014 - 09:43 AM, said:

    View PostMainMemory, on 07 December 2014 - 01:22 AM, said:

    For the life icon, if you wanted to do that, as far as I know you would have to have uncompressed copies of both the normal and super life icons (not the text area, just the picture) and initiate a DMA transfer to the VRAM location of the life icon graphic when you change forms. Depending on your disassembly, the function will be called DMA_68KtoVRAM, QueueCopyToVRAM, QueueVDPCommand, Add_To_DMA_Queue, or QueueDMATransfer.


    I'm inexperienced with DMA transfers with art. Could you explain a bit further?


    It's only four tiles, and you're not intending to change the art every frame: just once in a while when they turn Super or back. As such, I don't think uncompressed art is necessary. If you're using S3&K, just use Moduled Kosinski compression and:
    		lea	(ArtKosM_NewLifeIconHere).l,a1
    		move.w	#$1234,d2   ; replace with VRAM address for the life icon
    		jsr	(Queue_Kos_Module).l
    
    


    If you're not using S3&K, if you have a free $80 bytes of RAM (enough for four tiles) you could do a KosDec to RAM then DMA that RAM over (which I believe is basically what Queue_Kos_Module does, except it already has a buffer of $1000 bytes allocated, and takes care of making sure it doesn't lag up the game if there is a lot of art to load, etc.).

    Or if you want to be really fancy, find a spare $1000 bytes of RAM and port over the KosM code so you can speed up other things too :v:

    Edit: Forgot to actually answer the question about DMA...

    Depending on your disassembly, you may or may not have some code that looks like this:

    ; makes a VDP command
    vdpComm function addr,type,rwd,(((type&rwd)&3)<<30)|((addr&$3FFF)<<16)|(((type&rwd)&$FC)<<2)|((addr&$C000)>>14)
    
    ; values for the type argument
    VRAM = %100001
    CRAM = %101011
    VSRAM = %100101
    
    ; values for the rwd argument
    READ = %001100
    WRITE = %000111
    DMA = %100111
    
    ; tells the VDP to copy a region of 68k memory to VRAM or CRAM or VSRAM
    dma68kToVDP macro source,dest,length,type
    	lea	(VDP_control_port).l,a5
    	move.l	#(($9400|((((length)>>1)&$FF00)>>8))<<16)|($9300|(((length)>>1)&$FF)),(a5)
    	move.l	#(($9600|((((source)>>1)&$FF00)>>8))<<16)|($9500|(((source)>>1)&$FF)),(a5)
    	move.w	#$9700|(((((source)>>1)&$FF0000)>>16)&$7F),(a5)
    	move.w	#((vdpComm(dest,type,DMA)>>16)&$FFFF),(a5)
    	move.w	#(vdpComm(dest,type,DMA)&$FFFF),($FFFFF640).w
    	move.w	($FFFFF640).w,(a5)
        endm
    
    ; tells the VDP to fill a region of VRAM with a certain byte
    dmaFillVRAM macro byte,addr,length
    	lea	(VDP_control_port).l,a5
    	move.w	#$8F01,(a5) ; VRAM pointer increment: $0001
    	move.l	#(($9400|((((length)-1)&$FF00)>>8))<<16)|($9300|(((length)-1)&$FF)),(a5) ; DMA length ...
    	move.w	#$9780,(a5) ; VRAM fill
    	move.l	#$40000080|(((addr)&$3FFF)<<16)|(((addr)&$C000)>>14),(a5) ; Start at ...
    	move.w	#(byte)<<8,(VDP_data_port).l ; Fill with byte
    loop:	move.w	(a5),d1
    	btst	#1,d1
    	bne.s	loop	; busy loop until the VDP is finished filling...
    	move.w	#$8F02,(a5) ; VRAM pointer increment: $0002
        endm
    
    


    If not, it should be safe to copypaste in the above.

    Then, you can just write something like

      dma68kToVDP $1000,$2000,$800,VRAM
    
    


    where $1000 is the source location in RAM, $2000 is the destination location in VRAM, $800 is the number of bytes to copy and the last argument tells it to write to VRAM as opposed to CRAM or VSRAM.
  3. In Topic: General Project Screenshot/Video Thread

    13 January 2015 - 01:39 AM

    View PostEduardo Knuckles, on 08 January 2015 - 10:56 AM, said:

    Ignore the unfinished logo art and the shifted Tails and Knuckles in the title screen.

    Thanks to Genesisfan64 for his effort on making this impressive save selection menu.
    https://www.youtube....h?v=qxnbu5jgRwY


    This intro/title screen and save system makes two of the most impressive things I've ever seen in a Sonic hack. And some excellent music to it too. Good work!

    View PostTribeam, on 09 January 2015 - 02:06 AM, said:

    More Lua Shenanigans:
    Everything from level art, mappings, layout, palette cycles, and player control is all lua code(with some very slight asm edits)


    This has me wondering, did you write an entire Lua compiler or interpreter in assembly? Or am I missing something?
  4. In Topic: Don't know who might care, but Sonic X for Leapfrog Leapster

    28 December 2014 - 03:25 AM

    Just read through that whole thread, looks like it was all about the DI-DJ though. Which is interesting in its own right, but it looks like all the sprites there have already been cracked. No technical info on X (which makes sense since the ROM was only released a few days ago).
  5. In Topic: Ring Attack TAS

    27 December 2014 - 03:37 PM

    View PostBlivsey, on 27 December 2014 - 01:30 PM, said:

    Also this screenshot I took is pretty much a perfect encapsulation of the whole run:


    Hahaha, looks like he's imitating Kirby trying to suck up all the rings