Author Topic: Scripted Options menu  (Read 4036 times)

0 Members and 1 Guest are viewing this topic.

Offline The E

  • He's Ebeneezer Goode
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Scripted Options menu
After working on the mainhall mission script, I started thinking: Would it be worthwhile to make all the functions provided by the FreeSpace UI scriptable?

I have a rough idea what scripting functions are needed to make this work, and a rough idea how to implement them (which I will be starting to do over the next few weeks).
The Goal of this is to drastically reduce the amount of interface files FSO needs, as well as implementing a method of dealing correctly with display aspect ratios != 4:3. Any further comments or suggestions you would like to see?
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline Mobius

  • Back where he started
  • 213
  • Porto l'azzurro Dolce Stil Novo nella fantascienza
    • Skype
    • Twitter
    • The Lightblue Ribbon | Cultural Project
Re: Scripted Options menu
A shortcut to the Mission Simulator would be welcome. :)
The Lightblue Ribbon

Inferno: Nostos - Alliance
Series Resurrecta: {{FS Wiki Portal}} -  Gehenna's Gate - The Spirit of Ptah - Serendipity (WIP) - <REDACTED> (WIP)
FreeSpace Campaign Restoration Project
A tribute to FreeSpace in my book: Riflessioni dall'Infinito
My interviews: [ 1 ] - [ 2 ] - [ 3 ]

 

Offline JGZinv

  • 211
  • The Last Dual! Guardian
    • The FringeSpace Conversion Mod
Re: Scripted Options menu
Although maybe not directly related, FS is going to eventually need a menu that
can be triggered by docking at a ship or pad. This menu could then be selected from
using the arrow keys and enter.

This would be for outfitting certain weapons on the fly so to speak.
I'm sure Backslash would be interested or have some feedback on the idea as well.
True power comes not from strength, but from the soul and imagination.
Max to PCS2 to FS2 SCP Guide
The FringeSpace Conversion Mod

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: Scripted Options menu
i think a good place to start would be an object oriented meathod for defining custom interface objects, like radio buttons, text boxes, buttons, scrollbars, ect. it might be worthwhile to just use the interface system used in the lab, just bind those functions to scripting and add some sort of skin support (which i think it already supports). of course that requires some c. it should be possible to use the features from anywhere in the script, even possibly during simulation. any case simple menus can easily be done with scripting, its just a matter of making the system fast and usable.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline Wanderer

  • Wiki Warrior
  • 211
  • Mostly harmless
Re: Scripted Options menu
It might useful to write direct functions on how to create radio buttons etc into lua... Either via some commonly agreed 'lua_gui.lua' file or then directly writing those as functions into lua.cpp
Do not meddle in the affairs of coders for they are soggy and hard to light

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: Scripted Options menu
well ive done some object oriented lua, but not for freespace. freespace really doesnt benefit much anymore. i did a basic 2d vector and matrix classes, back when scripting was new, so that i could do certain things that were at the time impossible. of course new features had deprecated those. for something like ui elements it might work better.

id use sort of a vb type approach (without the ****ty proprietary language of course) where every interface object has a list of properties, what it is, how it behaves, what it looks like, what screen it appears on, functions to call when certain events take place and so on. lua tables are pretty powerful. not really just arrays, they have many other features that are extremely versatile. you can create a table and store button properties in it with named keys. then store each "ui element" table in a master table containing all the elements.

of course thats the easy part. all the things that can be done with the ui need to be bound to scripting. everything from control config editor, pilot selection, main halls, loadout, briefing, techroom, all need to have functions in scripting that can be called in place of the hard coded ui. on the other hand a lot of stuff can be simplified. skin alignments/gfx/whatever. dynamic resolution may be used, so only one set of art is required. if possibly derived from the existing interface (though recreating a lot of it might be better, since its all low res and crappy looking for todays standards). a really good lua based ui would make a good replacement for the old system if i can be made to the same standards have the same features and bundeled with the engine. all we really need are all the function the ui calls when the user change something, the rest can be made in lua entirely.

i would write it in two parts however. one that defines the basic ui objects, functions, tables declarations all on one file. while usage would be in another file all together. the second file would be what mods could edit to create their own uis. the first would be at engine level, and the second at the media vps level. this would mak it very mod friendly, and very powerful. i also just not to long ago wrote my on lua parser which parses files very similar to freespae tables and sticks them in lua tables. that sorta thing might be useful for storing not so hard coded files for modders to edit. it has some rough edges to iron out and could stand to parse more types of information (string lists, bool lists, multiple datatype fields, etc) since only numbers, strings, number lists, and vectors are currently supported.
« Last Edit: June 26, 2009, 03:01:01 pm by Nuke »
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: Scripted Options menu
oops double post
curse your enforcement of "proper brittish english"
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline The E

  • He's Ebeneezer Goode
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: Scripted Options menu
Yeah, that sounds good. Right now, I'm working on implementing all the functions needed to retrieve the data that is set in the options menu (which includes the multiplayer options, control config data, HUD config and detail settings). Next step would be to make functions that set those variables and store them in the right place. After that, I'll try to implement at least some of the stuff Nuke described. It's definitely a more sensible approach than what is currently implemented in the FSO code.
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: Scripted Options menu
i think also the same thing should be done for the hud, just not sure which one would be easier to do first. im not familiar with the internal ui at all. id definately think about the hud when designing stuff like drop down menus, sliders, buttons and the like. i can forsee a point and click hud using some of that stuff, comms menus, mouse adjustable ets, auto-targeting/speed matching, escort list targeting, general targeting (click on the ship) and weapon select could all be made mouse intractable at some point.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline The E

  • He's Ebeneezer Goode
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: Scripted Options menu
Yeah, I guess in the long run something like that will have to be done. At the moment, I want to concentrate on the non-mission UI. Once there is a sort of standard UI library for that, extending it to cover in-mission stuff should be comparatively easy.
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: Scripted Options menu
it shoud be pretty fast once all the art is loaded to memory. you would hardcode all the properties for all the buttons in the game, then when you enter a menu screen all the buttons linked to that screan would activate. functions would be available to create new ones that the modder may want to create. you would then call render_ui("current screen") to render all the active ui elements and ui_interact("current screen"), to check if events have occured and do something about them, by compairing input keystrokes and mouse events to button properties.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline The E

  • He's Ebeneezer Goode
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: Scripted Options menu
I smell....progress.

scripting.tbl:
Code: [Select]
#Conditional Hooks
$Application: Freespace 2
$On Game Init: [[Global_onInit.LUA]]

$State: GS_STATE_MAIN_MENU
$On State Start: [[mainhall_onStart.LUA]]
+Override: true
$On State End: [[mainhall_onEnd.lua]]
+Override: true
$On Frame: [[mainhall_onFrame.LUA]]
+Override: true
#End

Global_onInit:
Code: [Select]
--Function to handle a section every frame. These are used to create the entries in the Mainhall menu
--This function is useful for drawing a row or line of buttons

--name: (string) The text associated with the control
--num: (int) Multiplier that is used to generate the position
--hidden: (boolean) Whether or not there will be visual feedback for moving the mouse over the "button"
--xdivsize: (int) These control the positioning of the buttons. The actual coordinates for the buttons are dependant on the current screen resolution
--ydivsize: (int) (i.e. the horizontal coordinates can be determined by dividing the screen width by xdivsize)
--xadd: (int) These control the size of the buttons. If they are set to 10, for example, the result will be a box 10 pixels wide and long.
--yadd: (int)
--mode: (int) 1: Controls will be arranged horizontally (num will be applied to the x axis) 2: Vertical arrangement
--
--returns: (boolean) True when this button has received a left click

mh_section = function(name, num, hidden, xdivsize, ydivsize, xadd, yadd, mode)

--MENU COLOR
local xmargin = gr.getScreenWidth()/xdivsize
local ymargin = gr.getScreenHeight()/ydivsize

--Get corner coordinates for this box
--if (mode == 1) then
local x1 = xmargin*num
local y1 = ymargin
--elseif (mode == 2) then           --Why does this not work?
-- local x1 = xmargin
-- local y1 = ymargin*num
--end
local x2 = x1+xadd
local y2 = y1+yadd

--When the mouse is OVER this section...
if io.getMouseX() > x1 and io.getMouseX() < x2 and io.getMouseY() > y1 and io.getMouseY() < y2 then
if hidden == false then
--Draw the inside box
gr.setColor(0, 255, 0)
gr.drawRectangle(x1+5, y1+5, x2-5, y2-5, false, false)
--Draw the little target lines now
local x = x1+(x2-x1)/2
local y = y1-20

--Top target line
--gr.drawLine(x, y, x, y+15)

--Bottom target line
--y = y2+10
--gr.drawLine(x, y, x, y+15)

--Left target line
--x = x1-20
--y = y1+17
--gr.drawLine(x, y, x+15, y)

--Right target line
--x = x2+5
--gr.drawLine(x, y, x+15, y)
end

--Handle the button click
if io.isMouseButtonDown(MOUSE_LEFT_BUTTON) then
gr.drawString(name, x1 + ( (x2-x1) - gr.getStringWidth(name) ) / 2, (y2-((y2-y1)/2))-4 )
gr.drawRectangle(x1, y1, x2, y2, false, false)
return true
end
end

--Draw the outline
gr.setColor(255, 255, 255)
gr.drawRectangle(x1, y1, x2, y2, false, false)
if hidden == false then
--Draw the name
gr.drawString(name, x1 + ( (x2-x1) - gr.getStringWidth(name) ) / 2, (y2-((y2-y1)/2))-4 )
end
return false
end

mainhall_onStart:
Code: [Select]
logolist = {"43_logo","1610_logo"} --This is a list of logos. Basically the same Logo, only adapted for 4:3 aspect ratio displays and 16:10 ones
shiplist = {"EA Thunderbolt","EA Aurora","EA Badger","EA Tiger","PSI Command Ship","EA Hyperion","EA Omega","EA Warlock","EA Omega-X","Babylon 5 (S1)","MF Sharlin","NR G'Quan","CR Primus"} --Put your ship classes in quotes here
missionlist = {"Mainhall.fs2"} --List of missions to be used
backgroundlist43 = {"43_mainhall", "43_B5", "43_Omega"} --List of 4:3 backgrounds.
backgroundlist1610 = {"1610_mainhall", "1610_ea_warlock", "1610_warlock_b5"} --List of 16:10 backgrounds
splashscreen = "2_PreLoad"                      --Splashscreen displayed while the mission loads
usemission = false                              --If false, the single- and multiplayer UI will use the same layout. If true, one of the missions defined in the missionlist will play in the background of the single player UI
rotConst = 7                                    --Modify this to make the ship turn faster to slower
logoXFactor = 1 --Scaling Factor for the Logo. 1 means the Logo will fill the entire screen width.

screenWidth = gr.getScreenWidth()
screenHeight = gr.getScreenHeight()
aspectRatio = screenWidth/screenHeight

if aspectRatio == 1.6 then
logo = logolist[2]
bg_num = table.getn(backgroundlist1610)
background = backgroundlist1610[math.random(1, bg_num)]
logoYFactor = 0.06 -- This is similar to logoXFactor. Since the 16:10 logo in this example has the same height as the 4:3 one, I need to set this factor according to the aspect ratio as well
else
logo = logolist[1]
bg_num = table.getn(backgroundlist43)
background = backgroundlist43[math.random(1, bg_num)]
logoYFactor = 0.08
end

renderX1 = 0            --
renderX2 = screenWidth  -- These determine the amount of screen real estate the rotating model will take up.
renderY1 = 0            --
renderY2 = screenHeight --
rendermidX = (renderX1+renderX2)/2
logoX = 0 --
logoY = screenHeight-(screenHeight*logoYFactor) --These control the positioning and size of the logo
logoX2 = screenWidth --
logoY2 = screenHeight --

if ts.isCurrentPlayerMulti()==true or usemission==false then
numChoices = table.getn(shiplist)
randomShip = tb.ShipClasses[shiplist[math.random(1,numChoices)]]
shipName = randomShip.Name
init = 42
end

mainhall_onFrame:
Code: [Select]
if ts.isCurrentPlayerMulti()==true or usemission==false then

--Draw background image
local tex = gr.loadTexture(background)
if tex:isValid() then
gr.drawImage(tex, 0, 0, gr.getScreenWidth(), gr.getScreenHeight())
end

if rotate_pct then
rotate_pct = rotate_pct + rotConst*ba.getFrametime()
if rotate_pct > 100 then
rotate_pct = rotate_pct - 100
end
else
rotate_pct = 40
end

randomShip:renderTechModel(renderX1, renderY1, renderX2, renderY2, rotate_pct)

gr.setColor(255,255,255)
gr.drawString(shipName,rendermidX-gr.getStringWidth(shipName)/2,renderY2)
else
if not g_splashScreen then
--Don't need cursor
io.setCursorHidden(true)

--Draw splash image
local tex = gr.loadTexture(splashscreen)
if tex:isValid() then
gr.drawImage(tex, 0, 0, gr.getScreenWidth(), gr.getScreenHeight())
end

--Draw "Loading..."
gr.setColor(255, 255, 255)
gr.CurrentFont = gr.Fonts['font02']
local loadString = "Loading..."
local x = (gr.getScreenWidth()-gr.getStringWidth(loadString))/2
local y = (gr.getScreenHeight()-gr.CurrentFont.Height)/2
gr.drawString(loadString, x, y)

--Done with splash
gr.CurrentFont = gr.Fonts['font01']
g_splashScreen = true
elseif not g_missionLoaded then
if init2 == nil then
missionName = missionlist[math.random(1,table.getn(missionlist))]
init2 = 42
end
mn.loadMission(missionName)
io.setCursorHidden(false)
g_missionLoaded = true
end
end

if g_missionLoaded then
mn.simulateFrame()
mn.renderFrame()
end

if g_missionLoaded or ts.isCurrentPlayerMulti()==true or usemission==false then
if ts.isCurrentPlayerMulti()==true then
if ts.isPXOEnabled()==true then
b1 = mh_section("Multiplayer", 1, false, 8, 256, gr.getScreenWidth()/9, gr.getScreenHeight()/25, 1)
else
b1 = mh_section("Multiplayer", 1, false, 8, 256, gr.getScreenWidth()/9, gr.getScreenHeight()/25, 1)
end
else
b1 = mh_section("Ready Room", 1, false, 8, 256, gr.getScreenWidth()/9, gr.getScreenHeight()/25, 1)
end
b2 = mh_section("Campaign Room", 2, false, 8, 256, gr.getScreenWidth()/9, gr.getScreenHeight()/25, 1)
b3 = mh_section("Tech Room", 3, false, 8, 256, gr.getScreenWidth()/9, gr.getScreenHeight()/25, 1)
b4 = mh_section("Barracks", 4, false, 8, 256, gr.getScreenWidth()/9, gr.getScreenHeight()/25, 1)
b5 = mh_section("Options", 5, false, 8, 256, gr.getScreenWidth()/9, gr.getScreenHeight()/25, 1)
b6 = mh_section("Exit", 6, false, 8, 256, gr.getScreenWidth()/9, gr.getScreenHeight()/25, 1)
b7 = mh_section("F3", 1, true, 256, 256, 10, 10, 1)
end

gr.drawImage(logo, logoX, logoY, logoX2, logoY2)

--gr.drawRectangle(x1, y1, x2, y2, false, false)

if b1 then
if ts.isCurrentPlayerMulti()==true then
if ts.isPXOEnabled()==true then
event = "GS_EVENT_PXO"
else
event = "GS_EVENT_MULTI_JOIN_GAME"
end
else
event = "GS_EVENT_NEW_CAMPAIGN"
end
elseif b2 then
event = "GS_EVENT_CAMPAIGN_ROOM"
elseif b3 then
event = "GS_EVENT_TECH_MENU"
elseif b4 then
event = "GS_EVENT_BARRACKS_MENU"
elseif b5 then
event = "GS_EVENT_OPTIONS_MENU"
elseif b6 then
event = "GS_EVENT_QUIT_GAME"
elseif b7 then
event = "GS_EVENT_LAB"
else
event = NIL
end

if g_missionloaded and (event == "GS_EVENT_NEW_CAMPAIGN" or event == "GS_EVENT_OPTIONS_MENU") then
mn.unloadMission()
g_missionLoaded = nil
g_splashScreen = nil
end

if not (event == NIL) then
ba.postGameEvent(ba.GameEvents[event])
end

mainhall_onEnd:
Code: [Select]
if g_missionLoaded then
mn.unloadMission()
g_missionLoaded = nil
g_splashScreen = nil
end

Comments?
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline Aardwolf

  • 211
  • Posts: 16,384
    • Minecraft
Re: Scripted Options menu
There are plenty.

Feel free to say Derp. That was a deliberate bad joke.

 

Offline The E

  • He's Ebeneezer Goode
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: Scripted Options menu
Oh thank you very much, Aard.
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline Aardwolf

  • 211
  • Posts: 16,384
    • Minecraft
Re: Scripted Options menu
Fine, I'll be more helpful.

Your comments are numerous, but I notice there's at least one big section of code which is nothing but lines which have been commented out. As for the comments which are actually descriptive, you've done a good job.

But I haven't actually looked at what it does

 

Offline The E

  • He's Ebeneezer Goode
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: Scripted Options menu
What this does is described in pictures here. The Lines that were commented out without comment, were present in WMCoolmons' original script. They were there to give more visual feedback if the mouse is over the button, by drawing crosshairs centered on the button in question. I've commented them out since I didn't need them for TBP, but left them in because I do hope to be not the only one using this in the future.
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline Wanderer

  • Wiki Warrior
  • 211
  • Mostly harmless
Re: Scripted Options menu
Hmm.... I would avoid scripting.tbl for obvious reasons and favor -sct.tbms instead
Do not meddle in the affairs of coders for they are soggy and hard to light

 

Offline Aardwolf

  • 211
  • Posts: 16,384
    • Minecraft
Re: Scripted Options menu
Even with tbm's, global variable names that are the same in multiple scripts may interfere with each other.

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: Scripted Options menu
thats easily solved by using better variable naming conventions, and using functions to localize variables that arent used a lot. also you can use local within each hook to localize it only to that hook. another thing ive been toying with is the use of global tables to transport info between hooks, reducing the number of variables that can clash. i did this with the atmosperic script where some data from the flight physics was needed to draw some gauges of the hud. so i just created a hudvars table and used named keys in that table to store data. the result is only one variable that is global.

im not sure how tbms merge code blocks from different files, if they just merge them then this might cause some problems. it would probibly be better to seperate them by code blocks, running them one at a time under each hook. then the use of locals may be used to achieve better code isolation.

is there any way to make the scripting system allow multiple code blocks per each hook? if so that would make it possible to better the use of local variables. it would also make it easier to organize code into multiple files, and provide file specific error reporting, making debug easier. that would be very useful on large scale lua scripts.

for example instead of this :
Code: [Select]
#Global Hooks
$GameInit:
[[gameinit.lua]]
$Simulation:
[[simulation.lua]]
$Hud:
[[hud.lua]]
#end
you cand do this
Code: [Select]
#Global Hooks
$GameInit:
[[global_functions.lua]]
[[global_variables.lua]]
$Simulation:
[[physics.lua]]
[[targeting.lua]]
$Hud:
[[hud.lua]]
[[debug_print.lua
#end
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline The E

  • He's Ebeneezer Goode
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: Scripted Options menu
Oookaaay.

Progress is going on, yet I think I need some help. The problem is that the functions I wrote to get at all the nice little settings do not seem to work correctly. (Plus they are a bit too stupid for my own liking) What I would need is a function that returns some sort of struct or array with all the nice little settings data in it. I'll try to do this myself, of course, but any help would be welcome.

Another thing that's needed is a way to properly control music and sound effect playback via lua; right now we only have a ad.playSound() function, which, as far as control goes, is not much. Again, I tried this myself, and it sort of works, but may be doing bad things behind the scenes.
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns