|
|
Re: RII - Resolution Independent Interface[message #222072]
|
Fri, 19 June 2009 20:52
|
|
BirdFlu |
|
Messages:438
Registered:September 2007 Location: Lampukistan |
|
|
There are several components in a GUI that need to be tackled :
Definition , Layout , Function , Rendering
----------------
Definition : The rendered GUI elements have to be defined at a point in the code. This is about the pure existence of an element. It gets a name and is "accessible" (in an abstract sense) in the game from now on. It is accessed to set its layout, to link it to a function (e.g. button press) and to render it.
Layout : This is just the position of an element on the screen.
Function : There are static objects (e.g. background image) and there a dynamic ones (e.g. buttons). Whenever a dynamic element is supposed to react to some event a callback function is called. This callback function is linked to the element when it is defined.
Rendering : The elements that have an image associated with it are rendered by drawing its image to the frame buffer at the location specified by the layout.
----------------
In this project, i mostly addressed the definition and the layout of gui elements. I didn't changed the rendering and the functions. Because the rendering is explicit, that is only the elements that are known at compile time are rendered, the definition has also to happen at compile time. So, adding new elements is not possible now (maybe except for buttons, as there is generic rendering code for them). As the linking of the functions to the elements is also done at compile time, there is only the layout that can be modified.
Functions could be "externalized", now that the Lua project is getting some attention. Unfortunately functions and rendering code aren't always separated, that is rendering code is called from the callback function. So, that leaves us with externalizing only the non-critical callback function. Of course, you could also expose the rendering functions to the user, but i don't think it's a good idea. It's too low level, and would probably degrade performance (a lot?).
Exposing the functions wouldn't be too hard, i think. Right now we use GUI_CALLBACK, with is a function pointer typedef. That should be changed to a functor, because they are more powerful. As there are no functors (or delegates or similar constructs in C++) we would have to do it ourselves. But it's not that hard.
// base functor
class GUI_FUNCTOR
{
public:
virtual bool operator()(param1, param2, ...) = 0;
};
// GUI_CALLBACK replacement
class GUI_FUNPTR
{
public:
GUI_FUNPTR(GUI_CALLBACK funptr) : fun(funptr) {};
virtual bool operator()(param1, param2, ...)
{
return fun(param1,param2);
}
private:
GUI_CALLBACK fun;
};
// externalized Lua callback function
class GUI_LUACALLBACK
{
public:
GUI_LUACALLBACK(string filename, string funtionname) : file(filename), function(functionname) {};
virtual bool operator()(param1, param2, ...)
{
if(globalObject.FileNotLoaded(file)) globalObject.LoadFile(file);
lua_pushfunctionname(function);
lua_pushparameters(param1, param3);
if(!lua_pcall(...))
{
lua_geterror();
return false;
}
return lua_popresult();
}
private:
string file, function;
};
The Layout is externalized for some parts of the GUI. Basically, the layout of the complete strategic screen is available to modding. Just look at the xml files that are coming with this project. The Definition is also more relaxed now. You can define fonts and colors and even the actual image file(name)s that will be used for rendering.
So, the real "enemy" of this project is the explicit rendering code. It has to be made implicit, that is traversing a data structure (that can be filled from outside) and rendering its elements according to some rules. Once the rendering works, everything else will be much easier to transform.
I wasn't working on this project for some time, as i was busy integrating the VFS into the MP code, which is now merged with the main branch. But i already merged, my "old" code with the current SVN HEAD, so the next release should come in the next couple of "time units", although it probably won't contain any new stuff.
Report message to a moderator
|
|
|
|
Re: RII - Resolution Independent Interface[message #222083]
|
Fri, 19 June 2009 22:09
|
|
gmonk |
|
Messages:670
Registered:April 2002 Location: Newfoundland, Canada |
|
|
Dude, you are an angel. :angel:
You understand this idea completely. I don't think that Lua scripting for UI element placement, outside of game init, should even be a consideration. If there's interface scripting involved it should only be called for during game initialisation, perhaps it could be replaced by an .ini file, but I thought that perhaps Lua scripts could be more flexible.
Since most of us have no real idea how it works in the code, you're the guy to dictate what can or can't be done via scripting. If you can come up with anything at all that might be user configurable via scripts it'd be helpful.
In my crazy SMP diatribe I was thinking mostly mostly the placement of interface objects. Rendering can, and should only be, handled by the main engine. How would that affect something like a call for "FadeToBlack" or "Screenshake" though? I'm thinking ahead to user configurable cutscene scripts here.
Report message to a moderator
|
First Sergeant
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Re: RII - Resolution Independent Interface[message #222639]
|
Mon, 22 June 2009 22:18
|
|
BirdFlu |
|
Messages:438
Registered:September 2007 Location: Lampukistan |
|
|
First, the directory "Profiles/UserProfile_JA2113" must exist. And it usually does, when you have the newest SVN version. I don't know if the One Click Installer creates this directory.
Then you have to activate this mod by adding this in ja2.ini
[Ja2 Settings]
VFS_CONFIG_INI = vfs_config.RII.ini
;VFS_CONFIG_INI = some old vfs_config.*.ini that you commented out, in order to not loose it
Other wise you start the game with a wrong configuration file, which of course doesn't work. But i've written this in my first post, most of it.
You don't necessarily have to call the batch files. They convert SLF archives and the images that are not located in archives, but the vfs_config.*.ini file doesn't use them. You would have to modify the vfs_config.*.ini yourself, but you don't have to as it works without it.
The item/weapon png files are in the Profiles/RII/Interface/* directories and they are always used, independent of whether you called the batch files or not.
[Updated on: Mon, 22 June 2009 22:18] by Moderator Report message to a moderator
|
|
|
|
Re: RII - Resolution Independent Interface[message #222641]
|
Mon, 22 June 2009 22:22
|
|
gmonk |
|
Messages:670
Registered:April 2002 Location: Newfoundland, Canada |
|
|
See the info about setting up a new VFS entry here.
Anyone want to write a simple step-by-step tutorial for the setting up a new VFS entry with an example file? Off_Topic maybe? I can have a look at it tomorrow, but I'm not sure how much time I'll have.
[Updated on: Mon, 22 June 2009 22:25] by Moderator Report message to a moderator
|
First Sergeant
|
|
|
|
|
|
|
|
|
|
Re: RII - Resolution Independent Interface [UPDATE : Alpha V4c][message #223658]
|
Sat, 27 June 2009 03:23
|
|
Shanga |
|
Messages:3480
Registered:January 2000 Location: Danubia |
|
|
Here's an idea that haunted me for ages. Probably damn hard to implement, but sure seems more easy now than it was almost 10 years ago.
The gameworld can be rendered at 1280x1024 or any high res nowdays. Ok... but can we design a "sniper scope" that actually zooms down to lowest resolution? Like a movable lens.
Think of how much this would change aiming in JA2.
a) non-aimed shot, standard cursor, no option to pick body part (like on prone bodies). Equivalent to a shot from hip. Very fast, damn inaccurate.
b) normal sights lens, gives option to aim at head/torso/feet, limited levels of zoom, aka adding aim points.
c) scope lens, gives option to aim max points at a certain body part.
d) /dreammode on - add additional targeting points on the body (torso especially). Imagine shot to heart, shot to the shoulder/arm, etc. Game handles those randomly now, but why we shouldn't have the option to do them by hand?
[Updated on: Sat, 27 June 2009 03:26] by Moderator Report message to a moderator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RII Light v1[message #226365]
|
Thu, 09 July 2009 03:40
|
|
BirdFlu |
|
Messages:438
Registered:September 2007 Location: Lampukistan |
|
|
Here is a RII version with Lua support. But it doesn't contain the actual interface changes/updates. I call it RII Light, although i'm open for better name suggestions, as RII doesn't really fit the new direction of this mod anymore.
[ download ]
This exe is build on the current SVN version (r.3095) and it comes with a small script that demonstrates some features.
-- this function will be called from inside the game
function InitLuaUI()
print( "Initializing Lua User Interface
" )
-- get root node of 'MainMenu' screen
root = gui.getScreen("MainMenu").root_node
root.position = { 100, 100 }
move_image = {
[1] = { image = "BigItems/GUN11.sti", offset = {40, 100} },
[2] = { image = "BigItems/GUN33.sti", offset = {40, 200} },
}
for i in ipairs(move_image) do
local im = gui.createImage{ parent = root, image = move_image[i].image }
im.offset = move_image[i].offset
local t = gui.createTextNode{
parent = im,
text = move_image[i].image,
font = "BLOCKFONT2", foreground = 240, background = 0
}
--t.offset = { -1 * im.size[1]/2, -10 }
t.offset = { 0, -10 }
local re = gui.createRegion{ parent = im }
re.size = im.size
local move,button = GetMouseCallbacks(im)
re:define( button, move )
end
local text = gui.createTextNode{ parent = root }
text.font = "FONT16ARIAL"
text.foreground = 134
text.background = 1
text.text = "Hello World!"
text.position = { 640/2 - 40, 20 }
return 1
end
-- this function creates mouse callbacks (closures)
function GetMouseCallbacks(node)
local _node = node
local _lbutton = false
local _position = {}
local moveCallBack = function(tab)
if(tab.reason == 64) then
_lbutton = false
-- print("lost mouse")
elseif(tab.reason == 128) then
-- print("gain mouse")
end
if( _lbutton == true) then
-- compute relative displacement
local rd = {
tab.mouse_x - _position[1],
tab.mouse_y - _position[2]
}
-- apply displacement to node
local xy = _node.position
for i=1,2 do xy[i] = xy[i] + rd[i] end
_node.position = xy
-- save current mose position
_position = { tab.mouse_x, tab.mouse_y }
end
end
local buttonCallBack = function(tab)
if(tab.reason == 4) then
_lbutton = true
_position = { tab.mouse_x, tab.mouse_y }
elseif tab.reason == 8 then
_lbutton = false
elseif tab.reason == 16 then
local p = _node.position
local o = _node.offset
local t = _node.type;
print( t )
print( " position : " .. p[1] .. ", " .. p[2])
print( " offset : " .. o[1] .. ", " .. o[2])
end
end
return moveCallBack, buttonCallBack
end
It doesn't do very much, but it gives you something to play with.
Btw. you should start this version in windowed mode. It probably wont work in fullscreen mode, i haven't tested it yet.
[Updated on: Thu, 09 July 2009 10:57] by Moderator Report message to a moderator
|
|
|
|
|