24 January 2016, 00:14 | #1 |
Registered User
Join Date: Jan 2016
Location: Santa Cruz/US
Posts: 48
|
Resetting sprite problems
Hello everyone. I've been working on a simple game, but I've gotten stuck. For some reason I can't get my scoring/reset sprite code to work. I've trimmed down the problematic code into a simple program (attached - Vanilla A500/Devpac 3.02).
This is the desired behavior: Sprite0 moves towards Sprite2. Upon collision the sprite stops and a dot ("score") is drawn. When you press F1 the sprite goes back to the starting point and starts moving again. After each collision another dot is drawn. After restarting program all state is cleared. But this is the behavior I'm getting: First time program runs: Sprite0 moves towards Sprite2. Upon collision the sprite stops and a dot is drawn (so far so good). When you press F1 sprite0 goes back to the starting point, but doesn't move and another dot is drawn!? When pressing F1 again sprite starts moving but upon collision score isn't increased. After restarting program, state isn't cleared (dot still shown and sprite doesn't move). Not sure if I'm misunderstanding something with sprite collision, if sprite1 is somehow interfering, or if the way I use keyboard is wrong. I've really tried but I've run out of ideas now. I'd be eternally grateful* if someone could help. General comments on the program is also welcome. Thanks! Knocker *Well, at least until the singularity hits us |
24 January 2016, 09:59 | #2 |
Registered User
Join Date: Jan 2002
Location: Germany
Posts: 6,985
|
I don't know how to program collision detection on the Amiga, but to me your description sounds like you have to reset the collision bit after you checked it. It seems to stay set even if you move the sprite to another position.
|
24 January 2016, 18:22 | #4 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
|
You need to read CLXDAT after reseting the sprite position to clear previous collision state. Hardware collision checks are immediate, for example if you read CLXDAT when sprite is being drawn, collision bits gets set again immediately after you have read it.
btw, code has some oddities. - saving SR in interrupt is not needed, SR is automatically saved and RTE automatically restores it from stack. - clr.l $dff08a - bset #15,OldINTENA. Yes, it does work in this case but I am quite sure it does not work like you expected it to work. (I don't comment about system take over part because obviously it is just a test program ) |
27 January 2016, 07:16 | #5 |
Registered User
Join Date: Jan 2016
Location: Santa Cruz/US
Posts: 48
|
Thanks Toni, I got it to work after moving the sprite and then reading CLXDAT again. Really appreciate the response, and thanks a bunch for all the excellent work on WinUAE!
What did you mean to say about "clr.l $dff08a"? Not needed? Also, what do you think I intended to do with "bset #15,OldINTENA"? I actually didn't write the VBL interrupt code myself, so to be honest I'm not quite sure what the intention was. What do you recommend I do instead? |
27 January 2016, 12:06 | #6 | |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
|
It is word wide register. Not long word. Also technically clr is not good choice for strobe registers because clr <any memory address> on 68000 (only on 68000) does read first and then writes zero. It will strobe copper twice but it rarely causes problems (unless first copper instruction is MOVE that does something critical, like write to BLTSIZ) , it is just technically wrong
Quote:
bset #15-8,OldINTENA is more clear and makes it less likely to accidentally write (for example) bset #0,OldINTENA when you wanted to clear word wide bit 0, which would be bset #0,OldINTENA+1 |
|
28 January 2016, 00:31 | #7 |
Registered User
Join Date: Jan 2016
Location: Santa Cruz/US
Posts: 48
|
Thanks again Toni. Later versions of Devpac actually gives you an error if you try to set bit > 7 with bset. What I don't understand though is how my code can actually work, when it is setting bit 7, which is AUD0?!
So to really set bit 15 (the SET/CLR bit) I should do this? or.w #%1000000000000000,OldINTENA I tried bset #7,OldINTENA+1 - but that didn't work... |
28 January 2016, 10:12 | #8 | |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,408
|
Quote:
The 68000 stores words and longs in memory starting with the highest byte, so a word is stored bits 15-8 in address given +0 and bits 7-0 in address given +1. Furthermore, if you use BSET with a higher bit than 7 on a memory adress, the 68000 only looks at the 7 lowest bits in the given byte. So, if you say BSET #15,OldINTENA, it alters bits for the given adress - OldINTENA. This contains the top byte of the word as I explained above. Now, the 68000 can't set bit 15 of a byte. To fix this, internally the processor does an AND #7 on the given bit number. Take it all together and BSET #15,OldINTENA does the following: 1) Take the byte at OldINTENA, which contains bits 15-8 of the word stored at OldINTENA and OldINTENA+1 2) Change bit #15 AND #7 to 1 (changing bit #7 of the byte at OldINTENA) 3) Store it back at OldINTENA Hopefully this helps explain why doing BSET #15,OldINTENA does what you want. Last edited by roondar; 28 January 2016 at 11:18. |
|
28 January 2016, 10:28 | #9 | |
ex. demoscener "Bigmama"
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,624
|
Quote:
|
|
28 January 2016, 11:50 | #10 |
Registered User
Join Date: Sep 2008
Location: Germany
Age: 49
Posts: 137
|
The SET/CLR bit decides if the bits are set or cleared in the register (this is true for all amiga custom registers using a SET/CLR bit)
examples %1000000000000000 -> would no nothing (despite that you wrote a WORD into the register) because you say with the '1' in the 16th bit that you want to set a '1' to any bit which has a '1' %1000000000000001 -> would set the first bit of the register to '1' because you set the SET/CLR bit to '1' and set the first bit to '1', all other bits remain unchanged %1000000000000101 -> would set the first and third bit of the register to '1', again, all other bits remain unchanged %1111111111111111 -> would set all bits in the register to '1' except the 16th bit, because this is 'only' the SET/CLR bit setting the 16th bit to '0' %0000000000000001 -> would clear the first bit to '0' und would not change any other bit %0000000010100001 -> would clear the first, sixth and eight bit to '0' and would not change anything else or a more real world example If the register has the following value %0000000000111001 and you would write the following into it: %1000000000000010 (SET/CLR is active saying 'i want to set bits') then it would be afterwards: %0000000000111011 (hence the second bit is now set) now you write the following %0000000000111000 then it is: %0000000000000011 (hence, the 4th,5th and 6th bit are cleared now) I hope this helped a bit. |
28 January 2016, 12:49 | #11 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
|
|
29 January 2016, 00:30 | #12 |
Registered User
Join Date: Jan 2016
Location: Santa Cruz/US
Posts: 48
|
Thanks all. I should have been able to figure this out myself. Pretty "interesting" that bset behavior depends on the destination. Definitely something to watch out for.
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
FS-UAE 2.6.2 in OS X El Capitan - Workbench keep resetting | WeiXing3D | support.FS-UAE | 0 | 15 November 2015 07:47 |
Mani Pulite sprite problems (A500 mode) | andreas | support.WinUAE | 17 | 22 January 2015 14:41 |
A500: Trouble with resetting | BYTEMAN | support.Hardware | 7 | 21 December 2008 03:57 |
Whdload games resetting | Rave | support.WinUAE | 8 | 08 September 2004 20:38 |
HD games resetting under WinUAE | Rave | support.WinUAE | 3 | 07 September 2004 22:53 |
|
|