Author Topic: Pos Positioning Module  (Read 5294 times)

mahuti

  • Administrator
  • Sr. Member
  • *****
  • Posts: 252
    • View Profile
    • Github Repositories
Pos Positioning Module
« on: January 20, 2021, 07:06:48 PM »
https://github.com/mahuti/Pos-Module

The Pos (Layout Scaling) Module module for AttractMode helps position, scale or stretch items to fit a wide variety of screen dimensions using easy-to-reference pixel values. The goal of this module is to make it easier to design a layout using pixels in a layout editor like Photoshop and then scale it dynamically to fit any format, whether it's 16x9, 4x3 or vertical.

Basically you can tell the pos module your original sizes and positioning in Photoshop and the pos module will scale or stretch your content smartly to fit the current screen size. I like to think of this as something like the Preserve_Art module, except for any positioning and scaling. It also handles font scaling without stretching, and does some basic work to handle the differences between font sizes needed on a horizontal monitor vs. a vertical one.

It basically works in place of existing x,y,width,height values. The basics look like this:


Code: [Select]
fe.load_module("pos") // positioning & scaling module

local posData =  {
    base_width = 1440.0, /* the width of my photoshop design */
    base_height = 1080.0, /* the height of my photoshop design */
    layout_width = fe.layout.width,
    layout_height = fe.layout.height,
    scale= config['scale'], /* set to stretch or scale */
    debug = false,
}
local scalepos = Pos(posData)

local boxart = fe.add_artwork("boxart", scalepos .x(100), scalepos .y(100), scalepos .width(500), scalepos .height(500));

The code above will dynamically scale to any size or position. There are also methods to handle alignment against the screen and other objects.

I've been using some version of this code for the last few years to make it simpler for me to design a layout in Photoshop and then build it for AttractMode. Recently I updated a bunch of my layouts to use it while testing it. For detailed example of how it works, you can reference those layouts.

https://github.com/mahuti/Gameboy
https://github.com/mahuti/Gameboy-Color
https://github.com/mahuti/Gameboy-Advance
https://github.com/mahuti/Neo-Geo-Pocket

These were originally designed to fit 4:3 screens, but will now work on 16:9 or vertically, using the same code.

Lots of details are available in the readme. Check it out when you get a chance.

Here's some pics of what it can do.

mahuti

  • Administrator
  • Sr. Member
  • *****
  • Posts: 252
    • View Profile
    • Github Repositories
Re: Pos Positioning Module
« Reply #1 on: January 20, 2021, 07:41:37 PM »
Here' another quick example. I'd set all of the snaps and related screen objects to align based on the position of the neogeo pocket overlay image. I changed the overlay to align to the middle of the screen. This is the code i changed to make that happen. 

Code: [Select]
ngp_overlay.x=scalepos.x(-100,"right",ngp_overlay)

to this code

ngp_overlay.x=scalepos.x(-100,"middle",ngp_overlay)

And everything else shifted position with it.

mahuti

  • Administrator
  • Sr. Member
  • *****
  • Posts: 252
    • View Profile
    • Github Repositories
Re: Pos Positioning Module
« Reply #2 on: January 20, 2021, 07:47:43 PM »
And lastly.... here's a few before pics of the gameboy layout when it was just built for 4:3 and then shown on different sized monitors. You can see the snap image rotation leaves gaps due to the scaling.
« Last Edit: January 20, 2021, 07:49:29 PM by mahuti »

mahuti

  • Administrator
  • Sr. Member
  • *****
  • Posts: 252
    • View Profile
    • Github Repositories
Re: Pos Positioning Module
« Reply #3 on: February 01, 2021, 01:07:23 AM »
I've updated the module to now include a few more methods.

horizontal_space_between(object,object2=null,padding=0)
gets the horizontal space between 2 objects. Useful for cramming something in between them.  This can be used, for instance, to fill a gap between an object and the edge of the screen, or find the space between 2 things

vertical_space_between(object,object2=null,padding=0)
gets the vertical space between 2 objects. Useful for cramming something in between them.

get_object_xy2 (type, object) 
gets the right or bottom x/y value. Sometimes known as x2 or y2

In the screenshot, i used the vertical_space_between method to set the height of the logo to fit between the instruction card and the bottom of the screen with 10 (scaled) pixels of padding above and below
I used the x method to center the wheel against the instruction card
I used the y method to set the TOP of the wheel 20 pixels (scaled) below the BOTTOM of the instructions

Code: [Select]
            wheel.x = pos.x(0,"center",wheel,instructions_bg,"center")
            wheel.y = pos.y(20,"top",wheel, instructions_bg,"bottom") 
            wheel.height = pos.vertical_space_between(instructions_bg,null,10)
« Last Edit: February 01, 2021, 01:39:05 AM by mahuti »

manzarek

  • Sr. Member
  • ****
  • Posts: 147
    • View Profile
    • YouTube
Re: Pos Positioning Module
« Reply #4 on: February 01, 2021, 09:03:51 AM »
I'll take a look at it calmly thanks  :)
Mame Fighting

mahuti

  • Administrator
  • Sr. Member
  • *****
  • Posts: 252
    • View Profile
    • Github Repositories
Re: Pos Positioning Module
« Reply #5 on: February 01, 2021, 11:22:31 AM »
Is there another way to look at code? In any case... it doesn't get much more boring than scaling and positioning.

ReBirFh

  • Jr. Member
  • **
  • Posts: 12
    • View Profile
Re: Pos Positioning Module
« Reply #6 on: February 20, 2021, 10:43:14 AM »
This is great and if it was possible to position elements like an image files like in texts with ".centre" then making fluid layouts would be  super easy.

mahuti

  • Administrator
  • Sr. Member
  • *****
  • Posts: 252
    • View Profile
    • Github Repositories
Re: Pos Positioning Module
« Reply #7 on: February 20, 2021, 02:31:21 PM »
Quote
if it was possible to position elements like an image files like in texts with ".centre" then making fluid layouts would be  super easy.

This does that. This makes relative positioning to both the page and other objects simple.


Code: [Select]
fe.load_module("pos")
local  posData =  {base_width = 1920,  base_height = 1080,  layout_width = fe.layout.width, layout_height = fe.layout.height, scale= "scale" }
local scale = Pos(posData)

local myimage = fe.add_image("image1.png", 0,0, scale.width(500), scale.height(400))
local secondimage = fe.add_image("image2.png", 0,0, scale.width(400), scale.height(300))

myimage.x = scale.x(0,"center") // position left side to center of page
myimage.x = scale.x(0,"center",myimage) // center image on page
myimage.x = scale.x(0,"center",myimage, second_image, "center") // center against the center of other element


myimage.x = scale.x(0,"center", myimage, second_image, "left") // center against the left edge of other element

myimage.x = scale.x(-300,"center", myimage, second_image, "right" ) // center against the right edge of other element, then move 300px to the left of that
myimage.x = scale.x(0,"right",myimage,second_image,"left") // align the right edge of the image to the left edge of the second image

The scaling part of this module is quite useful to me, but its the ability to relatively position against other elements and the page that really makes my life easier. For instance, I often place the snap image and then align everything else on the page against that snap. So if i change the x/y position for that snap for some reason, everything else is repositioned as well.
« Last Edit: February 20, 2021, 02:41:14 PM by mahuti »

ReBirFh

  • Jr. Member
  • **
  • Posts: 12
    • View Profile
Re: Pos Positioning Module
« Reply #8 on: February 21, 2021, 02:54:00 PM »
Now I got it  ;). For some reason I thought it was limited to surfaces.

mahuti

  • Administrator
  • Sr. Member
  • *****
  • Posts: 252
    • View Profile
    • Github Repositories
Re: Pos Positioning Module
« Reply #9 on: February 21, 2021, 04:25:51 PM »
To calculate scaling values... it doesn't need anything but a number. To factor in relative sizes and positions it needs an object with a width,, height, x and y positions... which can be text, image, surface, artwork, etc. At its most basic it is just a number converter. If objects are passed in, it can greatly simplify relative and dynamic sizing and scaling

mahuti

  • Administrator
  • Sr. Member
  • *****
  • Posts: 252
    • View Profile
    • Github Repositories
Re: Pos Positioning Module
« Reply #10 on: February 25, 2021, 07:29:37 PM »
I just added a nearest_neighbor function for relatively scaling bitmap images with their edges intact.

Code: [Select]
local digdug = fe.add_image("sprites.png", 0,0)
scale.nearest_neighbor(digdug,300,"width")