update a progbar while a loading file ...

BlitzPlus Forums/BlitzPlus Programming/update a progbar while a loading file ...

Red(Posted 2003) [#1]
Is it possible ?


cyberseth(Posted 2003) [#2]
Program execution is halted during the LoadImage() command. You know this. It's as much the same in Windowed mode as it is in Graphics mode.

There is a way to get around it, if you load in your image byte by byte. You could do this by reading the bytes into a bank and then using BlitzPlus's "Locked Graphics" commands to transfer the bytes over into an image.

Hmmmm I should write a test app for this....


Red(Posted 2003) [#3]
it's not a easy question.


QuietBloke(Posted 2003) [#4]
as I think i mentioned before in another post you could do it the way a lot of apps seem to do it. Just increment the progress bar by a random amount each time slice. Then set it to 100% briefly once the load is finished.
If the bar reaches 98% and the file is still not loaded just leave it at 98% till the load is done then again show 100% breifly.

<grin>


Anthony Flack(Posted 2003) [#5]
Heh, yeah that sounds about right. And here was me thinking you should try to intelligently estimate it...


QuietBloke(Posted 2003) [#6]
hehe.. sometimes you need to approach problems from another angle :)

Seroiusly though.. you didnt mention what kind of file you were talking about.

If its an image then something along the line that cyberseth suggests is probably the way to do it.


RexRhino(Posted 2003) [#7]
QuietBloke:

I always wondered why with so many programs the first 70% took so long, and the rest seemed to zip by! :)


Kevin_(Posted 2003) [#8]
Try measuring the time it takes to load the file nornally from your hard drive.

Take this time and apply it to your progress bar.

e.g. Say it takes 1 second to load in a 1mb file. Divide the time by 100 to get the time it takes to load 1% of the file. Now simply use this new time (1 sec/100) for every 1% of your progress bar. It wont be accurate, but it should be fairly proportional to the size of the file.

Regards


LineOf7s(Posted 2003) [#9]
I get the whole 'add random bits to progress bar' idea, but as Seth mentioned, since program execution halts whilst something loads, how does one manage to do *anything* as far as a progress bar goes.

*rereads*

Unless all the suggestions that follow Seth's post relate to methods that _complement_ his idea of loading into a bank first?


Kevin_(Posted 2003) [#10]
You load in your file first measuring how long it takes to load then update the progress bar afterwards. If the file is smallish in size there will not be any noticable difference.

Regards


Kevin_(Posted 2003) [#11]
Look in the 'graphics' section in the code archives. I did a progress bar function some time ago.

regards


Skitchy(Posted 2003) [#12]
Custom loader (?)


cyberseth(Posted 2003) [#13]
Well you should be able to do this:

1. First of all read the File size, as this is the maximum value of the progress bar.
2. Open the bitmap file, and from whatever data positions, read the width and height.
3. Create a new image of that width and height and LOCK it.
4. bank = LockedPixels(ImageBuffer(img))
5. Then use ReadInt and PokeInt to read data from the file and draw it onto the image, pixel by pixel.
6. While doing that, update the progess bar.


cyberseth(Posted 2003) [#14]
Ok here is a loading/saving progress-bar test I've made.

win = CreateWindow("Image Loading Progress..",100,100,500,400,0,1)
can = CreateCanvas(50,50,ClientWidth(win)-100,ClientHeight(win)-100,win)
SeedRnd MilliSecs()

btn1 = CreateButton("Save Image",50,10,100,30,win)
btn2 = CreateButton("Load Image",160,10,100,30,win)
btn3 = CreateButton("Clear Canvas",270,10,100,30,win)

prog = CreateProgBar(50,ClientHeight(win)-40,ClientWidth(win)-100,30,win,1)


SetBuffer CanvasBuffer(can)
For i=0 To 1000
	Color 0,0,Rand($FFFFFF)
	Rect Rand(ClientWidth(can)-16),Rand(ClientHeight(can)-16),16,16
Next
FlipCanvas can

Repeat
	Select WaitEvent()
	Case $101
		If EventData()=1 Then End
	Case $803
		End
	Case $401
		Select EventSource()
		Case btn1
			f=WriteFile("C:\canvastest.enc")
			If f
				WriteInt f,ClientWidth(can)
				WriteInt f,ClientHeight(can)
				LockBuffer CanvasBuffer(can)
				bnk = LockedPixels() p=LockedPitch()
				For y=0 To ClientHeight(can)-1
					WriteBytes bnk,f,y*p,4*ClientWidth(can)
					UpdateProgBar prog,Float(y)/ClientHeight(can)
				Next
				UnlockBuffer CanvasBuffer(can)
				CloseFile f
			End If
		Case btn2
			f=ReadFile("C:\canvastest.enc")
			If f
				w = ReadInt(f)
				h = ReadInt(f)
				Cls
				LockBuffer
				x=0 y=0 bnk = LockedPixels()  p=LockedPitch()
				While Not Eof(f)
					ReadBytes bnk,f,y*p,4*w
					;PokeInt bnk,x*4+y*p,pxl
					;x=x+1 If x=ClientWidth(can) Then
					x=0 y=y+1 UpdateProgBar prog,Float(y)/Float(h)
				Wend
				UnlockBuffer
				CloseFile f
				FlipCanvas can
			End If
		Case btn3
			ClsColor 0,0,0
			Cls
			FlipCanvas can
		End Select
	End Select
Forever


Currently, it saves pretty much raw colour data, so the file is unrecognisable and quite large! If I knew how to read and write BMP(, PNG and JPEG) or make up my own compression, then it could be a really good function for loading images.

Basically, writing every pixel one by one is far too slow, so instead I got the bank of the buffer and used WriteBytes/ReadBytes to write all the pixels in "chunks" one line at a time. Much faster! Note however that this can only be done in BlitzPlus, not in Blitz3D.