unsigned libn64_fbchar32(const struct libn64_fbtext_context *context, uint32_t fb_address, char c) { const uint8_t *font = get_font_data(c); unsigned i, j; fb_address += (context->x << 5); for (i = 0; i < 16; i++) { uint8_t bitmask = font[i]; // Flush line contents if valid; otherwise flag it dirty. // This prevents an otherwise redundant read from memory. __asm__ __volatile__( "cache 0xD, 0x0(%0)\n\t" "cache 0xD, 0x10(%0)\n\t" :: "r"(fb_address) ); for (fb_address += 8 << 2, j = 0; j < 8; j ++) { unsigned bit = (bitmask >> j) & 0x1; uint16_t color = context->colors[bit]; __asm__ __volatile__( "sw %0, -4(%1)\n\t" :: "r"(color), "r"(fb_address) : "memory" ); fb_address -= 4; } // Ensure the line gets written to memory. __asm__ __volatile__( "cache 0x19, 0x0(%0)\n\t" "cache 0x19, 0x10(%0)\n\t" :: "r"(fb_address) ); fb_address += context->fb_width; } return 2; }
int main(int argc, char **argv){ Buffer_Set buffers; File_Data file; float *widths_data; float *wrap_ys; float font_height; float max_width; void *scratch; int scratch_size; Stats_Log log; int do_replay = 0; char *replay_filename = 0; if (argc < 2){ printf("usage: buffer_test <filename> <message> [-h <.hst file>]\n"); exit(1); } setup(); for (int i = 3; i < argc; ++i){ if (do_replay){ replay_filename = argv[i]; do_replay = 0; } if (strcmp(argv[i], "-h") == 0){ if (replay_filename != 0){ printf("found -h twice, ignoring duplicates\n"); } else{ do_replay = 1; } } } do_replay = (replay_filename != 0); memzero_4tech(buffers); log.max = 1 << 20; log.size = 0; log.out = (char*)malloc(log.max); log.sec_max = 32; log.sec_top = 0; log.sections = (Log_Section*)malloc(sizeof(Log_Section)*log.sec_max); log.error = 0; scratch_size = 1 << 20; scratch = malloc(scratch_size); file = get_file(argv[1]); if (!file.data) exit(1); widths_data = get_font_data("LiberationSans-Regular.ttf", &font_height); max_width = 500.f; log_begin_section(&log, litstr("which-test")); { log_write_str(&log, argv[1], (int)strlen(argv[1])); log_write_int(&log, file.size); log_write_str(&log, argv[2], (int)strlen(argv[2])); } log_end_section(&log); log_begin_section(&log, litstr("file-open")); { Record_Statistics init_rec, starts_widths_rec, wraps_rec; initialization_test(&log, &buffers, file, reps, scratch, scratch_size, &init_rec); stream_check_test(&buffers, scratch, scratch_size); measure_starts_widths_test(&log, &buffers, reps, scratch, scratch_size, &starts_widths_rec, widths_data); measure_check_test(&buffers); wrap_ys = measure_wraps_test(&log, &buffers, reps, scratch, scratch_size, &wraps_rec, font_height, max_width); Time_Record expected_file_open; expected_file_open = init_rec.expected + starts_widths_rec.expected + wraps_rec.expected; printf("average file open:\n"); print_record(expected_file_open); printf("\n"); log_time_record(&log, litstr("average"), expected_file_open); } log_end_section(&log); log_begin_section(&log, litstr("cursor-seek")); { Record_Statistics full_cursor; Time_Record full_cursor_average; log_begin_section(&log, litstr("to-pos")); { memzero_4tech(full_cursor_average); for (int i = 0; i < 5; ++i){ silence_test(); int pos = (file.size*i) / 5; full_cursor_test(&log, &buffers, pos, wrap_ys, widths_data, font_height, max_width, 5, scratch, scratch_size, &full_cursor); full_cursor_average = full_cursor_average + full_cursor.expected; } full_cursor_average /= 5; printf("average cursor from position:\n"); print_record(full_cursor_average); printf("\n"); log_time_record(&log, litstr("average"), full_cursor_average); } log_end_section(&log); log_begin_section(&log, litstr("to-line-character")); { memzero_4tech(full_cursor_average); for (int i = 0; i < 5; ++i){ silence_test(); int line = (buffers.buffer.line_count*i) / 5; full_cursor_line_test(&log, &buffers, line, 20, wrap_ys, widths_data, font_height, max_width, 5, scratch, scratch_size, &full_cursor); full_cursor_average = full_cursor_average + full_cursor.expected; } full_cursor_average /= 5; printf("average cursor from line & character:\n"); print_record(full_cursor_average); printf("\n"); log_time_record(&log, litstr("average"), full_cursor_average); } log_end_section(&log); log_begin_section(&log, litstr("to-unwrapped-x-y")); { memzero_4tech(full_cursor_average); for (int i = 0; i < 5; ++i){ silence_test(); float y = font_height * (buffers.buffer.line_count*i) / 4.f; full_cursor_xy_test(&log, &buffers, y, 37.f, 0, wrap_ys, widths_data, font_height, max_width, 5, scratch, scratch_size, &full_cursor); full_cursor_average = full_cursor_average + full_cursor.expected; } full_cursor_average /= 5; printf("average cursor from line & character:\n"); print_record(full_cursor_average); printf("\n"); log_time_record(&log, litstr("average"), full_cursor_average); } log_end_section(&log); } log_end_section(&log); log_begin_section(&log, litstr("word-seek")); { Record_Statistics word_seek; { char word[] = "not-going-to-find-this"; int word_len = sizeof(word) - 1; word_seek_test(&log, &buffers, reps, 0, word, word_len, scratch, scratch_size, &word_seek); } { char word[] = "return"; int word_len = sizeof(word) - 1; word_seek_test(&log, &buffers, reps, 1, word, word_len, scratch, scratch_size, &word_seek); printf("average normal word seek:\n"); print_record(word_seek.expected); printf("\n"); } } log_end_section(&log); log_begin_section(&log, litstr("one-hundred-single-edits")); { Record_Statistics edits; insert_bottom_test(&log, &buffers, reps, widths_data, 100, scratch, scratch_size, &edits); insert_top_test(&log, &buffers, reps, widths_data, 100, scratch, scratch_size, &edits); delete_bottom_test(&log, &buffers, reps, widths_data, 100, scratch, scratch_size, &edits); delete_top_test(&log, &buffers, reps, widths_data, 100, scratch, scratch_size, &edits); } log_end_section(&log); File_Data replay_file = {}; Replay replay; if (do_replay){ replay_file = get_file(replay_filename); prepare_replay(replay_file, &replay); } if (replay_file.data){ log_begin_section(&log, litstr("natural-edits")); { Record_Statistics edits; natural_edits_test(&log, &buffers, reps, widths_data, &replay, scratch, scratch_size, &edits); } log_end_section(&log); } else{ printf("skipped natural-edits test\n\n"); } log_begin_section(&log, litstr("batch-edit")); { Buffer_Edit *batch; char *str_base; int batch_size, str_size; batch_size = 1000; str_size = 10000; batch = (Buffer_Edit*)malloc(sizeof(Buffer_Edit)*batch_size); str_base = (char*)malloc(str_size); int character_stride; character_stride = buffer_size(&buffers.buffer); if (character_stride < batch_size * 10){ batch_size = character_stride / 10; character_stride = 10; } else{ character_stride = (character_stride / batch_size); } int p, curs; curs = 0; p = 0; for (int i = 0; i < batch_size; ++i){ Buffer_Edit edit; edit.start = p; edit.end = p+8; p += character_stride; edit.str_start = curs; if (i & 1){ edit.len = 9; memcpy_4tech(str_base + curs, "123456789", 9); curs += 9; } else{ edit.len = 7; memcpy_4tech(str_base + curs, "abcdefg", 7); curs += 7; } batch[i] = edit; } Record_Statistics batch_stats; batch_edit_test(&log, &buffers, reps, widths_data, batch, str_base, batch_size, scratch, scratch_size, &batch_stats); } log_end_section(&log); log_finish(&log); return(0); }
/* * changed this to take a filename so we can pass config files on the command line * default is config.xml */ sConfigData::sConfigData(const char *a_filename) : fonts() { DirPath dp = DirPath() << a_filename; // `J` moved to root directory DirPath dpold = DirPath() << "Resources" << "Data" << a_filename; string filename = dp.c_str(); string filenameold = dpold.c_str(); l.ss() << "Loading configuration variables from '" << filename << "'"; l.ssend(); /* * make sure we have something playable, * even if the file doesn't load */ set_defaults(); /* * open the file - moan most eloqently in its absence */ TiXmlDocument doc(filename); TiXmlDocument docold(filenameold); if (!doc.LoadFile()) { l.ss() << "Can't load " << filename << " from root directory." << endl << "Error: line " << doc.ErrorRow() << ", col " << doc.ErrorCol() << ": " << doc.ErrorDesc() << endl << "Attempting to load old file " << filenameold << "." << endl; l.ssend(); doc = docold; } if (!doc.LoadFile()) { l.ss() << "can't load " << filename << endl << "Error: line " << doc.ErrorRow() << ", col " << doc.ErrorCol() << ": " << doc.ErrorDesc(); l.ssend(); /* * a bit of narrative for the players: makes it easier to tell * if the config isn't being found */ l.ss() << "*** Game will run with default pricing factors.\n*** This may seem a little easy. To fix this\n*** get a config.xml file from pinkpetal.org\n*** or make one with W***e Master Editor"; l.ssend(); return; } /* * get the docuement root */ TiXmlElement *el, *root_el = doc.RootElement(); /* * loop over the elements attached to the root */ for (el = root_el->FirstChildElement(); el; el = el->NextSiblingElement()) { string tag = el->ValueStr(); // now, depending on the tag name... if (el->ValueStr() == "Folders") { get_folders_data(el); continue; } if (el->ValueStr() == "Resolution") { get_resolution_data(el); continue; } if (el->ValueStr() == "Initial") { get_initial_values(el); continue; } if (el->ValueStr() == "Income") { get_income_factors(el); continue; } if (el->ValueStr() == "Expenses") { get_expense_factors(el); continue; } if (el->ValueStr() == "Gambling") { get_gambling_factors(el); continue; } if (el->ValueStr() == "Prostitution") { get_pros_factors(el); continue; } if (el->ValueStr() == "Catacombs") { get_catacombs_data(el); continue; } if (el->ValueStr() == "SlaveMarket") { get_slave_market_data(el);continue; } if (el->ValueStr() == "Pregnancy") { get_preg_factors(el); continue; } if (el->ValueStr() == "Tax") { get_tax_factors(el); continue; } if (el->ValueStr() == "Gangs") { get_gang_factors(el); continue; } if (el->ValueStr() == "Items") { get_item_data(el); continue; } if (el->ValueStr() == "Fonts") { get_font_data(el); continue; } if (el->ValueStr() == "Debug") { get_debug_flags(el); continue; } l.ss() << "Warning: config.xml: tag: '" << tag << "' unexpected"; l.ssend(); } // check interface for colors DirPath dpi = DirPath() << "Resources" << "Interface" << resolution.resolution << "InterfaceColors.xml"; TiXmlDocument doci(dpi.c_str()); if (doci.LoadFile()) { string m_filename = dpi.c_str(); TiXmlElement *el, *root_el = doci.RootElement(); for (el = root_el->FirstChildElement(); el; el = el->NextSiblingElement()) { string tag = el->ValueStr(); if (tag == "Color") { XmlUtil xu(m_filename); string name; int r, g, b; xu.get_att(el, "Name", name); xu.get_att(el, "R", r); xu.get_att(el, "G", g); xu.get_att(el, "B", b); /* */if (name == "ItemRarity0") ColorConvert.RGBToSDLColor(items.rarity_color[0], r, g, b); else if (name == "ItemRarity1") ColorConvert.RGBToSDLColor(items.rarity_color[1], r, g, b); else if (name == "ItemRarity2") ColorConvert.RGBToSDLColor(items.rarity_color[2], r, g, b); else if (name == "ItemRarity3") ColorConvert.RGBToSDLColor(items.rarity_color[3], r, g, b); else if (name == "ItemRarity4") ColorConvert.RGBToSDLColor(items.rarity_color[4], r, g, b); else if (name == "ItemRarity5") ColorConvert.RGBToSDLColor(items.rarity_color[5], r, g, b); else if (name == "ItemRarity6") ColorConvert.RGBToSDLColor(items.rarity_color[6], r, g, b); else if (name == "ItemRarity7") ColorConvert.RGBToSDLColor(items.rarity_color[7], r, g, b); else if (name == "ItemRarity8") ColorConvert.RGBToSDLColor(items.rarity_color[8], r, g, b); } } } fonts.detailfontsize = 9; // default to 9 then check if it is set in girl_details_screen.xml DirPath dpt = DirPath() << "Resources" << "Interface" << resolution.resolution << "girl_details_screen.xml"; TiXmlDocument doct(dp.c_str()); if (doct.LoadFile()) { string m_filename = dpt.c_str(); TiXmlElement *el, *root_el = doct.RootElement(); for (el = root_el->FirstChildElement(); el; el = el->NextSiblingElement()) { string tag = el->ValueStr(); if (tag == "Text") { XmlUtil xu(m_filename); string name; int f = 9; xu.get_att(el, "Name", name); xu.get_att(el, "FontSize", f, true); if (name == "GirlDescription" && f > 0) { fonts.detailfontsize = f; break; } } } } }