Don't hurt me I try to figure out how pointers, strucs and arrays work and I think a need a little hand here. The search brings up a lot about pointer, arrays and stuff, but it made me even more confuse. I'm trying to fill in a simple ListBox, which actually works, but how do I make it to choose be
array FiltersDX5 or FiltersD3D9? Is a pointer here the right direction?
I'm trying to write my code as a module ;)
// *.ash
// new Setup module header
#define LST_DX5_LIST 7
#define LST_D3D9_LIST 10
struct GfxFilter {
String name;
String filter;
String filter_scaling;
};
GfxFilter FiltersDX5[LST_DX5_LIST];
GfxFilter FiltersD3D9[LST_D3D9_LIST];
export FiltersDX5; export FiltersD3D9;
// *.asc
// new module script
.....
......
String driver = ini.Read("graphics", "driver", "DX5");
// how to set a pointer??? to FiltersDX5[] array
int aVariableArraySize = LST_DX5_LIST;
if (driver == "D3D9") {
//change pointer??? to FiltersD3D9 array...
aVariableArraySize = LST_D3D9_LIST;
}
int i = 0;
while (i < aVariableArraySize) {
lstFilter.AddItem(Filters???[i].name);
i++;
}
....
.....
It depends on which version of AGS you're using, but as of the latest stable version (AGS 3.3.3), there are no pointers to custom user struct types. This is actually introduced in the up-coming version (AGS 3.4.0), but currently (AGS 3.4.0.3) you cannot have both pointers to a custom struct type
and pointers within that struct. This would prevent you from having a pointer to your type (or a dynamic array of your type) while storing Strings within them.
You
could use the old-style string functions like this:
Spoiler
// *.ash
#define LST_DX5_LIST 7
#define LST_D3D9_LIST 10
managed struct GfxFilter
{
char name[200];
char filter[200];
char filter_scaling[200];
};
// NOTE: **NEVER** define struct instances in a header file!! ONLY import them!
import GfxFilter* FiltersDX5[]; // use these as dynamic arrays, so you can get a pointer to the array
import GfxFilter* FiltersD3D9[];
// *.asc
// import old-style string functions
import void StrCopy(string, const string);
import int StrLen(const string);
GfxFilter* FiltersDX5[];
GfxFilter* FiltersD3D9[];
export FiltersDX5;
export FiltersD3D9;
function game_start()
{
// initialize arrays
FiltersDX5 = new GfxFilter[LST_DX5_LIST];
FiltersD3D9 = new GfxFilter[LST_D3D9_LIST];
int i;
for (i = 0; (i < LST_DX5_LIST) || (i < LST_D3D9_LIST); i++)
{
if (i < LST_DX5_LIST)
{
FiltersDX5[i] = new GfxFilter;
}
if (i < LST_D3D9_LIST)
{
FiltersD3D9[i] = new GfxFilter;
}
}
// populate array members
String buffer;
buffer = "SomeFilterName";
StrCopy(FiltersDX5[0].name, buffer); // etc.
}
String CharArrayToString(const string buffer)
{
String s = buffer;
return s;
}
void DoSomething()
{
String driver = ini.Read("graphics", "driver", "DX5");
GfxFilter *filters[] = FiltersDX5;
int aVariableArraySize = LST_DX5_LIST;
if (driver == "D3D9")
{
filters = FiltersD3D9;
aVariableArraySize = LST_D3D9_LIST;
}
int i = 0;
while (i < aVariableArraySize)
{
String name = CharArrayToString(filters[i].name); // copy the struct member into a String to take full advantage of any new-style String functions
lstFilter.AddItem(name);
i++;
}
}
That being said, if you're trying to change the graphics filter settings at run-time, just be aware that it won't work. The AGS engine currently can only change filters when the game is first launched.
Edit: Correction - The above code does not work, producing a segfault when trying to access the member arrays using StrCopy. The characters could be manually copied into the arrays, but that loses so much of the efficiency of the code that other solutions should be utilized instead.
Thank you very much monkey!!! Yes I know, I need to restart the engine to get all my changes to the acsetup.cfg file working.
But I have most of the winsetup settings now in a gui/module so I can change them easy In-Game under Linux. I already use the 3.4.0.3 build ;) It would be nice to know how it will change in the new build...just if you have time.
Quote from: Ronsen on Mon 26/01/2015 19:36:26
Thank you very much monkey!!! Yes I know, I need to restart the engine to get all my changes to the acsetup.cfg file working.
But I have most of the winsetup settings now in a gui/module so I can change them easy In-Game under Linux. I already use the 3.4.0.3 build ;) It would be nice to know how it will change in the new build...just if you have time.
Now we only need to introduce script commands to change gfx resolutions and filters at runtime ....
I was actually curious about doing that. Does Allegro 4 allow that to be done? I thought that it wasn't possible with A4.
Unfortunately I still have some trouble with this line:
GfxFilter *array = FiltersDX5;
It says : Type mismatch: cannot convert 'Gfxfilter[]' to 'Gfxfilter*' :/
Yeah, sorry. That was a mistake. I edited the post above.
I amended a few other things as well, such as incorrectly converting the char array into a new-style String. The above code should now work as intended.
Thank you a lot but i still have some trouble and it's btw already over my head. I get back to my level and put everything in 1 array...which I didn't want to do...but hey
// new Setup module header
#define FILTER_MAX 17
struct GfxFilter {
String name;
String filter;
String filter_scaling;
String driver;
};
import GfxFilter filters[FILTER_MAX];
GfxFilter filters[FILTER_MAX];
export filters;
....
String driver = ini.Read("graphics", "driver", "DX5");
String filter = ini.Read("graphics", "filter", "None");
String filter_scaling = ini.Read("graphics", "filter_scaling", "1")
.....
// DX5 gfxfilter (i know this could be better)
filters[0].name = "StdScale";
filters[0].filter = "StdScale";
filters[0].filter_scaling = "1";
filters[0].driver = "DX5";
filters[1].name = "StdScale2";
filters[1].filter = "StdScale";
filters[1].filter_scaling = "2";
filters[1].driver = "DX5";
filters[2].name = "StdScale3";
filters[2].filter = "StdScale";
filters[2].filter_scaling = "3";
filters[2].driver = "DX5";
filters[3].name = "StdScale4";
filters[3].filter = "StdScale";
filters[3].filter_scaling = "4";
filters[3].driver = "DX5";
filters[4].name = "StdScaleMax";
filters[4].filter = "StdScale";
filters[4].filter_scaling = "max";
filters[4].driver = "DX5";
filters[5].name = "Hq2x";
filters[5].filter = "Hq2x";
filters[5].filter_scaling = "2";
filters[5].driver = "DX5";
filters[6].name = "Hq3x";
filters[6].filter = "Hq3x";
filters[6].filter_scaling = "3";
filters[6].driver = "DX5";
// D3D9 gfxfilters
filters[7].name = "StdScale";
filters[7].filter = "StdScale";
filters[7].filter_scaling = "1";
filters[7].driver = "D3D9";
filters[8].name = "StdScale2";
filters[8].filter = "StdScale";
filters[8].filter_scaling = "2";
filters[8].driver = "D3D9";
filters[9].name = "StdScale3";
filters[9].filter = "StdScale";
filters[9].filter_scaling = "3";
filters[9].driver = "D3D9";
filters[10].name = "StdScale4";
filters[10].driver = "D3D9";
filters[10].filter = "StdScale";
filters[10].filter_scaling = "4";
filters[11].name = "StdScaleMax";
filters[11].filter = "StdScale";
filters[11].filter_scaling = "max";
filters[11].driver = "D3D9";
filters[12].name = "Linear";
filters[12].filter = "Linear";
filters[12].filter_scaling = "1";
filters[12].driver = "D3D9";
filters[13].name = "Linear2";
filters[13].driver = "D3D9";
filters[13].filter = "Linear";
filters[13].filter_scaling = "2";
filters[14].name = "Linear3";
filters[14].filter = "Linear";
filters[14].filter_scaling = "3";
filters[14].driver = "D3D9";
filters[15].name = "Linear4";
filters[15].filter = "Linear";
filters[15].filter_scaling = "4";
filters[15].driver = "D3D9";
filters[16].name = "LinearMax";
filters[16].filter = "Linear";
filters[16].filter_scaling = "max";
filters[16].driver = "D3D9";
lstFilter.Clear(); // Clear the Listbox first
// Fill in the Listbox
int i = 0;
while (i < FILTER_MAX) {
if (filters[i].driver == driver) {
lstFilter.AddItem(filters[i].name);
}
i++;
}
// Search for the Array[ID] and select it in the ListBox
int id = 0;
while (id < FILTER_MAX) {
if ((filters[id].filter == filter) && (filters[id].filter_scaling == filter_scaling) && (filters[id].driver == driver)) {
lstFilter.SelectedIndex = id;
lstFilter.TopItem = id;
lstFilter.ScrollUp(); // Bring it to the center ;)
}
id++;
}
Hmm, yes, sorry about that. I created this post while I was in class and didn't have access to AGS. I forgot that since the two GfxFilter arrays are actually arrays of pointers that the individual items in the arrays also have to be initialized.
And then I keep getting segmentation faults when trying to use StrCopy on the item's char[200] arrays, although I can manually copy them in a simple for loop. It now occurs to me that AGS never did allow old-style strings as members of a struct, so I wonder if there is some underlying cause as to why it can't read the address of the array properly. In any case, I redact my proposed solution as it doesn't actually work. Sorry again for the confusion.