/* * city_disasm() */ static void city_disasm(uint8_t cityno) { uint32_t i; b3city_t *city; FILE *fp; uint16_t offset; rangeSkipList = gl_list_create_empty(GL_ARRAY_LIST, NULL, NULL, range_free, 1); city = readCity(cityno); currentLevel.dataStartOffset = city->dataBaseOffset; currentLevel.monsterIndex = city->monsterIndex; currentLevel.codeStartOffset = 0; fp = xfopen(mkCodePath("%s.code", cityList[cityno].name, 0), "wb"); for (i = 0; i < city->dataCount; i++) { offset = city->dataList[i].offset; fprintf(fp, "(%3d, %3d) offset: %04x\n", city->dataList[i].sqE, city->dataList[i].sqN, offset ); } fprintf(fp, "=====================================\n"); #undef DUMP_CODE #ifdef DUMP_CODE dump_btstring(bts_sprintf("%s.dump", cityList[cityno].name), city->codeBuf, 1); #endif disasmCode(fp, city->codeBuf, city->dataBaseOffset); gl_list_free(rangeSkipList); rangeSkipList = NULL; fclose(fp); freeCity(city); }
/** * Top level function for parsing a City PML element * @param str Pointer to a string structure * @return Returns a pointer to a filled in city structure or NULL on failure **/ pCity cityTopLevel( pstring str ) { int lastGood = 0; pCity newCity = NULL; int startIndex = 0; int endIndex = 0; char *temp = NULL; int tempInt = 0; element el; if ( str == NULL ) { goto end; } /// Skip the opening "{" if ( skipOpen( str, 0 ) == 0 ) { goto end; } /// Get the start and end index of the element id getIndex( str, &startIndex); endIndex = skipAlpha(str); if ( endIndex == -1 ) { goto end; } if ( startIndex == endIndex ) { goto end; } temp = copyData( str, startIndex, endIndex ); if ( temp == NULL ) { goto end; } if ( strcmp( temp, "City") != 0 ) { deallocate(temp, cgc_strlen(temp) + 1 ); goto end; } deallocate(temp, cgc_strlen(temp) + 1 ); skipWhiteSpace( str ); if ( !atChar( str, '}') ) { goto end; } incChar( str ); skipWhiteSpace(str); lastGood = str->index; if ( allocate( sizeof(City), 0, (void**)&newCity) != 0 ) { newCity = NULL; goto error; } initCity( newCity ); temp = pullNextElementName( str ); while ( temp != NULL ) { el = elementNameToEnum( temp ); deallocate(temp, cgc_strlen(temp) + 1 ); switch (el) { case name: temp = extractName( str ); if ( temp == NULL ) { goto error; } /// Clear it out bzero( newCity->name, 20 ); /// Copy the name data. It has already been filtered /// for invalid characters. strncpy( newCity->name, temp, 19); /// Free the buffer deallocate( temp, cgc_strlen(temp) + 1 ); temp = NULL; break; case mayor: temp = extractMayor( str ); if ( temp == NULL ) { goto error; } bzero( newCity->mayor, 30 ); #ifdef PATCHED strncpy( newCity->mayor, temp, 29 ); #else strcpy( newCity->mayor, temp ); #endif freeCharPtr( &temp ); break; case url: temp = extractUrl( str ); if ( temp == NULL ) { goto error; } bzero( newCity->url, 30 ); strncpy( newCity->url, temp, 29 ); freeCharPtr( &temp ); break; case border: if ( newCity->border_count >= CITYBORDERMAX) { goto error; } tempInt = newCity->border_count; newCity->borders[ tempInt ] = extractBorder(str); if ( newCity->borders[ tempInt] == NULL ) { goto error; } newCity->border_count++; break; case population: newCity->population = extractPopulation( str ); if ( newCity->population < 0 ) { goto error; } break; default: printf("!!Invalid element ID for City\n"); goto error; break; }; lastGood = str->index; temp = pullNextElementName(str); } if ( skipOpen( str, 1) == 0 ) { goto error; } getIndex( str, &startIndex); endIndex = skipAlpha( str ); if ( endIndex == -1 ) { goto error; } else if ( startIndex == endIndex ) { goto error; } temp = copyData( str, startIndex, endIndex ); if ( temp == NULL ) { goto error; } if ( strcmp( temp, "City") != 0 ) { deallocate(temp, cgc_strlen(temp) + 1 ); goto error; } deallocate( temp, cgc_strlen(temp) + 1 ); skipWhiteSpace(str); if ( !atChar( str, '}') ) { goto error; } incChar(str); goto end; error: if ( newCity ) { freeCity( newCity ); newCity = NULL; } printf("!!Error at: @s\n", str->buffer + lastGood); str->index = lastGood; end: return newCity; }
int cityMenu ( pCity ci ) { int choice = 0; char selection[30]; pBorder pb = NULL; if ( ci == NULL ) { return 0; } while (1) { printf("\nCity: @s\n", ci->name); printf("1) Display City Info\n"); printf("2) Set Mayor\n"); printf("3) Set Url\n"); printf("4) Set Population\n"); printf("5) Add Border\n"); printf("6) Delete City and Exit Menu\n"); printf("7) Exit Menu\n"); printf("Selection: "); bzero( selection, 30 ); receive_until( selection, '\n', 4 ); choice = atoi( selection ); switch (choice) { case 1: printCityInfo( ci ); break; case 2: printf("\n-> "); bzero( selection, 30 ); receive_until( selection, '\n', 29); choice = 0; while ( isalnum(selection[choice]) || selection[choice] == ' ') { ci->mayor[choice] = selection[choice]; choice++; } ci->mayor[choice] = '\x00'; break; case 3: printf("\n-> "); bzero( selection, 30 ); receive_until( selection, '\n', 29 ); /// While it is valid url data copy loop and copy it /// Since the buffer is zeroed and the max received is 29 this loop /// should be safe choice = 0; while( isalnum(selection[choice]) || selection[choice] == ':' || selection[choice] == '.' || selection[choice] == '/') { ci->url[choice] = selection[choice]; choice++; } ci->url[choice] = '\x00'; break; case 4: printf("\n-> "); bzero( selection, 30); receive_until( selection, '\n', 29 ); ci->population = atoi( selection); break; case 5: if ( ci->border_count > CITYBORDERMAX ) { printf("Max Borders\n"); break; } if ( allocate( sizeof(Border), 0, (void**)&pb) != 0 ) { pb = NULL; continue; } printf("Lat Start: "); bzero(selection, 30 ); receive_until( selection, '\n', 19 ); pb->latStart = atof(selection); printf("Long Start: "); bzero(selection, 30 ); receive_until( selection, '\n', 19 ); pb->lngStart = atof(selection); printf("Lat End: "); bzero(selection, 30 ); receive_until( selection, '\n', 19 ); pb->latEnd = atof(selection); printf("Long End: "); bzero(selection, 30 ); receive_until( selection, '\n', 19 ); pb->lngEnd = atof(selection); ci->borders[ ci->border_count ] = pb; ci->border_count++; break; case 6: freeCity(ci); return 0; break; case 7: return 1; break; default: printf("Invalid\n"); break; }; } return 1; }