Page 3 of 4

Re: A few more questions

Posted: Thu Nov 22, 2012 8:35 am
by Boolsheet
rude wrote:<rude> There once was an experimental module ... love.native, which allowed you to compile C code 'inside' Lua code.
Now we have LuaJIT anyway.

Re: A few more questions

Posted: Thu Nov 22, 2012 10:26 am
by Santos
Interesting, thanks for the info! :)

Re: A few more questions

Posted: Wed Dec 12, 2012 3:18 pm
by Santos
Here are some more things I've been wondering about.

I'm struggling to think of a use case for love.graphics.checkMode. I'd assume that users would never input fullscreen dimensions directly and would instead choose from a list, and at least on the system which I've tested it, love.graphics.checkMode only returns false in windowed mode if the dimensions are waaay past the resolution of the screen. And then if a user did enter a window size which wasn't supported, it could be caught by love.graphics.setMode returning nil. Is this still a good reason for it existing, or have I missed some other reason?

Also, I have a question about love.graphics.isSupported. From the 0.8.0 changelog...
Added automatic PO2 padding for systems not supporting the OpenGL extension.
...
Added support for the subtract BlendMode on older graphics cards.
Would love.graphics.isSupported("npot", "subtractive") ever return false?

(I was wondering about non-power-of-two sized canvases, but it appears that "npot" only tests images.)

Am I right in thinking that the maximum number of Sources that can play simultaneously is system dependent?

I have a few questions about Files.

Do Files need to be closed?

Unopened Files seem to be able to be read multiple times without "rewinding" with seek, File:eof always returns true, seeking doesn't seem to do anything, and it errors if it's attempted to be written to. Is this all normal stuff? Or is the behaviour undefined?

The output of this was interesting to me...

Code: Select all

function love.load()
	file = love.filesystem.newFile('test.txt')
	file:open('r')

	s, b = file:read()
	print('#s '..#s)
	print(b..' bytes')
	print(s)
	print()

	s, b = file:read()
	print('#s '..#s)
	print(b..' bytes')
	print(s)
	print()

	file:seek(0)
	s, b = file:read()
	print('#s '..#s)
	print(b..' bytes')
	print(s)
	print()

	file:seek(10)
	s, b = file:read()
	print('#s '..#s)
	print(b..' bytes')
	print(s)
end
iiinteresting.png
iiinteresting.png (10.81 KiB) Viewed 3015 times
First read: Everything as expected.
Second: Apparently still 20 characters, but interpreted as Unicode I guess. Also I think this changed a couple of times between runs.
Third: File rewound with file:seek(0), and everything as expected again.
Fourth: After file:seek(10), 20 bytes were apparently still read, and the first 10 characters are repeated.

Is this all expected? If so, why do these things happen?

Re: A few more questions

Posted: Wed Dec 12, 2012 5:16 pm
by Robin
Santos wrote:Second: Apparently still 20 characters, but interpreted as Unicode I guess.
What? No, it's just reading garbage past EOF. It's interpreted however your terminal interprets raw bytes. (So the standard encoding of your terminal.)

Re: A few more questions

Posted: Wed Dec 12, 2012 6:28 pm
by Boolsheet
Santos wrote:I'm struggling to think of a use case for love.graphics.checkMode. [...] And then if a user did enter a window size which wasn't supported, it could be caught by love.graphics.setMode returning nil. Is this still a good reason for it existing, or have I missed some other reason?
love.graphics.setMode isn't perfect. checkMode should stay there just to cover all angles. :P
Santos wrote:Would love.graphics.isSupported("npot", "subtractive") ever return false?
You're asking if one of the two can ever be unsupported and the answer is obviously yes. I think you wanted to ask something different, but I fail to recognize it. I'll just answer it with this: The actual deployed implementations do follow certain patterns; it is usually safe to assume that if some new extension is supported, the older stuff is supported too. However, The OpenGL extension system allows the implementations to support all kinds of configurations and it may prevent problems later if the application checks properly for them.
Santos wrote:(I was wondering about non-power-of-two sized canvases, but it appears that "npot" only tests images.)
Canvases and Images both use OpenGL textures which are restricted to power-of-two widths before OpenGL 2.0 and the appropriate extension. I'm not sure if there actually is an implementation with framebuffers that doesn't do non-power-of-two textures, but I'm sure there's some weird configuration that would make it possible.
Santos wrote:Am I right in thinking that the maximum number of Sources that can play simultaneously is system dependent?
Agh, I thought LÖVE handles it this way, but it actually defaults to a hardcoded 64 sources. Odd, it should not do that...
Santos wrote:[filesystem related stuff...] Is this all expected? If so, why do these things happen?
This is a bug. Someone didn't write File:read carefully enough. It allocates too much memory and doesn't shrink it if not all of it could be filled. Robin is right, it's returning garbage from your memory.

Re: A few more questions

Posted: Thu Dec 13, 2012 2:10 am
by Santos
Thanks for the answers! :)

I did indeed want to ask something different about isSupported, hehe. Want I meant to ask was...

Even if PO2 isn't supported, images are automatically padded, right? So what I meant to ask was, does npot ever need to be checked, assuming it will never be a problem?

And I thought "ah, maybe it should still be checked to see if npot canvases will work!" But it seems like they aren't checked:

Code: Select all

case Graphics::SUPPORT_NPOT:
	if (!Image::hasNpot())
		supported = false;
	break;
And what I meant regarding subtractive blend mode...
Added support for the subtract BlendMode on older graphics cards.
Are there still graphics cards which won't support the subtractive blend mode even now?

And about checkMode, I saw it once used to recheck what was returned getModes, was this necessary?

Re: A few more questions

Posted: Thu Dec 13, 2012 6:21 am
by Boolsheet
Santos wrote:Even if PO2 isn't supported, images are automatically padded, right? So what I meant to ask was, does npot ever need to be checked, assuming it will never be a problem?
Images are only padded if non-power-of-two texture are unsupported. Padded images can show a different behaviour with texture filtering and wrapping.
Santos wrote:And I thought "ah, maybe it should still be checked to see if npot canvases will work!" But it seems like they aren't checked:
That check also counts for Canvases. As I said, they both use OpenGL textures.
Santos wrote:Are there still graphics cards which won't support the subtractive blend mode even now?
Err, a very old Intel chip. And the Windows software renderer of course.
Santos wrote:And about checkMode, I saw it once used to recheck what was returned getModes, was this necessary?
I looked very quickly at the SDL code and it looks like it gets the mode list to check for a specific mode. So, no... I guess.

Re: A few more questions

Posted: Thu Dec 13, 2012 7:28 am
by Santos
Aaaaah. I think I finally get it now. Thanks! :)

Re: A few more questions

Posted: Mon Dec 17, 2012 1:46 pm
by Santos
Hmm, using multiple Sources constructed from a Decoder seems to result in weird things. (Testing with the latest build from love2d.org/builds.)

Code: Select all

function love.load()
	decoder = love.sound.newDecoder('music.ogg')

	source1 = love.audio.newSource(decoder, 'stream')
	source2 = love.audio.newSource(decoder, 'stream')

	source1:play()
end

function love.keypressed(key)
	source2:play()
end
In this example, source1 plays when the program launches, as expected, but then when a key is pressed, it sounds like it's being played at double speed.

When both Sources are static...

Code: Select all

source1 = love.audio.newSource(decoder, 'static')
source2 = love.audio.newSource(decoder, 'static')
... the first Source plays, and pressing a key does nothing.

When the first Source is streaming and the second is static, no sound gets played on launch, but pressing a key plays the other sound.

And when the first Source is static and the second is streaming, the first sound gets played on launch, and the second sound plays over the first sound as expected, however only after the second key press.

Edit: I'm also unsure about the usefulness of using Decoders directly for lovers...

I currently assume there are only two ways of using a Decoder directly that a lover would use:
  • Changing the buffer size of a certain streaming Source to balance the speed/memory tradeoff.
  • Storing the encoded data in memory to create multiple Sources which use the same data, for memory and speed.
(The second point is what I tried to do in the test above, but I assume that this is supposed to work and either I'm doing something wrong or it's a bug.)

If these assumptions are correct (and please let me know if they're not! :)), I propose two changes (that probably aren't possible :D) which I think would make using Decoders directly unecessary, and also make things more elegant.

The solution to the first use for Decoders would be to be able to have a buffer size be the second parameter to newSource. For example...

Code: Select all

love.audio.newSource('music.ogg', 4096)
(Specifying "stream" would be redundant as buffer sizes don't affect static Sources, right?)

The solution to the second use for Decoders would be (this is where it gets kind of crazy/probably impossible to implement) the ability to copy Sources, using a Source argument in newSource, or possibly even as a method.

Code: Select all

source2 = love.audio.newSource(source1)
or
source2 = source1:copy()
Each copy would be played independently, but they would use the same encoded data in memory.

This API change would also be useful for caching static sounds as well. Maybe.

Thoughts? :ultrahappy:

Re: A few more questions

Posted: Mon Dec 17, 2012 2:36 pm
by bartbes
Santos wrote:

Code: Select all

source2 = love.audio.newSource(source1)
or
source2 = source1:copy()
Each copy would be played independently, but they would use the same encoded data in memory.

This API change would also be useful for caching static sounds as well. Maybe.
Which is currently done by using the same SoundData?