A new GFX_Wizzard_BF and SpriteTool_BF compatible module
This module is very powerful
It can completely simplest replace the missing GIF store functionality of PB
It can output BF CSS sprite sheets with invisible and without invisible color of any kind
Sophisticated automation allows for easy multiple output of animated frames of any kind
The handling is much easier than the GIF handling of PB and much more powerful
Sheets can be easily converted from GIF with SpriteTool_BF, inclusive all delays
BF sprite sheets automatically contain all GIF data and delays and can also use them fully automatically
Also you can edit and change all created BF CSS sprite sheets very simple with the SpriteTool_BF again
It works amazing
This screen shot is a multiple animated output directly on canvas
A directly runnable code for this output you find in the BF download packet
Named : Sheet_using_CSS_Alpha_Sheet_BF.pb (And additional other codes)
You can download the BF code packet directly here :
http://www.purearea.net/pb/download/mod ... ard_BF.zip
Visit also purearea net - For news, codes, annoncements, PureBasic purchase and trial versions
http://purearea.net/ - The official PB support site
Code: Select all
; - SheetMaster_BF - For PureBasic
; Author : W. Albus © 2018 - www.nachtoptik.de - www.quick-aes-256.de
; The use of the SheetMaster_BF is free, but the distribution is reserved for me
; Exceptions require my written permission
; This module is compatible to GFX_Wizzard_BF and his in the download packet included sprite tool (MAIN_SpriteTool_BF.pb)
DeclareModule SheetMaster_BF
EnableExplicit
Declare ErrorCheck_BF(result_) ; Rudimentary error checks
; 100 delay timer available - 0 to 99
; time=-1 Initialize the timer - This set the first delay to zero for beginning a animation directly without a delay)
; You can change the number of available timers
; For internal things use this timer not or you influence the timers
; For internal timer using look for Procedure "Delay_internal" and pre check in the code for actual used internal timers
#Size_Timer_Array=99 ; 100 different timers available
Declare Delay_BF(timer, time)
Declare GetGIFandCSS_invisible_color_BF() ; Get gif and CSS sheet invisible color after useing gif and sheet read or write functions
Declare GetGIFandCSS_Frames_BF() ; Get gif and CSS sheet number of frames after useing gif and sheet read or write functions
Declare GetGIFandCSS_Frame_width_BF() ; Get gif and CSS sheet frame width after useing gif and sheet read or write functions
Declare GetGIFandCSS_Frame_height_BF() ; Get gif and CSS sheet frame height after useing gif and sheet read or write functions
Declare GetCSS_width_BF() ; Get CSS sheet width after useing sheet read or write functions
Declare GetCSS_height_BF() ; Get CSS sheet height after useing sheet read or write functions
Declare GetFrames_in_a_row_BF() ; Get CSS sheet frames in a row after useing sheet read or write functions
Declare GetGIFandCSS_delay_array_BF(gif_and_css_delay_array_) ; Get gif and CSS frame delays after useing gif and sheet read or write functions
Declare GetFrameData_fromSheet_BF(path$) ; Get and move all included frame data from a CSS sheet to the functions above
Declare GetFrameDataFromString_BF(string$) ; Grabbing a frame data string and put it in the frame datas - Take with care
Declare ReadSheetInfoFile_BF(path$) ; Get and move all frame data from a CSS sheet info file to the functions above
Declare SetGIFandCSS_delay_array_BF(frame, delay) ; Set the Gif and CSS delay array
Declare SetGIFandCSS_invisible_color_BF(gif_css_invisible_color_) ; Set the Gif and CSS invisible_color
Declare SetGIFandCSS_Frames_BF(gif_css_frames_) ; Set Gif and CSS frames amount
Declare SetGIFandCSS_Frame_width_BF(gif_css_frame_width_) ; Set gif and CSS sheet frame width - Take with care
Declare SetGIFandCSS_Frame_height_BF(gif_css_frame_height_) ; Set gif and CSS sheet frame height - Take with care
Declare SetGIFandCSS_Frames_BF(gif_css_frames_) ; Set gif and CSS sheet frame amount - Take with care
Declare SetCSS_width_BF(css_width_) ; Set CSS sheet width - Take with care
Declare SetCSS_height_BF(css_height_) ; Set CSS sheet height - Take with care
Declare SetFrames_in_a_row_BF(css_frames_in_a_row_) ; Set css sheet frames in a row - Take with care
Declare.s SetFrameDataInString_BF() ; Grabbing the frame data and put it in a string - Take with care
Declare.s LoadFrameData_BF(path$) ; Get the frame data and put it in the frame variables and in a string - Fail results a empty string
; Function for grabbing a frame from any BF CSS sheet
Declare Sprite_CSS_sheet_grab_frame_BF(texture_ID,
frames, ; Numbers of frames
frame, ; Selected frame - For GIF compatibility the first frame is 0
frame_width, ; Frame width
frame_height, ; Frame height
frames_in_a_row=0, ; Frames in a row - Preset 0, then BF calculate self
output_width=0, ; Resizing - Define the output width - Preset zero = without resizing
output_height=0, ; Resizing - Define the output height
texture_clip_x=0, ; Startposition inside the texture - Preset 0
texture_clip_y=0, ; Startposition inside the texture - Preset 0
texture_clip_width=0, ; Endposition inside the texture - Preset 0 = full texture width
texture_clip_height=0) ; Endposition inside the texture - Preset 0 = full texture height
; Function for grabbing a frame from any BF CSS sheet and free a defined frame
Declare Sprite_CSS_sheet_grab_frame_and_free_BF(texture_ID, free_ID,
frames, ; Numbers of frames
frame, ; Selected frame - For GIF compatibility the first frame is 0
frame_width, ; Frame width
frame_height, ; Frame height
frames_in_a_row=0, ; Frames in a row - Preset 0, then BF calculate self
output_width=0, ; Resizing - Define the output width - Preset zero = without resizing
output_height=0, ; Resizing - Define the output height
texture_clip_x=0, ; Startposition inside the texture - Preset 0
texture_clip_y=0, ; Startposition inside the texture - Preset 0
texture_clip_width=0, ; Endposition inside the texture - Preset 0 = full texture width
texture_clip_height=0) ; Endposition inside the texture - Preset 0 = full texture height
EndDeclareModule
Module SheetMaster_BF
Global gif_css_frames, gif_css_invisible_color, gif_css_frame_width, gif_css_frame_height, css_frames_in_a_row, css_width, css_height
Global Dim gif_and_css_delay_array(0)
Macro error_message
"The function is terminated !"+#LF$+#LF$+"##"+RSet(Str(Abs(result_)), 2, "0")
EndMacro
Procedure ErrorCheck_BF(result_)
Protected result
Protected bf_type$="SheetMaster_BF"
Protected error$=" ERROR"
Select result_
Case -2
MessageRequester(error$, bf_type$+" - Image not found"+#LF$+#LF$+error_message)
Case -6
MessageRequester(error$, bf_type$+" - Creating image fail"+#LF$+#LF$+error_message)
Case -8
MessageRequester(error$, bf_type$+" - Parameter wrong"+#LF$+#LF$+error_message)
Case -9
MessageRequester(error$, bf_type$+" - Function result fail"+#LF$+#LF$+error_message)
Case -21
MessageRequester(error$, bf_type$+" - File - Can not read file"+#LF$+#LF$+error_message)
Default
result=1
EndSelect
; ProcedureReturn result ; Handle errors how you want
; The messages are helpfull on development - Run your programm you should never seen any again
If Not result : End : EndIf
EndProcedure
Procedure Delay_BF(timer, time)
If Not time : ProcedureReturn 1 : EndIf
If time<0 : time=0 : EndIf
Static Dim time_1.q(#Size_Timer_Array)
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86 ; Based on x86 timer code by Danilo
Static ElapsedMilliseconds_64_oldValue.q=0
Static ElapsedMilliseconds_64_overflow.q=0
Static time_result.q
Protected current_ms.q=ElapsedMilliseconds()&$FFFFFFFF
If ElapsedMilliseconds_64_oldValue>current_ms
ElapsedMilliseconds_64_overflow+1
EndIf
ElapsedMilliseconds_64_oldValue=current_ms
time_result=current_ms+ElapsedMilliseconds_64_overflow*$FFFFFFFF
If time_result>time_1(timer)+time
time_1(timer)=time_result
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
CompilerElse
If ElapsedMilliseconds()>time_1(timer)+time
time_1(timer)=ElapsedMilliseconds()
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
CompilerEndIf
EndProcedure
Define i : For i=0 To #Size_Timer_Array : Delay_BF(i, -1) : Next i ; Init the BF timers
Procedure GetGIFandCSS_invisible_color_BF()
ProcedureReturn gif_css_invisible_color
EndProcedure
Procedure GetGIFandCSS_Frames_BF()
ProcedureReturn gif_css_frames
EndProcedure
Procedure GetGIFandCSS_Frame_width_BF()
ProcedureReturn gif_css_frame_width
EndProcedure
Procedure GetGIFandCSS_Frame_height_BF()
ProcedureReturn gif_css_frame_height
EndProcedure
Procedure GetCSS_width_BF()
ProcedureReturn css_width
EndProcedure
Procedure GetCSS_height_BF()
ProcedureReturn css_height
EndProcedure
Procedure GetFrames_in_a_row_BF()
ProcedureReturn css_frames_in_a_row
EndProcedure
Procedure GetGIFandCSS_delay_array_BF(gif_and_css_delay_array_)
If gif_and_css_delay_array_>ArraySize(gif_and_css_delay_array())
ReDim gif_and_css_delay_array(gif_and_css_delay_array_)
EndIf
ProcedureReturn gif_and_css_delay_array(gif_and_css_delay_array_)
EndProcedure
Procedure GetFrameData_fromSheet_BF(path$)
Protected i, file, file_length_0.q, file_length_1.q, frame_delay
file=ReadFile(#PB_Any, path$)
If Not file : ProcedureReturn -21 : EndIf
file_length_0=Lof(file)
FileSeek(file, file_length_0-8)
file_length_1=ReadQuad(file)
If file_length_1>file_length_0 Or file_length_1<10 : CloseFile(file) : ProcedureReturn -21 : EndIf ; Fuse
file_length_0=file_length_0-file_length_1+2
FileSeek(file, file_length_0)
If ReadString(file, #PB_UTF8, 6)<>"Frames" : CloseFile(file) : ProcedureReturn -21 : EndIf
FileSeek(file, -16, #PB_Relative)
gif_css_frames=Val(Mid(ReadString(file), 19, 8)) ; Count frames in the sheet
gif_css_frame_width=Val(Mid(ReadString(file), 19, 8)) ; Frame width
gif_css_frame_height=Val(Mid(ReadString(file), 19, 8)) ; Frame height
css_width=Val(Mid(ReadString(file), 19, 8)) ; Sheet width
css_height=Val(Mid(ReadString(file), 19, 8)) ; Sheet height
css_frames_in_a_row=Val(Mid(ReadString(file), 19, 8)) ; Frames in a row
gif_css_invisible_color=Val(Mid(ReadString(file), 19, 8)) ; Invisible color
Dim gif_and_css_delay_array(gif_css_frames-1)
While Not Eof(file) And i<gif_css_frames
frame_delay=Val(Mid(ReadString(file), 29, 8) ) ; Frame delay
If Not frame_delay : frame_delay=100 : EndIf
gif_and_css_delay_array(i)=frame_delay ; Frame delay
; Debug GetGIFandCSS_delay_array_BF(i)
i+1
Wend
; Debug GetGIFandCSS_frames_BF()
; Debug GetGIFandCSS_frame_width_BF()
; Debug GetGIFandCSS_frame_height_BF()
; Debug GetCSS_width_BF()
; Debug GetCSS_height_BF()
; Debug GetFrames_in_a_row_BF()
; Debug GetGIFandCSS_invisible_color_BF()
CloseFile(file)
ProcedureReturn 1
EndProcedure
Procedure GetFrameDataFromString_BF(string$)
Protected i, ii=Len(string$)-1, iii
Protected delays=CountString(string$, "*")
If Not delays Or CountString(string$, "#")<>6 : ProcedureReturn -9 : EndIf ; Fuse
Dim gif_and_css_delay_array(delays-1)
i=2
SetGIFandCSS_Frames_BF(Val(Mid(string$, i, 8))) : i+9
SetGIFandCSS_frame_width_BF(Val(Mid(string$, i, 8))) : i+9
SetGIFandCSS_frame_height_BF(Val(Mid(string$, i, 8))) : i+9
SetCSS_width_BF(Val(Mid(string$, i, 8))) : i+9
SetCSS_height_BF(Val(Mid(string$, i, 8))) : i+9
SetFrames_in_a_row_BF(Val(Mid(string$, i, 8))) : i+9
SetGIFandCSS_invisible_color_BF(Val(Mid(string$, i, 8))) : i+9
For ii=i To Len(string$) Step 9
gif_and_css_delay_array(iii)=Val(Mid(string$, ii, 8))
iii+1
Next ii
ProcedureReturn 1
EndProcedure
Procedure ReadSheetInfoFile_BF(path$)
Protected i, file, frame_delay
file=ReadFile(#PB_Any, path$)
If Not file : ProcedureReturn -21 : EndIf
FileSeek(file, 10, #PB_Relative)
If ReadString(file, #PB_UTF8, 6)<>"Frames" : CloseFile(file) : ProcedureReturn -21 : EndIf
FileSeek(file, -16, #PB_Relative)
gif_css_frames=Val(Mid(ReadString(file), 19, 8)) ; Count frames in the sheet
gif_css_frame_width=Val(Mid(ReadString(file), 19, 8)) ; Frame width
gif_css_frame_height=Val(Mid(ReadString(file), 19, 8)) ; Frame height
css_width=Val(Mid(ReadString(file), 19, 8)) ; Sheet width
css_height=Val(Mid(ReadString(file), 19, 8)) ; Sheet height
css_frames_in_a_row=Val(Mid(ReadString(file), 19, 8)) ; Frames in a row
gif_css_invisible_color=Val(Mid(ReadString(file), 19, 8)) ; Invisible color
Dim gif_and_css_delay_array(gif_css_frames-1)
While Not Eof(file) And i<gif_css_frames
frame_delay=Val(Mid(ReadString(file), 29, 8) ) ; Frame delay
If Not frame_delay : frame_delay=100 : EndIf
gif_and_css_delay_array(i)=frame_delay ; Frame delay
; Debug GetGIFandCSS_delay_array_BF(i)
i+1
Wend
; Debug GetGIFandCSS_frames_BF()
; Debug GetGIFandCSS_frame_width_BF()
; Debug GetGIFandCSS_frame_height_BF()
; Debug GetCSS_width_BF()
; Debug GetCSS_height_BF()
; Debug GetFrames_in_a_row_BF()
; Debug GetGIFandCSS_invisible_color_BF()
CloseFile(file)
ProcedureReturn 1
EndProcedure
Procedure SetSheet_delay_array_BF(frame, delay)
gif_and_css_delay_array(frame)=delay
ProcedureReturn 0
EndProcedure
Procedure SetGIFandCSS_delay_array_BF(frame, delay)
gif_and_css_delay_array(frame)=delay
ProcedureReturn 0
EndProcedure
Procedure SetGIFandCSS_invisible_color_BF(gif_css_invisible_color_)
gif_css_invisible_color=gif_css_invisible_color_
ProcedureReturn 0
EndProcedure
Procedure SetGIFandCSS_Frames_BF(gif_css_frames_)
gif_css_frames=gif_css_frames_
ProcedureReturn
EndProcedure
Procedure SetGIFandCSS_Frame_width_BF(gif_css_frame_width_)
gif_css_frame_width=gif_css_frame_width_
ProcedureReturn 0
EndProcedure
Procedure SetGIFandCSS_Frame_height_BF(gif_css_frame_height_)
gif_css_frame_height=gif_css_frame_height_
ProcedureReturn 0
EndProcedure
Procedure SetCSS_width_BF(css_width_)
css_width=css_width_
ProcedureReturn 0
EndProcedure
Procedure SetCSS_height_BF(css_height_)
css_height=css_height_
ProcedureReturn 0
EndProcedure
Procedure SetFrames_in_a_row_BF(css_frames_in_a_row_)
css_frames_in_a_row=css_frames_in_a_row
EndProcedure
Procedure.s SetFrameDataInString_BF()
Protected i, ii=ArraySize(gif_and_css_delay_array())
Protected result$="#"+RSet(Str(GetGIFandCSS_Frames_BF()), 8, "0")+
"#"+RSet(Str(GetGIFandCSS_frame_width_BF()), 8, "0")+
"#"+RSet(Str(GetGIFandCSS_frame_height_BF()), 8, "0")+
"#"+RSet(Str(GetCSS_width_BF()), 8, "0")+
"#"+RSet(Str(GetCSS_height_BF()), 8, "0")+
"#"+RSet(Str(GetFrames_in_a_row_BF()), 8, "0")+
"$"+RSet(Str(GetGIFandCSS_invisible_color_BF()), 8, "0")
For i=0 To ii
result$+"*"+RSet(Str(gif_and_css_delay_array(i)), 8, "0")
Next i
ProcedureReturn result$
EndProcedure
Procedure.s LoadFrameData_BF(path$)
If GetFrameData_fromSheet_BF(path$)<>1
ProcedureReturn ""
EndIf
ProcedureReturn SetFrameDataInString_BF()
EndProcedure
Procedure Sprite_CSS_sheet_grab_frame_BF(texture_ID,
frames,
frame,
frame_width,
frame_height,
frames_in_a_row=0,
output_width=0,
output_height=0,
texture_clip_x=0,
texture_clip_y=0,
texture_clip_width=0,
texture_clip_height=0)
If frame_width<1 Or frame_height<1 : ProcedureReturn -8 : EndIf
If Not IsImage(texture_ID) : ProcedureReturn -2 : EndIf
If texture_clip_width>frame_width : texture_clip_width=frame_width : EndIf
If texture_clip_height>frame_height : texture_clip_height=frame_height : EndIf
If texture_clip_width<0 : texture_clip_width=0 : EndIf
If texture_clip_height<0 : texture_clip_height=0 : EndIf
If texture_clip_x>frame_width : texture_clip_x=frame_width : EndIf
If texture_clip_y>frame_height : texture_clip_y=frame_height : EndIf
If texture_clip_x<0 : texture_clip_x=0 : EndIf
If texture_clip_y<0 : texture_clip_y=0 : EndIf
If texture_clip_width
texture_clip_width=frame_width-texture_clip_width
EndIf
If texture_clip_height
texture_clip_height=frame_height-texture_clip_height
EndIf
If Not output_width : output_width=frame_width-texture_clip_x-texture_clip_width : EndIf
If Not output_height : output_height=frame_height-texture_clip_y-texture_clip_height : EndIf
If output_width<1 : output_width=frame_width : EndIf
If output_height<1 : output_height=frame_height : EndIf
Protected i, invisible_color_, frame_=1
Protected frame_offset_x, frame_offset_y, temporary_destination_image_ID
Protected sheet_width=ImageWidth(texture_ID)
Protected sheet_height=ImageHeight(texture_ID)
frame+1 ; BF internal, the first frame is frame 1 - PB GIF beginns with frame 0, so we get for compatibility the first frame as frame 0
If frames_in_a_row<1 : frames_in_a_row=sheet_width/frame_width : EndIf
If frame<1 : frame=1 : EndIf
Protected line, column
i=frame%frames_in_a_row
If frame<=frames_in_a_row
line=1
column=frame
Else
If i
line=frame/frames_in_a_row+1
column=i
Else
line=frame/frames_in_a_row
column=frames_in_a_row
EndIf
EndIf
column-1 : line-1
frame_offset_x=column*frame_width+texture_clip_x : frame_offset_y=line*frame_height+texture_clip_y
frame_width=frame_width-texture_clip_x-texture_clip_width
frame_height=frame_height-texture_clip_y-texture_clip_height
If frame_offset_x>-1 And frame_offset_x<sheet_width And frame_offset_y>-1 And frame_offset_y<sheet_height And frame_width>0 And frame_height>0
temporary_destination_image_ID=GrabImage(texture_ID, #PB_Any, frame_offset_x, frame_offset_y, frame_width, frame_height) ; Grab frame from sheet
If Not temporary_destination_image_ID
ProcedureReturn -6
EndIf
Else
ProcedureReturn 0
EndIf
If frame_width<>output_width Or frame_height<>output_height
ResizeImage(temporary_destination_image_ID, output_width, output_height)
EndIf
ProcedureReturn temporary_destination_image_ID
EndProcedure
Procedure Sprite_CSS_sheet_grab_frame_and_free_BF(texture_ID, free_ID,
frames,
frame,
frame_width,
frame_height,
frames_in_a_row=0,
output_width=0,
output_height=0,
texture_clip_x=0,
texture_clip_y=0,
texture_clip_width=0,
texture_clip_height=0)
Protected result=Sprite_CSS_sheet_grab_frame_BF(texture_ID,
frames,
frame,
frame_width,
frame_height,
frames_in_a_row,
output_width,
output_height,
texture_clip_x,
texture_clip_y,
texture_clip_width,
texture_clip_height)
If IsImage(free_ID) : FreeImage(free_ID) : EndIf
ProcedureReturn result
EndProcedure
EndModule
UseModule SheetMaster_BF