1 registered members (TipmyPip),
18,449
guests, and 6
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
problem with struct strings...
#403882
06/27/12 19:42
06/27/12 19:42
|
Joined: Mar 2008
Posts: 2,247 Baden Württemberg, Germany
Espér
OP
Expert
|
OP
Expert
Joined: Mar 2008
Posts: 2,247
Baden Württemberg, Germany
|
hi there.. i´ve written this functions to fill and erase tiles in my 3D Editor:
void fill_tile(VECTOR* positchange, var tool)
{
var f_handle;
VECTOR overgiv_pos;
wait(1);
vec_set(overgiv_pos, positchange);
if(tool == 0)
{
//Erstelle Grundwerte
blocks[positchange.x][positchange.y][positchange.z].filename = placing_filename;
blocks[positchange.x][positchange.y][positchange.z].setupname = placing_setupname;
blocks[positchange.x][positchange.y][positchange.z].contentname = actual_contentpack;
blocks[positchange.x][positchange.y][positchange.z].obj = ent_create(placing_filename, vector(positchange.x*editor_settings.tile_size, positchange.y*editor_settings.tile_size, positchange.z*editor_settings.tile_size-25), NULL);
blocks[positchange.x][positchange.y][positchange.z].obj.pan = preview_entity.pan;
blocks[positchange.x][positchange.y][positchange.z].obj. x_tile = positchange.x;
blocks[positchange.x][positchange.y][positchange.z].obj. y_tile = positchange.y;
blocks[positchange.x][positchange.y][positchange.z].obj. z_tile = positchange.z;
blocks[positchange.x][positchange.y][positchange.z].positionx = positchange.x;
blocks[positchange.x][positchange.y][positchange.z].positiony = positchange.y;
blocks[positchange.x][positchange.y][positchange.z].positionz = positchange.z;
blocks[positchange.x][positchange.y][positchange.z].obj_pan = blocks[positchange.x][positchange.y][positchange.z].obj.pan;
//lade Setupdatei
if(file_exists(blocks[positchange.x][positchange.y][positchange.z].setupname))
{
file_cpy("dmt.nymph", blocks[positchange.x][positchange.y][positchange.z].setupname);
f_handle = file_open_read("dmt.nymph");
nymph_reader = 0;
while(nymph_reader != -1)
{
nymph_filer = 0;
str_cpy(setupstring, "");
file_str_read(f_handle, setupstring);
//Ist SHADOW auf true?
if(str_stri(setupstring, "shadow=true"))
{set(blocks[positchange.x][positchange.y][positchange.z].obj, SHADOW);}
//Wird specBump Shader genutzt?
else if(str_stri(setupstring, "material=mtl_specBump"))
{blocks[positchange.x][positchange.y][positchange.z].obj.material = mtl_specBump;}
//Nutzt das Objekt 180° Rotationsalpha?
else if(str_stri(setupstring, "rotatealpha=true"))
{blocks[positchange.x][positchange.y][positchange.z].obj_rotatealpha = 1;set(blocks[positchange.x][positchange.y][positchange.z].obj, TRANSLUCENT);}
//Ist Das Ende der Nymph datei erreicht?
else if(str_stri(setupstring, "#end"))
{nymph_reader = -1;}
}
file_close(f_handle);
file_delete("dmt.nymph");
}
//Führe Rotationsalpha aus
blocks[positchange.x][positchange.y][positchange.z].obj.alpha = 100;
if(blocks[positchange.x][positchange.y][positchange.z].obj_rotatealpha == 1 && blocks[positchange.x][positchange.y][positchange.z].obj.pan > 160 && blocks[positchange.x][positchange.y][positchange.z].obj.pan < 200)
{blocks[positchange.x][positchange.y][positchange.z].obj.alpha = 60;}
//Selektiere objekt
selected_obj = blocks[positchange.x][positchange.y][positchange.z].obj;
//Schließe das Feld
blocks[positchange.x][positchange.y][positchange.z].locked = 1;
}
else if(tool == 1) //Fülleimer
{
load_empty(1, positchange.x, positchange.y, positchange.z);
wait_for(load_empty); wait(1);
//Erstelle Grundwerte
error("da1");
blocks[positchange.x][positchange.y][positchange.z].filename = placing_filename;
error("da2");
blocks[positchange.x][positchange.y][positchange.z].setupname = placing_setupname;
blocks[positchange.x][positchange.y][positchange.z].contentname = actual_contentpack;
blocks[positchange.x][positchange.y][positchange.z].obj = ent_create(placing_filename, vector(positchange.x*editor_settings.tile_size, positchange.y*editor_settings.tile_size, positchange.z*editor_settings.tile_size-25), NULL);
blocks[positchange.x][positchange.y][positchange.z].obj.pan = preview_entity.pan;
blocks[positchange.x][positchange.y][positchange.z].obj. x_tile = positchange.x;
blocks[positchange.x][positchange.y][positchange.z].obj. y_tile = positchange.y;
blocks[positchange.x][positchange.y][positchange.z].obj. z_tile = positchange.z;
blocks[positchange.x][positchange.y][positchange.z].positionx = positchange.x;
blocks[positchange.x][positchange.y][positchange.z].positiony = positchange.y;
blocks[positchange.x][positchange.y][positchange.z].positionz = positchange.z;
blocks[positchange.x][positchange.y][positchange.z].obj_pan = blocks[positchange.x][positchange.y][positchange.z].obj.pan;
//lade Setupdatei
if(file_exists(blocks[positchange.x][positchange.y][positchange.z].setupname))
{
file_cpy("dmt.nymph", blocks[positchange.x][positchange.y][positchange.z].setupname);
f_handle = file_open_read("dmt.nymph");
nymph_reader = 0;
while(nymph_reader != -1)
{
nymph_filer = 0;
str_cpy(setupstring, "");
file_str_read(f_handle, setupstring);
//Ist SHADOW auf true?
if(str_stri(setupstring, "shadow=true"))
{set(blocks[positchange.x][positchange.y][positchange.z].obj, SHADOW);}
//Wird specBump Shader genutzt?
else if(str_stri(setupstring, "material=mtl_specBump"))
{blocks[positchange.x][positchange.y][positchange.z].obj.material = mtl_specBump;}
//Nutzt das Objekt 180° Rotationsalpha?
else if(str_stri(setupstring, "rotatealpha=true"))
{blocks[positchange.x][positchange.y][positchange.z].obj_rotatealpha = 1;set(blocks[positchange.x][positchange.y][positchange.z].obj, TRANSLUCENT);}
//Ist Das Ende der Nymph datei erreicht?
else if(str_stri(setupstring, "#end"))
{nymph_reader = -1;}
}
file_close(f_handle);
file_delete("dmt.nymph");
}
//Führe Rotationsalpha aus
blocks[positchange.x][positchange.y][positchange.z].obj.alpha = 100;
if(blocks[positchange.x][positchange.y][positchange.z].obj_rotatealpha == 1 && blocks[positchange.x][positchange.y][positchange.z].obj.pan > 160 && blocks[positchange.x][positchange.y][positchange.z].obj.pan < 200)
{blocks[positchange.x][positchange.y][positchange.z].obj.alpha = 60;}
//Selektiere objekt
selected_obj = blocks[positchange.x][positchange.y][positchange.z].obj;
//Schließe das Feld
blocks[positchange.x][positchange.y][positchange.z].locked = 1;
wait(1);
positchange.x += 1;
positchange.x = clamp(positchange.x, 0, editor_settings.map_sizex);
if(blocks[positchange.x][positchange.y][positchange.z].locked == 0)
{fill_tile(vector(positchange.x, positchange.y, positchange.z), 1);}
else
{
if(str_cmpi(blocks[positchange.x][positchange.y][positchange.z].filename, placing_filename) == 0)
{
fill_tile(vector(positchange.x, positchange.y, positchange.z), 1);
}
}
vec_set(positchange, overgiv_pos);
positchange.x -= 1;
positchange.x = clamp(positchange.x, 0, editor_settings.map_sizex);
if(blocks[positchange.x][positchange.y][positchange.z].locked == 0)
{fill_tile(vector(positchange.x, positchange.y, positchange.z), 1);}
else
{
if(str_cmpi(blocks[positchange.x][positchange.y][positchange.z].filename, placing_filename) == 0)
{
fill_tile(vector(positchange.x, positchange.y, positchange.z), 1);
}
}
vec_set(positchange, overgiv_pos);
positchange.y += 1;
positchange.y = clamp(positchange.y, 0, editor_settings.map_sizey);
if(blocks[positchange.x][positchange.y][positchange.z].locked == 0)
{fill_tile(vector(positchange.x, positchange.y, positchange.z), 1);}
else
{
if(str_cmpi(blocks[positchange.x][positchange.y][positchange.z].filename, placing_filename) == 0)
{
fill_tile(vector(positchange.x, positchange.y, positchange.z), 1);
}
}
vec_set(positchange, overgiv_pos);
positchange.y -= 1;
positchange.y = clamp(positchange.y, 0, editor_settings.map_sizey);
if(blocks[positchange.x][positchange.y][positchange.z].locked == 0)
{fill_tile(vector(positchange.x, positchange.y, positchange.z), 1);}
else
{
if(str_cmpi(blocks[positchange.x][positchange.y][positchange.z].filename, placing_filename) == 0)
{
fill_tile(vector(positchange.x, positchange.y, positchange.z), 1);
}
}
vec_set(positchange, overgiv_pos);
}
}
void load_empty(var emptymode, var igox, var igoy, var igoz)
{
if(emptymode == 0)
{
var ix,iy,iz;
for(iz=0; iz<editor_settings.mapheight; iz++)
{
for(iy=0; iy<editor_settings.map_sizey; iy++)
{
for(ix=0; ix<editor_settings.map_sizex; ix++)
{
blocks[ix][iy][iz].locked = 0;
blocks[ix][iy][iz].team = 0;
blocks[ix][iy][iz].passable = 0;
blocks[ix][iy][iz].explored = 0;
blocks[ix][iy][iz].typus = 0;
blocks[ix][iy][iz].positionx = 0;
blocks[ix][iy][iz].positiony = 0;
blocks[ix][iy][iz].positionz = 0;
blocks[ix][iy][iz].obj_pan = 0;
blocks[ix][iy][iz].obj_rotatealpha = 0;
blocks[ix][iy][iz].objektname = "";
blocks[ix][iy][iz].filename = "";
blocks[ix][iy][iz].setupname = "";
blocks[ix][iy][iz].contentname = "";
blocks[igox][igoy][igoz].obj = NULL;
}
}
}
}
else if(emptymode == 1)
{
if(blocks[igox][igoy][igoz].obj != NULL)
{
reset(blocks[igox][igoy][igoz].obj, SHADOW);
ent_remove(blocks[igox][igoy][igoz].obj);
}
blocks[igox][igoy][igoz].locked = 0;
blocks[igox][igoy][igoz].team = 0;
blocks[igox][igoy][igoz].passable = 0;
blocks[igox][igoy][igoz].explored = 0;
blocks[igox][igoy][igoz].typus = 0;
blocks[igox][igoy][igoz].positionx = 0;
blocks[igox][igoy][igoz].positiony = 0;
blocks[igox][igoy][igoz].positionz = 0;
blocks[igox][igoy][igoz].obj_pan = 0;
blocks[igox][igoy][igoz].obj_rotatealpha = 0;
blocks[igox][igoy][igoz].objektname = "";
blocks[igox][igoy][igoz].filename = "";
blocks[igox][igoy][igoz].setupname = "";
blocks[igox][igoy][igoz].contentname = "";
}
}
i call it this way:
load_empty(0, 0, 0, 0); //Load defaults at startup
load_empty(1, x, y, z); //erase a tile
fill_tile(vector(x, y, z), chosen_tool); //fill a tile
chosen_tool can be 0 = pencil 1 = filling bucket My problem now: When i use the pencil, everything works great. But when i use the filling bucket to fill a framed plane, i got a crash in fill_tile problem line is this:
error("da1");
blocks[positchange.x][positchange.y][positchange.z].filename = placing_filename;
error("da2");
cause "da1" is shown.. the second not.. Am i doing something wrong? I tried to use a "if(blabla != NULL)" for each stat.. but it´s still the same.. ._.
|
|
|
Re: problem with struct strings...
[Re: Espér]
#403930
06/28/12 14:55
06/28/12 14:55
|
Joined: Nov 2002
Posts: 913 Berlin, Germany
SchokoKeks
User
|
User
Joined: Nov 2002
Posts: 913
Berlin, Germany
|
I've got admit that I didn't look through all your text. But are you sure you want to set STRING* with "=" ? especially this is very dangerous:
blocks[ix][iy][iz].objektname = "";
The literal "" (which is a char*) is stored once in memory, and its adress is copied to all blocks. That means that all blocks now share this single string, if you would change it on one block it would change the string on all blocks. EDIT: it is also not sure if that char* gets correctly transfromed to a STRING*, wouldn't work in C but might work in lite-C. Which brings is to another problem: I don't know if you are allowed to change a literal in lite-c. In normal C you are definatelly not allowed to do that. It works differently on STRING* definitions i suppose:
STRING *globalstring = "lool";
Thats perfectly valid in lite-C (In c it wouldn't be). So what's the buttom line? use str_create for initializing the string once and then use str_cpy to change it:
blocks[ix][iy][iz].objektname = str_create("");
str_cpy(blocks[positchange.x][positchange.y][positchange.z].setupname, placing_setupname);
if you unload the level, use ptr_remove once to destry the string objects you have created with str_create or else I'll get a memory leak.
Last edited by SchokoKeks; 06/28/12 15:17.
|
|
|
Re: problem with struct strings...
[Re: SchokoKeks]
#403946
06/28/12 21:51
06/28/12 21:51
|
Joined: Mar 2008
Posts: 2,247 Baden Württemberg, Germany
Espér
OP
Expert
|
OP
Expert
Joined: Mar 2008
Posts: 2,247
Baden Württemberg, Germany
|
i´ve done that 1st, Loading time increased dramatically... a 50x50x5 map loads for nearly 40 seconds ._. 2nd,
str_cpy(blocks[positchange.x][positchange.y][positchange.z].filename, placing_filename);
brings an invalid function argument ._.
|
|
|
Re: problem with struct strings...
[Re: Espér]
#403948
06/28/12 22:48
06/28/12 22:48
|
Joined: Nov 2002
Posts: 913 Berlin, Germany
SchokoKeks
User
|
User
Joined: Nov 2002
Posts: 913
Berlin, Germany
|
Could you also post the definition of the struct? Also: using structs as an array always gives me compiler errors in A7, there you have to do:
(blocks[positchange.x][positchange.y][positchange.z]).filename
if you want to access a struct member. Maybe thats no longer necessary in A8? It's very natural that using str_create takes a lot longer, Thats 12500 malloc calls for your level whenever you create or change the strings. Although 40 seconds is pretty long.
|
|
|
Re: problem with struct strings...
[Re: SchokoKeks]
#403949
06/28/12 22:51
06/28/12 22:51
|
Joined: Mar 2008
Posts: 2,247 Baden Württemberg, Germany
Espér
OP
Expert
|
OP
Expert
Joined: Mar 2008
Posts: 2,247
Baden Württemberg, Germany
|
typedef struct
{
var locked; //Switch if a block is placed or not
var team; //Wich Team is the block owner (MP)
var passable; //Is the block passable or not?
var explored; //Is there fog of war or not?
var typus; //typus_earth, typus_fire, typus_water
var obj_rotatealpha; //Turns the Block to alpha=60 if PAN is 180°?
var positionx; //The 3 block positions in this struct array
var positiony;
var positionz;
var obj_pan; //The object PAN rotation
char* objektname; //The name of the Block
char* filename; //The filename of the Block
char* setupname; //The filename of the PAK file of the Block
char* contentname; //The name of the WRS file the block is located in
ENTITY* obj; //The Block object itself
} BLOCK;
|
|
|
Re: problem with struct strings...
[Re: Espér]
#403951
06/28/12 23:11
06/28/12 23:11
|
Joined: Nov 2002
Posts: 913 Berlin, Germany
SchokoKeks
User
|
User
Joined: Nov 2002
Posts: 913
Berlin, Germany
|
lol, that changes everything. Thought you were using STRING* instead of char*. then, str_create and str_cpy are of course the wrong functions to use. you'll have to use sys_malloc to assign memory space to those char*. you can then copy content into them with the standard c function strcpy, but be aware of buffer overflows that can happen very easily. The question is: What do you actually want to do with this? If you want to speed things up, you should make another struct that encodes all possible block types and move some of the struct members to that:
typedef struct
{
var typus;
var obj_rotatealpha;
STRING* objektname; //The name of the Block
STRING* filename; //The filename of the Block
STRING* setupname; //The filename of the PAK file of the Block
STRING* contentname; //The name of the WRS file the block is located in
} BLOCK_TYPE;
typedef struct
{
var block_type_id; // points to an index in a BLOCK_TYPE array
var locked; //Switch if a block is placed or not
var team; //Wich Team is the block owner (MP)
var passable; //Is the block passable or not?
var explored; //Is there fog of war or not?
var positionx; //The 3 block positions in this struct array
var positiony;
var positionz;
var obj_pan; //The object PAN rotation
ENTITY* obj; //The Block object itself
} BLOCK;
You could still load the BLOCK_TYPE list from a file, making it moddable. Another advantage would be a lot less memory usage, and you could save the blocks into a binary file with file_save/file_load or file_asc_read/file_asc_write.
Last edited by SchokoKeks; 06/28/12 23:16. Reason: changed char* to STRING* in struct
|
|
|
Re: problem with struct strings...
[Re: Espér]
#403953
06/28/12 23:27
06/28/12 23:27
|
Joined: Nov 2002
Posts: 913 Berlin, Germany
SchokoKeks
User
|
User
Joined: Nov 2002
Posts: 913
Berlin, Germany
|
But are there no two tiles that have the same model/sound/bmap? If every tile has its very own model/sound/bmap, then there is no way to get faster than these 40 seconds.
your current method of using "=" to char* actually works, but this way you can only use names you have entered somewhere in your script. That might be okay though. If this special line crashes, then how is placing_filename defined and where is it changed?
EDIT: btw: are you saving or loading levels from files?
Last edited by SchokoKeks; 06/28/12 23:28.
|
|
|
Re: problem with struct strings...
[Re: SchokoKeks]
#403956
06/29/12 07:00
06/29/12 07:00
|
Joined: Mar 2008
Posts: 2,247 Baden Württemberg, Germany
Espér
OP
Expert
|
OP
Expert
Joined: Mar 2008
Posts: 2,247
Baden Württemberg, Germany
|
actually i don´t load maps from files.. cause i code the mapping first, and then the saving/loading script, wich will just runthrough the blocks struct and save its specs. But i load Models, Sounds..etc with this script:
void load_files(STRING* pakname)
{
STRING* openpak = str_create("");
str_cat(openpak, pakname);
str_cat(openpak, ".wrs");
str_cpy(actual_contentpack, openpak);
var ilt, objectcount, cutterlen;
entitycounter = 0;
if(pan_objectlist != NULL)
{pan_remove(pan_objectlist);}
wait(1);
pan_objectlist = pan_create("flags=SHOW;", 90);
pan_objectlist.pos_y = 64; pan_objectlist.pos_x = 0;
pan_objectlist.red = 1; pan_objectlist.green = 1; pan_objectlist.blue = 1;
pan_objectlist.size_y = 24;
set(pan_objectlist, SHOW);
for(ilt=0; ilt<4001; ilt++)
{
str_cpy((ordnerinhalt.pstring)[ilt], "");
if(ilt < 2001) //Weil liste nur 2000 Zeilen hat
{
str_cpy((objekteigenschaften.pstring)[ilt], "");
str_cpy((objektnamen.pstring)[ilt], "");
str_cpy((objektdigits.pstring)[entitycounter], "");
}
}
// free(buffer_single);
// buffer_single = file_load(actual_contentpack, NULL, NULL);
// add_resource(buffer_single);
str_trunc(openpak, 3);
str_cat(openpak, "pak");
file_cpy("Modelliste.txt", openpak);
var f_handle = file_open_read("Modelliste.txt");
var copystrings = 0;
var runthrough_list = 0;
while(copystrings == 0)
{
file_str_read(f_handle, (ordnerinhalt.pstring)[runthrough_list]);
if(str_stri((ordnerinhalt.pstring)[runthrough_list], "#end") == 1)
{
copystrings = 1;
}
runthrough_list ++;
}
file_close(f_handle);
file_delete("Modelliste.txt");
for(ilt=0; ilt<4001; ilt++)
{
if((ordnerinhalt.pstring)[ilt] != NULL)
{
if(str_stri((ordnerinhalt.pstring)[ilt], ".mdl") && str_stri((ordnerinhalt.pstring)[ilt], themenname) && str_stri((ordnerinhalt.pstring)[ilt], "Quader") == 0)
{
//objektname (mdl) eintragen
str_cpy((objektnamen.pstring)[entitycounter], (ordnerinhalt.pstring)[ilt]);
//trunc file extention
str_trunc((ordnerinhalt.pstring)[ilt], 3);
//save name without extention in shorter way
str_cpy((objektdigits.pstring)[entitycounter], (ordnerinhalt.pstring)[ilt]);
str_trunc((objektdigits.pstring)[entitycounter], 1);
if(str_len((objektdigits.pstring)[entitycounter]) > MAXIMALE_ZEICHENZAHL)
{
while(str_len((objektdigits.pstring)[entitycounter]) > MAXIMALE_ZEICHENZAHL)
{str_trunc((objektdigits.pstring)[entitycounter], 1);}
str_cat((objektdigits.pstring)[entitycounter], "...");
}
//add the nymph extention
str_cat((ordnerinhalt.pstring)[ilt], "pak");
//frag ob die nymph Datei existiert
if(file_exists((ordnerinhalt.pstring)[ilt]) == 0)
{
error("Es existiert keine PAK Datei zu einem geladenen Objekt!");
}
//Add object to the button list
pan_setdigits(pan_objectlist, 0, 4, 200+entitycounter*24, (objektdigits.pstring)[entitycounter], arialing, 1, ilt);
pan_setbutton(pan_objectlist, 0, 0, 2, 200+entitycounter*24, bm_listbutt_on, bm_listbutt_off, bm_listbutt_over, bm_listbutt_off, call_filename, NULL, call_info);
pan_objectlist.size_y += 24;
//go on to next Object
wait(1);
entitycounter += 1;
auswahlobjekte = ilt+1;
}
}
}
pan_setdigits(pan_objectlist, 0, 10, (200+(entitycounter+1)*24)+4, "NO MORE OBJECTS", arialing_bold, 1, ilt);
}
It loads the file list (a txt-pak file) from the chosen wrs file, readsout the filenames and creates buttons to it. The complete filename list is stored in: to call a file and set placing_filename..etc, i just use the button function:
void call_filename(var butt_num)
{
str_cpy(placing_filename, (objektnamen.pstring)[butt_num-1]);
str_cpy(regive_filename, placing_filename);
str_trunc(placing_filename, 3);
str_cat(placing_filename, "pak");
str_cpy(placing_setupname, "Models\\Map\\");
str_cat(placing_setupname, placing_filename);
str_cpy(placing_filename, (objektnamen.pstring)[butt_num-1]);
ent_morph(preview_entity, placing_filename);
set(preview_entity, PASSABLE | TRANSLUCENT | UNTOUCHABLE);
preview_entity.alpha = 50;
ent_morph(rotate_preview, placing_filename);
rotate_preview.material = mtl_specBump;
}
Last edited by Espér; 06/29/12 07:10.
|
|
|
Re: problem with struct strings...
[Re: Espér]
#403960
06/29/12 11:23
06/29/12 11:23
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
OK then... Once the objektnamen text is filled wih filenames, do you 'keep' it in memory, or do you purge it? BECAUSE, if you keep it, you can simply replace
typedef struct
{
...
char* objektname; //The name of the Block
char* filename; //The filename of the Block
char* setupname; //The filename of the PAK file of the Block
char* contentname; //The name of the WRS file the block is located in
ENTITY* obj; //The Block object itself
} BLOCK;
with
typedef struct
{
...
int objektname_idx; //Index of the name of the Block
int filename_idx; //Index of the filename of the Block
int setupname_idx; //Index of the filename of the PAK file of the Block
int contentname_idx; //Index of the name of the WRS file the block is located in
ENTITY* obj; //The Block object itself
} BLOCK;
And instead of storing a whole char array for every block, you now only need to store the line-number/index-number of its entry within the objektnamen array. Have I made myself clear? Or is further explaination needed?
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
|