Just some Questions and Suggestions

BlitzMax Forums/BlitzMax Beginners Area/Just some Questions and Suggestions

taumel(Posted 2005) [#1]
Hello,

this week i had some time playing around with the beta of bmax on win32.
Well i've run into some issues: might be because i'm a newbie to bmax, might be because it's beta.


*) As it's Beta no complaining about the IDE and some crashes.


a) Documentation (dunno if this is a beta-subject)

Well not every language might be so clear and easy to understand as ruby or python is but often i just only lost time because i simply wasn't able to find the appropriate help in the documentation.

Suggestions for the documentation:

- a search function
- to be complete (every command should have a working example)
- complete linking between related topics/commands
- working cut&paste of the example code with a working back in the navigation
- the 'sample code' examples should cover a wide range of different topics (i found no examples of how to do highscore, how to work with fonts, ...)
- tutorials to different topics would be nice


b) Incbin

Haven't used them since AsmOne on Amiga... :O)
Could it be possible to use them with a variable?

Something like

gfxDir="gfx/"
gfxImg="player.png"

Incbin gfxDir+gfxImg
img_player=LoadImage("incbin::"+gfxDir+gfxImg)

would be much more comfortable than

Incbin "gfx/player.png"
img_player=LoadImage("incbin::gfx/player.png")

as you would not have to define the literals twice.


c) Floats

Global dum#=0
dum:+.222
Print dum

Results to

0.222000003

I would have expected 0.222 here. Where does the rest 0.000000003 come from - incorrect rounding from cpu?


dum:+.222 is allowed
dum:+222. is not

Would be great if both would work.


d) Double Buffering/Trails

How do i make trails with the existing concept?

loop
drawing
flip;'cls
end loop

does make trails, but they flicker as i do have different pictures in the buffers.
Is there a way to do this with blitz without flickering? Or do i have to use openGL-Commands to choose the frontbuffer? If so am i completely in openGL then (as for the timing)?

e) I know that openGL 1.2 is widespread but what would happen if there is no openGL-driver for the video card installed?


Anyway i had quite some fun with it. But it guess it could be more if the final version would be around... ;O)


Greetings,

taumel


Dreamora(Posted 2005) [#2]
e) Look for Mesa3D, a softwareopengl driver very wide spread I think.


d) perhaps your refresh rate is to low? On linux you might need to use -1 for the hertz in the graphics creation to avoid this problem.


John Pickford(Posted 2005) [#3]
Incbin is not a command it's a compiler/linker directive. It doesn't get executed at runtime to using a variable wouldn't work.


ImaginaryHuman(Posted 2005) [#4]
a) just to note, if you click on a piece of example code in the documentation, it will load that example program as a program in the IDE. You can then cut-and-paste it at your leisure, or compile it. etc. Your other points are probably valid. A search would be nice, and definitely more detailed documentation for all commands. For example, ReadData, RestoreData, DefData have no description at all - although I used various forms of Basic in the past, it's been a while and I couldn't remember which of these did what.

b) Regarding incbin, I *think* there are technical reasons why you cannot use variables for the incbin'd files, although that would be nice. The reason is, as soon as you change from a constant (ie give the string of the file as part of the incbin command) to a variable, that would be implying you could change the content of the variable and something else would be incbin'd instead. That doesn't make sense because files are incbin'd at compile-time, not runtime. As the program compiles, the specified file is loaded up and inserted into the executable. This is then a fixed chunk of data in a fixed location in the exe and can't be changed. If you were to use a variable to define what the included file is, at runtime, and changed the content of that variable, a) how would you go about `re-incbin'ing` a different file (same as loading), and no overwrite or waste memory given that the original file size determines its space usage in the exe? If BRL wants to implement adjustable incbin'd files, they would have to come up with a much more flexible system, but then that functionality would be a duplicate of simply loading the files in at run-time anyway. So no point. You can't use variables with incbin, and to refer to it you need to give it a string probably because it uses that as a label to refer to the address of where the data starts. If you used a number (kinda feasible) it wouldn't be so clear. Maybe that's BRL's personal preference. Since Incbin is a compile-time functionality, you don't get any flexibility about what is included. You specify the file, that's it. If they were to try and support redefinable incbin contents, they would have to make an exception to how variables are handled in only that case, which I'm sure would complicate the compiler.

c) That is a bit odd, about the floats, but it probably is to do with the floating point format used. From what I recall, since they use exponents and so on, the numbers that can be represented can only have a certain amount of accuracy. Thus you might see a little extra or less showing up? If you need to, use a `Double` to give you more accuracy. (I don't think this is a bug, is it?)

d) In most modern games these days everything you can see on the screen is completely redrawn every frame. Background preservation algorithms aren't used as much anymore - they prefer to throw CPU/GPU power at it and just refresh everything. So double-buffering is pretty commonplace. Unfortunately that means that what you might've achieved in a single-buffered environment becomes more of the exception than the rule. To get both buffers to look the same and keep the same content, you either have to draw the object to both buffers (which would require you using a bit of OpenGL to redirect drawing to the front buffer). Alternatively you can draw the object to the backbuffer, flip the screen, then either draw that same object to the backbuffer again or copy from the front buffer to the backbuffer. You basically have to draw it twice somehow, either accross 2 frames or by copying part or all of the display. Your easiest bet is probably to draw the object twice - once at the end of rendering the current frame, and again at the start of next frame. That way you don't have to mess with OpenGL.

If there is no OpenGL driver then they won't be able to use your BlitzMax software as it stands. BlitzMax's 2D commands are based on OpenGL and require it to be supported. I have an ibook which has only software OpenGL support, whereas a more modern iMac has hardware OpenGL support. The ibook dates back to at least 1999 so you should be okay in most cases. If there is no support, either state that the user must have OpenGL support, or look for some other graphics rendering library such as Mesa as suggested, or make your own 2D graphics routines.


jhague(Posted 2005) [#5]
Instead of using incbin, I think what you want to do is create a memory bank at runtime, then load a file into it.


taumel(Posted 2005) [#6]
Hi all,

thanks for the answers!

d) perhaps your refresh rate is to low? On linux you might need to use -1 for the hertz in the graphics creation to avoid this problem.



I use a 60Hz LCD-Display here. But regardless of the framerate you have these two different buffers which are drawn and so the ghostframes. Increasing the framerate depends too much on the display of the user and moreover steals processing power. Choosing the frontbuffer anyhow would be the best...

Incbin is not a command it's a compiler/linker directive. It doesn't get executed at runtime to using a variable wouldn't work.


Okay, my fault i meant a constant which i define and got parsed before...something like a makro...i just don't want to type it twice.

a) just to note, if you click on a piece of example code in the documentation, it will load that example program as a program in the IDE...


Hmmm not working for me. For example:

Under "Help/Module Reference/Max2D/Cls" i click on the code then the rest of text (except the code) dissapears. I've only got the code on a white page, but i can't compile it, neither i can cut&paste it. Or am i doing something wrong?

If there is no OpenGL driver then they won't be able to use your BlitzMax software as it stands. ...


Yes sure, i was asking for: What would happen if an EXE-File is started on a computer with no openGL support:

Hmm i suppose that i would get no graphicmodes and so i would have to take the appropriate steps (alternatives, info message)...okay :O)


Greetings,

taumel


ImaginaryHuman(Posted 2005) [#7]
You'd get some kind of error such as not being able to create the graphics mode or something.


taumel(Posted 2005) [#8]
Instead of using incbin, I think what you want to do is create a memory bank at runtime, then load a file into it.


Ok thanks i will look into this.


Greetings,

taumel


Yan(Posted 2005) [#9]
a) just to note, if you click on a piece of example code in the documentation, it will load that example program as a program in the IDE...


Hmmm not working for me. For example:

Under "Help/Module Reference/Max2D/Cls" i click on the code then the rest of text (except the code) disappears. I've only got the code on a white page, but I can't compile it, neither I can cut&paste it. Or am I doing something wrong?

It's a bug in the Win32 IDE. This will work if you got to the help page via the quick help (put the cursor on a command and hit F1 twice).


taumel(Posted 2005) [#10]
Ahhh well okay. Thanks!

Greetings,

taumel


FlameDuck(Posted 2005) [#11]
I would have expected 0.222 here. Where does the rest 0.000000003 come from - incorrect rounding from cpu?
No. It's more a case of innacurate floating point operations. Since floating point numbers are stored in a finite ammount of memory (32 or 64 bit, depending on accuracy) most floating point numbers can never be represented entirely accurately. They are however accurate enough for most non sub-molecular research tasks.

How do i make trails with the existing concept?
Build a list of objects, and store the old "trail" position in it. The "CircleMania" example does this.

Increasing the framerate depends too much on the display of the user and moreover steals processing power.
No.

Choosing the frontbuffer anyhow would be the best...
No.


Warren(Posted 2005) [#12]
Use your words, Mikkel.


FlameDuck(Posted 2005) [#13]
No, it doesn't? :o>


taumel(Posted 2005) [#14]
No. It's more a case of innacurate floating point operations. Since floating point numbers are stored in a finite ammount of memory (32 or 64 bit, depending on accuracy) most floating point numbers can never be represented entirely accurately. They are however accurate enough for most non sub-molecular research tasks.


Well so what's up when i do have more float calculations and then after some calcs do a test like:

if var=.222 then blabla

Better to check for >= and <= then?

Build a list of objects, and store the old "trail" position in it. The "CircleMania" example does this.


Hmmm maybe the word trail was misleading. What i meant was something like a point which is drawing walls of a labyrinth for instance. When there's no swapping buffer than i only would have to draw the new position and woops there is the labyrinth.

I dunno this example. I will try to search for it. But you bring me the idea that i just have to remember the last coordinate which i've drawn to the other screen and redraw it there and the other way around....

Or i could do a double flip if i'm not after fps. With which i mean drawin the same thing twice. That's nonsense well :O)

By the way does anyone know if triple buffering is used anymore (not with blitz) or ist the benefit just to small compared to the memory usage?

No from fps


:O) Yes it does but it depends on the code which has to be run and if it's delta organized or not.

No from frontbuffer


Depends on what has to be drawn. It would be the easiest solution for easy drawings which are done fast. It looks worse for things where you will have to do more things. Depending on the position of the rasterbeam.


Greetings,

taumel


FlameDuck(Posted 2005) [#15]
Better to check for >= and <= then?
Yes. Even better would be to check for errors within a certain margin of error. Is there something specific you need it for?

When there's no swapping buffer than i only would have to draw the new position and woops there is the labyrinth.
True. But you might find that it's often just as fast to just redraw everything, rather than figure out which bits have changed.

By the way does anyone know if triple buffering is used anymore (not with blitz) or ist the benefit just to small compared to the memory usage?
Well it's used sometimes. Most games don't bother anymore tho'.

:O) Yes it does but it depends on the code which has to be run and if it's delta organized or not.
Except in Blitz your game loop always runs at the speed you tell it, regardless of refresh rate.

It would be the easiest solution for easy drawings which are done fast.
And would add needless Y position sorting code to your game loop to ensure that every objects is drawn ahead of the electron beam. The problem is that today, that is not faster than letting the GPU determine the fastest way.

Additionally not all screens use a (raster) scanning electron beam to draw the display (your TFT screen for instance), so you will get some tearing anyway.


taumel(Posted 2005) [#16]
Yes. Even better would be to check for errors within a certain margin of error. Is there something specific you need it for?


No just want to know how to do it right in this case.

Except in Blitz your game loop always runs at the speed you tell it, regardless of refresh rate.


Hmmm...

OK i tell Blitz to run at 60 fps. So in one second Blitz runs my loop 60 times.

Case-1:
I do no complex things or the system is just fast enough. No problem blitz will run at 60 fps.

Case-2:
My loop is more complex so it can't be done in 1/60 of a second. What will blitz do then? Normally everthing will move slower then, except i use deltas so greater offsets will be taken and in the worst case animations won't look soft anymore.

How does blitz achieve the same animation then? Does it use deltas on his own?

I mean keeping the refreshrate at a given value is another thing than showing the same content.

By the way: What happens if the user uses a system with a refreshrate of 80 Hz. Will Blitz change this system to 60Hz then or will it run at 80Hz and use a delta of 60/80?


Greetings,

taumel


Hotcakes(Posted 2005) [#17]
By the way: What happens if the user uses a system with a refreshrate of 80 Hz. Will Blitz change this system to 60Hz then or will it run at 80Hz and use a delta of 60/80?

Blitz takes the hertz number you specify in the Graphics command (if no hertz parameter is specified, it defaults to 60). It tries to open a screenmode with that number for the refresh rate, but if it can't it will open the first mode that is returned from the video card driver's list (usually 60 - hopefully that will be changed to the closest match in the future, rather than just the first returned value). In any case, Blitz continues to run your code internally at the hertz you specified. There is a way to turn this off, it's an OpenGL command which turns off the framewait in Flip. I don't know it off the top of my head.

If you specify 0 for hertz, Blitz uses the default/users desktop refresh rate.


taumel(Posted 2005) [#18]
In any case, Blitz continues to run your code internally at the hertz you specified.


Well i didn't get it. One more example please:

a) I tell Blitz to use 50Hz and get 60Hz.

The users system is running at 60Hz (the returned value from the driver list). So we've got a differnce of 10 frames.
My codeloop will run at 50 times a second but what will be drawn? Are the extra 10 frames drawn with old content then.

50 times code:
loop, loop, loop, loop, loop,NO loop,...
60 times refresh:
draw,draw,draw,draw,draw,draw(this time old content),...

How is the old content spread then?


b) I tell Blitz to use 50Hz and get 40Hz.

A substep-method? This would be like using a physics-engine where you can specify substeps for the physics calculation for more accuracy while not drawing every update.

Example:

- a 50Hz gameloop with 50Hz screenupdates.
- substeps for instance=10 would result into running the physicscode with 500 times a second while drawing it only 50 times.

50 times code:
loop,loop,loop,loop,loop,...
40 times refresh:
draw,draw,draw,draw,NO draw,...

Is it like this? How are the lost updates spread then?

c) Or does blitz internally use deltas for translations,rotations and scaling?

d) And by the way if it's openGL aren't 60Hz also the maximum framerate?


Greetings,

taumel


teamonkey(Posted 2005) [#19]
There is a way to turn this off, it's an OpenGL command which turns off the framewait in Flip. I don't know it off the top of my head.

The command you're thinking of is bglSetSwapInterval but I found that doesn't actually help in this case (see http://www.blitzwiki.org/index.php/BglSetSwapInterval ). If you don't want Blitz's framewaiting, use bglSwapBuffers instead of Flip.

a) I tell Blitz to use 50Hz and get 60Hz.

The users system is running at 60Hz (the returned value from the driver list). So we've got a differnce of 10 frames.
My codeloop will run at 50 times a second but what will be drawn? Are the extra 10 frames drawn with old content then.

The frame will be drawn at 50Hz (every 20ms) but your monitor might be halfway through drawing the previous frame and it will swap to the new frame halfway through. This can sometimes cause a bit of visual distortion called shearing, but it depends on the scene that you're rendering. If the scene changes a lot between frames you're going to notice a bigger distortion.

FWIW, I'd always choose a common refresh rate, like 60Hz, 75Hz or 85Hz. That way you know a sizable chunk of your users will be able to see the game without shearing.


Hotcakes(Posted 2005) [#20]
The users system is running at 60Hz (the returned value from the driver list). So we've got a differnce of 10 frames.
My codeloop will run at 50 times a second but what will be drawn? Are the extra 10 frames drawn with old content then.

Well, yeh, kinda. There won't be anything drawn for 10 of those frames, so they will have the old buffer from the previous frame.

A substep-method? This would be like using a physics-engine where you can specify substeps for the physics calculation for more accuracy while not drawing every update.

Exactly the same but in reverse. Every 10 frames a second you will have one loop of code (including a set of drawing commands presumably) that never get shown on screen, because the screen itself doesn't get updated until after the next loop.

d) And by the way if it's openGL aren't 60Hz also the maximum framerate?

No, but it's probably the minimum.

use bglSwapBuffers instead of Flip.

Oh, I don't understand the differance between those two commands, then. does bglSwapBuffers require some arguments passed to it?

I'd always choose a common refresh rate, like 60Hz, 75Hz or 85Hz.

I'd recommend 75 as a sort of 'safe' average between the two... better yet is to give the user the choice, of course =]


taumel(Posted 2005) [#21]
Hello,

okay thank you both.


Greetings,

taumel