bool TCOD_bsp_traverse_level_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData) { TCOD_list_t stack=TCOD_list_new(); TCOD_list_push(stack,node); while ( ! TCOD_list_is_empty(stack) ) { TCOD_bsp_t *node=(TCOD_bsp_t *)TCOD_list_get(stack,0); TCOD_list_remove(stack,node); if ( TCOD_bsp_left(node) ) TCOD_list_push(stack,TCOD_bsp_left(node)); if ( TCOD_bsp_right(node) ) TCOD_list_push(stack,TCOD_bsp_right(node)); if (!listener(node,userData)) { TCOD_list_delete(stack); return false; } } TCOD_list_delete(stack); return true; }
void sensor_visobjs_push(TCOD_list_t l, Object o) { //push if not present Object o2 = sensor_visobjs_member(l, o); if(!o2) { TCOD_list_push(l, o); } }
/* fill the pointed list with syllable data by extracting tokens */ void namegen_populate_list (char * source, TCOD_list_t list, bool wildcards) { size_t len = strlen(source); size_t i = 0; char * token = malloc(strlen(source)+1); /* tokens will typically be many and very short, but let's be cautious. What if the entire string is a single token?*/ memset(token,'\0',strlen(source)+1); do { /* do the tokenising using an iterator immitation :) */ char * it = source + i; /* append a normal character */ if ((*it >= 'a' && *it <= 'z') || (*it >= 'A' && *it <= 'Z') || *it == '\'' || *it == '-') strncat(token,it,1); /* special character */ else if (*it == '/') { if (wildcards == true) strncat(token,it++,2); else strncat(token,++it,1); i++; } /* underscore is converted to space */ else if (*it == '_') { if (wildcards == true) strncat(token,it,1); else strcat(token," "); } /* add wildcards if they are allowed */ else if (wildcards == true && (*it == '$' || *it == '%' || (*it >= '0' && *it <= '9'))) strncat(token,it,1); /* all other characters are treated as separators and cause adding the current token to the list */ else if (strlen(token) > 0) { TCOD_list_push(list,TCOD_strdup(token)); memset(token,'\0',strlen(source)+1); } } while (++i <= len); free(token); }
static void check_quadrant(map_t *m,int startX,int startY,int dx, int dy, int extentX,int extentY, bool light_walls) { TCOD_list_t active_views=TCOD_list_new(); line_t shallow_line= {offset,limit,extentX*STEP_SIZE,0}; line_t steep_line= {limit,offset,0,extentY*STEP_SIZE}; int maxI=extentX+extentY,i=1; view_t *view= &views[startX+startY*m->width]; view->shallow_line=shallow_line; view->steep_line=steep_line; view->shallow_bump=NULL; view->steep_bump=NULL; TCOD_list_push(active_views,view); current_view=(view_t **)TCOD_list_begin(active_views); while ( i != maxI+1 && ! TCOD_list_is_empty(active_views) ) { int startJ=MAX(i-extentX,0); int maxJ=MIN(i,extentY); int j=startJ; while ( j != maxJ+1 && ! TCOD_list_is_empty(active_views) && current_view != (view_t **)TCOD_list_end(active_views) ) { int x=(i - j)*STEP_SIZE; int y=j*STEP_SIZE; visit_coords(m,startX,startY,x,y,dx,dy,active_views, light_walls); j++; } i++; current_view=(view_t **)TCOD_list_begin(active_views); } TCOD_list_delete(active_views); }
/* add a coordinate pair in the heap so that the heap root always contains the minimum A* score */ static void heap_add(TCOD_path_data_t *path, TCOD_list_t heap, int x, int y) { /* append the new value to the end of the heap */ uintptr off=x+y*path->w; TCOD_list_push(heap,(void *)off); /* bubble the value up to its real position */ heap_sift_up(path,heap); }
bool TCOD_path_compute(TCOD_path_t p, int ox,int oy, int dx, int dy) { TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return false; path->ox=ox; path->oy=oy; path->dx=dx; path->dy=dy; TCOD_list_clear(path->path); TCOD_list_clear(path->heap); if ( ox == dx && oy == dy ) return true; /* trivial case */ /* check that origin and destination are inside the map */ TCOD_IFNOT((unsigned)ox < (unsigned)path->w && (unsigned)oy < (unsigned)path->h) return false; TCOD_IFNOT((unsigned)dx < (unsigned)path->w && (unsigned)dy < (unsigned)path->h) return false; /* initialize djikstra grids */ memset(path->grid,0,sizeof(float)*path->w*path->h); memset(path->prev,NONE,sizeof(dir_t)*path->w*path->h); path->heur[ ox + oy * path->w ] = 1.0f; /* anything != 0 */ TCOD_path_push_cell(path,ox,oy); /* put the origin cell as a bootstrap */ /* fill the djikstra grid until we reach dx,dy */ TCOD_path_set_cells(path); if ( path->grid[dx + dy * path->w] == 0 ) return false; /* no path found */ /* there is a path. retrieve it */ do { /* walk from destination to origin, using the 'prev' array */ int step=path->prev[ dx + dy * path->w ]; TCOD_list_push(path->path,(void *)(uintptr)step); dx -= dirx[step]; dy -= diry[step]; } while ( dx != ox || dy != oy ); return true; }
static void message(struct engine *engine, const TCOD_color_t col, const char *text, ...) { TCOD_list_t log = engine->gui->log; /* Build the text */ va_list ap; char buf[128]; va_start(ap, text); vsprintf(buf, text, ap); va_end(ap); char *line_begin = buf; char *line_end; do { /* make room for the new message */ if (TCOD_list_size(log) == MSG_HEIGHT) { struct message *to_remove = TCOD_list_get(log, 0); TCOD_list_remove(log, to_remove); free(to_remove); } // detect end of the line line_end = strchr(line_begin, '\n'); if (line_end) *line_end = '\0'; // add a new message to the log struct message *msg; mkmessage(&msg, line_begin, col); TCOD_list_push(log, msg); /* go to next line */ line_begin = line_end + 1; } while (line_end); }
/* retrieve the list of all available syllable set names */ TCOD_list_t TCOD_namegen_get_sets (void) { TCOD_list_t l = TCOD_list_new(); namegen_t ** it; for (it = (namegen_t**)TCOD_list_begin(namegen_generators_list); it < (namegen_t**)TCOD_list_end(namegen_generators_list); it++) TCOD_list_push(l,(const void*)((*it)->name)); return l; }
void sensor_push_stimulus(Sensor s, Stimulus stim) { mapVec pt, sz; perception *newVis; perception *snewVis = s->vistiles; perception newPerception; bool litAndVisible; Object o; Map m = s->map; mapVec borig=s->borig, bsz=s->bsz; switch(stimulus_type(stim)) { case StimTileLitChange: case StimTileVisChange: newVis = stimulus_tile_sight_change_get_new_perceptmap(stim); pt = stimulus_tile_sight_change_get_position(stim); sz = stimulus_tile_sight_change_get_size(stim); for(int z = pt.z; z < pt.z+sz.z; z++) { for(int y = pt.y; y < pt.y+sz.y; y++) { for(int x = pt.x; x < pt.x+sz.x; x++) { int stimIndex = tile_index(x, y, z, map_size(m), pt, sz); int visIndex = tile_index(x, y, z, map_size(m), borig, bsz); snewVis[visIndex] = newVis[stimIndex]; } } } break; case StimObjLitChange: case StimObjVisChange: case StimObjMoved: //is the object in newVis? if so, put it into oldVis; if not, make sure it isn't in oldVis. //do this search by _ID_, not by identity //are the new flags good? if so, be sure the object is in vis. otherwise, be sure it's not in vis. if(sensor_visobjs_contains(s->visObjects, o)) { sensor_visobjs_push(s->oldVisObjects, o); } else { sensor_visobjs_remove(s->oldVisObjects, o); } newPerception = stimulus_obj_sight_change_get_new_perception(stim); litAndVisible = map_item_visible(newPerception); if(litAndVisible) { if(!sensor_visobjs_contains(s->visObjects, o)) { sensor_visobjs_push(s->visObjects, o); } } else { if(sensor_visobjs_contains(s->visObjects, o)) { sensor_visobjs_remove(s->visObjects, o); } } break; case StimGeneric: default: break; } TCOD_list_push(s->stimuli, stim); }
void sensor_sense(Sensor s) { Map m = s->map; mapVec pos=s->borig, sz=s->bsz; memset(s->vistiles, 0, sz.x*sz.y*sz.z*sizeof(perception)); map_get_visible_tiles(m, s->vistiles, s->volume, pos, sz); Stimulus vistiles = stimulus_init_tile_vis_change(stimulus_new(), s->vistiles, pos, sz); // TCOD_console_print_left(NULL, 0, 20, "p {%f, %f, %f}, s {%f, %f, %f}", pos.x, pos.y, pos.z, sz.x, sz.y, sz.z); TCOD_list_push(s->stimuli, vistiles); TCOD_list_t oldObjList = s->visObjects; //one ago s->visObjects = s->oldVisObjects; //two ago TCOD_list_clear(s->visObjects); s->oldVisObjects = oldObjList; map_get_visible_objects(m, s->visObjects, s->vistiles, pos, sz); //remove the old objects Object o; mapVec pt; int index; Stimulus visobj; for(int i = 0; i < TCOD_list_size(s->oldVisObjects); i++) { o = TCOD_list_get(s->oldVisObjects, i); if(!TCOD_list_contains(s->visObjects, o)) { //not visible anymore //this isn't quite right, really, using percept_none here visobj = stimulus_init_obj_vis_change(stimulus_new(), o, percept_none, object_context(o)); TCOD_list_push(s->stimuli, visobj); } } //add the new objects for(int i = 0; i < TCOD_list_size(s->visObjects); i++) { o = TCOD_list_get(s->visObjects, i); if(!TCOD_list_contains(s->oldVisObjects, o)) { //not visible before pt = object_position(o); index = tile_index(pt.x, pt.y, pt.z, map_size(m), pos, sz); visobj = stimulus_init_obj_vis_change(stimulus_new(), o, s->vistiles[index], object_context(o)); TCOD_list_push(s->stimuli, visobj); } } }
TCOD_list_t TCOD_sys_get_directory_content(const char *path, const char *pattern) { TCOD_list_t list=TCOD_list_new(); #ifdef TCOD_WINDOWS WIN32_FIND_DATA FileData; HANDLE hList; char dname[ 512 ]; sprintf(dname, "%s\\*",path); hList = FindFirstFile(dname, &FileData); if (hList == INVALID_HANDLE_VALUE) { return list; } do { if ( ! (strcmp(FileData.cFileName,".") == 0 || strcmp(FileData.cFileName,"..") == 0 ) ) { if ( filename_match(FileData.cFileName,pattern) ) TCOD_list_push(list,TCOD_strdup(FileData.cFileName)); } } while ( FindNextFile(hList, &FileData) ); FindClose(hList); #else DIR *dir = opendir(path); struct dirent *dirent = NULL; if ( ! dir ) return list; while ( ( dirent = readdir(dir) ) ) { if ( ! (strcmp(dirent->d_name,".") == 0 || strcmp(dirent->d_name,"..") == 0 ) ) { if ( filename_match(dirent->d_name,pattern) ) TCOD_list_push(list,strdup(dirent->d_name)); } } closedir(dir); #endif return list; }
/* run the parser */ void namegen_parser_run (const char * filename) { char ** it; /* prepare the parser --- this will be executed only once */ namegen_parser_prepare(); if (parsed_files == NULL) parsed_files = TCOD_list_new(); if (TCOD_list_size(parsed_files) > 0) { for (it = (char **)TCOD_list_begin(parsed_files); it != (char **)TCOD_list_end(parsed_files); it++) if (strcmp(*it,filename) == 0) return; } /* if the file hasn't been parsed yet, add its name to the list so that it's never parsed twice */ TCOD_list_push(parsed_files,(const void *)TCOD_strdup(filename)); /* run the parser */ TCOD_parser_run(namegen_parser,filename,&namegen_listener); }
bool namegen_parser_end_struct(TCOD_parser_struct_t str, const char *name) { /* if there's no syllable set by this name, add it to the list */ if (namegen_generator_check(name) == false) { parser_data->name = TCOD_strdup(name); parser_output = namegen_generator_new(); namegen_populate(parser_output,parser_data); parser_output->random = namegen_random; if (namegen_generators_list == NULL) namegen_generators_list = TCOD_list_new(); TCOD_list_push(namegen_generators_list, (const void*)parser_output); } /* free the allocated memory to prevent a memory leak */ namegen_syllables_delete(parser_data); return true; }
static void processRay(map_t *m, TCOD_list_t perim, ray_data_t *new_ray, ray_data_t *input_ray) { if ( new_ray ) { int mapx=origx+new_ray->xloc; int mapy=origy+new_ray->yloc; int newrayidx; newrayidx=mapx+mapy*m->width; if ( new_ray->yloc == input_ray->yloc ) new_ray->xinput=input_ray; else new_ray->yinput=input_ray; if (! new_ray->added) { TCOD_list_push(perim,new_ray); new_ray->added=true; raymap[newrayidx] = new_ray; } } }
/* this is the slow part, when we change the heuristic of a cell already in the heap */ static void heap_reorder(TCOD_path_data_t *path, uint32 offset) { uintptr *array=(uintptr *)TCOD_list_begin(path->heap); uintptr *end=(uintptr *)TCOD_list_end(path->heap); uintptr *cur=array; /* find the node corresponding to offset ... SLOW !! */ while (cur != end) { if (*cur == offset ) break; cur++; } if ( cur == end ) return; /* remove it... SLOW !! */ TCOD_list_remove_iterator(path->heap,(void **)cur); /* put it back on the heap */ TCOD_list_push(path->heap,(void *)(uintptr)offset); /* bubble the value up to its real position */ heap_sift_up(path,path->heap); }
/* create a path */ bool TCOD_dijkstra_path_set (TCOD_dijkstra_t dijkstra, int x, int y) { dijkstra_t * data = (dijkstra_t*)dijkstra; int px = x, py = y; static int dx[9] = { -1, 0, 1, 0, -1, 1, 1, -1, 0 }; static int dy[9] = { 0, -1, 0, 1, -1, -1, 1, 1, 0 }; unsigned int distances[9]; int lowest_index = 666; TCOD_IFNOT(data != NULL) return false; TCOD_IFNOT((unsigned)x < (unsigned)data->width && (unsigned)y < (unsigned)data->height) return false; // check that destination is reachable if ( dijkstra_get_int_distance(data,x,y) == 0xFFFFFFFF ) return false; TCOD_list_clear(data->path); do { unsigned int lowest = 0xFFFFFFFF; int i; TCOD_list_push(data->path,(const void*)(uintptr)((py * data->width) + px)); for(i=0;i<8;i++) { int cx = px + dx[i]; int cy = py + dy[i]; if ((unsigned)cx < (unsigned)data->width && (unsigned)cy < (unsigned)data->height) distances[i] = dijkstra_get_int_distance(data,cx,cy); else distances[i] = 0xFFFFFFFF; } distances[8] = dijkstra_get_int_distance(data,px,py); for(i=0;i<9;i++) if (distances[i] < lowest) { lowest = distances[i]; lowest_index = i; } px += dx[lowest_index]; py += dy[lowest_index]; } while (lowest_index != 8); // remove the last step TCOD_list_pop(data->path); return true; }
void TCOD_list_add_all(TCOD_list_t l, TCOD_list_t l2) { void **curElt; for ( curElt = TCOD_list_begin(l2); curElt != TCOD_list_end(l2); curElt ++) { TCOD_list_push(l,*curElt); } }
void loader_add_move_flag(Loader l, char *moveFlag) { TCOD_list_push(l->moveFlags, moveFlag); }
void structrecord_add_flag(StructRecord sr, char *flag) { TCOD_list_push(sr->flags, strdup(flag)); }
void structrecord_add_prop(StructRecord sr, Prop p) { TCOD_list_push(sr->props, p); }
void structrecord_add_child(StructRecord sr, StructRecord kid) { TCOD_list_push(sr->children, kid); structrecord_set_parent(kid, sr); }