Amiga copper effects

BlitzPlus Forums/BlitzPlus Beginners Area/Amiga copper effects

DNielsen(Posted 2005) [#1]
How do you simulate Amiga Copper cycle effects in BlitzPlus?


CS_TBL(Posted 2005) [#2]
never had an amiga, on msx coders claimed to have the 'copper' effect (colorful filled sines, vertically stretching etc.), but that's all I know ..

you have a screenshot somewhere ? :)


sswift(Posted 2005) [#3]
If I'm not mistaken, copper effects require knowing what scanline the monitor is currently drawing, and having graphics based on a 256 color palette which you can change faster than the scanline can move.

BlitzPlus does not support palleted video modes, and though it will tell you what scanline is currently being drawn, that sort of effect wouldn't work on an LCD display which many PC's now use.

On today's PC, if you want something that looks like the copper effect, then all you really need to do is take advantage of the fact that the PC is realyl fast, and you have 24bit color. Creating smooth color gradients that scroll down the screen is pretty simple to do when you have 24bit color.


CS_TBL(Posted 2005) [#4]
dunno .. is this what you want? :)




Grey Alien(Posted 2005) [#5]
Try this code out, don't run it with debug mode on or it will crawl! The time in the top left is how many millisecs the code takes to execute (31 on my PC). It can be optimised lots. Paste into notepad first and then into blitz to ensure it formats correctly.

Hey CS_TBL how do you get you code to appear in the scrollbox?

; -----------------------------------------------------------------------------
; JB Demo 0.1 JB 09/01/05
; -----------------------------------------------------------------------------
; Last Revision: 28/01/05
; -----------------------------------------------------------------------------

	Const GAMENAME$ = "JB Demo"
	Const VERSION$ = "V0.1"
	Const COPYRIGHT$ = " (c) 2005"
	Const FULLNAME$ = GAMENAME$ + " " + VERSION$ + COPYRIGHT$

	Const GAME_WIDTH = 640
	Const GAME_HEIGHT = 480

	Const ESCAPE = 1

;demo globals
	Global Amp# = 100
	Global AmpSpeed% = 5
	Global Phase = 0
	Global PhaseSpeed = 4
	Global WL# = 1
	Global WLSpeed# = 0.05
	Global MidY% = GAME_HEIGHT/2
	Global StartTime%
	Global EndTime%	
	Global MinCounter = 90
	Global MaxCounter = 170
	Global Counter = MinCounter
	Global CounterDir% = 1
	
;Note: Sin 0 = 0, 90 = 1, 180 = 0, 270 = -1

; -----------------------------------------------------------------------------
; Includes...
; -----------------------------------------------------------------------------

; -----------------------------------------------------------------------------
; Create a Graphics window...
; -----------------------------------------------------------------------------
	AppTitle FULLNAME ;do before graphics is called
	Graphics GAME_WIDTH, GAME_HEIGHT, 32
	SetBuffer BackBuffer()	
	SeedRnd MilliSecs()

; -----------------------------------------------------------------------------
; Main loop...
; -----------------------------------------------------------------------------
SetBuffer BackBuffer() ;vital

Local LoopExit = 0
Repeat 

	LoopExit = 0	

	Repeat
		;code here	
		Cls

		;drawcode goes here		
		StartTime = MilliSecs()
		DrawSinWaveBlurToEdgeAuto()
		EndTime = MilliSecs()

		;output time
		Color 255,255,255
		Text(10,10,EndTime-StartTime + " ms")

		If DoVWait Then VWait
		Flip False

		;escape key quits
		If (KeyHit (ESCAPE)) Then
			LoopExit = 1
		EndIf
	
	Until LoopExit <> 0
	
	;set LoopExit to 1 to exit the program
Until LoopExit = 1

;Exit the program
End

; -----------------------------------------------------------------------------
Function DrawSinWaveBlurToEdgeAuto()
		;31ms
		Local Start = 200
		Local m=2 ;multiplier
		LockBuffer 
		For i = 0 To GAME_WIDTH-1
			Col = MakeARGB(Start,0,0)
			x = i

			;get y coord		
			y = MidY+Sin(phase+(i/WL))*Amp
			For j = 0 To Start*m
				Col = MakeARGB((Start-j/m),j/m,(Start-j/m)+j/m)
				oy = y-j
				;limit coords to screen
				;y
				If oy < 0 Then
				  oy = 0
				Else
				  If oy >= GAME_HEIGHT Then
				     oy = 0
				  EndIf
				EndIf  
				;don't draw oy=0 pixels
				If oy > 0 Then WritePixelFast (x, oy, Col)
				oy = y+j
				;y again
				If oy < 0 Then
				  oy = 0
				Else
				  If oy >= GAME_HEIGHT Then
				     oy = 0
				  EndIf
				EndIf
				;don't draw oy=0 pixels
				If oy > 0 Then WritePixelFast (x, oy, Col)
			Next	   
		Next
		UnlockBuffer 

		Phase = Phase + PhaseSpeed
		Limit = 360
;		Limit = 360 * WL
		While Phase >= Limit
		  Phase = Phase - Limit
		Wend
		
		;pendulum counter
		Select CounterDir
			Case 1
				If Counter < MaxCounter-1 Then
					Counter = Counter + 1
				Else
					CounterDir = -1
					Counter = Counter - 1
				EndIf
			Case -1
				If Counter > MinCounter Then
					Counter = Counter - 1
				Else
					CounterDir = 1
					Counter = Counter + 1
				EndIf
		End Select
		
		WL = Sin(Counter)
		If WL < 0.0 Then
    	   WL = 0.0-WL ;reverse -ve
		EndIf
		If WL = 0 Then WL = 0.001 ;avoid divide by zero
		Amp = 150 * Sin(Counter)
End Function

; -----------------------------------------------------------------------------
; Take 3 colours and make ARGB Integer
; -----------------------------------------------------------------------------
Function MakeARGB%(R, G, B)
    Return R*256*256+G*256+B
End Function



CS_TBL(Posted 2005) [#6]
how do you get you code to appear in the scrollbox?

<codebox>
</codebox>


<> = [] obviously ^_^


or:

CreateSlider()

^_^


Grey Alien(Posted 2005) [#7]
Thanks dude, try this then for copper bars (just whipped it up) ... 4ms on my PS.

On the Amiga the copper bars could go from the far left of the screen to the far right and thus would display on areas you couldn't normally draw too. Also the copper was a co-processor that did its cool stuff independantly of the main CPU so your main code never slowed down. There were other co-processors such as for sound etc. The PC's architecture is a bit crap by comparison.




CS_TBL(Posted 2005) [#8]
ah, I know that effect .. is that the official copper thing then?


Grey Alien(Posted 2005) [#9]
christ that was a quick reply, I just edited my post, read a bit more. Copper was used for full screen coloured sine waves, bars like in my 2nd post, mirror effects under scrolling messages, colour cycling fractals, gradiated sky effects behind platformers (Turrican etc.) and much more, it was cool.


aab(Posted 2005) [#10]
Why Not just Create an image to draw onto as the 'bar', and draw it at the relevent coordinates?


Grey Alien(Posted 2005) [#11]
Yeah, aab, much faster; but I was still thinking in Amiga mode and it was quick and dirty. Also commonly the bars would be different colours. In fact I nearly coded it using lock buffer and writepixel and thought doh ... use Line as it is probably well optimised.


Grey Alien(Posted 2005) [#12]
In fact here are some coloured copper bars




WolRon(Posted 2005) [#13]
use Line as it is probably well optimised
Actually not. A Rect only 1 pixel thick is 70% faster than a Line.


Grey Alien(Posted 2005) [#14]
wow, I guess that's because the line may have an end point not on the same line and a rect just draws a block.


CS_TBL(Posted 2005) [#15]
ok .. lame .. but it's small code :)
window=CreateWindow("B+ bars -- by CS^TBL",100,100,400,300,0,1)
canvas=CreateCanvas(1,1,2,240,window):SetGadgetShape canvas,4,4,320,240
Global f1

timer=CreateTimer(100)
SetBuffer CanvasBuffer(canvas)
Repeat
	WaitEvent()
	If EventID()=$803 quit=True
	If EventID()=$4001
		blah():	f1=f1+1:FlipCanvas canvas
	EndIf
Until quit
SetBuffer DesktopBuffer()
End

Function blah()
	For t=0 To 7
		p=120+Sin((f1+t*4)*2)*116
		Color 0,t*35,0:	Rect 0,p-4,1,8
		Color 255,0,(t*35):	Rect 1,p-4,1,8
	Next
End Function