[bb] CDG player by Space Fractal [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:42

Previous topic - Next topic

BlitzBot

Title : CDG player
Author : Space Fractal
Posted : 1+ years ago

Description : CDG Command Line Player

Public Domain. No warranty.

Version 0.1

Purpose:
CommandLine CDG player for using with external software players.

Supported formats:
MP3, OGG and WAV with added CDG graphic files.

Command:
CDG_Player.exe FILENAME
CDG_Player.exe FILENAME Rotate90
CDG_Player.exe FILENAME Rotate180
CDG_Player.exe FILENAME Rotate270

Example:
CDG_Player.exe D:Download   estCDGTwist and Shout.cdg Rotate90

Note:
If the file dosen't exists, it open a file requester instead.

Relaesed to:
Build You Own Arcade Controls (http://www.arcadecontrols.com) and Blitz Community.

All you need is just a little notice credit in your readme (I really hope).

Best Regaards by
Space Fractal
<a href="http://www.arcademusicbox.com/" target="_blank">http://www.arcademusicbox.com</a> (made in Blitz+)


Code :
Code: blitzbasic
Global CDG_COMMAND = 9
Global CDG_MASK = 63

Global CDG_INST_MEMORY_PRESET     = 1
Global CDG_INST_BORDER_PRESET     = 2
Global CDG_INST_TILE_BLOCK        = 6
Global CDG_INST_SCROLL_PRESET     = 20
Global CDG_INST_SCROLL_COPY       = 24
Global CDG_INST_DEF_TRANSP_COL    = 28
Global CDG_INST_LOAD_COL_TBL_0_7  = 30
Global CDG_INST_LOAD_COL_TBL_8_15 = 31
Global CDG_INST_TILE_BLOCK_XOR    = 38

Global CDG_STREAM_COMMAND
Global CDG_STREAM_INTRUCTION
Global CDG_BUFFER_FRONT=0
Global CDG_BUFFER_BACK=1

Global CDG_COLOR_BORDER=0
Global CDG_COLOR_FILL=0
Global CDG_COLOR_TRANSPERANT=0

Global CDG_STREAM_FILE$      = ""
Global CDG_STREAM_FILE_ID    = 0
Global CDG_STREAM_FILE_SOUND = 0
Global CDG_STREAM_FILE_TIMER
Global CDG_STREAM_XOFFSET = 0
Global CDG_STREAM_YOFFSET = 0
Global CDG_IMAGE
Global CDG_ROTATION = 0

Dim CDG_COLOR_TABLE(17,5)
Dim CDG_STREAM_PARITYQ(2)
Dim CDG_STREAM_DATA$(17)
Dim CDG_STREAM_PARITYP(4)
Dim CDG_SCREEN(301,217,2,2)

CMD$=Lower$(CommandLine$())
If Instr(CMD$,"otate90") Then CDG_ROTATION=90 : CMD$=Replace$(CMD$,"otate90","")
If Instr(CMD$,"otate180") Then CDG_ROTATION=180 : CMD$=Replace$(CMD$,"otate180","")
If Instr(CMD$,"otate270") Then CDG_ROTATION=270 : CMD$=Replace$(CMD$,"otate270","")
FILE$=Trim$(CMD$)
If FileType(FILE$)=-0 Then FILE$=RequestFile("Open a CDG file","CDG",False)

CDG_PLAY(FILE$,CDG_ROTATION)

Function CDG_PLAY(FILE$, CDG_ROTATION)
	;mode=2
	CDG_BUFFER_FRONT=0
	CDG_BUFFER_BACK=1
	
	; SETUP THE GRAPHICS CARD. THIS APPLICATION SUPPORT ROTATION
	If CDG_ROTATION=0 Or CDG_ROTATION=180
		If GfxModeExists(320,240,16) Then Graphics 320,240,16,0 Else Graphics 321,240,16,0
		CDG_IMAGE=CreateImage(301,217,1,1)
		MaskImage CDG_IMAGE,5,5,5
	EndIf

	If CDG_ROTATION=90 Or CDG_ROTATION=270
		If GfxModeExists(400,300,16) Then Graphics 400,300,16,0 Else Graphics 640,480,16,0
		CDG_IMAGE=CreateImage(217,301,1,1)
	EndIf
	

	fntVerdana=LoadFont("Verdana",14,False,False,False)
	SetFont fntVerdana

	A=StringWidth("Karaoke")
	COPYRIGHT=CreateImage(A,20,1,1)
	SetBuffer ImageBuffer(Copyright)
	SetFont fntVerdana
	Color 90,90,90
	Text 0,0,"Karaoke"

	A=StringWidth("Arcade Music Box")
	COPYRIGHT2=CreateImage(A,20,1,1)
	SetBuffer ImageBuffer(Copyright2)
	SetFont fntVerdana
	Color 90,90,90
	Text 0,0,"Arcade Music Box"

	If CDG_ROTATION=90
		MidHandle Copyright : MidHandle Copyright2
		RotateImage Copyright,90 :	RotateImage Copyright2,90
		HandleImage Copyright,0,0 : HandleImage Copyright2,0,0
	Else If CDG_ROTATION=180
		MidHandle Copyright : MidHandle Copyright2
		RotateImage Copyright,180 :	RotateImage Copyright2,180
		HandleImage Copyright,0,0 : HandleImage Copyright2,0,0
	Else If CDG_ROTATION=270
		MidHandle Copyright : MidHandle Copyright2
		RotateImage Copyright,270 :	RotateImage Copyright2,270
		HandleImage Copyright,0,0 : HandleImage Copyright2,0,0
	EndIf

	; READ MUSIC FILE AND OPEN CDG FILE
	CDG_STREAM_FILE_ID=ReadFile(FILE$)
	If CDG_STREAM_FILE_ID=0 Then Return

	FILE2$=Left$(FILE$,Len(FILE$)-4)
	CDG_STREAM_FILE_SOUND=LoadSound(FILE2$+".mp3")
	If CDG_STREAM_FILE_SOUND=0 Then LoadSound(FILE2$+".ogg")
	If CDG_STREAM_FILE_SOUND=0 Then LoadSound(FILE2$+".wav")
	If CDG_STREAM_FILE_SOUND=0 Then Return
	ok=PlaySound(CDG_STREAM_FILE_SOUND)
	
	; ********************
	; **** CDG PLAYER ****
	; ********************
	CDG_STREAM_FILE_TIMER = MilliSecs()+50
	Repeat
 		; READ A 24 BYTE PACKET FROM THE FILE (PARITYQ and PARITYP seen not been used in anyware, but keept them here)
		For ticks=1 To 15
			CDG_STREAM_COMMAND=ReadByte(CDG_STREAM_FILE_ID)  And CDG_MASK
			CDG_STREAM_INTRUCTION=ReadByte(CDG_STREAM_FILE_ID) And CDG_MASK
			CDG_STREAM_PARITYQ(1)=ReadByte(CDG_STREAM_FILE_ID) And CDG_MASK
			CDG_STREAM_PARITYQ(2)=ReadByte(CDG_STREAM_FILE_ID) And CDG_MASK
			For i=0 To 15 : Byte=ReadByte(CDG_STREAM_FILE_ID) : CDG_STREAM_DATA$(i)=Right$(Bin$(Byte),6) : Next
			For i=1 To 4 : CDG_STREAM_PARITYP(i)=ReadByte(CDG_STREAM_FILE_ID) And CDG_MASK : Next
			If CDG_STREAM_COMMAND=9
				ok=0
				If CDG_STREAM_INTRUCTION=CDG_INST_MEMORY_PRESET Then CDG_MEMORY_PRESET() : ok=1
				If CDG_STREAM_INTRUCTION=CDG_INST_BORDER_PRESET  Then CDG_BORDER_PRESET() : ok=1
				If CDG_STREAM_INTRUCTION=CDG_INST_LOAD_COL_TBL_0_7 Then CDG_LOAD_COL_TBL(0) : ok=1
				If CDG_STREAM_INTRUCTION=CDG_INST_LOAD_COL_TBL_8_15 Then CDG_LOAD_COL_TBL(8) : ok=1
				If CDG_STREAM_INTRUCTION=CDG_INST_TILE_BLOCK Then CDG_TILE_BLOCK(0) : ok=1
				If CDG_STREAM_INTRUCTION=CDG_INST_TILE_BLOCK_XOR Then CDG_TILE_BLOCK(1) : ok=1
				If CDG_STREAM_INTRUCTION=CDG_INST_SCROLL_PRESET Then CDG_SCROLL(0) : ok=1
				If CDG_STREAM_INTRUCTION=CDG_INST_SCROLL_COPY Then CDG_SCROLL(1) : ok=1
				;If CDG_STREAM_INTRUCTION>0 And ok=0 Then Print "unsupported instruction: "+CDG_STREAM_INTRUCTION
			EndIf
		Next

		SetBuffer ImageBuffer(CDG_IMAGE)
		If KeyDown(1)=True Then End
		
		; DISPLAY THE BUFFER TO THE SCREEN
		If (CDG_STREAM_FILE_TIMER >= MilliSecs())
			LockBuffer ImageBuffer(CDG_IMAGE)
			For x=7 To 300
				For y=13 To 216
					xx=x+CDG_STREAM_XOFFSET : If xx>300 Then xx=xx-300
					yy=y+CDG_STREAM_YOFFSET : If yy>216 Then yy=yy-216
					If CDG_ROTATION=0 Then WritePixelFast x-6,y-12,CDG_SCREEN(xx,yy,0,CDG_BUFFER_FRONT)
					If CDG_ROTATION=90 Then WritePixelFast 217-y,x-6,CDG_SCREEN(xx,yy,0,CDG_BUFFER_FRONT)
					If CDG_ROTATION=180 Then WritePixelFast 301-x,217-y,CDG_SCREEN(xx,yy,0,CDG_BUFFER_FRONT)
					If CDG_ROTATION=270 Then WritePixelFast y-12,301-x,CDG_SCREEN(xx,yy,0,CDG_BUFFER_FRONT)
				Next
			Next

			UnlockBuffer ImageBuffer(CDG_IMAGE)

			SetBuffer BackBuffer()
			If CDG_ROTATION=-1
		
			Else If CDG_ROTATION=0
				Color 255,255,255
				x=14 : y=18
				DrawImage CDG_IMAGE,x,y,0
				Rect x,y,294+2,204+2,0
				DrawImage COPYRIGHT,160-ImageWidth(COPYRIGHT)/2,1 : DrawImage COPYRIGHT2, 160-ImageWidth(COPYRIGHT2)/2,224
				Flip
			Else If CDG_ROTATION=90
				Color 255,255,255
				x=2 : y=100 : If GraphicsWidth()=640 Then x=96 : cx=244
				Rect y-1,x-1,204+2,294+2,1
				DrawImage CDG_IMAGE,y-1,x-1,0
				DrawImage COPYRIGHT2,30,GraphicsHeight()/2-ImageHeight(COPYRIGHT2)/2
				DrawImage COPYRIGHT, GraphicsWidth()-50-cx, GraphicsHeight()/2-ImageHeight(COPYRIGHT)/2	
				Flip
			Else If CDG_ROTATION=270
				Color 255,255,255
				x=2 : y=100 : If GraphicsWidth()=640 Then x=96 : cy=240 : y=y+cy : cx=244
				Rect y-1,x-1,204+2,294+2,1
				DrawImage CDG_IMAGE,y-1,x-1,0
				DrawImage COPYRIGHT,30+cy,GraphicsHeight()/2-ImageHeight(COPYRIGHT)/2
				DrawImage COPYRIGHT2, GraphicsWidth()-50-cx+cy, GraphicsHeight()/2-ImageHeight(COPYRIGHT2)/2
				Flip
			Else CDG_ROTATION=180
				Color 255,255,255
				x=14 : y=18
				Rect x-1,y-1,294+2,204+2,1
				DrawImage CDG_IMAGE,x-1,y-1,0
				DrawImage COPYRIGHT2,160-ImageWidth(COPYRIGHT2)/2,-5 : DrawImage COPYRIGHT, 160-ImageWidth(COPYRIGHT)/2,219		
				Flip
			EndIf
		EndIf
		
		; WAIT TIMER
		Repeat : Delay 1 : Until CDG_STREAM_FILE_TIMER < MilliSecs()
		CDG_STREAM_FILE_TIMER=CDG_STREAM_FILE_TIMER+50
	Until Eof(CDG_STREAM_FILE_ID) Or ChannelPlaying(CDG_STREAM_FILE_SOUND)=1
	FreeSound CDG_STREAM_FILE_SOUND
	FreeImage CDG_IMAGE
End Function

; **** DRAW A 6x12 TILE (USING XOR OR NORMAL OPERATION)
Function CDG_TILE_BLOCK(BLOCK_XOR)
	colorA=ReadBit(CDG_STREAM_DATA$(0),3,4)
	colorB=ReadBit(CDG_STREAM_DATA$(1),3,4)
	row=ReadBit(CDG_STREAM_DATA$(2),2,5)*12
	col=ReadBit(CDG_STREAM_DATA$(3),1,6)*6
	For y=0 To 11
		For x=0 To 5
			yy=y+row : xx=x+col
			If xx<294 And yy<205
				If Mid(CDG_STREAM_DATA$(y+4),x+1,1)="1" 
					display=colorB
				Else 
					display=colorA
				EndIf
				If BLOCK_XOR=1
					display=display Xor CDG_SCREEN(xx,yy,1,CDG_BUFFER_FRONT)   ;THIS COMMAND IS HEAVY USED
				EndIf
				CDG_SCREEN(xx,yy,1,CDG_BUFFER_FRONT)=display
				CDG_SCREEN(xx,yy,0,CDG_BUFFER_FRONT)=CDG_COLOR_TABLE(display,4)
			EndIf
		Next
	Next
End Function

; **** FILL THE SCREEN WITH THAT COLOR
Function CDG_MEMORY_PRESET()
	CDG_COLOR_FILL=ReadBit(CDG_STREAM_DATA$(0),3,4)
	CDG_COLOR_REPEAT=ReadBit(CDG_STREAM_DATA$(1),3,4) ; THIS MAY BE A BOUNCS IF COMMANDS. IT ONLY NEED THIS ONCE.
	If CDG_COLOR_REPEAT=0
		For x=7 To 300
			For y=13 To 216
				CDG_SCREEN(x,y,0,CDG_BUFFER_FRONT)=CDG_COLOR_TABLE(CDG_COLOR_FILL,4)
				CDG_SCREEN(x,y,1,CDG_BUFFER_FRONT)=CDG_COLOR_FILL
			Next
		Next
	EndIf
End Function

; **** FILL THE BORDER WITH THAT COLOR (ONLY USED FOR SCROLLING THINGS)
Function CDG_BORDER_PRESET(COLOUR=-1)
	If COLOUR=-1 Then CDG_COLOR_BORDER=ReadBit(CDG_STREAM_DATA$(0),3,4) Else CDG_COLOR_BORDER=COLOUR 
	For x=1 To 6
		For y=1 To 216
			CDG_SCREEN(x,y,0,CDG_BUFFER_FRONT)=CDG_COLOR_TABLE(CDG_COLOR_FILL,4)
			CDG_SCREEN(x,y,1,CDG_BUFFER_FRONT)=CDG_COLOR_BORDER
		Next
	Next 

	For x=1 To 300
		For y=1 To 12
			CDG_SCREEN(x,y,0,CDG_BUFFER_FRONT)=CDG_COLOR_TABLE(CDG_COLOR_FILL,4)
			CDG_SCREEN(x,y,1,CDG_BUFFER_FRONT)=CDG_COLOR_BORDER
		Next
	Next
End Function

; **** READ COLOR THE LOWER 8 OR HIGHER 8 COLOR TABLES
Function CDG_LOAD_COL_TBL(FROM)
	count=0
	For i=0 To 15 Step 2
		COLORS$=CDG_STREAM_DATA$(i)+CDG_STREAM_DATA$(i+1)
		RED=ReadBit(COLORS$,1,4)*17
		GREEN=ReadBit(COLORS$,5,4)*17
		BLUE=ReadBit(COLORS$,9,4)*17
		CDG_COLOR_TABLE(count+from,1)=RED
		CDG_COLOR_TABLE(count+from,2)=GREEN
		CDG_COLOR_TABLE(count+from,3)=BLUE
		COLORS$="00"+HexByte$(RED)+HexByte$(GREEN)+HexByte$(BLUE)
		COLOUR=VAL(COLORS$)
		CDG_COLOR_TABLE(count+FROM,4)=COLOUR
		count=count+1
	Next
End Function

; **** SCROLL THE TEXT ****
Function CDG_SCROLL(COPY=0)
	colorA=ReadBit(CDG_STREAM_DATA$(0),3,4)
	
	hSCmd = ReadBit(CDG_STREAM_DATA$(1),1,2)
 	hScroll=ReadBit(CDG_STREAM_DATA$(1),3,4)

	vSCmd = ReadBit(CDG_STREAM_DATA$(2),1,2)
 	vScroll=ReadBit(CDG_STREAM_DATA$(2),3,4)
	If vSCmd=0
		CDG_STREAM_YOFFSET=vScroll+1
	Else If vSCmd=1
		MOVE_Y=12
	Else
		MOVE_Y=-12
	EndIf

	If hSCmd=0
		CDG_STREAM_XOFFSET=hScroll+1
	Else If hSCmd=1
		MOVE_X=6
	Else
		MOVE_X=-6
	EndIf

	If MOVE_Y=0 And MOVE_Y=0 Then Return
	CDG_STREAM_YOFFSET=0
	CDG_STREAM_XOFFSET=0
	If COPY=0 Then CDG_BORDER_PRESET(colorA)
	
	For y=1 To 216
		For x=1 To 300
			NewX=x+MOVE_X 
			NewY=y+MOVE_Y 
			If NewY<1 Then NewY=NewY+216
			If NewY>216 Then NewY=NewY-216
			If NewX<1 Then NewX=NewX+300
			If NewX>300 Then NewX=NewX-300
			CDG_SCREEN(NewX,NewY,0, CDG_BUFFER_BACK)=CDG_SCREEN(x,y,0, CDG_BUFFER_FRONT) 
			CDG_SCREEN(NewX,NewY,1, CDG_BUFFER_BACK)=CDG_SCREEN(x,y,1, CDG_BUFFER_FRONT) 
		Next
	Next
	CDG_BUFFER_FRONT=CDG_BUFFER_FRONT+1 : If CDG_BUFFER_FRONT=2 Then CDG_BUFFER_FRONT=0
	CDG_BUFFER_BACK=CDG_BUFFER_BACK+1 : If CDG_BUFFER_BACK=2 Then CDG_BUFFER_BACK=0


End Function

; ************************
; **** HELP FUNCTIONS ****
; ************************

Function HexByte$(BYTE) ;THIS WAS USED FOR GETTING RGB VALUES OF COLORS
	Return Right$(Hex$(BYTE),2)
End Function 

Function ReadBit(BINARY$,s,c) ;IT EASIER TO READ BINARY BITS FROM A STRING, RATHER THAN BITS IT SELF.
	BI$=Mid$(BINARY$,s,c)
	D=1
	RES=0
	For i=c To 1 Step -1
		If Mid$(BI$,i,1)="1" Then RES=RES+D
		D=D+D
	Next
	Return RES
End Function

Function Tok$(FIND$,TXT$)
	RESULT$="" : ADD=0 : R=0
	For I=1 To Len(TXT$)
		If ADD=0 Then CHAR$=Mid$(TXT$, I,Len(FIND$)+1)
		If ADD=1 Then CHAR$=Mid$(TXT$, I,1)
		If CHAR$="|" Then Return RESULT$
		If ADD=1 Then RESULT$=RESULT$+CHAR$
		If Trim(CHAR$)=Trim(FIND$)+"=" And ADD=0 Then I=I+Len(FIND$) : ADD=1
	Next
Return
End Function

Function Val#(StringNumeric$)
	StringNumeric$="$"+StringNumeric$
	Local Num# = 0
	Local Hex1 = ((Left$(StringNumeric$,1)="#") Or (Left$(StringNumeric$,1)="$"))
	Local Hex2 = (Left$(StringNumeric$,2)="0x")
	Local i,c
   
	StringNumeric$ = Upper(StringNumeric$)
	For i=(Hex1 + (Hex2 * 2) + 1) To Len(StringNumeric$) 
		c = Asc(Mid$(StringNumeric$,i,1))
		Select True
			Case (c>=48 And c<=57)  ;0 through 9
 				Num# = (Num# * 16) + c-48
			Case (c>=65 And c<=70)  ;A through F
				Num# = (Num# * 16) + c-55
			Default
				Return Num#                        
		End Select
	Next
	Return Num#
End Function


Comments :


Damien Sturdy(Posted 1+ years ago)

 heh, now THATS sweet :) Cheers!


DjBigWorm(Posted 1+ years ago)

 This has to be the neatest code I have seen in a while.  I have always wondered what it took to make a karaoke cdg player.  (loud applause)  Thanks you.