/// Specify a 2d position in the range from 0,0 to
// w,h with w,h being the camera visible area size
// as from @{blitwizard.graphics.camera:getDimensions|
// getDimensions} with consider_zoom set to <b>false</b>.
//
// (So the position you specify is the coordinates a
// @{blitwizard.object:pinToCamera|pinned object} would have on screen
// or the coordinates you get from @{blitwizard.onMouseMove})
//
// The position can also be smaller than 0,0 or larger than the
// actual camera dimensions, in which case you'll get an out-of-screen
// world position as a result.
// @function screenPosTo2dWorldPos
// @tparam number pos_x the X coordinate of the screen position
// @tparam number pos_y the Y coordinate of the screen position
// @tparam number parallax (optional) if you want, specify the @{blitwizard.object:setParallax|parallax} effect strength to get the world position displaced accordingly for an object with that parallax effect strength
// @treturn number X coordinate of the resulting world position
// @treturn number Y coordinate of the resulting world position
int luafuncs_camera_screenPosTo2dWorldPos(lua_State* l) {
    struct luacameralistentry* e = toluacameralistentry(
                                       l, 1, 0, "blitwizard.graphics.camera:screenPosTo2dWorldPos");

    if (lua_type(l, 2) != LUA_TNUMBER) {
        return haveluaerror(l, badargument1, 1,
                            "blitwizard.graphics.camera:screenPosTo2dWorldPos", "number", lua_strtype(l, 2));
    }
    if (lua_type(l, 3) != LUA_TNUMBER) {
        return haveluaerror(l, badargument1, 2,
                            "blitwizard.graphics.camera:screenPosTo2dWorldPos", "number", lua_strtype(l, 3));
    }
    double parallax = 1;
    if (lua_gettop(l) >= 4 && lua_type(l, 4) != LUA_TNIL) {
        if (lua_type(l, 4) != LUA_TNUMBER) {
            return haveluaerror(l, badargument1, 3,
                                "blitwizard.graphics.camera:screenPosTo2dWorldPos", "number", lua_strtype(l, 4));
        }
        if (lua_tonumber(l, 4) <= 0) {
            return haveluaerror(l, badargument2, 3,
                                "blitwizard.graphics.camera:screenPosTo2dWorldPos",
                                "parallax effect strength needs to be greater than zero");
        }
        parallax = lua_tonumber(l, 4);
    }
    double x = lua_tonumber(l, 2);
    double y = lua_tonumber(l, 3);

    // calculate camera top left world position:
    double tx = graphics_getCamera2DCenterX(e->cameraslot);
    double ty = graphics_getCamera2DCenterY(e->cameraslot);
    double zoomscale =
        (UNIT_TO_PIXELS * graphics_getCamera2DZoom(e->cameraslot))
        / (double)UNIT_TO_PIXELS_DEFAULT;
    double cameraWidth = graphics_getCameraWidth(e->cameraslot)
                         / (double)UNIT_TO_PIXELS;
    double cameraHeight = graphics_getCameraHeight(e->cameraslot)
                          / (double)UNIT_TO_PIXELS;
    tx -= (cameraWidth / zoomscale) * 0.5f;
    ty -= (cameraHeight / zoomscale) * 0.5f;

    // apply parallax effect as desired with screen center as parallax center:
    x -= cameraWidth / 2;
    y -= cameraHeight / 2;
    x /= parallax;
    y /= parallax;
    x += cameraWidth / 2;
    y += cameraHeight / 2;

    // the onscreen coordinates need to be translated into "zoomed" space:
    x /= graphics_getCamera2DZoom(e->cameraslot);
    y /= graphics_getCamera2DZoom(e->cameraslot);

    lua_pushnumber(l, tx + x);
    lua_pushnumber(l, ty + y);
    return 2;
}
Example #2
0
void graphicsrender_draw(void) {
    graphicssdlrender_startFrame();

    graphics2dsprites_lockListOrTreeAccess();
    // render world sprites:
    double w = graphics_getCameraWidth(0);
    double h = graphics_getCameraHeight(0);
    double z = graphics_getCamera2DZoom(0);
    double cwidth = (w/UNIT_TO_PIXELS) * z;
    double cheight = (w/UNIT_TO_PIXELS) * z;
    double ctopleftx = graphics_getCamera2DCenterX(0) - cwidth/2;
    double ctoplefty = graphics_getCamera2DCenterY(0) - cheight/2;
    graphics2dspritestree_doForAllSpritesSortedBottomToTop(
        ctopleftx, ctoplefty, cwidth, cheight,
        &graphicssdlrender_spriteCallback, NULL);
    // render camera-pinned sprites:
    graphics2dspriteslist_doForAllSpritesBottomToTop(
        &graphicssdlrender_spriteCallback, NULL);
    graphics2dsprites_releaseListOrTreeAccess();

    graphicssdlrender_completeFrame();
}