Posted by: Petr - 03-06-2023, 07:41 PM - Forum: Petr
- Replies (2)
Let me introduce the PMF2 (that's my own file format) archiver. It is a compression program, the main advantage of which is that files can be compressed and decompressed using only QB64 directly from the source code. It allows you to view packed files and can unpack just one specific file or all files from the archive. It has a built-in feature that makes sure that if the unzipped file already exists on the hard drive, the new unzipped file will have a parenthesis with a number after the name, just like Windows does.
So you get the option to have many files in a single file with the option to extract just one specific one or all files.
Higher operations, such as updating a specific file in the archive, or deleting one file in the archive are not yet supported, I also saved something for another time, that's clear after all
Well, it's probably dawning on someone. So who asked how to add more files to the EXE? I'll add a new thread directly to that in a moment.
rewrite in source code file names for your correct files in array FL for trying!
Code: (Select All)
Type Header ' Header 1
ID As String * 4 ' file format signature PMF2
Files_Total As Long ' how much files container contains
End Type
Type File_List ' Header 2
FileNameLEN As _Unsigned _Byte 'Lenght for file name (example: Untitled.bas = file name lenght = 12)
Compress As _Unsigned _Byte ' Compression. 0 = not used, 1 = used (_INFLATE$)
Offset As Long ' Area in file (offset) where start this file data
BlockSize As Long ' Byte size (how much bytes is used for this file in PMF2 container, size after compression if used)
End Type
Dim Shared PMF2H As Header
ReDim Shared PMF2FL(0) As File_List 'each added file has its own index in this field
Const Show = -1
Const Unpack_All = 0
Dim FL(13) As String ' add here your own files for test it. Array can not have NONE empty records and must start from zero AND ALL RECORDS IN ARRAY FL() MUST BE VALID, or program automaticaly end, because file not exists.
FL(0) = "mrakyM.gif"
FL(1) = "NEW jezis.gif"
FL(2) = "NEW jezisek.gif"
FL(3) = "NEW sane.gif"
FL(4) = "NEW skret.gif"
FL(5) = "NEW sob.gif"
FL(6) = "New sprez.gif"
FL(7) = "NEWest1.gif"
FL(8) = "NEWest2.gif"
FL(9) = "NEWest3.gif"
FL(10) = "NEWest4.gif"
FL(11) = "NEWest5.gif"
FL(12) = "test.mp3"
FL(13) = "mech.ogg" '!all 13 records must contains valid file names! of course your limit for this array size (all files size) is limited just by your RAM size (tested)
' if you add here some 1.3 GB movies, is possible it crash with message OUT OF MEMORY, but.... why add so much? Solution for so big file but exists:
' Break really big file down into smaller units and put it back together as you unpack. But I didn't deal with that here.
Pack_PMF2 "Pmf2test2023", FL() ' create Pmf2test2023.pmf2 file container
UnPack_PMF2 "Pmf2test2023.pmf2", Show ' just read heads from created file Pmf2test and show you, which files are in PMF2 container and compressed file size in archive pmf2
Sleep
UnPack_PMF2 "Pmf2test2023.pmf2", Unpack_All ' Extract all files from PMF2 container (now is set to add parentheses and number if file already exists on harddrive)
UnPack_PMF2 "Pmf2test2023.pmf2", 2 ' Unpack just file nr.2 from archive
'BUT - You can also extract just one file from archive, not all at once: First look, which number is file, you need extract - use UnPack_PMF2 "Pmf2test.pmf2", Show
' look to left to "Pos". Now add this number and use it (for example for file 3 in PMF2) UnPack_PMF2 "Pmf2test.pmf2", 3
' next options be added later, but is released now, for free use for you all, so all can do Christmas theme :)
' So if you can package many files into one file... who asked about how to add multiple files to an EXE file, eh?
End
Sub UnPack_PMF2 (ArchiveName As String, METHOD As _Byte)
'method: -1 = show files in PMF2 file
' 0 = UnPack all files from PMF2 file
' > 0 = Unpack file writed in this position in PMF2 file (-1) - use record number printed in Show mode
If _FileExists(ArchiveName) Then
FF = FreeFile
Open ArchiveName For Binary As FF
Get FF, , PMF2H ' read head 1
If PMF2H.ID = "PMF2" Then
If PMF2H.Files_Total > -1 Then
ReDim As File_List PMF2FL(PMF2H.Files_Total)
Get FF, , PMF2FL() ' read head 2
ReDim As String Names(PMF2H.Files_Total)
For ReadFileNames = 0 To PMF2H.Files_Total ' read files names in file
N$ = Space$(PMF2FL(ReadFileNames).FileNameLEN)
Get FF, , N$
Names(ReadFileNames) = N$
N$ = ""
Next
Select Case METHOD ' This is information block (Show)
Case -1
Print "Pos. File name Compressed Size in PMF2 file [bytes]"
Print "-----------------------------------------------------------------"
For ReadContent = 0 To PMF2H.Files_Total
F_Name$ = Names(ReadContent)
If Len(F_Name$) > 15 Then F_Name$ = Mid$(F_Name$, 1, 12) + "..."
If PMF2FL(ReadContent).Compress Then F_Compress$ = "Yes" Else F_Compress$ = "No"
F_Size& = PMF2FL(ReadContent).BlockSize
ddd = Len(LTrim$(Str$(ReadContent)))
Print LTrim$(Str$(ReadContent + 1)) + "."; Spc(4 - ddd); F_Name$; Spc(18 - Len(F_Name$) + ddd); F_Compress$; Spc(12); F_Size&
If ReadContent Mod 18 = 0 And ReadContent > 0 Then
Print "Press any key for next..."
Sleep
Cls
Print "Pos. File name Compressed Size in PMF2 file [bytes]"
Print "-----------------------------------------------------------------"
End If
Next
Case 0 ' extract it
For UnPack = 0 To PMF2H.Files_Total
If _FileExists(Names(UnPack)) Then 'add automaticaly parentheses and number, if file exists
u = 0
Do Until _FileExists(Names(UnPack)) = 0
Dot = InStr(1, Names(UnPack), ".") - 1
Test$ = Mid$(Names(UnPack), 1, Dot) + "(" + _Trim$(Str$(u) + ")") + Right$(Names(UnPack), PMF2FL(UnPack).FileNameLEN - Dot)
If _FileExists(Test$) = 0 Then Names(UnPack) = Test$
Test$ = ""
u = u + 1
Loop
End If
EF = FreeFile
Open Names(UnPack) For Binary As EF
N$ = Space$(PMF2FL(UnPack).BlockSize)
Get FF, , N$
If PMF2FL(UnPack).Compress Then Rec$ = _Inflate$(N$) Else Rec$ = N$
Put EF, , Rec$
N$ = ""
Rec$ = ""
Close EF
Next UnPack
Case Is > 0 ' unpack just one concrete file
Fi = METHOD - 1
If Fi > UBound(Names) Then Print "Invalid record add as parameter for Unpack_PMF2 SUB!": Sleep 3: End
If _FileExists(Names(Fi)) Then 'add automaticaly parentheses and number, if file exists
u = 0
Do Until _FileExists(Names(Fi)) = 0
Dot = InStr(1, Names(Fi), ".") - 1
Test$ = Mid$(Names(Fi), 1, Dot) + "(" + _Trim$(Str$(u) + ")") + Right$(Names(Fi), PMF2FL(Fi).FileNameLEN - Dot)
If _FileExists(Test$) = 0 Then Names(Fi) = Test$
Test$ = ""
u = u + 1
Loop
End If
EF = FreeFile
Open Names(Fi) For Binary As EF
N$ = Space$(PMF2FL(Fi).BlockSize)
Seek FF, PMF2FL(Fi).Offset
Get FF, , N$
If PMF2FL(Fi).Compress Then Rec$ = _Inflate$(N$) Else Rec$ = N$
Put EF, , Rec$
N$ = ""
Rec$ = ""
Close EF
End Select
Else
Print "Invalid record: Number of files in PMF2 file: "; PMF2H.Files_Total: Sleep 3: End
End If
Else
Print "Invalid PMF2 file format. ": Sleep 3: End
End If
Else
Print "PMF2 file: "; ArchiveName$; " not exists. Can not continue.": Sleep 3: End
End If
End Sub
Sub Pack_PMF2 (ArchiveName As String, FileList() As String) 'Array in input contains file names for add to archive
If LCase$(Right$(ArchiveName, 5)) <> ".pmf2" Then ArchiveName$ = ArchiveName$ + ".pmf2"
PMF2H.ID = "PMF2"
PMF2H.Files_Total = UBound(FileList)
Dim Binaries(PMF2H.Files_Total) As String, Size As Long, C As _Byte
Dim Names(PMF2H.Files_Total) As String, Begin As Long
ReDim PMF2FL(PMF2H.Files_Total) As File_List
FF = FreeFile
For Names_And_Sizes = 0 To PMF2H.Files_Total
If _FileExists(FileList(Names_And_Sizes)) Then
Open FileList(Names_And_Sizes) For Binary As FF
Size = LOF(FF) 'if is copression not used, is block size the same as file size
test$ = Space$(Size)
Get #FF, , test$
Close #FF
Compressed$ = _Deflate$(test$)
If Len(Compressed$) < Size Then Binaries(Names_And_Sizes) = Compressed$: C = 1: Size = Len(Compressed$) Else Binaries(Names_And_Sizes) = test$: C = 0
PMF2FL(Names_And_Sizes).BlockSize = Size 'This Size and previous is different, if compression is used, or not (row 200)
Compressed$ = ""
test$ = ""
PMF2FL(Names_And_Sizes).FileNameLEN = Len(FileList(Names_And_Sizes))
Names(Names_And_Sizes) = FileList(Names_And_Sizes)
PMF2FL(Names_And_Sizes).Compress = C
PMF2FL(Names_And_Sizes).Offset = 0&
Else Print "Error: Can not add file "; FileList(Names_And_Sizes); " to archive, because this file not exists. Operation aborted!": Sleep 3: End
End If
Next
If _FileExists(ArchiveName$) Then Kill ArchiveName$ 'Here is next place for upgrade (dialog File exists: Replace / Rename / Skip / Add files) - now set for rewrite [PMF2 file with the same name!]
Open ArchiveName$ For Binary As FF
Put #FF, , PMF2H
BytePos = Seek(FF)
Put #FF, , PMF2FL()
'insert files names to PMF2
For NameIt = 0 To PMF2H.Files_Total
n$ = Names(NameIt)
Put #FF, , n$
Next
n$ = ""
'insert start offsets and files binary data
For starts = 0 To PMF2H.Files_Total
Begin = Seek(FF)
PMF2FL(starts).Offset = Begin 'record real End Offsets sizes
n$ = Binaries(starts)
Put #FF, , n$
n$ = ""
Next
'upgrade END OFFSETs info for all files in PMF2 in head2
Put #FF, BytePos, PMF2FL() ' Replace Head 2 - now contains also end offsets for files in PMF2
Close #FF
End Sub
Screen _NewImage(710, 710, 32)
_ScreenMove 300, 50
xc = _Width / 2: yc = _Height / 2 - 4
i = 1
lastx = xc: lasty = yc
_PrintString (xc - 4, yc - 8), Mid$(p$, i, 1)
For a = 0 To 23 * _Pi Step .01
x = xc + a * 5 * Cos(a): y = yc + a * 5 * Sin(a)
If _Hypot(x - lastx, y - lasty) >= 20 Then
i = i + 1
' Circle (x - 2, y - 2), 10
_PrintString (x - 4, y - 8), Mid$(p$, i, 1)
lastx = x: lasty = y
End If
Next
Sleep
Wondering if any of you guys have done any coding with Blockchain. As I understand it, there is basically a record which is not written until all records are searched and the new record to be written is deemed valid in someway before it can be written to the chain of records. The two main/key points I take away from this is that VALIDATION before writing the record can be very complex and secondly, the chain must be sequential or there has to be an index table that allows the records to be found in the order in which they were written. So in pseudocode the layout would be something like this:
- compose a validation routine which comprises decisions on what is accurate and acceptable
- Input a record
- Review the present chain
a:for duplication of inputted record
b:for a location in chain where the inputted record will be written
c: subject the inputted record to the validation routine
d: write the inputted record or reject the record.
e: keep an index as to where this inputted record can be found
The blockchain that I'm trying to work on is not for public input but rather something which raises the accuracy of the data in the data base and improves retrieval of any given small piece of data stored. In this regard, what I don't have in the above pseudocode layout is a search routine. It would seem I need 2 search routines, one associated with the Review of the chain before writing a record and one associated with a search of data where No record is intended on being written. A number of years ago I started on a blockchain program but found it was going to be extremely large and abandoned it. So I'm looking at it again but trying to conceptualize a smaller program.
Here is a small program for solving a Sudoku.
Start the program, press "C" to clear the field. Then fill in the sudoku that you can find in newspapers or other media and finally press "S" to solve the sudoku.
You cannot solve it yourself, the computer does all the work for you.
Comments are welcome
Would help me notice a new release sooner if latest release hyperline also had the version or have it displayed somewhere on the home page??? Guessing I missed 3.50 altogther
Just my two cents
BTW, requrie to update is a great touch for peeps like me
Back in December, we held a Christmas banner contest which Bplus won by blowing away the competition with a very nice Christmas themed banner. Now that Spring is right around the corner, it's time for folks to showcase their abilities and to have fun creating a Spring themed banner for our site!
Can Bplus hold on to his accolades and design another winning banner for the Spring season? Will someone else step up and knock him off his throne as our resident designer? The world (of QB64 Phoenix Edition, anyway) is anxiously holding its breath to find out!
Rules are rather simple -- Spend the time between now and the 18th of March (2023) to design and create the best logo and share that you can. A poll will be placed up on Sunday, the 19th of March (Spring-Eve) and folks will have all day to vote for their favorite banner. The one with the most votes on the 20th will have their banner placed prominently for display so everyone can enjoy their work and effort!
Banner Image size should be 1400x256 to match what we currently have, but with that single limitation in mind, the world is your imagination! Have fun and see what you can create that screams "Spring" "Phoenix" "QB64" "Steve is Awesome!!!"...
Posted by: Petr - 03-05-2023, 08:47 PM - Forum: Petr
- No Replies
I use this program quite often myself. This is a program that loads a file in ICO format. Its use is easy:
Icon = LOADICO (filename, imagenumber)
or
Number of Images in file = LOADICO (filename, -1)
or
Display all images in file ICO = LOADICO(filename, 0)
It is intended to be used on a 32-bit screen. It's just a small feature, so I didn't make it a library. Attached are some ICO files to try. ICO files can be freely downloaded. The reason I chose ICO is that a single file can contain multiple sizes of the same icon. This is what you need when creating an application. Not every computer has the same screen size, so - it is necessary to place different sizes of the same icons. Yes, this can be solved internally via _PUTIMAGE with a single size, but this is another option.
Code: (Select All)
'Petr Preclik presents:
'LOADICO function. Use ico files as icons in your programs! Use it as: handle = LOADICON (ico_file_name$, number of frame in this ICO file)
' For list all images in ICO file set second parameter to zero (call it in 32 bit screen)
' For returning how much frames ICO contains, set second parameter as < 0.
Total = LOADICO(file$, -1) 'TOTAL now contains number all frames in ICO file
_PrintMode _KeepBackground
Print "File contains"; Total; "frames."
For all = 1 To Total
i& = LOADICO(file$, all)
If i& < -1 Then _PutImage (X, 100), i&, 0
X = X + _Width(i&)
_FreeImage i&
Next
Function LOADICO& (file As String, fram As Integer)
'file identity header
PD = _Dest
Type File_Head
reserved As Integer '0
id_Type As Integer '1
id_Count As Integer 'number of frames in file
End Type
Type ICO_Head
bWidth As _Unsigned _Byte
bHeight As _Unsigned _Byte
color_count As _Unsigned _Byte '0 = >256 colors
bReserved As _Unsigned _Byte '0
wPlanes As _Unsigned Integer 'number of bit layers
wBitCount As _Unsigned Integer 'bites per pixel
dwBytesInRes As Long 'image lenght included palette
dwImageOffset As Long 'icon begin from file begin (driving record)
End Type
Type Ico_Image
ThisSize As Long '40
width As Long
height As Long
biPlanes As Integer '1
BitCount As Integer 'bites per pixel, tj 1, 4 , 8, 24
Compression As Long '0 = BI_RGB, 1 = BI_RLE8, 2 = BI_RLE4
SizeImage As Long 'image size
XPelsPerMeter As Long '0
YPelsPerMeter As Long '0
nic As Long '0 'nothing :)
taky_nic As Long '0 'also nothing :) i have none informations and none sources - for what is this!
End Type
Type IcIm 'help array (maybe? - this is wroted long time ago... :-/ )
W As Integer
H As Integer
colors As _Unsigned _Byte
BPP As _Unsigned _Byte
L As Long
Offset As Long
WP As _Unsigned Integer
End Type
Dim FH As File_Head, IH As ICO_Head, II As Ico_Image
ch = FreeFile
If _FileExists(file$) Then Open file$ For Binary As #ch Else Print "ICO loader error: file "; file$; " not exist.": Sleep 2: System
Get #ch, , FH
If FH.reserved = 0 And FH.id_Type = 1 Then Else Print "unknown format!": System
frames = FH.id_Count 'frames number (total frames) in file
If fram < 0 Then LOADICO& = frames: Exit Function ' -1 is for returning number frames in file
If fram > frames Then Print "This file contains not so much images. File "; file$; " contains "; frames; "frames. Can not using frame"; fram: Sleep 2: Exit Function
' PRINT "Frames in file: "; frames
ReDim Ico(frames) As IcIm
For al_fr = 1 To frames
Get #ch, , IH
Ico(al_fr).W = IH.bWidth
Ico(al_fr).H = IH.bHeight
Ico(al_fr).colors = IH.color_count '0 = >256 colors
Ico(al_fr).BPP = IH.wBitCount 'bites per pixel
Ico(al_fr).L = IH.dwBytesInRes 'image lenght included palette
Ico(al_fr).Offset = IH.dwImageOffset + 1 'icon record byte start position from file begin
If IH.color_count = 0 Then IHcolor_count = 256 Else IHcolor_count = IH.color_count
Ico(al_fr).WP = IHcolor_count
Next al_fr
'vsechny hlavy ke vsem snimkum jsou nacteny. Tato hlava je ridici pro kazdy snimek.
'all heads for all frames are ready. This is head for every head
If fram = 0 Then vs = 1: ve = frames Else vs = fram: ve = fram
For all = vs To ve
Seek #ch, Ico(all).Offset 'posun na spravnou pozici skip to correct position
If Ico(all).BPP = 32 Then ' nejprve otestuju pritomnost PNG pokud je hloubka 32 bit: 'first testing, if PNG is contained in file, when bites per pixel is 32
current_position = Seek(ch)
Dim start_test As String * 8
' DIM end_test AS STRING * 12
start$ = Chr$(137) + Chr$(80) + Chr$(78) + Chr$(71) + Chr$(13) + Chr$(10) + Chr$(26) + Chr$(10)
Get #ch, , start_test$
If start_test$ = start$ Then
Ico(all).BPP = 32
Ico(all).W = 256
Ico(all).H = 256
icon& = _CopyImage(extract_png&(ch), 32): GoTo ______skip
Else
Seek #ch, current_position
End If
End If
Get #ch, , II ' nactu hlavu obrazku. Tato hlava je navic a nepouziva se, aspon mysim.... ' really i dont know for what is this, just some records
If Ico(all).BPP > 0 And Ico(all).BPP <= 8 Then depth = 256 Else depth = 32
If Ico(all).W = 0 Then Ico(all).W = 256
If Ico(all).H = 0 Then Ico(all).H = 256
Select Case Ico(all).BPP ' za havou bitmapy nasleduje paleta After bitmap header is palette
Case 1
PalLenght = 1
Case 4
PalLenght = 15 'ok pro 4 barvy OK for 4 colors
Case 8
PalLenght = 255
Case 0, 32
GoTo _______noPalete
End Select
ReDim pal As _Unsigned Long 'vypoctem potvrzeno long LONG confirmed :)
For palete = 0 To PalLenght
Get #ch, , pal
_PaletteColor palete, pal, icon&
Next palete
_______noPalete:
Select Case Ico(all).BPP 'podle bitove hloubky probehne vykresleni drawing starts by bit depth
Case 1 ' testovano na jednom jedinem pripade... this is tested just on ONE file
ReDim bwi As String, valuee As _Unsigned _Byte
For draw1 = 1 To Ico(all).W * Ico(all).H
Get #ch, , valuee
bwi = bwi + DECtoBIN$(valuee)
Next
drawX = 0
drawY = Ico(all).H
For DrawXOR = 1 To Ico(all).W * Ico(all).H
If (Mid$(bwi$, DrawXOR, 1)) = "1" Then PSet (drawX, drawY)
drawX = drawX + 1: If drawX >= Ico(all).W And Ico(all).H Mod 4 = 0 Then drawX = 0: drawY = drawY - 1
Next
Case 4 ' pro soubory o jednom snimku naprosto v poradku (neni podpora PNG ale to asi v 16ti barvach nebude potreba)
' for files contins one frame is this all right (is not PNG support in 16 colors, i think this is not need)
Dim R4 As _Unsigned _Byte
binary$ = ""
For READ_XOR_DATA = 1 To (Ico(all).W * Ico(all).H) / 2
Get #ch, , R4
binary$ = binary$ + DECtoBIN$(R4)
Next READ_XOR_DATA
Dim colors4(Len(binary$)) As _Byte
calc_color = 0
For calc_colors = 1 To Len(binary$) Step 4
colors4(calc_color) = BINtoDEC(Mid$(binary$, calc_colors, 4))
calc_color = calc_color + 1
Next calc_colors
binary$ = ""
clc = 0
drawX = -1
drawY = Ico(all).H - 1
For DrawXOR = 0 To Ico(all).W * Ico(all).H
drawX = drawX + 1: If drawX >= Ico(all).W And Ico(all).H Mod 8 = 0 Then drawX = 0: drawY = drawY - 1
If drawX < Ico(all).W Then PSet (drawX, drawY), colors4(clc): clc = clc + 1
Next
'Pak je AND maska (sirka * vyska) / 8 a nakonec data obrazku
'Then is AND mask (widht * height) / 8 and in end are image data
Erase colors4: binary$ = ""
AndMaskLen = (Ico(all).H * Ico(all).W) / 8
For AM = 1 To AndMaskLen
Get #ch, , R4
binary$ = binary$ + DECtoBIN$(R4)
Next AM
clc = 0
For DrawAND = 0 To Ico(all).W * Ico(all).H
drawX = drawX + 1: If drawX >= Ico(all).W And Ico(all).H Mod 8 = 0 Then drawX = 0: drawY = drawY - 1
If drawX <= Ico(all).W And Mid$(binary$, clc, 1) = "1" Then
_Source icon&
cur = Point(drawX, drawY)
PSet (drawX, drawY), 255 And cur: clc = clc + 1
End If
Next
_Source 0
Case 8
ReDim colors8(Ico(all).H * Ico(all).W) As _Unsigned _Byte
For calc_colors = 1 To Ico(all).H * Ico(all).W
Get #ch, , colors8(calc_colors)
Next calc_colors
binary$ = ""
AndMaskLen = (Ico(all).H * Ico(all).W) / 8 'predelavano
ReDim r5 As _Unsigned _Byte
For AM = 1 To AndMaskLen
Get #ch, , r5
binary$ = binary$ + DECtoBIN$(r5)
Next AM
clc = 0
For draw_itY = 1 To Ico(all).H
For draw_itX = 0 To Ico(all).W - 1
clc = clc + 1
_Source icon&
cur = Point(draw_itX + 1, draw_itY)
PSet (draw_itX, Ico(all).H - draw_itY), colors8(clc) ' XOR cur
Next: Next
drawY = Ico(all).H - 1
clc = 0
For DrawAND = 1 To Ico(all).W * Ico(all).H
drawX = drawX + 1: If drawX >= Ico(all).W And Ico(all).H Mod 4 = 0 Then drawX = 0: drawY = drawY - 1
clrr = Point(drawX, drawY)
clc = clc + 1
If Mid$(binary$, clc, 1) = "1" Then PSet (drawX, drawY), 255 And clrr
Next
_Source 0
Case 0, 32 'overeno, v tomto pripade se opravdu ctou 4 byty 'confirmed, in this case are really 4 bytes read
ReDim cache(1 To Ico(all).W, 1 To Ico(all).H) As _Unsigned Long
For draw_itY = 1 To Ico(all).H
For draw_itX = 1 To Ico(all).W
Get #ch, , cache(draw_itX, draw_itY)
Next: Next
For draw_itY = 1 To Ico(all).H
For draw_itX = 1 To Ico(all).W
PSet (draw_itX - 1, Ico(all).H - draw_itY), cache(draw_itX, draw_itY)
Next: Next
Erase cache
End Select
______skip:
_Dest PD
If fram = 0 Then 'function paramter 0 as fram is for view all images in ico file (my loop muss be in 32 bit graphic mode)
'vypis pokud bude paramter nula
If _PixelSize(_Dest) < 4 Then Print "LOADICO parameter is set as 0. This option is for view all frames in ICO and muss be used with 32 bit screen.": Sleep 2: Exit Function
______resetview:
If listed = 0 Then listed = 1: Cls: _PrintString (300, 20), " Image nr. Width Height BPP Color count": row = 40
If _Height - (row + 10) < 256 Then _PrintString (50, row + 100), "Press key for view next...": Sleep: Cls: listed = 0: GoTo ______resetview
_PutImage (50, row), icon&, 0
_FreeImage icon&
row = row + Ico(all).H + 10
info$ = " " + Str$(all) + " " + Str$(Ico(all).W) + " " + Str$(Ico(all).H) + " " + Str$(Ico(all).BPP) + " " + Str$(Ico(all).WP)
_PrintString (350, row - (Ico(all).H + 10 / 2)), info$
Else
If all = fram Then LOADICO& = icon&: _Dest PD: Exit Function Else _FreeImage icon&
End If
Next all
End Function
Function DECtoBIN$ (vstup)
For rj = 7 To 0 Step -1
If vstup And 2 ^ rj Then DECtoBI$ = DECtoBI$ + "1" Else DECtoBI$ = DECtoBI$ + "0"
Next rj
DECtoBIN$ = DECtoBI$
End Function
Function BINtoDEC (b As String)
For Si = 1 To Len(b)
e$ = Mid$(b$, Si, 1)
c = Val(e$) '
Sj = Len(b) - Si
BINtoDE = BINtoDE + (c * 2 ^ Sj)
Next Si
BINtoDEC = BINtoDE
End Function
Function extract_png& (ch) 'Warning. This function can be very easy used for extraction PNG files from all (also binary) files!
'BEEP
start$ = Chr$(137) + Chr$(80) + Chr$(78) + Chr$(71) + Chr$(13) + Chr$(10) + Chr$(26) + Chr$(10) 'PNG start ID string
eend$ = Chr$(0) + Chr$(0) + Chr$(0) + Chr$(0) + Chr$(73) + Chr$(69) + Chr$(78) + Chr$(68) + Chr$(174) + Chr$(66) + Chr$(96) + Chr$(130) 'PNG end ID string
Seek #ch, Seek(ch) - 8
Z = Seek(ch)
Dim scan As String * 12
Do
Get #ch, , scan$
If scan$ = eend$ Then Exit Do
Seek #ch, Seek(ch) - 11
Loop
K = Seek(ch)
png$ = Space$(K - Z)
Seek #ch, Z
Get #ch, , png$
swp = FreeFile
Open "---png_extr_" For Output As #swp
Close #swp: Open "---png_extr_" For Binary As #swp
Put #swp, , png$
Close #swp
extract_png& = _LoadImage("---png_extr_", 32)
Kill "---png_extr_"
png$ = ""
End Function
Posted by: Petr - 03-05-2023, 07:06 PM - Forum: Petr
- Replies (1)
Hey guys.
I found in the depths of the hard disk my older thing, which has only one task - to allow you to use mouse cursors in a way other than the built-in function such as _MOUSESHOW "LINK" and the like. The ANI files have the same format (or very similar), so I included them in the library as well, under the same command.
command:
handle = LOADCURSOR (path\file.cur) or
handle = LOADCURSOR (path\file.ani)
Function to the variable handle returns a positive number of the cursor or animation in the case of ani file.
Then there is the command PUTCURSOR (handle, positionX, positionY) - this command, like the _PUTIMAGE command, places the cursor image on the screen. It is intended for the graphics screen loop when the screen background is refreshed on each cycle. I could, if there was interest, make the modification to a hardware image, then you won't have to monitor the screen refresh, but the _Display command will be necessary.
_Putimage will never work with the handle returned by the LOADCURSOR function!
PUTCURSOR is also a common command and places animations loaded from ANI files in the same way.
Then we have the FREECURSOR command, it releases the loaded images of cursors or animations from memory. Usage: FREECURSOR (handle)
I've gone so far as to allow the decomposition of animation from ANI files into individual frames. For this you need the following 2 functions:
LENCURSOR - works only with ANI files - returns the number of ANI animation frames. Usage:
Frames = LENCURSOR (handle)
And the second function - it will allow you to get a handle from the animation compatible with the _PUTIMAGE command of each frame in the animation. Example for getting the third image in the animation:
Pic3 = DECOMPOSECURSOR (handle, 3)
This is an older program (I had to patch it a lot to get it to work in PE) and I have a feeling that someone on Linux once reported something to me about display issues. If this happens, please go to the cursor.bm file, subroutine PUTCUR, disable all the lines related to the mouse (110, 111, 112), I have a note that this should be the source of the problem at the time.
Finally, I would like to mention the so-called field within a field, I see on the forum that you deal with something like that. I use something like this in this program. So let's break down the cursor.bi file:
TYPE Cursors_internal
StartOffset AS LONG 'use ANI
EndOffset AS LONG
X_reduction AS INTEGER ' CUR X coordinate reduction read from file
Y_reduction AS INTEGER ' CUR Y coordinate reduction read from file
Image AS LONG ' own CUR image is saved here
Flag AS LONG '1 for ANI, 2 for CUR
END TYPE
DIM SHARED ACTIVE_MOUSE_CURSOR ' variable, which memorize new mouse cursor usage. Used in PutCur SUB
REDIM SHARED Internal_Recorded(0) AS Cursors_internal
REDIM SHARED Internal_Recorded_ANIs(0) AS LONG 'frames array
StartOffset.
What is it? That's exactly it. A field within a field. This value indicates the starting index number in the Internal_Recorded_ANIs field. This is because an animation in an ANI file can have many frames. So how to write them in one field? You just add an auxiliary field and that is the Internal_Recorded_ANIs field.
EndOffset
This is the index value of the Internal_Recorded_ANIs field, it indicates the last index value that belongs to that one particular ANI file.
See how easy it is now to add more and more ANI images?
X_reduction AS INTEGER ' CUR X coordinate reduction read from file
Y_reduction AS INTEGER ' CUR Y coordinate reduction read from file
these values are contained in the CUR and ANI files and specify the number of pixels to shift the display so that the mouse points where the image
Image AS LONG 'own CUR image is saved here
exactly as the comment says. When you load a CUR file, you get them as one image. This can be added directly to the main field, it's one record for one item, no problem with that.
Flag AS LONG '1 for ANI, 2 for CUR
this is just a note that is written here by LOADCURSOR, according to which the program knows whether it should take the image from the main or from the auxiliary field
Finally own field
REDIM SHARED Internal_Recorded(0) AS Cursors_internal
As you can see above: You call the file via its handle, which is the index number of the Internal_Recorder field. From this you will immediately know if it is a CUR or ANI file. For ANI, the first two records will tell you about the images that belong to that particular ANI. Next, learn about display corrections. So you have everything you need
BI, BM, ANI and CUR files in attachment (zip format)
Code: (Select All)
'$include:'cursors.bi'
'2023 easyest at first: Program need folders CUR and ANI contains *.cur filer in CUR directory and *.ani files in ANI directory (or rewrite paths)
'Easy - how use it:
'example how load cursor with yellow arrow (in file CUR\3dgarro.cur)
'You need 32 graphic screen for use:
Screen _NewImage(1024, 768, 32)
'Load cursor to memory:
YellowCursor = LOADCURSOR(".\CUR\3dgarro.cur")
'test if load is correct, value must be higher than zero:
If YellowCursor > 0 Then Print "Cursor load correct" Else Print "Cursor load failed": End
'show this cursor as mouse cursor:
Print _Dest
Do Until RB = -1
While _MouseInput: Wend
RB = _MouseButton(2)
Mx = _MouseX
MY = _MouseY
Cls 'reset screen
Print "Press right mouse button for quit", _Dest
PUTCURSOR YellowCursor, Mx, MY
' _Display
_Limit 20
Loop
_AutoDisplay
Print "Now freeing your cursor from memory..."
FREECURSOR YellowCursor
Sleep 3
Print "Loading file mentronom.ani"
M = LOADCURSOR("ANI\metronom.ani")
If M > 0 Then Print "Metronom.ani loaded correctly" Else Print "Loading failed"
Sleep 3
RB = 0
Do Until RB = -1
While _MouseInput: Wend
RB = _MouseButton(2)
Mx = _MouseX
MY = _MouseY
Cls 'reset screen
Print "Press right mouse button for quit"
PUTCURSOR M, Mx, MY
_Display
_Limit 20
Loop
_AutoDisplay
ImgF = LENCURSOR(M)
Print "That is not all. You can split the ANI file into individual images:"
Print "First step for this is - how much frames contains ANI file? Use function LENCURSOR!"
Print "Matronom.ani contains "; ImgF; "frames."
Sleep 3
Print "Ok"
Print "Now use function DecomposeCursor (handle, image number):"
Print "Extract all frames:"
Sleep 2
Cls
For all = 1 To ImgF
Image1 = DECOMPOSECURSOR(M, all)
_PutImage (300 + stpX, 450), Image1
stpX = stpX + _Width(Image1) * 2
_FreeImage Image1
Next
Print "Press any key for continue..."
Sleep
Cls
'continue previous old presentation
ReDim cursorsList(0) As String ' array contains drive path and file names
If WIN Then path$ = _CWD$ + "\cursors" Else path$ = "/cursors"
MakeList path$, "*.*", cursorsList() ' path, mask, array as STRING
Dim Animated_Cursors(UBound(cursorsList)) As Long
' load ANI and CUR files to memory (new - both use the same statements)
For a = 0 To UBound(cursorsList) - 1
Locate 1, 1: Print "Loading "; SHOW_PERCENTS(a, UBound(cursorsList) - 1); "%"
Animated_Cursors(a) = LOADCURSOR(cursorsList(a))
Next
path$ = _CWD$ + "\cur\aero_pen_xl.cur"
k = LOADCURSOR(path$) ' load mouse cursor, which is show on the screen with others cursors as mouse
b = a
x = 50: Y = 0 ' its because it is better to set it with _SETALPHA or _CLEARCOLOR by user, as need.
sb = 20
If UBound(cursorsList) > 48 Then OnScreenShow = 48 Else OnScreenShow = UBound(cursorsList) ' cursor to view to one screen: 40
Cls , _RGB32(25, 55, 100)
Do ' create on screen list for all cursors. Some CUR types have NOT UNVISIBLE BACKGROUND.
Do
If OnScreenShow > UBound(cursorsList) Then OnScreenShow = 48
start = OnScreenShow - 48
If UBound(cursorsList) < 48 Then OnScreenShow = UBound(cursorsList): start = LBound(cursorsList)
For a = start To OnScreenShow - 1
Y = Y + 55
If Y > _Height - 55 Then Y = 55: x = x + 250
If x > _Width Then x = 50: Y = 0
_PrintMode _KeepBackground
Cname$ = Right$(cursorsList(a), LastPos(cursorsList(a), Chr$(92))) + " [" + LTrim$(Str$(a)) + "]" ' _revinstr not exists in time i developed this (or i use older IDE :} )
If Len(Cname$) > 19 Then Cname$ = "..." + Right$(Cname$, 16)
_PrintString (x + 70, Y + 5), Cname$
Line (x, Y)-(x + 48, Y + 48), _RGB32(25, 55, 100), BF
PUTCURSOR Animated_Cursors(a), x, Y
Next
x = 50: Y = 0
PCopy _Display, 1
While _MouseInput: Wend
PUTCURSOR k, _MouseX, _MouseY
_PrintString (650, 730), "Press space for next or ESC for end"
_Display
' _LIMIT 15
PCopy 1, _Display
k& = _KeyDown(32)
kk& = _KeyDown(27)
Loop Until k& Or kk&
If kk& Then Exit Do
OnScreenShow = OnScreenShow + 40
_Delay .2
x = 50: Y = 0
Cls , _RGB32(25, 55, 100)
PCopy _Display, 1
Loop
Screen my&
For free = 1 To UBound(cursorsList) - 2 'index cursorslist - 1 is cursor named "k", You can ask to it with "PRINT k" if k is LOADCURSOR output value.
FREECURSOR free ' delete all cursors from memory, not "k" cursor
Next
FREECURSOR k
_Source my&
_Dest my&
Cls
vv& = _NewImage(50, 50, 256)
_ClearColor 0, vv&
Color _RGB32(0, 0, 0), _RGB32(255, 255, 255)
If WIN Then
HourGlas = LOADCURSOR(_CWD$ + "\cursors\hourglas.ani")
M = LOADCURSOR(_CWD$ + "\cursors\hourgla2.ani") ' loading other cursor with name "m"
Else
HourGlas = LOADCURSOR(cwd$ + "/cursors/hourglas.ani")
M = LOADCURSOR(cwd$ + "/cursors/hourgla2.ani")
End If
If HourGlas < 1 Then Beep 'if is image not saved in memory, then beep (inspired with newimage)
Do
_Dest vv&
Cls , 255
PUTCURSOR HourGlas, 0, 0
_Dest my&
_PutImage (_Width / 2 - 150, _Height / 2 - 150)-(_Width / 2 + 150, _Height / 2 + 150), vv&, my&
While _MouseInput: Wend
PUTCURSOR M, _MouseX, _MouseY
Color _RGB32(255, 128, 99)
_PrintString (650, 730), " Press ESC for end", my&
_Limit 20
_Display
Cls , _RGB32(0, 0, 0)
Loop While _KeyDown(27) <> -1
'$include:'cursors.bm'
Function SHOW_PERCENTS (num, based)
SHOW_PERCENTS = Int(num / (based / 100))
End Function
Môže nám niekto pomôcť.
Mám problém s jedným algoritmom. Neviem to vyriešiť.
Ide o triedenie čísel od najväčšieho po najmenšie.
Predmet - Objekt - Strana - súradnice
- súradnice
- súradnice
- súradnice
- súradnice
- súradnice
Predmet - Objekt - Strana - súradnice
- súradnice
- súradnice
Objekt - Strana - súradnice
- súradnice
- súradnice
- súradnice
- súradnice
- súradnice
Objekt - Strana - súradnice
- súradnice
- súradnice
- súradnice
- súradnice
- súradnice
Predmet - Objekt - Strana - súradnice
- súradnice
- súradnice
Strana - súradnice
- súradnice
- súradnice
Strana - súradnice
- súradnice
- súradnice
Strana - súradnice
- súradnice
- súradnice
Predmet - Objekt - Strana - súradnice
- súradnice
- súradnice
- súradnice
- súradnice
- súradnice
Každý predmet má niekoľko objektov.
Každý objekt má niekoľko strán
Každá strana má niekoľko súradníc.
Čo sa môže zmeniť.
Musím ich vytriediť.
Vk = náhodné číslo
Objekt(1, 1, 1, 0).z = Vk
Objekt(1, 1, 1, 1).x = -Vk
Objekt(1, 1, 1, 1).y = -Vk
Objekt ( 2 , 1 , 2 , 6 )
Predmet - Objekt - Strana - súradnice
Počítal som súradnice a spočítal steny na obejct.
Teraz mám Predmet a Objekt
Skúsil som toto a nefunguje to veľmi dobre:
SwapStran(i, a, b).z = SwapStran(i, a, b).z + Z
SwapObjektov(i, a).z = SwapObjektov(i, a).z + SwapStran(i, a, b).z
--
SwapSubjektov(i).z = SwapSubjektov(i).z + SwapObjektov(i, a).z
toto už nie je možné
pretože súčet rôznych predmetov je príliš veľký a nefunguje to
--
SwapingStran:
Pre i = 1 Do PocetSubjektov
Ak PovolenieSwapObjektov(i) = 1 Potom
Znovu = 0
Pre a = 1 To Subjekt(i).PocetObjektov
Pre b = 1 To Subjekt(i).PocetStran
k = 1: Ak b = Predmet(i).PocetStran Potom k = 0
Ak SwapStran(i, a, b).z > SwapStran(i, a, b + k).z Potom
Swap SwapStran(i, a, b).z, SwapStran(i, a, b + k).z
Znovu = 1
Koniec Ak
Ďalej b
Ďalej a
Ak Znovu = 1, potom prejdite na SwapingStran:
Koniec Ak
Ďalej i
SwapingObjektov:
Pre i = 1 Do PocetSubjektov
Ak PovolenieSwapObjektov(i) = 1 Potom
Znovu = 0: O = 0: Ak i = PocetSubjektov Potom O = 1
Pre a = 1 To Subjekt(i).PocetObjektov
k = 1: Ak a = Subjekt(i).PocetObjektov Potom k = 0
Ak SwapObjektov(i - O, a).z < SwapObjektov(i, a + k).z Potom
Swap SwapObjektov(i - O, a).z, SwapObjektov(i, a + k).z
Znovu = 1
Koniec Ak
Ďalej a
Koniec Ak
Ďalej i
If Znovu = 1 Then GoTo SwapingObjektov
-------------------------------------------------- -------------------------------------
Tu je problém:
Výmena Subjektov:
Znovu = 0: ii = 0: a1 = 1: a = 0
Pre i = 1 Do PocetSubjektov
ii = ii + 1
Ak i + ii >= PocetSubjektov Potom ii = 0: Znovu = 0
Ak PovolenieSwapObjektov(i) = 1 alebo PovolenieSwapObjektov(i + ii) = 1 Potom
Do
a = a + 1
Ak SwapObjektov(i, a).z < SwapObjektov(i + ii, a1).z Potom
Swap SwapObjektov(i, a).z, SwapObjektov(i + ii, a1).z
Znovu = 1
Koniec Ak
Ak a >= Predmet(i).PocetObjektov Potom
a = 0
a1 = a1 + 1
Koniec Ak
Ak a1 >= Subjekt(i + ii).PocetObjektov Then a1 = 1: Exit Do
Slučka, kým znovu = 1
Koniec Ak
Ďalej i
If Znovu = 1 Then GoTo SwapingSubjektov