Author Topic: Discussion of creating Aspect-Aware Layouts  (Read 27598 times)

Luke_Nukem

  • Sr. Member
  • ****
  • Posts: 135
    • View Profile
    • Blogging about Rust lang
Re: Discussion of creating Aspect-Aware Layouts
« Reply #30 on: June 17, 2015, 09:22:01 PM »
Wow... This. had. me. SWEARING LIKE FUCK!!!

(overlay_vert.width * (overlay_vert.texture_height / overlay_vert.texture_width))

is... NOT EQUAL TO;

(overlay_vert.width * overlay_vert.texture_height / overlay_vert.texture_width)

The first one output only the very first variable. It DOESN'T do the division first. Or anything in parentheses AT ALL!!!!! (But, (x*y) - (g/i) does work).
Just have to rely on operator precedence.. Fuck me.. I was bashing my head over this for a good half hour. I can finally fix that damned layout to display on 4:3 properly, only problem is it reverts back to stretched on 16:9 or 16:10. So i'll just have to hurry up and finish the graphics that will be used for resolution, umm... resolution. Reference!

Why was I writing my code like that? Habit born from making code easier to read at a glance.

edit:
Okay, update. It's nested ( x * ( g * h) ) that is the problem. Which is really fucking stupid.
« Last Edit: June 17, 2015, 09:25:58 PM by Luke_Nukem »

liquid8d

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 442
    • View Profile
Re: Discussion of creating Aspect-Aware Layouts
« Reply #31 on: June 17, 2015, 10:01:45 PM »
I haven't had any operator precedence issues that I can think of. So if everything is in parenthesis it's calculating from left to right? I suck at math, I was smashing my head when converting some of the animate equations... :)

Luke_Nukem

  • Sr. Member
  • ****
  • Posts: 135
    • View Profile
    • Blogging about Rust lang
Re: Discussion of creating Aspect-Aware Layouts
« Reply #32 on: June 17, 2015, 10:15:45 PM »
I haven't had any operator precedence issues that I can think of. So if everything is in parenthesis it's calculating from left to right? I suck at math, I was smashing my head when converting some of the animate equations... :)

try this;
Code: [Select]
local x = 1027/(640/250);
print(x);
It should return 401.17. But instead it spits out 513. So NONE of the calculations I've been doing are any fucking good...

EDIT:
Oh hell no... 640/250 = 2 in SQ, and 2.56 on my calculator. There's the problem, floating point calculation. This is seriously stupid shit.
Solution is to write every single number as a float, so x = 1024.0, y = 666.6
« Last Edit: June 17, 2015, 10:24:45 PM by Luke_Nukem »

liquid8d

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 442
    • View Profile
Re: Discussion of creating Aspect-Aware Layouts
« Reply #33 on: June 17, 2015, 11:01:31 PM »
Doh! I didn't think about the float value, but when you are operating with all integers,  it will return an integer. I think this is typical in languages where you don't declare variables types. I thought that's how it works in python too.

Your previous example:
local x = 1027/(640/250);

That's doing 640/250 which results in 2.56 (but it will get an integer, so you only get 2 ). 1027/2 is 513.2 but you'll only get 513.

You only need one number to be a float on your variable though.. and you can use .tofloat() on it. Try:

Code: [Select]
(overlay_vert.width * overlay_vert.texture_height / overlay_vert.texture_width.tofloat())

I can't remember but it might need to be one of the division numbers to force the division result to be a float, then the multiplication will get you a float.
« Last Edit: June 17, 2015, 11:10:28 PM by liquid8d »

Luke_Nukem

  • Sr. Member
  • ****
  • Posts: 135
    • View Profile
    • Blogging about Rust lang
Re: Discussion of creating Aspect-Aware Layouts
« Reply #34 on: June 18, 2015, 12:00:14 AM »
Na it's not like that in Python. In fact Python is a seriously bloody good, logical language. I might even have a look at converting AM to Python at some point.
Operations of this sort in Python will always give you a float, unless you do something like
Code: [Select]
x = int(1024/(640/26)Which will give you 41.6, truncated to 41. The calculation will always be done in floating point precision.

The way Squirrel does it? Is just bloody stupid. Far too prone to errors like what I just had. And you know what? I couldn't find a damn single bit of information on this problem.

In the end it's just easier to type all my numbers with as 1024.0, 256.0 512.0 etc..

liquid8d

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 442
    • View Profile
Re: Discussion of creating Aspect-Aware Layouts
« Reply #35 on: June 18, 2015, 04:23:30 AM »
I don't have anything against Python... they changed it in 3:

Code: [Select]
Python 2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> print  5 * (2 / 5)
0
>>> print  5.0 * (2 / 5)
0.0
>>> print  5 * (2.0 / 5)
2.0
>>>

Code: [Select]
C:\Python34>python
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print ( 5 * ( 2 / 5 ) )
2.0
>>>

Supposedly, you could use // to force float, but that didnt't work for me in 2.7.6

Luke_Nukem

  • Sr. Member
  • ****
  • Posts: 135
    • View Profile
    • Blogging about Rust lang
Re: Discussion of creating Aspect-Aware Layouts
« Reply #36 on: June 18, 2015, 01:37:05 PM »
I don't know why anyone would want to continue using Python v2.7. It's old, it's clunky, it's also getting support dropped soon. v3.x is fantastic, and has a hell of a lot of very good improvements.

///
I'll see if I can attempt a good description of the framework I've come up with. My proof of concept is working extremely well so far.
///

Each object is instantiated by a class. There are two main types of objects; backgrounds, and "everything else".

When each object is created,  it is created with parameters.
Starting with backgrounds, "ID, art, orientation, aspect".
All others are created with "ID, orientation, aspect, x, y, w, h, reference Res", and a slight variation on that for text.

The "other" objects are linked to the background they were set up with, via sharing the same ID, and also being passed the resolution they were originally set up in. (Now, the reason for passing the res, is so it can be floating point. I'd prefer to just grab the bg.art.texture_width etc, but it's been too unreliable if all numbers end up being ints. Besides, this way allows you to scale the BG up later if everything is retaining the same placements)

All objects are appended to a global object list.

Each "tick", the object list is iterated through, an the objects update function called, but only if it matches the current aspect + orientation, otherwise the obj.update is skipped and set invisible.

So using the module I'm developing to grab the aspect ratio, combined with orientation and auto object linking, I can easily create a layout that caters for the 6 different use cases.
I'll eventually chunk the object setups into separate config files, so that all that needs to be done is just design the layout graphics, stick the object types and coords/dimensions/links in a config, and let my scripts do the work.

This will be good mostly only for simple layouts that use existing stock AM features.

Luke_Nukem

  • Sr. Member
  • ****
  • Posts: 135
    • View Profile
    • Blogging about Rust lang
Re: Discussion of creating Aspect-Aware Layouts
« Reply #37 on: June 18, 2015, 02:06:36 PM »
Quite seriously, the difference between;
Code: [Select]
(art.height * art.texture_width / art.texture_height)and
Code: [Select]
(art.height * (art.texture_width / art.texture_height));is really starting to piss me off.

Lets say that equates to 1080 * (1920 / 1080)
That returns 1920 right?
The form using nested ( ) returns 1080 because (1920/1080) = 1.77.
AND
The operator precedence is fucked! division should always be done before multiplication, so the entire equation is fucked and no good for anything.

The only solution is to use something like;
Code: [Select]
(art.height * (art.texture_width * 1.0 / art.texture_height));This is not acceptable for a language used by computers.

Test code::
Code: [Select]
local x = 1080*(1920/1080);
print("1080*(1920/1080) = "+x+"\n");
x = 1080 * 1920 / 1080;
print("1080 * 1920 / 1080 = "+x+"\n");
x = 1080*(1920*1.0/1080);
print("1080*(1920*1.0/1080 = "+x+"\n");
x = 1920*1.0/1080;
print("1920*1.0/1080 = "+x+"\n");
x = 1920/1080;
print("1920/1080 = "+x+"\n");
x = 1080*x;
print("x*1080 = "+x+"\n");

verion

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 861
    • View Profile
    • new projects
Re: Discussion of creating Aspect-Aware Layouts
« Reply #38 on: June 18, 2015, 04:19:23 PM »
Since I can’t help you guys with coding - I’ve designed simple layout to show how aspect-aware layout could look in practice.

See separate thread:
http://forum.attractmode.org/index.php?topic=277.0

Luke_Nukem

  • Sr. Member
  • ****
  • Posts: 135
    • View Profile
    • Blogging about Rust lang
Re: Discussion of creating Aspect-Aware Layouts
« Reply #39 on: June 18, 2015, 09:14:33 PM »
Here's a quick demo of what I've done. http://youtu.be/KkYFcZ3IygY.

Mind the shitty programmer graphics.  :P

(Videos playing will come soon. As I'm trying to do a universal class for it where there's only one instance of the video, but multiple settings to switch through).

Eventually I will make this one big universal class, to be used with just basic layouts consisting of only the main elements, such as video, screens, listbox, text, and perhaps sounds. Plus a way to load in from a single setting file per aspect+orientation.

liquid8d

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 442
    • View Profile
Re: Discussion of creating Aspect-Aware Layouts
« Reply #40 on: June 18, 2015, 09:57:24 PM »
Code: [Select]
local x = 1080*(1920/1080);
print("1080*(1920/1080) = "+x+"\n");
x = 1080 * 1920 / 1080;
print("1080 * 1920 / 1080 = "+x+"\n");
x = 1080*(1920*1.0/1080);
print("1080*(1920*1.0/1080 = "+x+"\n");
x = 1920*1.0/1080;
print("1920*1.0/1080 = "+x+"\n");
x = 1920/1080;
print("1920/1080 = "+x+"\n");
x = 1080*x;
print("x*1080 = "+x+"\n");

All of those results are correct, based on where your parenthesis are and the fact that using integers with no float will result in an integer value.

Division doesn't happen before multiplication, unless parenthesis alters it - they have the same rank and order is left to right in the equation in PEMDAS.

Code: [Select]
1080*(1920/1080) = 1080     (parenthesis first - and without a float, 1920/1080 = 1 - INTEGER )
1080 * 1920 / 1080 = 1920   (left to right - multiply, then divide - this is correct and different from above because all numbers and result are INTEGER)
1080*(1920*1.0/1080) = 1920  (parens first, left to right - multiply, then divide, then multiply by 1080)
1920*1.0/1080 = 1.77778     ( left to right, multiply (you get a FLOAT), then divide - result is a FLOAT
1920/1080 = 1               ( because dividing two integers results in an INTEGER, unless you force one to a float
x*1080 = 1080               ( just 1080, because the last x was 1 )

When you are dividing, just use .tofloat() on the value you are dividing by and you should get the numbers you expected.
« Last Edit: June 18, 2015, 10:15:44 PM by liquid8d »

Luke_Nukem

  • Sr. Member
  • ****
  • Posts: 135
    • View Profile
    • Blogging about Rust lang
Re: Discussion of creating Aspect-Aware Layouts
« Reply #41 on: June 18, 2015, 10:47:10 PM »
Yes I know the results are correct. But I also believe that when you are working with any computer language, you should be defaulted to floats, unless explicitly specifying integers.
In C/C++ when you do calculations with any variable specified as an int, then you get the results expected, because you declare your types etc.

But when it comes to a typeless language, it should definitely always default to floats, unless specified. The only time I've every really used a form of integer only calculation, is with the modulus operator. And that's in C/C++, Python, and Squirrel (Even Ruby + PHP, I've used all of these languages).

Imagine if a standard calculator defaulted everything to integers only...

Do you know how long it took me to find the "tointeger()" and "tofloat()" functions? Try searching "typecast", or "type cast" in the official reference. You won't get a single result.

And I've *always* gone by PEDMAS, not PEMDAS. But either are equivalent, and produce the same results. Man, this whole default to integer thing seriously messed with my head, trying to figure out why things were going batshit. (See this for why I am frustrated Link

Until Squirrel defaults to floats, it's much safer to write all numbers as xxx.0, that reduces the chances of an error due to a misplaced "tofloat()" to next to nil.
« Last Edit: June 18, 2015, 10:51:27 PM by Luke_Nukem »