

endless_zoom = {
  zoom=  0.0,
  movex= 0.0,
  movey= 0.0,
  light1=100,
  light2=100,
  light3=100,
  light4=100,

  images= {},
  palette= { 
    [0]=  0x0c0404, 0x0e0a0f, 0x10111a, 0x121725, 0x141e30, 0x16243b, 0x182b46, 0x1a3151, 
          0x1c385d, 0x1f3d62, 0x224268, 0x26476d, 0x294c73, 0x2c5178, 0x30567e, 0x335b83, 
          0x376089, 0x39648c, 0x3b6890, 0x3e6c93, 0x407197, 0x42759b, 0x45799e, 0x477da2, 
          0x4a82a6, 0x5d8faf, 0x709cb9, 0x84aac2, 0x97b7cc, 0xaac4d5, 0xbed2df, 0xd1dfe8, 
          0x000000, 0x06040a, 0x0c0914, 0x120d1f, 0x191229, 0x1f1733, 0x251b3e, 0x2b2048, 
          0x322553, 0x372a5b, 0x3c2f64, 0x41346c, 0x473a75, 0x4c3f7e, 0x514486, 0x56498f, 
          0x5c4f98, 0x64589d, 0x6d61a3, 0x756ba8, 0x7e74ae, 0x877db3, 0x8f87b9, 0x9890be, 
          0xa19ac4, 0xa9a3c9, 0xb2accf, 0xbbb6d4, 0xc4bfda, 0xccc8df, 0xd5d2e5, 0xdedbea, 
          0x08141c, 0x09161f, 0x0a1823, 0x0b1a26, 0x0c1d2a, 0x0d1f2e, 0x0e2131, 0x0f2335, 
          0x112639, 0x172d43, 0x1e354d, 0x243d57, 0x2b4561, 0x314d6b, 0x385575, 0x3e5d7f, 
          0x456589, 0x44708f, 0x447b96, 0x43879d, 0x4392a4, 0x429daa, 0x42a9b1, 0x41b4b8, 
          0x41c0bf, 0x53c6c5, 0x65cdcc, 0x78d4d2, 0x8adbd9, 0x9ce1df, 0xafe8e6, 0xc1efec, 
          0x000000, 0x09030a, 0x120715, 0x1b0b20, 0x250f2b, 0x2e1236, 0x371641, 0x401a4c, 
          0x4a1e57, 0x4f215d, 0x542563, 0x5a2869, 0x5f2c6f, 0x642f75, 0x6a337b, 0x6f3681, 
          0x753a88, 0x7f3f8e, 0x8a4495, 0x95499b, 0xa04ea2, 0xab53a9, 0xb658af, 0xc15db6, 
          0xcc63bd, 0xd071c2, 0xd480c8, 0xd88fce, 0xdd9ed4, 0xe1add9, 0xe5bcdf, 0xe9cbe5
  },

}


endless_zoom.load= function(this)
  for i=0,4 do
    local filename= "zoom0"..i..".pod"
    this.images[i]= unpod( fetch(filename) )
  end
  -- nr. 5 is dirt layer
--  this.images[5]:shr(2, true, 0,0, 240*135, 0,0,1)
end

endless_zoom.init= function(this)
end

endless_zoom.deinit= function(this)
  if (this.images ~= nil) then
    for i=0,4 do
      this.images[i]= nil
    end
    this.images= nil
  end
end

endless_zoom.update= function(this)

  local function rgbScale(col, scale)
    local r= flr((col >> 16) & 0xff) * scale >> 8
    local g= flr((col >> 8) & 0xff)  * scale >> 8
    local b= flr(col & 0xff)         * scale >> 8
    if (r>255) r=255
    if (g>255) g=255
    if (b>255) b=255
    return (r<<16) + (g<<8) + b
  end

  local l1= flr(this.light1*2.56)
  local l2= flr(this.light2*2.56)
  local l3= flr(this.light3*2.56)
  local l4= flr(this.light4*2.56)
  local colors= this.palette
  for i=0,15 do
    pal(   i, rgbScale(colors[i*2],   l1), 2)
    pal(16+i, rgbScale(colors[32+i*2],l2), 2)
    pal(32+i, rgbScale(colors[64+i*2],l3), 2)
    pal(48+i, rgbScale(colors[96+i*2],l4), 2)
  end
end

endless_zoom.setparams= function(this, params)
  this.zoom= params[2] or 0
  this.movex= params[3] or 0
  this.movey= params[4] or 0
  this.light1= params[5] or 100
  this.light2= params[6] or 100
  this.light3= params[7] or 100
  this.light4= params[8] or 100
end

endless_zoom.draw= function(this)
  if (this.images==nil) return
  
  local src_w= 480
  local src_h= 270

  local dst_w= 240
  local dst_h= 135

  local zoom= flr((this.zoom % 5.0)*65536.0) 
  local camx= this.movex
  local camy= this.movey
  local imageid= zoom >> 16

  local img= this.images[imageid]
  local t= (zoom & 65535) / 65535.0
  local z1= 1.0 
  local z2= 1.0 / 0.75
  local z= z1 + (z2-z1)*t
  local scale= 1-(1/z) -- 0.0 .. 0.25 

  local src_y= src_h*scale
  local src_x= src_w*scale

  local deltay= (src_h-src_y*2) / dst_h
  local deltax= (src_w-src_x*2) / dst_w

--  camx*=deltax
--  camy*=deltay

  local aoi_w= src_w - flr(src_x)*2
  local aoi_h= src_h - flr(src_y)*2
  local aoi16_1= userdata("i16", aoi_w, 1)
  local aoi16_2= userdata("i16", aoi_w, 1)
  local aoi16_3= userdata("i16", aoi_w, 1)
  local aoi16_4= userdata("i16", aoi_w, 1)
  local aoi16x_1= userdata("i16", dst_h*2, 1)
  local temp= userdata("u8", aoi_w, dst_h)
  local temp2= userdata("u8", aoi_w, dst_h)

  src_x+=0.5 - scale*2
  src_y+=0.5 - scale*2
  src_x += camx
  src_y += camy

  local startx,starty= src_x,src_y
  src_y= flr(src_y*65536.0)
  deltay= flr(deltay*65536.0)
  -- vertical pass
  for y=0,dst_h-1 do
    local iy= src_y >> 16
    local sy= src_y >> 8 & 255

    -- brighntess
    aoi16_1:copy(0, true, 0,0, aoi_w)
    aoi16_2:copy(0, true, 0,0, aoi_w)

    aoi16_1:mutate("u8")
    aoi16_1:copy(img, true, src_x+iy*src_w,0, 1, 1,2, aoi_w)
    aoi16_1:band(31, true, 0,0, 1, 0,2, aoi_w)
    aoi16_1:mutate("i16")

    aoi16_2:mutate("u8")
    aoi16_2:copy(img, true, src_x+(iy+1)*src_w,0, 1, 1,2, aoi_w)
    aoi16_2:band(31, true, 0,0, 1, 0,2, aoi_w)
    aoi16_2:mutate("i16")

    aoi16_1:mul(255-sy,  true, 0,0, aoi_w, 0,0, 1)
    aoi16_2:mul(sy,      true, 0,0, aoi_w, 0,0, 1)
    aoi16_1:add(aoi16_2, true, 0,0, aoi_w, 0,0, 1)

    aoi16_1:mutate("u8")
    temp:copy(aoi16_1, true, 1,y*aoi_w, 1, 2,1, aoi_w)
    aoi16_1:mutate("i16")

    -- color
    if (sy<128) then
      temp2:copy(img, true, src_x+(iy)*src_w,   y*aoi_w, aoi_w, 0,0, 1)
    else
      temp2:copy(img, true, src_x+(iy+1)*src_w, y*aoi_w, aoi_w, 0,0, 1)
    end

    src_y+=deltay
  end

  -- isolate 2bit color tone
  temp2:band(0x60, true, 0,0, aoi_w, 0,aoi_w, dst_h)
--  temp2:shr(1, true, 0,0, aoi_w, 0,aoi_w, dst_h)


  -- horizontal pass
--  src_x+= 0.5 - scale*2
  src_x-=flr(src_x)

  local test1= src_x

  for x=0,dst_w-1 do
    local ix= flr(src_x)
    local sx= flr((src_x % 1.0)*256.0)

    aoi16x_1:copy(0, true, 0,0, dst_h*2)

    aoi16x_1:mutate("u8")
    aoi16x_1:copy(temp, true, ix,  0,   1, aoi_w,4, dst_h)
    aoi16x_1:copy(temp, true, ix+1,2,   1, aoi_w,4, dst_h)
--    aoi16x_1:copy(temp, true, ix+1,2, 1, aoi_w,4, dst_h)
    aoi16x_1:mutate("i16")

    aoi16x_1:mul(255-sx, true, 0,0, 1, 0,2, dst_h)
    aoi16x_1:mul(sx,     true, 0,1, 1, 0,2, dst_h)
    aoi16x_1:add(aoi16x_1, true, 1,0, 1, 2,2, dst_h)
--    aoi16x_1:shr(1,      true, 0,0, 1, 2,2, dst_h)

    aoi16x_1:mutate("u8")
    get_display():copy(aoi16x_1, true, 1,x, 1, 4,dst_w, dst_h)
    get_display():add(1, true, 0,x+(dst_w*(x&1)), 3, 0,dst_w*2, dst_h/2)
--    get_display():add(this.images[5], true, x,x, 1, dst_w,dst_w, dst_h)
    get_display():min(31, true, 0,x, 1, 0,dst_w, dst_h)
--    get_display():copy(24, true, 0,x, 1, 0,dst_w, dst_h)
    get_display():bor(temp2,     true, ix,x, 1, aoi_w, dst_w, dst_h)
    aoi16x_1:mutate("i16")

    src_x+=deltax
  end

  get_display():shr(1, true, 0,0, dst_w, 0,dst_w, dst_h)
end

