English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 17 April 2011, 14:47   #1
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,771
Displaying sprites

I'd like to try and create a simple scrolling starfield for my next project.

Can someone please give me a quick rundown on how to create a simple sprite and display it on the screen? I've read the sprites section in the HRM several times, but find it very confusing to say the least.

If anyone can recommend a comprehensive and easy to understand book like the C64 Programmers Reference Guide for the Amiga, that would be great.

Thanks
Hewitson is offline  
Old 17 April 2011, 19:39   #2
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
On OCS you need to enable bitplane graphics before you can show any sprites on the screen, so that should be your first step. (there are ways to work around this, but to keep things simple..)

To get a 320*200 screen of 1 bitplane going, you can f.ex do this (did you get the customregisters.i include file to work?):
Code:
lea     $dff000, a6

; enable 1 bitplane and set horizontal scroll values to 0

move.w  #bpl_1bpl | bpl_color, bplcon0(a6)
move.w  #0, bplcon1(a6)

; set bitplane data fetch start and stop

move.w  #$38, ddfstrt(a6)
move.w  #$d0, ddfstop(a6)

; set upper left coordinate of display window to $81, $2C
; and the bottom right to $1C1, $F4 to get a 320x200 display

move.w  #$2c81, diwstrt(a6)
move.w  #$f4c1, diwstop(a6)

; enable master DMA and bitplane DMA

move.w  #dma_set | dma_en | dma_bpl, dmacon(a6)
Some prefer to write these values into the Copper program instead and have the Copper set the hardware registers every image frame, both ways work.

Now you just need to set the bitplane pointer, registers BPL1PTH and BPL1PTL in this example, to where your bitplane data is. Bitplane pointers (and sprite pointers) needs to be set every image frame or they will keep advancing and you'll see the whole memory scrolling by on the screen. You can either write the pointer value into a Copper program, or easier for now is to just set it yourself in your frame loop.
Leffmann is offline  
Old 19 April 2011, 09:18   #3
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,771
I did get the customregisters.i to work, I've switched to Asm-Pro as the debugger doesn't crash the machine unlike DevPac and Asm-One..

With the help of your code I managed to get a sprite to display on the screen, however I couldn't quite get my head around the bitplane stuff so I had a heap of random shit behind it!

What I did was filled #8000 of memory (at $21000) with FF's and pointed the start of that area to BPL1PTH with a move.l, I'm not sure why it didn't work as expected. The results were basically the same as not having any bitplane pointer defined except that it was a static picture.

I've uploaded the code to the zone in case anyone feels like taking a look at it for me.

Cheers

Last edited by Hewitson; 19 April 2011 at 09:24.
Hewitson is offline  
Old 19 April 2011, 09:33   #4
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by Hewitson View Post
The results were basically the same as not having any bitplane pointer defined except that it was a static picture.
Did you enable sprite DMA?
StingRay is offline  
Old 19 April 2011, 09:47   #5
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,771
I didn't, but I just tried with it enabled and it didn't make any improvement.

Last edited by Hewitson; 19 April 2011 at 09:54.
Hewitson is offline  
Old 19 April 2011, 10:36   #6
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
I have checked your code and it displays the sprite. The only thing I changed was the absolute address for the screen memory which is never a good idea! Allocate your screen memory properly (either use AllocMem or a BSS section). Your code is forced into Chip Ram and you never know where it is in memory, it's easily possible that your sprite data was located at $21000 too and you destroyed it when you cleared the screen mem -> thus no sprite visible.
StingRay is offline  
Old 19 April 2011, 11:28   #7
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,771
I just allocated the bitplane memory with a bss, works much better now, thanks

Any idea why the colours of the sprite change?

Edit: It's working perfectly now, I had to set BPL1MOD to 0 to correct the background colour issue, and setting SPR1-7PT to dummy sprites fixed the sprite's flashing colours.

Last edited by Hewitson; 19 April 2011 at 14:25.
Hewitson is offline  
Old 19 April 2011, 14:23   #8
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,771
I've now got it moving diagonally across the screen, however it's a little bit on the jerky side.

Can someone please tell me how I can achieve a smooth movement of the sprite? I am currently doing it like this:

Code:
        bsr     WaitRaster
        add.b   #1,sprite                       ;vstart
        add.b   #1,sprite+1                     ;hstart
        add.b   #1,sprite+2                     ;vstop

WaitRaster
        move.l  d0,-(a7)
.loop   move.l  $dff004,d0
        and.l   #$1ff00,d0
        cmp.l   #303<<8,d0
        bne.b   .loop
        move.l  (a7)+,d0
        rts
Hewitson is offline  
Old 19 April 2011, 21:00   #9
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
Try waiting for f.ex line 300 and then line 301. That way you're guaranteed your loop only runs once per image frame. You're also moving the sprite 2 pixels horizontally, you can calculate the control words from an X and Y coordinate like this:

Code:
move.w  #50, d0    ; x position
move.w  #100, d1   ; y position
move.w  #20, d2    ; height

add.w   #$80, d0   
add.w   #$2c, d1   
add.w   d1, d2     
clr.b   d3         

lsl.w   #8, d1     ; move vertical start bit 8 in place
addx.b  d3, d3     

lsl.w   #8, d2     ; vertical stop bit 8
addx.b  d3, d3     

lsr.w   #1, d0     ; horizontal start bit 0
addx.b  d3, d3     

move.b  d0, d1     ; make first control word
move.b  d3, d2     ; second control word
Leffmann is offline  
Old 19 April 2011, 21:30   #10
Lonewolf10
AMOS Extensions Developer
 
Lonewolf10's Avatar
 
Join Date: Jun 2007
Location: near Cambridge, UK
Age: 44
Posts: 1,924
Quote:
Originally Posted by Leffmann View Post
Try waiting for f.ex line 300 and then line 301. That way you're guaranteed your loop only runs once per image frame.

Why do we need to do that? Is it because the sprite movement code can be finished within 1 raster line, thus when the wait line 300 is encountered again it's still on line 300 and the sprite routine runs a 2nd time?

I currently have a sprite that moves smoothly in my demo, but occasionally it moves twice as far as intended within a VBL, thus making it jerk slightly.


Regards,
Lonewolf10
Lonewolf10 is offline  
Old 20 April 2011, 02:24   #11
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
Quote:
Originally Posted by Lonewolf10 View Post
Why do we need to do that? Is it because the sprite movement code can be finished within 1 raster line, thus when the wait line 300 is encountered again it's still on line 300 and the sprite routine runs a 2nd time?
Yeah that's exactly it. A lot of old games and demos were programmed with the assumption that some piece of code would always need a certain amount of time to finish, and of course many of them both fly and crash on an 060 or under WinUAE with JIT.
Leffmann is offline  
Old 20 April 2011, 10:05   #12
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,771
Quote:
Originally Posted by Leffmann View Post
Try waiting for f.ex line 300 and then line 301. That way you're guaranteed your loop only runs once per image frame.
It moves perfectly now, thanks

However I can't understand why that does any good. What stops it from executing the loop twice on line 301?

I'd like to move my bitplane & sprite pointer routine into the copper, what's the best way to do this? I wanted to do e.g "dc.l bpl1pth,#Bitplane1" but it wouldn't let me.
Hewitson is offline  
Old 20 April 2011, 10:16   #13
WayneK
Registered User
 
Join Date: May 2004
Location: Somewhere secret
Age: 50
Posts: 364
The copper can only take arguments as words (.w) not longs (.l)... try doing this instead:

(in copperlist)
pl1h:
dc.w Bpl1pth,$0000,Bpl1ptl,$0000

(in setup code)
lea Bitplane1,a0
lea pl1h,a1
movea.l a0,d0
move.w d0,6(a1)
swap d0
move.w d0,2(a1)

...this moves the lower word, then the higher word of your bitplane 1 address into the copperlist at the right places.
WayneK is offline  
Old 20 April 2011, 10:33   #14
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by Hewitson View Post
However I can't understand why that does any good. What stops it from executing the loop twice on line 301?
You wait for line 300, code needs less than 1 rasterline so when it reaches this check again, it won't wait since the raster beam is still in line 300. Now you wait for line 301 so the raster beam is not in line 300 anymore when the check is executed again.
Instead of waiting for line 301 you could also check if the raster beam is still in line 300 and if so, wait. Think about it.

Also, this is only necessary when your code doesn't really do much and needs less than 1 raster line, in all other cases it's a waste of cpu time/cycles.
StingRay is offline  
Old 20 April 2011, 13:23   #15
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,771
That works brilliantly thanks Wayne!

Quote:
Originally Posted by StingRay
Instead of waiting for line 301 you could also check if the raster beam is still in line 300 and if so, wait. Think about it.
Had a bit of a blonde moment there, didn't I?

Cheers
Hewitson is offline  
Old 24 April 2011, 08:43   #16
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,771
My little sprite experiment is slowly turning into a basic space invaders type game, unfortunately I'm stuck on trying to display the enemy sprites.

The original game uses 5 lines of enemies, with 11 enemies in each line. How should I go about trying to display all of these?
Hewitson is offline  
Old 24 April 2011, 09:12   #17
Codetapper
2 contact me: email only!
 
Codetapper's Avatar
 
Join Date: May 2001
Location: Auckland / New Zealand
Posts: 3,182
If you were happy with 4 colour enemies, the simplest way is to setup a 4 bitplane or less screen, load the enemy graphics into sprite 0 and 1, and multiplex them across the screen.

It's the same principle as Jim Power which repositions sprites 6 and 7 right across the screen.

When an enemy is killed, you can just 'nop' out that baddie in the copperlist by using a $1fe0000 or reset the background colour to black like $1800000 again. If the enemy is 16 pixels high, it only takes 16 longword writes to remove it from the game.
Codetapper is offline  
Old 27 April 2011, 08:57   #18
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,771
I'm more than happy with 4 colour enemies, but I'm afraid I need a lot more help with how to go about doing this..
Hewitson is offline  
Old 27 April 2011, 16:35   #19
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
Drawing the invaders using sprites only by multiplexing them horizontally across the screen is doable like Codetapper says, but it will become a pretty complex exercise.

An easier way is to place all 8 sprites together for a 128 pixel wide block which you draw a row of invaders into and move as one, reposition horizontally for the next row of invaders, and maybe even change colors for each row.

If 128 pixels is too narrow then another easy and more flexible way is to use bitplane graphics. This way you could have a different graphic, size, shape and color for each of your 44 invaders, as long as you segment them into rows. You wouldn't have to draw them separately with the blitter or anything, but just reposition the bitplanes and have them all move together at no cost. You can change colors for each row of invaders here too, and with bitplane graphics you could go all the way up to 256 colors if you wanted to.
Leffmann is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Screen not displaying on 2.6.1 Amiga1992 support.WinUAE 4 25 August 2013 17:50
CDTV without picture displaying ?? haynor666 support.Hardware 34 18 February 2013 05:26
Crystal Kingdom Dizzy sprites not displaying correctly lesta_smsc support.Games 9 05 October 2012 22:53
Displaying images Tiddlypeeps Coders. Tutorials 40 30 August 2012 10:11
New WinUAE's and screen displaying problem Sloppy Elf support.WinUAE 3 26 January 2007 14:18

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 02:07.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.09561 seconds with 13 queries