Universal App Emulator

This is a simple project that will change the viewable/clickable area to that of another ios device. Just add this as a dependency and add this global at the top of Main:

DEVICE = "iPhone4"
--DEVICE can be iPhone3, iPhone4, iPhone5, iPad, iPadRetina

Code:


--# Main
-- Universal

-----------------------------------------------------------------
--Add DEVICE = "NAME" as a global to your project. At the top of Main.
--Where NAME can be set to iPhone3,iPhone4,iPhone5,iPad,iPadRetina
------------------------------------------------------------------
DEVICE = "iPhone4"
function setup()
    displayMode(FULLSCREEN)
end

function draw()
    background(0, 0, 0, 255)
    spriteMode(CORNER)
    sprite("SpaceCute:Background",0,0,WIDTH,HEIGHT)
end

function touched(touch)
   print("Touched") 
end
--# BootStrap
-- bootstrap
local o_setup
local o_draw
local o_orientationChanged
local o_Width 
local o_Height
local o_touched
 
------------------------
--Create Bootstrap
-------------------------
debug.sethook(function(e)
    if setup and DEVICE then
        debug.sethook()
        o_setup = setup
        o_draw = draw
        if touched then
        o_touched = touched
        else
            o_touched = function() end
        end
        o_Width = WIDTH
        o_Height = HEIGHT
        if orientationChanged then
        o_orientationChanged = orientationChanged
        else
            o_orientationChanged = function() end
        end
        
        setup = function()
            iDevice.load()
            o_setup()
            iDevice.load()
            end
        draw = function()
            
            o_draw()
            iDevice.draw(o_Width,o_Height)
            end
        orientationChanged = function()
            iDevice.changed()
            o_orientationChanged()
        end
        
        touched = function(touch)
           if touch.x > WIDTH or touch.y > HEIGHT then
            --do nothing
            else
                o_touched(touch)
            end 
            
        end
            
        
    end
end, "r")  
--# iDevice
iDevice = {iPhone3 = {Portrait = vec2(320,480),Landscape = vec2(480,320)},
            iPhone4 = {Portrait=vec2(640,960),Landscape=vec2(960,640)},
            iPhone5 = {Portrait=vec2(640,1136),Landscape=vec2(1136,640)},
            iPad= {Portrait =vec2(768,1024),Landscape=vec2(1024,768)},
            iPadRetina = {Portrait=vec2(1536,2048),Landscape=vec2(2048,1536)}
            }
            
iDevice.load = function()
    local orient
    local device = DEVICE
    if CurrentOrientation == LANDSCAPE_LEFT or CurrentOrientation == LANDSCAPE_RIGHT then
        orient = "Landscape"
    else
        orient = "Portrait"
    end
    
    WIDTH = iDevice[device][orient].x
    HEIGHT = iDevice[device][orient].y
    

end

iDevice.draw = function(w,h)
    pushStyle()
    fill(162, 162, 162, 255)
    noStroke()
    rect(0,HEIGHT,h,h)
    rect(WIDTH,0,h,h)
    popStyle()
end

iDevice.changed = function()
    iDevice.load()
end

Cool. Thanks!

It works! Some good ideas flowing your way, thanks!

@Briarfox - nice one! Doing some refactoring for the iPhone and this perfect.

However, I’m getting an offset when I put something in the main draw loop. Put a Sprite command in there and you see what I mean - it looks like its shifted 50 pixels or so in x and y? Hmmm… Had a look for something obvious in the code and couldn’t see anything wrong.

Any thoughts?

Seems to be working fine for me. If you are trying this inside the app instead of using it as a dependency take note that spriteMode is set to corner not center.

Whoops - so it is… Works a treat once you pointed this out. :wink:

@Briarfox, what am I doing wrong in this.
I’ve got a iPad 3, and I set DEVICE to iPadRetina what it draws is double the size of the screen, everything seems bigger, the iPhone’s too. But it works properly when I set it to iPad.

@Saurabh - I think some of @Briarfox 's presets assumes that Retina displays are x2 the Width and Height (i.e. 2048 x 1536 IPad Landscape)

While this is the case for the ‘actual’ physical number of pixels horizontally and vertically on the device. Codea keeps the WIDTH and HEIGHT the same for Retina and Non-Retina devices, else things would get a bit more complicated when writing code across multiple devices. (i.e. keep it to 1024 x 768 for both).

Similarly, this thinking also applies to the iPhone/IPhone Retina (although remember the screen dimensions are different across IPhone3, 4 and 5).

So for the IPhone 5 you should use: 568 x 320 (rather than the 1136 x 640 Landscape preset)

It all works fine if you bear this in mind. :slight_smile:

Oh okay thanks! and I just tried one more thing and I can’t understand why it’s working out. How am I able to change WIDTH and HEIGHT like in this example. Aren’t those supposed to be constants for the device? Shouldn’t it give some error when I try to change it. What am I missing out here?

function setup()
    WIDTH = 300
    HEIGHT = 300
    print(WIDTH, HEIGHT)
end

function draw()
    background()
    ellipse(WIDTH/2, HEIGHT/2, 40)
end

@Saurabh - WIDTH and HEIGHT are immutable constants defined by Codea - so by definition, you can’t normally change them.

However, @Briarfox does something clever using debug.sethook() and defines these outside of the main setup, which redefines WIDTH and HEIGHT before setup is executed (or so I understand it).

I can’t take credit for the sethook, that was Toffers black magic that we used in Codea Community. I’ve been contemplating adding another setting that shrinks it down to the sceen size of the iphone in inches. This would be usful to see how it looks on a smaller screen and not just at the resolution. btw if anyone has a good idea for this feel free to add to it, just please share it with the community :slight_smile:

I don’t think that WIDTH and HEIGHT are immutable. They are global variables and can be overwritten just as any other global variable.

I’ve certainly done so in my code.

@Andrew_Stacey - With hindsight, I was probably being over-zealous in my use of the word ‘immutable’. :slight_smile: Although, personally I tend not to change these values unless I really have too and use them for reference only.

Much better IMHO is to make copies and use another variable (e.g. my_width = WIDTH) and reference these. Also, depending on the device orientation, WIDTH and HEIGHT ‘could’ change dynamically anyway - overwriting your values (unless you lock the orientation) so you have to be careful I guess.

When you change the orientation the WIDTH/HEIGHT is re written in Codea to reflect the orientation. I handle that in this project. to it does not reset to the ipad defualts.

@andymac3d I change them when I want to fool a piece of code into thinking that it is using the full screen when it isn’t. I have a project where I divide the screen into rectangles and in each rectangle then something is happening. The somethings all think they are using the full screen and I do this by modifying WIDTH and HEIGHT before running the code. As there are several of these regions, I modify WIDTH and HEIGHT on each draw cycle for each one and thus avoid the issue of them being reset by orientation changes.

(I usually use the orientationChanged function anyway to insert my own response to the orientation changing.)