SuperStrict
Rem
bbdoc: Reko
EndRem
Module pantson.reko
ModuleInfo "Version: 1.00"
ModuleInfo "Author: Richard Hanson"
ModuleInfo "Modserver: pantson"
ModuleInfo "More card packs : http://www.rekonet.org/"

'Import brl.retro
Import brl.system
Import brl.max2d

Public

Rem
bbdoc: LoadRekoImage returns an image of entire series of cards from the reko cardset.
EndRem
Function LoadRekoImage:timage(file:String,scale:Int=1)
	Local img:timage
	Local i:Int
	Local out:timage
	Local map_out:TPixmap,map_in:TPixmap
	Local x:Int,y:Int
	Local c:Int
	
	img = LoadRekoAnimImage(file,scale)
	out = CreateImage(img.width*img.frames.length,img.height)
	
	map_out = LockImage(out)	
	i = 0
	While i < img.frames.length
		map_in = LockImage(img,i)
		
		' copy data
		x = 0
		While x < img.width
			y = 0
			While y < img.height
				c = ReadPixel(map_in,x,y)
				WritePixel(map_out,x+i*img.width,y,c)
				y:+1
			Wend
			x:+1
		Wend
		
		UnlockImage(img,i)
		i:+1
	Wend
	UnlockImage(out)
	
	Return out
End Function

Rem
bbdoc: LoadRekoAnimImage returns a series of image of the the reko cardset.
EndRem
Function LoadRekoAnimImage:timage(file:String,scale:Int=1)
	Local p:Int[]
	Local bank:TBank
	Local header:Int
	Local bodysize:Int
	Local cardsize:Int
	Local width:Int
	Local height:Int
	Local depth:Int
	Local cardcnt:Int
	Local modeID:Int
	Local x:Int
	Local y:Int
	Local image:timage
	Local map:TPixmap
	Local c:Int,r:Int,g:Int,b:Int
	Local col:Int[256]
	Local bits:Int[8]
	Local bitmapsize:Int
	Local bitplanewidth:Int
	Local numcolours:Int
	Local prer:Int,preg:Int,preb:Int
	Local i:Int,d:Int
	
	Local n:Int,m:Int
	
	bank = LoadBank(file)
	If bank = Null Then Return Null
	
	LockBank(bank)
	
	image = Null
	
	' PC style
	If peekstring(bank,0,6) = "PCREKO"		
		bodysize = PeekInt(bank,8)
		cardsize = PeekInt(bank,12)
		width = PeekShort(bank,16)
		height = PeekShort(bank,18)
		depth = PeekByte(bank,20)
		cardcnt = PeekByte(bank,21)
		
		header = 26
	
		' create anim image
		image = CreateImage(width*scale,height*scale,cardcnt)
		
		Select depth
		Case 16
			cardsize = width*height*2 + 4 
			i = 0	
			While i < cardcnt
				map = LockImage(image,i)
				'width = PeekShort(bank,header + cardsize*i + 0)+1
				'height = PeekShort(bank,header + cardsize*i + 2)+1
				
				y = 0
				While y < height
					x = 0
					While x < width
						c = PeekShort(bank,header + cardsize*i + (y*width+x)*2)
						r = (c & %0111110000000000) Shr 7
						g = (c & %0000001111100000) Shr 2
						b = (c & %0000000000011111) Shl 3
						
						n = 0
						While n < scale
							m = 0
							While m < scale
								WritePixel map,x*scale+n,y*scale+m,(r Shl 16)+(g Shl 8)+b 
								m:+1
							Wend
							n:+1
						Wend
						
						x:+1
					Wend
					y:+1
				Wend
				
				UnlockImage(image,i)
				i:+1
			Wend
		Case 8
			cardsize = width*height + 4 + 512
			i = 0	
			While i < cardcnt
				map = LockImage(image,i)
				width = PeekShort(bank,header + cardsize*i + 0)+1
				height = PeekShort(bank,header + cardsize*i + 2)+1
				
				' get colours
				numcolours = 0
				While numcolours < 256
					c = PeekShort(bank,header + cardsize*i + 4 + numcolours*2)
					r = (c & %0111110000000000) Shr 7
					g = (c & %0000001111100000) Shr 2
					b = (c & %0000000000011111) Shl 3
					col[numcolours] = (r Shl 16)+(g Shl 8)+b
					numcolours:+1
				Wend 
				
				' get colour data
				y = 0
				While y < height
					x = 0
					While x < width
						c = PeekByte(bank,header + cardsize*i + 512+4 + (y*width+x))
						n = 0
						While n < scale
							m = 0
							While m < scale
								WritePixel map,x*scale+m,y*scale+n,col[c] 
								m:+1
							Wend
							n:+1
						Wend
						
						x:+1
					Wend
					y:+1
				Wend
				
				UnlockImage(image,i)
				i:+1
			Wend
		End Select
	EndIf
	
	' old amiga style
	If peekstring(bank,0,4) = "REKO"
		bodysize = EndianLong(PeekInt(bank,4))
		cardsize = EndianLong(PeekInt(bank,8))	
		width = Endianshort(PeekShort(bank,14))
		height = Endianshort(PeekShort(bank,12))
		modeid = EndianLong(PeekInt(bank,16)) & 2048		
		depth = PeekByte(bank,20)
		
		numcolours = Ceil(2^depth)
		If modeid= 2048 Then numcolours = Ceil(2^(depth-2))
		cardcnt = Min(59,PeekByte(bank,21))
		
		header = 22
		i = 0
		While i < numcolours
			r = PeekByte(bank,header + i*3 + 0)
			g = PeekByte(bank,header + i*3 + 1)
			b = PeekByte(bank,header + i*3 + 2)
			
			col[i] = (r Shl 16) + (g Shl 8) + b
			i:+1
		Wend	
		header:+ numcolours*3
			
		image = CreateImage(width,height,cardcnt)
	
		bitplanewidth = width/8
		cardsize = bitplanewidth*height*depth
		
		i = 0
		While i < cardcnt
			map = LockImage(image,i)
					
			y = 0
			While y < height
				x = 0
				While x < bitplanewidth
					d = 0
					While d < depth
						bits[d] = PeekByte(bank,header + bitplanewidth*d + x + (depth*bitplanewidth)*y + (cardsize*i))
						d:+1
					Wend
					
					p = BitmapConvert(bits)		
					
					If modeid = 2048		
						prer = 0
						preg = 0
						preb = 0
						If x > 0
							c = ReadPixel(map,x*8-1,y)
							prer = (c Shr 16) & 255
							preg = (c Shr 8) & 255
							preb = (c Shr 0) & 255
						EndIf
					EndIf
					
					c = 0
					While c <8
						' ham mode
						If modeid = 2048
							If p[c] < numcolours
								WritePixel map,x*8+c,y,col[p[c]]
								prer = (col[p[c]] Shr 16) & 255							
								preg = (col[p[c]] Shr 8) & 255							
								preb = (col[p[c]] Shr 0) & 255							
							Else
								Select (p[c] Shr 6)
								Case 1
									preb = ((p[c]-64) Shl 2)
								Case 3
									preg = ((p[c]-192) Shl 2)
								Case 2
									prer = ((p[c]-128) Shl 2)
								End Select
								WritePixel map,x*8+c,y,(prer Shl 16) + (preg Shl 8) + preb
							EndIf
						Else
							WritePixel map,x*8+c,y,col[p[c]]
						EndIf
						c:+1
					Wend
					x:+1
				Wend
				y:+1
			Wend

			UnlockImage(image,i)	 
			i:+1
		Wend		
	EndIf
	
	UnlockBank(bank)
	bank=Null
	
	Return image
End Function

Private
Function BitmapConvert:Int[](bitplanes:Int[]=Null)
	Local pixels:Int[8]
	Local i:Int
	Local test:Byte
	Local mask:Byte
	Local b:Int
	
'	test = %11000110

	i = 0
	While i < 7
		pixels[i] = 0
		i:+1
	Wend
	
	b = 0
	While b < bitplanes.length 
		i = 0
		While i < 8
			mask = Ceil(2^(7-i))
			If (bitplanes[b] & mask) > 0 Then pixels[i]:+ Ceil(2^b)
			i:+1
		Wend
		b:+1
	Wend
	
	Return pixels
End Function

Function peekstring:String(bank:TBank,position:Int,length:Int)
	Local i:Int
	Local str:String
	
	i = 0
	While i < length
		str=str+Chr(PeekByte(bank,position+i))
		i:+1
	Wend
	
	Return str
End Function

Function EndianShort:Int(n:Int)
	Return ((n & $ff00) Shr 8) + ((n & $ff) Shl 8)
End Function

Function EndianLong:Int(n:Int)
	Local i:Int
	
	i = (n & $ff000000) Shr 24
	i:+ (n & $000000ff) Shl 24
	i:+ (n & $00FF0000) Shr 8
	i:+ (n & $0000FF00) Shl 8

	Return i
End Function

