User File #41866565069073796

Upload All User Files

#41866565069073796 - Zook Man ZX4 - Casual display script v2 (rearranged)

ZM_CasualDisplayv2.lua
802 downloads
Uploaded 9/20/2017 10:55 AM by FatRatKnight (see all 245)
The only significant difference is the fact I rearranged the elements. The map/Boss HP is toward the top, so as a boss takes damage, the relation of its HP and that health bar should be more apparent by proximity.
It's still just a 40 pixel width display.
--GBA Zook Man ZX4 - Casual Display script
--The display is intended to make sense for real-time viewing.
--For BizHawk
--FatRatKnight

local R4u,R4s= memory.read_u32_le,memory.read_s32_le
local R2u,R2s= memory.read_u16_le,memory.read_s16_le
local R1u,R1s= memory.read_u8    ,memory.read_s8

--Would stick function inside function. BizHawk seems to hate it.
local function BoxB(x,y,i,bc,fc) gui.drawRectangle(x-1+5*i,y+7,3,3,bc,fc) end
--*****************************************************************************
local function BarrierDisplay(x,y)
--*****************************************************************************
--37x16 - Displays barrier information in a pretty fashion.
--Squares for each HP. Changes color and shows a timer if barrier is hit.

  local BarrierHP = R4u(0x16B4,"IWRAM")
  local BarrierTmr= R4u(0x16B8,"IWRAM")

  if BarrierHP >  6 then return end --Panic
  if BarrierTmr> 48 then return end --Panic
  local clr= 0xFF808080
  if BarrierHP > 0 then
    clr= 0xFF00FFFF
    if BarrierTmr > 0 then
      BoxB(x,y,BarrierHP,0xFFFF8000,0xFFFFFF00)
      local X,Y= x+6,y+13
      gui.drawLine( X,Y,X+math.floor((BarrierTmr-1)/2),Y,0xFFFFFF00)
      gui.drawPixel(X,Y,0xFFFFFF00) --Because line doesn't draw coord1==coord2

      BarrierHP= BarrierHP-1
    end
    for i= 1, BarrierHP do
      BoxB(x,y,i,0xFF0080FF,0xFF0080FF)
    end
  end
  gui.pixelText(x+ 4,y   ,"Barrier",clr)
  gui.drawLine( x   ,y   ,x   ,y+15,clr)
  gui.drawLine( x+ 1,y+15,x+35,y+15,clr)
  gui.drawLine( x+36,y   ,x+36,y+15,clr)
end

local WpnClr= {
  0xFFFF2000,  --Flame
  0xFF00FF00,  --Whirlwind
  0xFFC08000,  --Dirt
  0xFF0040FF,  --Bubble
  0xFFC0FFFF,  --Missile
  0xFFFFFF00,  --Star
  0xFFFF00FF,  --Spikeball
  0xFF00FFFF   --Laser
}
local function BoxW(x,y,bc,fc) gui.drawRectangle(x,y,6,24,bc,fc) end
--*****************************************************************************
local function WeaponDisplay(x,y,w)
--*****************************************************************************
--7x25 - For a single weapon. Will display negative ammo as well.

  local HaveWpn= R1u(0x1668+w,"IWRAM") == 1
  if not HaveWpn then  BoxW(x,y,0xFF606060,0); return  end
  local clr= WpnClr[w] or 0xFFFFFFFF
  local WpnAmmo= R1s(0x165C+w,"IWRAM")
  local WpnSelect= R4u(0x15E4,"IWRAM")

  if WpnSelect == w then
    local FlashingClr= 0xFF008000 + 0x00FF7FFF * (math.floor(emu.framecount()/2)%2)
    BoxW(x,y,FlashingClr,0)
    WpnAmmo= R4s(0x163C,"IWRAM")  --There's an edge case where the array fails
  else                            --Specifically, refilling when ammo negative
    BoxW(x,y,clr,0)
  end

  if WpnAmmo > 11 then return end --Panic
  if WpnAmmo <-11 then return end --Panic

  if WpnAmmo < 0 then
    WpnAmmo= -WpnAmmo
    for i= 1, WpnAmmo do
      local X,Y= x+2,y+2*i
      gui.drawPixel(X  ,Y,0xFFFF0000)
      gui.drawPixel(X+2,Y,0xFFFF0000)
    end
  else
    for i= 1, WpnAmmo do
      local X,Y= x+2,y+24-2*i
      gui.drawLine(X,Y,X+2,Y,clr)
    end
  end
end

--*****************************************************************************
local function ChargeDisplay(x,y,h)
--*****************************************************************************
--3xh - Vertical charge display

  local Charge=     R4u(0x1608,"IWRAM")
  local WpnCooldown=R4u(0x15E0,"IWRAM")
  local WpnSelect=  R4u(0x15E4,"IWRAM")
  local ArmUpgrade= R1u(0x1650,"IWRAM") == 1

  local clr= 0xFFC0C0C0
  if     (Charge >= 140) and ArmUpgrade and (WpnSelect == 0) then
    clr= 0xFF20FF20
    gui.drawLine(x+1,y+h,x+1,y  ,clr)
    gui.drawLine(x+2,y+h,x+2,y  ,clr)
  elseif (Charge >   60) and ArmUpgrade and (WpnSelect == 0) then
    clr= 0xFFFFFF00
    gui.drawLine(x+1,y+h,x+1,y  ,clr)
    local dist= math.floor(h/80 * (Charge-60))
    gui.drawLine(x+2,y+h,x+2,y+h-dist,0xFF20FF20)
  elseif (Charge >=  60) then
    clr= 0xFFFFFF00
    gui.drawLine(x+1,y,x+1,y+h,clr)
  elseif (Charge >    0) then
    local dist= math.floor(h/60 * Charge)
    gui.drawLine(x+1,y+h,x+1,y+h-dist,0xFFFFFF00)
  end
  local dist= math.floor(h/18 * math.min(18,WpnCooldown))
  gui.drawLine(x  ,y+h,x  ,y+h-dist,0xFFFF2000)
  gui.drawLine(x  ,y  ,x+2,y  ,clr)
  gui.drawLine(x  ,y+h,x+2,y+h,clr)
end

local PlayerStateText={
[0]= "Normal"  ,
     "Beam in" , -- 1
     "Ldr.Down", -- 2
     "Ldr.Up1" , -- 3
     "Ldr.Up2" , -- 4
     "Ouch!!"  , -- 5
     nil,
     nil,
     "On fire!", -- 8
     "Laser"   , -- 9
     "Pre-boss", --10
     "Beam out", --11
     nil,
     "Show off", --13
     "Capsule"   --14
}

local UpgradeLetter= {[0]="H","A","B","L"}
--*****************************************************************************
local function MiscDisplay(x,y)
--*****************************************************************************
--No idea what I'm putting here. Fun stuff, I suppose.

  local s= R4u(0x15F0,"IWRAM") --Player state
  local clr= 0xFFFFFFFF
  if s == 0 then clr= 0xFFC0C0C0 end
  gui.pixelText(x,y,PlayerStateText[s] or ("St " .. s),clr)
  y= y+7

  s= R1u(0x1EA4,"IWRAM")  --Flame charge timer
  if s > 0 then
    s= math.floor((64-s)/2)
    gui.drawLine( x,y,x+s,y,0xFFFFFF00)
    gui.drawPixel(x,y,      0xFFFFFF00)
  end
  y= y+4

  if R4u(0x1624,"IWRAM") ~= 0 then  --Full invincibility
    gui.pixelText(x,y,"D.Immune",0xFFFFFF00)
    s= R4u(0x1628,"IWRAM") --Invincibility timer
    if s <= 48 then
      s= math.floor(s/2)
      gui.drawLine( x,y+7,x+s,y+7,0xFFFFFF00)
      gui.drawPixel(x,y+7,        0xFFFFFF00)
    end --sanity
  else
    gui.pixelText(x,y,"No mercy",0xFF808080)
  end
  y= y+11

  if R4u(0x1618,"IWRAM") ~= 0 then  --Object invincibility
    gui.pixelText(x,y,"O.Immune",0xFF00FFFF)
  else
    gui.pixelText(x,y,"Wpn Inv.",0xFF808080)
  end
  y= y+11

  gui.pixelText(x   ,y,"HT:" .. R4u(0x1640,"IWRAM"),0xFFFF2000) --Heart Tanks
  gui.pixelText(x+20,y,"AT:" .. R4u(0x1644,"IWRAM"),0xFF0080FF) --Ammo Tanks
  y= y+11

  for i= 0, 3 do
    s= R4u(0x164C+4*i,"IWRAM") ~= 0  --Upgrades
    local clr= 0xFF808080
    if s then clr= 0xFF00FFFF end
    gui.pixelText(x+4+8*i,y,UpgradeLetter[i],clr)
  end

end

local BossModeText= {
[0]={"Not"     ," here,"  ,"  silly!"},
    {"Loading.","Please"  ," wait..."},
    {"Wild"    ," BOSS"   ,"appears!"},
    {"Shoot"   ," him"    ,"already!"},
    {"Opening" ," his big","  mouth."},
    {"Yappin',"," not"    ,"rappin'."},
    {"Uh, I"   ," should" ,"show HP."}, --6, I really should show HP instead!
    {"The 'no" ," damage'","  state."}, --7, another moment to show HP.
    {"How did" ,"you read","this?"   },
    {"Took"    ," long"   ,"enough." }
}

--*****************************************************************************
local function BossDisplay(x,y)
--*****************************************************************************
--Gives a status on the current affairs of the boss.

  local BossState= R4u(0x16F4,"IWRAM")

  if (BossState ~= 6) and (BossState ~= 7) then  --Show silly text
    local t= BossModeText[BossState]
    if t then
      gui.pixelText(x,y   ,t[1],0xFF00FF00)
      gui.pixelText(x,y+ 7,t[2],0xFF00FF00)
      gui.pixelText(x,y+14,t[3],0xFF00FF00)
    else
      gui.pixelText(x,y   ,"I didn't",0xFFC0C0C0) --I thought I covered all
      gui.pixelText(x,y+ 7,"see this",0xFFC0C0C0) --the BossState numbers!
      gui.pixelText(x,y+14,"coming." ,0xFFC0C0C0) --But just in case...
    end

  else  --Boss fighty mode!
    local BossHP = R4u(0x1708,"IWRAM")
    local BossSub= R4s(0x170C,"IWRAM")  --Sub HP units
    local BossInv= R4u(0x16F8,"IWRAM")

    if BossHP > 11 then return end --Panic
    for i= 1, BossHP do
      local X= x + ((i-1)%6)*5
      local Y= y + 14 - 7*math.floor((i-1)/6)
      local v= math.max(0,math.min(5,BossHP*5 + BossSub - i*5))
--      if BossState == 7 then  --Need a better immunity check.
--        gui.pixelText(x,y,"Immune:",0xFFFF8000)
--      else
      gui.pixelText(x,y,"Boss HP:")
--      end
      gui.pixelText(X,Y,v)
    end

    if BossInv > 96 then return end --Panic
    if BossInv >  0 then
      local Y= y+21
      local len= math.floor(BossInv/3)
      gui.drawLine( x,Y,x+len,Y,0xFFFFFF00)
      gui.drawPixel(x,Y,        0xFFFFFF00)
    end
  end
end

local mBossModeText= {
[0]={"Wrong"   ,"function"," bub."   },
    {"Generate"," one"    ,"miniboss"},
    {"Please"  ," hit me" ,"  now!!" },
    {"Strange" ," state." ,"What?"   },
    {"We hit." ,"Wait 60" ," frames."},
    {"Ooh..."  ," pretty" ,"  booms."}
}

--*****************************************************************************
local function MinibossDisplay(x,y)
--*****************************************************************************
--Informs us on what's happening with the miniboss.

  local mBossState= R4u(0x16DC,"IWRAM")

  if (mBossState < 2) or (mBossState > 4) then
    local t= mBossModeText[mBossState]
    if t then
      gui.pixelText(x,y   ,t[1],0xFFFFFF00)
      gui.pixelText(x,y+ 7,t[2],0xFFFFFF00)
      gui.pixelText(x,y+14,t[3],0xFFFFFF00)
    else
      gui.pixelText(x,y   ,"What is" ,0xFFC0C0C0) --Never assume. Always have
      gui.pixelText(x,y+ 7,"this"    ,0xFFC0C0C0) --a fallback in case of
      gui.pixelText(x,y+14,"thing?"  ,0xFFC0C0C0) --unexpected numbers.
    end

  else
    local mBossHP
    local addr= 0x2BA8   --1DE4, objSize=0x74, 30th object, offset+0x2C
    repeat  --My miniboss detector is whoever has more than zero HP...
      mBossHP= R2s(addr)
      if mBossHP > 0 then break end
      addr= addr+0x74
    until addr >= 0x3914  --Panic

    local mBossInv= R4u(0x16E0,"IWRAM")

    gui.pixelText(x,y   ,"Miniboss")
    gui.pixelText(x,y+ 7,mBossHP)

    if mBossInv > 60 then return end --Panic
    if mBossInv >  0 then
      local Y= y+14
      local len= math.floor((60-mBossInv)/2)
      gui.drawLine( x,Y,x+len,Y,0xFFFFFF00)
      gui.drawPixel(x,Y,        0xFFFFFF00)
    end

  end

--  gui.pixelText(x,y,mBossState)
end

local MapClrCycle= {
  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
  0xFFFF0000,0xFFFF0000,0xFF00FF00,0xFF00FF00,0xFF0000FF,
  0xFF0000FF,0xFF00FF00,0xFF00FF00,0xFFFF00FF,0xFFFF00FF,
}

--*****************************************************************************
local function MapDisplay(x,y)
--*****************************************************************************
--38x?? - Intended to be... Really basic. We only have 40 pixels width.
--Segments are as wide as 18 blocks. We ain't got a lot o' room.

--Segment rectangle
  local Width=  R4u(0x153C,"IWRAM")
  local Height= R4u(0x1540,"IWRAM")
  if Width > 18 then return end           --Panic
  if Height > (160 - y)/2 then return end --Panic
  gui.drawRectangle(x,y,Width*2+1,Height*2+1,0xFFC0C0C0,0)

--Player position (1:128 scale ratio)
  local clr= MapClrCycle[emu.framecount()%(#MapClrCycle)+1]
  local X= x + 1 + math.floor((R4s(0x1500,"IWRAM")+R4s(0x1E58,"IWRAM") + 8)/128)
  local Y= y + 1 + math.floor((R4s(0x1504,"IWRAM")+R4s(0x1E5C,"IWRAM") +24)/128)
  gui.drawPixel(X,Y,clr)
end


client.SetGameExtraPadding(0,0,40,0)  --7:4, a touch under 16:9
--Uncomment the below line if you want to see what room exact 16:9 gives.
--client.SetGameExtraPadding(0,0,80,20)
--*****************************************************************************
while true do
--*****************************************************************************
--Our overhead.

  if R4u(0x16F4,"IWRAM") ~= 0 then
    BossDisplay(241,1)

  elseif R4u(0x16DC,"IWRAM") ~= 0 then
    MinibossDisplay(241,1)

  else
    gui.pixelText(241,1,string.format("St%2d:%2d",
      R4u(0x152C,"IWRAM"), --Stage
      R4u(0x1530,"IWRAM")  --Segment
    ))
    MapDisplay(241,8)
  end

  ChargeDisplay(241,33,51)
  for i= 1, 8 do
    local X= 245+((i-1)%4)*9
    local Y= 33 + math.floor((i-1)/4)*27
    WeaponDisplay(X,Y,i)
  end
  BarrierDisplay(242,86)
  MiscDisplay(  241,107)

  emu.frameadvance()
end