You are not logged in.

Read the FAQ and Knowledge Base before posting.
WiFi not emulated and not supported!!
We won't make a 3DS/2DS emulator.



#1 2018-10-12 17:32:49

windwakr
Member
Registered: 2010-06-10
Posts: 10

freelook Lua script

Putting this here to get people to stop replying in the issue page on github.

DeSmuME now has the ability to implement freelook through Lua scripting. Read zeromus' explanation on that here.

I've created this crappy script to look around with a controller. Honestly have no clue what I'm doing, but it somehow works well enough with most games I've tried. It's not a universal solution, though. There's a bunch of games that it doesn't work that great or at all with.

Some webms showing it off:
https://my.mixtape.moe/tkxvho.webm
https://my.mixtape.moe/ypdlzx.webm
https://my.mixtape.moe/hwtkso.webm

Use with something like an xbox 360 controller, or modify the controls to suit your needs.

Left stick moves left/right and forward/back
Right stick rotates
Triggers move up down(according to where you're looking)

A button resets position, rotation, and pitch offset
B button resets rotation and pitch offset
X sets pitch offset

Dpad Up/Down sets the movement scale
Dpad Left/Right sets the rotation scale

Angle your pitch towards the "horizon" and press X. Then rotate the camera left/right and adjust up/down a little while pressing X until everything's level.

EDIT: This script does some things the wrong way and I don't feel like updating since it's such a mess. You may experience some graphical bugs as a result.

yaw = 0.0;
pitch = 0.0;
pitchoffs = 0.0;
xt = 0.0;
yt = 0.0;
zt = 0.0;
scale = 1.0;
rotscale = 1.0;
cooldown = 0;

function MatrixMult4x4(m1, m2) --Sorta copied/inspired from some lua matrix library
    local mtx = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    for i=1,4 do
        for j=1,4 do
            local num = 0
            for n=1,4 do
                num = num + m1[(i-1)*4+n] * m2[(n-1)*4+j]
            mtx[(i-1)*4+j] = num
            end
        end
    end
    return mtx;
end


function Rotate(angle,x,y,z)
    local s = math.sin(math.rad(angle));
    local c = math.cos(math.rad(angle));
    return {(1-c)*x*x+c, (1-c)*y*x-s*z, (1-c)*z*x+s*y, 0,
            (1-c)*x*y+s*z, (1-c)*y*y+c, (1-c)*z*y-s*x, 0,
            (1-c)*x*z-s*y, (1-c)*y*z+s*x, (1-c)*z*z+c, 0,
            0, 0, 0, 1};
end

function vecrotx(angle, vx, vy, vz)
    return vx,
            vy * math.cos(math.rad(angle)) - vz * math.sin(math.rad(angle)),
            vy * math.sin(math.rad(angle)) + vz * math.cos(math.rad(angle));
end

function MoveForward(l) --sorta based off https://www.gamedev.net/forums/topic/415144-get-forward-right-up-vectors-from-pitch-yaw-roll/
    local fX = math.sin(math.rad(yaw)) * math.cos(math.rad(pitch+pitchoffs));
    local fY = -math.sin(math.rad(pitch+pitchoffs));
    local fZ = -math.cos(math.rad(yaw)) * math.cos(math.rad(pitch+pitchoffs));
    
    fX, fY, fZ = vecrotx(pitchoffs, fX, fY, fZ);
    
    local mag = math.sqrt(fX*fX + fY*fY + fZ*fZ);
    fX = fX / mag; fY = fY / mag; fZ = fZ / mag;
    fX = fX * l; fY = fY * l; fZ = fZ * l;
    xt = xt + fX; yt = yt + fY; zt = zt + fZ;
end

function MoveUp(l)
    local fX = math.sin(math.rad(yaw)) * math.cos(math.rad(pitch+pitchoffs+90));
    local fY = -math.sin(math.rad(pitch+pitchoffs+90));
    local fZ = -math.cos(math.rad(yaw)) * math.cos(math.rad(pitch+pitchoffs+90));
    
    fX, fY, fZ = vecrotx(pitchoffs, fX, fY, fZ);
    
    local mag = math.sqrt(fX*fX + fY*fY + fZ*fZ);
    fX = fX / mag; fY = fY / mag; fZ = fZ / mag;
    fX = fX * l; fY = fY * l; fZ = fZ * l;
    xt = xt + fX; yt = yt + fY; zt = zt + fZ;
end

function MoveRight(l)
    local fX = math.sin(math.rad(yaw+90));
    local fY = 0;
    local fZ = -math.cos(math.rad(yaw+90));
    
    fX, fY, fZ = vecrotx(pitchoffs, fX, fY, fZ);
    
    local mag = math.sqrt(fX*fX + fY*fY + fZ*fZ);
    fX = fX / mag; fY = fY / mag; fZ = fZ / mag;
    fX = fX * l; fY = fY * l; fZ = fZ * l;
    xt = xt + fX; yt = yt + fY; zt = zt + fZ;
end


while true do
    local key = controller.get()
    
    if key.up and cooldown==0 then --Dpad
        cooldown = 10;
        scale = scale + 0.1;
        print("scale: " .. scale);
    end
    if key.down and cooldown==0 then --Dpad
        cooldown = 10;
        scale = scale - 0.1;
        print("scale: " .. scale);
    end
    if key.right and cooldown==0 then --Dpad
        cooldown = 10;
        rotscale = rotscale + 0.1;
        print("rotscale: " .. rotscale);
    end
    if key.left and cooldown==0 then --Dpad
        cooldown = 10;
        rotscale = rotscale - 0.1;
        print("rotscale: " .. rotscale);
    end
    
    if(math.abs(key.x)>0.25) then --Left Stick
        MoveRight(-key.x * scale);
    end
    if(math.abs(key.y)>0.25) then --Left Stick
        MoveForward(key.y * scale);
    end
    if(math.abs(key.z)>0.25) then --Triggers
        MoveUp(-key.z * scale);
    end
    if(math.abs(key.u)>0.25) then --Right Stick
        yaw = (yaw + (key.u * rotscale)) % 360;
    end
    if(math.abs(key.r)>0.25) then --Right Stick
        pitch = (pitch + (key.r * rotscale)) % 360;
    end
    
    if key["1"] then --A button
        yaw = 0.0;
        pitch = 0.0;
        pitchoffs = 0.0;
        xt = 0.0;
        yt = 0.0;
        zt = 0.0;
    end
    if key["2"] then --B button
        yaw = 0.0;
        pitch = 0.0;
        pitchoffs = 0.0;
    end
    if key["3"] then --X button
        pitchoffs = -pitch;
    end
    
    local tmp = Rotate(-yaw, 0.0, math.cos(math.rad(pitchoffs)), math.sin(math.rad(pitchoffs)));
    tmp = MatrixMult4x4(tmp, Rotate(-pitch, 1.0, 0.0, 0.0));
    local translation = {1,0,0,0,0,1,0,0,0,0,1,0,xt,yt,zt,1};
    matAdjustment = MatrixMult4x4(translation, tmp);
    
    emu.set3dtransform(2,matAdjustment);
    
    if cooldown>0 then cooldown=cooldown-1 end
    emu.frameadvance()
end

Last edited by windwakr (2018-11-01 05:34:51)

Offline

#2 2018-10-31 21:02:09

zeromus
Radical Ninja
Registered: 2009-01-05
Posts: 4,833

Re: freelook Lua script

It looks like we need your fork. Which is now AWOL.

Even if it's sloppy, paste your code onto our master and send a PR and I'll make sure it's OK
also I too was missing math.abs.. I have no idea why (don't want to know; I hate lua) but anyway here is a math.abs:

math.abs = function(x)
  if x == nil then return 0 end
  if x<0 then return -x end
  return x;
end

Offline

#3 2018-11-01 01:38:47

windwakr
Member
Registered: 2010-06-10
Posts: 10

Re: freelook Lua script

zeromus wrote:

It looks like we need your fork. Which is now AWOL.

Even if it's sloppy, paste your code onto our master and send a PR and I'll make sure it's OK
also I too was missing math.abs.. I have no idea why (don't want to know; I hate lua) but anyway here is a math.abs:

math.abs = function(x)
  if x == nil then return 0 end
  if x<0 then return -x end
  return x;
end

My fork was just what the queefersutherland guy PR'd, I don't think he made any changes to it. I didn't want to make a PR myself. The script just assumes you have a controller plugged in that's joystick id 0 and has the 3 axes it checks for, and that causes an error when trying to use them if they don't exist. It really should check for the axes before trying to use them.

Last edited by windwakr (2018-11-01 02:00:36)

Offline

Board footer

Powered by FluxBB