-- Majora's Mask (U): Camera Control Script
-- by Jimmie1717
-- BizHawk 1.11.8.2
-- Controls:
-- Home: Toggle Camera Control.
-- This also hides the game HUD and stops in-game time.
--
-- Page Up/Down: Adjust the Camera's Zoom.
--
-- Arrow Keys: Move the Camera's Position on the X and Z Axis.
-- Shift + Arrow Keys: Move the Camera's Position on the X and Y Axis.
-- This also moves the Camera's Target. (so the camera rotation doesn't change)
--
-- Ctrl + Arrow Keys: Move the Camera's Target on the X and Z Axis.
-- Ctrl + Shift + Arrow Keys: Move the Camera's Target on the X and Y Axis.
-- This will change the Camera's Rotation and distance of what it's looking at.
console.clear();
gui.defaultTextBackground(0x00000000);
-- Global
readWord = memory.read_u16_be;
readDWord = memory.read_u32_be;
readFloat = memory.readfloat;
writeWord = memory.write_u16_be;
writeDWord = memory.write_u32_be;
writeFloat = memory.writefloat;
-- Addresses
local time_speed_area = 0x382502;
local hud_tranparency = {
[0] = 0x3FD76E,
[1] = 0x3FD770,
[2] = 0x3FD772,
[3] = 0x3FD774,
[4] = 0x3FD776,
[5] = 0x3FD778,
[6] = 0x3FD77A
};
local camera = {
mode = 0x3E6E82,
target = {
x = 0x3E6D90,
y = 0x3E6D94,
z = 0x3E6D98,
},
position = {
x = 0x3E6D9C,
y = 0x3E6DA0,
z = 0x3E6DA4,
},
zoom = 0x3E6E3C
};
local camera_data = {
mode = nil,
target = {
x = nil,
y = nil,
z = nil,
},
position = {
x = nil,
y = nil,
z = nil,
},
zoom = nil
};
local cameraEdit = false;
local isPressed = false;
-- Anchor and Tranparency for Text Display
local x = 0;
local y = 375;
local transparency = 0xFF000000;
-- Draw a String.
function drawString(x, y, text, color)
gui.drawText(x + 1, y + 1, string.format("%s", text), transparency + 0x000000);
gui.drawText(x, y, string.format("%s", text), transparency + color);
end
-- Draw a String formatted like a value.
function drawStringValue(x, y, value, color)
gui.drawText(x + 1, y + 1, string.format("% 8s", value), transparency + 0x000000);
gui.drawText(x, y, string.format("% 8s", value), transparency + color);
end
-- Draw an Integer formatted like a value.
function drawIntegerValue(x, y, value, color)
gui.drawText(x + 1, y + 1, string.format("% 8d", value), transparency + 0x000000);
gui.drawText(x, y, string.format("% 8d", value), transparency + color);
end
-- Draw a Float formatted like a value.
function drawFloatValue(x, y, value, color)
gui.drawText(x + 1, y + 1, string.format("% 8.1f", value), transparency + 0x000000);
gui.drawText(x, y, string.format("% 8.1f", value), transparency + color);
end
-- Draw Byte from supplied address.
function drawByte(x, y, address, color)
gui.drawText(x + 1, y + 1, string.format("% 8d", readByte(address)), transparency + 0x000000);
gui.drawText(x, y, string.format("% 8d", readByte(address)), transparency + color);
end
-- Draw Word from supplied address.
function drawWord(x, y, address, color)
gui.drawText(x + 1, y + 1, string.format("% 8d", readWord(address)), transparency + 0x000000);
gui.drawText(x, y, string.format("% 8d", readWord(address)), transparency + color);
end
-- Draw Double Word from supplied address.
function drawDWord(x, y, address, color)
gui.drawText(x + 1, y + 1, string.format("% 8d", readDWord(address)), transparency + 0x000000);
gui.drawText(x, y, string.format("% 8d", readDWord(address)), transparency + color);
end
-- Draw Float from supplied address.
function drawFloat(x, y, address, color)
gui.drawText(x + 1, y + 1, string.format("% 8.1f", readFloat(address, true)), transparency + 0x000000);
gui.drawText(x, y, string.format("% 8.1f", readFloat(address, true)), transparency + color);
end
-- Draw Byte from supplied address in hexadecimal.
function drawHexByte(x, y, address, color)
gui.drawText(x + 46, y + 1, string.format("%02s", bizstring.hex(readByte(address))), transparency + 0x000000);
gui.drawText(x + 45, y, string.format("%02s", bizstring.hex(readByte(address))), transparency + color);
end
-- Draw Word from supplied address in hexadecimal.
function drawHexWord(x, y, address, color)
gui.drawText(x + 31, y + 1, string.format("%04s", bizstring.hex(readWord(address))), transparency + 0x000000);
gui.drawText(x + 30, y, string.format("%04s", bizstring.hex(readWord(address))), transparency + color);
end
-- Draw Double Word from supplied address in hexadecimal.
function drawHexDWord(x, y, address, color)
gui.drawText(x + 1, y + 1, string.format("%08s", bizstring.hex(readDWord(address))), transparency + 0x000000);
gui.drawText(x, y, string.format("%08s", bizstring.hex(readDWord(address))), transparency + color);
end
-- Text Display
function textDisplay()
drawString(x, y - 18, "Zoom:", 0xFFFFFF);
drawFloat(x + 100, y - 18, camera.zoom, 0x80FFFF);
---
drawString(x, y, "Position:", 0xFFFFFF);
drawString(x, y + 12, " X:", 0xFFFFFF);
drawFloat(x + 100, y + 12, camera.position.x, 0x80FFFF);
drawString(x, y + 24, " Y:", 0xFFFFFF);
drawFloat(x + 100, y + 24, camera.position.y, 0xFF80FF);
drawString(x, y + 36, " Z:", 0xFFFFFF);
drawFloat(x + 100, y + 36, camera.position.z, 0xFFFF80);
---
drawString(x, y + 54, "Target:", 0xFFFFFF);
drawString(x, y + 66, " X:", 0xFFFFFF);
drawFloat(x + 100, y + 66, camera.target.x, 0x80FFFF);
drawString(x, y + 78, " Y:", 0xFFFFFF);
drawFloat(x + 100, y + 78, camera.target.y, 0xFF80FF);
drawString(x, y + 90, " Z:", 0xFFFFFF);
drawFloat(x + 100, y + 90, camera.target.z, 0xFFFF80);
end
-- Hide/Show HUD
function hideHUD(type)
local transparency = nil;
if (type == true) then
transparency = 0x0000;
writeWord(time_speed_area, 0x0000);
elseif (type == false) then
transparency = 0x00FF;
writeWord(time_speed_area, 0x0003);
end
for i = 0, 6, 1 do
writeWord(hud_tranparency[i], transparency);
end
end
-- Disable Camera Control on Load Savestate.
-- I call this instead of "toggleCamera()" from loading a state
-- because apparently "event.onloadstate()" calls the funtion several times???
function disableCamera()
cameraEdit = false;
setCamera(false);
end
-- Enable/Disable Camera Control
function toggleCamera()
isPressed = true;
if (cameraEdit == true) then
cameraEdit = false;
gui.addmessage("Camera Control Disabled.");
elseif (cameraEdit == false) then
cameraEdit = true;
gui.addmessage("Camera Control Enabled.");
end
setCamera(true);
end
-- Set the Camera mode and Save/Load it's Position when Enabled/Disabled.
function setCamera(disable)
if (cameraEdit == true) then
camera_data.mode = readWord(camera.mode);
camera_data.target.x = readFloat(camera.target.x, true);
camera_data.target.y = readFloat(camera.target.y, true);
camera_data.target.z = readFloat(camera.target.z, true);
camera_data.position.x = readFloat(camera.position.x, true);
camera_data.position.y = readFloat(camera.position.y, true);
camera_data.position.z = readFloat(camera.position.z, true);
camera_data.zoom = readFloat(camera.zoom, true);
writeWord(camera.mode, 0x0006);
elseif (cameraEdit == false and disable ~= false) then
writeWord(camera.mode, camera_data.mode);
writeFloat(camera.target.x, camera_data.target.x, true);
writeFloat(camera.target.y, camera_data.target.y, true);
writeFloat(camera.target.z, camera_data.target.z, true);
writeFloat(camera.position.x, camera_data.position.x, true);
writeFloat(camera.position.y, camera_data.position.y, true);
writeFloat(camera.position.z, camera_data.position.z, true);
writeFloat(camera.zoom, camera_data.zoom, true);
hideHUD(false);
end
end
-- Update Camera Position/Target.
function moveCamera(address, value)
local newLocation = readFloat(address, true) + value;
if (cameraEdit == true) then
writeFloat(address, newLocation, true);
end
end
-- Update Camera Zoom.
function zoomCamera(value)
local newZoom = readFloat(camera.zoom, true) + value;
if (cameraEdit == true) then
writeFloat(camera.zoom, newZoom, true);
end
end
-- Core Loop
while true do
-- Disable if a Savestate is loaded.
event.onloadstate(disableCamera);
-- Toggle Camera Control
if (input.get().Home == true and isPressed == false) then
toggleCamera();
-- Zoom Camera
elseif (input.get().PageUp == true) then
zoomCamera(1);
elseif (input.get().PageDown == true) then
zoomCamera(-1);
-- Move Camera Position
elseif (input.get().Ctrl == nil and isPressed == false) then
if (input.get().LeftArrow == true) then
moveCamera(camera.position.x, 10.0);
moveCamera(camera.target.x, 10.0);
elseif (input.get().RightArrow == true) then
moveCamera(camera.position.x, -10.0);
moveCamera(camera.target.x, -10.0);
elseif (input.get().UpArrow == true and input.get().Shift == true) then
moveCamera(camera.position.y, 10.0);
moveCamera(camera.target.y, 10.0);
elseif (input.get().DownArrow == true and input.get().Shift == true) then
moveCamera(camera.position.y, -10.0);
moveCamera(camera.target.y, -10.0);
elseif (input.get().UpArrow == true and input.get().Shift == nil) then
moveCamera(camera.position.z, 10.0);
moveCamera(camera.target.z, 10.0);
elseif (input.get().DownArrow == true and input.get().Shift == nil) then
moveCamera(camera.position.z, -10.0);
moveCamera(camera.target.z, -10.0);
end
-- Move Camera Target
elseif (input.get().Ctrl == true and isPressed == false) then
if (input.get().LeftArrow == true) then
moveCamera(camera.target.x, 10.0);
elseif (input.get().RightArrow == true) then
moveCamera(camera.target.x, -10.0);
elseif (input.get().UpArrow == true and input.get().Shift == true) then
moveCamera(camera.target.y, 10.0);
elseif (input.get().DownArrow == true and input.get().Shift == true) then
moveCamera(camera.target.y, -10.0);
elseif (input.get().UpArrow == true and input.get().Shift == nil) then
moveCamera(camera.target.z, 10.0);
elseif (input.get().DownArrow == true and input.get().Shift == nil) then
moveCamera(camera.target.z, -10.0);
end
elseif (input.get().Home == nil and
input.get().PageUp == nil and
input.get().PageDown == nil and
input.get().Shift == nil and
input.get().Ctrl == nil and
input.get().UpArrow == nil and
input.get().DownArrow == nil and
input.get().LeftArrow == nil and
input.get().RightArrow == nil) then
isPressed = false;
end
-- Display Camera Info
if (cameraEdit == true) then
textDisplay();
hideHUD(true);
end
emu.frameadvance();
end
Comments
0 B
|👍
/👎